From 1645bd0d4ed136c6c72a3156b16ee75819d11247 Mon Sep 17 00:00:00 2001 From: verytactical <186486509+verytactical@users.noreply.github.com> Date: Sun, 13 Apr 2025 17:02:51 +0400 Subject: [PATCH 01/38] feat: new parser --- spell/cspell-list.txt | 3 +- src/cli/colors.ts | 4 +- src/imports/path.ts | 8 - src/next/ast/common.ts | 45 + src/next/ast/expression.ts | 148 ++ src/next/ast/generated/common.ts | 40 + src/next/ast/generated/expression.ts | 217 +++ src/next/ast/generated/root.ts | 419 +++++ src/next/ast/generated/statement.ts | 248 +++ src/next/ast/generated/type.ts | 103 + src/next/ast/index.ts | 5 + src/next/ast/root.ts | 270 +++ src/next/ast/statement.ts | 146 ++ src/next/ast/type.ts | 89 + src/next/grammar/gen.sh | 1 + src/next/grammar/grammar.gg | 362 ++++ src/next/grammar/grammar.ts | 2608 ++++++++++++++++++++++++++ src/next/grammar/index.ts | 1626 ++++++++++++++++ src/next/grammar/parser-error.ts | 228 +++ src/next/grammar/path.ts | 60 + src/next/grammar/src-info.ts | 279 +++ src/next/index.ts | 26 + src/next/wallet-v4.tact | 235 +++ 23 files changed, 7159 insertions(+), 11 deletions(-) create mode 100644 src/next/ast/common.ts create mode 100644 src/next/ast/expression.ts create mode 100644 src/next/ast/generated/common.ts create mode 100644 src/next/ast/generated/expression.ts create mode 100644 src/next/ast/generated/root.ts create mode 100644 src/next/ast/generated/statement.ts create mode 100644 src/next/ast/generated/type.ts create mode 100644 src/next/ast/index.ts create mode 100644 src/next/ast/root.ts create mode 100644 src/next/ast/statement.ts create mode 100644 src/next/ast/type.ts create mode 100755 src/next/grammar/gen.sh create mode 100644 src/next/grammar/grammar.gg create mode 100644 src/next/grammar/grammar.ts create mode 100644 src/next/grammar/index.ts create mode 100644 src/next/grammar/parser-error.ts create mode 100644 src/next/grammar/path.ts create mode 100644 src/next/grammar/src-info.ts create mode 100644 src/next/index.ts create mode 100644 src/next/wallet-v4.tact diff --git a/spell/cspell-list.txt b/spell/cspell-list.txt index efb4f61f75..2b6ff4d36c 100644 --- a/spell/cspell-list.txt +++ b/spell/cspell-list.txt @@ -97,8 +97,8 @@ Lagus Laika langle langtools -letrec learnXinYminutes +letrec Liskov llm llms @@ -166,6 +166,7 @@ seti shardchains shiki Shvetc +Signedness skywardboundd Stateinit statinit diff --git a/src/cli/colors.ts b/src/cli/colors.ts index 1d4d934cf2..77d15f2cba 100644 --- a/src/cli/colors.ts +++ b/src/cli/colors.ts @@ -4,8 +4,8 @@ export const isColorSupported = () => { if (process.platform === "win32") { const [major, _, build] = release().split(".").map(Number); // Windows 10, Build 10586+ - return ( - (major && major > 10) || (major === 10 && build && build >= 10586) + return Boolean( + (major && major > 10) || (major === 10 && build && build >= 10586), ); } if (process.stdout.isTTY && process.env.TERM !== "dumb") { diff --git a/src/imports/path.ts b/src/imports/path.ts index 5a45ee0817..4acc8accf5 100644 --- a/src/imports/path.ts +++ b/src/imports/path.ts @@ -1,9 +1,6 @@ import { throwInternalCompilerError } from "@/error/errors"; import { repeat } from "@/utils/array"; -// Witness tag. Do not use, do not export. -const pathTag = Symbol("path"); - /** * Safe relative path */ @@ -16,10 +13,6 @@ export type RelativePath = { * /-separated strings that go after optional ../ */ readonly segments: readonly string[]; - /** - * Proof that path was created by RelativePath constructor - */ - readonly [pathTag]: true; }; /** @@ -33,7 +26,6 @@ const RelativePath = ( throwInternalCompilerError("Negative number of ../ in path"); } const result: RelativePath = { - [pathTag]: true, stepsUp, segments: Object.freeze(segments), }; diff --git a/src/next/ast/common.ts b/src/next/ast/common.ts new file mode 100644 index 0000000000..2e5dd25a30 --- /dev/null +++ b/src/next/ast/common.ts @@ -0,0 +1,45 @@ +export type Range = { + readonly start: number; + readonly end: number; +}; + +export type OptionalId = Id | Wildcard; + +export type Id = { + readonly kind: "id"; + readonly text: string; + readonly loc: Range; +}; + +export type Wildcard = { + readonly kind: "wildcard"; + readonly loc: Range; +}; + +export type FuncId = { + readonly kind: "func_id"; + readonly text: string; + readonly loc: Range; +}; + +export type TypeId = { + readonly kind: "type_id"; + readonly text: string; + readonly loc: Range; +}; + +export type Language = "func" | "tact"; + +/** + * Safe relative path + */ +export type RelativePath = { + /** + * Number of "../" in front of path + */ + readonly stepsUp: number; + /** + * /-separated strings that go after optional ../ + */ + readonly segments: readonly string[]; +}; diff --git a/src/next/ast/expression.ts b/src/next/ast/expression.ts new file mode 100644 index 0000000000..fe4dd425d0 --- /dev/null +++ b/src/next/ast/expression.ts @@ -0,0 +1,148 @@ +import type { Id, Range, TypeId } from "@/next/ast/common"; + +export type Expression = + | OpBinary + | OpUnary + | Conditional + | MethodCall + | FieldAccess + | StaticCall + | StructInstance + | InitOf + | CodeOf + | Number + | Boolean + | Null + | String + | Var; + +export type Var = { + readonly kind: "var"; + readonly name: string; + readonly loc: Range; +}; + +export type Number = { + readonly kind: "number"; + readonly base: NumberBase; + readonly value: bigint; + readonly loc: Range; +}; + +export type NumberBase = "2" | "8" | "10" | "16"; + +export type Boolean = { + readonly kind: "boolean"; + readonly value: boolean; + readonly loc: Range; +}; + +// A String is a string in which escaping characters, like '\\' has been simplified, e.g., '\\' simplified to '\'. +export type String = { + readonly kind: "string"; + readonly value: string; + readonly loc: Range; +}; + +// `null` value is an inhabitant of several types: +// it can represent missing values in optional types, +// or empty map of any key and value types +export type Null = { + readonly kind: "null"; + readonly loc: Range; +}; + +export type BinaryOperation = + | "+" + | "-" + | "*" + | "/" + | "!=" + | ">" + | "<" + | ">=" + | "<=" + | "==" + | "&&" + | "||" + | "%" + | "<<" + | ">>" + | "&" + | "|" + | "^"; + +export type OpBinary = { + readonly kind: "op_binary"; + readonly op: BinaryOperation; + readonly left: Expression; + readonly right: Expression; + readonly loc: Range; +}; + +export type UnaryOperation = "+" | "-" | "!" | "!!" | "~"; + +export type OpUnary = { + readonly kind: "op_unary"; + readonly op: UnaryOperation; + readonly operand: Expression; + readonly loc: Range; +}; + +export type FieldAccess = { + readonly kind: "field_access"; + readonly aggregate: Expression; // contract, trait, struct, message + readonly field: Id; + readonly loc: Range; +}; + +export type MethodCall = { + readonly kind: "method_call"; + readonly self: Expression; // anything with a method + readonly method: Id; + readonly args: readonly Expression[]; + readonly loc: Range; +}; + +// builtins or top-level (module) functions +export type StaticCall = { + readonly kind: "static_call"; + readonly function: Id; + readonly args: readonly Expression[]; + readonly loc: Range; +}; + +export type StructInstance = { + readonly kind: "struct_instance"; + readonly type: TypeId; + readonly args: readonly StructFieldInitializer[]; + readonly loc: Range; +}; + +export type StructFieldInitializer = { + readonly kind: "struct_field_initializer"; + readonly field: Id; + readonly initializer: Expression; + readonly loc: Range; +}; + +export type InitOf = { + readonly kind: "init_of"; + readonly contract: TypeId; + readonly args: readonly Expression[]; + readonly loc: Range; +}; + +export type CodeOf = { + readonly kind: "code_of"; + readonly contract: TypeId; + readonly loc: Range; +}; + +export type Conditional = { + readonly kind: "conditional"; + readonly condition: Expression; + readonly thenBranch: Expression; + readonly elseBranch: Expression; + readonly loc: Range; +}; diff --git a/src/next/ast/generated/common.ts b/src/next/ast/generated/common.ts new file mode 100644 index 0000000000..0f5e9479f5 --- /dev/null +++ b/src/next/ast/generated/common.ts @@ -0,0 +1,40 @@ +/* eslint-disable @typescript-eslint/no-unnecessary-condition */ +import type * as $ from "@/next/ast/common"; +export type Range = $.Range; +export const Range = (start: number, end: number): $.Range => + Object.freeze({ + start, + end, + }); +export type Id = $.Id; +export const Id = (text: string, loc: $.Range): $.Id => + Object.freeze({ + kind: "id", + text, + loc, + }); +export const isId = ($value: Id) => $value.kind === "id"; +export type Wildcard = $.Wildcard; +export const Wildcard = (loc: $.Range): $.Wildcard => + Object.freeze({ + kind: "wildcard", + loc, + }); +export const isWildcard = ($value: Wildcard) => $value.kind === "wildcard"; +export type OptionalId = $.OptionalId; +export type FuncId = $.FuncId; +export const FuncId = (text: string, loc: $.Range): $.FuncId => + Object.freeze({ + kind: "func_id", + text, + loc, + }); +export const isFuncId = ($value: FuncId) => $value.kind === "func_id"; +export type TypeId = $.TypeId; +export const TypeId = (text: string, loc: $.Range): $.TypeId => + Object.freeze({ + kind: "type_id", + text, + loc, + }); +export const isTypeId = ($value: TypeId) => $value.kind === "type_id"; diff --git a/src/next/ast/generated/expression.ts b/src/next/ast/generated/expression.ts new file mode 100644 index 0000000000..6291ba19c1 --- /dev/null +++ b/src/next/ast/generated/expression.ts @@ -0,0 +1,217 @@ +/* eslint-disable @typescript-eslint/no-unnecessary-condition */ +import type * as $c from "@/next/ast/common"; +import type * as $ from "@/next/ast/expression"; + +export type BinaryOperation = $.BinaryOperation; +export const allBinaryOperation: readonly $.BinaryOperation[] = [ + "+", + "-", + "*", + "/", + "!=", + ">", + "<", + ">=", + "<=", + "==", + "&&", + "||", + "%", + "<<", + ">>", + "&", + "|", + "^", +]; +export type UnaryOperation = $.UnaryOperation; +export const allUnaryOperation: readonly $.UnaryOperation[] = [ + "+", + "-", + "!", + "!!", + "~", +]; +export type CodeOf = $.CodeOf; +export const CodeOf = (contract: $c.TypeId, loc: $c.Range): $.CodeOf => + Object.freeze({ + kind: "code_of", + contract, + loc, + }); +export const isCodeOf = ($value: CodeOf) => $value.kind === "code_of"; +export type NumberBase = $.NumberBase; +export const allNumberBase: readonly $.NumberBase[] = ["2", "8", "10", "16"]; +export type Number = $.Number; +export const Number = ( + base: $.NumberBase, + value: bigint, + loc: $c.Range, +): $.Number => + Object.freeze({ + kind: "number", + base, + value, + loc, + }); +export const isNumber = ($value: Number) => $value.kind === "number"; +export type Boolean = $.Boolean; +export const Boolean = (value: boolean, loc: $c.Range): $.Boolean => + Object.freeze({ + kind: "boolean", + value, + loc, + }); +export const isBoolean = ($value: Boolean) => $value.kind === "boolean"; +export type Null = $.Null; +export const Null = (loc: $c.Range): $.Null => + Object.freeze({ + kind: "null", + loc, + }); +export const isNull = ($value: Null) => $value.kind === "null"; +export type String = $.String; +export const String = (value: string, loc: $c.Range): $.String => + Object.freeze({ + kind: "string", + value, + loc, + }); +export const isString = ($value: String) => $value.kind === "string"; +export type Var = $.Var; +export const Var = (name: string, loc: $c.Range): $.Var => + Object.freeze({ + kind: "var", + name, + loc, + }); +export const isVar = ($value: Var) => $value.kind === "var"; +export type InitOf = $.InitOf; +export const InitOf = ( + contract: $c.TypeId, + args: readonly $.Expression[], + loc: $c.Range, +): $.InitOf => + Object.freeze({ + kind: "init_of", + contract, + args, + loc, + }); +export const isInitOf = ($value: InitOf) => $value.kind === "init_of"; +export type StructFieldInitializer = $.StructFieldInitializer; +export const StructFieldInitializer = ( + field: $c.Id, + initializer: $.Expression, + loc: $c.Range, +): $.StructFieldInitializer => + Object.freeze({ + kind: "struct_field_initializer", + field, + initializer, + loc, + }); +export const isStructFieldInitializer = ($value: StructFieldInitializer) => + $value.kind === "struct_field_initializer"; +export type StructInstance = $.StructInstance; +export const StructInstance = ( + type_: $c.TypeId, + args: readonly $.StructFieldInitializer[], + loc: $c.Range, +): $.StructInstance => + Object.freeze({ + kind: "struct_instance", + type: type_, + args, + loc, + }); +export const isStructInstance = ($value: StructInstance) => + $value.kind === "struct_instance"; +export type StaticCall = $.StaticCall; +export const StaticCall = ( + function_: $c.Id, + args: readonly $.Expression[], + loc: $c.Range, +): $.StaticCall => + Object.freeze({ + kind: "static_call", + function: function_, + args, + loc, + }); +export const isStaticCall = ($value: StaticCall) => + $value.kind === "static_call"; +export type FieldAccess = $.FieldAccess; +export const FieldAccess = ( + aggregate: $.Expression, + field: $c.Id, + loc: $c.Range, +): $.FieldAccess => + Object.freeze({ + kind: "field_access", + aggregate, + field, + loc, + }); +export const isFieldAccess = ($value: FieldAccess) => + $value.kind === "field_access"; +export type MethodCall = $.MethodCall; +export const MethodCall = ( + self: $.Expression, + method: $c.Id, + args: readonly $.Expression[], + loc: $c.Range, +): $.MethodCall => + Object.freeze({ + kind: "method_call", + self, + method, + args, + loc, + }); +export const isMethodCall = ($value: MethodCall) => + $value.kind === "method_call"; +export type Conditional = $.Conditional; +export const Conditional = ( + condition: $.Expression, + thenBranch: $.Expression, + elseBranch: $.Expression, + loc: $c.Range, +): $.Conditional => + Object.freeze({ + kind: "conditional", + condition, + thenBranch, + elseBranch, + loc, + }); +export const isConditional = ($value: Conditional) => + $value.kind === "conditional"; +export type OpUnary = $.OpUnary; +export const OpUnary = ( + op: $.UnaryOperation, + operand: $.Expression, + loc: $c.Range, +): $.OpUnary => + Object.freeze({ + kind: "op_unary", + op, + operand, + loc, + }); +export const isOpUnary = ($value: OpUnary) => $value.kind === "op_unary"; +export type OpBinary = $.OpBinary; +export const OpBinary = ( + op: $.BinaryOperation, + left: $.Expression, + right: $.Expression, + loc: $c.Range, +): $.OpBinary => + Object.freeze({ + kind: "op_binary", + op, + left, + right, + loc, + }); +export const isOpBinary = ($value: OpBinary) => $value.kind === "op_binary"; +export type Expression = $.Expression; diff --git a/src/next/ast/generated/root.ts b/src/next/ast/generated/root.ts new file mode 100644 index 0000000000..98de92d0c4 --- /dev/null +++ b/src/next/ast/generated/root.ts @@ -0,0 +1,419 @@ +/* eslint-disable @typescript-eslint/no-unnecessary-condition */ +import type * as $c from "@/next/ast/common"; +import type * as $e from "@/next/ast/expression"; +import type * as $s from "@/next/ast/statement"; +import type * as $t from "@/next/ast/type"; +import type * as $ from "@/next/ast/root"; +export type ImportType = $.ImportType; +export const allImportType: readonly $.ImportType[] = ["stdlib", "relative"]; +export type ImportPath = $.ImportPath; +export const ImportPath = ( + path: $c.RelativePath, + type_: $.ImportType, + language: $c.Language, +): $.ImportPath => + Object.freeze({ + path, + type: type_, + language, + }); +export type Import = $.Import; +export const Import = (importPath: $.ImportPath, loc: $c.Range): $.Import => + Object.freeze({ + kind: "import", + importPath, + loc, + }); +export const isImport = ($value: Import) => $value.kind === "import"; +export type FunctionAttributeGet = $.FunctionAttributeGet; +export const FunctionAttributeGet = ( + methodId: $e.Expression | undefined, + loc: $c.Range, +): $.FunctionAttributeGet => + Object.freeze({ + kind: "function_attribute", + type: "get", + methodId, + loc, + }); +export const isFunctionAttributeGet = ($value: FunctionAttributeGet) => + $value.kind === "function_attribute"; +export type FunctionAttributeName = $.FunctionAttributeName; +export const allFunctionAttributeName: readonly $.FunctionAttributeName[] = [ + "mutates", + "extends", + "virtual", + "abstract", + "override", + "inline", +]; +export type FunctionAttributeRest = $.FunctionAttributeRest; +export const FunctionAttributeRest = ( + type_: $.FunctionAttributeName, + loc: $c.Range, +): $.FunctionAttributeRest => + Object.freeze({ + kind: "function_attribute", + type: type_, + loc, + }); +export const isFunctionAttributeRest = ($value: FunctionAttributeRest) => + $value.kind === "function_attribute"; +export type FunctionAttribute = $.FunctionAttribute; +export type TypedParameter = $.TypedParameter; +export const TypedParameter = ( + name: $c.OptionalId, + type_: $t.Type, + loc: $c.Range, +): $.TypedParameter => + Object.freeze({ + kind: "typed_parameter", + name, + type: type_, + loc, + }); +export const isTypedParameter = ($value: TypedParameter) => + $value.kind === "typed_parameter"; +export type FunctionDef = $.FunctionDef; +export const FunctionDef = ( + attributes: readonly $.FunctionAttribute[], + name: $c.Id, + return_: $t.Type | undefined, + params: readonly $.TypedParameter[], + statements: readonly $s.Statement[], + loc: $c.Range, +): $.FunctionDef => + Object.freeze({ + kind: "function_def", + attributes, + name, + return: return_, + params, + statements, + loc, + }); +export const isFunctionDef = ($value: FunctionDef) => + $value.kind === "function_def"; +export type AsmShuffle = $.AsmShuffle; +export const AsmShuffle = ( + args: readonly $c.Id[], + ret: readonly $e.Number[], +): $.AsmShuffle => + Object.freeze({ + args, + ret, + }); +export type AsmInstruction = $.AsmInstruction; +export type AsmFunctionDef = $.AsmFunctionDef; +export const AsmFunctionDef = ( + shuffle: $.AsmShuffle, + attributes: readonly $.FunctionAttribute[], + name: $c.Id, + return_: $t.Type | undefined, + params: readonly $.TypedParameter[], + instructions: readonly $.AsmInstruction[], + loc: $c.Range, +): $.AsmFunctionDef => + Object.freeze({ + kind: "asm_function_def", + shuffle, + attributes, + name, + return: return_, + params, + instructions, + loc, + }); +export const isAsmFunctionDef = ($value: AsmFunctionDef) => + $value.kind === "asm_function_def"; +export type NativeFunctionDecl = $.NativeFunctionDecl; +export const NativeFunctionDecl = ( + attributes: readonly $.FunctionAttribute[], + name: $c.Id, + nativeName: $c.FuncId, + params: readonly $.TypedParameter[], + return_: $t.Type | undefined, + loc: $c.Range, +): $.NativeFunctionDecl => + Object.freeze({ + kind: "native_function_decl", + attributes, + name, + nativeName, + params, + return: return_, + loc, + }); +export const isNativeFunctionDecl = ($value: NativeFunctionDecl) => + $value.kind === "native_function_decl"; +export type ConstantAttributeName = $.ConstantAttributeName; +export const allConstantAttributeName: readonly $.ConstantAttributeName[] = [ + "virtual", + "override", + "abstract", +]; +export type ConstantAttribute = $.ConstantAttribute; +export const ConstantAttribute = ( + type_: $.ConstantAttributeName, + loc: $c.Range, +): $.ConstantAttribute => + Object.freeze({ + type: type_, + loc, + }); +export type ConstantDef = $.ConstantDef; +export const ConstantDef = ( + attributes: readonly $.ConstantAttribute[], + name: $c.Id, + type_: $t.Type, + initializer: $e.Expression, + loc: $c.Range, +): $.ConstantDef => + Object.freeze({ + kind: "constant_def", + attributes, + name, + type: type_, + initializer, + loc, + }); +export const isConstantDef = ($value: ConstantDef) => + $value.kind === "constant_def"; +export type FieldDecl = $.FieldDecl; +export const FieldDecl = ( + name: $c.Id, + type_: $t.Type, + initializer: $e.Expression | undefined, + loc: $c.Range, +): $.FieldDecl => + Object.freeze({ + kind: "field_decl", + name, + type: type_, + initializer, + loc, + }); +export const isFieldDecl = ($value: FieldDecl) => $value.kind === "field_decl"; +export type StructDecl = $.StructDecl; +export const StructDecl = ( + name: $c.TypeId, + fields: readonly $.FieldDecl[], + loc: $c.Range, +): $.StructDecl => + Object.freeze({ + kind: "struct_decl", + name, + fields, + loc, + }); +export const isStructDecl = ($value: StructDecl) => + $value.kind === "struct_decl"; +export type MessageDecl = $.MessageDecl; +export const MessageDecl = ( + name: $c.TypeId, + opcode: $e.Expression | undefined, + fields: readonly $.FieldDecl[], + loc: $c.Range, +): $.MessageDecl => + Object.freeze({ + kind: "message_decl", + name, + opcode, + fields, + loc, + }); +export const isMessageDecl = ($value: MessageDecl) => + $value.kind === "message_decl"; +export type ContractAttribute = $.ContractAttribute; +export const ContractAttribute = ( + name: string, + loc: $c.Range, +): $.ContractAttribute => + Object.freeze({ + type: "interface", + name, + loc, + }); +export type ContractInit = $.ContractInit; +export const ContractInit = ( + params: readonly $.TypedParameter[], + statements: readonly $s.Statement[], + loc: $c.Range, +): $.ContractInit => + Object.freeze({ + kind: "contract_init", + params, + statements, + loc, + }); +export const isContractInit = ($value: ContractInit) => + $value.kind === "contract_init"; +export type ReceiverSimple = $.ReceiverSimple; +export const ReceiverSimple = (param: $.TypedParameter): $.ReceiverSimple => + Object.freeze({ + kind: "simple", + param, + }); +export const isReceiverSimple = ($value: ReceiverSimple) => + $value.kind === "simple"; +export type ReceiverFallback = $.ReceiverFallback; +export const ReceiverFallback = (): $.ReceiverFallback => + Object.freeze({ + kind: "fallback", + }); +export const isReceiverFallback = ($value: ReceiverFallback) => + $value.kind === "fallback"; +export type ReceiverComment = $.ReceiverComment; +export const ReceiverComment = (comment: $e.String): $.ReceiverComment => + Object.freeze({ + kind: "comment", + comment, + }); +export const isReceiverComment = ($value: ReceiverComment) => + $value.kind === "comment"; +export type ReceiverSubKind = $.ReceiverSubKind; +export type ReceiverInternal = $.ReceiverInternal; +export const ReceiverInternal = ( + subKind: $.ReceiverSubKind, + loc: $c.Range, +): $.ReceiverInternal => + Object.freeze({ + kind: "internal", + subKind, + loc, + }); +export const isReceiverInternal = ($value: ReceiverInternal) => + $value.kind === "internal"; +export type ReceiverExternal = $.ReceiverExternal; +export const ReceiverExternal = ( + subKind: $.ReceiverSubKind, + loc: $c.Range, +): $.ReceiverExternal => + Object.freeze({ + kind: "external", + subKind, + loc, + }); +export const isReceiverExternal = ($value: ReceiverExternal) => + $value.kind === "external"; +export type ReceiverBounce = $.ReceiverBounce; +export const ReceiverBounce = ( + param: $.TypedParameter, + loc: $c.Range, +): $.ReceiverBounce => + Object.freeze({ + kind: "bounce", + param, + loc, + }); +export const isReceiverBounce = ($value: ReceiverBounce) => + $value.kind === "bounce"; +export type ReceiverKind = $.ReceiverKind; +export type Receiver = $.Receiver; +export const Receiver = ( + selector: $.ReceiverKind, + statements: readonly $s.Statement[], + loc: $c.Range, +): $.Receiver => + Object.freeze({ + kind: "receiver", + selector, + statements, + loc, + }); +export const isReceiver = ($value: Receiver) => $value.kind === "receiver"; +export type ContractItem = $.ContractItem; +export type Contract = $.Contract; +export const Contract = ( + name: $c.TypeId, + traits: readonly $c.TypeId[], + attributes: readonly $.ContractAttribute[], + params: readonly $.FieldDecl[] | undefined, + declarations: readonly $.ContractItem[], + loc: $c.Range, +): $.Contract => + Object.freeze({ + kind: "contract", + name, + traits, + attributes, + params, + declarations, + loc, + }); +export const isContract = ($value: Contract) => $value.kind === "contract"; +export type FunctionDecl = $.FunctionDecl; +export const FunctionDecl = ( + attributes: readonly $.FunctionAttribute[], + name: $c.Id, + return_: $t.Type | undefined, + params: readonly $.TypedParameter[], + loc: $c.Range, +): $.FunctionDecl => + Object.freeze({ + kind: "function_decl", + attributes, + name, + return: return_, + params, + loc, + }); +export const isFunctionDecl = ($value: FunctionDecl) => + $value.kind === "function_decl"; +export type ConstantDecl = $.ConstantDecl; +export const ConstantDecl = ( + attributes: readonly $.ConstantAttribute[], + name: $c.Id, + type_: $t.Type, + loc: $c.Range, +): $.ConstantDecl => + Object.freeze({ + kind: "constant_decl", + attributes, + name, + type: type_, + loc, + }); +export const isConstantDecl = ($value: ConstantDecl) => + $value.kind === "constant_decl"; +export type TraitItem = $.TraitItem; +export type Trait = $.Trait; +export const Trait = ( + name: $c.TypeId, + traits: readonly $c.TypeId[], + attributes: readonly $.ContractAttribute[], + declarations: readonly $.TraitItem[], + loc: $c.Range, +): $.Trait => + Object.freeze({ + kind: "trait", + name, + traits, + attributes, + declarations, + loc, + }); +export const isTrait = ($value: Trait) => $value.kind === "trait"; +export type ModuleItem = $.ModuleItem; +export type Module = $.Module; +export const Module = ( + imports: readonly $.Import[], + items: readonly $.ModuleItem[], +): $.Module => + Object.freeze({ + kind: "module", + imports, + items, + }); +export const isModule = ($value: Module) => $value.kind === "module"; +export type Source = $.Source; +export const Source = ( + file: string | undefined, + contents: string, + root: $.Module, +): $.Source => + Object.freeze({ + file, + contents, + root, + }); diff --git a/src/next/ast/generated/statement.ts b/src/next/ast/generated/statement.ts new file mode 100644 index 0000000000..6a4d868319 --- /dev/null +++ b/src/next/ast/generated/statement.ts @@ -0,0 +1,248 @@ +/* eslint-disable @typescript-eslint/no-unnecessary-condition */ +import type * as $c from "@/next/ast/common"; +import type * as $e from "@/next/ast/expression"; +import type * as $t from "@/next/ast/type"; +import type * as $ from "@/next/ast/statement"; + +export type StatementLet = $.StatementLet; +export const StatementLet = ( + name: $c.OptionalId, + type_: $t.Type | undefined, + expression: $e.Expression, + loc: $c.Range, +): $.StatementLet => + Object.freeze({ + kind: "statement_let", + name, + type: type_, + expression, + loc, + }); +export const isStatementLet = ($value: StatementLet) => + $value.kind === "statement_let"; +export type StatementReturn = $.StatementReturn; +export const StatementReturn = ( + expression: $e.Expression | undefined, + loc: $c.Range, +): $.StatementReturn => + Object.freeze({ + kind: "statement_return", + expression, + loc, + }); +export const isStatementReturn = ($value: StatementReturn) => + $value.kind === "statement_return"; +export type StatementExpression = $.StatementExpression; +export const StatementExpression = ( + expression: $e.Expression, + loc: $c.Range, +): $.StatementExpression => + Object.freeze({ + kind: "statement_expression", + expression, + loc, + }); +export const isStatementExpression = ($value: StatementExpression) => + $value.kind === "statement_expression"; +export type StatementAssign = $.StatementAssign; +export const StatementAssign = ( + path: $e.Expression, + expression: $e.Expression, + loc: $c.Range, +): $.StatementAssign => + Object.freeze({ + kind: "statement_assign", + path, + expression, + loc, + }); +export const isStatementAssign = ($value: StatementAssign) => + $value.kind === "statement_assign"; +export type AugmentedAssignOperation = $.AugmentedAssignOperation; +export const allAugmentedAssignOperation: readonly $.AugmentedAssignOperation[] = + [ + "+=", + "-=", + "*=", + "/=", + "&&=", + "||=", + "%=", + "|=", + "<<=", + ">>=", + "&=", + "^=", + ]; +export type StatementAugmentedAssign = $.StatementAugmentedAssign; +export const StatementAugmentedAssign = ( + op: $.AugmentedAssignOperation, + path: $e.Expression, + expression: $e.Expression, + loc: $c.Range, +): $.StatementAugmentedAssign => + Object.freeze({ + kind: "statement_augmentedassign", + op, + path, + expression, + loc, + }); +export const isStatementAugmentedAssign = ($value: StatementAugmentedAssign) => + $value.kind === "statement_augmentedassign"; +export type StatementDestruct = $.StatementDestruct; +export const StatementDestruct = ( + type_: $c.TypeId, + identifiers: ReadonlyMap, + ignoreUnspecifiedFields: boolean, + expression: $e.Expression, + loc: $c.Range, +): $.StatementDestruct => + Object.freeze({ + kind: "statement_destruct", + type: type_, + identifiers, + ignoreUnspecifiedFields, + expression, + loc, + }); +export const isStatementDestruct = ($value: StatementDestruct) => + $value.kind === "statement_destruct"; +export type StatementBlock = $.StatementBlock; +export const StatementBlock = ( + statements: readonly $.Statement[], + loc: $c.Range, +): $.StatementBlock => + Object.freeze({ + kind: "statement_block", + statements, + loc, + }); +export const isStatementBlock = ($value: StatementBlock) => + $value.kind === "statement_block"; +export type StatementForEach = $.StatementForEach; +export const StatementForEach = ( + keyName: $c.OptionalId, + valueName: $c.OptionalId, + map: $e.Expression, + statements: readonly $.Statement[], + loc: $c.Range, +): $.StatementForEach => + Object.freeze({ + kind: "statement_foreach", + keyName, + valueName, + map, + statements, + loc, + }); +export const isStatementForEach = ($value: StatementForEach) => + $value.kind === "statement_foreach"; +export type CatchBlock = $.CatchBlock; +export const CatchBlock = ( + catchName: $c.OptionalId, + catchStatements: readonly $.Statement[], +): $.CatchBlock => + Object.freeze({ + catchName, + catchStatements, + }); +export type StatementTry = $.StatementTry; +export const StatementTry = ( + statements: readonly $.Statement[], + catchBlock: $.CatchBlock | undefined, + loc: $c.Range, +): $.StatementTry => + Object.freeze({ + kind: "statement_try", + statements, + catchBlock, + loc, + }); +export const isStatementTry = ($value: StatementTry) => + $value.kind === "statement_try"; +export type StatementRepeat = $.StatementRepeat; +export const StatementRepeat = ( + iterations: $e.Expression, + statements: readonly $.Statement[], + loc: $c.Range, +): $.StatementRepeat => + Object.freeze({ + kind: "statement_repeat", + iterations, + statements, + loc, + }); +export const isStatementRepeat = ($value: StatementRepeat) => + $value.kind === "statement_repeat"; +export type StatementUntil = $.StatementUntil; +export const StatementUntil = ( + condition: $e.Expression, + statements: readonly $.Statement[], + loc: $c.Range, +): $.StatementUntil => + Object.freeze({ + kind: "statement_until", + condition, + statements, + loc, + }); +export const isStatementUntil = ($value: StatementUntil) => + $value.kind === "statement_until"; +export type StatementWhile = $.StatementWhile; +export const StatementWhile = ( + condition: $e.Expression, + statements: readonly $.Statement[], + loc: $c.Range, +): $.StatementWhile => + Object.freeze({ + kind: "statement_while", + condition, + statements, + loc, + }); +export const isStatementWhile = ($value: StatementWhile) => + $value.kind === "statement_while"; +export type StatementCondition = $.StatementCondition; +export const StatementCondition = ( + condition: $e.Expression, + trueStatements: readonly $.Statement[], + falseStatements: readonly $.Statement[] | undefined, + loc: $c.Range, +): $.StatementCondition => + Object.freeze({ + kind: "statement_condition", + condition, + trueStatements, + falseStatements, + loc, + }); +export const isStatementCondition = ($value: StatementCondition) => + $value.kind === "statement_condition"; +export type Statement = $.Statement; +export type DestructMapping = $.DestructMapping; +export const DestructMapping = ( + field: $c.Id, + name: $c.Id, + loc: $c.Range, +): $.DestructMapping => + Object.freeze({ + kind: "destruct_mapping", + field, + name, + loc, + }); +export const isDestructMapping = ($value: DestructMapping) => + $value.kind === "destruct_mapping"; +export type DestructEnd = $.DestructEnd; +export const DestructEnd = ( + ignoreUnspecifiedFields: boolean, + loc: $c.Range, +): $.DestructEnd => + Object.freeze({ + kind: "destruct_end", + ignoreUnspecifiedFields, + loc, + }); +export const isDestructEnd = ($value: DestructEnd) => + $value.kind === "destruct_end"; diff --git a/src/next/ast/generated/type.ts b/src/next/ast/generated/type.ts new file mode 100644 index 0000000000..e9db39860a --- /dev/null +++ b/src/next/ast/generated/type.ts @@ -0,0 +1,103 @@ +/* eslint-disable @typescript-eslint/no-unnecessary-condition */ +import type * as $c from "@/next/ast/common"; +import type * as $ from "@/next/ast/type"; + +export type Signedness = $.Signedness; +export const allSignedness: readonly $.Signedness[] = ["signed", "unsigned"]; +export type IFInt = $.IFInt; +export const IFInt = (sign: $.Signedness, width: number, loc: $c.Range): $.IFInt => Object.freeze({ + kind: "FInt", + sign, + width, + loc +}); +export const isIFInt = ($value: IFInt) => $value.kind === "FInt"; +export type VarIntWidth = $.VarIntWidth; +export const allVarIntWidth: readonly $.VarIntWidth[] = ["16", "32"]; +export type IFVarInt = $.IFVarInt; +export const IFVarInt = (sign: $.Signedness, width: $.VarIntWidth, loc: $c.Range): $.IFVarInt => Object.freeze({ + kind: "FVarInt", + sign, + width, + loc +}); +export const isIFVarInt = ($value: IFVarInt) => $value.kind === "FVarInt"; +export type IntFormat = $.IntFormat; +export type TypeInt = $.TypeInt; +export const TypeInt = (format: $.IntFormat, loc: $c.Range): $.TypeInt => Object.freeze({ + kind: "TyInt", + format, + loc +}); +export const isTypeInt = ($value: TypeInt) => $value.kind === "TyInt"; +export type SFBits = $.SFBits; +export const SFBits = (bits: number, loc: $c.Range): $.SFBits => Object.freeze({ + kind: "SFBits", + bits, + loc +}); +export const isSFBits = ($value: SFBits) => $value.kind === "SFBits"; +export type SFRemaining = $.SFRemaining; +export const SFRemaining = (loc: $c.Range): $.SFRemaining => Object.freeze({ + kind: "SFRemaining", + loc +}); +export const isSFRemaining = ($value: SFRemaining) => $value.kind === "SFRemaining"; +export type SFDefault = $.SFDefault; +export const SFDefault = (loc: $c.Range): $.SFDefault => Object.freeze({ + kind: "SFDefault", + loc +}); +export const isSFDefault = ($value: SFDefault) => $value.kind === "SFDefault"; +export type SliceFormat = $.SliceFormat; +export type TypeSlice = $.TypeSlice; +export const TypeSlice = (format: $.SliceFormat, loc: $c.Range): $.TypeSlice => Object.freeze({ + kind: "TySlice", + format, + loc +}); +export const isTypeSlice = ($value: TypeSlice) => $value.kind === "TySlice"; +export type RemFormat = $.RemFormat; +export type TypeCell = $.TypeCell; +export const TypeCell = (format: $.RemFormat, loc: $c.Range): $.TypeCell => Object.freeze({ + kind: "TyCell", + format, + loc +}); +export const isTypeCell = ($value: TypeCell) => $value.kind === "TyCell"; +export type TypeBuilder = $.TypeBuilder; +export const TypeBuilder = (format: $.RemFormat, loc: $c.Range): $.TypeBuilder => Object.freeze({ + kind: "TyBuilder", + format, + loc +}); +export const isTypeBuilder = ($value: TypeBuilder) => $value.kind === "TyBuilder"; +export type TypeUnit = $.TypeUnit; +export const TypeUnit = (loc: $c.Range): $.TypeUnit => Object.freeze({ + kind: "unit_type", + loc +}); +export const isTypeUnit = ($value: TypeUnit) => $value.kind === "unit_type"; +export type TypeTensor = $.TypeTensor; +export const TypeTensor = (typeArgs: readonly $.Type[], loc: $c.Range): $.TypeTensor => Object.freeze({ + kind: "tensor_type", + typeArgs, + loc +}); +export const isTypeTensor = ($value: TypeTensor) => $value.kind === "tensor_type"; +export type TypeTuple = $.TypeTuple; +export const TypeTuple = (typeArgs: readonly $.Type[], loc: $c.Range): $.TypeTuple => Object.freeze({ + kind: "tuple_type", + typeArgs, + loc +}); +export const isTypeTuple = ($value: TypeTuple) => $value.kind === "tuple_type"; +export type TypeCons = $.TypeCons; +export const TypeCons = (name: $c.TypeId, typeArgs: readonly $.Type[], loc: $c.Range): $.TypeCons => Object.freeze({ + kind: "cons_type", + name, + typeArgs, + loc +}); +export const isTypeCons = ($value: TypeCons) => $value.kind === "cons_type"; +export type Type = $.Type; \ No newline at end of file diff --git a/src/next/ast/index.ts b/src/next/ast/index.ts new file mode 100644 index 0000000000..ba26755dcf --- /dev/null +++ b/src/next/ast/index.ts @@ -0,0 +1,5 @@ +export * from "@/next/ast/generated/common"; +export * from "@/next/ast/generated/expression"; +export * from "@/next/ast/generated/statement"; +export * from "@/next/ast/generated/type"; +export * from "@/next/ast/generated/root"; diff --git a/src/next/ast/root.ts b/src/next/ast/root.ts new file mode 100644 index 0000000000..a12ba26bda --- /dev/null +++ b/src/next/ast/root.ts @@ -0,0 +1,270 @@ +import type { + FuncId, + Id, + Range, + OptionalId, + TypeId, + RelativePath, + Language, +} from "@/next/ast/common"; +import type { Expression, Number, String } from "@/next/ast/expression"; +import type { Statement } from "@/next/ast/statement"; +import type { Type } from "@/next/ast/type"; + +export type Source = { + readonly file: string | undefined; + readonly contents: string; + readonly root: Module; +}; + +export type Module = { + readonly kind: "module"; + readonly imports: readonly Import[]; + readonly items: readonly ModuleItem[]; +}; + +export type Contract = { + readonly kind: "contract"; + readonly name: TypeId; + readonly traits: readonly TypeId[]; + readonly attributes: readonly ContractAttribute[]; + readonly params: undefined | readonly FieldDecl[]; + readonly declarations: readonly ContractItem[]; + readonly loc: Range; +}; + +export type Trait = { + readonly kind: "trait"; + readonly name: TypeId; + readonly traits: readonly TypeId[]; + readonly attributes: readonly ContractAttribute[]; + readonly declarations: readonly TraitItem[]; + readonly loc: Range; +}; + +export type ModuleItem = + | FunctionDef + | AsmFunctionDef + | NativeFunctionDecl + | ConstantDef + | StructDecl + | MessageDecl + | Contract + | Trait; + +export type ContractItem = + | FieldDecl + | FunctionDef + | AsmFunctionDef + | ContractInit + | Receiver + | ConstantDef; + +export type TraitItem = + | FieldDecl + | FunctionDef + | AsmFunctionDef + | FunctionDecl + | Receiver + | ConstantDef + | ConstantDecl; + +export type Import = { + readonly kind: "import"; + readonly importPath: ImportPath; + readonly loc: Range; +}; + +export type FunctionDef = { + readonly kind: "function_def"; + readonly attributes: readonly FunctionAttribute[]; + readonly name: Id; + readonly return: Type | undefined; + readonly params: readonly TypedParameter[]; + readonly statements: readonly Statement[]; + readonly loc: Range; +}; + +export type Receiver = { + readonly kind: "receiver"; + readonly selector: ReceiverKind; + readonly statements: readonly Statement[]; + readonly loc: Range; +}; + +export type ContractInit = { + readonly kind: "contract_init"; + readonly params: readonly TypedParameter[]; + readonly statements: readonly Statement[]; + readonly loc: Range; +}; + +export type AsmFunctionDef = { + readonly kind: "asm_function_def"; + readonly shuffle: AsmShuffle; + readonly attributes: readonly FunctionAttribute[]; + readonly name: Id; + readonly return: Type | undefined; + readonly params: readonly TypedParameter[]; + readonly instructions: readonly AsmInstruction[]; + readonly loc: Range; +}; + +export type AsmInstruction = string; +export type AsmShuffle = { + readonly args: readonly Id[]; + readonly ret: readonly Number[]; +}; + +export type FunctionDecl = { + readonly kind: "function_decl"; + readonly attributes: readonly FunctionAttribute[]; + readonly name: Id; + readonly return: Type | undefined; + readonly params: readonly TypedParameter[]; + readonly loc: Range; +}; + +export type NativeFunctionDecl = { + readonly kind: "native_function_decl"; + readonly attributes: readonly FunctionAttribute[]; + readonly name: Id; + readonly nativeName: FuncId; + readonly params: readonly TypedParameter[]; + readonly return: Type | undefined; + readonly loc: Range; +}; + +export type ConstantDef = { + readonly kind: "constant_def"; + readonly attributes: readonly ConstantAttribute[]; + readonly name: Id; + readonly type: Type; + readonly initializer: Expression; + readonly loc: Range; +}; + +export type ConstantDecl = { + readonly kind: "constant_decl"; + readonly attributes: readonly ConstantAttribute[]; + readonly name: Id; + readonly type: Type; + readonly loc: Range; +}; + +export type StructDecl = { + readonly kind: "struct_decl"; + readonly name: TypeId; + readonly fields: readonly FieldDecl[]; + readonly loc: Range; +}; + +export type MessageDecl = { + readonly kind: "message_decl"; + readonly name: TypeId; + readonly opcode: Expression | undefined; + readonly fields: readonly FieldDecl[]; + readonly loc: Range; +}; + +export type FieldDecl = { + readonly kind: "field_decl"; + readonly name: Id; + readonly type: Type; + readonly initializer: Expression | undefined; + // readonly as: Id | undefined; + readonly loc: Range; +}; + +// Reference to source file +export type ImportPath = { + readonly path: RelativePath; + readonly type: ImportType; + readonly language: Language; +}; + +// This is different from ItemOrigin, because relative import +// from standard library is still import with origin: "stdlib" +export type ImportType = "stdlib" | "relative"; + +export type ConstantAttributeName = "virtual" | "override" | "abstract"; + +export type ConstantAttribute = { + readonly type: ConstantAttributeName; + readonly loc: Range; +}; + +export type ContractAttribute = { + readonly type: "interface"; + readonly name: string; + readonly loc: Range; +}; + +export type FunctionAttributeGet = { + readonly kind: "function_attribute"; + readonly type: "get"; + readonly methodId: Expression | undefined; + readonly loc: Range; +}; + +export type FunctionAttributeName = + | "mutates" + | "extends" + | "virtual" + | "abstract" + | "override" + | "inline"; + +export type FunctionAttributeRest = { + readonly kind: "function_attribute"; + readonly type: FunctionAttributeName; + readonly loc: Range; +}; + +export type FunctionAttribute = FunctionAttributeGet | FunctionAttributeRest; + +export type TypedParameter = { + readonly kind: "typed_parameter"; + readonly name: OptionalId; + readonly type: Type; + readonly loc: Range; +}; + +export type ReceiverSimple = { + readonly kind: "simple"; + readonly param: TypedParameter; +}; + +export type ReceiverFallback = { + readonly kind: "fallback"; +}; + +export type ReceiverComment = { + readonly kind: "comment"; + readonly comment: String; +}; + +export type ReceiverSubKind = + | ReceiverSimple + | ReceiverFallback + | ReceiverComment; + +export type ReceiverInternal = { + readonly kind: "internal"; + readonly subKind: ReceiverSubKind; + readonly loc: Range; +}; + +export type ReceiverExternal = { + readonly kind: "external"; + readonly subKind: ReceiverSubKind; + readonly loc: Range; +}; + +export type ReceiverBounce = { + readonly kind: "bounce"; + readonly param: TypedParameter; + readonly loc: Range; +}; + +export type ReceiverKind = ReceiverInternal | ReceiverExternal | ReceiverBounce; diff --git a/src/next/ast/statement.ts b/src/next/ast/statement.ts new file mode 100644 index 0000000000..ef2c922d5b --- /dev/null +++ b/src/next/ast/statement.ts @@ -0,0 +1,146 @@ +import type { Id, Range, OptionalId, TypeId } from "@/next/ast/common"; +import type { Expression } from "@/next/ast/expression"; +import type { Type } from "@/next/ast/type"; + +export type Statement = + | StatementLet + | StatementReturn + | StatementExpression + | StatementAssign + | StatementAugmentedAssign + | StatementCondition + | StatementWhile + | StatementUntil + | StatementRepeat + | StatementTry + | StatementForEach + | StatementDestruct + | StatementBlock; + +export type StatementLet = { + readonly kind: "statement_let"; + readonly name: OptionalId; + readonly type: Type | undefined; + readonly expression: Expression; + readonly loc: Range; +}; + +export type StatementReturn = { + readonly kind: "statement_return"; + readonly expression: Expression | undefined; + readonly loc: Range; +}; + +export type StatementExpression = { + readonly kind: "statement_expression"; + readonly expression: Expression; + readonly loc: Range; +}; + +export type StatementAssign = { + readonly kind: "statement_assign"; + readonly path: Expression; // left-hand side of `=` + readonly expression: Expression; + readonly loc: Range; +}; + +export type AugmentedAssignOperation = + | "+=" + | "-=" + | "*=" + | "/=" + | "&&=" + | "||=" + | "%=" + | "|=" + | "<<=" + | ">>=" + | "&=" + | "^="; + +export type StatementAugmentedAssign = { + readonly kind: "statement_augmentedassign"; + readonly op: AugmentedAssignOperation; + readonly path: Expression; + readonly expression: Expression; + readonly loc: Range; +}; + +export type StatementCondition = { + readonly kind: "statement_condition"; + readonly condition: Expression; + readonly trueStatements: readonly Statement[]; + readonly falseStatements: readonly Statement[] | undefined; + readonly loc: Range; +}; + +export type StatementWhile = { + readonly kind: "statement_while"; + readonly condition: Expression; + readonly statements: readonly Statement[]; + readonly loc: Range; +}; + +export type StatementUntil = { + readonly kind: "statement_until"; + readonly condition: Expression; + readonly statements: readonly Statement[]; + readonly loc: Range; +}; + +export type StatementRepeat = { + readonly kind: "statement_repeat"; + readonly iterations: Expression; + readonly statements: readonly Statement[]; + readonly loc: Range; +}; + +export type StatementTry = { + readonly kind: "statement_try"; + readonly statements: readonly Statement[]; + readonly catchBlock: CatchBlock | undefined; + readonly loc: Range; +}; + +export type CatchBlock = { + readonly catchName: OptionalId; + readonly catchStatements: readonly Statement[]; +}; + +export type StatementForEach = { + readonly kind: "statement_foreach"; + readonly keyName: OptionalId; + readonly valueName: OptionalId; + readonly map: Expression; + readonly statements: readonly Statement[]; + readonly loc: Range; +}; + +export type StatementDestruct = { + readonly kind: "statement_destruct"; + readonly type: TypeId; + /** field name -> [field id, local id] */ + readonly identifiers: ReadonlyMap; + readonly ignoreUnspecifiedFields: boolean; + readonly expression: Expression; + readonly loc: Range; +}; + +export type StatementBlock = { + readonly kind: "statement_block"; + readonly statements: readonly Statement[]; + readonly loc: Range; +}; + +export type DestructMapping = { + readonly kind: "destruct_mapping"; + readonly field: Id; + readonly name: Id; + readonly loc: Range; +}; + +export type DestructEnd = { + readonly kind: "destruct_end"; + readonly ignoreUnspecifiedFields: boolean; + readonly loc: Range; +}; diff --git a/src/next/ast/type.ts b/src/next/ast/type.ts new file mode 100644 index 0000000000..177c118e22 --- /dev/null +++ b/src/next/ast/type.ts @@ -0,0 +1,89 @@ +import type { Range, TypeId } from "@/next/ast/common"; + +export type Type = + | TypeCons + | TypeInt + | TypeSlice + | TypeCell + | TypeBuilder + | TypeTuple + | TypeUnit + | TypeTensor; + +export type TypeCons = { + readonly kind: "cons_type"; + readonly name: TypeId; + readonly typeArgs: readonly Type[]; + readonly loc: Range; +}; + +export type TypeInt = { + readonly kind: "TyInt"; + readonly format: IntFormat; + readonly loc: Range; +}; +export type IntFormat = IFInt | IFVarInt; +export type IFInt = { + readonly kind: "FInt"; + readonly sign: Signedness; + readonly width: number; + readonly loc: Range; +}; +export type IFVarInt = { + readonly kind: "FVarInt"; + readonly sign: Signedness; + readonly width: VarIntWidth; + readonly loc: Range; +}; +export type VarIntWidth = "16" | "32"; +export type Signedness = "signed" | "unsigned"; + +export type TypeSlice = { + readonly kind: "TySlice"; + readonly format: SliceFormat; + readonly loc: Range; +}; +export type SliceFormat = SFBits | SFRemaining | SFDefault; +export type SFBits = { + readonly kind: "SFBits"; + readonly bits: number; + readonly loc: Range; +}; +export type SFRemaining = { + readonly kind: "SFRemaining"; + readonly loc: Range; +}; +export type SFDefault = { + readonly kind: "SFDefault"; + readonly loc: Range; +}; + +export type TypeCell = { + readonly kind: "TyCell"; + readonly format: RemFormat; + readonly loc: Range; +}; +export type TypeBuilder = { + readonly kind: "TyBuilder"; + readonly format: RemFormat; + readonly loc: Range; +}; +export type RemFormat = SFRemaining | SFDefault; + +export type TypeTuple = { + readonly kind: "tuple_type"; + readonly typeArgs: readonly Type[]; + readonly loc: Range; +}; + +export type TypeUnit = { + readonly kind: "unit_type"; + readonly loc: Range; +}; + +export type TypeTensor = { + readonly kind: "tensor_type"; + readonly typeArgs: readonly Type[]; + readonly loc: Range; +}; + diff --git a/src/next/grammar/gen.sh b/src/next/grammar/gen.sh new file mode 100755 index 0000000000..b7bcda7f65 --- /dev/null +++ b/src/next/grammar/gen.sh @@ -0,0 +1 @@ +pgen src/next/grammar/grammar.gg -o src/next/grammar/grammar.ts diff --git a/src/next/grammar/grammar.gg b/src/next/grammar/grammar.gg new file mode 100644 index 0000000000..b31b4b92f0 --- /dev/null +++ b/src/next/grammar/grammar.gg @@ -0,0 +1,362 @@ +Module = + imports:Import* + items:moduleItem*; + +Import = + keyword<"import"> + path:StringLiteral + ";"; + +moduleItem + = PrimitiveTypeDecl + / Function + / AsmFunction + / NativeFunctionDecl + / Constant + / StructDecl + / MessageDecl + / Contract + / Trait; + +contractItemDecl + = ContractInit + / Receiver + / Function + / AsmFunction + / Constant + / storageVar; + +traitItemDecl + = Receiver + / Function + / AsmFunction + / Constant + / storageVar; + +PrimitiveTypeDecl = + keyword<"primitive"> + name:TypeId + ";"; + +Function = + attributes:FunctionAttribute* + keyword<"fun"> + name:Id + parameters:parameterList + returnType:ascription? + body:(FunctionDefinition / FunctionDeclaration); + +FunctionDefinition = body:statements; + +FunctionDeclaration = semicolon; + +AsmFunction = + "asm" + shuffle:shuffle? + attributes:FunctionAttribute* + keyword<"fun"> + name:Id + parameters:parameterList + returnType:ascription? + "{" + instructions:assembly + "}"; + +shuffle = "(" ids:Id* to:("->" @IntegerLiteralDec+)? ")"; + +NativeFunctionDecl = + "@name" "(" + nativeName:#FuncId + ")" + attributes:FunctionAttribute* + keyword<"native"> + name:Id + parameters:parameterList + returnType:ascription? + ";"; + +Constant = + attributes:ConstantAttribute* + keyword<"const"> + name:Id + type:ascription + body:(ConstantDefinition / ConstantDeclaration); + +ConstantAttribute = name:( + keyword<"virtual"> + / keyword<"override"> + / keyword<"abstract"> +); + +ConstantDefinition = "=" expression:expression semicolon; + +ConstantDeclaration = semicolon; + +storageVar = @FieldDecl semicolon; + +StructDecl = + "struct" + name:TypeId + "{" + fields:structFields + "}"; + +MessageDecl = + "message" + opcode:("(" @expression ")")? + name:TypeId + "{" + fields:structFields + "}"; + +structFields = @inter? ";"?; + +FieldDecl = + name:Id + type:ascription + expression:("=" @expression)?; + +Contract = + attributes:ContractAttribute* + keyword<"contract"> + name:TypeId + parameters:ParameterList? + traits:inheritedTraits? + "{" + declarations:contractItemDecl* + "}"; + +Trait = + attributes:ContractAttribute* + keyword<"trait"> + name:TypeId + traits:inheritedTraits? + "{" + declarations:traitItemDecl* + "}"; + +inheritedTraits = keyword<"with"> @commaList; + +ContractInit = + "init" + parameters:parameterList + body:statements; + +ContractAttribute = "@interface" "(" name:StringLiteral ")"; + +// 'get' cannot be a reserved word because there is the map '.get' method +FunctionAttribute = name:( + GetAttribute + / keyword<"mutates"> + / keyword<"extends"> + / keyword<"virtual"> + / keyword<"override"> + / keyword<"inline"> + / keyword<"abstract"> +); + +GetAttribute = "get" methodId:("(" @expression ")")?; + +Receiver = type:ReceiverType "(" param:receiverParam ")" body:statements; +// "bounced" cannot be a reserved word because there a 'bounced' field in stdlib's 'Context' structure +ReceiverType = name:("bounced" / keyword<"receive"> / keyword<"external">); +receiverParam = @(Parameter / StringLiteral)?; + +assembly = #$assemblySequence; +assemblySequence = assemblyItem*; +assemblyItem + = "{" assemblySequence "}" + / comment + / "\"" [^"]* "\"" + / (!(["{}] / "//" / "/*") .)+; + +ascription = ":" @type; + +type = TypeAs; +TypeAs = type:TypeOptional as:(keyword<"as"> @#storage)*; +TypeOptional = type:typePrimary optionals:Optional*; +Optional = "?"; + +typePrimary = TypeGeneric / TypeRegular / TypeTuple / TypeTensor / TypeUnit / typeParens; +TypeRegular = child:TypeId; +TypeGeneric = name:(MapKeyword / Bounced / TypeId) "<" args:commaList ">"; +TypeTuple = "[" types:commaList? "]"; +TypeTensor = "(" head:type tail:("," @type)+ ","? ")"; +TypeUnit = "(" ")"; +typeParens = "(" @type ")"; +MapKeyword = keyword<"map">; +Bounced = "bounced"; + +storage + = IntStorage + / CoinsStorage + / RemainingStorage + / BytesStorage; +IntStorage = + isVar:"var"? + isUnsigned: "u"? + "int" + width:$(digit+); +CoinsStorage = "coins"; +RemainingStorage = "remaining"; +BytesStorage = "bytes" width:$(digit+); + +TypeId "capitalized identifier" = name:#$([A-Z] [a-zA-Z0-9_]*); + +statement + = StatementLet + / StatementDestruct + / StatementBlock + / StatementReturn + / StatementCondition + / StatementWhile + / StatementRepeat + / StatementUntil + / StatementTry + / StatementForEach + / StatementExpression + / StatementAssign; + +statements = "{" @statement* "}"; + +StatementLet = keyword<"let"> name:Id type:ascription? "=" init:expression semicolon; +StatementDestruct = keyword<"let"> type:TypeId "{" fields:inter rest:optionalRest "}" "=" init:expression semicolon; +StatementBlock = body:statements; +StatementReturn = keyword<"return"> expression:expression? semicolon; +StatementExpression = expression:expression semicolon; +StatementAssign = left:expression operator:(augmentedOp / "=") right:expression semicolon; +StatementCondition = keyword<"if"> condition:expression trueBranch:statements falseBranch:(keyword<"else"> @(FalseBranch / StatementCondition))?; +StatementWhile = keyword<"while"> condition:parens body:statements; +StatementRepeat = keyword<"repeat"> condition:parens body:statements; +StatementUntil = keyword<"do"> body:statements keyword<"until"> condition:parens semicolon; +StatementTry = keyword<"try"> body:statements handler:(keyword<"catch"> "(" name:Id ")" body:statements)?; +StatementForEach = keyword<"foreach"> "(" key:Id "," value:Id "in" expression:expression ")" body:statements; + +augmentedOp = "||=" / "&&=" / ">>=" / "<<=" / "-=" / "+=" / "*=" / "/=" / "%=" / "|=" / "&=" / "^="; +FalseBranch = body:statements; +semicolon = ";" / &"}"; + +destructItem = RegularField / PunnedField; +RegularField = fieldName:Id ":" varName:Id; +PunnedField = name:Id; + +optionalRest = "," @RestArgument / NoRestArgument; +RestArgument = ".."; +NoRestArgument = ","?; + +expression = Conditional; + +Conditional = head:or tail:("?" thenBranch:or ":" elseBranch:Conditional)?; + +or = Binary; +and = Binary; +bitwiseOr = Binary; +bitwiseXor = Binary; +bitwiseAnd = Binary; +equality = Binary=" / ">")>; +bitwiseShift = Binary>")>; +add = Binary; +mul = Binary; + +Unary = prefixes:Operator<[-+!~]>* expression:Suffix; +Suffix = expression:primary suffixes:suffix*; + +Binary = exprs:inter>; +Operator = name:U; + +suffix + = SuffixUnboxNotNull + / SuffixCall + / SuffixFieldAccess; + +SuffixUnboxNotNull = "!!"; +SuffixCall = params:parameterList; +SuffixFieldAccess = "." name:Id; + +// Order is important +primary + = Parens + / StructInstance + / IntegerLiteral + / BoolLiteral + / InitOf + / CodeOf + / Null + / StringLiteral + / Id; + +Null = keyword<"null">; + +parens = "(" @expression ")"; +Parens = child:parens; + +StructInstance = type:TypeId "{" fields:commaList? "}"; +InitOf = keyword<"initOf"> name:TypeId params:parameterList; +CodeOf = "codeOf" name:TypeId; + +StructFieldInitializer = name:Id init:(":" @expression)?; + +ParameterList = "(" values:commaList? ")"; +parameterList = "(" @commaList? ")"; +Parameter = name:Id type:ascription; + +commaList = @inter ","?; + +// order is important +IntegerLiteral = value:(IntegerLiteralHex / IntegerLiteralBin / IntegerLiteralOct / IntegerLiteralDec); + +IntegerLiteralDec = digits:#underscored; +IntegerLiteralHex = digits:#("0" [xX] @underscored); +IntegerLiteralBin = digits:#("0" [bB] @underscored<[01]>); +IntegerLiteralOct = digits:#("0" [oO] @underscored<[0-7]>); +underscored = $(T ("_"? T)*); +digit "digit" = [0-9]; + +idPart "identifier character" = [a-zA-Z0-9_]; +Id "identifier" = name:#$(!reservedWord [a-zA-Z_] idPart*); + +// FunC identifiers, where `FuncId` stands for FunC function identifier +// A plain identifier cannot be a number, a single underscore, an operator, a keyword or a compiler directive +// See: https://github.com/ton-blockchain/ton/blob/master/crypto/func/keywords.cpp + +FuncId "FunC identifier" = accessor:[.~]? id:$("`" [^`\r\n]+ "`" / [^ \t\r\n()[\],.;~]+); + +// Boolean literals +BoolLiteral = value:("true" / "false") !idPart; + +// String literals +StringLiteral = value:#("\"" @$([^"\\] / "\\" @escapeChar)* "\""); + +escapeChar + = [\\"nrtvbf] + / "u{" @$(hexDigit hexDigit? hexDigit? hexDigit? hexDigit? hexDigit?) "}" + / "u" @$(hexDigit hexDigit hexDigit hexDigit) + / "x" @$(hexDigit hexDigit); + +hexDigit "hexadecimal digit" = [0-9a-fA-F]; + +keyword = #(@T !idPart); + +// Order is important +reservedWord "reserved word" = keyword<( + // extend and public are reserved for legacy reasons + "extend" / "public" / + + "fun" / "let" / "return" / "receive" / "native" / "primitive" / "null" / + "if" / "else" / "while" / "repeat" / "do" / "until" / "try" / "catch" / + "foreach" / "as" / "map" / "mutates" / "extends" / "external" / "import" / + "with" / "trait" / "initOf" / "override" / "abstract" / "virtual" / + "inline" / "const" +)>; + +space "space" = [ \t\r\n] / comment; +comment = multiLineComment / singleLineComment; +multiLineComment = "/*" @$(!"*/" .)* "*/"; +singleLineComment = "//" @$[^\r\n]*; + +// This is not used in the Tact grammar but +// it is useful for imports resolution +JustImports = imports:Import* .*; + +inter = head:A tail:(op:B right:A)*; diff --git a/src/next/grammar/grammar.ts b/src/next/grammar/grammar.ts new file mode 100644 index 0000000000..68dc6a44d9 --- /dev/null +++ b/src/next/grammar/grammar.ts @@ -0,0 +1,2608 @@ +/* Generated. Do not edit. */ +/* eslint-disable @typescript-eslint/no-namespace */ +/* eslint-disable @typescript-eslint/ban-types */ +/* eslint-disable @typescript-eslint/no-redundant-type-constituents */ +/* eslint-disable @typescript-eslint/no-duplicate-type-constituents */ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import * as $ from "@tonstudio/parser-runtime"; +export namespace $ast { + export type Module = $.Located<{ + readonly $: "Module"; + readonly imports: readonly Import[]; + readonly items: readonly moduleItem[]; + }>; + export type Import = $.Located<{ + readonly $: "Import"; + readonly path: StringLiteral; + }>; + export type PrimitiveTypeDecl = $.Located<{ + readonly $: "PrimitiveTypeDecl"; + readonly name: TypeId; + }>; + export type $Function = $.Located<{ + readonly $: "Function"; + readonly attributes: readonly FunctionAttribute[]; + readonly name: Id; + readonly parameters: parameterList; + readonly returnType: ascription | undefined; + readonly body: FunctionDefinition | FunctionDeclaration; + }>; + export type AsmFunction = $.Located<{ + readonly $: "AsmFunction"; + readonly shuffle: shuffle | undefined; + readonly attributes: readonly FunctionAttribute[]; + readonly name: Id; + readonly parameters: parameterList; + readonly returnType: ascription | undefined; + readonly instructions: assembly; + }>; + export type NativeFunctionDecl = $.Located<{ + readonly $: "NativeFunctionDecl"; + readonly nativeName: FuncId; + readonly attributes: readonly FunctionAttribute[]; + readonly name: Id; + readonly parameters: parameterList; + readonly returnType: ascription | undefined; + }>; + export type Constant = $.Located<{ + readonly $: "Constant"; + readonly attributes: readonly ConstantAttribute[]; + readonly name: Id; + readonly type: ascription; + readonly body: ConstantDefinition | ConstantDeclaration; + }>; + export type StructDecl = $.Located<{ + readonly $: "StructDecl"; + readonly name: TypeId; + readonly fields: structFields; + }>; + export type MessageDecl = $.Located<{ + readonly $: "MessageDecl"; + readonly opcode: expression | undefined; + readonly name: TypeId; + readonly fields: structFields; + }>; + export type Contract = $.Located<{ + readonly $: "Contract"; + readonly attributes: readonly ContractAttribute[]; + readonly name: TypeId; + readonly parameters: ParameterList | undefined; + readonly traits: inheritedTraits | undefined; + readonly declarations: readonly contractItemDecl[]; + }>; + export type Trait = $.Located<{ + readonly $: "Trait"; + readonly attributes: readonly ContractAttribute[]; + readonly name: TypeId; + readonly traits: inheritedTraits | undefined; + readonly declarations: readonly traitItemDecl[]; + }>; + export type moduleItem = + | PrimitiveTypeDecl + | $Function + | AsmFunction + | NativeFunctionDecl + | Constant + | StructDecl + | MessageDecl + | Contract + | Trait; + export type ContractInit = $.Located<{ + readonly $: "ContractInit"; + readonly parameters: parameterList; + readonly body: statements; + }>; + export type Receiver = $.Located<{ + readonly $: "Receiver"; + readonly type: ReceiverType; + readonly param: receiverParam; + readonly body: statements; + }>; + export type FieldDecl = $.Located<{ + readonly $: "FieldDecl"; + readonly name: Id; + readonly type: ascription; + readonly expression: expression | undefined; + }>; + export type semicolon = ";" | "}"; + export type storageVar = FieldDecl; + export type contractItemDecl = + | ContractInit + | Receiver + | $Function + | AsmFunction + | Constant + | storageVar; + export type traitItemDecl = + | Receiver + | $Function + | AsmFunction + | Constant + | storageVar; + export type FunctionDefinition = $.Located<{ + readonly $: "FunctionDefinition"; + readonly body: statements; + }>; + export type FunctionDeclaration = $.Located<{ + readonly $: "FunctionDeclaration"; + }>; + export type Id = $.Located<{ + readonly $: "Id"; + readonly name: string; + }>; + export type IntegerLiteralDec = $.Located<{ + readonly $: "IntegerLiteralDec"; + readonly digits: underscored; + }>; + export type shuffle = { + readonly ids: readonly Id[]; + readonly to: readonly IntegerLiteralDec[] | undefined; + }; + export type ConstantAttribute = $.Located<{ + readonly $: "ConstantAttribute"; + readonly name: + | keyword<"virtual"> + | keyword<"override"> + | keyword<"abstract">; + }>; + export type ConstantDefinition = $.Located<{ + readonly $: "ConstantDefinition"; + readonly expression: expression; + }>; + export type ConstantDeclaration = $.Located<{ + readonly $: "ConstantDeclaration"; + }>; + export type inter = { + readonly head: A; + readonly tail: readonly { + readonly op: B; + readonly right: A; + }[]; + }; + export type structFields = inter | undefined; + export type keyword = T; + export type commaList = inter; + export type TypeId = $.Located<{ + readonly $: "TypeId"; + readonly name: string; + }>; + export type inheritedTraits = commaList; + export type ContractAttribute = $.Located<{ + readonly $: "ContractAttribute"; + readonly name: StringLiteral; + }>; + export type FunctionAttribute = $.Located<{ + readonly $: "FunctionAttribute"; + readonly name: + | GetAttribute + | keyword<"mutates"> + | keyword<"extends"> + | keyword<"virtual"> + | keyword<"override"> + | keyword<"inline"> + | keyword<"abstract">; + }>; + export type GetAttribute = $.Located<{ + readonly $: "GetAttribute"; + readonly methodId: expression | undefined; + }>; + export type ReceiverType = $.Located<{ + readonly $: "ReceiverType"; + readonly name: "bounced" | keyword<"receive"> | keyword<"external">; + }>; + export type Parameter = $.Located<{ + readonly $: "Parameter"; + readonly name: Id; + readonly type: ascription; + }>; + export type StringLiteral = $.Located<{ + readonly $: "StringLiteral"; + readonly value: string; + }>; + export type receiverParam = Parameter | StringLiteral | undefined; + export type assembly = string; + export type multiLineComment = string; + export type singleLineComment = string; + export type comment = multiLineComment | singleLineComment; + export type assemblyItem = {} | comment | {} | readonly {}[]; + export type assemblySequence = readonly assemblyItem[]; + export type TypeAs = $.Located<{ + readonly $: "TypeAs"; + readonly type: TypeOptional; + readonly as: readonly storage[]; + }>; + export type $type = TypeAs; + export type ascription = $type; + export type TypeOptional = $.Located<{ + readonly $: "TypeOptional"; + readonly type: typePrimary; + readonly optionals: readonly Optional[]; + }>; + export type Optional = $.Located<{ + readonly $: "Optional"; + }>; + export type TypeGeneric = $.Located<{ + readonly $: "TypeGeneric"; + readonly name: MapKeyword | Bounced | TypeId; + readonly args: commaList<$type>; + }>; + export type TypeRegular = $.Located<{ + readonly $: "TypeRegular"; + readonly child: TypeId; + }>; + export type TypeTuple = $.Located<{ + readonly $: "TypeTuple"; + readonly types: commaList<$type> | undefined; + }>; + export type TypeTensor = $.Located<{ + readonly $: "TypeTensor"; + readonly head: $type; + readonly tail: readonly $type[]; + }>; + export type TypeUnit = $.Located<{ + readonly $: "TypeUnit"; + }>; + export type typeParens = $type; + export type typePrimary = + | TypeGeneric + | TypeRegular + | TypeTuple + | TypeTensor + | TypeUnit + | typeParens; + export type MapKeyword = $.Located<{ + readonly $: "MapKeyword"; + }>; + export type Bounced = $.Located<{ + readonly $: "Bounced"; + }>; + export type IntStorage = $.Located<{ + readonly $: "IntStorage"; + readonly isVar: "var" | undefined; + readonly isUnsigned: "u" | undefined; + readonly width: string; + }>; + export type CoinsStorage = $.Located<{ + readonly $: "CoinsStorage"; + }>; + export type RemainingStorage = $.Located<{ + readonly $: "RemainingStorage"; + }>; + export type BytesStorage = $.Located<{ + readonly $: "BytesStorage"; + readonly width: string; + }>; + export type storage = + | IntStorage + | CoinsStorage + | RemainingStorage + | BytesStorage; + export type StatementLet = $.Located<{ + readonly $: "StatementLet"; + readonly name: Id; + readonly type: ascription | undefined; + readonly init: expression; + }>; + export type StatementDestruct = $.Located<{ + readonly $: "StatementDestruct"; + readonly type: TypeId; + readonly fields: inter; + readonly rest: optionalRest; + readonly init: expression; + }>; + export type StatementBlock = $.Located<{ + readonly $: "StatementBlock"; + readonly body: statements; + }>; + export type StatementReturn = $.Located<{ + readonly $: "StatementReturn"; + readonly expression: expression | undefined; + }>; + export type StatementCondition = $.Located<{ + readonly $: "StatementCondition"; + readonly condition: expression; + readonly trueBranch: statements; + readonly falseBranch: FalseBranch | StatementCondition | undefined; + }>; + export type StatementWhile = $.Located<{ + readonly $: "StatementWhile"; + readonly condition: parens; + readonly body: statements; + }>; + export type StatementRepeat = $.Located<{ + readonly $: "StatementRepeat"; + readonly condition: parens; + readonly body: statements; + }>; + export type StatementUntil = $.Located<{ + readonly $: "StatementUntil"; + readonly body: statements; + readonly condition: parens; + }>; + export type StatementTry = $.Located<{ + readonly $: "StatementTry"; + readonly body: statements; + readonly handler: + | { + readonly name: Id; + readonly body: statements; + } + | undefined; + }>; + export type StatementForEach = $.Located<{ + readonly $: "StatementForEach"; + readonly key: Id; + readonly value: Id; + readonly expression: expression; + readonly body: statements; + }>; + export type StatementExpression = $.Located<{ + readonly $: "StatementExpression"; + readonly expression: expression; + }>; + export type StatementAssign = $.Located<{ + readonly $: "StatementAssign"; + readonly left: expression; + readonly operator: augmentedOp | "="; + readonly right: expression; + }>; + export type statement = + | StatementLet + | StatementDestruct + | StatementBlock + | StatementReturn + | StatementCondition + | StatementWhile + | StatementRepeat + | StatementUntil + | StatementTry + | StatementForEach + | StatementExpression + | StatementAssign; + export type statements = readonly statement[]; + export type augmentedOp = + | "||=" + | "&&=" + | ">>=" + | "<<=" + | "-=" + | "+=" + | "*=" + | "/=" + | "%=" + | "|=" + | "&=" + | "^="; + export type FalseBranch = $.Located<{ + readonly $: "FalseBranch"; + readonly body: statements; + }>; + export type RegularField = $.Located<{ + readonly $: "RegularField"; + readonly fieldName: Id; + readonly varName: Id; + }>; + export type PunnedField = $.Located<{ + readonly $: "PunnedField"; + readonly name: Id; + }>; + export type destructItem = RegularField | PunnedField; + export type RestArgument = $.Located<{ + readonly $: "RestArgument"; + }>; + export type NoRestArgument = $.Located<{ + readonly $: "NoRestArgument"; + }>; + export type optionalRest = RestArgument | NoRestArgument; + export type Conditional = $.Located<{ + readonly $: "Conditional"; + readonly head: or; + readonly tail: + | { + readonly thenBranch: or; + readonly elseBranch: Conditional; + } + | undefined; + }>; + export type expression = Conditional; + export type Binary = $.Located<{ + readonly $: "Binary"; + readonly exprs: inter>; + }>; + export type Unary = $.Located<{ + readonly $: "Unary"; + readonly prefixes: readonly Operator<"-" | "+" | "!" | "~">[]; + readonly expression: Suffix; + }>; + export type mul = Binary; + export type add = Binary; + export type bitwiseShift = Binary>">; + export type compare = Binary=" | ">">; + export type equality = Binary; + export type bitwiseXor = Binary; + export type bitwiseOr = Binary; + export type and = Binary; + export type or = Binary; + export type Suffix = $.Located<{ + readonly $: "Suffix"; + readonly expression: primary; + readonly suffixes: readonly suffix[]; + }>; + export type Operator = $.Located<{ + readonly $: "Operator"; + readonly name: U; + }>; + export type SuffixUnboxNotNull = $.Located<{ + readonly $: "SuffixUnboxNotNull"; + }>; + export type SuffixCall = $.Located<{ + readonly $: "SuffixCall"; + readonly params: parameterList; + }>; + export type SuffixFieldAccess = $.Located<{ + readonly $: "SuffixFieldAccess"; + readonly name: Id; + }>; + export type suffix = SuffixUnboxNotNull | SuffixCall | SuffixFieldAccess; + export type Parens = $.Located<{ + readonly $: "Parens"; + readonly child: parens; + }>; + export type StructInstance = $.Located<{ + readonly $: "StructInstance"; + readonly type: TypeId; + readonly fields: commaList | undefined; + }>; + export type IntegerLiteral = $.Located<{ + readonly $: "IntegerLiteral"; + readonly value: + | IntegerLiteralHex + | IntegerLiteralBin + | IntegerLiteralOct + | IntegerLiteralDec; + }>; + export type BoolLiteral = $.Located<{ + readonly $: "BoolLiteral"; + readonly value: "true" | "false"; + }>; + export type InitOf = $.Located<{ + readonly $: "InitOf"; + readonly name: TypeId; + readonly params: parameterList; + }>; + export type CodeOf = $.Located<{ + readonly $: "CodeOf"; + readonly name: TypeId; + }>; + export type Null = $.Located<{ + readonly $: "Null"; + }>; + export type primary = + | Parens + | StructInstance + | IntegerLiteral + | BoolLiteral + | InitOf + | CodeOf + | Null + | StringLiteral + | Id; + export type parens = expression; + export type StructFieldInitializer = $.Located<{ + readonly $: "StructFieldInitializer"; + readonly name: Id; + readonly init: expression | undefined; + }>; + export type ParameterList = $.Located<{ + readonly $: "ParameterList"; + readonly values: commaList | undefined; + }>; + export type parameterList = commaList | undefined; + export type IntegerLiteralHex = $.Located<{ + readonly $: "IntegerLiteralHex"; + readonly digits: underscored; + }>; + export type IntegerLiteralBin = $.Located<{ + readonly $: "IntegerLiteralBin"; + readonly digits: underscored<"0" | "1">; + }>; + export type IntegerLiteralOct = $.Located<{ + readonly $: "IntegerLiteralOct"; + readonly digits: underscored; + }>; + export type underscored = string; + export type digit = string; + export type idPart = string | string | string | "_"; + export type FuncId = $.Located<{ + readonly $: "FuncId"; + readonly accessor: "." | "~" | undefined; + readonly id: string; + }>; + export type hexDigit = string | string | string; + export type escapeChar = + | "\\" + | '"' + | "n" + | "r" + | "t" + | "v" + | "b" + | "f" + | string + | string + | string; + export type reservedWord = keyword< + | "extend" + | "public" + | "fun" + | "let" + | "return" + | "receive" + | "native" + | "primitive" + | "null" + | "if" + | "else" + | "while" + | "repeat" + | "do" + | "until" + | "try" + | "catch" + | "foreach" + | "as" + | "map" + | "mutates" + | "extends" + | "external" + | "import" + | "with" + | "trait" + | "initOf" + | "override" + | "abstract" + | "virtual" + | "inline" + | "const" + >; + export type space = " " | "\t" | "\r" | "\n" | comment; + export type JustImports = $.Located<{ + readonly $: "JustImports"; + readonly imports: readonly Import[]; + }>; +} +export const Module: $.Parser<$ast.Module> = $.loc( + $.field( + $.pure("Module"), + "$", + $.field( + $.star($.lazy(() => Import)), + "imports", + $.field($.star($.lazy(() => moduleItem)), "items", $.eps), + ), + ), +); +export const Import: $.Parser<$ast.Import> = $.loc( + $.field( + $.pure("Import"), + "$", + $.right( + $.lazy(() => keyword($.str("import"))), + $.field( + $.lazy(() => StringLiteral), + "path", + $.right($.str(";"), $.eps), + ), + ), + ), +); +export const PrimitiveTypeDecl: $.Parser<$ast.PrimitiveTypeDecl> = $.loc( + $.field( + $.pure("PrimitiveTypeDecl"), + "$", + $.right( + $.lazy(() => keyword($.str("primitive"))), + $.field( + $.lazy(() => TypeId), + "name", + $.right($.str(";"), $.eps), + ), + ), + ), +); +export const $Function: $.Parser<$ast.$Function> = $.loc( + $.field( + $.pure("Function"), + "$", + $.field( + $.star($.lazy(() => FunctionAttribute)), + "attributes", + $.right( + $.lazy(() => keyword($.str("fun"))), + $.field( + $.lazy(() => Id), + "name", + $.field( + $.lazy(() => parameterList($.lazy(() => Parameter))), + "parameters", + $.field( + $.opt($.lazy(() => ascription)), + "returnType", + $.field( + $.alt( + $.lazy(() => FunctionDefinition), + $.lazy(() => FunctionDeclaration), + ), + "body", + $.eps, + ), + ), + ), + ), + ), + ), + ), +); +export const AsmFunction: $.Parser<$ast.AsmFunction> = $.loc( + $.field( + $.pure("AsmFunction"), + "$", + $.right( + $.str("asm"), + $.field( + $.opt($.lazy(() => shuffle)), + "shuffle", + $.field( + $.star($.lazy(() => FunctionAttribute)), + "attributes", + $.right( + $.lazy(() => keyword($.str("fun"))), + $.field( + $.lazy(() => Id), + "name", + $.field( + $.lazy(() => + parameterList($.lazy(() => Parameter)), + ), + "parameters", + $.field( + $.opt($.lazy(() => ascription)), + "returnType", + $.right( + $.str("{"), + $.field( + $.lazy(() => assembly), + "instructions", + $.right($.str("}"), $.eps), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), +); +export const NativeFunctionDecl: $.Parser<$ast.NativeFunctionDecl> = $.loc( + $.field( + $.pure("NativeFunctionDecl"), + "$", + $.right( + $.str("@name"), + $.right( + $.str("("), + $.field( + $.lex($.lazy(() => FuncId)), + "nativeName", + $.right( + $.str(")"), + $.field( + $.star($.lazy(() => FunctionAttribute)), + "attributes", + $.right( + $.lazy(() => keyword($.str("native"))), + $.field( + $.lazy(() => Id), + "name", + $.field( + $.lazy(() => + parameterList( + $.lazy(() => Parameter), + ), + ), + "parameters", + $.field( + $.opt($.lazy(() => ascription)), + "returnType", + $.right($.str(";"), $.eps), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), +); +export const Constant: $.Parser<$ast.Constant> = $.loc( + $.field( + $.pure("Constant"), + "$", + $.field( + $.star($.lazy(() => ConstantAttribute)), + "attributes", + $.right( + $.lazy(() => keyword($.str("const"))), + $.field( + $.lazy(() => Id), + "name", + $.field( + $.lazy(() => ascription), + "type", + $.field( + $.alt( + $.lazy(() => ConstantDefinition), + $.lazy(() => ConstantDeclaration), + ), + "body", + $.eps, + ), + ), + ), + ), + ), + ), +); +export const StructDecl: $.Parser<$ast.StructDecl> = $.loc( + $.field( + $.pure("StructDecl"), + "$", + $.right( + $.str("struct"), + $.field( + $.lazy(() => TypeId), + "name", + $.right( + $.str("{"), + $.field( + $.lazy(() => structFields), + "fields", + $.right($.str("}"), $.eps), + ), + ), + ), + ), + ), +); +export const MessageDecl: $.Parser<$ast.MessageDecl> = $.loc( + $.field( + $.pure("MessageDecl"), + "$", + $.right( + $.str("message"), + $.field( + $.opt( + $.right( + $.str("("), + $.left( + $.lazy(() => expression), + $.str(")"), + ), + ), + ), + "opcode", + $.field( + $.lazy(() => TypeId), + "name", + $.right( + $.str("{"), + $.field( + $.lazy(() => structFields), + "fields", + $.right($.str("}"), $.eps), + ), + ), + ), + ), + ), + ), +); +export const Contract: $.Parser<$ast.Contract> = $.loc( + $.field( + $.pure("Contract"), + "$", + $.field( + $.star($.lazy(() => ContractAttribute)), + "attributes", + $.right( + $.lazy(() => keyword($.str("contract"))), + $.field( + $.lazy(() => TypeId), + "name", + $.field( + $.opt( + $.lazy(() => + ParameterList($.lazy(() => Parameter)), + ), + ), + "parameters", + $.field( + $.opt($.lazy(() => inheritedTraits)), + "traits", + $.right( + $.str("{"), + $.field( + $.star($.lazy(() => contractItemDecl)), + "declarations", + $.right($.str("}"), $.eps), + ), + ), + ), + ), + ), + ), + ), + ), +); +export const Trait: $.Parser<$ast.Trait> = $.loc( + $.field( + $.pure("Trait"), + "$", + $.field( + $.star($.lazy(() => ContractAttribute)), + "attributes", + $.right( + $.lazy(() => keyword($.str("trait"))), + $.field( + $.lazy(() => TypeId), + "name", + $.field( + $.opt($.lazy(() => inheritedTraits)), + "traits", + $.right( + $.str("{"), + $.field( + $.star($.lazy(() => traitItemDecl)), + "declarations", + $.right($.str("}"), $.eps), + ), + ), + ), + ), + ), + ), + ), +); +export const moduleItem: $.Parser<$ast.moduleItem> = $.alt( + PrimitiveTypeDecl, + $.alt( + $Function, + $.alt( + AsmFunction, + $.alt( + NativeFunctionDecl, + $.alt( + Constant, + $.alt( + StructDecl, + $.alt(MessageDecl, $.alt(Contract, Trait)), + ), + ), + ), + ), + ), +); +export const ContractInit: $.Parser<$ast.ContractInit> = $.loc( + $.field( + $.pure("ContractInit"), + "$", + $.right( + $.str("init"), + $.field( + $.lazy(() => parameterList($.lazy(() => Parameter))), + "parameters", + $.field( + $.lazy(() => statements), + "body", + $.eps, + ), + ), + ), + ), +); +export const Receiver: $.Parser<$ast.Receiver> = $.loc( + $.field( + $.pure("Receiver"), + "$", + $.field( + $.lazy(() => ReceiverType), + "type", + $.right( + $.str("("), + $.field( + $.lazy(() => receiverParam), + "param", + $.right( + $.str(")"), + $.field( + $.lazy(() => statements), + "body", + $.eps, + ), + ), + ), + ), + ), + ), +); +export const FieldDecl: $.Parser<$ast.FieldDecl> = $.loc( + $.field( + $.pure("FieldDecl"), + "$", + $.field( + $.lazy(() => Id), + "name", + $.field( + $.lazy(() => ascription), + "type", + $.field( + $.opt( + $.right( + $.str("="), + $.lazy(() => expression), + ), + ), + "expression", + $.eps, + ), + ), + ), + ), +); +export const semicolon: $.Parser<$ast.semicolon> = $.alt( + $.str(";"), + $.lookPos($.str("}")), +); +export const storageVar: $.Parser<$ast.storageVar> = $.left( + FieldDecl, + semicolon, +); +export const contractItemDecl: $.Parser<$ast.contractItemDecl> = $.alt( + ContractInit, + $.alt( + Receiver, + $.alt($Function, $.alt(AsmFunction, $.alt(Constant, storageVar))), + ), +); +export const traitItemDecl: $.Parser<$ast.traitItemDecl> = $.alt( + Receiver, + $.alt($Function, $.alt(AsmFunction, $.alt(Constant, storageVar))), +); +export const FunctionDefinition: $.Parser<$ast.FunctionDefinition> = $.loc( + $.field( + $.pure("FunctionDefinition"), + "$", + $.field( + $.lazy(() => statements), + "body", + $.eps, + ), + ), +); +export const FunctionDeclaration: $.Parser<$ast.FunctionDeclaration> = $.loc( + $.field($.pure("FunctionDeclaration"), "$", $.right(semicolon, $.eps)), +); +export const Id: $.Parser<$ast.Id> = $.named( + "identifier", + $.loc( + $.field( + $.pure("Id"), + "$", + $.field( + $.lex( + $.stry( + $.right( + $.lookNeg($.lazy(() => reservedWord)), + $.right( + $.regex("a-zA-Z_", [ + $.ExpRange("a", "z"), + $.ExpRange("A", "Z"), + $.ExpString("_"), + ]), + $.right($.star($.lazy(() => idPart)), $.eps), + ), + ), + ), + ), + "name", + $.eps, + ), + ), + ), +); +export const IntegerLiteralDec: $.Parser<$ast.IntegerLiteralDec> = $.loc( + $.field( + $.pure("IntegerLiteralDec"), + "$", + $.field( + $.lex($.lazy(() => underscored($.lazy(() => digit)))), + "digits", + $.eps, + ), + ), +); +export const shuffle: $.Parser<$ast.shuffle> = $.right( + $.str("("), + $.field( + $.star(Id), + "ids", + $.field( + $.opt($.right($.str("->"), $.plus(IntegerLiteralDec))), + "to", + $.right($.str(")"), $.eps), + ), + ), +); +export const ConstantAttribute: $.Parser<$ast.ConstantAttribute> = $.loc( + $.field( + $.pure("ConstantAttribute"), + "$", + $.field( + $.alt( + $.lazy(() => keyword($.str("virtual"))), + $.alt( + $.lazy(() => keyword($.str("override"))), + $.lazy(() => keyword($.str("abstract"))), + ), + ), + "name", + $.eps, + ), + ), +); +export const ConstantDefinition: $.Parser<$ast.ConstantDefinition> = $.loc( + $.field( + $.pure("ConstantDefinition"), + "$", + $.right( + $.str("="), + $.field( + $.lazy(() => expression), + "expression", + $.right(semicolon, $.eps), + ), + ), + ), +); +export const ConstantDeclaration: $.Parser<$ast.ConstantDeclaration> = $.loc( + $.field($.pure("ConstantDeclaration"), "$", $.right(semicolon, $.eps)), +); +export const inter = ( + A: $.Parser, + B: $.Parser, +): $.Parser<$ast.inter> => + $.field( + $.lazy(() => A), + "head", + $.field( + $.star( + $.field( + $.lazy(() => B), + "op", + $.field( + $.lazy(() => A), + "right", + $.eps, + ), + ), + ), + "tail", + $.eps, + ), + ); +export const structFields: $.Parser<$ast.structFields> = $.left( + $.opt(inter(FieldDecl, $.str(";"))), + $.opt($.str(";")), +); +export const keyword = (T: $.Parser): $.Parser<$ast.keyword> => + $.lex( + $.left( + $.lazy(() => T), + $.lookNeg($.lazy(() => idPart)), + ), + ); +export const commaList = (T: $.Parser): $.Parser<$ast.commaList> => + $.left( + inter( + $.lazy(() => T), + $.str(","), + ), + $.opt($.str(",")), + ); +export const TypeId: $.Parser<$ast.TypeId> = $.named( + "capitalized identifier", + $.loc( + $.field( + $.pure("TypeId"), + "$", + $.field( + $.lex( + $.stry( + $.right( + $.regex("A-Z", [$.ExpRange("A", "Z")]), + $.right( + $.star( + $.regex( + "a-zA-Z0-9_", + [ + $.ExpRange("a", "z"), + $.ExpRange("A", "Z"), + $.ExpRange("0", "9"), + $.ExpString("_"), + ], + ), + ), + $.eps, + ), + ), + ), + ), + "name", + $.eps, + ), + ), + ), +); +export const inheritedTraits: $.Parser<$ast.inheritedTraits> = $.right( + keyword($.str("with")), + commaList(TypeId), +); +export const ContractAttribute: $.Parser<$ast.ContractAttribute> = $.loc( + $.field( + $.pure("ContractAttribute"), + "$", + $.right( + $.str("@interface"), + $.right( + $.str("("), + $.field( + $.lazy(() => StringLiteral), + "name", + $.right($.str(")"), $.eps), + ), + ), + ), + ), +); +export const FunctionAttribute: $.Parser<$ast.FunctionAttribute> = $.loc( + $.field( + $.pure("FunctionAttribute"), + "$", + $.field( + $.alt( + $.lazy(() => GetAttribute), + $.alt( + keyword($.str("mutates")), + $.alt( + keyword($.str("extends")), + $.alt( + keyword($.str("virtual")), + $.alt( + keyword($.str("override")), + $.alt( + keyword($.str("inline")), + keyword($.str("abstract")), + ), + ), + ), + ), + ), + ), + "name", + $.eps, + ), + ), +); +export const GetAttribute: $.Parser<$ast.GetAttribute> = $.loc( + $.field( + $.pure("GetAttribute"), + "$", + $.right( + $.str("get"), + $.field( + $.opt( + $.right( + $.str("("), + $.left( + $.lazy(() => expression), + $.str(")"), + ), + ), + ), + "methodId", + $.eps, + ), + ), + ), +); +export const ReceiverType: $.Parser<$ast.ReceiverType> = $.loc( + $.field( + $.pure("ReceiverType"), + "$", + $.field( + $.alt( + $.str("bounced"), + $.alt(keyword($.str("receive")), keyword($.str("external"))), + ), + "name", + $.eps, + ), + ), +); +export const Parameter: $.Parser<$ast.Parameter> = $.loc( + $.field( + $.pure("Parameter"), + "$", + $.field( + Id, + "name", + $.field( + $.lazy(() => ascription), + "type", + $.eps, + ), + ), + ), +); +export const StringLiteral: $.Parser<$ast.StringLiteral> = $.loc( + $.field( + $.pure("StringLiteral"), + "$", + $.field( + $.lex( + $.right( + $.str('"'), + $.left( + $.stry( + $.star( + $.alt( + $.regex<'"' | "\\">( + '^"\\\\', + $.negateExps([ + $.ExpString('"'), + $.ExpString("\\"), + ]), + ), + $.right( + $.str("\\"), + $.lazy(() => escapeChar), + ), + ), + ), + ), + $.str('"'), + ), + ), + ), + "value", + $.eps, + ), + ), +); +export const receiverParam: $.Parser<$ast.receiverParam> = $.opt( + $.alt(Parameter, StringLiteral), +); +export const assembly: $.Parser<$ast.assembly> = $.lex( + $.stry($.lazy(() => assemblySequence)), +); +export const multiLineComment: $.Parser<$ast.multiLineComment> = $.right( + $.str("/*"), + $.left( + $.stry($.star($.right($.lookNeg($.str("*/")), $.right($.any, $.eps)))), + $.str("*/"), + ), +); +export const singleLineComment: $.Parser<$ast.singleLineComment> = $.right( + $.str("//"), + $.stry( + $.star( + $.regex<"\r" | "\n">( + "^\\r\\n", + $.negateExps([$.ExpString("\r"), $.ExpString("\n")]), + ), + ), + ), +); +export const comment: $.Parser<$ast.comment> = $.alt( + multiLineComment, + singleLineComment, +); +export const assemblyItem: $.Parser<$ast.assemblyItem> = $.alt( + $.right( + $.str("{"), + $.right( + $.lazy(() => assemblySequence), + $.right($.str("}"), $.eps), + ), + ), + $.alt( + comment, + $.alt( + $.right( + $.str('"'), + $.right( + $.star( + $.regex<'"'>('^"', $.negateExps([$.ExpString('"')])), + ), + $.right($.str('"'), $.eps), + ), + ), + $.plus( + $.right( + $.lookNeg( + $.alt( + $.regex<'"' | "{" | "}">('"{}', [ + $.ExpString('"'), + $.ExpString("{"), + $.ExpString("}"), + ]), + $.alt($.str("//"), $.str("/*")), + ), + ), + $.right($.any, $.eps), + ), + ), + ), + ), +); +export const assemblySequence: $.Parser<$ast.assemblySequence> = + $.star(assemblyItem); +export const TypeAs: $.Parser<$ast.TypeAs> = $.loc( + $.field( + $.pure("TypeAs"), + "$", + $.field( + $.lazy(() => TypeOptional), + "type", + $.field( + $.star( + $.right(keyword($.str("as")), $.lex($.lazy(() => storage))), + ), + "as", + $.eps, + ), + ), + ), +); +export const $type: $.Parser<$ast.$type> = TypeAs; +export const ascription: $.Parser<$ast.ascription> = $.right($.str(":"), $type); +export const TypeOptional: $.Parser<$ast.TypeOptional> = $.loc( + $.field( + $.pure("TypeOptional"), + "$", + $.field( + $.lazy(() => typePrimary), + "type", + $.field($.star($.lazy(() => Optional)), "optionals", $.eps), + ), + ), +); +export const Optional: $.Parser<$ast.Optional> = $.loc( + $.field($.pure("Optional"), "$", $.right($.str("?"), $.eps)), +); +export const TypeGeneric: $.Parser<$ast.TypeGeneric> = $.loc( + $.field( + $.pure("TypeGeneric"), + "$", + $.field( + $.alt( + $.lazy(() => MapKeyword), + $.alt( + $.lazy(() => Bounced), + TypeId, + ), + ), + "name", + $.right( + $.str("<"), + $.field(commaList($type), "args", $.right($.str(">"), $.eps)), + ), + ), + ), +); +export const TypeRegular: $.Parser<$ast.TypeRegular> = $.loc( + $.field($.pure("TypeRegular"), "$", $.field(TypeId, "child", $.eps)), +); +export const TypeTuple: $.Parser<$ast.TypeTuple> = $.loc( + $.field( + $.pure("TypeTuple"), + "$", + $.right( + $.str("["), + $.field( + $.opt(commaList($type)), + "types", + $.right($.str("]"), $.eps), + ), + ), + ), +); +export const TypeTensor: $.Parser<$ast.TypeTensor> = $.loc( + $.field( + $.pure("TypeTensor"), + "$", + $.right( + $.str("("), + $.field( + $type, + "head", + $.field( + $.plus($.right($.str(","), $type)), + "tail", + $.right($.opt($.str(",")), $.right($.str(")"), $.eps)), + ), + ), + ), + ), +); +export const TypeUnit: $.Parser<$ast.TypeUnit> = $.loc( + $.field( + $.pure("TypeUnit"), + "$", + $.right($.right($.str("("), $.right($.str(")"), $.eps)), $.eps), + ), +); +export const typeParens: $.Parser<$ast.typeParens> = $.right( + $.str("("), + $.left($type, $.str(")")), +); +export const typePrimary: $.Parser<$ast.typePrimary> = $.alt( + TypeGeneric, + $.alt( + TypeRegular, + $.alt(TypeTuple, $.alt(TypeTensor, $.alt(TypeUnit, typeParens))), + ), +); +export const MapKeyword: $.Parser<$ast.MapKeyword> = $.loc( + $.field($.pure("MapKeyword"), "$", $.right(keyword($.str("map")), $.eps)), +); +export const Bounced: $.Parser<$ast.Bounced> = $.loc( + $.field($.pure("Bounced"), "$", $.right($.str("bounced"), $.eps)), +); +export const IntStorage: $.Parser<$ast.IntStorage> = $.loc( + $.field( + $.pure("IntStorage"), + "$", + $.field( + $.opt($.str("var")), + "isVar", + $.field( + $.opt($.str("u")), + "isUnsigned", + $.right( + $.str("int"), + $.field( + $.stry($.plus($.lazy(() => digit))), + "width", + $.eps, + ), + ), + ), + ), + ), +); +export const CoinsStorage: $.Parser<$ast.CoinsStorage> = $.loc( + $.field($.pure("CoinsStorage"), "$", $.right($.str("coins"), $.eps)), +); +export const RemainingStorage: $.Parser<$ast.RemainingStorage> = $.loc( + $.field( + $.pure("RemainingStorage"), + "$", + $.right($.str("remaining"), $.eps), + ), +); +export const BytesStorage: $.Parser<$ast.BytesStorage> = $.loc( + $.field( + $.pure("BytesStorage"), + "$", + $.right( + $.str("bytes"), + $.field($.stry($.plus($.lazy(() => digit))), "width", $.eps), + ), + ), +); +export const storage: $.Parser<$ast.storage> = $.alt( + IntStorage, + $.alt(CoinsStorage, $.alt(RemainingStorage, BytesStorage)), +); +export const StatementLet: $.Parser<$ast.StatementLet> = $.loc( + $.field( + $.pure("StatementLet"), + "$", + $.right( + keyword($.str("let")), + $.field( + Id, + "name", + $.field( + $.opt(ascription), + "type", + $.right( + $.str("="), + $.field( + $.lazy(() => expression), + "init", + $.right(semicolon, $.eps), + ), + ), + ), + ), + ), + ), +); +export const StatementDestruct: $.Parser<$ast.StatementDestruct> = $.loc( + $.field( + $.pure("StatementDestruct"), + "$", + $.right( + keyword($.str("let")), + $.field( + TypeId, + "type", + $.right( + $.str("{"), + $.field( + inter( + $.lazy(() => destructItem), + $.str(","), + ), + "fields", + $.field( + $.lazy(() => optionalRest), + "rest", + $.right( + $.str("}"), + $.right( + $.str("="), + $.field( + $.lazy(() => expression), + "init", + $.right(semicolon, $.eps), + ), + ), + ), + ), + ), + ), + ), + ), + ), +); +export const StatementBlock: $.Parser<$ast.StatementBlock> = $.loc( + $.field( + $.pure("StatementBlock"), + "$", + $.field( + $.lazy(() => statements), + "body", + $.eps, + ), + ), +); +export const StatementReturn: $.Parser<$ast.StatementReturn> = $.loc( + $.field( + $.pure("StatementReturn"), + "$", + $.right( + keyword($.str("return")), + $.field( + $.opt($.lazy(() => expression)), + "expression", + $.right(semicolon, $.eps), + ), + ), + ), +); +export const StatementCondition: $.Parser<$ast.StatementCondition> = $.loc( + $.field( + $.pure("StatementCondition"), + "$", + $.right( + keyword($.str("if")), + $.field( + $.lazy(() => expression), + "condition", + $.field( + $.lazy(() => statements), + "trueBranch", + $.field( + $.opt( + $.right( + keyword($.str("else")), + $.alt( + $.lazy(() => FalseBranch), + $.lazy(() => StatementCondition), + ), + ), + ), + "falseBranch", + $.eps, + ), + ), + ), + ), + ), +); +export const StatementWhile: $.Parser<$ast.StatementWhile> = $.loc( + $.field( + $.pure("StatementWhile"), + "$", + $.right( + keyword($.str("while")), + $.field( + $.lazy(() => parens), + "condition", + $.field( + $.lazy(() => statements), + "body", + $.eps, + ), + ), + ), + ), +); +export const StatementRepeat: $.Parser<$ast.StatementRepeat> = $.loc( + $.field( + $.pure("StatementRepeat"), + "$", + $.right( + keyword($.str("repeat")), + $.field( + $.lazy(() => parens), + "condition", + $.field( + $.lazy(() => statements), + "body", + $.eps, + ), + ), + ), + ), +); +export const StatementUntil: $.Parser<$ast.StatementUntil> = $.loc( + $.field( + $.pure("StatementUntil"), + "$", + $.right( + keyword($.str("do")), + $.field( + $.lazy(() => statements), + "body", + $.right( + keyword($.str("until")), + $.field( + $.lazy(() => parens), + "condition", + $.right(semicolon, $.eps), + ), + ), + ), + ), + ), +); +export const StatementTry: $.Parser<$ast.StatementTry> = $.loc( + $.field( + $.pure("StatementTry"), + "$", + $.right( + keyword($.str("try")), + $.field( + $.lazy(() => statements), + "body", + $.field( + $.opt( + $.right( + keyword($.str("catch")), + $.right( + $.str("("), + $.field( + Id, + "name", + $.right( + $.str(")"), + $.field( + $.lazy(() => statements), + "body", + $.eps, + ), + ), + ), + ), + ), + ), + "handler", + $.eps, + ), + ), + ), + ), +); +export const StatementForEach: $.Parser<$ast.StatementForEach> = $.loc( + $.field( + $.pure("StatementForEach"), + "$", + $.right( + keyword($.str("foreach")), + $.right( + $.str("("), + $.field( + Id, + "key", + $.right( + $.str(","), + $.field( + Id, + "value", + $.right( + $.str("in"), + $.field( + $.lazy(() => expression), + "expression", + $.right( + $.str(")"), + $.field( + $.lazy(() => statements), + "body", + $.eps, + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), +); +export const StatementExpression: $.Parser<$ast.StatementExpression> = $.loc( + $.field( + $.pure("StatementExpression"), + "$", + $.field( + $.lazy(() => expression), + "expression", + $.right(semicolon, $.eps), + ), + ), +); +export const StatementAssign: $.Parser<$ast.StatementAssign> = $.loc( + $.field( + $.pure("StatementAssign"), + "$", + $.field( + $.lazy(() => expression), + "left", + $.field( + $.alt( + $.lazy(() => augmentedOp), + $.str("="), + ), + "operator", + $.field( + $.lazy(() => expression), + "right", + $.right(semicolon, $.eps), + ), + ), + ), + ), +); +export const statement: $.Parser<$ast.statement> = $.alt( + StatementLet, + $.alt( + StatementDestruct, + $.alt( + StatementBlock, + $.alt( + StatementReturn, + $.alt( + StatementCondition, + $.alt( + StatementWhile, + $.alt( + StatementRepeat, + $.alt( + StatementUntil, + $.alt( + StatementTry, + $.alt( + StatementForEach, + $.alt( + StatementExpression, + StatementAssign, + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), +); +export const statements: $.Parser<$ast.statements> = $.right( + $.str("{"), + $.left($.star(statement), $.str("}")), +); +export const augmentedOp: $.Parser<$ast.augmentedOp> = $.alt( + $.str("||="), + $.alt( + $.str("&&="), + $.alt( + $.str(">>="), + $.alt( + $.str("<<="), + $.alt( + $.str("-="), + $.alt( + $.str("+="), + $.alt( + $.str("*="), + $.alt( + $.str("/="), + $.alt( + $.str("%="), + $.alt( + $.str("|="), + $.alt($.str("&="), $.str("^=")), + ), + ), + ), + ), + ), + ), + ), + ), + ), +); +export const FalseBranch: $.Parser<$ast.FalseBranch> = $.loc( + $.field($.pure("FalseBranch"), "$", $.field(statements, "body", $.eps)), +); +export const RegularField: $.Parser<$ast.RegularField> = $.loc( + $.field( + $.pure("RegularField"), + "$", + $.field( + Id, + "fieldName", + $.right($.str(":"), $.field(Id, "varName", $.eps)), + ), + ), +); +export const PunnedField: $.Parser<$ast.PunnedField> = $.loc( + $.field($.pure("PunnedField"), "$", $.field(Id, "name", $.eps)), +); +export const destructItem: $.Parser<$ast.destructItem> = $.alt( + RegularField, + PunnedField, +); +export const RestArgument: $.Parser<$ast.RestArgument> = $.loc( + $.field($.pure("RestArgument"), "$", $.right($.str(".."), $.eps)), +); +export const NoRestArgument: $.Parser<$ast.NoRestArgument> = $.loc( + $.field($.pure("NoRestArgument"), "$", $.right($.opt($.str(",")), $.eps)), +); +export const optionalRest: $.Parser<$ast.optionalRest> = $.alt( + $.right($.str(","), RestArgument), + NoRestArgument, +); +export const Conditional: $.Parser<$ast.Conditional> = $.loc( + $.field( + $.pure("Conditional"), + "$", + $.field( + $.lazy(() => or), + "head", + $.field( + $.opt( + $.right( + $.str("?"), + $.field( + $.lazy(() => or), + "thenBranch", + $.right( + $.str(":"), + $.field( + $.lazy(() => Conditional), + "elseBranch", + $.eps, + ), + ), + ), + ), + ), + "tail", + $.eps, + ), + ), + ), +); +export const expression: $.Parser<$ast.expression> = Conditional; +export const Binary = ( + T: $.Parser, + U: $.Parser, +): $.Parser<$ast.Binary> => + $.loc( + $.field( + $.pure("Binary"), + "$", + $.field( + inter( + $.lazy(() => T), + $.lazy(() => Operator($.lazy(() => U))), + ), + "exprs", + $.eps, + ), + ), + ); +export const Unary: $.Parser<$ast.Unary> = $.loc( + $.field( + $.pure("Unary"), + "$", + $.field( + $.star( + $.lazy(() => + Operator( + $.regex<"-" | "+" | "!" | "~">("-+!~", [ + $.ExpString("-"), + $.ExpString("+"), + $.ExpString("!"), + $.ExpString("~"), + ]), + ), + ), + ), + "prefixes", + $.field( + $.lazy(() => Suffix), + "expression", + $.eps, + ), + ), + ), +); +export const mul: $.Parser<$ast.mul> = Binary( + Unary, + $.regex<"*" | "/" | "%">("*/%", [ + $.ExpString("*"), + $.ExpString("/"), + $.ExpString("%"), + ]), +); +export const add: $.Parser<$ast.add> = Binary( + mul, + $.alt($.str("+"), $.str("-")), +); +export const bitwiseShift: $.Parser<$ast.bitwiseShift> = Binary( + add, + $.alt($.str("<<"), $.str(">>")), +); +export const compare: $.Parser<$ast.compare> = Binary( + bitwiseShift, + $.alt($.str("<="), $.alt($.str("<"), $.alt($.str(">="), $.str(">")))), +); +export const equality: $.Parser<$ast.equality> = Binary( + compare, + $.alt($.str("!="), $.str("==")), +); +export const bitwiseAnd: $.Parser<$ast.bitwiseAnd> = Binary( + equality, + $.str("&"), +); +export const bitwiseXor: $.Parser<$ast.bitwiseXor> = Binary( + bitwiseAnd, + $.str("^"), +); +export const bitwiseOr: $.Parser<$ast.bitwiseOr> = Binary( + bitwiseXor, + $.str("|"), +); +export const and: $.Parser<$ast.and> = Binary(bitwiseOr, $.str("&&")); +export const or: $.Parser<$ast.or> = Binary(and, $.str("||")); +export const Suffix: $.Parser<$ast.Suffix> = $.loc( + $.field( + $.pure("Suffix"), + "$", + $.field( + $.lazy(() => primary), + "expression", + $.field($.star($.lazy(() => suffix)), "suffixes", $.eps), + ), + ), +); +export const Operator = (U: $.Parser): $.Parser<$ast.Operator> => + $.loc( + $.field( + $.pure("Operator"), + "$", + $.field( + $.lazy(() => U), + "name", + $.eps, + ), + ), + ); +export const SuffixUnboxNotNull: $.Parser<$ast.SuffixUnboxNotNull> = $.loc( + $.field($.pure("SuffixUnboxNotNull"), "$", $.right($.str("!!"), $.eps)), +); +export const SuffixCall: $.Parser<$ast.SuffixCall> = $.loc( + $.field( + $.pure("SuffixCall"), + "$", + $.field( + $.lazy(() => parameterList(expression)), + "params", + $.eps, + ), + ), +); +export const SuffixFieldAccess: $.Parser<$ast.SuffixFieldAccess> = $.loc( + $.field( + $.pure("SuffixFieldAccess"), + "$", + $.right($.str("."), $.field(Id, "name", $.eps)), + ), +); +export const suffix: $.Parser<$ast.suffix> = $.alt( + SuffixUnboxNotNull, + $.alt(SuffixCall, SuffixFieldAccess), +); +export const Parens: $.Parser<$ast.Parens> = $.loc( + $.field( + $.pure("Parens"), + "$", + $.field( + $.lazy(() => parens), + "child", + $.eps, + ), + ), +); +export const StructInstance: $.Parser<$ast.StructInstance> = $.loc( + $.field( + $.pure("StructInstance"), + "$", + $.field( + TypeId, + "type", + $.right( + $.str("{"), + $.field( + $.opt(commaList($.lazy(() => StructFieldInitializer))), + "fields", + $.right($.str("}"), $.eps), + ), + ), + ), + ), +); +export const IntegerLiteral: $.Parser<$ast.IntegerLiteral> = $.loc( + $.field( + $.pure("IntegerLiteral"), + "$", + $.field( + $.alt( + $.lazy(() => IntegerLiteralHex), + $.alt( + $.lazy(() => IntegerLiteralBin), + $.alt( + $.lazy(() => IntegerLiteralOct), + IntegerLiteralDec, + ), + ), + ), + "value", + $.eps, + ), + ), +); +export const BoolLiteral: $.Parser<$ast.BoolLiteral> = $.loc( + $.field( + $.pure("BoolLiteral"), + "$", + $.field( + $.alt($.str("true"), $.str("false")), + "value", + $.right($.lookNeg($.lazy(() => idPart)), $.eps), + ), + ), +); +export const InitOf: $.Parser<$ast.InitOf> = $.loc( + $.field( + $.pure("InitOf"), + "$", + $.right( + keyword($.str("initOf")), + $.field( + TypeId, + "name", + $.field( + $.lazy(() => parameterList(expression)), + "params", + $.eps, + ), + ), + ), + ), +); +export const CodeOf: $.Parser<$ast.CodeOf> = $.loc( + $.field( + $.pure("CodeOf"), + "$", + $.right($.str("codeOf"), $.field(TypeId, "name", $.eps)), + ), +); +export const Null: $.Parser<$ast.Null> = $.loc( + $.field($.pure("Null"), "$", $.right(keyword($.str("null")), $.eps)), +); +export const primary: $.Parser<$ast.primary> = $.alt( + Parens, + $.alt( + StructInstance, + $.alt( + IntegerLiteral, + $.alt( + BoolLiteral, + $.alt( + InitOf, + $.alt(CodeOf, $.alt(Null, $.alt(StringLiteral, Id))), + ), + ), + ), + ), +); +export const parens: $.Parser<$ast.parens> = $.right( + $.str("("), + $.left(expression, $.str(")")), +); +export const StructFieldInitializer: $.Parser<$ast.StructFieldInitializer> = + $.loc( + $.field( + $.pure("StructFieldInitializer"), + "$", + $.field( + Id, + "name", + $.field($.opt($.right($.str(":"), expression)), "init", $.eps), + ), + ), + ); +export const ParameterList = ( + T: $.Parser, +): $.Parser<$ast.ParameterList> => + $.loc( + $.field( + $.pure("ParameterList"), + "$", + $.right( + $.str("("), + $.field( + $.opt(commaList($.lazy(() => T))), + "values", + $.right($.str(")"), $.eps), + ), + ), + ), + ); +export const parameterList = ( + T: $.Parser, +): $.Parser<$ast.parameterList> => + $.right($.str("("), $.left($.opt(commaList($.lazy(() => T))), $.str(")"))); +export const IntegerLiteralHex: $.Parser<$ast.IntegerLiteralHex> = $.loc( + $.field( + $.pure("IntegerLiteralHex"), + "$", + $.field( + $.lex( + $.right( + $.str("0"), + $.right( + $.regex<"x" | "X">("xX", [ + $.ExpString("x"), + $.ExpString("X"), + ]), + $.lazy(() => underscored($.lazy(() => hexDigit))), + ), + ), + ), + "digits", + $.eps, + ), + ), +); +export const IntegerLiteralBin: $.Parser<$ast.IntegerLiteralBin> = $.loc( + $.field( + $.pure("IntegerLiteralBin"), + "$", + $.field( + $.lex( + $.right( + $.str("0"), + $.right( + $.regex<"b" | "B">("bB", [ + $.ExpString("b"), + $.ExpString("B"), + ]), + $.lazy(() => + underscored( + $.regex<"0" | "1">("01", [ + $.ExpString("0"), + $.ExpString("1"), + ]), + ), + ), + ), + ), + ), + "digits", + $.eps, + ), + ), +); +export const IntegerLiteralOct: $.Parser<$ast.IntegerLiteralOct> = $.loc( + $.field( + $.pure("IntegerLiteralOct"), + "$", + $.field( + $.lex( + $.right( + $.str("0"), + $.right( + $.regex<"o" | "O">("oO", [ + $.ExpString("o"), + $.ExpString("O"), + ]), + $.lazy(() => + underscored( + $.regex("0-7", [$.ExpRange("0", "7")]), + ), + ), + ), + ), + ), + "digits", + $.eps, + ), + ), +); +export const underscored = (T: $.Parser): $.Parser<$ast.underscored> => + $.stry( + $.right( + $.lazy(() => T), + $.right( + $.star( + $.right( + $.opt($.str("_")), + $.right( + $.lazy(() => T), + $.eps, + ), + ), + ), + $.eps, + ), + ), + ); +export const digit: $.Parser<$ast.digit> = $.named( + "digit", + $.regex("0-9", [$.ExpRange("0", "9")]), +); +export const idPart: $.Parser<$ast.idPart> = $.named( + "identifier character", + $.regex("a-zA-Z0-9_", [ + $.ExpRange("a", "z"), + $.ExpRange("A", "Z"), + $.ExpRange("0", "9"), + $.ExpString("_"), + ]), +); +export const FuncId: $.Parser<$ast.FuncId> = $.named( + "FunC identifier", + $.loc( + $.field( + $.pure("FuncId"), + "$", + $.field( + $.opt( + $.regex<"." | "~">(".~", [ + $.ExpString("."), + $.ExpString("~"), + ]), + ), + "accessor", + $.field( + $.stry( + $.alt( + $.right( + $.str("`"), + $.right( + $.plus( + $.regex<"`" | "\r" | "\n">( + "^`\\r\\n", + $.negateExps([ + $.ExpString("`"), + $.ExpString("\r"), + $.ExpString("\n"), + ]), + ), + ), + $.right($.str("`"), $.eps), + ), + ), + $.plus( + $.regex< + | " " + | "\t" + | "\r" + | "\n" + | "(" + | ")" + | "[" + | string + | "," + | "." + | ";" + | "~" + >( + "^ \\t\\r\\n()[\\],.;~", + $.negateExps([ + $.ExpString(" "), + $.ExpString("\t"), + $.ExpString("\r"), + $.ExpString("\n"), + $.ExpString("("), + $.ExpString(")"), + $.ExpString("["), + $.ExpString('"\\]"'), + $.ExpString(","), + $.ExpString("."), + $.ExpString(";"), + $.ExpString("~"), + ]), + ), + ), + ), + ), + "id", + $.eps, + ), + ), + ), + ), +); +export const hexDigit: $.Parser<$ast.hexDigit> = $.named( + "hexadecimal digit", + $.regex("0-9a-fA-F", [ + $.ExpRange("0", "9"), + $.ExpRange("a", "f"), + $.ExpRange("A", "F"), + ]), +); +export const escapeChar: $.Parser<$ast.escapeChar> = $.alt( + $.regex<"\\" | '"' | "n" | "r" | "t" | "v" | "b" | "f">('\\\\"nrtvbf', [ + $.ExpString("\\"), + $.ExpString('"'), + $.ExpString("n"), + $.ExpString("r"), + $.ExpString("t"), + $.ExpString("v"), + $.ExpString("b"), + $.ExpString("f"), + ]), + $.alt( + $.right( + $.str("u{"), + $.left( + $.stry( + $.right( + hexDigit, + $.right( + $.opt(hexDigit), + $.right( + $.opt(hexDigit), + $.right( + $.opt(hexDigit), + $.right( + $.opt(hexDigit), + $.right($.opt(hexDigit), $.eps), + ), + ), + ), + ), + ), + ), + $.str("}"), + ), + ), + $.alt( + $.right( + $.str("u"), + $.stry( + $.right( + hexDigit, + $.right( + hexDigit, + $.right(hexDigit, $.right(hexDigit, $.eps)), + ), + ), + ), + ), + $.right( + $.str("x"), + $.stry($.right(hexDigit, $.right(hexDigit, $.eps))), + ), + ), + ), +); +export const reservedWord: $.Parser<$ast.reservedWord> = $.named( + "reserved word", + keyword( + $.alt( + $.str("extend"), + $.alt( + $.str("public"), + $.alt( + $.str("fun"), + $.alt( + $.str("let"), + $.alt( + $.str("return"), + $.alt( + $.str("receive"), + $.alt( + $.str("native"), + $.alt( + $.str("primitive"), + $.alt( + $.str("null"), + $.alt( + $.str("if"), + $.alt( + $.str("else"), + $.alt( + $.str("while"), + $.alt( + $.str("repeat"), + $.alt( + $.str("do"), + $.alt( + $.str( + "until", + ), + $.alt( + $.str( + "try", + ), + $.alt( + $.str( + "catch", + ), + $.alt( + $.str( + "foreach", + ), + $.alt( + $.str( + "as", + ), + $.alt( + $.str( + "map", + ), + $.alt( + $.str( + "mutates", + ), + $.alt( + $.str( + "extends", + ), + $.alt( + $.str( + "external", + ), + $.alt( + $.str( + "import", + ), + $.alt( + $.str( + "with", + ), + $.alt( + $.str( + "trait", + ), + $.alt( + $.str( + "initOf", + ), + $.alt( + $.str( + "override", + ), + $.alt( + $.str( + "abstract", + ), + $.alt( + $.str( + "virtual", + ), + $.alt( + $.str( + "inline", + ), + $.str( + "const", + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), +); +export const space: $.Parser<$ast.space> = $.named( + "space", + $.alt( + $.regex<" " | "\t" | "\r" | "\n">(" \\t\\r\\n", [ + $.ExpString(" "), + $.ExpString("\t"), + $.ExpString("\r"), + $.ExpString("\n"), + ]), + comment, + ), +); +export const JustImports: $.Parser<$ast.JustImports> = $.loc( + $.field( + $.pure("JustImports"), + "$", + $.field($.star(Import), "imports", $.right($.star($.any), $.eps)), + ), +); diff --git a/src/next/grammar/index.ts b/src/next/grammar/index.ts new file mode 100644 index 0000000000..c73c3479bf --- /dev/null +++ b/src/next/grammar/index.ts @@ -0,0 +1,1626 @@ +import * as $ from "@tonstudio/parser-runtime"; +import * as Ast from "@/next/ast"; +import type { $ast } from "@/next/grammar/grammar"; +import * as G from "@/next/grammar/grammar"; +import { SyntaxErrors } from "@/next/grammar/parser-error"; +import { makeMakeVisitor } from "@/utils/tricks"; +import { emptyPath, fromString } from "@/next/grammar/path"; +import type { Language, Range } from "@/next/ast/common"; +import { throwInternal } from "@/error/errors"; +import type { SourceLogger } from "@/error/logger-util"; + +const makeVisitor = makeMakeVisitor("$"); + +const toRange = (loc: $.Loc): Ast.Range => { + if (loc.$ === "empty") { + return throwInternal("Lookahead at top level"); + } + const { start, end } = loc; + return { start, end }; +}; + +const mergeRange = (left: Ast.Range, right: Ast.Range): Ast.Range => { + if (left.start > right.end) { + return throwInternal("Invalid range merge"); + } + return { start: left.start, end: right.end }; +}; + +type Context = { + err: SyntaxErrors; +}; + +type Handler = (ctx: Context) => T; + +const map = + (ts: readonly T[], handler: (t: T) => Handler): Handler => + (ctx) => { + return ts.map((t) => handler(t)(ctx)); + }; + +const parseList = (node: $ast.inter | undefined): T[] => { + if (!node) { + return []; + } + const { head, tail } = node; + return [head, ...tail.map(({ right }) => right)]; +}; + +const parseId = + ({ name, loc }: $ast.Id | $ast.TypeId): Handler => + (ctx) => { + if (name.startsWith("__gen")) { + ctx.err.reservedVarPrefix("__gen")(toRange(loc)); + } + if (name.startsWith("__tact")) { + ctx.err.reservedVarPrefix("__tact")(toRange(loc)); + } + if (name === "_") { + ctx.err.noWildcard()(toRange(loc)); + } + return Ast.Id(name, toRange(loc)); + }; + +const parseOptionalId = + ({ name, loc }: $ast.Id | $ast.TypeId): Handler => + (ctx) => { + if (name.startsWith("__gen")) { + ctx.err.reservedVarPrefix("__gen")(toRange(loc)); + } + if (name.startsWith("__tact")) { + ctx.err.reservedVarPrefix("__tact")(toRange(loc)); + } + if (name === "_") { + return Ast.Wildcard(toRange(loc)); + } + return Ast.Id(name, toRange(loc)); + }; + +const parseVar = + ({ name, loc }: $ast.Id): Handler => + (ctx) => { + if (name.startsWith("__gen")) { + ctx.err.reservedVarPrefix("__gen")(toRange(loc)); + } + if (name.startsWith("__tact")) { + ctx.err.reservedVarPrefix("__tact")(toRange(loc)); + } + if (name === "_") { + ctx.err.noWildcard()(toRange(loc)); + } + return Ast.Var(name, toRange(loc)); + }; + +/* + FunC can parse much more than Fift can handle. For example, _0x0 and _0 are + valid identifiers in FunC, and using either of them compiles and is then + interpreted fine by Fift. But if you use both, FunC still compiles, but Fift crashes. + + Same goes for plain identifiers using hashes # or emojis — you can have one + FunC function with any of those combinations of characters, but you (generally) + cannot have two or more of such functions. +*/ +const reservedFuncIds: Set = new Set([ + "_", + "#include", + "#pragma", + "[", + "]", + "{", + "}", + "?", + ":", + "+", + "-", + "*", + "/%", + "/", + "%", + "~/", + "^/", + "~%", + "^%", + "<=>", + "<=", + "<", + ">=", + ">", + "!=", + "==", + "~>>", + "~", + "^>>", + "^", + "&", + "|", + "<<", + ">>", + "=", + "+=", + "-=", + "*=", + "/=", + "%=", + "~>>=", + "~/=", + "~%=", + "^>>=", + "^/=", + "^%=", + "^=", + "<<=", + ">>=", + "&=", + "|=", + "int", + "cell", + "builder", + "slice", + "cont", + "tuple", + "type", + "->", + "forall", + "return", + "var", + "repeat", + "do", + "while", + "until", + "try", + "catch", + "ifnot", + "if", + "then", + "elseifnot", + "elseif", + "else", + "extern", + "global", + "asm", + "impure", + "inline_ref", + "inline", + "auto_apply", + "method_id", + "operator", + "infixl", + "infixr", + "infix", + "const", +]); + +const parseFuncId = + ({ accessor, id, loc }: $ast.FuncId): Handler => + (ctx) => { + if (reservedFuncIds.has(id)) { + ctx.err.reservedFuncId()(toRange(loc)); + } + if (id.match(/^-?([0-9]+|0x[0-9a-fA-F]+)$/)) { + ctx.err.numericFuncId()(toRange(loc)); + } + if (id.startsWith('"') || id.startsWith("{-")) { + ctx.err.invalidFuncId()(toRange(loc)); + } + return Ast.FuncId((accessor ?? "") + id, toRange(loc)); + }; + +const baseMap = { + IntegerLiteralBin: "2", + IntegerLiteralOct: "8", + IntegerLiteralDec: "10", + IntegerLiteralHex: "16", +} as const; + +const prefixMap = { + IntegerLiteralBin: "0b", + IntegerLiteralOct: "0o", + IntegerLiteralDec: "", + IntegerLiteralHex: "0x", +} as const; + +const parseIntegerLiteralValue = + ({ $, digits, loc }: $ast.IntegerLiteral["value"]): Handler => + (ctx) => { + if ( + $ === "IntegerLiteralDec" && + digits.startsWith("0") && + digits.includes("_") + ) { + ctx.err.leadingZeroUnderscore()(toRange(loc)); + } + const value = BigInt(prefixMap[$] + digits.replaceAll("_", "")); + return Ast.Number(baseMap[$], value, toRange(loc)); + }; + +const parseIntegerLiteral = + ({ value }: $ast.IntegerLiteral): Handler => + (ctx) => { + return parseIntegerLiteralValue(value)(ctx); + }; + +const parseStringLiteral = + ({ value, loc }: $ast.StringLiteral): Handler => + (ctx) => { + const simplifiedValue = replaceEscapeSequences(value, loc, ctx); + return Ast.String(simplifiedValue, toRange(loc)); + }; + +export function replaceEscapeSequences( + stringLiteral: string, + loc: $.Loc, + ctx: Context, +): string { + return stringLiteral.replace( + /\\\\|\\"|\\n|\\r|\\t|\\v|\\b|\\f|\\u{([0-9A-Fa-f]{1,6})}|\\u([0-9A-Fa-f]{4})|\\x([0-9A-Fa-f]{2})/g, + (match, unicodeCodePoint, unicodeEscape, hexEscape) => { + switch (match) { + case "\\\\": + return "\\"; + case '\\"': + return '"'; + case "\\n": + return "\n"; + case "\\r": + return "\r"; + case "\\t": + return "\t"; + case "\\v": + return "\v"; + case "\\b": + return "\b"; + case "\\f": + return "\f"; + default: + // Handle Unicode code point escape + if (unicodeCodePoint) { + const codePoint = parseInt(unicodeCodePoint, 16); + if (codePoint > 0x10ffff) { + ctx.err.undefinedUnicodeCodepoint()(toRange(loc)); + return match; + } + return String.fromCodePoint(codePoint); + } + // Handle Unicode escape + if (unicodeEscape) { + const codeUnit = parseInt(unicodeEscape, 16); + return String.fromCharCode(codeUnit); + } + // Handle hex escape + if (hexEscape) { + const hexValue = parseInt(hexEscape, 16); + return String.fromCharCode(hexValue); + } + return match; + } + }, + ); +} + +const parseBoolLiteral = + ({ value, loc }: $ast.BoolLiteral): Handler => + (_ctx) => { + return Ast.Boolean(value === "true", toRange(loc)); + }; + +const parseNull = + ({ loc }: $ast.Null): Handler => + (_ctx) => { + return Ast.Null(toRange(loc)); + }; + +const parseStructFieldInitializer = + ({ + name, + init, + loc, + }: $ast.StructFieldInitializer): Handler => + (ctx) => { + const fieldId = parseId(name)(ctx); + + // { x } + return Ast.StructFieldInitializer( + fieldId, + init ? parseExpression(init)(ctx) : parseVar(name)(ctx), + toRange(loc), + ); + }; + +const parseStructInstance = + ({ type, fields, loc }: $ast.StructInstance): Handler => + (ctx) => { + return Ast.StructInstance( + parseTypeId(type)(ctx), + map(parseList(fields), parseStructFieldInitializer)(ctx), + toRange(loc), + ); + }; + +const parseInitOf = + ({ name, params, loc }: $ast.InitOf): Handler => + (ctx) => { + return Ast.InitOf( + parseTypeId(name)(ctx), + map(parseList(params), parseExpression)(ctx), + toRange(loc), + ); + }; + +const parseCodeOf = + ({ name, loc }: $ast.CodeOf): Handler => + (ctx) => { + return Ast.CodeOf(parseTypeId(name)(ctx), toRange(loc)); + }; + +const parseConditional = + ({ head, tail, loc }: $ast.Conditional): Handler => + (ctx) => { + const condition = parseExpression(head)(ctx); + if (!tail) { + return condition; + } + const { thenBranch, elseBranch } = tail; + return Ast.Conditional( + condition, + parseExpression(thenBranch)(ctx), + parseExpression(elseBranch)(ctx), + toRange(loc), + ); + }; + +const parseBinary = + ({ + exprs: { head, tail }, + }: $ast.Binary): Handler => + (ctx) => { + return tail.reduce( + ({ child, range }, { op, right }) => { + const merged = mergeRange( + range, + mergeRange(toRange(op.loc), toRange(right.loc)), + ); + return { + child: Ast.OpBinary( + op.name, + child, + parseExpression(right)(ctx), + merged, + ), + range: merged, + }; + }, + { child: parseExpression(head)(ctx), range: toRange(head.loc) }, + ).child; + }; + +const parseUnary = + ({ prefixes, expression }: $ast.Unary): Handler => + (ctx) => { + return prefixes.reduceRight( + ({ child, range }, { name, loc }) => { + const merged = mergeRange(toRange(loc), range); + return { + child: Ast.OpUnary(name, child, merged), + range: merged, + }; + }, + { + child: parseExpression(expression)(ctx), + range: toRange(expression.loc), + }, + ).child; + }; + +type SuffixHandler = Handler< + (child: Ast.Expression, loc: Ast.Range) => Ast.Expression +>; + +const parseSuffixUnboxNotNull = + (_: $ast.SuffixUnboxNotNull): SuffixHandler => + (_ctx) => + (child, loc) => { + return Ast.OpUnary("!!", child, loc); + }; + +const parseSuffixCall = + ({ params }: $ast.SuffixCall): SuffixHandler => + (ctx) => + (child, loc) => { + const paramsAst = map(parseList(params), parseExpression)(ctx); + if (child.kind === "var") { + return Ast.StaticCall( + Ast.Id(child.name, child.loc), + paramsAst, + loc, + ); + } else if (child.kind === "field_access") { + return Ast.MethodCall(child.aggregate, child.field, paramsAst, loc); + } else { + ctx.err.notCallable()(loc); + return Ast.StaticCall(Ast.Id("__invalid__", loc), paramsAst, loc); + } + }; + +const parseSuffixFieldAccess = + ({ name }: $ast.SuffixFieldAccess): SuffixHandler => + (ctx) => + (child, loc) => { + return Ast.FieldAccess(child, parseId(name)(ctx), loc); + }; + +const suffixVisitor: (node: $ast.suffix) => SuffixHandler = + makeVisitor<$ast.suffix>()({ + SuffixUnboxNotNull: parseSuffixUnboxNotNull, + SuffixCall: parseSuffixCall, + SuffixFieldAccess: parseSuffixFieldAccess, + }); + +const parseSuffix = + ({ expression, suffixes }: $ast.Suffix): Handler => + (ctx) => { + return suffixes.reduce( + ({ child, range }, suffix) => { + const merged = mergeRange(range, toRange(suffix.loc)); + return { + child: suffixVisitor(suffix)(ctx)(child, merged), + range: merged, + }; + }, + { + child: parseExpression(expression)(ctx), + range: toRange(expression.loc), + }, + ).child; + }; + +const parseParens = ({ child }: $ast.Parens): Handler => { + return parseExpression(child); +}; + +// has to be an interface because of the way TS handles circular type references +// eslint-disable-next-line @typescript-eslint/no-empty-object-type +interface Binary extends $ast.Binary {} + +type Expression = + | $ast.Conditional + | Binary + | $ast.Unary + | $ast.Suffix + | $ast.Parens + | $ast.StructInstance + | $ast.IntegerLiteral + | $ast.BoolLiteral + | $ast.InitOf + | $ast.CodeOf + | $ast.Null + | $ast.StringLiteral + | $ast.Id; + +const parseExpression: (input: Expression) => Handler = + makeVisitor()({ + Conditional: parseConditional, + Binary: parseBinary, + Unary: parseUnary, + Suffix: parseSuffix, + Parens: parseParens, + StructInstance: parseStructInstance, + IntegerLiteral: parseIntegerLiteral, + BoolLiteral: parseBoolLiteral, + InitOf: parseInitOf, + CodeOf: parseCodeOf, + Null: parseNull, + StringLiteral: parseStringLiteral, + Id: parseVar, + }); + +const parseStatementLet = + ({ name, type, init, loc }: $ast.StatementLet): Handler => + (ctx) => { + return Ast.StatementLet( + parseOptionalId(name)(ctx), + type ? parseType(type)(ctx) : undefined, + parseExpression(init)(ctx), + toRange(loc), + ); + }; + +const parsePunnedField = + ({ name }: $ast.PunnedField): Handler<[Ast.Id, Ast.Id]> => + (ctx) => { + return [parseId(name)(ctx), parseId(name)(ctx)]; + }; + +const parseRegularField = + ({ + fieldName, + varName, + }: $ast.RegularField): Handler<[Ast.Id, Ast.OptionalId]> => + (ctx) => { + return [parseId(fieldName)(ctx), parseOptionalId(varName)(ctx)]; + }; + +const parseDestructItem: ( + node: $ast.destructItem, +) => Handler<[Ast.Id, Ast.OptionalId]> = makeVisitor<$ast.destructItem>()({ + PunnedField: parsePunnedField, + RegularField: parseRegularField, +}); + +const parseStatementDestruct = + ({ + type, + fields, + rest, + init, + loc, + }: $ast.StatementDestruct): Handler => + (ctx) => { + const ids: Map = new Map(); + for (const param of parseList(fields)) { + const pair = parseDestructItem(param)(ctx); + const [field] = pair; + const name = field.text; + if (ids.has(name)) { + ctx.err.duplicateField(name)(toRange(param.loc)); + } + ids.set(name, pair); + } + + return Ast.StatementDestruct( + parseTypeId(type)(ctx), + ids, + rest.$ === "RestArgument", + parseExpression(init)(ctx), + toRange(loc), + ); + }; + +const parseStatementBlock = + ({ body, loc }: $ast.StatementBlock): Handler => + (ctx) => { + return Ast.StatementBlock(parseStatements(body)(ctx), toRange(loc)); + }; + +const parseStatementReturn = + ({ expression, loc }: $ast.StatementReturn): Handler => + (ctx) => { + return Ast.StatementReturn( + expression ? parseExpression(expression)(ctx) : undefined, + toRange(loc), + ); + }; + +const parseStatementCondition = + ({ + condition, + trueBranch, + falseBranch, + loc, + }: $ast.StatementCondition): Handler => + (ctx) => { + if (typeof falseBranch === "undefined") { + return Ast.StatementCondition( + parseExpression(condition)(ctx), + parseStatements(trueBranch)(ctx), + undefined, + toRange(loc), + ); + } else if (falseBranch.$ === "FalseBranch") { + return Ast.StatementCondition( + parseExpression(condition)(ctx), + parseStatements(trueBranch)(ctx), + parseStatements(falseBranch.body)(ctx), + toRange(loc), + ); + } else { + return Ast.StatementCondition( + parseExpression(condition)(ctx), + parseStatements(trueBranch)(ctx), + [parseStatementCondition(falseBranch)(ctx)], + toRange(loc), + ); + } + }; + +const parseStatementWhile = + ({ + condition, + body, + loc, + }: $ast.StatementWhile): Handler => + (ctx) => { + return Ast.StatementWhile( + parseExpression(condition)(ctx), + parseStatements(body)(ctx), + toRange(loc), + ); + }; + +const parseStatementRepeat = + ({ + condition, + body, + loc, + }: $ast.StatementRepeat): Handler => + (ctx) => { + return Ast.StatementRepeat( + parseExpression(condition)(ctx), + parseStatements(body)(ctx), + toRange(loc), + ); + }; + +const parseStatementUntil = + ({ + condition, + body, + loc, + }: $ast.StatementUntil): Handler => + (ctx) => { + return Ast.StatementUntil( + parseExpression(condition)(ctx), + parseStatements(body)(ctx), + toRange(loc), + ); + }; + +const parseStatementTry = + ({ body, handler, loc }: $ast.StatementTry): Handler => + (ctx) => { + if (handler) { + return Ast.StatementTry( + parseStatements(body)(ctx), + { + catchName: parseOptionalId(handler.name)(ctx), + catchStatements: parseStatements(handler.body)(ctx), + }, + toRange(loc), + ); + } else { + return Ast.StatementTry( + parseStatements(body)(ctx), + undefined, + toRange(loc), + ); + } + }; + +const parseStatementForEach = + ({ + key, + value, + expression, + body, + loc, + }: $ast.StatementForEach): Handler => + (ctx) => { + return Ast.StatementForEach( + parseOptionalId(key)(ctx), + parseOptionalId(value)(ctx), + parseExpression(expression)(ctx), + parseStatements(body)(ctx), + toRange(loc), + ); + }; + +const parseStatementExpression = + ({ + expression, + loc, + }: $ast.StatementExpression): Handler => + (ctx) => { + return Ast.StatementExpression( + parseExpression(expression)(ctx), + toRange(loc), + ); + }; + +const parseStatementAssign = + ({ + left, + operator, + right, + loc, + }: $ast.StatementAssign): Handler< + Ast.StatementAssign | Ast.StatementAugmentedAssign + > => + (ctx) => { + if (operator === "=") { + return Ast.StatementAssign( + parseExpression(left)(ctx), + parseExpression(right)(ctx), + toRange(loc), + ); + } else { + return Ast.StatementAugmentedAssign( + operator, + parseExpression(left)(ctx), + parseExpression(right)(ctx), + toRange(loc), + ); + } + }; + +const parseStatement: (node: $ast.statement) => Handler = + makeVisitor<$ast.statement>()({ + StatementLet: parseStatementLet, + StatementDestruct: parseStatementDestruct, + StatementBlock: parseStatementBlock, + StatementReturn: parseStatementReturn, + StatementCondition: parseStatementCondition, + StatementWhile: parseStatementWhile, + StatementRepeat: parseStatementRepeat, + StatementUntil: parseStatementUntil, + StatementTry: parseStatementTry, + StatementForEach: parseStatementForEach, + StatementExpression: parseStatementExpression, + StatementAssign: parseStatementAssign, + }); + +const parseStatements = + (nodes: readonly $ast.statement[]): Handler => + (ctx) => { + return map(nodes, parseStatement)(ctx); + }; + +const parseFunctionAttribute = + (node: $ast.FunctionAttribute): Handler => + (ctx) => { + if (typeof node.name === "string") { + return Ast.FunctionAttributeRest(node.name, toRange(node.loc)); + } + + return Ast.FunctionAttributeGet( + node.name.methodId + ? parseExpression(node.name.methodId)(ctx) + : undefined, + toRange(node.loc), + ); + }; + +const checkAttributes = + (kind: "constant" | "function") => + ( + ctx: Context, + isAbstract: boolean, + attributes: readonly ( + | $ast.FunctionAttribute + | $ast.ConstantAttribute + )[], + loc: $.Loc, + ) => { + const { duplicate, tooAbstract, notAbstract } = ctx.err[kind]; + const k: Set = new Set(); + for (const { name, loc } of attributes) { + const type = typeof name === "string" ? name : name.$; + if (k.has(type)) { + duplicate(type)(toRange(loc)); + } + k.add(type); + } + if (isAbstract && !k.has("abstract")) { + notAbstract()(toRange(loc)); + } + if (!isAbstract && k.has("abstract")) { + tooAbstract()(toRange(loc)); + } + }; + +const parseFunctionAttributes = + ( + nodes: readonly $ast.FunctionAttribute[], + isAbstract: boolean, + loc: $.Loc, + ): Handler => + (ctx) => { + checkAttributes("function")(ctx, isAbstract, nodes, loc); + return map(nodes, parseFunctionAttribute)(ctx); + }; + +const parseConstantAttribute = + ({ name, loc }: $ast.ConstantAttribute): Handler => + (_ctx) => { + return Ast.ConstantAttribute(name, toRange(loc)); + }; + +const parseConstantAttributes = + ( + nodes: readonly $ast.ConstantAttribute[], + isAbstract: boolean, + loc: $.Loc, + noAttributes: boolean, + ): Handler => + (ctx) => { + const [head] = nodes; + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + if (noAttributes && head) { + ctx.err.topLevelConstantWithAttribute()(toRange(head.loc)); + } + checkAttributes("constant")(ctx, isAbstract, nodes, loc); + return map(nodes, parseConstantAttribute)(ctx); + }; + +const parseParameter = + ({ name, type, loc }: $ast.Parameter): Handler => + (ctx) => { + return Ast.TypedParameter( + parseOptionalId(name)(ctx), + parseType(type)(ctx), + toRange(loc), + ); + }; + +const parseTypeId = + ({ name, loc }: $ast.TypeId): Handler => + (_ctx) => { + return Ast.TypeId(name, toRange(loc)); + }; + +const applyFormat = + (type: Ast.Type, storage: $ast.storage, asLoc: Range): Handler => + (ctx) => { + const fallback = Ast.TypeCons(Ast.TypeId("ERROR", asLoc), [], asLoc); + if (type.kind === "TyInt") { + if (storage.$ === "CoinsStorage") { + return Ast.TypeInt( + Ast.IFVarInt("unsigned", "16", toRange(storage.loc)), + type.loc, + ); + } else if (storage.$ === "IntStorage") { + const width = parseInt(storage.width, 10); + if (storage.isVar) { + if (width === 16) { + return Ast.TypeInt( + Ast.IFVarInt( + typeof storage.isUnsigned === "undefined" + ? "signed" + : "unsigned", + "16", + toRange(storage.loc), + ), + type.loc, + ); + } else if (width === 32) { + return Ast.TypeInt( + Ast.IFVarInt( + typeof storage.isUnsigned === "undefined" + ? "signed" + : "unsigned", + "32", + toRange(storage.loc), + ), + type.loc, + ); + } else { + ctx.err.wrongVarIntSize()(asLoc); + return fallback; + } + } else if (storage.isUnsigned) { + if (1 <= width && width <= 256) { + return Ast.TypeInt( + Ast.IFInt("unsigned", width, asLoc), + type.loc, + ); + } else { + ctx.err.wrongUIntSize()(asLoc); + return fallback; + } + } else { + if (1 <= width && width <= 257) { + return Ast.TypeInt( + Ast.IFInt("signed", width, asLoc), + type.loc, + ); + } else { + ctx.err.wrongIntSize()(asLoc); + return fallback; + } + } + } else { + ctx.err.wrongFormat("Integer")(asLoc); + return fallback; + } + } else if (type.kind === "TySlice") { + if (storage.$ === "RemainingStorage") { + return Ast.TypeSlice(Ast.SFRemaining(asLoc), type.loc); + } else if (storage.$ === "BytesStorage") { + const width = parseInt(storage.width, 10); + if (width === 32 || width === 64) { + return Ast.TypeSlice( + Ast.SFBits(width * 8, asLoc), + type.loc, + ); + } else { + ctx.err.wrongSliceSize()(asLoc); + return fallback; + } + } else { + ctx.err.wrongFormat("Slice")(asLoc); + return fallback; + } + } else if (type.kind === "TyCell" || type.kind === "TyBuilder") { + if (storage.$ === "RemainingStorage") { + const Type = + type.kind === "TyCell" ? Ast.TypeCell : Ast.TypeBuilder; + return Type(Ast.SFRemaining(asLoc), type.loc); + } else { + ctx.err.wrongFormat( + type.kind === "TyCell" ? "Cell" : "Builder", + )(asLoc); + return fallback; + } + } else if (type.kind === "cons_type" && type.name.text === "Maybe") { + // NB! Compatibility with old code that allowed `Int? as int32` + // instead of `(Int as int32)?` + const arg = type.typeArgs[0]; + if (type.typeArgs.length !== 1 || typeof arg === "undefined") { + return throwInternal("Maybe can only have one argument"); + } + const result = applyFormat(arg, storage, asLoc)(ctx); + return Ast.TypeCons(type.name, [result], type.loc); + } else { + ctx.err.cannotHaveFormat()(type.loc); + return fallback; + } + }; + +const parseTypeAs = + ({ type, as, loc }: $ast.TypeAs): Handler => + (ctx) => { + const onlyAs = as[0]; + if (as.length === 0 || typeof onlyAs === "undefined") { + return parseType(type)(ctx); + } + if (as.length > 1) { + ctx.err.duplicateAs()(toRange(loc)); + return Ast.TypeCons( + Ast.TypeId("ERROR", toRange(loc)), + [], + toRange(loc), + ); + } + const asLoc = toRange(loc); + const result = parseType(type)(ctx); + return applyFormat(result, onlyAs, asLoc)(ctx); + }; + +const flattenName = (name: $ast.TypeId | $ast.MapKeyword | $ast.Bounced) => { + if (name.$ === "MapKeyword") { + return "map"; + } else if (name.$ === "Bounced") { + return "bounced"; + } else { + return name.name; + } +}; + +const parseTypeGeneric = + ({ name, args, loc }: $ast.TypeGeneric): Handler => + (ctx) => { + return Ast.TypeCons( + Ast.TypeId(flattenName(name), toRange(name.loc)), + map(parseList(args), parseTypeAs)(ctx), + toRange(loc), + ); + }; + +const parseTypeOptional = + ({ type, optionals }: $ast.TypeOptional): Handler => + (ctx) => { + return optionals.reduce((acc, optional) => { + return Ast.TypeCons( + Ast.TypeId("Maybe", toRange(optional.loc)), + [acc], + toRange(optional.loc), + ); + }, parseType(type)(ctx)); + }; + +const parseTypeRegular = + ({ child }: $ast.TypeRegular): Handler => + (ctx) => { + const range = toRange(child.loc); + if (child.name === "Int") { + return Ast.TypeInt(Ast.IFInt("signed", 257, range), range); + } else if (child.name === "Slice") { + return Ast.TypeSlice(Ast.SFDefault(range), range); + } else if (child.name === "Cell") { + return Ast.TypeCell(Ast.SFDefault(range), range); + } else if (child.name === "Builder") { + return Ast.TypeBuilder(Ast.SFDefault(range), range); + } + return Ast.TypeCons(parseTypeId(child)(ctx), [], range); + }; + +const parseTypeTensor = + ({ head, tail, loc }: $ast.TypeTensor): Handler => + (ctx) => { + return Ast.TypeTensor( + map([head, ...tail], parseType)(ctx), + toRange(loc), + ); + }; + +const parseTypeTuple = + ({ types, loc }: $ast.TypeTuple): Handler => + (ctx) => { + return Ast.TypeTuple( + map(parseList(types), parseType)(ctx), + toRange(loc), + ); + }; + +const parseTypeUnit = + ({ loc }: $ast.TypeUnit): Handler => + (_ctx) => { + return Ast.TypeUnit(toRange(loc)); + }; + +type RawType = + | $ast.TypeAs + | $ast.TypeGeneric + | $ast.TypeRegular + | $ast.TypeOptional + | $ast.TypeTensor + | $ast.TypeUnit + | $ast.TypeTuple; + +const parseType: (node: RawType) => Handler = makeVisitor()({ + TypeAs: parseTypeAs, + TypeGeneric: parseTypeGeneric, + TypeOptional: parseTypeOptional, + TypeRegular: parseTypeRegular, + TypeTensor: parseTypeTensor, + TypeTuple: parseTypeTuple, + TypeUnit: parseTypeUnit, +}); + +const parseFieldDecl = + ({ name, type, expression, loc }: $ast.FieldDecl): Handler => + (ctx) => { + return Ast.FieldDecl( + parseId(name)(ctx), + parseType(type)(ctx), + expression ? parseExpression(expression)(ctx) : undefined, + toRange(loc), + ); + }; + +const parseReceiverParam = + (param: $ast.receiverParam): Handler => + (ctx) => { + return !param + ? Ast.ReceiverFallback() + : param.$ === "Parameter" + ? Ast.ReceiverSimple(parseParameter(param)(ctx)) + : Ast.ReceiverComment(parseStringLiteral(param)(ctx)); + }; + +const parseReceiverReceive = + ({ type, param, body, loc }: $ast.Receiver): Handler => + (ctx) => { + return Ast.Receiver( + Ast.ReceiverInternal( + parseReceiverParam(param)(ctx), + toRange(type.loc), + ), + map(body, parseStatement)(ctx), + toRange(loc), + ); + }; + +const parseReceiverExternal = + ({ type, param, body, loc }: $ast.Receiver): Handler => + (ctx) => { + return Ast.Receiver( + Ast.ReceiverExternal( + parseReceiverParam(param)(ctx), + toRange(type.loc), + ), + map(body, parseStatement)(ctx), + toRange(loc), + ); + }; + +const emptyLoc = { $: "range", start: 0, end: 0 } as const; +const repairParam: $ast.receiverParam = { + $: "Parameter", + name: { + $: "Id", + name: "__invalid__", + loc: emptyLoc, + }, + type: { + $: "TypeAs", + as: [], + type: { + $: "TypeOptional", + optionals: [], + type: { + $: "TypeRegular", + child: { + $: "TypeId", + name: "__Invalid__", + loc: emptyLoc, + }, + loc: emptyLoc, + }, + loc: emptyLoc, + }, + loc: emptyLoc, + }, + loc: emptyLoc, +}; + +const parseReceiverBounced = + ({ type, param, body, loc }: $ast.Receiver): Handler => + (ctx) => { + if (typeof param === "undefined") { + ctx.err.noBouncedWithoutArg()(toRange(loc)); + param = repairParam; + } + + if (param.$ === "StringLiteral") { + ctx.err.noBouncedWithString()(toRange(loc)); + param = repairParam; + } + + return Ast.Receiver( + Ast.ReceiverBounce(parseParameter(param)(ctx), toRange(type.loc)), + map(body, parseStatement)(ctx), + toRange(loc), + ); + }; + +const parserByReceiverType: Record< + $ast.ReceiverType["name"], + (node: $ast.Receiver) => Handler +> = { + bounced: parseReceiverBounced, + receive: parseReceiverReceive, + external: parseReceiverExternal, +}; + +const parseReceiver = (node: $ast.Receiver): Handler => { + return parserByReceiverType[node.type.name](node); +}; + +const defaultShuffle = { + args: [], + ret: [], +}; + +const parseAsmShuffle = + (node: $ast.shuffle | undefined): Handler => + (ctx) => { + if (!node) { + return defaultShuffle; + } + + return { + args: map(node.ids, parseId)(ctx), + ret: node.to ? map(node.to, parseIntegerLiteralValue)(ctx) : [], + }; + }; + +const parseUnsupportedAsmFunction = + (node: $ast.AsmFunction): Handler => + (ctx) => { + ctx.err.unsupportedAsmFunctionInContracts()(toRange(node.loc)); + return parseAsmFunction(node)(ctx); + }; + +const parseAsmFunction = + (node: $ast.AsmFunction): Handler => + (ctx) => { + return Ast.AsmFunctionDef( + parseAsmShuffle(node.shuffle)(ctx), + parseFunctionAttributes(node.attributes, false, node.loc)(ctx), + parseId(node.name)(ctx), + node.returnType ? parseType(node.returnType)(ctx) : undefined, + map(parseList(node.parameters), parseParameter)(ctx), + [node.instructions.trim()], + toRange(node.loc), + ); + }; + +const parseContractInit = + ({ parameters, body, loc }: $ast.ContractInit): Handler => + (ctx) => { + return Ast.ContractInit( + map(parseList(parameters), parseParameter)(ctx), + map(body, parseStatement)(ctx), + toRange(loc), + ); + }; + +const parseConstantDefInModule = + (node: $ast.Constant): Handler => + (ctx) => { + return parseConstantDef(node, true)(ctx); + }; + +const parseConstantDef = + (node: $ast.Constant, noAttributes: boolean): Handler => + (ctx) => { + const result = parseConstant(node, noAttributes)(ctx); + + if (result.kind !== "constant_def") { + ctx.err.noConstantDecl()(toRange(node.loc)); + return { + ...result, + kind: "constant_def", + initializer: Ast.Number("10", 0n, toRange(node.loc)), + }; + } + + return result; + }; + +const parseConstantDefLocal = (node: $ast.Constant) => + parseConstantDef(node, false); + +const parseConstant = + ( + node: $ast.Constant, + noAttributes: boolean, + ): Handler => + (ctx) => { + const name = parseId(node.name)(ctx); + const type = parseType(node.type)(ctx); + + if (node.body.$ === "ConstantDeclaration") { + const attributes = parseConstantAttributes( + node.attributes, + true, + node.loc, + noAttributes, + )(ctx); + return Ast.ConstantDecl(attributes, name, type, toRange(node.loc)); + } else { + const attributes = parseConstantAttributes( + node.attributes, + false, + node.loc, + noAttributes, + )(ctx); + const initializer = parseExpression(node.body.expression)(ctx); + return Ast.ConstantDef( + attributes, + name, + type, + initializer, + toRange(node.loc), + ); + } + }; + +const parseConstantLocal = (node: $ast.Constant) => parseConstant(node, false); + +const parseContract = + ({ + name, + attributes, + parameters, + traits, + declarations, + loc, + }: $ast.Contract): Handler => + (ctx) => { + const params = parseList<$ast.Parameter>(parameters?.values).map( + (param) => { + return parseFieldDecl({ + $: "FieldDecl", + name: param.name, + type: param.type, + expression: undefined, + loc: param.loc, + })(ctx); + }, + ); + + return Ast.Contract( + parseTypeId(name)(ctx), + map(parseList(traits), parseTypeId)(ctx), + map(attributes, parseContractAttribute)(ctx), + typeof parameters !== "undefined" ? params : undefined, + map(declarations, parseContractItem)(ctx), + toRange(loc), + ); + }; + +const parseFunctionDef = + (node: $ast.$Function): Handler => + (ctx) => { + const result = parseFunction(node)(ctx); + + if (result.kind !== "function_def") { + ctx.err.noFunctionDecl()(toRange(node.loc)); + return { + ...parseFunction(node)(ctx), + kind: "function_def", + statements: [], + }; + } + + return result; + }; + +const parseFunction = + (node: $ast.$Function): Handler => + (ctx) => { + const name = parseId(node.name)(ctx); + const returnType = node.returnType + ? parseType(node.returnType)(ctx) + : undefined; + const parameters = map(parseList(node.parameters), parseParameter)(ctx); + + if (node.body.$ === "FunctionDeclaration") { + const attributes = parseFunctionAttributes( + node.attributes, + true, + node.loc, + )(ctx); + return Ast.FunctionDecl( + attributes, + name, + returnType, + parameters, + toRange(node.loc), + ); + } else { + const attributes = parseFunctionAttributes( + node.attributes, + false, + node.loc, + )(ctx); + const statements = map(node.body.body, parseStatement)(ctx); + return Ast.FunctionDef( + attributes, + name, + returnType, + parameters, + statements, + toRange(node.loc), + ); + } + }; + +const parseMessageDecl = + ({ + name, + opcode, + fields, + loc, + }: $ast.MessageDecl): Handler => + (ctx) => { + return Ast.MessageDecl( + parseTypeId(name)(ctx), + opcode ? parseExpression(opcode)(ctx) : undefined, + map(parseList(fields), parseFieldDecl)(ctx), + toRange(loc), + ); + }; + +const parseNativeFunctionDecl = + ({ + name, + attributes, + nativeName, + parameters, + returnType, + loc, + }: $ast.NativeFunctionDecl): Handler => + (ctx) => { + return Ast.NativeFunctionDecl( + map(attributes, parseFunctionAttribute)(ctx), + parseId(name)(ctx), + parseFuncId(nativeName)(ctx), + map(parseList(parameters), parseParameter)(ctx), + returnType ? parseType(returnType)(ctx) : undefined, + toRange(loc), + ); + }; + +const parseStructDecl = + ({ name, fields, loc }: $ast.StructDecl): Handler => + (ctx) => { + return Ast.StructDecl( + parseTypeId(name)(ctx), + map(parseList(fields), parseFieldDecl)(ctx), + toRange(loc), + ); + }; + +const parseContractAttribute = + ({ name, loc }: $ast.ContractAttribute): Handler => + (ctx) => { + return Ast.ContractAttribute( + parseStringLiteral(name)(ctx).value, + toRange(loc), + ); + }; + +const parseTrait = + ({ + name, + traits, + attributes, + declarations, + loc, + }: $ast.Trait): Handler => + (ctx) => { + return Ast.Trait( + parseTypeId(name)(ctx), + traits ? map(parseList(traits), parseTypeId)(ctx) : [], + map(attributes, parseContractAttribute)(ctx), + map(declarations, parseTraitItem)(ctx), + toRange(loc), + ); + }; + +const parseContractItem: ( + input: $ast.contractItemDecl, +) => Handler = makeVisitor<$ast.contractItemDecl>()({ + ContractInit: parseContractInit, + FieldDecl: parseFieldDecl, + Receiver: parseReceiver, + Function: parseFunctionDef, + AsmFunction: parseUnsupportedAsmFunction, + Constant: parseConstantDefLocal, +}); + +const parseTraitItem: (input: $ast.traitItemDecl) => Handler = + makeVisitor<$ast.traitItemDecl>()({ + FieldDecl: parseFieldDecl, + Receiver: parseReceiver, + Function: parseFunction, + AsmFunction: parseUnsupportedAsmFunction, + Constant: parseConstantLocal, + }); + +type ModuleItemAux = Exclude<$ast.moduleItem, $ast.PrimitiveTypeDecl>; + +const parseModuleItemAux: (input: ModuleItemAux) => Handler = + makeVisitor()({ + Function: parseFunctionDef, + AsmFunction: parseAsmFunction, + NativeFunctionDecl: parseNativeFunctionDecl, + Constant: parseConstantDefInModule, + StructDecl: parseStructDecl, + MessageDecl: parseMessageDecl, + Contract: parseContract, + Trait: parseTrait, + }); + +const parseModuleItem = + (node: $ast.moduleItem): Handler => + (ctx) => { + if (node.$ === "PrimitiveTypeDecl") { + ctx.err.deprecatedPrimitiveDecl()(toRange(node.loc)); + return []; + } + return [parseModuleItemAux(node)(ctx)]; + }; + +const detectLanguage = (path: string): Language | undefined => { + if (path.endsWith(".fc") || path.endsWith(".func")) { + return "func"; + } + + if (path.endsWith(".tact")) { + return "tact"; + } + + return undefined; +}; + +const guessExtension = ( + importText: string, +): { language: Language; guessedPath: string } => { + const language = detectLanguage(importText); + if (language) { + return { guessedPath: importText, language }; + } else { + return { guessedPath: `${importText}.tact`, language: "tact" }; + } +}; + +const stdlibPrefix = "@stdlib/"; + +const parseImportString = + (importText: string, loc: $.Loc): Handler => + (ctx) => { + if (importText.endsWith("/")) { + ctx.err.noFolderImports()(toRange(loc)); + importText = importText.slice(0, -1); + } + + if (importText.includes("\\")) { + ctx.err.importWithBackslash()(toRange(loc)); + importText = importText.replace(/\\/g, "/"); + } + + const { guessedPath, language } = guessExtension(importText); + + if (guessedPath.startsWith(stdlibPrefix)) { + const path = fromString(guessedPath.substring(stdlibPrefix.length)); + + if (path.stepsUp !== 0) { + ctx.err.importWithBackslash()(toRange(loc)); + } + + return { + path, + type: "stdlib", + language, + }; + } else if ( + guessedPath.startsWith("./") || + guessedPath.startsWith("../") + ) { + return { + path: fromString(guessedPath), + type: "relative", + language, + }; + } else { + ctx.err.invalidImport()(toRange(loc)); + return { + path: emptyPath, + type: "relative", + language: "tact", + }; + } + }; + +const parseImport = + ({ path, loc }: $ast.Import): Handler => + (ctx) => { + const stringLiteral = parseStringLiteral(path)(ctx); + const parsedString: string = JSON.parse(`"${stringLiteral.value}"`); + return Ast.Import( + parseImportString(parsedString, loc)(ctx), + toRange(loc), + ); + }; + +const parseModule = + ({ imports, items }: $ast.Module): Handler => + (ctx) => { + return Ast.Module( + map(imports, parseImport)(ctx), + map(items, parseModuleItem)(ctx).flat(), + ); + }; + +// const parseJustImports = +// ({ imports }: $ast.JustImports): Handler => +// (ctx) => { +// return map(imports, parseImport)(ctx); +// }; + +export const getParser = (logRaw: SourceLogger) => { + const err = SyntaxErrors(logRaw); + + return (text: string): Ast.Module => { + const result = $.parse({ + grammar: G.Module, + space: G.space, + text, + }); + + if (result.$ === "error") { + const { expected, position } = result.error; + err.expected(expected)({ + start: position, + end: position, + }); + return Ast.Module([], []); + } + + return parseModule(result.value)({ + err, + }); + }; +}; diff --git a/src/next/grammar/parser-error.ts b/src/next/grammar/parser-error.ts new file mode 100644 index 0000000000..36405a5f56 --- /dev/null +++ b/src/next/grammar/parser-error.ts @@ -0,0 +1,228 @@ +import type { SourceLogger } from "@/error/logger-util"; +import type { Range } from "@/error/range"; + +const attributeSchema = (name: string, l: SourceLogger) => ({ + duplicate: (attr: string) => (loc: Range) => { + return l.at(loc).error(l.text`Duplicate ${name} attribute "${attr}"`); + }, + notAbstract: () => (loc: Range) => { + return l + .at(loc) + .error( + l.text`Abstract ${name} can only be declared inside traits and should have the abstract modifier`, + ); + }, + tooAbstract: () => (loc: Range) => { + return l + .at(loc) + .error(l.text`Non-abstract ${name} has abstract modifier`); + }, +}); + +const getExpectedText = (expected: ReadonlySet) => { + const result: string[] = []; + const failures = [...expected].sort(); + for (const [idx, failure] of failures.entries()) { + if (idx > 0) { + if (idx === failures.length - 1) { + result.push(failures.length > 2 ? ", or " : " or "); + } else { + result.push(", "); + } + } + result.push(failure); + } + return result.join(""); +}; + +export const SyntaxErrors = (l: SourceLogger) => ({ + constant: attributeSchema("constant", l), + function: attributeSchema("function", l), + + topLevelConstantWithAttribute: () => (loc: Range) => { + return l + .at(loc) + .error(l.text`Module-level constants do not support attributes`); + }, + literalTooLong: () => (loc: Range) => { + return l.at(loc).error(l.text`Bitstring has more than 128 digits`); + }, + extraneousComma: () => (loc: Range) => { + return l + .at(loc) + .error( + l.text`Empty parameter list should not have a dangling comma`, + ); + }, + duplicateField: (name: string) => (loc: Range) => { + return l + .at(loc) + .error(l.text`Duplicate field destructuring: "${name}"`); + }, + restShouldBeLast: () => (loc: Range) => { + return l.at(loc).error(l.text`Rest parameter should be last`); + }, + importWithBackslash: () => (loc: Range) => { + return l.at(loc).error(l.text`Import path can't contain "\\"`); + }, + reservedVarPrefix: (prefix: string) => (loc: Range) => { + return l + .at(loc) + .error(l.text`Variable name cannot start with "${prefix}"`); + }, + notCallable: () => (loc: Range) => { + return l.at(loc).error(l.text`Expression is not callable`); + }, + noBouncedWithoutArg: () => (loc: Range) => { + return l + .at(loc) + .error( + l.text`bounced() receiver should accept a Message, bounced or Slice`, + ); + }, + noBouncedWithString: () => (loc: Range) => { + return l + .at(loc) + .error( + l.text`bounced() receiver can only accept a Message, bounced or Slice`, + ); + }, + noConstantDecl: () => (loc: Range) => { + return l + .at(loc) + .error(l.text`Constant definition requires an initializer`); + }, + noFunctionDecl: () => (loc: Range) => { + return l + .at(loc) + .error(l.text`Only full function definitions are allowed here`); + }, + expected: (expects: ReadonlySet) => (loc: Range) => { + return l.at(loc).error(l.text`Expected ${getExpectedText(expects)}`); + }, + invalidFuncId: () => (loc: Range) => { + return l.at(loc).error(l.text`Invalid FunC identifier`); + }, + reservedFuncId: () => (loc: Range) => { + return l.at(loc).error(l.text`Reserved FunC identifier`); + }, + numericFuncId: () => (loc: Range) => { + return l.at(loc).error(l.text`FunC identifier cannot be a number`); + }, + leadingZeroUnderscore: () => (loc: Range) => { + return l + .at(loc) + .error( + l.text`Numbers with leading zeroes cannot use underscores for JS compatibility`, + ); + }, + noFolderImports: () => (loc: Range) => { + return l.at(loc).error(l.text`Cannot import a folder`); + }, + invalidImport: () => (loc: Range) => { + return l + .at(loc) + .error(l.text`Import must start with ./, ../ or @stdlib/`); + }, + escapingImport: () => (loc: Range) => { + return l + .at(loc) + .error(l.text`Standard library imports should be inside its root`); + }, + asNotAllowed: () => (loc: Range) => { + return l.at(loc).error(l.text`"as" type is not allowed here`); + }, + multipleOptionals: () => (loc: Range) => { + return l.at(loc).error(l.text`Nested optional types are not allowed`); + }, + onlyOptionalOfNamed: () => (loc: Range) => { + return l.at(loc).error(l.text`Only named type can be optional`); + }, + genericArgCount: + (name: string, expectedCount: number, gotCount: number) => + (loc: Range) => { + return l + .at(loc) + .error( + l.text`${name}<> expects exactly ${String(expectedCount)} arguments, but got ${String(gotCount)}`, + ); + }, + unknownType: (name: string) => (loc: Range) => { + return l.at(loc).error(l.text`Unknown generic type: ${name}`); + }, + onlyBouncedOfNamed: () => (loc: Range) => { + return l.at(loc).error(l.text`Only named type can be bounced<>`); + }, + mapOnlyOneAs: (name: "key" | "value") => (loc: Range) => { + return l + .at(loc) + .error(l.text`Cannot use several "as" on ${name} of a map`); + }, + cannotBeOptional: (name: "key" | "value") => (loc: Range) => { + return l.at(loc).error(l.text`${name} cannot be optional`); + }, + onlyTypeId: (name: "key" | "value") => (loc: Range) => { + return l.at(loc).error(l.text`${name} can only be a named type`); + }, + fieldOnlyOneAs: () => (loc: Range) => { + return l.at(loc).error(l.text`Cannot use several "as" on a field type`); + }, + noOptionalFieldType: () => (loc: Range) => { + return l.at(loc).error(l.text`Field type cannot be optional`); + }, + fieldMustBeNamed: () => (loc: Range) => { + return l + .at(loc) + .error(l.text`Only named type can be a type of a field`); + }, + unknownGeneric: () => (loc: Range) => { + return l.at(loc).error(l.text`Unknown generic type`); + }, + noWildcard: () => (loc: Range) => { + return l.at(loc).error(l.text`Wildcard not allowed here`); + }, + undefinedUnicodeCodepoint: () => (loc: Range) => { + return l.at(loc).error(l.text`Undefined Unicode code-point`); + }, + unsupportedAsmFunctionInContracts: () => (loc: Range) => { + return l + .at(loc) + .error( + l.text`Assembly functions are only allowed at the module level - outside contracts or traits`, + ); + }, + duplicateAs: () => (loc: Range) => { + return l.at(loc).error(l.text`"as" cannot be nested`); + }, + wrongVarIntSize: () => (loc: Range) => { + return l.at(loc).error(l.text`Varint can only be 16 or 32 bits wide`); + }, + wrongUIntSize: () => (loc: Range) => { + return l + .at(loc) + .error(l.text`Unsigned integer must be 1 to 256 bits wide`); + }, + wrongIntSize: () => (loc: Range) => { + return l + .at(loc) + .error(l.text`Signed integer must be 1 to 257 bits wide`); + }, + wrongFormat: (name: string) => (loc: Range) => { + return l + .at(loc) + .error(l.text`${name} cannot be defined with this storage format`); + }, + wrongSliceSize: () => (loc: Range) => { + return l + .at(loc) + .error(l.text`Slice byte format must either be 32 or 64`); + }, + cannotHaveFormat: () => (loc: Range) => { + return l.at(loc).error(l.text`This type cannot have format definition`); + }, + deprecatedPrimitiveDecl: () => (loc: Range) => { + l.at(loc).warn(l.text`"primitive" type declaration are deprecated`); + }, +}); + +export type SyntaxErrors = ReturnType>; diff --git a/src/next/grammar/path.ts b/src/next/grammar/path.ts new file mode 100644 index 0000000000..b21d0ffb11 --- /dev/null +++ b/src/next/grammar/path.ts @@ -0,0 +1,60 @@ +import { throwInternalCompilerError } from "@/error/errors"; +import { RelativePath } from "@/next/ast/common"; +import { repeat } from "@/utils/array"; + +/** + * Constructor for relative paths + */ +const RelativePath = ( + stepsUp: number, + segments: readonly string[], +): RelativePath => { + if (stepsUp < 0) { + throwInternalCompilerError("Negative number of ../ in path"); + } + const result: RelativePath = { + stepsUp, + segments: Object.freeze(segments), + }; + return Object.freeze(result); +}; + +/** + * Convert raw string with relative POSIX path into RelativePath + */ +export const fromString = (raw: string): RelativePath => { + return raw.split("/").map(parseSegment).reduce(appendPath, emptyPath); +}; + +/** + * Convert RelativePath to string. + */ +export const asString = ({ stepsUp, segments }: RelativePath): string => { + return [...repeat("..", stepsUp), ...segments].join("/"); +}; + +/** + * Empty path, equivalent to "." + */ +export const emptyPath = RelativePath(0, []); + +/** + * Combine two relative paths + */ +const appendPath = (left: RelativePath, right: RelativePath): RelativePath => { + const delta = right.stepsUp - left.segments.length; + return RelativePath(left.stepsUp + Math.max(0, delta), [ + ...left.segments.slice(0, Math.max(0, -delta)), + ...right.segments, + ]); +}; + +const parseSegment = (segment: string): RelativePath => { + if (segment === "..") { + return RelativePath(1, []); + } + if (segment === "." || segment === "") { + return emptyPath; + } + return RelativePath(0, [segment]); +}; diff --git a/src/next/grammar/src-info.ts b/src/next/grammar/src-info.ts new file mode 100644 index 0000000000..8c054bc90f --- /dev/null +++ b/src/next/grammar/src-info.ts @@ -0,0 +1,279 @@ +import { throwInternalCompilerError } from "@/error/errors"; +import type { ItemOrigin } from "@/imports/source"; + +type LineAndColumnInfo = { + lineNum: number; + colNum: number; + toString(...ranges: number[][]): string; +}; + +type Interval = { + contents: string; + getLineAndColumnMessage(): string; + getLineAndColumn(): LineAndColumnInfo; + startIdx: number; + endIdx: number; +}; + +// Do not export! Use isSrcInfo +const srcInfoSymbol = Symbol("src-info"); + +export const isSrcInfo = (t: unknown): t is SrcInfo => { + return ( + typeof t === "object" && + t !== null && + srcInfoSymbol in t && + Boolean(t[srcInfoSymbol]) + ); +}; + +export interface SrcInfo { + file: string | null; + contents: string; + interval: Interval; + origin: ItemOrigin; + + /** + * Tag so that custom snapshot serializer can distinguish it + */ + [srcInfoSymbol]: true; + /** + * toJSON method is provided, so that it's not serialized into snapshots + */ + toJSON: () => object; +} + +export const srcInfoEqual = (left: SrcInfo, right: SrcInfo): boolean => { + return ( + left.file === right.file && + left.interval.contents === right.interval.contents && + left.interval.startIdx === right.interval.startIdx && + left.interval.endIdx === right.interval.endIdx + ); +}; + +const isEndline = (s: string) => s === "\n"; + +const repeat = (s: string, n: number): string => new Array(n + 1).join(s); + +type Range = { + start: number; + end: number; +}; + +const intersect = (a: Range, b: Range): Range => { + return { + start: Math.max(a.start, b.start), + end: Math.min(a.end, b.end), + }; +}; + +const shift = (a: Range, b: number) => { + return { + start: a.start + b, + end: a.end + b, + }; +}; + +type Line = { + id: number; + text: string; + range: Range; +}; + +/** + * Convert code into a list of lines + */ +const toLines = (source: string): Line[] => { + const result: Line[] = []; + let position = 0; + for (const [id, text] of source.split("\n").entries()) { + result.push({ + id, + text, + range: { + start: position, + end: position + text.length, + }, + }); + position += text.length + 1; + } + return result; +}; + +/** + * Should wrap string into ANSI codes for coloring + */ +type Colorer = (s: string) => string; + +type ErrorPrinterParams = { + /** + * Number of context lines below and above error + */ + contextLines: number; + /** + * Colorer for code with error + */ + error: Colorer; + /** + * Colorer for context lines of code + */ + context: Colorer; +}; + +const getErrorPrinter = ({ + error, + context, + contextLines, +}: ErrorPrinterParams) => { + const displayLine = (line: Line, range: Range) => { + // Only the line that contains range.start is underlined in error message + // Otherwise error on `while (...) {}` would display the whole loop body, for example + const hasInterval = + line.range.start <= range.start && range.start <= line.range.end; + + // Find the line-relative range + const mapped = shift(intersect(range, line.range), -line.range.start); + + // All lines except with error message are displayed in gray + if (!hasInterval) { + return [ + { + id: line.id, + text: context(line.text), + hasInterval, + startOfError: mapped.start, + }, + ]; + } + + // Source line with error colored + const sourceLine = { + id: line.id, + text: [ + line.text.substring(0, mapped.start), + error(line.text.substring(mapped.start, mapped.end)), + line.text.substring(mapped.end), + ].join(""), + hasInterval: true, + startOfError: mapped.start, + }; + + // Wiggly line underneath it + const underline = { + id: null, + text: [ + repeat(" ", mapped.start), + "^", + repeat("~", Math.max(0, mapped.end - mapped.start - 1)), + ].join(""), + hasInterval: true, + startOfError: mapped.start, + }; + + return [sourceLine, underline]; + }; + + const show = (str: string, range: Range): string => { + // Display all lines of source file + const lines = toLines(str).flatMap((line) => displayLine(line, range)); + + // Find first and lines lines with error message + const firstLineNum = lines.findIndex((line) => line.hasInterval); + const lastLineNum = lines.findLastIndex((line) => line.hasInterval); + if (firstLineNum === -1 || lastLineNum === -1) { + throwInternalCompilerError( + `Interval [${range.start}, ${range.end}[ is empty or out of source bounds (${str.length})`, + ); + } + + // Expand the line range so that `contextLines` are above and below + const rangeStart = Math.max(0, firstLineNum - contextLines); + const rangeEnd = Math.min(lines.length - 1, lastLineNum + contextLines); + + // Pick displayed lines out of full list + const displayedLines = lines.slice(rangeStart, rangeEnd + 1); + + // Find padding based on the line with largest line number + const maxLineId = displayedLines.reduce((acc, line) => { + return line.id === null ? acc : Math.max(acc, line.id); + }, 1); + const lineNumLength = String(maxLineId + 1).length; + + // Add line numbers and cursor to lines + const paddedLines = displayedLines.map(({ hasInterval, id, text }) => { + const prefix = hasInterval && id !== null ? ">" : " "; + const paddedLineNum = + id === null + ? repeat(" ", lineNumLength) + " " + : String(id + 1).padStart(lineNumLength) + " |"; + return `${prefix} ${paddedLineNum} ${text}`; + }); + + return paddedLines.join("\n") + "\n"; + }; + + const getLineAndColumn = (str: string, range: Range) => { + const prefix = str.substring(0, range.start).split(""); + const lineNum = prefix.filter(isEndline).length; + const prevLineEndPos = prefix.findLastIndex(isEndline); + const lineStartPos = prevLineEndPos === -1 ? 0 : prevLineEndPos + 1; + const colNum = range.start - lineStartPos; + + return { + offset: range.start, + lineNum: lineNum + 1, + colNum: colNum + 1, + toString: () => show(str, range), + }; + }; + + return { show, getLineAndColumn }; +}; + +// Default error printer. Should be initialized in entry point instead +const errorPrinter = getErrorPrinter({ + // This should be `chalk.red` + error: (s) => s, + // This should be `chalk.gray` + context: (s) => s, + contextLines: 1, +}); + +export const getSrcInfo = ( + sourceString: string, + startIdx: number, + endIdx: number, + file: string | null, + origin: ItemOrigin, +): SrcInfo => { + const getLineAndColumn = () => { + return errorPrinter.getLineAndColumn(sourceString, { + start: startIdx, + end: endIdx, + }); + }; + + const getLineAndColumnMessage = () => { + return getLineAndColumn().toString(); + }; + + const contents = sourceString.substring(startIdx, endIdx); + + return { + [srcInfoSymbol]: true, + contents: contents, + file, + interval: { + contents: contents, + startIdx: startIdx, + endIdx: endIdx, + getLineAndColumn, + getLineAndColumnMessage, + }, + origin, + toJSON: () => ({}), + }; +}; + +export const dummySrcInfo: SrcInfo = getSrcInfo("", 0, 0, null, "user"); diff --git a/src/next/index.ts b/src/next/index.ts new file mode 100644 index 0000000000..4c03a6a03c --- /dev/null +++ b/src/next/index.ts @@ -0,0 +1,26 @@ +import fs from "fs/promises"; +import path from "path"; +import { getParser } from "@/next/grammar"; +import { TerminalLogger } from "@/cli/logger"; +import { getAnsiMarkup, isColorSupported } from "@/cli/colors"; +import { inspect } from 'util'; + +// eslint-disable-next-line @typescript-eslint/no-confusing-void-expression +const dump = (obj: unknown) => console.log(inspect(obj, { colors: true, depth: Infinity })); + +const main = async () => { + const ansi = getAnsiMarkup(isColorSupported()); + await TerminalLogger(path, "info", ansi, async (log) => { + const sourcePath = path.join(__dirname, "wallet-v4.tact"); + const code = await fs.readFile(sourcePath, "utf8"); + log.source(sourcePath, code, (log) => { + log.recover((log) => { + const parse = getParser(log); + const ast = parse(code); + dump(ast); + }); + }); + }); +}; + +void main(); diff --git a/src/next/wallet-v4.tact b/src/next/wallet-v4.tact new file mode 100644 index 0000000000..2587434e31 --- /dev/null +++ b/src/next/wallet-v4.tact @@ -0,0 +1,235 @@ +message(0x64737472) RemovePlugin { + queryId: Int as uint64; +} + +message(0x706c7567) PluginRequestFunds { + queryId: Int as uint64; + amount: Int as coins; + extra: Cell?; +} + +struct ExtRequest { + bundle: SignedBundle; + walletId: Int as int32; + validUntil: Int as uint32; + seqno: Int as uint32; + op: Int as uint8; + payload: Slice as remaining; +} + +struct RawMsg { + bits: Int as uint6 = 0x18; + receiver: Address; + amount: Int as coins; + extra: Cell?; + bits2: Int as uint106 = 0; // 4 + 4 + 64 + 32 + 1 + 1 + op: Int as uint32; + queryId: Int as uint64; +} + +struct RawMsgWithDeploy { + bits: Int as uint6 = 0x18; + receiver: Address; + amount: Int as coins; + bits2: Int as uint108 = 4 + 2 + 1; // 1 + 4 + 4 + 64 + 32 + 1 + 1 + 1 + stateInit: Cell; + body: Cell; +} + +struct ContractState { + seqno: Int as uint32; + walletId: Int as int32; + publicKey: Int as uint256; + extensions: map; +} + +// Exit codes +const LowBalance: Int = 80; +const Expired: Int = 36; +const SeqnoMismatch: Int = 33; +const WalletIdMismatch: Int = 34; +const SignatureMismatch: Int = 35; +const PluginWasNotDeleted: Int = 39; + +// Op +const PluginTakeFunds: Int = 0x706c7567 | 0x80000000; +const PluginRemove: Int = 0x64737472 | 0x80000000; +const AddPluginAction: Int = 0x6e6f7465; +const RemovePluginAction: Int = 0x64737472; + +contract WalletV4( + state: ContractState, +) { + receive(msg: PluginRequestFunds) { + let addr = sender(); // check gas for ctx + + if (!self.state.extensions.exists(addr)) { + return; + } + + throwUnless(LowBalance, myBalance() - context().value >= msg.amount); + + // NOTE: Here and later we use RawMsg with nativeSendMessage because + // in v4 wallet implementation message bodies are stored as slices in the same cell + // instead of separate cell with ref. Our send built-ins (message, send) doesn't support such serialization + nativeSendMessage( + RawMsg { + queryId: msg.queryId, + op: PluginTakeFunds, + extra: msg.extra, + amount: msg.amount, + receiver: addr, + }.toCell(), + 64, + ); + } + + receive(msg: RemovePlugin) { + let addr = sender(); // check gas for ctx + + if (!self.state.extensions.exists(addr)) { + return; + } + + let _ = self.state.extensions.del(addr); + + if (context().bounceable) { + nativeSendMessage( + RawMsg { + queryId: msg.queryId, + op: PluginRemove, + extra: null, + amount: 0, + receiver: addr, + }.toCell(), + 64, + ); + } + } + + external(msgSlice: Slice) { + let msg = ExtRequest.fromSlice(msgSlice); + throwIf(Expired, msg.validUntil < now()); + throwUnless(SeqnoMismatch, msg.seqno == self.state.seqno); + throwUnless(WalletIdMismatch, msg.walletId == self.state.walletId); + throwUnless(SignatureMismatch, msg.bundle.verifySignature(self.state.publicKey)); + + acceptMessage(); + self.state.seqno += 1; + setData(self.state.toCell()); + commit(); + + // simple transfer + if (msg.op == 0) { + let payload = msg.payload; + /* + foreach (ref in payload.refs) { + let mode = payload.loadUint(8); + nativeSendMessage(ref, mode); + } + */ + while (payload.refs() != 0) { + let mode = payload.loadUint(8); + nativeSendMessage(payload.loadRef(), mode); + } + return; + } + + // deploy and add plugin + if (msg.op == 1) { + let payload = msg.payload; + let wc = payload.loadUint(8); + let amount = payload.loadCoins(); + let stateInit = payload.loadRef(); + let body = payload.loadRef(); + + let addr = newAddress(wc, stateInit.hash()); + // cant use deploy here because of only basechain support + nativeSendMessage( + RawMsgWithDeploy { + stateInit, + body, + amount, + receiver: addr, + }.toCell(), + 3, + ); + + self.state.extensions.set(addr, true); + } else if (msg.op == 2) { + // add plugin + let payload = msg.payload; + + let wc = payload.loadUint(8); + let addrHash = payload.loadUint(256); + let addr = newAddress(wc, addrHash); + + let amount = payload.loadCoins(); + let queryId = payload.loadUint(64); + + self.state.extensions.set(addr, true); + + nativeSendMessage( + RawMsg { + queryId, + op: AddPluginAction, + extra: null, + amount, + receiver: addr, + }.toCell(), + 64, + ); + } else if (msg.op == 3) { + // remove plugin + let payload = msg.payload; + + let wc = payload.loadUint(8); + let addrHash = payload.loadUint(256); + let addr = newAddress(wc, addrHash); + + let amount = payload.loadCoins(); + let queryId = payload.loadUint(64); + + throwUnless(PluginWasNotDeleted, self.state.extensions.del(addr)); + + nativeSendMessage( + RawMsg { + queryId, + op: RemovePluginAction, + extra: null, + amount: amount, + receiver: addr, + }.toCell(), + 64, + ); + } + } + + receive(_: Slice) { + // Fallback + } + + get fun seqno(): Int { + return self.state.seqno; + } + + get fun get_subwallet_id(): Int { + return self.state.walletId; + } + + get fun get_public_key(): Int { + return self.state.publicKey; + } + + get fun is_plugin_installed(wc: Int, hash: Int): Bool { + return self.state.extensions.exists(newAddress(wc, hash)); + } + + // this is different from FunC version, awaiting unbounded tuple impl in Tact + // also we need to return it as map of instead of Address (skip first 4 bytes) + get fun get_plugin_list(): map { + return self.state.extensions; + } +} + +asm fun setData(data: Cell) { c4 POP } From 4386e4c3c24f4d5f571e5931b5a3522e9890ee4c Mon Sep 17 00:00:00 2001 From: verytactical <186486509+verytactical@users.noreply.github.com> Date: Sun, 13 Apr 2025 19:02:16 +0400 Subject: [PATCH 02/38] generics --- src/next/ast/expression.ts | 26 +- src/next/ast/generated/expression.ts | 303 +-- src/next/ast/generated/root.ts | 568 ++--- src/next/ast/root.ts | 7 +- src/next/generic.tact | 42 + src/next/grammar/grammar.gg | 36 +- src/next/grammar/grammar.ts | 3187 +++++--------------------- src/next/grammar/index.ts | 64 +- src/next/grammar/parser-error.ts | 3 + src/next/index.ts | 5 +- src/next/union.tact | 36 + 11 files changed, 1114 insertions(+), 3163 deletions(-) create mode 100644 src/next/generic.tact create mode 100644 src/next/union.tact diff --git a/src/next/ast/expression.ts b/src/next/ast/expression.ts index fe4dd425d0..f92cd47129 100644 --- a/src/next/ast/expression.ts +++ b/src/next/ast/expression.ts @@ -1,4 +1,5 @@ import type { Id, Range, TypeId } from "@/next/ast/common"; +import type { Type } from "@/next/ast/type"; export type Expression = | OpBinary @@ -14,7 +15,10 @@ export type Expression = | Boolean | Null | String - | Var; + | Var + | Unit + | Tuple + | Tensor; export type Var = { readonly kind: "var"; @@ -100,6 +104,7 @@ export type MethodCall = { readonly kind: "method_call"; readonly self: Expression; // anything with a method readonly method: Id; + readonly typeArgs: readonly Type[]; readonly args: readonly Expression[]; readonly loc: Range; }; @@ -108,6 +113,7 @@ export type MethodCall = { export type StaticCall = { readonly kind: "static_call"; readonly function: Id; + readonly typeArgs: readonly Type[]; readonly args: readonly Expression[]; readonly loc: Range; }; @@ -115,6 +121,7 @@ export type StaticCall = { export type StructInstance = { readonly kind: "struct_instance"; readonly type: TypeId; + readonly typeArgs: readonly Type[]; readonly args: readonly StructFieldInitializer[]; readonly loc: Range; }; @@ -146,3 +153,20 @@ export type Conditional = { readonly elseBranch: Expression; readonly loc: Range; }; + +export type Unit = { + readonly kind: "unit"; + readonly loc: Range; +} + +export type Tuple = { + readonly kind: "tuple"; + readonly children: readonly Expression[]; + readonly loc: Range; +} + +export type Tensor = { + readonly kind: "tensor"; + readonly children: readonly Expression[]; + readonly loc: Range; +} \ No newline at end of file diff --git a/src/next/ast/generated/expression.ts b/src/next/ast/generated/expression.ts index 6291ba19c1..ef62b173ed 100644 --- a/src/next/ast/generated/expression.ts +++ b/src/next/ast/generated/expression.ts @@ -1,217 +1,152 @@ /* eslint-disable @typescript-eslint/no-unnecessary-condition */ import type * as $c from "@/next/ast/common"; +import type * as $t from "@/next/ast/type"; import type * as $ from "@/next/ast/expression"; export type BinaryOperation = $.BinaryOperation; -export const allBinaryOperation: readonly $.BinaryOperation[] = [ - "+", - "-", - "*", - "/", - "!=", - ">", - "<", - ">=", - "<=", - "==", - "&&", - "||", - "%", - "<<", - ">>", - "&", - "|", - "^", -]; +export const allBinaryOperation: readonly $.BinaryOperation[] = ["+", "-", "*", "/", "!=", ">", "<", ">=", "<=", "==", "&&", "||", "%", "<<", ">>", "&", "|", "^"]; export type UnaryOperation = $.UnaryOperation; -export const allUnaryOperation: readonly $.UnaryOperation[] = [ - "+", - "-", - "!", - "!!", - "~", -]; +export const allUnaryOperation: readonly $.UnaryOperation[] = ["+", "-", "!", "!!", "~"]; export type CodeOf = $.CodeOf; -export const CodeOf = (contract: $c.TypeId, loc: $c.Range): $.CodeOf => - Object.freeze({ - kind: "code_of", - contract, - loc, - }); +export const CodeOf = (contract: $c.TypeId, loc: $c.Range): $.CodeOf => Object.freeze({ + kind: "code_of", + contract, + loc +}); export const isCodeOf = ($value: CodeOf) => $value.kind === "code_of"; export type NumberBase = $.NumberBase; export const allNumberBase: readonly $.NumberBase[] = ["2", "8", "10", "16"]; export type Number = $.Number; -export const Number = ( - base: $.NumberBase, - value: bigint, - loc: $c.Range, -): $.Number => - Object.freeze({ - kind: "number", - base, - value, - loc, - }); +export const Number = (base: $.NumberBase, value: bigint, loc: $c.Range): $.Number => Object.freeze({ + kind: "number", + base, + value, + loc +}); export const isNumber = ($value: Number) => $value.kind === "number"; export type Boolean = $.Boolean; -export const Boolean = (value: boolean, loc: $c.Range): $.Boolean => - Object.freeze({ - kind: "boolean", - value, - loc, - }); +export const Boolean = (value: boolean, loc: $c.Range): $.Boolean => Object.freeze({ + kind: "boolean", + value, + loc +}); export const isBoolean = ($value: Boolean) => $value.kind === "boolean"; export type Null = $.Null; -export const Null = (loc: $c.Range): $.Null => - Object.freeze({ - kind: "null", - loc, - }); +export const Null = (loc: $c.Range): $.Null => Object.freeze({ + kind: "null", + loc +}); export const isNull = ($value: Null) => $value.kind === "null"; export type String = $.String; -export const String = (value: string, loc: $c.Range): $.String => - Object.freeze({ - kind: "string", - value, - loc, - }); +export const String = (value: string, loc: $c.Range): $.String => Object.freeze({ + kind: "string", + value, + loc +}); export const isString = ($value: String) => $value.kind === "string"; export type Var = $.Var; -export const Var = (name: string, loc: $c.Range): $.Var => - Object.freeze({ - kind: "var", - name, - loc, - }); +export const Var = (name: string, loc: $c.Range): $.Var => Object.freeze({ + kind: "var", + name, + loc +}); export const isVar = ($value: Var) => $value.kind === "var"; +export type Unit = $.Unit; +export const Unit = (loc: $c.Range): $.Unit => Object.freeze({ + kind: "unit", + loc +}); +export const isUnit = ($value: Unit) => $value.kind === "unit"; +export type Tensor = $.Tensor; +export const Tensor = (children: readonly $.Expression[], loc: $c.Range): $.Tensor => Object.freeze({ + kind: "tensor", + children, + loc +}); +export const isTensor = ($value: Tensor) => $value.kind === "tensor"; +export type Tuple = $.Tuple; +export const Tuple = (children: readonly $.Expression[], loc: $c.Range): $.Tuple => Object.freeze({ + kind: "tuple", + children, + loc +}); +export const isTuple = ($value: Tuple) => $value.kind === "tuple"; export type InitOf = $.InitOf; -export const InitOf = ( - contract: $c.TypeId, - args: readonly $.Expression[], - loc: $c.Range, -): $.InitOf => - Object.freeze({ - kind: "init_of", - contract, - args, - loc, - }); +export const InitOf = (contract: $c.TypeId, args: readonly $.Expression[], loc: $c.Range): $.InitOf => Object.freeze({ + kind: "init_of", + contract, + args, + loc +}); export const isInitOf = ($value: InitOf) => $value.kind === "init_of"; export type StructFieldInitializer = $.StructFieldInitializer; -export const StructFieldInitializer = ( - field: $c.Id, - initializer: $.Expression, - loc: $c.Range, -): $.StructFieldInitializer => - Object.freeze({ - kind: "struct_field_initializer", - field, - initializer, - loc, - }); -export const isStructFieldInitializer = ($value: StructFieldInitializer) => - $value.kind === "struct_field_initializer"; +export const StructFieldInitializer = (field: $c.Id, initializer: $.Expression, loc: $c.Range): $.StructFieldInitializer => Object.freeze({ + kind: "struct_field_initializer", + field, + initializer, + loc +}); +export const isStructFieldInitializer = ($value: StructFieldInitializer) => $value.kind === "struct_field_initializer"; export type StructInstance = $.StructInstance; -export const StructInstance = ( - type_: $c.TypeId, - args: readonly $.StructFieldInitializer[], - loc: $c.Range, -): $.StructInstance => - Object.freeze({ - kind: "struct_instance", - type: type_, - args, - loc, - }); -export const isStructInstance = ($value: StructInstance) => - $value.kind === "struct_instance"; +export const StructInstance = (type_: $c.TypeId, typeArgs: readonly $t.Type[], args: readonly $.StructFieldInitializer[], loc: $c.Range): $.StructInstance => Object.freeze({ + kind: "struct_instance", + type: type_, + typeArgs, + args, + loc +}); +export const isStructInstance = ($value: StructInstance) => $value.kind === "struct_instance"; export type StaticCall = $.StaticCall; -export const StaticCall = ( - function_: $c.Id, - args: readonly $.Expression[], - loc: $c.Range, -): $.StaticCall => - Object.freeze({ - kind: "static_call", - function: function_, - args, - loc, - }); -export const isStaticCall = ($value: StaticCall) => - $value.kind === "static_call"; +export const StaticCall = (function_: $c.Id, typeArgs: readonly $t.Type[], args: readonly $.Expression[], loc: $c.Range): $.StaticCall => Object.freeze({ + kind: "static_call", + function: function_, + typeArgs, + args, + loc +}); +export const isStaticCall = ($value: StaticCall) => $value.kind === "static_call"; export type FieldAccess = $.FieldAccess; -export const FieldAccess = ( - aggregate: $.Expression, - field: $c.Id, - loc: $c.Range, -): $.FieldAccess => - Object.freeze({ - kind: "field_access", - aggregate, - field, - loc, - }); -export const isFieldAccess = ($value: FieldAccess) => - $value.kind === "field_access"; +export const FieldAccess = (aggregate: $.Expression, field: $c.Id, loc: $c.Range): $.FieldAccess => Object.freeze({ + kind: "field_access", + aggregate, + field, + loc +}); +export const isFieldAccess = ($value: FieldAccess) => $value.kind === "field_access"; export type MethodCall = $.MethodCall; -export const MethodCall = ( - self: $.Expression, - method: $c.Id, - args: readonly $.Expression[], - loc: $c.Range, -): $.MethodCall => - Object.freeze({ - kind: "method_call", - self, - method, - args, - loc, - }); -export const isMethodCall = ($value: MethodCall) => - $value.kind === "method_call"; +export const MethodCall = (self: $.Expression, method: $c.Id, typeArgs: readonly $t.Type[], args: readonly $.Expression[], loc: $c.Range): $.MethodCall => Object.freeze({ + kind: "method_call", + self, + method, + typeArgs, + args, + loc +}); +export const isMethodCall = ($value: MethodCall) => $value.kind === "method_call"; export type Conditional = $.Conditional; -export const Conditional = ( - condition: $.Expression, - thenBranch: $.Expression, - elseBranch: $.Expression, - loc: $c.Range, -): $.Conditional => - Object.freeze({ - kind: "conditional", - condition, - thenBranch, - elseBranch, - loc, - }); -export const isConditional = ($value: Conditional) => - $value.kind === "conditional"; +export const Conditional = (condition: $.Expression, thenBranch: $.Expression, elseBranch: $.Expression, loc: $c.Range): $.Conditional => Object.freeze({ + kind: "conditional", + condition, + thenBranch, + elseBranch, + loc +}); +export const isConditional = ($value: Conditional) => $value.kind === "conditional"; export type OpUnary = $.OpUnary; -export const OpUnary = ( - op: $.UnaryOperation, - operand: $.Expression, - loc: $c.Range, -): $.OpUnary => - Object.freeze({ - kind: "op_unary", - op, - operand, - loc, - }); +export const OpUnary = (op: $.UnaryOperation, operand: $.Expression, loc: $c.Range): $.OpUnary => Object.freeze({ + kind: "op_unary", + op, + operand, + loc +}); export const isOpUnary = ($value: OpUnary) => $value.kind === "op_unary"; export type OpBinary = $.OpBinary; -export const OpBinary = ( - op: $.BinaryOperation, - left: $.Expression, - right: $.Expression, - loc: $c.Range, -): $.OpBinary => - Object.freeze({ - kind: "op_binary", - op, - left, - right, - loc, - }); +export const OpBinary = (op: $.BinaryOperation, left: $.Expression, right: $.Expression, loc: $c.Range): $.OpBinary => Object.freeze({ + kind: "op_binary", + op, + left, + right, + loc +}); export const isOpBinary = ($value: OpBinary) => $value.kind === "op_binary"; export type Expression = $.Expression; diff --git a/src/next/ast/generated/root.ts b/src/next/ast/generated/root.ts index 98de92d0c4..ff1d4ab62b 100644 --- a/src/next/ast/generated/root.ts +++ b/src/next/ast/generated/root.ts @@ -7,413 +7,247 @@ import type * as $ from "@/next/ast/root"; export type ImportType = $.ImportType; export const allImportType: readonly $.ImportType[] = ["stdlib", "relative"]; export type ImportPath = $.ImportPath; -export const ImportPath = ( - path: $c.RelativePath, - type_: $.ImportType, - language: $c.Language, -): $.ImportPath => - Object.freeze({ - path, - type: type_, - language, - }); +export const ImportPath = (path: $c.RelativePath, type_: $.ImportType, language: $c.Language): $.ImportPath => Object.freeze({ + path, + type: type_, + language +}); export type Import = $.Import; -export const Import = (importPath: $.ImportPath, loc: $c.Range): $.Import => - Object.freeze({ - kind: "import", - importPath, - loc, - }); +export const Import = (importPath: $.ImportPath, loc: $c.Range): $.Import => Object.freeze({ + kind: "import", + importPath, + loc +}); export const isImport = ($value: Import) => $value.kind === "import"; export type FunctionAttributeGet = $.FunctionAttributeGet; -export const FunctionAttributeGet = ( - methodId: $e.Expression | undefined, - loc: $c.Range, -): $.FunctionAttributeGet => - Object.freeze({ - kind: "function_attribute", - type: "get", - methodId, - loc, - }); -export const isFunctionAttributeGet = ($value: FunctionAttributeGet) => - $value.kind === "function_attribute"; +export const FunctionAttributeGet = (methodId: $e.Expression | undefined, loc: $c.Range): $.FunctionAttributeGet => Object.freeze({ + kind: "function_attribute", + type: "get", + methodId, + loc +}); +export const isFunctionAttributeGet = ($value: FunctionAttributeGet) => $value.kind === "function_attribute"; export type FunctionAttributeName = $.FunctionAttributeName; -export const allFunctionAttributeName: readonly $.FunctionAttributeName[] = [ - "mutates", - "extends", - "virtual", - "abstract", - "override", - "inline", -]; +export const allFunctionAttributeName: readonly $.FunctionAttributeName[] = ["mutates", "extends", "virtual", "abstract", "override", "inline"]; export type FunctionAttributeRest = $.FunctionAttributeRest; -export const FunctionAttributeRest = ( - type_: $.FunctionAttributeName, - loc: $c.Range, -): $.FunctionAttributeRest => - Object.freeze({ - kind: "function_attribute", - type: type_, - loc, - }); -export const isFunctionAttributeRest = ($value: FunctionAttributeRest) => - $value.kind === "function_attribute"; +export const FunctionAttributeRest = (type_: $.FunctionAttributeName, loc: $c.Range): $.FunctionAttributeRest => Object.freeze({ + kind: "function_attribute", + type: type_, + loc +}); +export const isFunctionAttributeRest = ($value: FunctionAttributeRest) => $value.kind === "function_attribute"; export type FunctionAttribute = $.FunctionAttribute; export type TypedParameter = $.TypedParameter; -export const TypedParameter = ( - name: $c.OptionalId, - type_: $t.Type, - loc: $c.Range, -): $.TypedParameter => - Object.freeze({ - kind: "typed_parameter", - name, - type: type_, - loc, - }); -export const isTypedParameter = ($value: TypedParameter) => - $value.kind === "typed_parameter"; +export const TypedParameter = (name: $c.OptionalId, type_: $t.Type, loc: $c.Range): $.TypedParameter => Object.freeze({ + kind: "typed_parameter", + name, + type: type_, + loc +}); +export const isTypedParameter = ($value: TypedParameter) => $value.kind === "typed_parameter"; export type FunctionDef = $.FunctionDef; -export const FunctionDef = ( - attributes: readonly $.FunctionAttribute[], - name: $c.Id, - return_: $t.Type | undefined, - params: readonly $.TypedParameter[], - statements: readonly $s.Statement[], - loc: $c.Range, -): $.FunctionDef => - Object.freeze({ - kind: "function_def", - attributes, - name, - return: return_, - params, - statements, - loc, - }); -export const isFunctionDef = ($value: FunctionDef) => - $value.kind === "function_def"; +export const FunctionDef = (attributes: readonly $.FunctionAttribute[], name: $c.Id, typeParams: readonly $c.TypeId[], return_: $t.Type | undefined, params: readonly $.TypedParameter[], statements: readonly $s.Statement[], loc: $c.Range): $.FunctionDef => Object.freeze({ + kind: "function_def", + attributes, + name, + typeParams, + return: return_, + params, + statements, + loc +}); +export const isFunctionDef = ($value: FunctionDef) => $value.kind === "function_def"; export type AsmShuffle = $.AsmShuffle; -export const AsmShuffle = ( - args: readonly $c.Id[], - ret: readonly $e.Number[], -): $.AsmShuffle => - Object.freeze({ - args, - ret, - }); +export const AsmShuffle = (args: readonly $c.Id[], ret: readonly $e.Number[]): $.AsmShuffle => Object.freeze({ + args, + ret +}); export type AsmInstruction = $.AsmInstruction; export type AsmFunctionDef = $.AsmFunctionDef; -export const AsmFunctionDef = ( - shuffle: $.AsmShuffle, - attributes: readonly $.FunctionAttribute[], - name: $c.Id, - return_: $t.Type | undefined, - params: readonly $.TypedParameter[], - instructions: readonly $.AsmInstruction[], - loc: $c.Range, -): $.AsmFunctionDef => - Object.freeze({ - kind: "asm_function_def", - shuffle, - attributes, - name, - return: return_, - params, - instructions, - loc, - }); -export const isAsmFunctionDef = ($value: AsmFunctionDef) => - $value.kind === "asm_function_def"; +export const AsmFunctionDef = (shuffle: $.AsmShuffle, attributes: readonly $.FunctionAttribute[], name: $c.Id, typeParams: readonly $c.TypeId[], return_: $t.Type | undefined, params: readonly $.TypedParameter[], instructions: readonly $.AsmInstruction[], loc: $c.Range): $.AsmFunctionDef => Object.freeze({ + kind: "asm_function_def", + shuffle, + attributes, + name, + typeParams, + return: return_, + params, + instructions, + loc +}); +export const isAsmFunctionDef = ($value: AsmFunctionDef) => $value.kind === "asm_function_def"; export type NativeFunctionDecl = $.NativeFunctionDecl; -export const NativeFunctionDecl = ( - attributes: readonly $.FunctionAttribute[], - name: $c.Id, - nativeName: $c.FuncId, - params: readonly $.TypedParameter[], - return_: $t.Type | undefined, - loc: $c.Range, -): $.NativeFunctionDecl => - Object.freeze({ - kind: "native_function_decl", - attributes, - name, - nativeName, - params, - return: return_, - loc, - }); -export const isNativeFunctionDecl = ($value: NativeFunctionDecl) => - $value.kind === "native_function_decl"; +export const NativeFunctionDecl = (attributes: readonly $.FunctionAttribute[], name: $c.Id, typeParams: readonly $c.TypeId[], nativeName: $c.FuncId, params: readonly $.TypedParameter[], return_: $t.Type | undefined, loc: $c.Range): $.NativeFunctionDecl => Object.freeze({ + kind: "native_function_decl", + attributes, + name, + typeParams, + nativeName, + params, + return: return_, + loc +}); +export const isNativeFunctionDecl = ($value: NativeFunctionDecl) => $value.kind === "native_function_decl"; export type ConstantAttributeName = $.ConstantAttributeName; -export const allConstantAttributeName: readonly $.ConstantAttributeName[] = [ - "virtual", - "override", - "abstract", -]; +export const allConstantAttributeName: readonly $.ConstantAttributeName[] = ["virtual", "override", "abstract"]; export type ConstantAttribute = $.ConstantAttribute; -export const ConstantAttribute = ( - type_: $.ConstantAttributeName, - loc: $c.Range, -): $.ConstantAttribute => - Object.freeze({ - type: type_, - loc, - }); +export const ConstantAttribute = (type_: $.ConstantAttributeName, loc: $c.Range): $.ConstantAttribute => Object.freeze({ + type: type_, + loc +}); export type ConstantDef = $.ConstantDef; -export const ConstantDef = ( - attributes: readonly $.ConstantAttribute[], - name: $c.Id, - type_: $t.Type, - initializer: $e.Expression, - loc: $c.Range, -): $.ConstantDef => - Object.freeze({ - kind: "constant_def", - attributes, - name, - type: type_, - initializer, - loc, - }); -export const isConstantDef = ($value: ConstantDef) => - $value.kind === "constant_def"; +export const ConstantDef = (attributes: readonly $.ConstantAttribute[], name: $c.Id, type_: $t.Type | undefined, initializer: $e.Expression, loc: $c.Range): $.ConstantDef => Object.freeze({ + kind: "constant_def", + attributes, + name, + type: type_, + initializer, + loc +}); +export const isConstantDef = ($value: ConstantDef) => $value.kind === "constant_def"; export type FieldDecl = $.FieldDecl; -export const FieldDecl = ( - name: $c.Id, - type_: $t.Type, - initializer: $e.Expression | undefined, - loc: $c.Range, -): $.FieldDecl => - Object.freeze({ - kind: "field_decl", - name, - type: type_, - initializer, - loc, - }); +export const FieldDecl = (name: $c.Id, type_: $t.Type, initializer: $e.Expression | undefined, loc: $c.Range): $.FieldDecl => Object.freeze({ + kind: "field_decl", + name, + type: type_, + initializer, + loc +}); export const isFieldDecl = ($value: FieldDecl) => $value.kind === "field_decl"; export type StructDecl = $.StructDecl; -export const StructDecl = ( - name: $c.TypeId, - fields: readonly $.FieldDecl[], - loc: $c.Range, -): $.StructDecl => - Object.freeze({ - kind: "struct_decl", - name, - fields, - loc, - }); -export const isStructDecl = ($value: StructDecl) => - $value.kind === "struct_decl"; +export const StructDecl = (name: $c.TypeId, typeParams: readonly $c.TypeId[], fields: readonly $.FieldDecl[], loc: $c.Range): $.StructDecl => Object.freeze({ + kind: "struct_decl", + name, + typeParams, + fields, + loc +}); +export const isStructDecl = ($value: StructDecl) => $value.kind === "struct_decl"; export type MessageDecl = $.MessageDecl; -export const MessageDecl = ( - name: $c.TypeId, - opcode: $e.Expression | undefined, - fields: readonly $.FieldDecl[], - loc: $c.Range, -): $.MessageDecl => - Object.freeze({ - kind: "message_decl", - name, - opcode, - fields, - loc, - }); -export const isMessageDecl = ($value: MessageDecl) => - $value.kind === "message_decl"; +export const MessageDecl = (name: $c.TypeId, opcode: $e.Expression | undefined, fields: readonly $.FieldDecl[], loc: $c.Range): $.MessageDecl => Object.freeze({ + kind: "message_decl", + name, + opcode, + fields, + loc +}); +export const isMessageDecl = ($value: MessageDecl) => $value.kind === "message_decl"; export type ContractAttribute = $.ContractAttribute; -export const ContractAttribute = ( - name: string, - loc: $c.Range, -): $.ContractAttribute => - Object.freeze({ - type: "interface", - name, - loc, - }); +export const ContractAttribute = (name: string, loc: $c.Range): $.ContractAttribute => Object.freeze({ + type: "interface", + name, + loc +}); export type ContractInit = $.ContractInit; -export const ContractInit = ( - params: readonly $.TypedParameter[], - statements: readonly $s.Statement[], - loc: $c.Range, -): $.ContractInit => - Object.freeze({ - kind: "contract_init", - params, - statements, - loc, - }); -export const isContractInit = ($value: ContractInit) => - $value.kind === "contract_init"; +export const ContractInit = (params: readonly $.TypedParameter[], statements: readonly $s.Statement[], loc: $c.Range): $.ContractInit => Object.freeze({ + kind: "contract_init", + params, + statements, + loc +}); +export const isContractInit = ($value: ContractInit) => $value.kind === "contract_init"; export type ReceiverSimple = $.ReceiverSimple; -export const ReceiverSimple = (param: $.TypedParameter): $.ReceiverSimple => - Object.freeze({ - kind: "simple", - param, - }); -export const isReceiverSimple = ($value: ReceiverSimple) => - $value.kind === "simple"; +export const ReceiverSimple = (param: $.TypedParameter): $.ReceiverSimple => Object.freeze({ + kind: "simple", + param +}); +export const isReceiverSimple = ($value: ReceiverSimple) => $value.kind === "simple"; export type ReceiverFallback = $.ReceiverFallback; -export const ReceiverFallback = (): $.ReceiverFallback => - Object.freeze({ - kind: "fallback", - }); -export const isReceiverFallback = ($value: ReceiverFallback) => - $value.kind === "fallback"; +export const ReceiverFallback = (): $.ReceiverFallback => Object.freeze({ + kind: "fallback" +}); +export const isReceiverFallback = ($value: ReceiverFallback) => $value.kind === "fallback"; export type ReceiverComment = $.ReceiverComment; -export const ReceiverComment = (comment: $e.String): $.ReceiverComment => - Object.freeze({ - kind: "comment", - comment, - }); -export const isReceiverComment = ($value: ReceiverComment) => - $value.kind === "comment"; +export const ReceiverComment = (comment: $e.String): $.ReceiverComment => Object.freeze({ + kind: "comment", + comment +}); +export const isReceiverComment = ($value: ReceiverComment) => $value.kind === "comment"; export type ReceiverSubKind = $.ReceiverSubKind; export type ReceiverInternal = $.ReceiverInternal; -export const ReceiverInternal = ( - subKind: $.ReceiverSubKind, - loc: $c.Range, -): $.ReceiverInternal => - Object.freeze({ - kind: "internal", - subKind, - loc, - }); -export const isReceiverInternal = ($value: ReceiverInternal) => - $value.kind === "internal"; +export const ReceiverInternal = (subKind: $.ReceiverSubKind, loc: $c.Range): $.ReceiverInternal => Object.freeze({ + kind: "internal", + subKind, + loc +}); +export const isReceiverInternal = ($value: ReceiverInternal) => $value.kind === "internal"; export type ReceiverExternal = $.ReceiverExternal; -export const ReceiverExternal = ( - subKind: $.ReceiverSubKind, - loc: $c.Range, -): $.ReceiverExternal => - Object.freeze({ - kind: "external", - subKind, - loc, - }); -export const isReceiverExternal = ($value: ReceiverExternal) => - $value.kind === "external"; +export const ReceiverExternal = (subKind: $.ReceiverSubKind, loc: $c.Range): $.ReceiverExternal => Object.freeze({ + kind: "external", + subKind, + loc +}); +export const isReceiverExternal = ($value: ReceiverExternal) => $value.kind === "external"; export type ReceiverBounce = $.ReceiverBounce; -export const ReceiverBounce = ( - param: $.TypedParameter, - loc: $c.Range, -): $.ReceiverBounce => - Object.freeze({ - kind: "bounce", - param, - loc, - }); -export const isReceiverBounce = ($value: ReceiverBounce) => - $value.kind === "bounce"; +export const ReceiverBounce = (param: $.TypedParameter, loc: $c.Range): $.ReceiverBounce => Object.freeze({ + kind: "bounce", + param, + loc +}); +export const isReceiverBounce = ($value: ReceiverBounce) => $value.kind === "bounce"; export type ReceiverKind = $.ReceiverKind; export type Receiver = $.Receiver; -export const Receiver = ( - selector: $.ReceiverKind, - statements: readonly $s.Statement[], - loc: $c.Range, -): $.Receiver => - Object.freeze({ - kind: "receiver", - selector, - statements, - loc, - }); +export const Receiver = (selector: $.ReceiverKind, statements: readonly $s.Statement[], loc: $c.Range): $.Receiver => Object.freeze({ + kind: "receiver", + selector, + statements, + loc +}); export const isReceiver = ($value: Receiver) => $value.kind === "receiver"; export type ContractItem = $.ContractItem; export type Contract = $.Contract; -export const Contract = ( - name: $c.TypeId, - traits: readonly $c.TypeId[], - attributes: readonly $.ContractAttribute[], - params: readonly $.FieldDecl[] | undefined, - declarations: readonly $.ContractItem[], - loc: $c.Range, -): $.Contract => - Object.freeze({ - kind: "contract", - name, - traits, - attributes, - params, - declarations, - loc, - }); +export const Contract = (name: $c.TypeId, traits: readonly $c.TypeId[], attributes: readonly $.ContractAttribute[], params: readonly $.FieldDecl[] | undefined, declarations: readonly $.ContractItem[], loc: $c.Range): $.Contract => Object.freeze({ + kind: "contract", + name, + traits, + attributes, + params, + declarations, + loc +}); export const isContract = ($value: Contract) => $value.kind === "contract"; export type FunctionDecl = $.FunctionDecl; -export const FunctionDecl = ( - attributes: readonly $.FunctionAttribute[], - name: $c.Id, - return_: $t.Type | undefined, - params: readonly $.TypedParameter[], - loc: $c.Range, -): $.FunctionDecl => - Object.freeze({ - kind: "function_decl", - attributes, - name, - return: return_, - params, - loc, - }); -export const isFunctionDecl = ($value: FunctionDecl) => - $value.kind === "function_decl"; +export const FunctionDecl = (attributes: readonly $.FunctionAttribute[], name: $c.Id, typeParams: readonly $c.TypeId[], return_: $t.Type | undefined, params: readonly $.TypedParameter[], loc: $c.Range): $.FunctionDecl => Object.freeze({ + kind: "function_decl", + attributes, + name, + typeParams, + return: return_, + params, + loc +}); +export const isFunctionDecl = ($value: FunctionDecl) => $value.kind === "function_decl"; export type ConstantDecl = $.ConstantDecl; -export const ConstantDecl = ( - attributes: readonly $.ConstantAttribute[], - name: $c.Id, - type_: $t.Type, - loc: $c.Range, -): $.ConstantDecl => - Object.freeze({ - kind: "constant_decl", - attributes, - name, - type: type_, - loc, - }); -export const isConstantDecl = ($value: ConstantDecl) => - $value.kind === "constant_decl"; +export const ConstantDecl = (attributes: readonly $.ConstantAttribute[], name: $c.Id, type_: $t.Type, loc: $c.Range): $.ConstantDecl => Object.freeze({ + kind: "constant_decl", + attributes, + name, + type: type_, + loc +}); +export const isConstantDecl = ($value: ConstantDecl) => $value.kind === "constant_decl"; export type TraitItem = $.TraitItem; export type Trait = $.Trait; -export const Trait = ( - name: $c.TypeId, - traits: readonly $c.TypeId[], - attributes: readonly $.ContractAttribute[], - declarations: readonly $.TraitItem[], - loc: $c.Range, -): $.Trait => - Object.freeze({ - kind: "trait", - name, - traits, - attributes, - declarations, - loc, - }); +export const Trait = (name: $c.TypeId, traits: readonly $c.TypeId[], attributes: readonly $.ContractAttribute[], declarations: readonly $.TraitItem[], loc: $c.Range): $.Trait => Object.freeze({ + kind: "trait", + name, + traits, + attributes, + declarations, + loc +}); export const isTrait = ($value: Trait) => $value.kind === "trait"; export type ModuleItem = $.ModuleItem; export type Module = $.Module; -export const Module = ( - imports: readonly $.Import[], - items: readonly $.ModuleItem[], -): $.Module => - Object.freeze({ - kind: "module", - imports, - items, - }); +export const Module = (imports: readonly $.Import[], items: readonly $.ModuleItem[]): $.Module => Object.freeze({ + kind: "module", + imports, + items +}); export const isModule = ($value: Module) => $value.kind === "module"; export type Source = $.Source; -export const Source = ( - file: string | undefined, - contents: string, - root: $.Module, -): $.Source => - Object.freeze({ - file, - contents, - root, - }); +export const Source = (file: string | undefined, contents: string, root: $.Module): $.Source => Object.freeze({ + file, + contents, + root +}); \ No newline at end of file diff --git a/src/next/ast/root.ts b/src/next/ast/root.ts index a12ba26bda..b19a501687 100644 --- a/src/next/ast/root.ts +++ b/src/next/ast/root.ts @@ -79,6 +79,7 @@ export type FunctionDef = { readonly kind: "function_def"; readonly attributes: readonly FunctionAttribute[]; readonly name: Id; + readonly typeParams: readonly TypeId[]; readonly return: Type | undefined; readonly params: readonly TypedParameter[]; readonly statements: readonly Statement[]; @@ -104,6 +105,7 @@ export type AsmFunctionDef = { readonly shuffle: AsmShuffle; readonly attributes: readonly FunctionAttribute[]; readonly name: Id; + readonly typeParams: readonly TypeId[]; readonly return: Type | undefined; readonly params: readonly TypedParameter[]; readonly instructions: readonly AsmInstruction[]; @@ -120,6 +122,7 @@ export type FunctionDecl = { readonly kind: "function_decl"; readonly attributes: readonly FunctionAttribute[]; readonly name: Id; + readonly typeParams: readonly TypeId[]; readonly return: Type | undefined; readonly params: readonly TypedParameter[]; readonly loc: Range; @@ -129,6 +132,7 @@ export type NativeFunctionDecl = { readonly kind: "native_function_decl"; readonly attributes: readonly FunctionAttribute[]; readonly name: Id; + readonly typeParams: readonly TypeId[]; readonly nativeName: FuncId; readonly params: readonly TypedParameter[]; readonly return: Type | undefined; @@ -139,7 +143,7 @@ export type ConstantDef = { readonly kind: "constant_def"; readonly attributes: readonly ConstantAttribute[]; readonly name: Id; - readonly type: Type; + readonly type: Type | undefined; readonly initializer: Expression; readonly loc: Range; }; @@ -155,6 +159,7 @@ export type ConstantDecl = { export type StructDecl = { readonly kind: "struct_decl"; readonly name: TypeId; + readonly typeParams: readonly TypeId[]; readonly fields: readonly FieldDecl[]; readonly loc: Range; }; diff --git a/src/next/generic.tact b/src/next/generic.tact new file mode 100644 index 0000000000..7fa1ae69cf --- /dev/null +++ b/src/next/generic.tact @@ -0,0 +1,42 @@ +const m = emptyMap(); + +struct MapLen { + m: map; + l: Int as uint32; + // fun get(self: MapLen, key: K): V? { + // return self.m.get(key); + // } +} + +extends fun get(self: MapLen, key: K): V? { + return self.m.get(key); +} + +extends mutates fun set(self: MapLen, key: K, value: V) { + if (self.m.has(key)) { + self.m.set(key, value); + if (value == null) { + self.l -= 1; + } + } else { + self.m.set(key, value); + if (value != null) { + self.l += 1; + } + } +} + +// template +// std::optional MapLen::get(key: K) { +// } + +// const m = f < x > (1); +// const m =(f < x)> (1); + +// fun f() {} + +// fun f(a: A, b: B) {} +// fun g(x: X, y: Y) { +// f(x, y); +// f(y, x); +// } \ No newline at end of file diff --git a/src/next/grammar/grammar.gg b/src/next/grammar/grammar.gg index b31b4b92f0..96efbf2d44 100644 --- a/src/next/grammar/grammar.gg +++ b/src/next/grammar/grammar.gg @@ -42,6 +42,7 @@ Function = attributes:FunctionAttribute* keyword<"fun"> name:Id + typeParams:typeParams? parameters:parameterList returnType:ascription? body:(FunctionDefinition / FunctionDeclaration); @@ -56,6 +57,7 @@ AsmFunction = attributes:FunctionAttribute* keyword<"fun"> name:Id + typeParams:typeParams? parameters:parameterList returnType:ascription? "{" @@ -71,6 +73,7 @@ NativeFunctionDecl = attributes:FunctionAttribute* keyword<"native"> name:Id + typeParams:typeParams? parameters:parameterList returnType:ascription? ";"; @@ -79,7 +82,7 @@ Constant = attributes:ConstantAttribute* keyword<"const"> name:Id - type:ascription + type:ascription? body:(ConstantDefinition / ConstantDeclaration); ConstantAttribute = name:( @@ -97,6 +100,7 @@ storageVar = @FieldDecl semicolon; StructDecl = "struct" name:TypeId + typeParams:typeParams? "{" fields:structFields "}"; @@ -179,7 +183,7 @@ Optional = "?"; typePrimary = TypeGeneric / TypeRegular / TypeTuple / TypeTensor / TypeUnit / typeParens; TypeRegular = child:TypeId; -TypeGeneric = name:(MapKeyword / Bounced / TypeId) "<" args:commaList ">"; +TypeGeneric = name:(MapKeyword / Bounced / TypeId) args:typeArgs; TypeTuple = "[" types:commaList? "]"; TypeTensor = "(" head:type tail:("," @type)+ ","? ")"; TypeUnit = "(" ")"; @@ -203,6 +207,10 @@ BytesStorage = "bytes" width:$(digit+); TypeId "capitalized identifier" = name:#$([A-Z] [a-zA-Z0-9_]*); +typeParams = generic; +typeArgs = generic; +generic = "<" @commaList? ">"; + statement = StatementLet / StatementDestruct @@ -271,12 +279,17 @@ suffix / SuffixFieldAccess; SuffixUnboxNotNull = "!!"; -SuffixCall = params:parameterList; +SuffixCall = + typeArgs:typeArgs? + params:parameterList; SuffixFieldAccess = "." name:Id; // Order is important primary - = Parens + = Unit + / Tensor + / Tuple + / Parens / StructInstance / IntegerLiteral / BoolLiteral @@ -291,12 +304,21 @@ Null = keyword<"null">; parens = "(" @expression ")"; Parens = child:parens; -StructInstance = type:TypeId "{" fields:commaList? "}"; -InitOf = keyword<"initOf"> name:TypeId params:parameterList; -CodeOf = "codeOf" name:TypeId; +Unit = "(" ")"; +Tensor = "(" head:expression tail:("," @expression)+ ","? ")"; +Tuple = "[" types:commaList? "]"; +StructInstance = + type:TypeId + typeArgs:typeArgs? + "{" + fields:commaList? + "}"; StructFieldInitializer = name:Id init:(":" @expression)?; +InitOf = keyword<"initOf"> name:TypeId params:parameterList; +CodeOf = "codeOf" name:TypeId; + ParameterList = "(" values:commaList? ")"; parameterList = "(" @commaList? ")"; Parameter = name:Id type:ascription; diff --git a/src/next/grammar/grammar.ts b/src/next/grammar/grammar.ts index 68dc6a44d9..bc002d2010 100644 --- a/src/next/grammar/grammar.ts +++ b/src/next/grammar/grammar.ts @@ -6,2603 +6,602 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ import * as $ from "@tonstudio/parser-runtime"; export namespace $ast { - export type Module = $.Located<{ - readonly $: "Module"; - readonly imports: readonly Import[]; - readonly items: readonly moduleItem[]; - }>; - export type Import = $.Located<{ - readonly $: "Import"; - readonly path: StringLiteral; - }>; - export type PrimitiveTypeDecl = $.Located<{ - readonly $: "PrimitiveTypeDecl"; - readonly name: TypeId; - }>; - export type $Function = $.Located<{ - readonly $: "Function"; - readonly attributes: readonly FunctionAttribute[]; - readonly name: Id; - readonly parameters: parameterList; - readonly returnType: ascription | undefined; - readonly body: FunctionDefinition | FunctionDeclaration; - }>; - export type AsmFunction = $.Located<{ - readonly $: "AsmFunction"; - readonly shuffle: shuffle | undefined; - readonly attributes: readonly FunctionAttribute[]; - readonly name: Id; - readonly parameters: parameterList; - readonly returnType: ascription | undefined; - readonly instructions: assembly; - }>; - export type NativeFunctionDecl = $.Located<{ - readonly $: "NativeFunctionDecl"; - readonly nativeName: FuncId; - readonly attributes: readonly FunctionAttribute[]; - readonly name: Id; - readonly parameters: parameterList; - readonly returnType: ascription | undefined; - }>; - export type Constant = $.Located<{ - readonly $: "Constant"; - readonly attributes: readonly ConstantAttribute[]; - readonly name: Id; - readonly type: ascription; - readonly body: ConstantDefinition | ConstantDeclaration; - }>; - export type StructDecl = $.Located<{ - readonly $: "StructDecl"; - readonly name: TypeId; - readonly fields: structFields; - }>; - export type MessageDecl = $.Located<{ - readonly $: "MessageDecl"; - readonly opcode: expression | undefined; - readonly name: TypeId; - readonly fields: structFields; - }>; - export type Contract = $.Located<{ - readonly $: "Contract"; - readonly attributes: readonly ContractAttribute[]; - readonly name: TypeId; - readonly parameters: ParameterList | undefined; - readonly traits: inheritedTraits | undefined; - readonly declarations: readonly contractItemDecl[]; - }>; - export type Trait = $.Located<{ - readonly $: "Trait"; - readonly attributes: readonly ContractAttribute[]; - readonly name: TypeId; - readonly traits: inheritedTraits | undefined; - readonly declarations: readonly traitItemDecl[]; - }>; - export type moduleItem = - | PrimitiveTypeDecl - | $Function - | AsmFunction - | NativeFunctionDecl - | Constant - | StructDecl - | MessageDecl - | Contract - | Trait; - export type ContractInit = $.Located<{ - readonly $: "ContractInit"; - readonly parameters: parameterList; - readonly body: statements; - }>; - export type Receiver = $.Located<{ - readonly $: "Receiver"; - readonly type: ReceiverType; - readonly param: receiverParam; - readonly body: statements; - }>; - export type FieldDecl = $.Located<{ - readonly $: "FieldDecl"; - readonly name: Id; - readonly type: ascription; - readonly expression: expression | undefined; - }>; - export type semicolon = ";" | "}"; - export type storageVar = FieldDecl; - export type contractItemDecl = - | ContractInit - | Receiver - | $Function - | AsmFunction - | Constant - | storageVar; - export type traitItemDecl = - | Receiver - | $Function - | AsmFunction - | Constant - | storageVar; - export type FunctionDefinition = $.Located<{ - readonly $: "FunctionDefinition"; - readonly body: statements; - }>; - export type FunctionDeclaration = $.Located<{ - readonly $: "FunctionDeclaration"; - }>; - export type Id = $.Located<{ - readonly $: "Id"; - readonly name: string; - }>; - export type IntegerLiteralDec = $.Located<{ - readonly $: "IntegerLiteralDec"; - readonly digits: underscored; - }>; - export type shuffle = { - readonly ids: readonly Id[]; - readonly to: readonly IntegerLiteralDec[] | undefined; - }; - export type ConstantAttribute = $.Located<{ - readonly $: "ConstantAttribute"; - readonly name: - | keyword<"virtual"> - | keyword<"override"> - | keyword<"abstract">; - }>; - export type ConstantDefinition = $.Located<{ - readonly $: "ConstantDefinition"; - readonly expression: expression; - }>; - export type ConstantDeclaration = $.Located<{ - readonly $: "ConstantDeclaration"; - }>; - export type inter = { - readonly head: A; - readonly tail: readonly { - readonly op: B; - readonly right: A; - }[]; - }; - export type structFields = inter | undefined; - export type keyword = T; - export type commaList = inter; - export type TypeId = $.Located<{ - readonly $: "TypeId"; - readonly name: string; - }>; - export type inheritedTraits = commaList; - export type ContractAttribute = $.Located<{ - readonly $: "ContractAttribute"; - readonly name: StringLiteral; - }>; - export type FunctionAttribute = $.Located<{ - readonly $: "FunctionAttribute"; - readonly name: - | GetAttribute - | keyword<"mutates"> - | keyword<"extends"> - | keyword<"virtual"> - | keyword<"override"> - | keyword<"inline"> - | keyword<"abstract">; - }>; - export type GetAttribute = $.Located<{ - readonly $: "GetAttribute"; - readonly methodId: expression | undefined; - }>; - export type ReceiverType = $.Located<{ - readonly $: "ReceiverType"; - readonly name: "bounced" | keyword<"receive"> | keyword<"external">; - }>; - export type Parameter = $.Located<{ - readonly $: "Parameter"; - readonly name: Id; - readonly type: ascription; - }>; - export type StringLiteral = $.Located<{ - readonly $: "StringLiteral"; - readonly value: string; - }>; - export type receiverParam = Parameter | StringLiteral | undefined; - export type assembly = string; - export type multiLineComment = string; - export type singleLineComment = string; - export type comment = multiLineComment | singleLineComment; - export type assemblyItem = {} | comment | {} | readonly {}[]; - export type assemblySequence = readonly assemblyItem[]; - export type TypeAs = $.Located<{ - readonly $: "TypeAs"; - readonly type: TypeOptional; - readonly as: readonly storage[]; - }>; - export type $type = TypeAs; - export type ascription = $type; - export type TypeOptional = $.Located<{ - readonly $: "TypeOptional"; - readonly type: typePrimary; - readonly optionals: readonly Optional[]; - }>; - export type Optional = $.Located<{ - readonly $: "Optional"; - }>; - export type TypeGeneric = $.Located<{ - readonly $: "TypeGeneric"; - readonly name: MapKeyword | Bounced | TypeId; - readonly args: commaList<$type>; - }>; - export type TypeRegular = $.Located<{ - readonly $: "TypeRegular"; - readonly child: TypeId; - }>; - export type TypeTuple = $.Located<{ - readonly $: "TypeTuple"; - readonly types: commaList<$type> | undefined; - }>; - export type TypeTensor = $.Located<{ - readonly $: "TypeTensor"; - readonly head: $type; - readonly tail: readonly $type[]; - }>; - export type TypeUnit = $.Located<{ - readonly $: "TypeUnit"; - }>; - export type typeParens = $type; - export type typePrimary = - | TypeGeneric - | TypeRegular - | TypeTuple - | TypeTensor - | TypeUnit - | typeParens; - export type MapKeyword = $.Located<{ - readonly $: "MapKeyword"; - }>; - export type Bounced = $.Located<{ - readonly $: "Bounced"; - }>; - export type IntStorage = $.Located<{ - readonly $: "IntStorage"; - readonly isVar: "var" | undefined; - readonly isUnsigned: "u" | undefined; - readonly width: string; - }>; - export type CoinsStorage = $.Located<{ - readonly $: "CoinsStorage"; - }>; - export type RemainingStorage = $.Located<{ - readonly $: "RemainingStorage"; - }>; - export type BytesStorage = $.Located<{ - readonly $: "BytesStorage"; - readonly width: string; - }>; - export type storage = - | IntStorage - | CoinsStorage - | RemainingStorage - | BytesStorage; - export type StatementLet = $.Located<{ - readonly $: "StatementLet"; - readonly name: Id; - readonly type: ascription | undefined; - readonly init: expression; - }>; - export type StatementDestruct = $.Located<{ - readonly $: "StatementDestruct"; - readonly type: TypeId; - readonly fields: inter; - readonly rest: optionalRest; - readonly init: expression; - }>; - export type StatementBlock = $.Located<{ - readonly $: "StatementBlock"; - readonly body: statements; - }>; - export type StatementReturn = $.Located<{ - readonly $: "StatementReturn"; - readonly expression: expression | undefined; - }>; - export type StatementCondition = $.Located<{ - readonly $: "StatementCondition"; - readonly condition: expression; - readonly trueBranch: statements; - readonly falseBranch: FalseBranch | StatementCondition | undefined; - }>; - export type StatementWhile = $.Located<{ - readonly $: "StatementWhile"; - readonly condition: parens; - readonly body: statements; - }>; - export type StatementRepeat = $.Located<{ - readonly $: "StatementRepeat"; - readonly condition: parens; - readonly body: statements; - }>; - export type StatementUntil = $.Located<{ - readonly $: "StatementUntil"; - readonly body: statements; - readonly condition: parens; - }>; - export type StatementTry = $.Located<{ - readonly $: "StatementTry"; - readonly body: statements; - readonly handler: - | { - readonly name: Id; - readonly body: statements; - } - | undefined; - }>; - export type StatementForEach = $.Located<{ - readonly $: "StatementForEach"; - readonly key: Id; - readonly value: Id; - readonly expression: expression; - readonly body: statements; - }>; - export type StatementExpression = $.Located<{ - readonly $: "StatementExpression"; - readonly expression: expression; - }>; - export type StatementAssign = $.Located<{ - readonly $: "StatementAssign"; - readonly left: expression; - readonly operator: augmentedOp | "="; - readonly right: expression; - }>; - export type statement = - | StatementLet - | StatementDestruct - | StatementBlock - | StatementReturn - | StatementCondition - | StatementWhile - | StatementRepeat - | StatementUntil - | StatementTry - | StatementForEach - | StatementExpression - | StatementAssign; - export type statements = readonly statement[]; - export type augmentedOp = - | "||=" - | "&&=" - | ">>=" - | "<<=" - | "-=" - | "+=" - | "*=" - | "/=" - | "%=" - | "|=" - | "&=" - | "^="; - export type FalseBranch = $.Located<{ - readonly $: "FalseBranch"; - readonly body: statements; - }>; - export type RegularField = $.Located<{ - readonly $: "RegularField"; - readonly fieldName: Id; - readonly varName: Id; - }>; - export type PunnedField = $.Located<{ - readonly $: "PunnedField"; - readonly name: Id; - }>; - export type destructItem = RegularField | PunnedField; - export type RestArgument = $.Located<{ - readonly $: "RestArgument"; - }>; - export type NoRestArgument = $.Located<{ - readonly $: "NoRestArgument"; - }>; - export type optionalRest = RestArgument | NoRestArgument; - export type Conditional = $.Located<{ - readonly $: "Conditional"; - readonly head: or; - readonly tail: - | { - readonly thenBranch: or; - readonly elseBranch: Conditional; - } - | undefined; - }>; - export type expression = Conditional; - export type Binary = $.Located<{ - readonly $: "Binary"; - readonly exprs: inter>; - }>; - export type Unary = $.Located<{ - readonly $: "Unary"; - readonly prefixes: readonly Operator<"-" | "+" | "!" | "~">[]; - readonly expression: Suffix; - }>; - export type mul = Binary; - export type add = Binary; - export type bitwiseShift = Binary>">; - export type compare = Binary=" | ">">; - export type equality = Binary; - export type bitwiseXor = Binary; - export type bitwiseOr = Binary; - export type and = Binary; - export type or = Binary; - export type Suffix = $.Located<{ - readonly $: "Suffix"; - readonly expression: primary; - readonly suffixes: readonly suffix[]; - }>; - export type Operator = $.Located<{ - readonly $: "Operator"; - readonly name: U; - }>; - export type SuffixUnboxNotNull = $.Located<{ - readonly $: "SuffixUnboxNotNull"; - }>; - export type SuffixCall = $.Located<{ - readonly $: "SuffixCall"; - readonly params: parameterList; - }>; - export type SuffixFieldAccess = $.Located<{ - readonly $: "SuffixFieldAccess"; - readonly name: Id; - }>; - export type suffix = SuffixUnboxNotNull | SuffixCall | SuffixFieldAccess; - export type Parens = $.Located<{ - readonly $: "Parens"; - readonly child: parens; - }>; - export type StructInstance = $.Located<{ - readonly $: "StructInstance"; - readonly type: TypeId; - readonly fields: commaList | undefined; - }>; - export type IntegerLiteral = $.Located<{ - readonly $: "IntegerLiteral"; - readonly value: - | IntegerLiteralHex - | IntegerLiteralBin - | IntegerLiteralOct - | IntegerLiteralDec; - }>; - export type BoolLiteral = $.Located<{ - readonly $: "BoolLiteral"; - readonly value: "true" | "false"; - }>; - export type InitOf = $.Located<{ - readonly $: "InitOf"; - readonly name: TypeId; - readonly params: parameterList; - }>; - export type CodeOf = $.Located<{ - readonly $: "CodeOf"; - readonly name: TypeId; - }>; - export type Null = $.Located<{ - readonly $: "Null"; - }>; - export type primary = - | Parens - | StructInstance - | IntegerLiteral - | BoolLiteral - | InitOf - | CodeOf - | Null - | StringLiteral - | Id; - export type parens = expression; - export type StructFieldInitializer = $.Located<{ - readonly $: "StructFieldInitializer"; - readonly name: Id; - readonly init: expression | undefined; - }>; - export type ParameterList = $.Located<{ - readonly $: "ParameterList"; - readonly values: commaList | undefined; - }>; - export type parameterList = commaList | undefined; - export type IntegerLiteralHex = $.Located<{ - readonly $: "IntegerLiteralHex"; - readonly digits: underscored; - }>; - export type IntegerLiteralBin = $.Located<{ - readonly $: "IntegerLiteralBin"; - readonly digits: underscored<"0" | "1">; - }>; - export type IntegerLiteralOct = $.Located<{ - readonly $: "IntegerLiteralOct"; - readonly digits: underscored; - }>; - export type underscored = string; - export type digit = string; - export type idPart = string | string | string | "_"; - export type FuncId = $.Located<{ - readonly $: "FuncId"; - readonly accessor: "." | "~" | undefined; - readonly id: string; - }>; - export type hexDigit = string | string | string; - export type escapeChar = - | "\\" - | '"' - | "n" - | "r" - | "t" - | "v" - | "b" - | "f" - | string - | string - | string; - export type reservedWord = keyword< - | "extend" - | "public" - | "fun" - | "let" - | "return" - | "receive" - | "native" - | "primitive" - | "null" - | "if" - | "else" - | "while" - | "repeat" - | "do" - | "until" - | "try" - | "catch" - | "foreach" - | "as" - | "map" - | "mutates" - | "extends" - | "external" - | "import" - | "with" - | "trait" - | "initOf" - | "override" - | "abstract" - | "virtual" - | "inline" - | "const" - >; - export type space = " " | "\t" | "\r" | "\n" | comment; - export type JustImports = $.Located<{ - readonly $: "JustImports"; - readonly imports: readonly Import[]; - }>; + export type Module = $.Located<{ + readonly $: "Module"; + readonly imports: readonly Import[]; + readonly items: readonly moduleItem[]; + }>; + export type Import = $.Located<{ + readonly $: "Import"; + readonly path: StringLiteral; + }>; + export type PrimitiveTypeDecl = $.Located<{ + readonly $: "PrimitiveTypeDecl"; + readonly name: TypeId; + }>; + export type $Function = $.Located<{ + readonly $: "Function"; + readonly attributes: readonly FunctionAttribute[]; + readonly name: Id; + readonly typeParams: typeParams | undefined; + readonly parameters: parameterList; + readonly returnType: ascription | undefined; + readonly body: FunctionDefinition | FunctionDeclaration; + }>; + export type AsmFunction = $.Located<{ + readonly $: "AsmFunction"; + readonly shuffle: shuffle | undefined; + readonly attributes: readonly FunctionAttribute[]; + readonly name: Id; + readonly typeParams: typeParams | undefined; + readonly parameters: parameterList; + readonly returnType: ascription | undefined; + readonly instructions: assembly; + }>; + export type NativeFunctionDecl = $.Located<{ + readonly $: "NativeFunctionDecl"; + readonly nativeName: FuncId; + readonly attributes: readonly FunctionAttribute[]; + readonly name: Id; + readonly typeParams: typeParams | undefined; + readonly parameters: parameterList; + readonly returnType: ascription | undefined; + }>; + export type Constant = $.Located<{ + readonly $: "Constant"; + readonly attributes: readonly ConstantAttribute[]; + readonly name: Id; + readonly type: ascription | undefined; + readonly body: ConstantDefinition | ConstantDeclaration; + }>; + export type StructDecl = $.Located<{ + readonly $: "StructDecl"; + readonly name: TypeId; + readonly typeParams: typeParams | undefined; + readonly fields: structFields; + }>; + export type MessageDecl = $.Located<{ + readonly $: "MessageDecl"; + readonly opcode: expression | undefined; + readonly name: TypeId; + readonly fields: structFields; + }>; + export type Contract = $.Located<{ + readonly $: "Contract"; + readonly attributes: readonly ContractAttribute[]; + readonly name: TypeId; + readonly parameters: ParameterList | undefined; + readonly traits: inheritedTraits | undefined; + readonly declarations: readonly contractItemDecl[]; + }>; + export type Trait = $.Located<{ + readonly $: "Trait"; + readonly attributes: readonly ContractAttribute[]; + readonly name: TypeId; + readonly traits: inheritedTraits | undefined; + readonly declarations: readonly traitItemDecl[]; + }>; + export type moduleItem = PrimitiveTypeDecl | $Function | AsmFunction | NativeFunctionDecl | Constant | StructDecl | MessageDecl | Contract | Trait; + export type ContractInit = $.Located<{ + readonly $: "ContractInit"; + readonly parameters: parameterList; + readonly body: statements; + }>; + export type Receiver = $.Located<{ + readonly $: "Receiver"; + readonly type: ReceiverType; + readonly param: receiverParam; + readonly body: statements; + }>; + export type FieldDecl = $.Located<{ + readonly $: "FieldDecl"; + readonly name: Id; + readonly type: ascription; + readonly expression: expression | undefined; + }>; + export type semicolon = ";" | "}"; + export type storageVar = FieldDecl; + export type contractItemDecl = ContractInit | Receiver | $Function | AsmFunction | Constant | storageVar; + export type traitItemDecl = Receiver | $Function | AsmFunction | Constant | storageVar; + export type FunctionDefinition = $.Located<{ + readonly $: "FunctionDefinition"; + readonly body: statements; + }>; + export type FunctionDeclaration = $.Located<{ + readonly $: "FunctionDeclaration"; + }>; + export type Id = $.Located<{ + readonly $: "Id"; + readonly name: string; + }>; + export type IntegerLiteralDec = $.Located<{ + readonly $: "IntegerLiteralDec"; + readonly digits: underscored; + }>; + export type shuffle = { + readonly ids: readonly Id[]; + readonly to: readonly IntegerLiteralDec[] | undefined; + }; + export type ConstantAttribute = $.Located<{ + readonly $: "ConstantAttribute"; + readonly name: keyword<"virtual"> | keyword<"override"> | keyword<"abstract">; + }>; + export type ConstantDefinition = $.Located<{ + readonly $: "ConstantDefinition"; + readonly expression: expression; + }>; + export type ConstantDeclaration = $.Located<{ + readonly $: "ConstantDeclaration"; + }>; + export type inter = { + readonly head: A; + readonly tail: readonly { + readonly op: B; + readonly right: A; + }[]; + }; + export type structFields = inter | undefined; + export type keyword = T; + export type commaList = inter; + export type TypeId = $.Located<{ + readonly $: "TypeId"; + readonly name: string; + }>; + export type inheritedTraits = commaList; + export type ContractAttribute = $.Located<{ + readonly $: "ContractAttribute"; + readonly name: StringLiteral; + }>; + export type FunctionAttribute = $.Located<{ + readonly $: "FunctionAttribute"; + readonly name: GetAttribute | keyword<"mutates"> | keyword<"extends"> | keyword<"virtual"> | keyword<"override"> | keyword<"inline"> | keyword<"abstract">; + }>; + export type GetAttribute = $.Located<{ + readonly $: "GetAttribute"; + readonly methodId: expression | undefined; + }>; + export type ReceiverType = $.Located<{ + readonly $: "ReceiverType"; + readonly name: "bounced" | keyword<"receive"> | keyword<"external">; + }>; + export type Parameter = $.Located<{ + readonly $: "Parameter"; + readonly name: Id; + readonly type: ascription; + }>; + export type StringLiteral = $.Located<{ + readonly $: "StringLiteral"; + readonly value: string; + }>; + export type receiverParam = Parameter | StringLiteral | undefined; + export type assembly = string; + export type multiLineComment = string; + export type singleLineComment = string; + export type comment = multiLineComment | singleLineComment; + export type assemblyItem = {} | comment | {} | readonly {}[]; + export type assemblySequence = readonly assemblyItem[]; + export type TypeAs = $.Located<{ + readonly $: "TypeAs"; + readonly type: TypeOptional; + readonly as: readonly storage[]; + }>; + export type $type = TypeAs; + export type ascription = $type; + export type TypeOptional = $.Located<{ + readonly $: "TypeOptional"; + readonly type: typePrimary; + readonly optionals: readonly Optional[]; + }>; + export type Optional = $.Located<{ + readonly $: "Optional"; + }>; + export type TypeGeneric = $.Located<{ + readonly $: "TypeGeneric"; + readonly name: MapKeyword | Bounced | TypeId; + readonly args: typeArgs; + }>; + export type TypeRegular = $.Located<{ + readonly $: "TypeRegular"; + readonly child: TypeId; + }>; + export type TypeTuple = $.Located<{ + readonly $: "TypeTuple"; + readonly types: commaList<$type> | undefined; + }>; + export type TypeTensor = $.Located<{ + readonly $: "TypeTensor"; + readonly head: $type; + readonly tail: readonly $type[]; + }>; + export type TypeUnit = $.Located<{ + readonly $: "TypeUnit"; + }>; + export type typeParens = $type; + export type typePrimary = TypeGeneric | TypeRegular | TypeTuple | TypeTensor | TypeUnit | typeParens; + export type MapKeyword = $.Located<{ + readonly $: "MapKeyword"; + }>; + export type Bounced = $.Located<{ + readonly $: "Bounced"; + }>; + export type IntStorage = $.Located<{ + readonly $: "IntStorage"; + readonly isVar: "var" | undefined; + readonly isUnsigned: "u" | undefined; + readonly width: string; + }>; + export type CoinsStorage = $.Located<{ + readonly $: "CoinsStorage"; + }>; + export type RemainingStorage = $.Located<{ + readonly $: "RemainingStorage"; + }>; + export type BytesStorage = $.Located<{ + readonly $: "BytesStorage"; + readonly width: string; + }>; + export type storage = IntStorage | CoinsStorage | RemainingStorage | BytesStorage; + export type generic = commaList | undefined; + export type typeParams = generic; + export type typeArgs = generic<$type>; + export type StatementLet = $.Located<{ + readonly $: "StatementLet"; + readonly name: Id; + readonly type: ascription | undefined; + readonly init: expression; + }>; + export type StatementDestruct = $.Located<{ + readonly $: "StatementDestruct"; + readonly type: TypeId; + readonly fields: inter; + readonly rest: optionalRest; + readonly init: expression; + }>; + export type StatementBlock = $.Located<{ + readonly $: "StatementBlock"; + readonly body: statements; + }>; + export type StatementReturn = $.Located<{ + readonly $: "StatementReturn"; + readonly expression: expression | undefined; + }>; + export type StatementCondition = $.Located<{ + readonly $: "StatementCondition"; + readonly condition: expression; + readonly trueBranch: statements; + readonly falseBranch: FalseBranch | StatementCondition | undefined; + }>; + export type StatementWhile = $.Located<{ + readonly $: "StatementWhile"; + readonly condition: parens; + readonly body: statements; + }>; + export type StatementRepeat = $.Located<{ + readonly $: "StatementRepeat"; + readonly condition: parens; + readonly body: statements; + }>; + export type StatementUntil = $.Located<{ + readonly $: "StatementUntil"; + readonly body: statements; + readonly condition: parens; + }>; + export type StatementTry = $.Located<{ + readonly $: "StatementTry"; + readonly body: statements; + readonly handler: { + readonly name: Id; + readonly body: statements; + } | undefined; + }>; + export type StatementForEach = $.Located<{ + readonly $: "StatementForEach"; + readonly key: Id; + readonly value: Id; + readonly expression: expression; + readonly body: statements; + }>; + export type StatementExpression = $.Located<{ + readonly $: "StatementExpression"; + readonly expression: expression; + }>; + export type StatementAssign = $.Located<{ + readonly $: "StatementAssign"; + readonly left: expression; + readonly operator: augmentedOp | "="; + readonly right: expression; + }>; + export type statement = StatementLet | StatementDestruct | StatementBlock | StatementReturn | StatementCondition | StatementWhile | StatementRepeat | StatementUntil | StatementTry | StatementForEach | StatementExpression | StatementAssign; + export type statements = readonly statement[]; + export type augmentedOp = "||=" | "&&=" | ">>=" | "<<=" | "-=" | "+=" | "*=" | "/=" | "%=" | "|=" | "&=" | "^="; + export type FalseBranch = $.Located<{ + readonly $: "FalseBranch"; + readonly body: statements; + }>; + export type RegularField = $.Located<{ + readonly $: "RegularField"; + readonly fieldName: Id; + readonly varName: Id; + }>; + export type PunnedField = $.Located<{ + readonly $: "PunnedField"; + readonly name: Id; + }>; + export type destructItem = RegularField | PunnedField; + export type RestArgument = $.Located<{ + readonly $: "RestArgument"; + }>; + export type NoRestArgument = $.Located<{ + readonly $: "NoRestArgument"; + }>; + export type optionalRest = RestArgument | NoRestArgument; + export type Conditional = $.Located<{ + readonly $: "Conditional"; + readonly head: or; + readonly tail: { + readonly thenBranch: or; + readonly elseBranch: Conditional; + } | undefined; + }>; + export type expression = Conditional; + export type Binary = $.Located<{ + readonly $: "Binary"; + readonly exprs: inter>; + }>; + export type Unary = $.Located<{ + readonly $: "Unary"; + readonly prefixes: readonly Operator<"-" | "+" | "!" | "~">[]; + readonly expression: Suffix; + }>; + export type mul = Binary; + export type add = Binary; + export type bitwiseShift = Binary>">; + export type compare = Binary=" | ">">; + export type equality = Binary; + export type bitwiseXor = Binary; + export type bitwiseOr = Binary; + export type and = Binary; + export type or = Binary; + export type Suffix = $.Located<{ + readonly $: "Suffix"; + readonly expression: primary; + readonly suffixes: readonly suffix[]; + }>; + export type Operator = $.Located<{ + readonly $: "Operator"; + readonly name: U; + }>; + export type SuffixUnboxNotNull = $.Located<{ + readonly $: "SuffixUnboxNotNull"; + }>; + export type SuffixCall = $.Located<{ + readonly $: "SuffixCall"; + readonly typeArgs: typeArgs | undefined; + readonly params: parameterList; + }>; + export type SuffixFieldAccess = $.Located<{ + readonly $: "SuffixFieldAccess"; + readonly name: Id; + }>; + export type suffix = SuffixUnboxNotNull | SuffixCall | SuffixFieldAccess; + export type Unit = $.Located<{ + readonly $: "Unit"; + }>; + export type Tensor = $.Located<{ + readonly $: "Tensor"; + readonly head: expression; + readonly tail: readonly expression[]; + }>; + export type Tuple = $.Located<{ + readonly $: "Tuple"; + readonly types: commaList | undefined; + }>; + export type Parens = $.Located<{ + readonly $: "Parens"; + readonly child: parens; + }>; + export type StructInstance = $.Located<{ + readonly $: "StructInstance"; + readonly type: TypeId; + readonly typeArgs: typeArgs | undefined; + readonly fields: commaList | undefined; + }>; + export type IntegerLiteral = $.Located<{ + readonly $: "IntegerLiteral"; + readonly value: IntegerLiteralHex | IntegerLiteralBin | IntegerLiteralOct | IntegerLiteralDec; + }>; + export type BoolLiteral = $.Located<{ + readonly $: "BoolLiteral"; + readonly value: "true" | "false"; + }>; + export type InitOf = $.Located<{ + readonly $: "InitOf"; + readonly name: TypeId; + readonly params: parameterList; + }>; + export type CodeOf = $.Located<{ + readonly $: "CodeOf"; + readonly name: TypeId; + }>; + export type Null = $.Located<{ + readonly $: "Null"; + }>; + export type primary = Unit | Tensor | Tuple | Parens | StructInstance | IntegerLiteral | BoolLiteral | InitOf | CodeOf | Null | StringLiteral | Id; + export type parens = expression; + export type StructFieldInitializer = $.Located<{ + readonly $: "StructFieldInitializer"; + readonly name: Id; + readonly init: expression | undefined; + }>; + export type ParameterList = $.Located<{ + readonly $: "ParameterList"; + readonly values: commaList | undefined; + }>; + export type parameterList = commaList | undefined; + export type IntegerLiteralHex = $.Located<{ + readonly $: "IntegerLiteralHex"; + readonly digits: underscored; + }>; + export type IntegerLiteralBin = $.Located<{ + readonly $: "IntegerLiteralBin"; + readonly digits: underscored<"0" | "1">; + }>; + export type IntegerLiteralOct = $.Located<{ + readonly $: "IntegerLiteralOct"; + readonly digits: underscored; + }>; + export type underscored = string; + export type digit = string; + export type idPart = string | string | string | "_"; + export type FuncId = $.Located<{ + readonly $: "FuncId"; + readonly accessor: "." | "~" | undefined; + readonly id: string; + }>; + export type hexDigit = string | string | string; + export type escapeChar = "\\" | "\"" | "n" | "r" | "t" | "v" | "b" | "f" | string | string | string; + export type reservedWord = keyword<"extend" | "public" | "fun" | "let" | "return" | "receive" | "native" | "primitive" | "null" | "if" | "else" | "while" | "repeat" | "do" | "until" | "try" | "catch" | "foreach" | "as" | "map" | "mutates" | "extends" | "external" | "import" | "with" | "trait" | "initOf" | "override" | "abstract" | "virtual" | "inline" | "const">; + export type space = " " | "\t" | "\r" | "\n" | comment; + export type JustImports = $.Located<{ + readonly $: "JustImports"; + readonly imports: readonly Import[]; + }>; } -export const Module: $.Parser<$ast.Module> = $.loc( - $.field( - $.pure("Module"), - "$", - $.field( - $.star($.lazy(() => Import)), - "imports", - $.field($.star($.lazy(() => moduleItem)), "items", $.eps), - ), - ), -); -export const Import: $.Parser<$ast.Import> = $.loc( - $.field( - $.pure("Import"), - "$", - $.right( - $.lazy(() => keyword($.str("import"))), - $.field( - $.lazy(() => StringLiteral), - "path", - $.right($.str(";"), $.eps), - ), - ), - ), -); -export const PrimitiveTypeDecl: $.Parser<$ast.PrimitiveTypeDecl> = $.loc( - $.field( - $.pure("PrimitiveTypeDecl"), - "$", - $.right( - $.lazy(() => keyword($.str("primitive"))), - $.field( - $.lazy(() => TypeId), - "name", - $.right($.str(";"), $.eps), - ), - ), - ), -); -export const $Function: $.Parser<$ast.$Function> = $.loc( - $.field( - $.pure("Function"), - "$", - $.field( - $.star($.lazy(() => FunctionAttribute)), - "attributes", - $.right( - $.lazy(() => keyword($.str("fun"))), - $.field( - $.lazy(() => Id), - "name", - $.field( - $.lazy(() => parameterList($.lazy(() => Parameter))), - "parameters", - $.field( - $.opt($.lazy(() => ascription)), - "returnType", - $.field( - $.alt( - $.lazy(() => FunctionDefinition), - $.lazy(() => FunctionDeclaration), - ), - "body", - $.eps, - ), - ), - ), - ), - ), - ), - ), -); -export const AsmFunction: $.Parser<$ast.AsmFunction> = $.loc( - $.field( - $.pure("AsmFunction"), - "$", - $.right( - $.str("asm"), - $.field( - $.opt($.lazy(() => shuffle)), - "shuffle", - $.field( - $.star($.lazy(() => FunctionAttribute)), - "attributes", - $.right( - $.lazy(() => keyword($.str("fun"))), - $.field( - $.lazy(() => Id), - "name", - $.field( - $.lazy(() => - parameterList($.lazy(() => Parameter)), - ), - "parameters", - $.field( - $.opt($.lazy(() => ascription)), - "returnType", - $.right( - $.str("{"), - $.field( - $.lazy(() => assembly), - "instructions", - $.right($.str("}"), $.eps), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), -); -export const NativeFunctionDecl: $.Parser<$ast.NativeFunctionDecl> = $.loc( - $.field( - $.pure("NativeFunctionDecl"), - "$", - $.right( - $.str("@name"), - $.right( - $.str("("), - $.field( - $.lex($.lazy(() => FuncId)), - "nativeName", - $.right( - $.str(")"), - $.field( - $.star($.lazy(() => FunctionAttribute)), - "attributes", - $.right( - $.lazy(() => keyword($.str("native"))), - $.field( - $.lazy(() => Id), - "name", - $.field( - $.lazy(() => - parameterList( - $.lazy(() => Parameter), - ), - ), - "parameters", - $.field( - $.opt($.lazy(() => ascription)), - "returnType", - $.right($.str(";"), $.eps), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), -); -export const Constant: $.Parser<$ast.Constant> = $.loc( - $.field( - $.pure("Constant"), - "$", - $.field( - $.star($.lazy(() => ConstantAttribute)), - "attributes", - $.right( - $.lazy(() => keyword($.str("const"))), - $.field( - $.lazy(() => Id), - "name", - $.field( - $.lazy(() => ascription), - "type", - $.field( - $.alt( - $.lazy(() => ConstantDefinition), - $.lazy(() => ConstantDeclaration), - ), - "body", - $.eps, - ), - ), - ), - ), - ), - ), -); -export const StructDecl: $.Parser<$ast.StructDecl> = $.loc( - $.field( - $.pure("StructDecl"), - "$", - $.right( - $.str("struct"), - $.field( - $.lazy(() => TypeId), - "name", - $.right( - $.str("{"), - $.field( - $.lazy(() => structFields), - "fields", - $.right($.str("}"), $.eps), - ), - ), - ), - ), - ), -); -export const MessageDecl: $.Parser<$ast.MessageDecl> = $.loc( - $.field( - $.pure("MessageDecl"), - "$", - $.right( - $.str("message"), - $.field( - $.opt( - $.right( - $.str("("), - $.left( - $.lazy(() => expression), - $.str(")"), - ), - ), - ), - "opcode", - $.field( - $.lazy(() => TypeId), - "name", - $.right( - $.str("{"), - $.field( - $.lazy(() => structFields), - "fields", - $.right($.str("}"), $.eps), - ), - ), - ), - ), - ), - ), -); -export const Contract: $.Parser<$ast.Contract> = $.loc( - $.field( - $.pure("Contract"), - "$", - $.field( - $.star($.lazy(() => ContractAttribute)), - "attributes", - $.right( - $.lazy(() => keyword($.str("contract"))), - $.field( - $.lazy(() => TypeId), - "name", - $.field( - $.opt( - $.lazy(() => - ParameterList($.lazy(() => Parameter)), - ), - ), - "parameters", - $.field( - $.opt($.lazy(() => inheritedTraits)), - "traits", - $.right( - $.str("{"), - $.field( - $.star($.lazy(() => contractItemDecl)), - "declarations", - $.right($.str("}"), $.eps), - ), - ), - ), - ), - ), - ), - ), - ), -); -export const Trait: $.Parser<$ast.Trait> = $.loc( - $.field( - $.pure("Trait"), - "$", - $.field( - $.star($.lazy(() => ContractAttribute)), - "attributes", - $.right( - $.lazy(() => keyword($.str("trait"))), - $.field( - $.lazy(() => TypeId), - "name", - $.field( - $.opt($.lazy(() => inheritedTraits)), - "traits", - $.right( - $.str("{"), - $.field( - $.star($.lazy(() => traitItemDecl)), - "declarations", - $.right($.str("}"), $.eps), - ), - ), - ), - ), - ), - ), - ), -); -export const moduleItem: $.Parser<$ast.moduleItem> = $.alt( - PrimitiveTypeDecl, - $.alt( - $Function, - $.alt( - AsmFunction, - $.alt( - NativeFunctionDecl, - $.alt( - Constant, - $.alt( - StructDecl, - $.alt(MessageDecl, $.alt(Contract, Trait)), - ), - ), - ), - ), - ), -); -export const ContractInit: $.Parser<$ast.ContractInit> = $.loc( - $.field( - $.pure("ContractInit"), - "$", - $.right( - $.str("init"), - $.field( - $.lazy(() => parameterList($.lazy(() => Parameter))), - "parameters", - $.field( - $.lazy(() => statements), - "body", - $.eps, - ), - ), - ), - ), -); -export const Receiver: $.Parser<$ast.Receiver> = $.loc( - $.field( - $.pure("Receiver"), - "$", - $.field( - $.lazy(() => ReceiverType), - "type", - $.right( - $.str("("), - $.field( - $.lazy(() => receiverParam), - "param", - $.right( - $.str(")"), - $.field( - $.lazy(() => statements), - "body", - $.eps, - ), - ), - ), - ), - ), - ), -); -export const FieldDecl: $.Parser<$ast.FieldDecl> = $.loc( - $.field( - $.pure("FieldDecl"), - "$", - $.field( - $.lazy(() => Id), - "name", - $.field( - $.lazy(() => ascription), - "type", - $.field( - $.opt( - $.right( - $.str("="), - $.lazy(() => expression), - ), - ), - "expression", - $.eps, - ), - ), - ), - ), -); -export const semicolon: $.Parser<$ast.semicolon> = $.alt( - $.str(";"), - $.lookPos($.str("}")), -); -export const storageVar: $.Parser<$ast.storageVar> = $.left( - FieldDecl, - semicolon, -); -export const contractItemDecl: $.Parser<$ast.contractItemDecl> = $.alt( - ContractInit, - $.alt( - Receiver, - $.alt($Function, $.alt(AsmFunction, $.alt(Constant, storageVar))), - ), -); -export const traitItemDecl: $.Parser<$ast.traitItemDecl> = $.alt( - Receiver, - $.alt($Function, $.alt(AsmFunction, $.alt(Constant, storageVar))), -); -export const FunctionDefinition: $.Parser<$ast.FunctionDefinition> = $.loc( - $.field( - $.pure("FunctionDefinition"), - "$", - $.field( - $.lazy(() => statements), - "body", - $.eps, - ), - ), -); -export const FunctionDeclaration: $.Parser<$ast.FunctionDeclaration> = $.loc( - $.field($.pure("FunctionDeclaration"), "$", $.right(semicolon, $.eps)), -); -export const Id: $.Parser<$ast.Id> = $.named( - "identifier", - $.loc( - $.field( - $.pure("Id"), - "$", - $.field( - $.lex( - $.stry( - $.right( - $.lookNeg($.lazy(() => reservedWord)), - $.right( - $.regex("a-zA-Z_", [ - $.ExpRange("a", "z"), - $.ExpRange("A", "Z"), - $.ExpString("_"), - ]), - $.right($.star($.lazy(() => idPart)), $.eps), - ), - ), - ), - ), - "name", - $.eps, - ), - ), - ), -); -export const IntegerLiteralDec: $.Parser<$ast.IntegerLiteralDec> = $.loc( - $.field( - $.pure("IntegerLiteralDec"), - "$", - $.field( - $.lex($.lazy(() => underscored($.lazy(() => digit)))), - "digits", - $.eps, - ), - ), -); -export const shuffle: $.Parser<$ast.shuffle> = $.right( - $.str("("), - $.field( - $.star(Id), - "ids", - $.field( - $.opt($.right($.str("->"), $.plus(IntegerLiteralDec))), - "to", - $.right($.str(")"), $.eps), - ), - ), -); -export const ConstantAttribute: $.Parser<$ast.ConstantAttribute> = $.loc( - $.field( - $.pure("ConstantAttribute"), - "$", - $.field( - $.alt( - $.lazy(() => keyword($.str("virtual"))), - $.alt( - $.lazy(() => keyword($.str("override"))), - $.lazy(() => keyword($.str("abstract"))), - ), - ), - "name", - $.eps, - ), - ), -); -export const ConstantDefinition: $.Parser<$ast.ConstantDefinition> = $.loc( - $.field( - $.pure("ConstantDefinition"), - "$", - $.right( - $.str("="), - $.field( - $.lazy(() => expression), - "expression", - $.right(semicolon, $.eps), - ), - ), - ), -); -export const ConstantDeclaration: $.Parser<$ast.ConstantDeclaration> = $.loc( - $.field($.pure("ConstantDeclaration"), "$", $.right(semicolon, $.eps)), -); -export const inter = ( - A: $.Parser, - B: $.Parser, -): $.Parser<$ast.inter> => - $.field( - $.lazy(() => A), - "head", - $.field( - $.star( - $.field( - $.lazy(() => B), - "op", - $.field( - $.lazy(() => A), - "right", - $.eps, - ), - ), - ), - "tail", - $.eps, - ), - ); -export const structFields: $.Parser<$ast.structFields> = $.left( - $.opt(inter(FieldDecl, $.str(";"))), - $.opt($.str(";")), -); -export const keyword = (T: $.Parser): $.Parser<$ast.keyword> => - $.lex( - $.left( - $.lazy(() => T), - $.lookNeg($.lazy(() => idPart)), - ), - ); -export const commaList = (T: $.Parser): $.Parser<$ast.commaList> => - $.left( - inter( - $.lazy(() => T), - $.str(","), - ), - $.opt($.str(",")), - ); -export const TypeId: $.Parser<$ast.TypeId> = $.named( - "capitalized identifier", - $.loc( - $.field( - $.pure("TypeId"), - "$", - $.field( - $.lex( - $.stry( - $.right( - $.regex("A-Z", [$.ExpRange("A", "Z")]), - $.right( - $.star( - $.regex( - "a-zA-Z0-9_", - [ - $.ExpRange("a", "z"), - $.ExpRange("A", "Z"), - $.ExpRange("0", "9"), - $.ExpString("_"), - ], - ), - ), - $.eps, - ), - ), - ), - ), - "name", - $.eps, - ), - ), - ), -); -export const inheritedTraits: $.Parser<$ast.inheritedTraits> = $.right( - keyword($.str("with")), - commaList(TypeId), -); -export const ContractAttribute: $.Parser<$ast.ContractAttribute> = $.loc( - $.field( - $.pure("ContractAttribute"), - "$", - $.right( - $.str("@interface"), - $.right( - $.str("("), - $.field( - $.lazy(() => StringLiteral), - "name", - $.right($.str(")"), $.eps), - ), - ), - ), - ), -); -export const FunctionAttribute: $.Parser<$ast.FunctionAttribute> = $.loc( - $.field( - $.pure("FunctionAttribute"), - "$", - $.field( - $.alt( - $.lazy(() => GetAttribute), - $.alt( - keyword($.str("mutates")), - $.alt( - keyword($.str("extends")), - $.alt( - keyword($.str("virtual")), - $.alt( - keyword($.str("override")), - $.alt( - keyword($.str("inline")), - keyword($.str("abstract")), - ), - ), - ), - ), - ), - ), - "name", - $.eps, - ), - ), -); -export const GetAttribute: $.Parser<$ast.GetAttribute> = $.loc( - $.field( - $.pure("GetAttribute"), - "$", - $.right( - $.str("get"), - $.field( - $.opt( - $.right( - $.str("("), - $.left( - $.lazy(() => expression), - $.str(")"), - ), - ), - ), - "methodId", - $.eps, - ), - ), - ), -); -export const ReceiverType: $.Parser<$ast.ReceiverType> = $.loc( - $.field( - $.pure("ReceiverType"), - "$", - $.field( - $.alt( - $.str("bounced"), - $.alt(keyword($.str("receive")), keyword($.str("external"))), - ), - "name", - $.eps, - ), - ), -); -export const Parameter: $.Parser<$ast.Parameter> = $.loc( - $.field( - $.pure("Parameter"), - "$", - $.field( - Id, - "name", - $.field( - $.lazy(() => ascription), - "type", - $.eps, - ), - ), - ), -); -export const StringLiteral: $.Parser<$ast.StringLiteral> = $.loc( - $.field( - $.pure("StringLiteral"), - "$", - $.field( - $.lex( - $.right( - $.str('"'), - $.left( - $.stry( - $.star( - $.alt( - $.regex<'"' | "\\">( - '^"\\\\', - $.negateExps([ - $.ExpString('"'), - $.ExpString("\\"), - ]), - ), - $.right( - $.str("\\"), - $.lazy(() => escapeChar), - ), - ), - ), - ), - $.str('"'), - ), - ), - ), - "value", - $.eps, - ), - ), -); -export const receiverParam: $.Parser<$ast.receiverParam> = $.opt( - $.alt(Parameter, StringLiteral), -); -export const assembly: $.Parser<$ast.assembly> = $.lex( - $.stry($.lazy(() => assemblySequence)), -); -export const multiLineComment: $.Parser<$ast.multiLineComment> = $.right( - $.str("/*"), - $.left( - $.stry($.star($.right($.lookNeg($.str("*/")), $.right($.any, $.eps)))), - $.str("*/"), - ), -); -export const singleLineComment: $.Parser<$ast.singleLineComment> = $.right( - $.str("//"), - $.stry( - $.star( - $.regex<"\r" | "\n">( - "^\\r\\n", - $.negateExps([$.ExpString("\r"), $.ExpString("\n")]), - ), - ), - ), -); -export const comment: $.Parser<$ast.comment> = $.alt( - multiLineComment, - singleLineComment, -); -export const assemblyItem: $.Parser<$ast.assemblyItem> = $.alt( - $.right( - $.str("{"), - $.right( - $.lazy(() => assemblySequence), - $.right($.str("}"), $.eps), - ), - ), - $.alt( - comment, - $.alt( - $.right( - $.str('"'), - $.right( - $.star( - $.regex<'"'>('^"', $.negateExps([$.ExpString('"')])), - ), - $.right($.str('"'), $.eps), - ), - ), - $.plus( - $.right( - $.lookNeg( - $.alt( - $.regex<'"' | "{" | "}">('"{}', [ - $.ExpString('"'), - $.ExpString("{"), - $.ExpString("}"), - ]), - $.alt($.str("//"), $.str("/*")), - ), - ), - $.right($.any, $.eps), - ), - ), - ), - ), -); -export const assemblySequence: $.Parser<$ast.assemblySequence> = - $.star(assemblyItem); -export const TypeAs: $.Parser<$ast.TypeAs> = $.loc( - $.field( - $.pure("TypeAs"), - "$", - $.field( - $.lazy(() => TypeOptional), - "type", - $.field( - $.star( - $.right(keyword($.str("as")), $.lex($.lazy(() => storage))), - ), - "as", - $.eps, - ), - ), - ), -); +export const Module: $.Parser<$ast.Module> = $.loc($.field($.pure("Module"), "$", $.field($.star($.lazy(() => Import)), "imports", $.field($.star($.lazy(() => moduleItem)), "items", $.eps)))); +export const Import: $.Parser<$ast.Import> = $.loc($.field($.pure("Import"), "$", $.right($.lazy(() => keyword($.str("import"))), $.field($.lazy(() => StringLiteral), "path", $.right($.str(";"), $.eps))))); +export const PrimitiveTypeDecl: $.Parser<$ast.PrimitiveTypeDecl> = $.loc($.field($.pure("PrimitiveTypeDecl"), "$", $.right($.lazy(() => keyword($.str("primitive"))), $.field($.lazy(() => TypeId), "name", $.right($.str(";"), $.eps))))); +export const $Function: $.Parser<$ast.$Function> = $.loc($.field($.pure("Function"), "$", $.field($.star($.lazy(() => FunctionAttribute)), "attributes", $.right($.lazy(() => keyword($.str("fun"))), $.field($.lazy(() => Id), "name", $.field($.opt($.lazy(() => typeParams)), "typeParams", $.field($.lazy(() => parameterList($.lazy(() => Parameter))), "parameters", $.field($.opt($.lazy(() => ascription)), "returnType", $.field($.alt($.lazy(() => FunctionDefinition), $.lazy(() => FunctionDeclaration)), "body", $.eps))))))))); +export const AsmFunction: $.Parser<$ast.AsmFunction> = $.loc($.field($.pure("AsmFunction"), "$", $.right($.str("asm"), $.field($.opt($.lazy(() => shuffle)), "shuffle", $.field($.star($.lazy(() => FunctionAttribute)), "attributes", $.right($.lazy(() => keyword($.str("fun"))), $.field($.lazy(() => Id), "name", $.field($.opt($.lazy(() => typeParams)), "typeParams", $.field($.lazy(() => parameterList($.lazy(() => Parameter))), "parameters", $.field($.opt($.lazy(() => ascription)), "returnType", $.right($.str("{"), $.field($.lazy(() => assembly), "instructions", $.right($.str("}"), $.eps))))))))))))); +export const NativeFunctionDecl: $.Parser<$ast.NativeFunctionDecl> = $.loc($.field($.pure("NativeFunctionDecl"), "$", $.right($.str("@name"), $.right($.str("("), $.field($.lex($.lazy(() => FuncId)), "nativeName", $.right($.str(")"), $.field($.star($.lazy(() => FunctionAttribute)), "attributes", $.right($.lazy(() => keyword($.str("native"))), $.field($.lazy(() => Id), "name", $.field($.opt($.lazy(() => typeParams)), "typeParams", $.field($.lazy(() => parameterList($.lazy(() => Parameter))), "parameters", $.field($.opt($.lazy(() => ascription)), "returnType", $.right($.str(";"), $.eps))))))))))))); +export const Constant: $.Parser<$ast.Constant> = $.loc($.field($.pure("Constant"), "$", $.field($.star($.lazy(() => ConstantAttribute)), "attributes", $.right($.lazy(() => keyword($.str("const"))), $.field($.lazy(() => Id), "name", $.field($.opt($.lazy(() => ascription)), "type", $.field($.alt($.lazy(() => ConstantDefinition), $.lazy(() => ConstantDeclaration)), "body", $.eps))))))); +export const StructDecl: $.Parser<$ast.StructDecl> = $.loc($.field($.pure("StructDecl"), "$", $.right($.str("struct"), $.field($.lazy(() => TypeId), "name", $.field($.opt($.lazy(() => typeParams)), "typeParams", $.right($.str("{"), $.field($.lazy(() => structFields), "fields", $.right($.str("}"), $.eps)))))))); +export const MessageDecl: $.Parser<$ast.MessageDecl> = $.loc($.field($.pure("MessageDecl"), "$", $.right($.str("message"), $.field($.opt($.right($.str("("), $.left($.lazy(() => expression), $.str(")")))), "opcode", $.field($.lazy(() => TypeId), "name", $.right($.str("{"), $.field($.lazy(() => structFields), "fields", $.right($.str("}"), $.eps)))))))); +export const Contract: $.Parser<$ast.Contract> = $.loc($.field($.pure("Contract"), "$", $.field($.star($.lazy(() => ContractAttribute)), "attributes", $.right($.lazy(() => keyword($.str("contract"))), $.field($.lazy(() => TypeId), "name", $.field($.opt($.lazy(() => ParameterList($.lazy(() => Parameter)))), "parameters", $.field($.opt($.lazy(() => inheritedTraits)), "traits", $.right($.str("{"), $.field($.star($.lazy(() => contractItemDecl)), "declarations", $.right($.str("}"), $.eps)))))))))); +export const Trait: $.Parser<$ast.Trait> = $.loc($.field($.pure("Trait"), "$", $.field($.star($.lazy(() => ContractAttribute)), "attributes", $.right($.lazy(() => keyword($.str("trait"))), $.field($.lazy(() => TypeId), "name", $.field($.opt($.lazy(() => inheritedTraits)), "traits", $.right($.str("{"), $.field($.star($.lazy(() => traitItemDecl)), "declarations", $.right($.str("}"), $.eps))))))))); +export const moduleItem: $.Parser<$ast.moduleItem> = $.alt(PrimitiveTypeDecl, $.alt($Function, $.alt(AsmFunction, $.alt(NativeFunctionDecl, $.alt(Constant, $.alt(StructDecl, $.alt(MessageDecl, $.alt(Contract, Trait)))))))); +export const ContractInit: $.Parser<$ast.ContractInit> = $.loc($.field($.pure("ContractInit"), "$", $.right($.str("init"), $.field($.lazy(() => parameterList($.lazy(() => Parameter))), "parameters", $.field($.lazy(() => statements), "body", $.eps))))); +export const Receiver: $.Parser<$ast.Receiver> = $.loc($.field($.pure("Receiver"), "$", $.field($.lazy(() => ReceiverType), "type", $.right($.str("("), $.field($.lazy(() => receiverParam), "param", $.right($.str(")"), $.field($.lazy(() => statements), "body", $.eps))))))); +export const FieldDecl: $.Parser<$ast.FieldDecl> = $.loc($.field($.pure("FieldDecl"), "$", $.field($.lazy(() => Id), "name", $.field($.lazy(() => ascription), "type", $.field($.opt($.right($.str("="), $.lazy(() => expression))), "expression", $.eps))))); +export const semicolon: $.Parser<$ast.semicolon> = $.alt($.str(";"), $.lookPos($.str("}"))); +export const storageVar: $.Parser<$ast.storageVar> = $.left(FieldDecl, semicolon); +export const contractItemDecl: $.Parser<$ast.contractItemDecl> = $.alt(ContractInit, $.alt(Receiver, $.alt($Function, $.alt(AsmFunction, $.alt(Constant, storageVar))))); +export const traitItemDecl: $.Parser<$ast.traitItemDecl> = $.alt(Receiver, $.alt($Function, $.alt(AsmFunction, $.alt(Constant, storageVar)))); +export const FunctionDefinition: $.Parser<$ast.FunctionDefinition> = $.loc($.field($.pure("FunctionDefinition"), "$", $.field($.lazy(() => statements), "body", $.eps))); +export const FunctionDeclaration: $.Parser<$ast.FunctionDeclaration> = $.loc($.field($.pure("FunctionDeclaration"), "$", $.right(semicolon, $.eps))); +export const Id: $.Parser<$ast.Id> = $.named("identifier", $.loc($.field($.pure("Id"), "$", $.field($.lex($.stry($.right($.lookNeg($.lazy(() => reservedWord)), $.right($.regex("a-zA-Z_", [$.ExpRange("a", "z"), $.ExpRange("A", "Z"), $.ExpString("_")]), $.right($.star($.lazy(() => idPart)), $.eps))))), "name", $.eps)))); +export const IntegerLiteralDec: $.Parser<$ast.IntegerLiteralDec> = $.loc($.field($.pure("IntegerLiteralDec"), "$", $.field($.lex($.lazy(() => underscored($.lazy(() => digit)))), "digits", $.eps))); +export const shuffle: $.Parser<$ast.shuffle> = $.right($.str("("), $.field($.star(Id), "ids", $.field($.opt($.right($.str("->"), $.plus(IntegerLiteralDec))), "to", $.right($.str(")"), $.eps)))); +export const ConstantAttribute: $.Parser<$ast.ConstantAttribute> = $.loc($.field($.pure("ConstantAttribute"), "$", $.field($.alt($.lazy(() => keyword($.str("virtual"))), $.alt($.lazy(() => keyword($.str("override"))), $.lazy(() => keyword($.str("abstract"))))), "name", $.eps))); +export const ConstantDefinition: $.Parser<$ast.ConstantDefinition> = $.loc($.field($.pure("ConstantDefinition"), "$", $.right($.str("="), $.field($.lazy(() => expression), "expression", $.right(semicolon, $.eps))))); +export const ConstantDeclaration: $.Parser<$ast.ConstantDeclaration> = $.loc($.field($.pure("ConstantDeclaration"), "$", $.right(semicolon, $.eps))); +export const inter = (A: $.Parser, B: $.Parser): $.Parser<$ast.inter> => $.field($.lazy(() => A), "head", $.field($.star($.field($.lazy(() => B), "op", $.field($.lazy(() => A), "right", $.eps))), "tail", $.eps)); +export const structFields: $.Parser<$ast.structFields> = $.left($.opt(inter(FieldDecl, $.str(";"))), $.opt($.str(";"))); +export const keyword = (T: $.Parser): $.Parser<$ast.keyword> => $.lex($.left($.lazy(() => T), $.lookNeg($.lazy(() => idPart)))); +export const commaList = (T: $.Parser): $.Parser<$ast.commaList> => $.left(inter($.lazy(() => T), $.str(",")), $.opt($.str(","))); +export const TypeId: $.Parser<$ast.TypeId> = $.named("capitalized identifier", $.loc($.field($.pure("TypeId"), "$", $.field($.lex($.stry($.right($.regex("A-Z", [$.ExpRange("A", "Z")]), $.right($.star($.regex("a-zA-Z0-9_", [$.ExpRange("a", "z"), $.ExpRange("A", "Z"), $.ExpRange("0", "9"), $.ExpString("_")])), $.eps)))), "name", $.eps)))); +export const inheritedTraits: $.Parser<$ast.inheritedTraits> = $.right(keyword($.str("with")), commaList(TypeId)); +export const ContractAttribute: $.Parser<$ast.ContractAttribute> = $.loc($.field($.pure("ContractAttribute"), "$", $.right($.str("@interface"), $.right($.str("("), $.field($.lazy(() => StringLiteral), "name", $.right($.str(")"), $.eps)))))); +export const FunctionAttribute: $.Parser<$ast.FunctionAttribute> = $.loc($.field($.pure("FunctionAttribute"), "$", $.field($.alt($.lazy(() => GetAttribute), $.alt(keyword($.str("mutates")), $.alt(keyword($.str("extends")), $.alt(keyword($.str("virtual")), $.alt(keyword($.str("override")), $.alt(keyword($.str("inline")), keyword($.str("abstract")))))))), "name", $.eps))); +export const GetAttribute: $.Parser<$ast.GetAttribute> = $.loc($.field($.pure("GetAttribute"), "$", $.right($.str("get"), $.field($.opt($.right($.str("("), $.left($.lazy(() => expression), $.str(")")))), "methodId", $.eps)))); +export const ReceiverType: $.Parser<$ast.ReceiverType> = $.loc($.field($.pure("ReceiverType"), "$", $.field($.alt($.str("bounced"), $.alt(keyword($.str("receive")), keyword($.str("external")))), "name", $.eps))); +export const Parameter: $.Parser<$ast.Parameter> = $.loc($.field($.pure("Parameter"), "$", $.field(Id, "name", $.field($.lazy(() => ascription), "type", $.eps)))); +export const StringLiteral: $.Parser<$ast.StringLiteral> = $.loc($.field($.pure("StringLiteral"), "$", $.field($.lex($.right($.str("\""), $.left($.stry($.star($.alt($.regex<"\"" | "\\">("^\"\\\\", $.negateExps([$.ExpString("\""), $.ExpString("\\")])), $.right($.str("\\"), $.lazy(() => escapeChar))))), $.str("\"")))), "value", $.eps))); +export const receiverParam: $.Parser<$ast.receiverParam> = $.opt($.alt(Parameter, StringLiteral)); +export const assembly: $.Parser<$ast.assembly> = $.lex($.stry($.lazy(() => assemblySequence))); +export const multiLineComment: $.Parser<$ast.multiLineComment> = $.right($.str("/*"), $.left($.stry($.star($.right($.lookNeg($.str("*/")), $.right($.any, $.eps)))), $.str("*/"))); +export const singleLineComment: $.Parser<$ast.singleLineComment> = $.right($.str("//"), $.stry($.star($.regex<"\r" | "\n">("^\\r\\n", $.negateExps([$.ExpString("\r"), $.ExpString("\n")]))))); +export const comment: $.Parser<$ast.comment> = $.alt(multiLineComment, singleLineComment); +export const assemblyItem: $.Parser<$ast.assemblyItem> = $.alt($.right($.str("{"), $.right($.lazy(() => assemblySequence), $.right($.str("}"), $.eps))), $.alt(comment, $.alt($.right($.str("\""), $.right($.star($.regex<"\"">("^\"", $.negateExps([$.ExpString("\"")]))), $.right($.str("\""), $.eps))), $.plus($.right($.lookNeg($.alt($.regex<"\"" | "{" | "}">("\"{}", [$.ExpString("\""), $.ExpString("{"), $.ExpString("}")]), $.alt($.str("//"), $.str("/*")))), $.right($.any, $.eps)))))); +export const assemblySequence: $.Parser<$ast.assemblySequence> = $.star(assemblyItem); +export const TypeAs: $.Parser<$ast.TypeAs> = $.loc($.field($.pure("TypeAs"), "$", $.field($.lazy(() => TypeOptional), "type", $.field($.star($.right(keyword($.str("as")), $.lex($.lazy(() => storage)))), "as", $.eps)))); export const $type: $.Parser<$ast.$type> = TypeAs; export const ascription: $.Parser<$ast.ascription> = $.right($.str(":"), $type); -export const TypeOptional: $.Parser<$ast.TypeOptional> = $.loc( - $.field( - $.pure("TypeOptional"), - "$", - $.field( - $.lazy(() => typePrimary), - "type", - $.field($.star($.lazy(() => Optional)), "optionals", $.eps), - ), - ), -); -export const Optional: $.Parser<$ast.Optional> = $.loc( - $.field($.pure("Optional"), "$", $.right($.str("?"), $.eps)), -); -export const TypeGeneric: $.Parser<$ast.TypeGeneric> = $.loc( - $.field( - $.pure("TypeGeneric"), - "$", - $.field( - $.alt( - $.lazy(() => MapKeyword), - $.alt( - $.lazy(() => Bounced), - TypeId, - ), - ), - "name", - $.right( - $.str("<"), - $.field(commaList($type), "args", $.right($.str(">"), $.eps)), - ), - ), - ), -); -export const TypeRegular: $.Parser<$ast.TypeRegular> = $.loc( - $.field($.pure("TypeRegular"), "$", $.field(TypeId, "child", $.eps)), -); -export const TypeTuple: $.Parser<$ast.TypeTuple> = $.loc( - $.field( - $.pure("TypeTuple"), - "$", - $.right( - $.str("["), - $.field( - $.opt(commaList($type)), - "types", - $.right($.str("]"), $.eps), - ), - ), - ), -); -export const TypeTensor: $.Parser<$ast.TypeTensor> = $.loc( - $.field( - $.pure("TypeTensor"), - "$", - $.right( - $.str("("), - $.field( - $type, - "head", - $.field( - $.plus($.right($.str(","), $type)), - "tail", - $.right($.opt($.str(",")), $.right($.str(")"), $.eps)), - ), - ), - ), - ), -); -export const TypeUnit: $.Parser<$ast.TypeUnit> = $.loc( - $.field( - $.pure("TypeUnit"), - "$", - $.right($.right($.str("("), $.right($.str(")"), $.eps)), $.eps), - ), -); -export const typeParens: $.Parser<$ast.typeParens> = $.right( - $.str("("), - $.left($type, $.str(")")), -); -export const typePrimary: $.Parser<$ast.typePrimary> = $.alt( - TypeGeneric, - $.alt( - TypeRegular, - $.alt(TypeTuple, $.alt(TypeTensor, $.alt(TypeUnit, typeParens))), - ), -); -export const MapKeyword: $.Parser<$ast.MapKeyword> = $.loc( - $.field($.pure("MapKeyword"), "$", $.right(keyword($.str("map")), $.eps)), -); -export const Bounced: $.Parser<$ast.Bounced> = $.loc( - $.field($.pure("Bounced"), "$", $.right($.str("bounced"), $.eps)), -); -export const IntStorage: $.Parser<$ast.IntStorage> = $.loc( - $.field( - $.pure("IntStorage"), - "$", - $.field( - $.opt($.str("var")), - "isVar", - $.field( - $.opt($.str("u")), - "isUnsigned", - $.right( - $.str("int"), - $.field( - $.stry($.plus($.lazy(() => digit))), - "width", - $.eps, - ), - ), - ), - ), - ), -); -export const CoinsStorage: $.Parser<$ast.CoinsStorage> = $.loc( - $.field($.pure("CoinsStorage"), "$", $.right($.str("coins"), $.eps)), -); -export const RemainingStorage: $.Parser<$ast.RemainingStorage> = $.loc( - $.field( - $.pure("RemainingStorage"), - "$", - $.right($.str("remaining"), $.eps), - ), -); -export const BytesStorage: $.Parser<$ast.BytesStorage> = $.loc( - $.field( - $.pure("BytesStorage"), - "$", - $.right( - $.str("bytes"), - $.field($.stry($.plus($.lazy(() => digit))), "width", $.eps), - ), - ), -); -export const storage: $.Parser<$ast.storage> = $.alt( - IntStorage, - $.alt(CoinsStorage, $.alt(RemainingStorage, BytesStorage)), -); -export const StatementLet: $.Parser<$ast.StatementLet> = $.loc( - $.field( - $.pure("StatementLet"), - "$", - $.right( - keyword($.str("let")), - $.field( - Id, - "name", - $.field( - $.opt(ascription), - "type", - $.right( - $.str("="), - $.field( - $.lazy(() => expression), - "init", - $.right(semicolon, $.eps), - ), - ), - ), - ), - ), - ), -); -export const StatementDestruct: $.Parser<$ast.StatementDestruct> = $.loc( - $.field( - $.pure("StatementDestruct"), - "$", - $.right( - keyword($.str("let")), - $.field( - TypeId, - "type", - $.right( - $.str("{"), - $.field( - inter( - $.lazy(() => destructItem), - $.str(","), - ), - "fields", - $.field( - $.lazy(() => optionalRest), - "rest", - $.right( - $.str("}"), - $.right( - $.str("="), - $.field( - $.lazy(() => expression), - "init", - $.right(semicolon, $.eps), - ), - ), - ), - ), - ), - ), - ), - ), - ), -); -export const StatementBlock: $.Parser<$ast.StatementBlock> = $.loc( - $.field( - $.pure("StatementBlock"), - "$", - $.field( - $.lazy(() => statements), - "body", - $.eps, - ), - ), -); -export const StatementReturn: $.Parser<$ast.StatementReturn> = $.loc( - $.field( - $.pure("StatementReturn"), - "$", - $.right( - keyword($.str("return")), - $.field( - $.opt($.lazy(() => expression)), - "expression", - $.right(semicolon, $.eps), - ), - ), - ), -); -export const StatementCondition: $.Parser<$ast.StatementCondition> = $.loc( - $.field( - $.pure("StatementCondition"), - "$", - $.right( - keyword($.str("if")), - $.field( - $.lazy(() => expression), - "condition", - $.field( - $.lazy(() => statements), - "trueBranch", - $.field( - $.opt( - $.right( - keyword($.str("else")), - $.alt( - $.lazy(() => FalseBranch), - $.lazy(() => StatementCondition), - ), - ), - ), - "falseBranch", - $.eps, - ), - ), - ), - ), - ), -); -export const StatementWhile: $.Parser<$ast.StatementWhile> = $.loc( - $.field( - $.pure("StatementWhile"), - "$", - $.right( - keyword($.str("while")), - $.field( - $.lazy(() => parens), - "condition", - $.field( - $.lazy(() => statements), - "body", - $.eps, - ), - ), - ), - ), -); -export const StatementRepeat: $.Parser<$ast.StatementRepeat> = $.loc( - $.field( - $.pure("StatementRepeat"), - "$", - $.right( - keyword($.str("repeat")), - $.field( - $.lazy(() => parens), - "condition", - $.field( - $.lazy(() => statements), - "body", - $.eps, - ), - ), - ), - ), -); -export const StatementUntil: $.Parser<$ast.StatementUntil> = $.loc( - $.field( - $.pure("StatementUntil"), - "$", - $.right( - keyword($.str("do")), - $.field( - $.lazy(() => statements), - "body", - $.right( - keyword($.str("until")), - $.field( - $.lazy(() => parens), - "condition", - $.right(semicolon, $.eps), - ), - ), - ), - ), - ), -); -export const StatementTry: $.Parser<$ast.StatementTry> = $.loc( - $.field( - $.pure("StatementTry"), - "$", - $.right( - keyword($.str("try")), - $.field( - $.lazy(() => statements), - "body", - $.field( - $.opt( - $.right( - keyword($.str("catch")), - $.right( - $.str("("), - $.field( - Id, - "name", - $.right( - $.str(")"), - $.field( - $.lazy(() => statements), - "body", - $.eps, - ), - ), - ), - ), - ), - ), - "handler", - $.eps, - ), - ), - ), - ), -); -export const StatementForEach: $.Parser<$ast.StatementForEach> = $.loc( - $.field( - $.pure("StatementForEach"), - "$", - $.right( - keyword($.str("foreach")), - $.right( - $.str("("), - $.field( - Id, - "key", - $.right( - $.str(","), - $.field( - Id, - "value", - $.right( - $.str("in"), - $.field( - $.lazy(() => expression), - "expression", - $.right( - $.str(")"), - $.field( - $.lazy(() => statements), - "body", - $.eps, - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), -); -export const StatementExpression: $.Parser<$ast.StatementExpression> = $.loc( - $.field( - $.pure("StatementExpression"), - "$", - $.field( - $.lazy(() => expression), - "expression", - $.right(semicolon, $.eps), - ), - ), -); -export const StatementAssign: $.Parser<$ast.StatementAssign> = $.loc( - $.field( - $.pure("StatementAssign"), - "$", - $.field( - $.lazy(() => expression), - "left", - $.field( - $.alt( - $.lazy(() => augmentedOp), - $.str("="), - ), - "operator", - $.field( - $.lazy(() => expression), - "right", - $.right(semicolon, $.eps), - ), - ), - ), - ), -); -export const statement: $.Parser<$ast.statement> = $.alt( - StatementLet, - $.alt( - StatementDestruct, - $.alt( - StatementBlock, - $.alt( - StatementReturn, - $.alt( - StatementCondition, - $.alt( - StatementWhile, - $.alt( - StatementRepeat, - $.alt( - StatementUntil, - $.alt( - StatementTry, - $.alt( - StatementForEach, - $.alt( - StatementExpression, - StatementAssign, - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), -); -export const statements: $.Parser<$ast.statements> = $.right( - $.str("{"), - $.left($.star(statement), $.str("}")), -); -export const augmentedOp: $.Parser<$ast.augmentedOp> = $.alt( - $.str("||="), - $.alt( - $.str("&&="), - $.alt( - $.str(">>="), - $.alt( - $.str("<<="), - $.alt( - $.str("-="), - $.alt( - $.str("+="), - $.alt( - $.str("*="), - $.alt( - $.str("/="), - $.alt( - $.str("%="), - $.alt( - $.str("|="), - $.alt($.str("&="), $.str("^=")), - ), - ), - ), - ), - ), - ), - ), - ), - ), -); -export const FalseBranch: $.Parser<$ast.FalseBranch> = $.loc( - $.field($.pure("FalseBranch"), "$", $.field(statements, "body", $.eps)), -); -export const RegularField: $.Parser<$ast.RegularField> = $.loc( - $.field( - $.pure("RegularField"), - "$", - $.field( - Id, - "fieldName", - $.right($.str(":"), $.field(Id, "varName", $.eps)), - ), - ), -); -export const PunnedField: $.Parser<$ast.PunnedField> = $.loc( - $.field($.pure("PunnedField"), "$", $.field(Id, "name", $.eps)), -); -export const destructItem: $.Parser<$ast.destructItem> = $.alt( - RegularField, - PunnedField, -); -export const RestArgument: $.Parser<$ast.RestArgument> = $.loc( - $.field($.pure("RestArgument"), "$", $.right($.str(".."), $.eps)), -); -export const NoRestArgument: $.Parser<$ast.NoRestArgument> = $.loc( - $.field($.pure("NoRestArgument"), "$", $.right($.opt($.str(",")), $.eps)), -); -export const optionalRest: $.Parser<$ast.optionalRest> = $.alt( - $.right($.str(","), RestArgument), - NoRestArgument, -); -export const Conditional: $.Parser<$ast.Conditional> = $.loc( - $.field( - $.pure("Conditional"), - "$", - $.field( - $.lazy(() => or), - "head", - $.field( - $.opt( - $.right( - $.str("?"), - $.field( - $.lazy(() => or), - "thenBranch", - $.right( - $.str(":"), - $.field( - $.lazy(() => Conditional), - "elseBranch", - $.eps, - ), - ), - ), - ), - ), - "tail", - $.eps, - ), - ), - ), -); +export const TypeOptional: $.Parser<$ast.TypeOptional> = $.loc($.field($.pure("TypeOptional"), "$", $.field($.lazy(() => typePrimary), "type", $.field($.star($.lazy(() => Optional)), "optionals", $.eps)))); +export const Optional: $.Parser<$ast.Optional> = $.loc($.field($.pure("Optional"), "$", $.right($.str("?"), $.eps))); +export const TypeGeneric: $.Parser<$ast.TypeGeneric> = $.loc($.field($.pure("TypeGeneric"), "$", $.field($.alt($.lazy(() => MapKeyword), $.alt($.lazy(() => Bounced), TypeId)), "name", $.field($.lazy(() => typeArgs), "args", $.eps)))); +export const TypeRegular: $.Parser<$ast.TypeRegular> = $.loc($.field($.pure("TypeRegular"), "$", $.field(TypeId, "child", $.eps))); +export const TypeTuple: $.Parser<$ast.TypeTuple> = $.loc($.field($.pure("TypeTuple"), "$", $.right($.str("["), $.field($.opt(commaList($type)), "types", $.right($.str("]"), $.eps))))); +export const TypeTensor: $.Parser<$ast.TypeTensor> = $.loc($.field($.pure("TypeTensor"), "$", $.right($.str("("), $.field($type, "head", $.field($.plus($.right($.str(","), $type)), "tail", $.right($.opt($.str(",")), $.right($.str(")"), $.eps))))))); +export const TypeUnit: $.Parser<$ast.TypeUnit> = $.loc($.field($.pure("TypeUnit"), "$", $.right($.right($.str("("), $.right($.str(")"), $.eps)), $.eps))); +export const typeParens: $.Parser<$ast.typeParens> = $.right($.str("("), $.left($type, $.str(")"))); +export const typePrimary: $.Parser<$ast.typePrimary> = $.alt(TypeGeneric, $.alt(TypeRegular, $.alt(TypeTuple, $.alt(TypeTensor, $.alt(TypeUnit, typeParens))))); +export const MapKeyword: $.Parser<$ast.MapKeyword> = $.loc($.field($.pure("MapKeyword"), "$", $.right(keyword($.str("map")), $.eps))); +export const Bounced: $.Parser<$ast.Bounced> = $.loc($.field($.pure("Bounced"), "$", $.right($.str("bounced"), $.eps))); +export const IntStorage: $.Parser<$ast.IntStorage> = $.loc($.field($.pure("IntStorage"), "$", $.field($.opt($.str("var")), "isVar", $.field($.opt($.str("u")), "isUnsigned", $.right($.str("int"), $.field($.stry($.plus($.lazy(() => digit))), "width", $.eps)))))); +export const CoinsStorage: $.Parser<$ast.CoinsStorage> = $.loc($.field($.pure("CoinsStorage"), "$", $.right($.str("coins"), $.eps))); +export const RemainingStorage: $.Parser<$ast.RemainingStorage> = $.loc($.field($.pure("RemainingStorage"), "$", $.right($.str("remaining"), $.eps))); +export const BytesStorage: $.Parser<$ast.BytesStorage> = $.loc($.field($.pure("BytesStorage"), "$", $.right($.str("bytes"), $.field($.stry($.plus($.lazy(() => digit))), "width", $.eps)))); +export const storage: $.Parser<$ast.storage> = $.alt(IntStorage, $.alt(CoinsStorage, $.alt(RemainingStorage, BytesStorage))); +export const generic = (T: $.Parser): $.Parser<$ast.generic> => $.right($.str("<"), $.left($.opt(commaList($.lazy(() => T))), $.str(">"))); +export const typeParams: $.Parser<$ast.typeParams> = generic(TypeId); +export const typeArgs: $.Parser<$ast.typeArgs> = generic($type); +export const StatementLet: $.Parser<$ast.StatementLet> = $.loc($.field($.pure("StatementLet"), "$", $.right(keyword($.str("let")), $.field(Id, "name", $.field($.opt(ascription), "type", $.right($.str("="), $.field($.lazy(() => expression), "init", $.right(semicolon, $.eps)))))))); +export const StatementDestruct: $.Parser<$ast.StatementDestruct> = $.loc($.field($.pure("StatementDestruct"), "$", $.right(keyword($.str("let")), $.field(TypeId, "type", $.right($.str("{"), $.field(inter($.lazy(() => destructItem), $.str(",")), "fields", $.field($.lazy(() => optionalRest), "rest", $.right($.str("}"), $.right($.str("="), $.field($.lazy(() => expression), "init", $.right(semicolon, $.eps))))))))))); +export const StatementBlock: $.Parser<$ast.StatementBlock> = $.loc($.field($.pure("StatementBlock"), "$", $.field($.lazy(() => statements), "body", $.eps))); +export const StatementReturn: $.Parser<$ast.StatementReturn> = $.loc($.field($.pure("StatementReturn"), "$", $.right(keyword($.str("return")), $.field($.opt($.lazy(() => expression)), "expression", $.right(semicolon, $.eps))))); +export const StatementCondition: $.Parser<$ast.StatementCondition> = $.loc($.field($.pure("StatementCondition"), "$", $.right(keyword($.str("if")), $.field($.lazy(() => expression), "condition", $.field($.lazy(() => statements), "trueBranch", $.field($.opt($.right(keyword($.str("else")), $.alt($.lazy(() => FalseBranch), $.lazy(() => StatementCondition)))), "falseBranch", $.eps)))))); +export const StatementWhile: $.Parser<$ast.StatementWhile> = $.loc($.field($.pure("StatementWhile"), "$", $.right(keyword($.str("while")), $.field($.lazy(() => parens), "condition", $.field($.lazy(() => statements), "body", $.eps))))); +export const StatementRepeat: $.Parser<$ast.StatementRepeat> = $.loc($.field($.pure("StatementRepeat"), "$", $.right(keyword($.str("repeat")), $.field($.lazy(() => parens), "condition", $.field($.lazy(() => statements), "body", $.eps))))); +export const StatementUntil: $.Parser<$ast.StatementUntil> = $.loc($.field($.pure("StatementUntil"), "$", $.right(keyword($.str("do")), $.field($.lazy(() => statements), "body", $.right(keyword($.str("until")), $.field($.lazy(() => parens), "condition", $.right(semicolon, $.eps))))))); +export const StatementTry: $.Parser<$ast.StatementTry> = $.loc($.field($.pure("StatementTry"), "$", $.right(keyword($.str("try")), $.field($.lazy(() => statements), "body", $.field($.opt($.right(keyword($.str("catch")), $.right($.str("("), $.field(Id, "name", $.right($.str(")"), $.field($.lazy(() => statements), "body", $.eps)))))), "handler", $.eps))))); +export const StatementForEach: $.Parser<$ast.StatementForEach> = $.loc($.field($.pure("StatementForEach"), "$", $.right(keyword($.str("foreach")), $.right($.str("("), $.field(Id, "key", $.right($.str(","), $.field(Id, "value", $.right($.str("in"), $.field($.lazy(() => expression), "expression", $.right($.str(")"), $.field($.lazy(() => statements), "body", $.eps))))))))))); +export const StatementExpression: $.Parser<$ast.StatementExpression> = $.loc($.field($.pure("StatementExpression"), "$", $.field($.lazy(() => expression), "expression", $.right(semicolon, $.eps)))); +export const StatementAssign: $.Parser<$ast.StatementAssign> = $.loc($.field($.pure("StatementAssign"), "$", $.field($.lazy(() => expression), "left", $.field($.alt($.lazy(() => augmentedOp), $.str("=")), "operator", $.field($.lazy(() => expression), "right", $.right(semicolon, $.eps)))))); +export const statement: $.Parser<$ast.statement> = $.alt(StatementLet, $.alt(StatementDestruct, $.alt(StatementBlock, $.alt(StatementReturn, $.alt(StatementCondition, $.alt(StatementWhile, $.alt(StatementRepeat, $.alt(StatementUntil, $.alt(StatementTry, $.alt(StatementForEach, $.alt(StatementExpression, StatementAssign))))))))))); +export const statements: $.Parser<$ast.statements> = $.right($.str("{"), $.left($.star(statement), $.str("}"))); +export const augmentedOp: $.Parser<$ast.augmentedOp> = $.alt($.str("||="), $.alt($.str("&&="), $.alt($.str(">>="), $.alt($.str("<<="), $.alt($.str("-="), $.alt($.str("+="), $.alt($.str("*="), $.alt($.str("/="), $.alt($.str("%="), $.alt($.str("|="), $.alt($.str("&="), $.str("^=")))))))))))); +export const FalseBranch: $.Parser<$ast.FalseBranch> = $.loc($.field($.pure("FalseBranch"), "$", $.field(statements, "body", $.eps))); +export const RegularField: $.Parser<$ast.RegularField> = $.loc($.field($.pure("RegularField"), "$", $.field(Id, "fieldName", $.right($.str(":"), $.field(Id, "varName", $.eps))))); +export const PunnedField: $.Parser<$ast.PunnedField> = $.loc($.field($.pure("PunnedField"), "$", $.field(Id, "name", $.eps))); +export const destructItem: $.Parser<$ast.destructItem> = $.alt(RegularField, PunnedField); +export const RestArgument: $.Parser<$ast.RestArgument> = $.loc($.field($.pure("RestArgument"), "$", $.right($.str(".."), $.eps))); +export const NoRestArgument: $.Parser<$ast.NoRestArgument> = $.loc($.field($.pure("NoRestArgument"), "$", $.right($.opt($.str(",")), $.eps))); +export const optionalRest: $.Parser<$ast.optionalRest> = $.alt($.right($.str(","), RestArgument), NoRestArgument); +export const Conditional: $.Parser<$ast.Conditional> = $.loc($.field($.pure("Conditional"), "$", $.field($.lazy(() => or), "head", $.field($.opt($.right($.str("?"), $.field($.lazy(() => or), "thenBranch", $.right($.str(":"), $.field($.lazy(() => Conditional), "elseBranch", $.eps))))), "tail", $.eps)))); export const expression: $.Parser<$ast.expression> = Conditional; -export const Binary = ( - T: $.Parser, - U: $.Parser, -): $.Parser<$ast.Binary> => - $.loc( - $.field( - $.pure("Binary"), - "$", - $.field( - inter( - $.lazy(() => T), - $.lazy(() => Operator($.lazy(() => U))), - ), - "exprs", - $.eps, - ), - ), - ); -export const Unary: $.Parser<$ast.Unary> = $.loc( - $.field( - $.pure("Unary"), - "$", - $.field( - $.star( - $.lazy(() => - Operator( - $.regex<"-" | "+" | "!" | "~">("-+!~", [ - $.ExpString("-"), - $.ExpString("+"), - $.ExpString("!"), - $.ExpString("~"), - ]), - ), - ), - ), - "prefixes", - $.field( - $.lazy(() => Suffix), - "expression", - $.eps, - ), - ), - ), -); -export const mul: $.Parser<$ast.mul> = Binary( - Unary, - $.regex<"*" | "/" | "%">("*/%", [ - $.ExpString("*"), - $.ExpString("/"), - $.ExpString("%"), - ]), -); -export const add: $.Parser<$ast.add> = Binary( - mul, - $.alt($.str("+"), $.str("-")), -); -export const bitwiseShift: $.Parser<$ast.bitwiseShift> = Binary( - add, - $.alt($.str("<<"), $.str(">>")), -); -export const compare: $.Parser<$ast.compare> = Binary( - bitwiseShift, - $.alt($.str("<="), $.alt($.str("<"), $.alt($.str(">="), $.str(">")))), -); -export const equality: $.Parser<$ast.equality> = Binary( - compare, - $.alt($.str("!="), $.str("==")), -); -export const bitwiseAnd: $.Parser<$ast.bitwiseAnd> = Binary( - equality, - $.str("&"), -); -export const bitwiseXor: $.Parser<$ast.bitwiseXor> = Binary( - bitwiseAnd, - $.str("^"), -); -export const bitwiseOr: $.Parser<$ast.bitwiseOr> = Binary( - bitwiseXor, - $.str("|"), -); +export const Binary = (T: $.Parser, U: $.Parser): $.Parser<$ast.Binary> => $.loc($.field($.pure("Binary"), "$", $.field(inter($.lazy(() => T), $.lazy(() => Operator($.lazy(() => U)))), "exprs", $.eps))); +export const Unary: $.Parser<$ast.Unary> = $.loc($.field($.pure("Unary"), "$", $.field($.star($.lazy(() => Operator($.regex<"-" | "+" | "!" | "~">("-+!~", [$.ExpString("-"), $.ExpString("+"), $.ExpString("!"), $.ExpString("~")])))), "prefixes", $.field($.lazy(() => Suffix), "expression", $.eps)))); +export const mul: $.Parser<$ast.mul> = Binary(Unary, $.regex<"*" | "/" | "%">("*/%", [$.ExpString("*"), $.ExpString("/"), $.ExpString("%")])); +export const add: $.Parser<$ast.add> = Binary(mul, $.alt($.str("+"), $.str("-"))); +export const bitwiseShift: $.Parser<$ast.bitwiseShift> = Binary(add, $.alt($.str("<<"), $.str(">>"))); +export const compare: $.Parser<$ast.compare> = Binary(bitwiseShift, $.alt($.str("<="), $.alt($.str("<"), $.alt($.str(">="), $.str(">"))))); +export const equality: $.Parser<$ast.equality> = Binary(compare, $.alt($.str("!="), $.str("=="))); +export const bitwiseAnd: $.Parser<$ast.bitwiseAnd> = Binary(equality, $.str("&")); +export const bitwiseXor: $.Parser<$ast.bitwiseXor> = Binary(bitwiseAnd, $.str("^")); +export const bitwiseOr: $.Parser<$ast.bitwiseOr> = Binary(bitwiseXor, $.str("|")); export const and: $.Parser<$ast.and> = Binary(bitwiseOr, $.str("&&")); export const or: $.Parser<$ast.or> = Binary(and, $.str("||")); -export const Suffix: $.Parser<$ast.Suffix> = $.loc( - $.field( - $.pure("Suffix"), - "$", - $.field( - $.lazy(() => primary), - "expression", - $.field($.star($.lazy(() => suffix)), "suffixes", $.eps), - ), - ), -); -export const Operator = (U: $.Parser): $.Parser<$ast.Operator> => - $.loc( - $.field( - $.pure("Operator"), - "$", - $.field( - $.lazy(() => U), - "name", - $.eps, - ), - ), - ); -export const SuffixUnboxNotNull: $.Parser<$ast.SuffixUnboxNotNull> = $.loc( - $.field($.pure("SuffixUnboxNotNull"), "$", $.right($.str("!!"), $.eps)), -); -export const SuffixCall: $.Parser<$ast.SuffixCall> = $.loc( - $.field( - $.pure("SuffixCall"), - "$", - $.field( - $.lazy(() => parameterList(expression)), - "params", - $.eps, - ), - ), -); -export const SuffixFieldAccess: $.Parser<$ast.SuffixFieldAccess> = $.loc( - $.field( - $.pure("SuffixFieldAccess"), - "$", - $.right($.str("."), $.field(Id, "name", $.eps)), - ), -); -export const suffix: $.Parser<$ast.suffix> = $.alt( - SuffixUnboxNotNull, - $.alt(SuffixCall, SuffixFieldAccess), -); -export const Parens: $.Parser<$ast.Parens> = $.loc( - $.field( - $.pure("Parens"), - "$", - $.field( - $.lazy(() => parens), - "child", - $.eps, - ), - ), -); -export const StructInstance: $.Parser<$ast.StructInstance> = $.loc( - $.field( - $.pure("StructInstance"), - "$", - $.field( - TypeId, - "type", - $.right( - $.str("{"), - $.field( - $.opt(commaList($.lazy(() => StructFieldInitializer))), - "fields", - $.right($.str("}"), $.eps), - ), - ), - ), - ), -); -export const IntegerLiteral: $.Parser<$ast.IntegerLiteral> = $.loc( - $.field( - $.pure("IntegerLiteral"), - "$", - $.field( - $.alt( - $.lazy(() => IntegerLiteralHex), - $.alt( - $.lazy(() => IntegerLiteralBin), - $.alt( - $.lazy(() => IntegerLiteralOct), - IntegerLiteralDec, - ), - ), - ), - "value", - $.eps, - ), - ), -); -export const BoolLiteral: $.Parser<$ast.BoolLiteral> = $.loc( - $.field( - $.pure("BoolLiteral"), - "$", - $.field( - $.alt($.str("true"), $.str("false")), - "value", - $.right($.lookNeg($.lazy(() => idPart)), $.eps), - ), - ), -); -export const InitOf: $.Parser<$ast.InitOf> = $.loc( - $.field( - $.pure("InitOf"), - "$", - $.right( - keyword($.str("initOf")), - $.field( - TypeId, - "name", - $.field( - $.lazy(() => parameterList(expression)), - "params", - $.eps, - ), - ), - ), - ), -); -export const CodeOf: $.Parser<$ast.CodeOf> = $.loc( - $.field( - $.pure("CodeOf"), - "$", - $.right($.str("codeOf"), $.field(TypeId, "name", $.eps)), - ), -); -export const Null: $.Parser<$ast.Null> = $.loc( - $.field($.pure("Null"), "$", $.right(keyword($.str("null")), $.eps)), -); -export const primary: $.Parser<$ast.primary> = $.alt( - Parens, - $.alt( - StructInstance, - $.alt( - IntegerLiteral, - $.alt( - BoolLiteral, - $.alt( - InitOf, - $.alt(CodeOf, $.alt(Null, $.alt(StringLiteral, Id))), - ), - ), - ), - ), -); -export const parens: $.Parser<$ast.parens> = $.right( - $.str("("), - $.left(expression, $.str(")")), -); -export const StructFieldInitializer: $.Parser<$ast.StructFieldInitializer> = - $.loc( - $.field( - $.pure("StructFieldInitializer"), - "$", - $.field( - Id, - "name", - $.field($.opt($.right($.str(":"), expression)), "init", $.eps), - ), - ), - ); -export const ParameterList = ( - T: $.Parser, -): $.Parser<$ast.ParameterList> => - $.loc( - $.field( - $.pure("ParameterList"), - "$", - $.right( - $.str("("), - $.field( - $.opt(commaList($.lazy(() => T))), - "values", - $.right($.str(")"), $.eps), - ), - ), - ), - ); -export const parameterList = ( - T: $.Parser, -): $.Parser<$ast.parameterList> => - $.right($.str("("), $.left($.opt(commaList($.lazy(() => T))), $.str(")"))); -export const IntegerLiteralHex: $.Parser<$ast.IntegerLiteralHex> = $.loc( - $.field( - $.pure("IntegerLiteralHex"), - "$", - $.field( - $.lex( - $.right( - $.str("0"), - $.right( - $.regex<"x" | "X">("xX", [ - $.ExpString("x"), - $.ExpString("X"), - ]), - $.lazy(() => underscored($.lazy(() => hexDigit))), - ), - ), - ), - "digits", - $.eps, - ), - ), -); -export const IntegerLiteralBin: $.Parser<$ast.IntegerLiteralBin> = $.loc( - $.field( - $.pure("IntegerLiteralBin"), - "$", - $.field( - $.lex( - $.right( - $.str("0"), - $.right( - $.regex<"b" | "B">("bB", [ - $.ExpString("b"), - $.ExpString("B"), - ]), - $.lazy(() => - underscored( - $.regex<"0" | "1">("01", [ - $.ExpString("0"), - $.ExpString("1"), - ]), - ), - ), - ), - ), - ), - "digits", - $.eps, - ), - ), -); -export const IntegerLiteralOct: $.Parser<$ast.IntegerLiteralOct> = $.loc( - $.field( - $.pure("IntegerLiteralOct"), - "$", - $.field( - $.lex( - $.right( - $.str("0"), - $.right( - $.regex<"o" | "O">("oO", [ - $.ExpString("o"), - $.ExpString("O"), - ]), - $.lazy(() => - underscored( - $.regex("0-7", [$.ExpRange("0", "7")]), - ), - ), - ), - ), - ), - "digits", - $.eps, - ), - ), -); -export const underscored = (T: $.Parser): $.Parser<$ast.underscored> => - $.stry( - $.right( - $.lazy(() => T), - $.right( - $.star( - $.right( - $.opt($.str("_")), - $.right( - $.lazy(() => T), - $.eps, - ), - ), - ), - $.eps, - ), - ), - ); -export const digit: $.Parser<$ast.digit> = $.named( - "digit", - $.regex("0-9", [$.ExpRange("0", "9")]), -); -export const idPart: $.Parser<$ast.idPart> = $.named( - "identifier character", - $.regex("a-zA-Z0-9_", [ - $.ExpRange("a", "z"), - $.ExpRange("A", "Z"), - $.ExpRange("0", "9"), - $.ExpString("_"), - ]), -); -export const FuncId: $.Parser<$ast.FuncId> = $.named( - "FunC identifier", - $.loc( - $.field( - $.pure("FuncId"), - "$", - $.field( - $.opt( - $.regex<"." | "~">(".~", [ - $.ExpString("."), - $.ExpString("~"), - ]), - ), - "accessor", - $.field( - $.stry( - $.alt( - $.right( - $.str("`"), - $.right( - $.plus( - $.regex<"`" | "\r" | "\n">( - "^`\\r\\n", - $.negateExps([ - $.ExpString("`"), - $.ExpString("\r"), - $.ExpString("\n"), - ]), - ), - ), - $.right($.str("`"), $.eps), - ), - ), - $.plus( - $.regex< - | " " - | "\t" - | "\r" - | "\n" - | "(" - | ")" - | "[" - | string - | "," - | "." - | ";" - | "~" - >( - "^ \\t\\r\\n()[\\],.;~", - $.negateExps([ - $.ExpString(" "), - $.ExpString("\t"), - $.ExpString("\r"), - $.ExpString("\n"), - $.ExpString("("), - $.ExpString(")"), - $.ExpString("["), - $.ExpString('"\\]"'), - $.ExpString(","), - $.ExpString("."), - $.ExpString(";"), - $.ExpString("~"), - ]), - ), - ), - ), - ), - "id", - $.eps, - ), - ), - ), - ), -); -export const hexDigit: $.Parser<$ast.hexDigit> = $.named( - "hexadecimal digit", - $.regex("0-9a-fA-F", [ - $.ExpRange("0", "9"), - $.ExpRange("a", "f"), - $.ExpRange("A", "F"), - ]), -); -export const escapeChar: $.Parser<$ast.escapeChar> = $.alt( - $.regex<"\\" | '"' | "n" | "r" | "t" | "v" | "b" | "f">('\\\\"nrtvbf', [ - $.ExpString("\\"), - $.ExpString('"'), - $.ExpString("n"), - $.ExpString("r"), - $.ExpString("t"), - $.ExpString("v"), - $.ExpString("b"), - $.ExpString("f"), - ]), - $.alt( - $.right( - $.str("u{"), - $.left( - $.stry( - $.right( - hexDigit, - $.right( - $.opt(hexDigit), - $.right( - $.opt(hexDigit), - $.right( - $.opt(hexDigit), - $.right( - $.opt(hexDigit), - $.right($.opt(hexDigit), $.eps), - ), - ), - ), - ), - ), - ), - $.str("}"), - ), - ), - $.alt( - $.right( - $.str("u"), - $.stry( - $.right( - hexDigit, - $.right( - hexDigit, - $.right(hexDigit, $.right(hexDigit, $.eps)), - ), - ), - ), - ), - $.right( - $.str("x"), - $.stry($.right(hexDigit, $.right(hexDigit, $.eps))), - ), - ), - ), -); -export const reservedWord: $.Parser<$ast.reservedWord> = $.named( - "reserved word", - keyword( - $.alt( - $.str("extend"), - $.alt( - $.str("public"), - $.alt( - $.str("fun"), - $.alt( - $.str("let"), - $.alt( - $.str("return"), - $.alt( - $.str("receive"), - $.alt( - $.str("native"), - $.alt( - $.str("primitive"), - $.alt( - $.str("null"), - $.alt( - $.str("if"), - $.alt( - $.str("else"), - $.alt( - $.str("while"), - $.alt( - $.str("repeat"), - $.alt( - $.str("do"), - $.alt( - $.str( - "until", - ), - $.alt( - $.str( - "try", - ), - $.alt( - $.str( - "catch", - ), - $.alt( - $.str( - "foreach", - ), - $.alt( - $.str( - "as", - ), - $.alt( - $.str( - "map", - ), - $.alt( - $.str( - "mutates", - ), - $.alt( - $.str( - "extends", - ), - $.alt( - $.str( - "external", - ), - $.alt( - $.str( - "import", - ), - $.alt( - $.str( - "with", - ), - $.alt( - $.str( - "trait", - ), - $.alt( - $.str( - "initOf", - ), - $.alt( - $.str( - "override", - ), - $.alt( - $.str( - "abstract", - ), - $.alt( - $.str( - "virtual", - ), - $.alt( - $.str( - "inline", - ), - $.str( - "const", - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), -); -export const space: $.Parser<$ast.space> = $.named( - "space", - $.alt( - $.regex<" " | "\t" | "\r" | "\n">(" \\t\\r\\n", [ - $.ExpString(" "), - $.ExpString("\t"), - $.ExpString("\r"), - $.ExpString("\n"), - ]), - comment, - ), -); -export const JustImports: $.Parser<$ast.JustImports> = $.loc( - $.field( - $.pure("JustImports"), - "$", - $.field($.star(Import), "imports", $.right($.star($.any), $.eps)), - ), -); +export const Suffix: $.Parser<$ast.Suffix> = $.loc($.field($.pure("Suffix"), "$", $.field($.lazy(() => primary), "expression", $.field($.star($.lazy(() => suffix)), "suffixes", $.eps)))); +export const Operator = (U: $.Parser): $.Parser<$ast.Operator> => $.loc($.field($.pure("Operator"), "$", $.field($.lazy(() => U), "name", $.eps))); +export const SuffixUnboxNotNull: $.Parser<$ast.SuffixUnboxNotNull> = $.loc($.field($.pure("SuffixUnboxNotNull"), "$", $.right($.str("!!"), $.eps))); +export const SuffixCall: $.Parser<$ast.SuffixCall> = $.loc($.field($.pure("SuffixCall"), "$", $.field($.opt(typeArgs), "typeArgs", $.field($.lazy(() => parameterList(expression)), "params", $.eps)))); +export const SuffixFieldAccess: $.Parser<$ast.SuffixFieldAccess> = $.loc($.field($.pure("SuffixFieldAccess"), "$", $.right($.str("."), $.field(Id, "name", $.eps)))); +export const suffix: $.Parser<$ast.suffix> = $.alt(SuffixUnboxNotNull, $.alt(SuffixCall, SuffixFieldAccess)); +export const Unit: $.Parser<$ast.Unit> = $.loc($.field($.pure("Unit"), "$", $.right($.right($.str("("), $.right($.str(")"), $.eps)), $.eps))); +export const Tensor: $.Parser<$ast.Tensor> = $.loc($.field($.pure("Tensor"), "$", $.right($.str("("), $.field(expression, "head", $.field($.plus($.right($.str(","), expression)), "tail", $.right($.opt($.str(",")), $.right($.str(")"), $.eps))))))); +export const Tuple: $.Parser<$ast.Tuple> = $.loc($.field($.pure("Tuple"), "$", $.right($.str("["), $.field($.opt(commaList(expression)), "types", $.right($.str("]"), $.eps))))); +export const Parens: $.Parser<$ast.Parens> = $.loc($.field($.pure("Parens"), "$", $.field($.lazy(() => parens), "child", $.eps))); +export const StructInstance: $.Parser<$ast.StructInstance> = $.loc($.field($.pure("StructInstance"), "$", $.field(TypeId, "type", $.field($.opt(typeArgs), "typeArgs", $.right($.str("{"), $.field($.opt(commaList($.lazy(() => StructFieldInitializer))), "fields", $.right($.str("}"), $.eps))))))); +export const IntegerLiteral: $.Parser<$ast.IntegerLiteral> = $.loc($.field($.pure("IntegerLiteral"), "$", $.field($.alt($.lazy(() => IntegerLiteralHex), $.alt($.lazy(() => IntegerLiteralBin), $.alt($.lazy(() => IntegerLiteralOct), IntegerLiteralDec))), "value", $.eps))); +export const BoolLiteral: $.Parser<$ast.BoolLiteral> = $.loc($.field($.pure("BoolLiteral"), "$", $.field($.alt($.str("true"), $.str("false")), "value", $.right($.lookNeg($.lazy(() => idPart)), $.eps)))); +export const InitOf: $.Parser<$ast.InitOf> = $.loc($.field($.pure("InitOf"), "$", $.right(keyword($.str("initOf")), $.field(TypeId, "name", $.field($.lazy(() => parameterList(expression)), "params", $.eps))))); +export const CodeOf: $.Parser<$ast.CodeOf> = $.loc($.field($.pure("CodeOf"), "$", $.right($.str("codeOf"), $.field(TypeId, "name", $.eps)))); +export const Null: $.Parser<$ast.Null> = $.loc($.field($.pure("Null"), "$", $.right(keyword($.str("null")), $.eps))); +export const primary: $.Parser<$ast.primary> = $.alt(Unit, $.alt(Tensor, $.alt(Tuple, $.alt(Parens, $.alt(StructInstance, $.alt(IntegerLiteral, $.alt(BoolLiteral, $.alt(InitOf, $.alt(CodeOf, $.alt(Null, $.alt(StringLiteral, Id))))))))))); +export const parens: $.Parser<$ast.parens> = $.right($.str("("), $.left(expression, $.str(")"))); +export const StructFieldInitializer: $.Parser<$ast.StructFieldInitializer> = $.loc($.field($.pure("StructFieldInitializer"), "$", $.field(Id, "name", $.field($.opt($.right($.str(":"), expression)), "init", $.eps)))); +export const ParameterList = (T: $.Parser): $.Parser<$ast.ParameterList> => $.loc($.field($.pure("ParameterList"), "$", $.right($.str("("), $.field($.opt(commaList($.lazy(() => T))), "values", $.right($.str(")"), $.eps))))); +export const parameterList = (T: $.Parser): $.Parser<$ast.parameterList> => $.right($.str("("), $.left($.opt(commaList($.lazy(() => T))), $.str(")"))); +export const IntegerLiteralHex: $.Parser<$ast.IntegerLiteralHex> = $.loc($.field($.pure("IntegerLiteralHex"), "$", $.field($.lex($.right($.str("0"), $.right($.regex<"x" | "X">("xX", [$.ExpString("x"), $.ExpString("X")]), $.lazy(() => underscored($.lazy(() => hexDigit)))))), "digits", $.eps))); +export const IntegerLiteralBin: $.Parser<$ast.IntegerLiteralBin> = $.loc($.field($.pure("IntegerLiteralBin"), "$", $.field($.lex($.right($.str("0"), $.right($.regex<"b" | "B">("bB", [$.ExpString("b"), $.ExpString("B")]), $.lazy(() => underscored($.regex<"0" | "1">("01", [$.ExpString("0"), $.ExpString("1")])))))), "digits", $.eps))); +export const IntegerLiteralOct: $.Parser<$ast.IntegerLiteralOct> = $.loc($.field($.pure("IntegerLiteralOct"), "$", $.field($.lex($.right($.str("0"), $.right($.regex<"o" | "O">("oO", [$.ExpString("o"), $.ExpString("O")]), $.lazy(() => underscored($.regex("0-7", [$.ExpRange("0", "7")])))))), "digits", $.eps))); +export const underscored = (T: $.Parser): $.Parser<$ast.underscored> => $.stry($.right($.lazy(() => T), $.right($.star($.right($.opt($.str("_")), $.right($.lazy(() => T), $.eps))), $.eps))); +export const digit: $.Parser<$ast.digit> = $.named("digit", $.regex("0-9", [$.ExpRange("0", "9")])); +export const idPart: $.Parser<$ast.idPart> = $.named("identifier character", $.regex("a-zA-Z0-9_", [$.ExpRange("a", "z"), $.ExpRange("A", "Z"), $.ExpRange("0", "9"), $.ExpString("_")])); +export const FuncId: $.Parser<$ast.FuncId> = $.named("FunC identifier", $.loc($.field($.pure("FuncId"), "$", $.field($.opt($.regex<"." | "~">(".~", [$.ExpString("."), $.ExpString("~")])), "accessor", $.field($.stry($.alt($.right($.str("`"), $.right($.plus($.regex<"`" | "\r" | "\n">("^`\\r\\n", $.negateExps([$.ExpString("`"), $.ExpString("\r"), $.ExpString("\n")]))), $.right($.str("`"), $.eps))), $.plus($.regex<" " | "\t" | "\r" | "\n" | "(" | ")" | "[" | string | "," | "." | ";" | "~">("^ \\t\\r\\n()[\\],.;~", $.negateExps([$.ExpString(" "), $.ExpString("\t"), $.ExpString("\r"), $.ExpString("\n"), $.ExpString("("), $.ExpString(")"), $.ExpString("["), $.ExpString("\"\\]\""), $.ExpString(","), $.ExpString("."), $.ExpString(";"), $.ExpString("~")]))))), "id", $.eps))))); +export const hexDigit: $.Parser<$ast.hexDigit> = $.named("hexadecimal digit", $.regex("0-9a-fA-F", [$.ExpRange("0", "9"), $.ExpRange("a", "f"), $.ExpRange("A", "F")])); +export const escapeChar: $.Parser<$ast.escapeChar> = $.alt($.regex<"\\" | "\"" | "n" | "r" | "t" | "v" | "b" | "f">("\\\\\"nrtvbf", [$.ExpString("\\"), $.ExpString("\""), $.ExpString("n"), $.ExpString("r"), $.ExpString("t"), $.ExpString("v"), $.ExpString("b"), $.ExpString("f")]), $.alt($.right($.str("u{"), $.left($.stry($.right(hexDigit, $.right($.opt(hexDigit), $.right($.opt(hexDigit), $.right($.opt(hexDigit), $.right($.opt(hexDigit), $.right($.opt(hexDigit), $.eps))))))), $.str("}"))), $.alt($.right($.str("u"), $.stry($.right(hexDigit, $.right(hexDigit, $.right(hexDigit, $.right(hexDigit, $.eps)))))), $.right($.str("x"), $.stry($.right(hexDigit, $.right(hexDigit, $.eps))))))); +export const reservedWord: $.Parser<$ast.reservedWord> = $.named("reserved word", keyword($.alt($.str("extend"), $.alt($.str("public"), $.alt($.str("fun"), $.alt($.str("let"), $.alt($.str("return"), $.alt($.str("receive"), $.alt($.str("native"), $.alt($.str("primitive"), $.alt($.str("null"), $.alt($.str("if"), $.alt($.str("else"), $.alt($.str("while"), $.alt($.str("repeat"), $.alt($.str("do"), $.alt($.str("until"), $.alt($.str("try"), $.alt($.str("catch"), $.alt($.str("foreach"), $.alt($.str("as"), $.alt($.str("map"), $.alt($.str("mutates"), $.alt($.str("extends"), $.alt($.str("external"), $.alt($.str("import"), $.alt($.str("with"), $.alt($.str("trait"), $.alt($.str("initOf"), $.alt($.str("override"), $.alt($.str("abstract"), $.alt($.str("virtual"), $.alt($.str("inline"), $.str("const")))))))))))))))))))))))))))))))))); +export const space: $.Parser<$ast.space> = $.named("space", $.alt($.regex<" " | "\t" | "\r" | "\n">(" \\t\\r\\n", [$.ExpString(" "), $.ExpString("\t"), $.ExpString("\r"), $.ExpString("\n")]), comment)); +export const JustImports: $.Parser<$ast.JustImports> = $.loc($.field($.pure("JustImports"), "$", $.field($.star(Import), "imports", $.right($.star($.any), $.eps)))); \ No newline at end of file diff --git a/src/next/grammar/index.ts b/src/next/grammar/index.ts index c73c3479bf..5c2c99aa5a 100644 --- a/src/next/grammar/index.ts +++ b/src/next/grammar/index.ts @@ -327,10 +327,11 @@ const parseStructFieldInitializer = }; const parseStructInstance = - ({ type, fields, loc }: $ast.StructInstance): Handler => + ({ type, typeArgs, fields, loc }: $ast.StructInstance): Handler => (ctx) => { return Ast.StructInstance( parseTypeId(type)(ctx), + map(parseList(typeArgs), parseType)(ctx), map(parseList(fields), parseStructFieldInitializer)(ctx), toRange(loc), ); @@ -423,21 +424,33 @@ const parseSuffixUnboxNotNull = }; const parseSuffixCall = - ({ params }: $ast.SuffixCall): SuffixHandler => + ({ params, typeArgs }: $ast.SuffixCall): SuffixHandler => (ctx) => (child, loc) => { const paramsAst = map(parseList(params), parseExpression)(ctx); if (child.kind === "var") { return Ast.StaticCall( Ast.Id(child.name, child.loc), + map(parseList(typeArgs), parseType)(ctx), paramsAst, loc, ); } else if (child.kind === "field_access") { - return Ast.MethodCall(child.aggregate, child.field, paramsAst, loc); + return Ast.MethodCall( + child.aggregate, + child.field, + map(parseList(typeArgs), parseType)(ctx), + paramsAst, + loc, + ); } else { ctx.err.notCallable()(loc); - return Ast.StaticCall(Ast.Id("__invalid__", loc), paramsAst, loc); + return Ast.StaticCall( + Ast.Id("__invalid__", loc), + map(parseList(typeArgs), parseType)(ctx), + paramsAst, + loc, + ); } }; @@ -473,6 +486,18 @@ const parseSuffix = ).child; }; +const parseUnit = ({ loc }: $ast.Unit): Handler => _ctx => { + return Ast.Unit(toRange(loc)); +}; + +const parseTensor = ({ head, tail, loc }: $ast.Tensor): Handler => ctx => { + return Ast.Tensor(map([head, ...tail], parseExpression)(ctx), toRange(loc)); +}; + +const parseTuple = ({ types, loc }: $ast.Tuple): Handler => ctx => { + return Ast.Tuple(map(parseList(types), parseExpression)(ctx), toRange(loc)); +}; + const parseParens = ({ child }: $ast.Parens): Handler => { return parseExpression(child); }; @@ -494,7 +519,10 @@ type Expression = | $ast.CodeOf | $ast.Null | $ast.StringLiteral - | $ast.Id; + | $ast.Id + | $ast.Unit + | $ast.Tensor + | $ast.Tuple; const parseExpression: (input: Expression) => Handler = makeVisitor()({ @@ -511,6 +539,9 @@ const parseExpression: (input: Expression) => Handler = Null: parseNull, StringLiteral: parseStringLiteral, Id: parseVar, + Unit: parseUnit, + Tensor: parseTensor, + Tuple: parseTuple, }); const parseStatementLet = @@ -1217,6 +1248,7 @@ const parseAsmFunction = parseAsmShuffle(node.shuffle)(ctx), parseFunctionAttributes(node.attributes, false, node.loc)(ctx), parseId(node.name)(ctx), + map(parseList(node.typeParams), parseTypeId)(ctx), node.returnType ? parseType(node.returnType)(ctx) : undefined, map(parseList(node.parameters), parseParameter)(ctx), [node.instructions.trim()], @@ -1267,7 +1299,7 @@ const parseConstant = ): Handler => (ctx) => { const name = parseId(node.name)(ctx); - const type = parseType(node.type)(ctx); + const type = node.type ? parseType(node.type)(ctx) : undefined; if (node.body.$ === "ConstantDeclaration") { const attributes = parseConstantAttributes( @@ -1276,7 +1308,17 @@ const parseConstant = node.loc, noAttributes, )(ctx); - return Ast.ConstantDecl(attributes, name, type, toRange(node.loc)); + const range = toRange(node.loc); + if (!type) { + ctx.err.constDeclNoType()(range); + return Ast.ConstantDecl( + attributes, + name, + Ast.TypeCons(Ast.TypeId("ERROR", range), [], range), + range, + ); + } + return Ast.ConstantDecl(attributes, name, type, range); } else { const attributes = parseConstantAttributes( node.attributes, @@ -1353,6 +1395,7 @@ const parseFunction = const returnType = node.returnType ? parseType(node.returnType)(ctx) : undefined; + const typeParams = map(parseList(node.typeParams), parseTypeId)(ctx); const parameters = map(parseList(node.parameters), parseParameter)(ctx); if (node.body.$ === "FunctionDeclaration") { @@ -1364,6 +1407,7 @@ const parseFunction = return Ast.FunctionDecl( attributes, name, + typeParams, returnType, parameters, toRange(node.loc), @@ -1378,6 +1422,7 @@ const parseFunction = return Ast.FunctionDef( attributes, name, + typeParams, returnType, parameters, statements, @@ -1406,6 +1451,7 @@ const parseNativeFunctionDecl = ({ name, attributes, + typeParams, nativeName, parameters, returnType, @@ -1415,6 +1461,7 @@ const parseNativeFunctionDecl = return Ast.NativeFunctionDecl( map(attributes, parseFunctionAttribute)(ctx), parseId(name)(ctx), + map(parseList(typeParams), parseTypeId)(ctx), parseFuncId(nativeName)(ctx), map(parseList(parameters), parseParameter)(ctx), returnType ? parseType(returnType)(ctx) : undefined, @@ -1423,10 +1470,11 @@ const parseNativeFunctionDecl = }; const parseStructDecl = - ({ name, fields, loc }: $ast.StructDecl): Handler => + ({ name, typeParams, fields, loc }: $ast.StructDecl): Handler => (ctx) => { return Ast.StructDecl( parseTypeId(name)(ctx), + map(parseList(typeParams), parseTypeId)(ctx), map(parseList(fields), parseFieldDecl)(ctx), toRange(loc), ); diff --git a/src/next/grammar/parser-error.ts b/src/next/grammar/parser-error.ts index 36405a5f56..d9ee2ef7bb 100644 --- a/src/next/grammar/parser-error.ts +++ b/src/next/grammar/parser-error.ts @@ -223,6 +223,9 @@ export const SyntaxErrors = (l: SourceLogger) => ({ deprecatedPrimitiveDecl: () => (loc: Range) => { l.at(loc).warn(l.text`"primitive" type declaration are deprecated`); }, + constDeclNoType: () => (loc: Range) => { + return l.at(loc).error(l.text`Constant declaration must have a type`); + }, }); export type SyntaxErrors = ReturnType>; diff --git a/src/next/index.ts b/src/next/index.ts index 4c03a6a03c..16b8f8b23f 100644 --- a/src/next/index.ts +++ b/src/next/index.ts @@ -5,13 +5,16 @@ import { TerminalLogger } from "@/cli/logger"; import { getAnsiMarkup, isColorSupported } from "@/cli/colors"; import { inspect } from 'util'; +// const target = "wallet-v4.tact"; +const target = "generic.tact"; + // eslint-disable-next-line @typescript-eslint/no-confusing-void-expression const dump = (obj: unknown) => console.log(inspect(obj, { colors: true, depth: Infinity })); const main = async () => { const ansi = getAnsiMarkup(isColorSupported()); await TerminalLogger(path, "info", ansi, async (log) => { - const sourcePath = path.join(__dirname, "wallet-v4.tact"); + const sourcePath = path.join(__dirname, target); const code = await fs.readFile(sourcePath, "utf8"); log.source(sourcePath, code, (log) => { log.recover((log) => { diff --git a/src/next/union.tact b/src/next/union.tact new file mode 100644 index 0000000000..a3431865d4 --- /dev/null +++ b/src/next/union.tact @@ -0,0 +1,36 @@ +union Either { + Left { + $: uint1 = 0; + left: L; + } + Right { + $: uint1 = 1; + right: R; + } +} + +union Messages { + Foo { + $: uint32 = 0x12345678; + foo: uint4; + } + Bar { + $: uint32 = 0x87654321; + bar: uint8; + } +} + + +UnionDecl = + "union" + name:TypeId + typeParams:typeParams? + "{" + cases:Case* + "}"; + +Case = + name:TypeId + "{" + fields:structFields + "}" \ No newline at end of file From b3afb2b940e22f0a0379517daa5f572ebcc2ad97 Mon Sep 17 00:00:00 2001 From: verytactical <186486509+verytactical@users.noreply.github.com> Date: Sun, 13 Apr 2025 19:33:12 +0400 Subject: [PATCH 03/38] unions --- src/next/ast/generated/root.ts | 16 ++++- src/next/ast/root.ts | 14 +++++ src/next/grammar/grammar.gg | 27 ++++++++- src/next/grammar/grammar.ts | 28 +++++++-- src/next/grammar/index.ts | 100 ++++++++++++++++++++++++++++++- src/next/grammar/parser-error.ts | 5 ++ src/next/index.ts | 3 +- src/next/union.tact | 15 ----- 8 files changed, 183 insertions(+), 25 deletions(-) diff --git a/src/next/ast/generated/root.ts b/src/next/ast/generated/root.ts index ff1d4ab62b..3a7727b7f8 100644 --- a/src/next/ast/generated/root.ts +++ b/src/next/ast/generated/root.ts @@ -250,4 +250,18 @@ export const Source = (file: string | undefined, contents: string, root: $.Modul file, contents, root -}); \ No newline at end of file +}); +export type UnionCase = $.UnionCase; +export const UnionCase = (name: $c.TypeId, fields: readonly $.FieldDecl[]): $.UnionCase => Object.freeze({ + name, + fields +}); +export type UnionDecl = $.UnionDecl; +export const UnionDecl = (name: $c.TypeId, typeParams: readonly $c.TypeId[], cases: readonly $.UnionCase[], loc: $c.Range): $.UnionDecl => Object.freeze({ + kind: "union_decl", + name, + typeParams, + cases, + loc +}); +export const isUnionDecl = ($value: UnionDecl) => $value.kind === "union_decl"; \ No newline at end of file diff --git a/src/next/ast/root.ts b/src/next/ast/root.ts index b19a501687..cdebe4c292 100644 --- a/src/next/ast/root.ts +++ b/src/next/ast/root.ts @@ -49,6 +49,7 @@ export type ModuleItem = | ConstantDef | StructDecl | MessageDecl + | UnionDecl | Contract | Trait; @@ -172,6 +173,19 @@ export type MessageDecl = { readonly loc: Range; }; +export type UnionDecl = { + readonly kind: "union_decl"; + readonly name: TypeId; + readonly typeParams: readonly TypeId[]; + readonly cases: readonly UnionCase[]; + readonly loc: Range; +} + +export type UnionCase = { + readonly name: TypeId; + readonly fields: readonly FieldDecl[]; +} + export type FieldDecl = { readonly kind: "field_decl"; readonly name: Id; diff --git a/src/next/grammar/grammar.gg b/src/next/grammar/grammar.gg index 96efbf2d44..c62cea2dff 100644 --- a/src/next/grammar/grammar.gg +++ b/src/next/grammar/grammar.gg @@ -15,6 +15,7 @@ moduleItem / Constant / StructDecl / MessageDecl + / UnionDecl / Contract / Trait; @@ -113,6 +114,20 @@ MessageDecl = fields:structFields "}"; +UnionDecl = + "union" + name:TypeId + typeParams:typeParams? + "{" + cases:Case* + "}"; + +Case = + name:TypeId + "{" + fields:structFields + "}"; + structFields = @inter? ";"?; FieldDecl = @@ -181,8 +196,16 @@ TypeAs = type:TypeOptional as:(keyword<"as"> @#storage)*; TypeOptional = type:typePrimary optionals:Optional*; Optional = "?"; -typePrimary = TypeGeneric / TypeRegular / TypeTuple / TypeTensor / TypeUnit / typeParens; +typePrimary + = TypeGeneric + / TypeRegular + / TypeStorage + / TypeTuple + / TypeTensor + / TypeUnit + / typeParens; TypeRegular = child:TypeId; +TypeStorage = child:storage; TypeGeneric = name:(MapKeyword / Bounced / TypeId) args:typeArgs; TypeTuple = "[" types:commaList? "]"; TypeTensor = "(" head:type tail:("," @type)+ ","? ")"; @@ -336,7 +359,7 @@ underscored = $(T ("_"? T)*); digit "digit" = [0-9]; idPart "identifier character" = [a-zA-Z0-9_]; -Id "identifier" = name:#$(!reservedWord [a-zA-Z_] idPart*); +Id "identifier" = name:#$(!reservedWord ([a-zA-Z_] idPart* / "$")); // FunC identifiers, where `FuncId` stands for FunC function identifier // A plain identifier cannot be a number, a single underscore, an operator, a keyword or a compiler directive diff --git a/src/next/grammar/grammar.ts b/src/next/grammar/grammar.ts index bc002d2010..adabcb2a69 100644 --- a/src/next/grammar/grammar.ts +++ b/src/next/grammar/grammar.ts @@ -66,6 +66,12 @@ export namespace $ast { readonly name: TypeId; readonly fields: structFields; }>; + export type UnionDecl = $.Located<{ + readonly $: "UnionDecl"; + readonly name: TypeId; + readonly typeParams: typeParams | undefined; + readonly cases: readonly Case[]; + }>; export type Contract = $.Located<{ readonly $: "Contract"; readonly attributes: readonly ContractAttribute[]; @@ -81,7 +87,7 @@ export namespace $ast { readonly traits: inheritedTraits | undefined; readonly declarations: readonly traitItemDecl[]; }>; - export type moduleItem = PrimitiveTypeDecl | $Function | AsmFunction | NativeFunctionDecl | Constant | StructDecl | MessageDecl | Contract | Trait; + export type moduleItem = PrimitiveTypeDecl | $Function | AsmFunction | NativeFunctionDecl | Constant | StructDecl | MessageDecl | UnionDecl | Contract | Trait; export type ContractInit = $.Located<{ readonly $: "ContractInit"; readonly parameters: parameterList; @@ -133,6 +139,11 @@ export namespace $ast { export type ConstantDeclaration = $.Located<{ readonly $: "ConstantDeclaration"; }>; + export type Case = $.Located<{ + readonly $: "Case"; + readonly name: TypeId; + readonly fields: structFields; + }>; export type inter = { readonly head: A; readonly tail: readonly { @@ -204,6 +215,10 @@ export namespace $ast { readonly $: "TypeRegular"; readonly child: TypeId; }>; + export type TypeStorage = $.Located<{ + readonly $: "TypeStorage"; + readonly child: storage; + }>; export type TypeTuple = $.Located<{ readonly $: "TypeTuple"; readonly types: commaList<$type> | undefined; @@ -217,7 +232,7 @@ export namespace $ast { readonly $: "TypeUnit"; }>; export type typeParens = $type; - export type typePrimary = TypeGeneric | TypeRegular | TypeTuple | TypeTensor | TypeUnit | typeParens; + export type typePrimary = TypeGeneric | TypeRegular | TypeStorage | TypeTuple | TypeTensor | TypeUnit | typeParens; export type MapKeyword = $.Located<{ readonly $: "MapKeyword"; }>; @@ -477,9 +492,10 @@ export const NativeFunctionDecl: $.Parser<$ast.NativeFunctionDecl> = $.loc($.fie export const Constant: $.Parser<$ast.Constant> = $.loc($.field($.pure("Constant"), "$", $.field($.star($.lazy(() => ConstantAttribute)), "attributes", $.right($.lazy(() => keyword($.str("const"))), $.field($.lazy(() => Id), "name", $.field($.opt($.lazy(() => ascription)), "type", $.field($.alt($.lazy(() => ConstantDefinition), $.lazy(() => ConstantDeclaration)), "body", $.eps))))))); export const StructDecl: $.Parser<$ast.StructDecl> = $.loc($.field($.pure("StructDecl"), "$", $.right($.str("struct"), $.field($.lazy(() => TypeId), "name", $.field($.opt($.lazy(() => typeParams)), "typeParams", $.right($.str("{"), $.field($.lazy(() => structFields), "fields", $.right($.str("}"), $.eps)))))))); export const MessageDecl: $.Parser<$ast.MessageDecl> = $.loc($.field($.pure("MessageDecl"), "$", $.right($.str("message"), $.field($.opt($.right($.str("("), $.left($.lazy(() => expression), $.str(")")))), "opcode", $.field($.lazy(() => TypeId), "name", $.right($.str("{"), $.field($.lazy(() => structFields), "fields", $.right($.str("}"), $.eps)))))))); +export const UnionDecl: $.Parser<$ast.UnionDecl> = $.loc($.field($.pure("UnionDecl"), "$", $.right($.str("union"), $.field($.lazy(() => TypeId), "name", $.field($.opt($.lazy(() => typeParams)), "typeParams", $.right($.str("{"), $.field($.star($.lazy(() => Case)), "cases", $.right($.str("}"), $.eps)))))))); export const Contract: $.Parser<$ast.Contract> = $.loc($.field($.pure("Contract"), "$", $.field($.star($.lazy(() => ContractAttribute)), "attributes", $.right($.lazy(() => keyword($.str("contract"))), $.field($.lazy(() => TypeId), "name", $.field($.opt($.lazy(() => ParameterList($.lazy(() => Parameter)))), "parameters", $.field($.opt($.lazy(() => inheritedTraits)), "traits", $.right($.str("{"), $.field($.star($.lazy(() => contractItemDecl)), "declarations", $.right($.str("}"), $.eps)))))))))); export const Trait: $.Parser<$ast.Trait> = $.loc($.field($.pure("Trait"), "$", $.field($.star($.lazy(() => ContractAttribute)), "attributes", $.right($.lazy(() => keyword($.str("trait"))), $.field($.lazy(() => TypeId), "name", $.field($.opt($.lazy(() => inheritedTraits)), "traits", $.right($.str("{"), $.field($.star($.lazy(() => traitItemDecl)), "declarations", $.right($.str("}"), $.eps))))))))); -export const moduleItem: $.Parser<$ast.moduleItem> = $.alt(PrimitiveTypeDecl, $.alt($Function, $.alt(AsmFunction, $.alt(NativeFunctionDecl, $.alt(Constant, $.alt(StructDecl, $.alt(MessageDecl, $.alt(Contract, Trait)))))))); +export const moduleItem: $.Parser<$ast.moduleItem> = $.alt(PrimitiveTypeDecl, $.alt($Function, $.alt(AsmFunction, $.alt(NativeFunctionDecl, $.alt(Constant, $.alt(StructDecl, $.alt(MessageDecl, $.alt(UnionDecl, $.alt(Contract, Trait))))))))); export const ContractInit: $.Parser<$ast.ContractInit> = $.loc($.field($.pure("ContractInit"), "$", $.right($.str("init"), $.field($.lazy(() => parameterList($.lazy(() => Parameter))), "parameters", $.field($.lazy(() => statements), "body", $.eps))))); export const Receiver: $.Parser<$ast.Receiver> = $.loc($.field($.pure("Receiver"), "$", $.field($.lazy(() => ReceiverType), "type", $.right($.str("("), $.field($.lazy(() => receiverParam), "param", $.right($.str(")"), $.field($.lazy(() => statements), "body", $.eps))))))); export const FieldDecl: $.Parser<$ast.FieldDecl> = $.loc($.field($.pure("FieldDecl"), "$", $.field($.lazy(() => Id), "name", $.field($.lazy(() => ascription), "type", $.field($.opt($.right($.str("="), $.lazy(() => expression))), "expression", $.eps))))); @@ -489,12 +505,13 @@ export const contractItemDecl: $.Parser<$ast.contractItemDecl> = $.alt(ContractI export const traitItemDecl: $.Parser<$ast.traitItemDecl> = $.alt(Receiver, $.alt($Function, $.alt(AsmFunction, $.alt(Constant, storageVar)))); export const FunctionDefinition: $.Parser<$ast.FunctionDefinition> = $.loc($.field($.pure("FunctionDefinition"), "$", $.field($.lazy(() => statements), "body", $.eps))); export const FunctionDeclaration: $.Parser<$ast.FunctionDeclaration> = $.loc($.field($.pure("FunctionDeclaration"), "$", $.right(semicolon, $.eps))); -export const Id: $.Parser<$ast.Id> = $.named("identifier", $.loc($.field($.pure("Id"), "$", $.field($.lex($.stry($.right($.lookNeg($.lazy(() => reservedWord)), $.right($.regex("a-zA-Z_", [$.ExpRange("a", "z"), $.ExpRange("A", "Z"), $.ExpString("_")]), $.right($.star($.lazy(() => idPart)), $.eps))))), "name", $.eps)))); +export const Id: $.Parser<$ast.Id> = $.named("identifier", $.loc($.field($.pure("Id"), "$", $.field($.lex($.stry($.right($.lookNeg($.lazy(() => reservedWord)), $.right($.alt($.right($.regex("a-zA-Z_", [$.ExpRange("a", "z"), $.ExpRange("A", "Z"), $.ExpString("_")]), $.right($.star($.lazy(() => idPart)), $.eps)), $.str("$")), $.eps)))), "name", $.eps)))); export const IntegerLiteralDec: $.Parser<$ast.IntegerLiteralDec> = $.loc($.field($.pure("IntegerLiteralDec"), "$", $.field($.lex($.lazy(() => underscored($.lazy(() => digit)))), "digits", $.eps))); export const shuffle: $.Parser<$ast.shuffle> = $.right($.str("("), $.field($.star(Id), "ids", $.field($.opt($.right($.str("->"), $.plus(IntegerLiteralDec))), "to", $.right($.str(")"), $.eps)))); export const ConstantAttribute: $.Parser<$ast.ConstantAttribute> = $.loc($.field($.pure("ConstantAttribute"), "$", $.field($.alt($.lazy(() => keyword($.str("virtual"))), $.alt($.lazy(() => keyword($.str("override"))), $.lazy(() => keyword($.str("abstract"))))), "name", $.eps))); export const ConstantDefinition: $.Parser<$ast.ConstantDefinition> = $.loc($.field($.pure("ConstantDefinition"), "$", $.right($.str("="), $.field($.lazy(() => expression), "expression", $.right(semicolon, $.eps))))); export const ConstantDeclaration: $.Parser<$ast.ConstantDeclaration> = $.loc($.field($.pure("ConstantDeclaration"), "$", $.right(semicolon, $.eps))); +export const Case: $.Parser<$ast.Case> = $.loc($.field($.pure("Case"), "$", $.field($.lazy(() => TypeId), "name", $.right($.str("{"), $.field($.lazy(() => structFields), "fields", $.right($.str("}"), $.eps)))))); export const inter = (A: $.Parser, B: $.Parser): $.Parser<$ast.inter> => $.field($.lazy(() => A), "head", $.field($.star($.field($.lazy(() => B), "op", $.field($.lazy(() => A), "right", $.eps))), "tail", $.eps)); export const structFields: $.Parser<$ast.structFields> = $.left($.opt(inter(FieldDecl, $.str(";"))), $.opt($.str(";"))); export const keyword = (T: $.Parser): $.Parser<$ast.keyword> => $.lex($.left($.lazy(() => T), $.lookNeg($.lazy(() => idPart)))); @@ -521,11 +538,12 @@ export const TypeOptional: $.Parser<$ast.TypeOptional> = $.loc($.field($.pure("T export const Optional: $.Parser<$ast.Optional> = $.loc($.field($.pure("Optional"), "$", $.right($.str("?"), $.eps))); export const TypeGeneric: $.Parser<$ast.TypeGeneric> = $.loc($.field($.pure("TypeGeneric"), "$", $.field($.alt($.lazy(() => MapKeyword), $.alt($.lazy(() => Bounced), TypeId)), "name", $.field($.lazy(() => typeArgs), "args", $.eps)))); export const TypeRegular: $.Parser<$ast.TypeRegular> = $.loc($.field($.pure("TypeRegular"), "$", $.field(TypeId, "child", $.eps))); +export const TypeStorage: $.Parser<$ast.TypeStorage> = $.loc($.field($.pure("TypeStorage"), "$", $.field($.lazy(() => storage), "child", $.eps))); export const TypeTuple: $.Parser<$ast.TypeTuple> = $.loc($.field($.pure("TypeTuple"), "$", $.right($.str("["), $.field($.opt(commaList($type)), "types", $.right($.str("]"), $.eps))))); export const TypeTensor: $.Parser<$ast.TypeTensor> = $.loc($.field($.pure("TypeTensor"), "$", $.right($.str("("), $.field($type, "head", $.field($.plus($.right($.str(","), $type)), "tail", $.right($.opt($.str(",")), $.right($.str(")"), $.eps))))))); export const TypeUnit: $.Parser<$ast.TypeUnit> = $.loc($.field($.pure("TypeUnit"), "$", $.right($.right($.str("("), $.right($.str(")"), $.eps)), $.eps))); export const typeParens: $.Parser<$ast.typeParens> = $.right($.str("("), $.left($type, $.str(")"))); -export const typePrimary: $.Parser<$ast.typePrimary> = $.alt(TypeGeneric, $.alt(TypeRegular, $.alt(TypeTuple, $.alt(TypeTensor, $.alt(TypeUnit, typeParens))))); +export const typePrimary: $.Parser<$ast.typePrimary> = $.alt(TypeGeneric, $.alt(TypeRegular, $.alt(TypeStorage, $.alt(TypeTuple, $.alt(TypeTensor, $.alt(TypeUnit, typeParens)))))); export const MapKeyword: $.Parser<$ast.MapKeyword> = $.loc($.field($.pure("MapKeyword"), "$", $.right(keyword($.str("map")), $.eps))); export const Bounced: $.Parser<$ast.Bounced> = $.loc($.field($.pure("Bounced"), "$", $.right($.str("bounced"), $.eps))); export const IntStorage: $.Parser<$ast.IntStorage> = $.loc($.field($.pure("IntStorage"), "$", $.field($.opt($.str("var")), "isVar", $.field($.opt($.str("u")), "isUnsigned", $.right($.str("int"), $.field($.stry($.plus($.lazy(() => digit))), "width", $.eps)))))); diff --git a/src/next/grammar/index.ts b/src/next/grammar/index.ts index 5c2c99aa5a..42181d5553 100644 --- a/src/next/grammar/index.ts +++ b/src/next/grammar/index.ts @@ -887,6 +887,85 @@ const parseTypeId = return Ast.TypeId(name, toRange(loc)); }; +const parseTypeStorage = ({ child: storage, loc }: $ast.TypeStorage): Handler => ctx => { + const range = toRange(loc); + const fallback = Ast.TypeCons(Ast.TypeId("ERROR", range), [], range); + if (storage.$ === "CoinsStorage") { + return Ast.TypeInt( + Ast.IFVarInt("unsigned", "16", toRange(storage.loc)), + range, + ); + } else if (storage.$ === "IntStorage") { + const width = parseInt(storage.width, 10); + if (storage.isVar) { + if (width === 16) { + return Ast.TypeInt( + Ast.IFVarInt( + typeof storage.isUnsigned === "undefined" + ? "signed" + : "unsigned", + "16", + toRange(storage.loc), + ), + range, + ); + } else if (width === 32) { + return Ast.TypeInt( + Ast.IFVarInt( + typeof storage.isUnsigned === "undefined" + ? "signed" + : "unsigned", + "32", + toRange(storage.loc), + ), + range, + ); + } else { + ctx.err.wrongVarIntSize()(range); + return fallback; + } + } else if (storage.isUnsigned) { + if (1 <= width && width <= 256) { + return Ast.TypeInt( + Ast.IFInt("unsigned", width, range), + range, + ); + } else { + ctx.err.wrongUIntSize()(range); + return fallback; + } + } else { + if (1 <= width && width <= 257) { + return Ast.TypeInt( + Ast.IFInt("signed", width, range), + range, + ); + } else { + ctx.err.wrongIntSize()(range); + return fallback; + } + } + } else if (storage.$ === "RemainingStorage") { + ctx.err.rawRemaining()(range); + return Ast.TypeSlice(Ast.SFRemaining(range), range); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + } else if (storage.$ === "BytesStorage") { + const width = parseInt(storage.width, 10); + if (width === 32 || width === 64) { + return Ast.TypeSlice( + Ast.SFBits(width * 8, range), + range, + ); + } else { + ctx.err.wrongSliceSize()(range); + return fallback; + } + } else { + ctx.err.wrongFormat("No type")(range); + return fallback; + } +}; + const applyFormat = (type: Ast.Type, storage: $ast.storage, asLoc: Range): Handler => (ctx) => { @@ -1094,7 +1173,8 @@ type RawType = | $ast.TypeOptional | $ast.TypeTensor | $ast.TypeUnit - | $ast.TypeTuple; + | $ast.TypeTuple + | $ast.TypeStorage; const parseType: (node: RawType) => Handler = makeVisitor()({ TypeAs: parseTypeAs, @@ -1104,6 +1184,7 @@ const parseType: (node: RawType) => Handler = makeVisitor()({ TypeTensor: parseTypeTensor, TypeTuple: parseTypeTuple, TypeUnit: parseTypeUnit, + TypeStorage: parseTypeStorage, }); const parseFieldDecl = @@ -1469,6 +1550,22 @@ const parseNativeFunctionDecl = ); }; +const parseUnion = ({ name, typeParams, cases, loc }: $ast.UnionDecl): Handler => ctx => { + return Ast.UnionDecl( + parseTypeId(name)(ctx), + map(parseList(typeParams), parseTypeId)(ctx), + map(cases, parseUnionCase)(ctx), + toRange(loc), + ) +}; + +const parseUnionCase = ({ name, fields }: $ast.Case): Handler => ctx => { + return Ast.UnionCase( + parseTypeId(name)(ctx), + map(parseList(fields), parseFieldDecl)(ctx), + ); +}; + const parseStructDecl = ({ name, typeParams, fields, loc }: $ast.StructDecl): Handler => (ctx) => { @@ -1539,6 +1636,7 @@ const parseModuleItemAux: (input: ModuleItemAux) => Handler = MessageDecl: parseMessageDecl, Contract: parseContract, Trait: parseTrait, + UnionDecl: parseUnion, }); const parseModuleItem = diff --git a/src/next/grammar/parser-error.ts b/src/next/grammar/parser-error.ts index d9ee2ef7bb..3ed54d7da4 100644 --- a/src/next/grammar/parser-error.ts +++ b/src/next/grammar/parser-error.ts @@ -217,6 +217,11 @@ export const SyntaxErrors = (l: SourceLogger) => ({ .at(loc) .error(l.text`Slice byte format must either be 32 or 64`); }, + rawRemaining: () => (loc: Range) => { + return l + .at(loc) + .error(l.text`Remaining can only be used as storage type on Slice, cell, or Builder`); + }, cannotHaveFormat: () => (loc: Range) => { return l.at(loc).error(l.text`This type cannot have format definition`); }, diff --git a/src/next/index.ts b/src/next/index.ts index 16b8f8b23f..392374af4e 100644 --- a/src/next/index.ts +++ b/src/next/index.ts @@ -6,7 +6,8 @@ import { getAnsiMarkup, isColorSupported } from "@/cli/colors"; import { inspect } from 'util'; // const target = "wallet-v4.tact"; -const target = "generic.tact"; +// const target = "generic.tact"; +const target = "union.tact"; // eslint-disable-next-line @typescript-eslint/no-confusing-void-expression const dump = (obj: unknown) => console.log(inspect(obj, { colors: true, depth: Infinity })); diff --git a/src/next/union.tact b/src/next/union.tact index a3431865d4..05bdef2665 100644 --- a/src/next/union.tact +++ b/src/next/union.tact @@ -19,18 +19,3 @@ union Messages { bar: uint8; } } - - -UnionDecl = - "union" - name:TypeId - typeParams:typeParams? - "{" - cases:Case* - "}"; - -Case = - name:TypeId - "{" - fields:structFields - "}" \ No newline at end of file From 889acc4575429795cb4951b169a3d9823c46906e Mon Sep 17 00:00:00 2001 From: verytactical <186486509+verytactical@users.noreply.github.com> Date: Sun, 13 Apr 2025 19:42:03 +0400 Subject: [PATCH 04/38] type aliases --- src/next/alias.tact | 2 ++ src/next/ast/generated/root.ts | 9 ++++++++- src/next/ast/root.ts | 7 +++++++ src/next/grammar/grammar.gg | 8 ++++++++ src/next/grammar/grammar.ts | 10 ++++++++-- src/next/grammar/index.ts | 8 ++++++++ src/next/index.ts | 3 ++- 7 files changed, 43 insertions(+), 4 deletions(-) create mode 100644 src/next/alias.tact diff --git a/src/next/alias.tact b/src/next/alias.tact new file mode 100644 index 0000000000..aea8882dc9 --- /dev/null +++ b/src/next/alias.tact @@ -0,0 +1,2 @@ +type Foo = map; + diff --git a/src/next/ast/generated/root.ts b/src/next/ast/generated/root.ts index 3a7727b7f8..f89bf5ff6f 100644 --- a/src/next/ast/generated/root.ts +++ b/src/next/ast/generated/root.ts @@ -264,4 +264,11 @@ export const UnionDecl = (name: $c.TypeId, typeParams: readonly $c.TypeId[], cas cases, loc }); -export const isUnionDecl = ($value: UnionDecl) => $value.kind === "union_decl"; \ No newline at end of file +export const isUnionDecl = ($value: UnionDecl) => $value.kind === "union_decl"; +export type AliasDecl = $.AliasDecl; +export const AliasDecl = (name: $c.TypeId, type_: $t.Type): $.AliasDecl => Object.freeze({ + kind: "alias_decl", + name, + type: type_ +}); +export const isAliasDecl = ($value: AliasDecl) => $value.kind === "alias_decl"; diff --git a/src/next/ast/root.ts b/src/next/ast/root.ts index cdebe4c292..a7a8e22612 100644 --- a/src/next/ast/root.ts +++ b/src/next/ast/root.ts @@ -50,6 +50,7 @@ export type ModuleItem = | StructDecl | MessageDecl | UnionDecl + | AliasDecl | Contract | Trait; @@ -181,6 +182,12 @@ export type UnionDecl = { readonly loc: Range; } +export type AliasDecl = { + readonly kind: "alias_decl"; + readonly name: TypeId; + readonly type: Type; +} + export type UnionCase = { readonly name: TypeId; readonly fields: readonly FieldDecl[]; diff --git a/src/next/grammar/grammar.gg b/src/next/grammar/grammar.gg index c62cea2dff..1545b76dcf 100644 --- a/src/next/grammar/grammar.gg +++ b/src/next/grammar/grammar.gg @@ -16,6 +16,7 @@ moduleItem / StructDecl / MessageDecl / UnionDecl + / AliasDecl / Contract / Trait; @@ -130,6 +131,13 @@ Case = structFields = @inter? ";"?; +AliasDecl = + "type" + name:TypeId + "=" + type:type + ";"; + FieldDecl = name:Id type:ascription diff --git a/src/next/grammar/grammar.ts b/src/next/grammar/grammar.ts index adabcb2a69..efd900a30e 100644 --- a/src/next/grammar/grammar.ts +++ b/src/next/grammar/grammar.ts @@ -72,6 +72,11 @@ export namespace $ast { readonly typeParams: typeParams | undefined; readonly cases: readonly Case[]; }>; + export type AliasDecl = $.Located<{ + readonly $: "AliasDecl"; + readonly name: TypeId; + readonly type: $type; + }>; export type Contract = $.Located<{ readonly $: "Contract"; readonly attributes: readonly ContractAttribute[]; @@ -87,7 +92,7 @@ export namespace $ast { readonly traits: inheritedTraits | undefined; readonly declarations: readonly traitItemDecl[]; }>; - export type moduleItem = PrimitiveTypeDecl | $Function | AsmFunction | NativeFunctionDecl | Constant | StructDecl | MessageDecl | UnionDecl | Contract | Trait; + export type moduleItem = PrimitiveTypeDecl | $Function | AsmFunction | NativeFunctionDecl | Constant | StructDecl | MessageDecl | UnionDecl | AliasDecl | Contract | Trait; export type ContractInit = $.Located<{ readonly $: "ContractInit"; readonly parameters: parameterList; @@ -493,9 +498,10 @@ export const Constant: $.Parser<$ast.Constant> = $.loc($.field($.pure("Constant" export const StructDecl: $.Parser<$ast.StructDecl> = $.loc($.field($.pure("StructDecl"), "$", $.right($.str("struct"), $.field($.lazy(() => TypeId), "name", $.field($.opt($.lazy(() => typeParams)), "typeParams", $.right($.str("{"), $.field($.lazy(() => structFields), "fields", $.right($.str("}"), $.eps)))))))); export const MessageDecl: $.Parser<$ast.MessageDecl> = $.loc($.field($.pure("MessageDecl"), "$", $.right($.str("message"), $.field($.opt($.right($.str("("), $.left($.lazy(() => expression), $.str(")")))), "opcode", $.field($.lazy(() => TypeId), "name", $.right($.str("{"), $.field($.lazy(() => structFields), "fields", $.right($.str("}"), $.eps)))))))); export const UnionDecl: $.Parser<$ast.UnionDecl> = $.loc($.field($.pure("UnionDecl"), "$", $.right($.str("union"), $.field($.lazy(() => TypeId), "name", $.field($.opt($.lazy(() => typeParams)), "typeParams", $.right($.str("{"), $.field($.star($.lazy(() => Case)), "cases", $.right($.str("}"), $.eps)))))))); +export const AliasDecl: $.Parser<$ast.AliasDecl> = $.loc($.field($.pure("AliasDecl"), "$", $.right($.str("type"), $.field($.lazy(() => TypeId), "name", $.right($.str("="), $.field($.lazy(() => $type), "type", $.right($.str(";"), $.eps))))))); export const Contract: $.Parser<$ast.Contract> = $.loc($.field($.pure("Contract"), "$", $.field($.star($.lazy(() => ContractAttribute)), "attributes", $.right($.lazy(() => keyword($.str("contract"))), $.field($.lazy(() => TypeId), "name", $.field($.opt($.lazy(() => ParameterList($.lazy(() => Parameter)))), "parameters", $.field($.opt($.lazy(() => inheritedTraits)), "traits", $.right($.str("{"), $.field($.star($.lazy(() => contractItemDecl)), "declarations", $.right($.str("}"), $.eps)))))))))); export const Trait: $.Parser<$ast.Trait> = $.loc($.field($.pure("Trait"), "$", $.field($.star($.lazy(() => ContractAttribute)), "attributes", $.right($.lazy(() => keyword($.str("trait"))), $.field($.lazy(() => TypeId), "name", $.field($.opt($.lazy(() => inheritedTraits)), "traits", $.right($.str("{"), $.field($.star($.lazy(() => traitItemDecl)), "declarations", $.right($.str("}"), $.eps))))))))); -export const moduleItem: $.Parser<$ast.moduleItem> = $.alt(PrimitiveTypeDecl, $.alt($Function, $.alt(AsmFunction, $.alt(NativeFunctionDecl, $.alt(Constant, $.alt(StructDecl, $.alt(MessageDecl, $.alt(UnionDecl, $.alt(Contract, Trait))))))))); +export const moduleItem: $.Parser<$ast.moduleItem> = $.alt(PrimitiveTypeDecl, $.alt($Function, $.alt(AsmFunction, $.alt(NativeFunctionDecl, $.alt(Constant, $.alt(StructDecl, $.alt(MessageDecl, $.alt(UnionDecl, $.alt(AliasDecl, $.alt(Contract, Trait)))))))))); export const ContractInit: $.Parser<$ast.ContractInit> = $.loc($.field($.pure("ContractInit"), "$", $.right($.str("init"), $.field($.lazy(() => parameterList($.lazy(() => Parameter))), "parameters", $.field($.lazy(() => statements), "body", $.eps))))); export const Receiver: $.Parser<$ast.Receiver> = $.loc($.field($.pure("Receiver"), "$", $.field($.lazy(() => ReceiverType), "type", $.right($.str("("), $.field($.lazy(() => receiverParam), "param", $.right($.str(")"), $.field($.lazy(() => statements), "body", $.eps))))))); export const FieldDecl: $.Parser<$ast.FieldDecl> = $.loc($.field($.pure("FieldDecl"), "$", $.field($.lazy(() => Id), "name", $.field($.lazy(() => ascription), "type", $.field($.opt($.right($.str("="), $.lazy(() => expression))), "expression", $.eps))))); diff --git a/src/next/grammar/index.ts b/src/next/grammar/index.ts index 42181d5553..afa7a5042d 100644 --- a/src/next/grammar/index.ts +++ b/src/next/grammar/index.ts @@ -1550,6 +1550,13 @@ const parseNativeFunctionDecl = ); }; +const parseAlias = ({ name, type }: $ast.AliasDecl): Handler => ctx => { + return Ast.AliasDecl( + parseTypeId(name)(ctx), + parseType(type)(ctx), + ); +}; + const parseUnion = ({ name, typeParams, cases, loc }: $ast.UnionDecl): Handler => ctx => { return Ast.UnionDecl( parseTypeId(name)(ctx), @@ -1637,6 +1644,7 @@ const parseModuleItemAux: (input: ModuleItemAux) => Handler = Contract: parseContract, Trait: parseTrait, UnionDecl: parseUnion, + AliasDecl: parseAlias, }); const parseModuleItem = diff --git a/src/next/index.ts b/src/next/index.ts index 392374af4e..63c7797dd8 100644 --- a/src/next/index.ts +++ b/src/next/index.ts @@ -7,7 +7,8 @@ import { inspect } from 'util'; // const target = "wallet-v4.tact"; // const target = "generic.tact"; -const target = "union.tact"; +// const target = "union.tact"; +const target = "alias.tact"; // eslint-disable-next-line @typescript-eslint/no-confusing-void-expression const dump = (obj: unknown) => console.log(inspect(obj, { colors: true, depth: Infinity })); From bd666507a040c95a8d38f34a3de4a5869625bf33 Mon Sep 17 00:00:00 2001 From: verytactical <186486509+verytactical@users.noreply.github.com> Date: Tue, 15 Apr 2025 06:16:31 +0400 Subject: [PATCH 05/38] fix alias --- src/next/alias.tact | 2 - src/next/ast/generated/root.ts | 9 +- src/next/ast/root.ts | 2 +- src/next/example/alias.tact | 1 + src/next/{ => example}/generic.tact | 0 src/next/example/import0.tact | 13 ++ src/next/example/import1.tact | 14 ++ src/next/example/import2.tact | 3 + src/next/{ => example}/union.tact | 0 src/next/{ => example}/wallet-v4.tact | 0 src/next/grammar/grammar.gg | 1 + src/next/grammar/grammar.ts | 3 +- src/next/grammar/index.ts | 3 +- src/next/grammar/src-info.ts | 279 -------------------------- src/next/index.ts | 2 +- 15 files changed, 43 insertions(+), 289 deletions(-) delete mode 100644 src/next/alias.tact create mode 100644 src/next/example/alias.tact rename src/next/{ => example}/generic.tact (100%) create mode 100644 src/next/example/import0.tact create mode 100644 src/next/example/import1.tact create mode 100644 src/next/example/import2.tact rename src/next/{ => example}/union.tact (100%) rename src/next/{ => example}/wallet-v4.tact (100%) delete mode 100644 src/next/grammar/src-info.ts diff --git a/src/next/alias.tact b/src/next/alias.tact deleted file mode 100644 index aea8882dc9..0000000000 --- a/src/next/alias.tact +++ /dev/null @@ -1,2 +0,0 @@ -type Foo = map; - diff --git a/src/next/ast/generated/root.ts b/src/next/ast/generated/root.ts index f89bf5ff6f..3533a85ceb 100644 --- a/src/next/ast/generated/root.ts +++ b/src/next/ast/generated/root.ts @@ -266,9 +266,10 @@ export const UnionDecl = (name: $c.TypeId, typeParams: readonly $c.TypeId[], cas }); export const isUnionDecl = ($value: UnionDecl) => $value.kind === "union_decl"; export type AliasDecl = $.AliasDecl; -export const AliasDecl = (name: $c.TypeId, type_: $t.Type): $.AliasDecl => Object.freeze({ - kind: "alias_decl", - name, - type: type_ +export const AliasDecl = (name: $c.TypeId, typeParams: readonly $c.TypeId[], type_: $t.Type): $.AliasDecl => Object.freeze({ + kind: "alias_decl", + name, + typeParams, + type: type_ }); export const isAliasDecl = ($value: AliasDecl) => $value.kind === "alias_decl"; diff --git a/src/next/ast/root.ts b/src/next/ast/root.ts index a7a8e22612..58c41e35f4 100644 --- a/src/next/ast/root.ts +++ b/src/next/ast/root.ts @@ -185,6 +185,7 @@ export type UnionDecl = { export type AliasDecl = { readonly kind: "alias_decl"; readonly name: TypeId; + readonly typeParams: readonly TypeId[]; readonly type: Type; } @@ -198,7 +199,6 @@ export type FieldDecl = { readonly name: Id; readonly type: Type; readonly initializer: Expression | undefined; - // readonly as: Id | undefined; readonly loc: Range; }; diff --git a/src/next/example/alias.tact b/src/next/example/alias.tact new file mode 100644 index 0000000000..71ef243c76 --- /dev/null +++ b/src/next/example/alias.tact @@ -0,0 +1 @@ +type Foo = map; diff --git a/src/next/generic.tact b/src/next/example/generic.tact similarity index 100% rename from src/next/generic.tact rename to src/next/example/generic.tact diff --git a/src/next/example/import0.tact b/src/next/example/import0.tact new file mode 100644 index 0000000000..e83dc2ab33 --- /dev/null +++ b/src/next/example/import0.tact @@ -0,0 +1,13 @@ +import { h } from "./import1"; + +fun f(x: Int) { + return x + 1; +} + +contract G() { + receive() {} + + get fun g(): Int { + return f(41); + } +} \ No newline at end of file diff --git a/src/next/example/import1.tact b/src/next/example/import1.tact new file mode 100644 index 0000000000..1a3a6edb80 --- /dev/null +++ b/src/next/example/import1.tact @@ -0,0 +1,14 @@ +import { f } from "./import2"; +export { f } from "./import2"; + +export fun h(x: Int) { + return x - 1; +} + +contract F() { + receive() {} + + get fun g(): Int { + return f(41); + } +} diff --git a/src/next/example/import2.tact b/src/next/example/import2.tact new file mode 100644 index 0000000000..33d331d131 --- /dev/null +++ b/src/next/example/import2.tact @@ -0,0 +1,3 @@ +export fun f(x: Int) { + return x + 1; +} diff --git a/src/next/union.tact b/src/next/example/union.tact similarity index 100% rename from src/next/union.tact rename to src/next/example/union.tact diff --git a/src/next/wallet-v4.tact b/src/next/example/wallet-v4.tact similarity index 100% rename from src/next/wallet-v4.tact rename to src/next/example/wallet-v4.tact diff --git a/src/next/grammar/grammar.gg b/src/next/grammar/grammar.gg index 1545b76dcf..7dabe6e9b3 100644 --- a/src/next/grammar/grammar.gg +++ b/src/next/grammar/grammar.gg @@ -134,6 +134,7 @@ structFields = @inter? ";"?; AliasDecl = "type" name:TypeId + typeParams:typeParams? "=" type:type ";"; diff --git a/src/next/grammar/grammar.ts b/src/next/grammar/grammar.ts index efd900a30e..c4ef8915cd 100644 --- a/src/next/grammar/grammar.ts +++ b/src/next/grammar/grammar.ts @@ -75,6 +75,7 @@ export namespace $ast { export type AliasDecl = $.Located<{ readonly $: "AliasDecl"; readonly name: TypeId; + readonly typeParams: typeParams | undefined; readonly type: $type; }>; export type Contract = $.Located<{ @@ -498,7 +499,7 @@ export const Constant: $.Parser<$ast.Constant> = $.loc($.field($.pure("Constant" export const StructDecl: $.Parser<$ast.StructDecl> = $.loc($.field($.pure("StructDecl"), "$", $.right($.str("struct"), $.field($.lazy(() => TypeId), "name", $.field($.opt($.lazy(() => typeParams)), "typeParams", $.right($.str("{"), $.field($.lazy(() => structFields), "fields", $.right($.str("}"), $.eps)))))))); export const MessageDecl: $.Parser<$ast.MessageDecl> = $.loc($.field($.pure("MessageDecl"), "$", $.right($.str("message"), $.field($.opt($.right($.str("("), $.left($.lazy(() => expression), $.str(")")))), "opcode", $.field($.lazy(() => TypeId), "name", $.right($.str("{"), $.field($.lazy(() => structFields), "fields", $.right($.str("}"), $.eps)))))))); export const UnionDecl: $.Parser<$ast.UnionDecl> = $.loc($.field($.pure("UnionDecl"), "$", $.right($.str("union"), $.field($.lazy(() => TypeId), "name", $.field($.opt($.lazy(() => typeParams)), "typeParams", $.right($.str("{"), $.field($.star($.lazy(() => Case)), "cases", $.right($.str("}"), $.eps)))))))); -export const AliasDecl: $.Parser<$ast.AliasDecl> = $.loc($.field($.pure("AliasDecl"), "$", $.right($.str("type"), $.field($.lazy(() => TypeId), "name", $.right($.str("="), $.field($.lazy(() => $type), "type", $.right($.str(";"), $.eps))))))); +export const AliasDecl: $.Parser<$ast.AliasDecl> = $.loc($.field($.pure("AliasDecl"), "$", $.right($.str("type"), $.field($.lazy(() => TypeId), "name", $.field($.opt($.lazy(() => typeParams)), "typeParams", $.right($.str("="), $.field($.lazy(() => $type), "type", $.right($.str(";"), $.eps)))))))); export const Contract: $.Parser<$ast.Contract> = $.loc($.field($.pure("Contract"), "$", $.field($.star($.lazy(() => ContractAttribute)), "attributes", $.right($.lazy(() => keyword($.str("contract"))), $.field($.lazy(() => TypeId), "name", $.field($.opt($.lazy(() => ParameterList($.lazy(() => Parameter)))), "parameters", $.field($.opt($.lazy(() => inheritedTraits)), "traits", $.right($.str("{"), $.field($.star($.lazy(() => contractItemDecl)), "declarations", $.right($.str("}"), $.eps)))))))))); export const Trait: $.Parser<$ast.Trait> = $.loc($.field($.pure("Trait"), "$", $.field($.star($.lazy(() => ContractAttribute)), "attributes", $.right($.lazy(() => keyword($.str("trait"))), $.field($.lazy(() => TypeId), "name", $.field($.opt($.lazy(() => inheritedTraits)), "traits", $.right($.str("{"), $.field($.star($.lazy(() => traitItemDecl)), "declarations", $.right($.str("}"), $.eps))))))))); export const moduleItem: $.Parser<$ast.moduleItem> = $.alt(PrimitiveTypeDecl, $.alt($Function, $.alt(AsmFunction, $.alt(NativeFunctionDecl, $.alt(Constant, $.alt(StructDecl, $.alt(MessageDecl, $.alt(UnionDecl, $.alt(AliasDecl, $.alt(Contract, Trait)))))))))); diff --git a/src/next/grammar/index.ts b/src/next/grammar/index.ts index afa7a5042d..b4028cf4e4 100644 --- a/src/next/grammar/index.ts +++ b/src/next/grammar/index.ts @@ -1550,9 +1550,10 @@ const parseNativeFunctionDecl = ); }; -const parseAlias = ({ name, type }: $ast.AliasDecl): Handler => ctx => { +const parseAlias = ({ name, typeParams, type }: $ast.AliasDecl): Handler => ctx => { return Ast.AliasDecl( parseTypeId(name)(ctx), + map(parseList(typeParams), parseTypeId)(ctx), parseType(type)(ctx), ); }; diff --git a/src/next/grammar/src-info.ts b/src/next/grammar/src-info.ts deleted file mode 100644 index 8c054bc90f..0000000000 --- a/src/next/grammar/src-info.ts +++ /dev/null @@ -1,279 +0,0 @@ -import { throwInternalCompilerError } from "@/error/errors"; -import type { ItemOrigin } from "@/imports/source"; - -type LineAndColumnInfo = { - lineNum: number; - colNum: number; - toString(...ranges: number[][]): string; -}; - -type Interval = { - contents: string; - getLineAndColumnMessage(): string; - getLineAndColumn(): LineAndColumnInfo; - startIdx: number; - endIdx: number; -}; - -// Do not export! Use isSrcInfo -const srcInfoSymbol = Symbol("src-info"); - -export const isSrcInfo = (t: unknown): t is SrcInfo => { - return ( - typeof t === "object" && - t !== null && - srcInfoSymbol in t && - Boolean(t[srcInfoSymbol]) - ); -}; - -export interface SrcInfo { - file: string | null; - contents: string; - interval: Interval; - origin: ItemOrigin; - - /** - * Tag so that custom snapshot serializer can distinguish it - */ - [srcInfoSymbol]: true; - /** - * toJSON method is provided, so that it's not serialized into snapshots - */ - toJSON: () => object; -} - -export const srcInfoEqual = (left: SrcInfo, right: SrcInfo): boolean => { - return ( - left.file === right.file && - left.interval.contents === right.interval.contents && - left.interval.startIdx === right.interval.startIdx && - left.interval.endIdx === right.interval.endIdx - ); -}; - -const isEndline = (s: string) => s === "\n"; - -const repeat = (s: string, n: number): string => new Array(n + 1).join(s); - -type Range = { - start: number; - end: number; -}; - -const intersect = (a: Range, b: Range): Range => { - return { - start: Math.max(a.start, b.start), - end: Math.min(a.end, b.end), - }; -}; - -const shift = (a: Range, b: number) => { - return { - start: a.start + b, - end: a.end + b, - }; -}; - -type Line = { - id: number; - text: string; - range: Range; -}; - -/** - * Convert code into a list of lines - */ -const toLines = (source: string): Line[] => { - const result: Line[] = []; - let position = 0; - for (const [id, text] of source.split("\n").entries()) { - result.push({ - id, - text, - range: { - start: position, - end: position + text.length, - }, - }); - position += text.length + 1; - } - return result; -}; - -/** - * Should wrap string into ANSI codes for coloring - */ -type Colorer = (s: string) => string; - -type ErrorPrinterParams = { - /** - * Number of context lines below and above error - */ - contextLines: number; - /** - * Colorer for code with error - */ - error: Colorer; - /** - * Colorer for context lines of code - */ - context: Colorer; -}; - -const getErrorPrinter = ({ - error, - context, - contextLines, -}: ErrorPrinterParams) => { - const displayLine = (line: Line, range: Range) => { - // Only the line that contains range.start is underlined in error message - // Otherwise error on `while (...) {}` would display the whole loop body, for example - const hasInterval = - line.range.start <= range.start && range.start <= line.range.end; - - // Find the line-relative range - const mapped = shift(intersect(range, line.range), -line.range.start); - - // All lines except with error message are displayed in gray - if (!hasInterval) { - return [ - { - id: line.id, - text: context(line.text), - hasInterval, - startOfError: mapped.start, - }, - ]; - } - - // Source line with error colored - const sourceLine = { - id: line.id, - text: [ - line.text.substring(0, mapped.start), - error(line.text.substring(mapped.start, mapped.end)), - line.text.substring(mapped.end), - ].join(""), - hasInterval: true, - startOfError: mapped.start, - }; - - // Wiggly line underneath it - const underline = { - id: null, - text: [ - repeat(" ", mapped.start), - "^", - repeat("~", Math.max(0, mapped.end - mapped.start - 1)), - ].join(""), - hasInterval: true, - startOfError: mapped.start, - }; - - return [sourceLine, underline]; - }; - - const show = (str: string, range: Range): string => { - // Display all lines of source file - const lines = toLines(str).flatMap((line) => displayLine(line, range)); - - // Find first and lines lines with error message - const firstLineNum = lines.findIndex((line) => line.hasInterval); - const lastLineNum = lines.findLastIndex((line) => line.hasInterval); - if (firstLineNum === -1 || lastLineNum === -1) { - throwInternalCompilerError( - `Interval [${range.start}, ${range.end}[ is empty or out of source bounds (${str.length})`, - ); - } - - // Expand the line range so that `contextLines` are above and below - const rangeStart = Math.max(0, firstLineNum - contextLines); - const rangeEnd = Math.min(lines.length - 1, lastLineNum + contextLines); - - // Pick displayed lines out of full list - const displayedLines = lines.slice(rangeStart, rangeEnd + 1); - - // Find padding based on the line with largest line number - const maxLineId = displayedLines.reduce((acc, line) => { - return line.id === null ? acc : Math.max(acc, line.id); - }, 1); - const lineNumLength = String(maxLineId + 1).length; - - // Add line numbers and cursor to lines - const paddedLines = displayedLines.map(({ hasInterval, id, text }) => { - const prefix = hasInterval && id !== null ? ">" : " "; - const paddedLineNum = - id === null - ? repeat(" ", lineNumLength) + " " - : String(id + 1).padStart(lineNumLength) + " |"; - return `${prefix} ${paddedLineNum} ${text}`; - }); - - return paddedLines.join("\n") + "\n"; - }; - - const getLineAndColumn = (str: string, range: Range) => { - const prefix = str.substring(0, range.start).split(""); - const lineNum = prefix.filter(isEndline).length; - const prevLineEndPos = prefix.findLastIndex(isEndline); - const lineStartPos = prevLineEndPos === -1 ? 0 : prevLineEndPos + 1; - const colNum = range.start - lineStartPos; - - return { - offset: range.start, - lineNum: lineNum + 1, - colNum: colNum + 1, - toString: () => show(str, range), - }; - }; - - return { show, getLineAndColumn }; -}; - -// Default error printer. Should be initialized in entry point instead -const errorPrinter = getErrorPrinter({ - // This should be `chalk.red` - error: (s) => s, - // This should be `chalk.gray` - context: (s) => s, - contextLines: 1, -}); - -export const getSrcInfo = ( - sourceString: string, - startIdx: number, - endIdx: number, - file: string | null, - origin: ItemOrigin, -): SrcInfo => { - const getLineAndColumn = () => { - return errorPrinter.getLineAndColumn(sourceString, { - start: startIdx, - end: endIdx, - }); - }; - - const getLineAndColumnMessage = () => { - return getLineAndColumn().toString(); - }; - - const contents = sourceString.substring(startIdx, endIdx); - - return { - [srcInfoSymbol]: true, - contents: contents, - file, - interval: { - contents: contents, - startIdx: startIdx, - endIdx: endIdx, - getLineAndColumn, - getLineAndColumnMessage, - }, - origin, - toJSON: () => ({}), - }; -}; - -export const dummySrcInfo: SrcInfo = getSrcInfo("", 0, 0, null, "user"); diff --git a/src/next/index.ts b/src/next/index.ts index 63c7797dd8..9276809d74 100644 --- a/src/next/index.ts +++ b/src/next/index.ts @@ -16,7 +16,7 @@ const dump = (obj: unknown) => console.log(inspect(obj, { colors: true, depth: I const main = async () => { const ansi = getAnsiMarkup(isColorSupported()); await TerminalLogger(path, "info", ansi, async (log) => { - const sourcePath = path.join(__dirname, target); + const sourcePath = path.join(__dirname, 'example', target); const code = await fs.readFile(sourcePath, "utf8"); log.source(sourcePath, code, (log) => { log.recover((log) => { From 0637ddb65fff56ab0075b660cf9e9e2f0d1b5941 Mon Sep 17 00:00:00 2001 From: verytactical <186486509+verytactical@users.noreply.github.com> Date: Tue, 15 Apr 2025 07:50:19 +0400 Subject: [PATCH 06/38] fs --- src/next/ast/common.ts | 14 ---- src/next/ast/generated/root.ts | 3 +- src/next/ast/root.ts | 2 +- src/next/fs/cursor.ts | 29 +++++++ src/next/fs/errors.ts | 38 +++++++++ src/next/fs/index.ts | 3 + src/next/fs/memory-fs.ts | 53 ++++++++++++ src/next/fs/path.ts | 13 +++ src/next/fs/proxy-fs.ts | 83 +++++++++++++++++++ src/next/{grammar/path.ts => fs/util.ts} | 4 +- .../grammar/{parser-error.ts => errors.ts} | 18 +--- src/next/grammar/index.ts | 4 +- src/next/index.ts | 28 +++++-- 13 files changed, 246 insertions(+), 46 deletions(-) create mode 100644 src/next/fs/cursor.ts create mode 100644 src/next/fs/errors.ts create mode 100644 src/next/fs/index.ts create mode 100644 src/next/fs/memory-fs.ts create mode 100644 src/next/fs/path.ts create mode 100644 src/next/fs/proxy-fs.ts rename src/next/{grammar/path.ts => fs/util.ts} (91%) rename src/next/grammar/{parser-error.ts => errors.ts} (93%) diff --git a/src/next/ast/common.ts b/src/next/ast/common.ts index 2e5dd25a30..fc17fd28d8 100644 --- a/src/next/ast/common.ts +++ b/src/next/ast/common.ts @@ -29,17 +29,3 @@ export type TypeId = { }; export type Language = "func" | "tact"; - -/** - * Safe relative path - */ -export type RelativePath = { - /** - * Number of "../" in front of path - */ - readonly stepsUp: number; - /** - * /-separated strings that go after optional ../ - */ - readonly segments: readonly string[]; -}; diff --git a/src/next/ast/generated/root.ts b/src/next/ast/generated/root.ts index 3533a85ceb..5d1c707ae5 100644 --- a/src/next/ast/generated/root.ts +++ b/src/next/ast/generated/root.ts @@ -3,11 +3,12 @@ import type * as $c from "@/next/ast/common"; import type * as $e from "@/next/ast/expression"; import type * as $s from "@/next/ast/statement"; import type * as $t from "@/next/ast/type"; +import type * as $f from "@/next/fs"; import type * as $ from "@/next/ast/root"; export type ImportType = $.ImportType; export const allImportType: readonly $.ImportType[] = ["stdlib", "relative"]; export type ImportPath = $.ImportPath; -export const ImportPath = (path: $c.RelativePath, type_: $.ImportType, language: $c.Language): $.ImportPath => Object.freeze({ +export const ImportPath = (path: $f.RelativePath, type_: $.ImportType, language: $c.Language): $.ImportPath => Object.freeze({ path, type: type_, language diff --git a/src/next/ast/root.ts b/src/next/ast/root.ts index 58c41e35f4..cbe2bc58d8 100644 --- a/src/next/ast/root.ts +++ b/src/next/ast/root.ts @@ -4,12 +4,12 @@ import type { Range, OptionalId, TypeId, - RelativePath, Language, } from "@/next/ast/common"; import type { Expression, Number, String } from "@/next/ast/expression"; import type { Statement } from "@/next/ast/statement"; import type { Type } from "@/next/ast/type"; +import type { RelativePath } from "@/next/fs"; export type Source = { readonly file: string | undefined; diff --git a/src/next/fs/cursor.ts b/src/next/fs/cursor.ts new file mode 100644 index 0000000000..024dc8102f --- /dev/null +++ b/src/next/fs/cursor.ts @@ -0,0 +1,29 @@ +import type { RelativePath } from "@/next/fs/path"; + +/** + * Points to a node of a file system: directory or file + */ +export interface Cursor { + /** + * Move cursor by given relative path + */ + readonly focus: (path: RelativePath) => this; + + /** + * Read file under the cursor + */ + readonly read: () => Promise; + + /** + * Write to file under the cursor + */ + readonly write: (content: string | Blob) => Promise; + + /** + * Get full absolute path to a file or directory + * + * NB! Only to be used with `log.source()` + */ + readonly getAbsolutePathForLog: () => string; +} + diff --git a/src/next/fs/errors.ts b/src/next/fs/errors.ts new file mode 100644 index 0000000000..f61491de02 --- /dev/null +++ b/src/next/fs/errors.ts @@ -0,0 +1,38 @@ +import type { Logger } from "@/error/logger-util"; + +export const FsErrors = (l: Logger) => { + const regular = { + 'ENOENT': (absPath: string) => { + return l.error(l.text`File not found: ${l.path(absPath)}`); + }, + 'EACCES': (absPath: string) => { + return l.error(l.text`Permission denied: ${l.path(absPath)}`); + }, + 'EISDIR': (absPath: string) => { + return l.error(l.text`Directory is not a file: ${l.path(absPath)}`); + }, + 'EMFILE': (absPath: string) => { + return l.error(l.text`Too many open files: ${l.path(absPath)}`); + }, + 'ENAMETOOLONG': (absPath: string) => { + return l.error(l.text`Filename too long: ${l.path(absPath)}`); + }, + 'ENOSPC': (absPath: string) => { + return l.error(l.text`No space left on device: ${l.path(absPath)}`); + }, + } as const; + return { + regular, + unexpected: (error: unknown) => { + throw error; + }, + outOfRoot: (absPath: string) => { + return l.error(l.text`Outside of the root directory: ${l.path(absPath)}`); + }, + readonly: (absPath: string) => { + return l.error(l.text`Filesystem is readonly: ${l.path(absPath)}`); + }, + }; +}; + +export type FsErrors = ReturnType; \ No newline at end of file diff --git a/src/next/fs/index.ts b/src/next/fs/index.ts new file mode 100644 index 0000000000..a2497776b1 --- /dev/null +++ b/src/next/fs/index.ts @@ -0,0 +1,3 @@ +export * from '@/next/fs/cursor'; +export * from '@/next/fs/path'; +export * from '@/next/fs/util'; diff --git a/src/next/fs/memory-fs.ts b/src/next/fs/memory-fs.ts new file mode 100644 index 0000000000..71022bfc41 --- /dev/null +++ b/src/next/fs/memory-fs.ts @@ -0,0 +1,53 @@ +import { appendPath, asString, emptyPath } from "@/next/fs/util"; +import { FsErrors } from "@/next/fs/errors"; + +import type { RelativePath } from "@/next/fs/path"; +import type { Cursor } from "@/next/fs/cursor"; +import type { Logger } from "@/error/logger-util"; + +export function createMemoryFs( + fs: Map, + root: RelativePath, + log: Logger, + isReadonly: boolean, +): Cursor { + const errors = FsErrors(log); + + function builder(currPath: RelativePath): Cursor { + const getAbsolutePathForLog = () => { + return asString(appendPath(root, currPath)); + }; + return { + getAbsolutePathForLog, + focus: (path) => { + const newPath = appendPath(currPath, path); + if (newPath.stepsUp !== 0) { + errors.outOfRoot(getAbsolutePathForLog()); + } + return builder(newPath); + }, + read: async () => { + const fullPath = asString(appendPath(root, currPath)); + const blob = fs.get(fullPath); + if (typeof blob === "undefined") { + errors.regular.ENOENT(getAbsolutePathForLog()); + return; + } + return new TextDecoder("utf-8").decode(await blob.arrayBuffer()); + }, + // eslint-disable-next-line @typescript-eslint/require-await + write: async (content) => { + if (isReadonly) { + errors.readonly(getAbsolutePathForLog()); + } + const fullPath = asString(appendPath(root, currPath)); + const blob = typeof content === 'string' + ? new Blob([content], { type: "text/plain;charset=utf-8" }) + : content; + fs.set(fullPath, blob); + }, + }; + } + + return builder(emptyPath); +} diff --git a/src/next/fs/path.ts b/src/next/fs/path.ts new file mode 100644 index 0000000000..106d40a649 --- /dev/null +++ b/src/next/fs/path.ts @@ -0,0 +1,13 @@ +/** + * Safe relative path + */ +export type RelativePath = { + /** + * Number of "../" in front of path + */ + readonly stepsUp: number; + /** + * /-separated strings that go after optional ../ + */ + readonly segments: readonly string[]; +}; diff --git a/src/next/fs/proxy-fs.ts b/src/next/fs/proxy-fs.ts new file mode 100644 index 0000000000..6442ec15d8 --- /dev/null +++ b/src/next/fs/proxy-fs.ts @@ -0,0 +1,83 @@ +import { mkdir, readFile, writeFile } from "fs/promises"; +import { dirname, isAbsolute, join } from "path"; + +import { appendPath, asString, emptyPath } from "@/next/fs/util"; +import { throwInternal } from "@/error/errors"; +import { FsErrors } from "@/next/fs/errors"; +import type { Cursor } from "@/next/fs/cursor"; +import type { RelativePath } from "@/next/fs/path"; +import type { Logger } from "@/error/logger-util"; + +const asRecord = (t: Record) => t; + +export function createProxyFs( + root: string, + log: Logger, + isReadonly: boolean, +): Cursor { + const errors = FsErrors(log); + + function builder(currPath: RelativePath): Cursor { + const getAbsolutePathForLog = () => { + return join(root, asString(currPath)); + }; + + async function catchCommonFsErrors(cb: () => Promise) { + try { + return await cb(); + } catch (error) { + if (!(error instanceof Error) || !('code' in error)) { + return errors.unexpected(error); + } + const code = error.code; + if (typeof code !== 'string') { + return errors.unexpected(error); + } + const handlers = asRecord(errors.regular); + const handler = handlers[code]; + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + if (handler) { + handler(getAbsolutePathForLog()); + return; + } else { + return errors.unexpected(error); + } + } + } + + return { + getAbsolutePathForLog, + focus: (path) => { + const newPath = appendPath(currPath, path); + if (newPath.stepsUp !== 0) { + errors.outOfRoot(getAbsolutePathForLog()); + } + return builder(newPath); + }, + read: () => { + return catchCommonFsErrors(() => { + return readFile(join(root, asString(currPath)), "utf-8"); + }); + }, + write: async (content) => { + if (isReadonly) { + errors.readonly(getAbsolutePathForLog()); + } + await catchCommonFsErrors(async () => { + const fullPath = join(root, asString(currPath)); + await mkdir(dirname(fullPath), { recursive: true }); + const encodedContent = typeof content === 'string' + ? content + : Buffer.from(await content.arrayBuffer()); + await writeFile(fullPath, encodedContent); + }); + }, + }; + } + + if (!isAbsolute(root)) { + throwInternal("Cannot pass relative paths"); + } + + return builder(emptyPath); +} \ No newline at end of file diff --git a/src/next/grammar/path.ts b/src/next/fs/util.ts similarity index 91% rename from src/next/grammar/path.ts rename to src/next/fs/util.ts index b21d0ffb11..93f289a94c 100644 --- a/src/next/grammar/path.ts +++ b/src/next/fs/util.ts @@ -1,5 +1,5 @@ import { throwInternalCompilerError } from "@/error/errors"; -import { RelativePath } from "@/next/ast/common"; +import { RelativePath } from "@/next/fs/path"; import { repeat } from "@/utils/array"; /** @@ -41,7 +41,7 @@ export const emptyPath = RelativePath(0, []); /** * Combine two relative paths */ -const appendPath = (left: RelativePath, right: RelativePath): RelativePath => { +export const appendPath = (left: RelativePath, right: RelativePath): RelativePath => { const delta = right.stepsUp - left.segments.length; return RelativePath(left.stepsUp + Math.max(0, delta), [ ...left.segments.slice(0, Math.max(0, -delta)), diff --git a/src/next/grammar/parser-error.ts b/src/next/grammar/errors.ts similarity index 93% rename from src/next/grammar/parser-error.ts rename to src/next/grammar/errors.ts index 3ed54d7da4..408358f968 100644 --- a/src/next/grammar/parser-error.ts +++ b/src/next/grammar/errors.ts @@ -19,22 +19,6 @@ const attributeSchema = (name: string, l: SourceLogger) => ({ }, }); -const getExpectedText = (expected: ReadonlySet) => { - const result: string[] = []; - const failures = [...expected].sort(); - for (const [idx, failure] of failures.entries()) { - if (idx > 0) { - if (idx === failures.length - 1) { - result.push(failures.length > 2 ? ", or " : " or "); - } else { - result.push(", "); - } - } - result.push(failure); - } - return result.join(""); -}; - export const SyntaxErrors = (l: SourceLogger) => ({ constant: attributeSchema("constant", l), function: attributeSchema("function", l), @@ -98,7 +82,7 @@ export const SyntaxErrors = (l: SourceLogger) => ({ .error(l.text`Only full function definitions are allowed here`); }, expected: (expects: ReadonlySet) => (loc: Range) => { - return l.at(loc).error(l.text`Expected ${getExpectedText(expects)}`); + return l.at(loc).error(l.expected(expects)); }, invalidFuncId: () => (loc: Range) => { return l.at(loc).error(l.text`Invalid FunC identifier`); diff --git a/src/next/grammar/index.ts b/src/next/grammar/index.ts index b4028cf4e4..e80142604d 100644 --- a/src/next/grammar/index.ts +++ b/src/next/grammar/index.ts @@ -2,9 +2,9 @@ import * as $ from "@tonstudio/parser-runtime"; import * as Ast from "@/next/ast"; import type { $ast } from "@/next/grammar/grammar"; import * as G from "@/next/grammar/grammar"; -import { SyntaxErrors } from "@/next/grammar/parser-error"; +import { SyntaxErrors } from "@/next/grammar/errors"; import { makeMakeVisitor } from "@/utils/tricks"; -import { emptyPath, fromString } from "@/next/grammar/path"; +import { emptyPath, fromString } from "@/next/fs"; import type { Language, Range } from "@/next/ast/common"; import { throwInternal } from "@/error/errors"; import type { SourceLogger } from "@/error/logger-util"; diff --git a/src/next/index.ts b/src/next/index.ts index 9276809d74..da8ee5648a 100644 --- a/src/next/index.ts +++ b/src/next/index.ts @@ -1,9 +1,10 @@ -import fs from "fs/promises"; import path from "path"; import { getParser } from "@/next/grammar"; import { TerminalLogger } from "@/cli/logger"; import { getAnsiMarkup, isColorSupported } from "@/cli/colors"; import { inspect } from 'util'; +import { createProxyFs } from "@/next/fs/proxy-fs"; +import { fromString } from "@/imports/path"; // const target = "wallet-v4.tact"; // const target = "generic.tact"; @@ -16,15 +17,24 @@ const dump = (obj: unknown) => console.log(inspect(obj, { colors: true, depth: I const main = async () => { const ansi = getAnsiMarkup(isColorSupported()); await TerminalLogger(path, "info", ansi, async (log) => { - const sourcePath = path.join(__dirname, 'example', target); - const code = await fs.readFile(sourcePath, "utf8"); - log.source(sourcePath, code, (log) => { - log.recover((log) => { - const parse = getParser(log); - const ast = parse(code); - dump(ast); + const project = createProxyFs( + path.join(__dirname, 'example'), + log, + false, + ); + + const file = project.focus(fromString(target)); + const code = await file.read(); + + if (code) { + log.source(file.getAbsolutePathForLog(), code, (log) => { + log.recover((log) => { + const parse = getParser(log); + const ast = parse(code); + dump(ast); + }); }); - }); + } }); }; From de3c322f2d11a94e2b775847ba31e1bf8616797b Mon Sep 17 00:00:00 2001 From: verytactical <186486509+verytactical@users.noreply.github.com> Date: Tue, 15 Apr 2025 07:50:36 +0400 Subject: [PATCH 07/38] fmt --- src/next/ast/expression.ts | 6 +- src/next/ast/generated/expression.ts | 325 ++- src/next/ast/generated/root.ts | 627 +++-- src/next/ast/generated/type.ts | 175 +- src/next/ast/root.ts | 6 +- src/next/ast/type.ts | 1 - src/next/fs/cursor.ts | 3 +- src/next/fs/errors.ts | 18 +- src/next/fs/index.ts | 6 +- src/next/fs/memory-fs.ts | 13 +- src/next/fs/proxy-fs.ts | 13 +- src/next/fs/util.ts | 5 +- src/next/grammar/errors.ts | 4 +- src/next/grammar/grammar.ts | 3438 +++++++++++++++++++++----- src/next/grammar/index.ts | 236 +- src/next/index.ts | 7 +- 16 files changed, 3731 insertions(+), 1152 deletions(-) diff --git a/src/next/ast/expression.ts b/src/next/ast/expression.ts index f92cd47129..91288e330b 100644 --- a/src/next/ast/expression.ts +++ b/src/next/ast/expression.ts @@ -157,16 +157,16 @@ export type Conditional = { export type Unit = { readonly kind: "unit"; readonly loc: Range; -} +}; export type Tuple = { readonly kind: "tuple"; readonly children: readonly Expression[]; readonly loc: Range; -} +}; export type Tensor = { readonly kind: "tensor"; readonly children: readonly Expression[]; readonly loc: Range; -} \ No newline at end of file +}; diff --git a/src/next/ast/generated/expression.ts b/src/next/ast/generated/expression.ts index ef62b173ed..8aee654c2e 100644 --- a/src/next/ast/generated/expression.ts +++ b/src/next/ast/generated/expression.ts @@ -4,149 +4,250 @@ import type * as $t from "@/next/ast/type"; import type * as $ from "@/next/ast/expression"; export type BinaryOperation = $.BinaryOperation; -export const allBinaryOperation: readonly $.BinaryOperation[] = ["+", "-", "*", "/", "!=", ">", "<", ">=", "<=", "==", "&&", "||", "%", "<<", ">>", "&", "|", "^"]; +export const allBinaryOperation: readonly $.BinaryOperation[] = [ + "+", + "-", + "*", + "/", + "!=", + ">", + "<", + ">=", + "<=", + "==", + "&&", + "||", + "%", + "<<", + ">>", + "&", + "|", + "^", +]; export type UnaryOperation = $.UnaryOperation; -export const allUnaryOperation: readonly $.UnaryOperation[] = ["+", "-", "!", "!!", "~"]; +export const allUnaryOperation: readonly $.UnaryOperation[] = [ + "+", + "-", + "!", + "!!", + "~", +]; export type CodeOf = $.CodeOf; -export const CodeOf = (contract: $c.TypeId, loc: $c.Range): $.CodeOf => Object.freeze({ - kind: "code_of", - contract, - loc -}); +export const CodeOf = (contract: $c.TypeId, loc: $c.Range): $.CodeOf => + Object.freeze({ + kind: "code_of", + contract, + loc, + }); export const isCodeOf = ($value: CodeOf) => $value.kind === "code_of"; export type NumberBase = $.NumberBase; export const allNumberBase: readonly $.NumberBase[] = ["2", "8", "10", "16"]; export type Number = $.Number; -export const Number = (base: $.NumberBase, value: bigint, loc: $c.Range): $.Number => Object.freeze({ - kind: "number", - base, - value, - loc -}); +export const Number = ( + base: $.NumberBase, + value: bigint, + loc: $c.Range, +): $.Number => + Object.freeze({ + kind: "number", + base, + value, + loc, + }); export const isNumber = ($value: Number) => $value.kind === "number"; export type Boolean = $.Boolean; -export const Boolean = (value: boolean, loc: $c.Range): $.Boolean => Object.freeze({ - kind: "boolean", - value, - loc -}); +export const Boolean = (value: boolean, loc: $c.Range): $.Boolean => + Object.freeze({ + kind: "boolean", + value, + loc, + }); export const isBoolean = ($value: Boolean) => $value.kind === "boolean"; export type Null = $.Null; -export const Null = (loc: $c.Range): $.Null => Object.freeze({ - kind: "null", - loc -}); +export const Null = (loc: $c.Range): $.Null => + Object.freeze({ + kind: "null", + loc, + }); export const isNull = ($value: Null) => $value.kind === "null"; export type String = $.String; -export const String = (value: string, loc: $c.Range): $.String => Object.freeze({ - kind: "string", - value, - loc -}); +export const String = (value: string, loc: $c.Range): $.String => + Object.freeze({ + kind: "string", + value, + loc, + }); export const isString = ($value: String) => $value.kind === "string"; export type Var = $.Var; -export const Var = (name: string, loc: $c.Range): $.Var => Object.freeze({ - kind: "var", - name, - loc -}); +export const Var = (name: string, loc: $c.Range): $.Var => + Object.freeze({ + kind: "var", + name, + loc, + }); export const isVar = ($value: Var) => $value.kind === "var"; export type Unit = $.Unit; -export const Unit = (loc: $c.Range): $.Unit => Object.freeze({ - kind: "unit", - loc -}); +export const Unit = (loc: $c.Range): $.Unit => + Object.freeze({ + kind: "unit", + loc, + }); export const isUnit = ($value: Unit) => $value.kind === "unit"; export type Tensor = $.Tensor; -export const Tensor = (children: readonly $.Expression[], loc: $c.Range): $.Tensor => Object.freeze({ - kind: "tensor", - children, - loc -}); +export const Tensor = ( + children: readonly $.Expression[], + loc: $c.Range, +): $.Tensor => + Object.freeze({ + kind: "tensor", + children, + loc, + }); export const isTensor = ($value: Tensor) => $value.kind === "tensor"; export type Tuple = $.Tuple; -export const Tuple = (children: readonly $.Expression[], loc: $c.Range): $.Tuple => Object.freeze({ - kind: "tuple", - children, - loc -}); +export const Tuple = ( + children: readonly $.Expression[], + loc: $c.Range, +): $.Tuple => + Object.freeze({ + kind: "tuple", + children, + loc, + }); export const isTuple = ($value: Tuple) => $value.kind === "tuple"; export type InitOf = $.InitOf; -export const InitOf = (contract: $c.TypeId, args: readonly $.Expression[], loc: $c.Range): $.InitOf => Object.freeze({ - kind: "init_of", - contract, - args, - loc -}); +export const InitOf = ( + contract: $c.TypeId, + args: readonly $.Expression[], + loc: $c.Range, +): $.InitOf => + Object.freeze({ + kind: "init_of", + contract, + args, + loc, + }); export const isInitOf = ($value: InitOf) => $value.kind === "init_of"; export type StructFieldInitializer = $.StructFieldInitializer; -export const StructFieldInitializer = (field: $c.Id, initializer: $.Expression, loc: $c.Range): $.StructFieldInitializer => Object.freeze({ - kind: "struct_field_initializer", - field, - initializer, - loc -}); -export const isStructFieldInitializer = ($value: StructFieldInitializer) => $value.kind === "struct_field_initializer"; +export const StructFieldInitializer = ( + field: $c.Id, + initializer: $.Expression, + loc: $c.Range, +): $.StructFieldInitializer => + Object.freeze({ + kind: "struct_field_initializer", + field, + initializer, + loc, + }); +export const isStructFieldInitializer = ($value: StructFieldInitializer) => + $value.kind === "struct_field_initializer"; export type StructInstance = $.StructInstance; -export const StructInstance = (type_: $c.TypeId, typeArgs: readonly $t.Type[], args: readonly $.StructFieldInitializer[], loc: $c.Range): $.StructInstance => Object.freeze({ - kind: "struct_instance", - type: type_, - typeArgs, - args, - loc -}); -export const isStructInstance = ($value: StructInstance) => $value.kind === "struct_instance"; +export const StructInstance = ( + type_: $c.TypeId, + typeArgs: readonly $t.Type[], + args: readonly $.StructFieldInitializer[], + loc: $c.Range, +): $.StructInstance => + Object.freeze({ + kind: "struct_instance", + type: type_, + typeArgs, + args, + loc, + }); +export const isStructInstance = ($value: StructInstance) => + $value.kind === "struct_instance"; export type StaticCall = $.StaticCall; -export const StaticCall = (function_: $c.Id, typeArgs: readonly $t.Type[], args: readonly $.Expression[], loc: $c.Range): $.StaticCall => Object.freeze({ - kind: "static_call", - function: function_, - typeArgs, - args, - loc -}); -export const isStaticCall = ($value: StaticCall) => $value.kind === "static_call"; +export const StaticCall = ( + function_: $c.Id, + typeArgs: readonly $t.Type[], + args: readonly $.Expression[], + loc: $c.Range, +): $.StaticCall => + Object.freeze({ + kind: "static_call", + function: function_, + typeArgs, + args, + loc, + }); +export const isStaticCall = ($value: StaticCall) => + $value.kind === "static_call"; export type FieldAccess = $.FieldAccess; -export const FieldAccess = (aggregate: $.Expression, field: $c.Id, loc: $c.Range): $.FieldAccess => Object.freeze({ - kind: "field_access", - aggregate, - field, - loc -}); -export const isFieldAccess = ($value: FieldAccess) => $value.kind === "field_access"; +export const FieldAccess = ( + aggregate: $.Expression, + field: $c.Id, + loc: $c.Range, +): $.FieldAccess => + Object.freeze({ + kind: "field_access", + aggregate, + field, + loc, + }); +export const isFieldAccess = ($value: FieldAccess) => + $value.kind === "field_access"; export type MethodCall = $.MethodCall; -export const MethodCall = (self: $.Expression, method: $c.Id, typeArgs: readonly $t.Type[], args: readonly $.Expression[], loc: $c.Range): $.MethodCall => Object.freeze({ - kind: "method_call", - self, - method, - typeArgs, - args, - loc -}); -export const isMethodCall = ($value: MethodCall) => $value.kind === "method_call"; +export const MethodCall = ( + self: $.Expression, + method: $c.Id, + typeArgs: readonly $t.Type[], + args: readonly $.Expression[], + loc: $c.Range, +): $.MethodCall => + Object.freeze({ + kind: "method_call", + self, + method, + typeArgs, + args, + loc, + }); +export const isMethodCall = ($value: MethodCall) => + $value.kind === "method_call"; export type Conditional = $.Conditional; -export const Conditional = (condition: $.Expression, thenBranch: $.Expression, elseBranch: $.Expression, loc: $c.Range): $.Conditional => Object.freeze({ - kind: "conditional", - condition, - thenBranch, - elseBranch, - loc -}); -export const isConditional = ($value: Conditional) => $value.kind === "conditional"; +export const Conditional = ( + condition: $.Expression, + thenBranch: $.Expression, + elseBranch: $.Expression, + loc: $c.Range, +): $.Conditional => + Object.freeze({ + kind: "conditional", + condition, + thenBranch, + elseBranch, + loc, + }); +export const isConditional = ($value: Conditional) => + $value.kind === "conditional"; export type OpUnary = $.OpUnary; -export const OpUnary = (op: $.UnaryOperation, operand: $.Expression, loc: $c.Range): $.OpUnary => Object.freeze({ - kind: "op_unary", - op, - operand, - loc -}); +export const OpUnary = ( + op: $.UnaryOperation, + operand: $.Expression, + loc: $c.Range, +): $.OpUnary => + Object.freeze({ + kind: "op_unary", + op, + operand, + loc, + }); export const isOpUnary = ($value: OpUnary) => $value.kind === "op_unary"; export type OpBinary = $.OpBinary; -export const OpBinary = (op: $.BinaryOperation, left: $.Expression, right: $.Expression, loc: $c.Range): $.OpBinary => Object.freeze({ - kind: "op_binary", - op, - left, - right, - loc -}); +export const OpBinary = ( + op: $.BinaryOperation, + left: $.Expression, + right: $.Expression, + loc: $c.Range, +): $.OpBinary => + Object.freeze({ + kind: "op_binary", + op, + left, + right, + loc, + }); export const isOpBinary = ($value: OpBinary) => $value.kind === "op_binary"; export type Expression = $.Expression; diff --git a/src/next/ast/generated/root.ts b/src/next/ast/generated/root.ts index 5d1c707ae5..54bee5496f 100644 --- a/src/next/ast/generated/root.ts +++ b/src/next/ast/generated/root.ts @@ -8,269 +8,460 @@ import type * as $ from "@/next/ast/root"; export type ImportType = $.ImportType; export const allImportType: readonly $.ImportType[] = ["stdlib", "relative"]; export type ImportPath = $.ImportPath; -export const ImportPath = (path: $f.RelativePath, type_: $.ImportType, language: $c.Language): $.ImportPath => Object.freeze({ - path, - type: type_, - language -}); +export const ImportPath = ( + path: $f.RelativePath, + type_: $.ImportType, + language: $c.Language, +): $.ImportPath => + Object.freeze({ + path, + type: type_, + language, + }); export type Import = $.Import; -export const Import = (importPath: $.ImportPath, loc: $c.Range): $.Import => Object.freeze({ - kind: "import", - importPath, - loc -}); +export const Import = (importPath: $.ImportPath, loc: $c.Range): $.Import => + Object.freeze({ + kind: "import", + importPath, + loc, + }); export const isImport = ($value: Import) => $value.kind === "import"; export type FunctionAttributeGet = $.FunctionAttributeGet; -export const FunctionAttributeGet = (methodId: $e.Expression | undefined, loc: $c.Range): $.FunctionAttributeGet => Object.freeze({ - kind: "function_attribute", - type: "get", - methodId, - loc -}); -export const isFunctionAttributeGet = ($value: FunctionAttributeGet) => $value.kind === "function_attribute"; +export const FunctionAttributeGet = ( + methodId: $e.Expression | undefined, + loc: $c.Range, +): $.FunctionAttributeGet => + Object.freeze({ + kind: "function_attribute", + type: "get", + methodId, + loc, + }); +export const isFunctionAttributeGet = ($value: FunctionAttributeGet) => + $value.kind === "function_attribute"; export type FunctionAttributeName = $.FunctionAttributeName; -export const allFunctionAttributeName: readonly $.FunctionAttributeName[] = ["mutates", "extends", "virtual", "abstract", "override", "inline"]; +export const allFunctionAttributeName: readonly $.FunctionAttributeName[] = [ + "mutates", + "extends", + "virtual", + "abstract", + "override", + "inline", +]; export type FunctionAttributeRest = $.FunctionAttributeRest; -export const FunctionAttributeRest = (type_: $.FunctionAttributeName, loc: $c.Range): $.FunctionAttributeRest => Object.freeze({ - kind: "function_attribute", - type: type_, - loc -}); -export const isFunctionAttributeRest = ($value: FunctionAttributeRest) => $value.kind === "function_attribute"; +export const FunctionAttributeRest = ( + type_: $.FunctionAttributeName, + loc: $c.Range, +): $.FunctionAttributeRest => + Object.freeze({ + kind: "function_attribute", + type: type_, + loc, + }); +export const isFunctionAttributeRest = ($value: FunctionAttributeRest) => + $value.kind === "function_attribute"; export type FunctionAttribute = $.FunctionAttribute; export type TypedParameter = $.TypedParameter; -export const TypedParameter = (name: $c.OptionalId, type_: $t.Type, loc: $c.Range): $.TypedParameter => Object.freeze({ - kind: "typed_parameter", - name, - type: type_, - loc -}); -export const isTypedParameter = ($value: TypedParameter) => $value.kind === "typed_parameter"; +export const TypedParameter = ( + name: $c.OptionalId, + type_: $t.Type, + loc: $c.Range, +): $.TypedParameter => + Object.freeze({ + kind: "typed_parameter", + name, + type: type_, + loc, + }); +export const isTypedParameter = ($value: TypedParameter) => + $value.kind === "typed_parameter"; export type FunctionDef = $.FunctionDef; -export const FunctionDef = (attributes: readonly $.FunctionAttribute[], name: $c.Id, typeParams: readonly $c.TypeId[], return_: $t.Type | undefined, params: readonly $.TypedParameter[], statements: readonly $s.Statement[], loc: $c.Range): $.FunctionDef => Object.freeze({ - kind: "function_def", - attributes, - name, - typeParams, - return: return_, - params, - statements, - loc -}); -export const isFunctionDef = ($value: FunctionDef) => $value.kind === "function_def"; +export const FunctionDef = ( + attributes: readonly $.FunctionAttribute[], + name: $c.Id, + typeParams: readonly $c.TypeId[], + return_: $t.Type | undefined, + params: readonly $.TypedParameter[], + statements: readonly $s.Statement[], + loc: $c.Range, +): $.FunctionDef => + Object.freeze({ + kind: "function_def", + attributes, + name, + typeParams, + return: return_, + params, + statements, + loc, + }); +export const isFunctionDef = ($value: FunctionDef) => + $value.kind === "function_def"; export type AsmShuffle = $.AsmShuffle; -export const AsmShuffle = (args: readonly $c.Id[], ret: readonly $e.Number[]): $.AsmShuffle => Object.freeze({ - args, - ret -}); +export const AsmShuffle = ( + args: readonly $c.Id[], + ret: readonly $e.Number[], +): $.AsmShuffle => + Object.freeze({ + args, + ret, + }); export type AsmInstruction = $.AsmInstruction; export type AsmFunctionDef = $.AsmFunctionDef; -export const AsmFunctionDef = (shuffle: $.AsmShuffle, attributes: readonly $.FunctionAttribute[], name: $c.Id, typeParams: readonly $c.TypeId[], return_: $t.Type | undefined, params: readonly $.TypedParameter[], instructions: readonly $.AsmInstruction[], loc: $c.Range): $.AsmFunctionDef => Object.freeze({ - kind: "asm_function_def", - shuffle, - attributes, - name, - typeParams, - return: return_, - params, - instructions, - loc -}); -export const isAsmFunctionDef = ($value: AsmFunctionDef) => $value.kind === "asm_function_def"; +export const AsmFunctionDef = ( + shuffle: $.AsmShuffle, + attributes: readonly $.FunctionAttribute[], + name: $c.Id, + typeParams: readonly $c.TypeId[], + return_: $t.Type | undefined, + params: readonly $.TypedParameter[], + instructions: readonly $.AsmInstruction[], + loc: $c.Range, +): $.AsmFunctionDef => + Object.freeze({ + kind: "asm_function_def", + shuffle, + attributes, + name, + typeParams, + return: return_, + params, + instructions, + loc, + }); +export const isAsmFunctionDef = ($value: AsmFunctionDef) => + $value.kind === "asm_function_def"; export type NativeFunctionDecl = $.NativeFunctionDecl; -export const NativeFunctionDecl = (attributes: readonly $.FunctionAttribute[], name: $c.Id, typeParams: readonly $c.TypeId[], nativeName: $c.FuncId, params: readonly $.TypedParameter[], return_: $t.Type | undefined, loc: $c.Range): $.NativeFunctionDecl => Object.freeze({ - kind: "native_function_decl", - attributes, - name, - typeParams, - nativeName, - params, - return: return_, - loc -}); -export const isNativeFunctionDecl = ($value: NativeFunctionDecl) => $value.kind === "native_function_decl"; +export const NativeFunctionDecl = ( + attributes: readonly $.FunctionAttribute[], + name: $c.Id, + typeParams: readonly $c.TypeId[], + nativeName: $c.FuncId, + params: readonly $.TypedParameter[], + return_: $t.Type | undefined, + loc: $c.Range, +): $.NativeFunctionDecl => + Object.freeze({ + kind: "native_function_decl", + attributes, + name, + typeParams, + nativeName, + params, + return: return_, + loc, + }); +export const isNativeFunctionDecl = ($value: NativeFunctionDecl) => + $value.kind === "native_function_decl"; export type ConstantAttributeName = $.ConstantAttributeName; -export const allConstantAttributeName: readonly $.ConstantAttributeName[] = ["virtual", "override", "abstract"]; +export const allConstantAttributeName: readonly $.ConstantAttributeName[] = [ + "virtual", + "override", + "abstract", +]; export type ConstantAttribute = $.ConstantAttribute; -export const ConstantAttribute = (type_: $.ConstantAttributeName, loc: $c.Range): $.ConstantAttribute => Object.freeze({ - type: type_, - loc -}); +export const ConstantAttribute = ( + type_: $.ConstantAttributeName, + loc: $c.Range, +): $.ConstantAttribute => + Object.freeze({ + type: type_, + loc, + }); export type ConstantDef = $.ConstantDef; -export const ConstantDef = (attributes: readonly $.ConstantAttribute[], name: $c.Id, type_: $t.Type | undefined, initializer: $e.Expression, loc: $c.Range): $.ConstantDef => Object.freeze({ - kind: "constant_def", - attributes, - name, - type: type_, - initializer, - loc -}); -export const isConstantDef = ($value: ConstantDef) => $value.kind === "constant_def"; +export const ConstantDef = ( + attributes: readonly $.ConstantAttribute[], + name: $c.Id, + type_: $t.Type | undefined, + initializer: $e.Expression, + loc: $c.Range, +): $.ConstantDef => + Object.freeze({ + kind: "constant_def", + attributes, + name, + type: type_, + initializer, + loc, + }); +export const isConstantDef = ($value: ConstantDef) => + $value.kind === "constant_def"; export type FieldDecl = $.FieldDecl; -export const FieldDecl = (name: $c.Id, type_: $t.Type, initializer: $e.Expression | undefined, loc: $c.Range): $.FieldDecl => Object.freeze({ - kind: "field_decl", - name, - type: type_, - initializer, - loc -}); +export const FieldDecl = ( + name: $c.Id, + type_: $t.Type, + initializer: $e.Expression | undefined, + loc: $c.Range, +): $.FieldDecl => + Object.freeze({ + kind: "field_decl", + name, + type: type_, + initializer, + loc, + }); export const isFieldDecl = ($value: FieldDecl) => $value.kind === "field_decl"; export type StructDecl = $.StructDecl; -export const StructDecl = (name: $c.TypeId, typeParams: readonly $c.TypeId[], fields: readonly $.FieldDecl[], loc: $c.Range): $.StructDecl => Object.freeze({ - kind: "struct_decl", - name, - typeParams, - fields, - loc -}); -export const isStructDecl = ($value: StructDecl) => $value.kind === "struct_decl"; +export const StructDecl = ( + name: $c.TypeId, + typeParams: readonly $c.TypeId[], + fields: readonly $.FieldDecl[], + loc: $c.Range, +): $.StructDecl => + Object.freeze({ + kind: "struct_decl", + name, + typeParams, + fields, + loc, + }); +export const isStructDecl = ($value: StructDecl) => + $value.kind === "struct_decl"; export type MessageDecl = $.MessageDecl; -export const MessageDecl = (name: $c.TypeId, opcode: $e.Expression | undefined, fields: readonly $.FieldDecl[], loc: $c.Range): $.MessageDecl => Object.freeze({ - kind: "message_decl", - name, - opcode, - fields, - loc -}); -export const isMessageDecl = ($value: MessageDecl) => $value.kind === "message_decl"; +export const MessageDecl = ( + name: $c.TypeId, + opcode: $e.Expression | undefined, + fields: readonly $.FieldDecl[], + loc: $c.Range, +): $.MessageDecl => + Object.freeze({ + kind: "message_decl", + name, + opcode, + fields, + loc, + }); +export const isMessageDecl = ($value: MessageDecl) => + $value.kind === "message_decl"; export type ContractAttribute = $.ContractAttribute; -export const ContractAttribute = (name: string, loc: $c.Range): $.ContractAttribute => Object.freeze({ - type: "interface", - name, - loc -}); +export const ContractAttribute = ( + name: string, + loc: $c.Range, +): $.ContractAttribute => + Object.freeze({ + type: "interface", + name, + loc, + }); export type ContractInit = $.ContractInit; -export const ContractInit = (params: readonly $.TypedParameter[], statements: readonly $s.Statement[], loc: $c.Range): $.ContractInit => Object.freeze({ - kind: "contract_init", - params, - statements, - loc -}); -export const isContractInit = ($value: ContractInit) => $value.kind === "contract_init"; +export const ContractInit = ( + params: readonly $.TypedParameter[], + statements: readonly $s.Statement[], + loc: $c.Range, +): $.ContractInit => + Object.freeze({ + kind: "contract_init", + params, + statements, + loc, + }); +export const isContractInit = ($value: ContractInit) => + $value.kind === "contract_init"; export type ReceiverSimple = $.ReceiverSimple; -export const ReceiverSimple = (param: $.TypedParameter): $.ReceiverSimple => Object.freeze({ - kind: "simple", - param -}); -export const isReceiverSimple = ($value: ReceiverSimple) => $value.kind === "simple"; +export const ReceiverSimple = (param: $.TypedParameter): $.ReceiverSimple => + Object.freeze({ + kind: "simple", + param, + }); +export const isReceiverSimple = ($value: ReceiverSimple) => + $value.kind === "simple"; export type ReceiverFallback = $.ReceiverFallback; -export const ReceiverFallback = (): $.ReceiverFallback => Object.freeze({ - kind: "fallback" -}); -export const isReceiverFallback = ($value: ReceiverFallback) => $value.kind === "fallback"; +export const ReceiverFallback = (): $.ReceiverFallback => + Object.freeze({ + kind: "fallback", + }); +export const isReceiverFallback = ($value: ReceiverFallback) => + $value.kind === "fallback"; export type ReceiverComment = $.ReceiverComment; -export const ReceiverComment = (comment: $e.String): $.ReceiverComment => Object.freeze({ - kind: "comment", - comment -}); -export const isReceiverComment = ($value: ReceiverComment) => $value.kind === "comment"; +export const ReceiverComment = (comment: $e.String): $.ReceiverComment => + Object.freeze({ + kind: "comment", + comment, + }); +export const isReceiverComment = ($value: ReceiverComment) => + $value.kind === "comment"; export type ReceiverSubKind = $.ReceiverSubKind; export type ReceiverInternal = $.ReceiverInternal; -export const ReceiverInternal = (subKind: $.ReceiverSubKind, loc: $c.Range): $.ReceiverInternal => Object.freeze({ - kind: "internal", - subKind, - loc -}); -export const isReceiverInternal = ($value: ReceiverInternal) => $value.kind === "internal"; +export const ReceiverInternal = ( + subKind: $.ReceiverSubKind, + loc: $c.Range, +): $.ReceiverInternal => + Object.freeze({ + kind: "internal", + subKind, + loc, + }); +export const isReceiverInternal = ($value: ReceiverInternal) => + $value.kind === "internal"; export type ReceiverExternal = $.ReceiverExternal; -export const ReceiverExternal = (subKind: $.ReceiverSubKind, loc: $c.Range): $.ReceiverExternal => Object.freeze({ - kind: "external", - subKind, - loc -}); -export const isReceiverExternal = ($value: ReceiverExternal) => $value.kind === "external"; +export const ReceiverExternal = ( + subKind: $.ReceiverSubKind, + loc: $c.Range, +): $.ReceiverExternal => + Object.freeze({ + kind: "external", + subKind, + loc, + }); +export const isReceiverExternal = ($value: ReceiverExternal) => + $value.kind === "external"; export type ReceiverBounce = $.ReceiverBounce; -export const ReceiverBounce = (param: $.TypedParameter, loc: $c.Range): $.ReceiverBounce => Object.freeze({ - kind: "bounce", - param, - loc -}); -export const isReceiverBounce = ($value: ReceiverBounce) => $value.kind === "bounce"; +export const ReceiverBounce = ( + param: $.TypedParameter, + loc: $c.Range, +): $.ReceiverBounce => + Object.freeze({ + kind: "bounce", + param, + loc, + }); +export const isReceiverBounce = ($value: ReceiverBounce) => + $value.kind === "bounce"; export type ReceiverKind = $.ReceiverKind; export type Receiver = $.Receiver; -export const Receiver = (selector: $.ReceiverKind, statements: readonly $s.Statement[], loc: $c.Range): $.Receiver => Object.freeze({ - kind: "receiver", - selector, - statements, - loc -}); +export const Receiver = ( + selector: $.ReceiverKind, + statements: readonly $s.Statement[], + loc: $c.Range, +): $.Receiver => + Object.freeze({ + kind: "receiver", + selector, + statements, + loc, + }); export const isReceiver = ($value: Receiver) => $value.kind === "receiver"; export type ContractItem = $.ContractItem; export type Contract = $.Contract; -export const Contract = (name: $c.TypeId, traits: readonly $c.TypeId[], attributes: readonly $.ContractAttribute[], params: readonly $.FieldDecl[] | undefined, declarations: readonly $.ContractItem[], loc: $c.Range): $.Contract => Object.freeze({ - kind: "contract", - name, - traits, - attributes, - params, - declarations, - loc -}); +export const Contract = ( + name: $c.TypeId, + traits: readonly $c.TypeId[], + attributes: readonly $.ContractAttribute[], + params: readonly $.FieldDecl[] | undefined, + declarations: readonly $.ContractItem[], + loc: $c.Range, +): $.Contract => + Object.freeze({ + kind: "contract", + name, + traits, + attributes, + params, + declarations, + loc, + }); export const isContract = ($value: Contract) => $value.kind === "contract"; export type FunctionDecl = $.FunctionDecl; -export const FunctionDecl = (attributes: readonly $.FunctionAttribute[], name: $c.Id, typeParams: readonly $c.TypeId[], return_: $t.Type | undefined, params: readonly $.TypedParameter[], loc: $c.Range): $.FunctionDecl => Object.freeze({ - kind: "function_decl", - attributes, - name, - typeParams, - return: return_, - params, - loc -}); -export const isFunctionDecl = ($value: FunctionDecl) => $value.kind === "function_decl"; +export const FunctionDecl = ( + attributes: readonly $.FunctionAttribute[], + name: $c.Id, + typeParams: readonly $c.TypeId[], + return_: $t.Type | undefined, + params: readonly $.TypedParameter[], + loc: $c.Range, +): $.FunctionDecl => + Object.freeze({ + kind: "function_decl", + attributes, + name, + typeParams, + return: return_, + params, + loc, + }); +export const isFunctionDecl = ($value: FunctionDecl) => + $value.kind === "function_decl"; export type ConstantDecl = $.ConstantDecl; -export const ConstantDecl = (attributes: readonly $.ConstantAttribute[], name: $c.Id, type_: $t.Type, loc: $c.Range): $.ConstantDecl => Object.freeze({ - kind: "constant_decl", - attributes, - name, - type: type_, - loc -}); -export const isConstantDecl = ($value: ConstantDecl) => $value.kind === "constant_decl"; +export const ConstantDecl = ( + attributes: readonly $.ConstantAttribute[], + name: $c.Id, + type_: $t.Type, + loc: $c.Range, +): $.ConstantDecl => + Object.freeze({ + kind: "constant_decl", + attributes, + name, + type: type_, + loc, + }); +export const isConstantDecl = ($value: ConstantDecl) => + $value.kind === "constant_decl"; export type TraitItem = $.TraitItem; export type Trait = $.Trait; -export const Trait = (name: $c.TypeId, traits: readonly $c.TypeId[], attributes: readonly $.ContractAttribute[], declarations: readonly $.TraitItem[], loc: $c.Range): $.Trait => Object.freeze({ - kind: "trait", - name, - traits, - attributes, - declarations, - loc -}); +export const Trait = ( + name: $c.TypeId, + traits: readonly $c.TypeId[], + attributes: readonly $.ContractAttribute[], + declarations: readonly $.TraitItem[], + loc: $c.Range, +): $.Trait => + Object.freeze({ + kind: "trait", + name, + traits, + attributes, + declarations, + loc, + }); export const isTrait = ($value: Trait) => $value.kind === "trait"; export type ModuleItem = $.ModuleItem; export type Module = $.Module; -export const Module = (imports: readonly $.Import[], items: readonly $.ModuleItem[]): $.Module => Object.freeze({ - kind: "module", - imports, - items -}); +export const Module = ( + imports: readonly $.Import[], + items: readonly $.ModuleItem[], +): $.Module => + Object.freeze({ + kind: "module", + imports, + items, + }); export const isModule = ($value: Module) => $value.kind === "module"; export type Source = $.Source; -export const Source = (file: string | undefined, contents: string, root: $.Module): $.Source => Object.freeze({ - file, - contents, - root -}); +export const Source = ( + file: string | undefined, + contents: string, + root: $.Module, +): $.Source => + Object.freeze({ + file, + contents, + root, + }); export type UnionCase = $.UnionCase; -export const UnionCase = (name: $c.TypeId, fields: readonly $.FieldDecl[]): $.UnionCase => Object.freeze({ - name, - fields -}); +export const UnionCase = ( + name: $c.TypeId, + fields: readonly $.FieldDecl[], +): $.UnionCase => + Object.freeze({ + name, + fields, + }); export type UnionDecl = $.UnionDecl; -export const UnionDecl = (name: $c.TypeId, typeParams: readonly $c.TypeId[], cases: readonly $.UnionCase[], loc: $c.Range): $.UnionDecl => Object.freeze({ - kind: "union_decl", - name, - typeParams, - cases, - loc -}); +export const UnionDecl = ( + name: $c.TypeId, + typeParams: readonly $c.TypeId[], + cases: readonly $.UnionCase[], + loc: $c.Range, +): $.UnionDecl => + Object.freeze({ + kind: "union_decl", + name, + typeParams, + cases, + loc, + }); export const isUnionDecl = ($value: UnionDecl) => $value.kind === "union_decl"; export type AliasDecl = $.AliasDecl; -export const AliasDecl = (name: $c.TypeId, typeParams: readonly $c.TypeId[], type_: $t.Type): $.AliasDecl => Object.freeze({ - kind: "alias_decl", - name, - typeParams, - type: type_ -}); +export const AliasDecl = ( + name: $c.TypeId, + typeParams: readonly $c.TypeId[], + type_: $t.Type, +): $.AliasDecl => + Object.freeze({ + kind: "alias_decl", + name, + typeParams, + type: type_, + }); export const isAliasDecl = ($value: AliasDecl) => $value.kind === "alias_decl"; diff --git a/src/next/ast/generated/type.ts b/src/next/ast/generated/type.ts index e9db39860a..22a77b21e3 100644 --- a/src/next/ast/generated/type.ts +++ b/src/next/ast/generated/type.ts @@ -5,99 +5,136 @@ import type * as $ from "@/next/ast/type"; export type Signedness = $.Signedness; export const allSignedness: readonly $.Signedness[] = ["signed", "unsigned"]; export type IFInt = $.IFInt; -export const IFInt = (sign: $.Signedness, width: number, loc: $c.Range): $.IFInt => Object.freeze({ - kind: "FInt", - sign, - width, - loc -}); +export const IFInt = ( + sign: $.Signedness, + width: number, + loc: $c.Range, +): $.IFInt => + Object.freeze({ + kind: "FInt", + sign, + width, + loc, + }); export const isIFInt = ($value: IFInt) => $value.kind === "FInt"; export type VarIntWidth = $.VarIntWidth; export const allVarIntWidth: readonly $.VarIntWidth[] = ["16", "32"]; export type IFVarInt = $.IFVarInt; -export const IFVarInt = (sign: $.Signedness, width: $.VarIntWidth, loc: $c.Range): $.IFVarInt => Object.freeze({ - kind: "FVarInt", - sign, - width, - loc -}); +export const IFVarInt = ( + sign: $.Signedness, + width: $.VarIntWidth, + loc: $c.Range, +): $.IFVarInt => + Object.freeze({ + kind: "FVarInt", + sign, + width, + loc, + }); export const isIFVarInt = ($value: IFVarInt) => $value.kind === "FVarInt"; export type IntFormat = $.IntFormat; export type TypeInt = $.TypeInt; -export const TypeInt = (format: $.IntFormat, loc: $c.Range): $.TypeInt => Object.freeze({ - kind: "TyInt", - format, - loc -}); +export const TypeInt = (format: $.IntFormat, loc: $c.Range): $.TypeInt => + Object.freeze({ + kind: "TyInt", + format, + loc, + }); export const isTypeInt = ($value: TypeInt) => $value.kind === "TyInt"; export type SFBits = $.SFBits; -export const SFBits = (bits: number, loc: $c.Range): $.SFBits => Object.freeze({ - kind: "SFBits", - bits, - loc -}); +export const SFBits = (bits: number, loc: $c.Range): $.SFBits => + Object.freeze({ + kind: "SFBits", + bits, + loc, + }); export const isSFBits = ($value: SFBits) => $value.kind === "SFBits"; export type SFRemaining = $.SFRemaining; -export const SFRemaining = (loc: $c.Range): $.SFRemaining => Object.freeze({ - kind: "SFRemaining", - loc -}); -export const isSFRemaining = ($value: SFRemaining) => $value.kind === "SFRemaining"; +export const SFRemaining = (loc: $c.Range): $.SFRemaining => + Object.freeze({ + kind: "SFRemaining", + loc, + }); +export const isSFRemaining = ($value: SFRemaining) => + $value.kind === "SFRemaining"; export type SFDefault = $.SFDefault; -export const SFDefault = (loc: $c.Range): $.SFDefault => Object.freeze({ - kind: "SFDefault", - loc -}); +export const SFDefault = (loc: $c.Range): $.SFDefault => + Object.freeze({ + kind: "SFDefault", + loc, + }); export const isSFDefault = ($value: SFDefault) => $value.kind === "SFDefault"; export type SliceFormat = $.SliceFormat; export type TypeSlice = $.TypeSlice; -export const TypeSlice = (format: $.SliceFormat, loc: $c.Range): $.TypeSlice => Object.freeze({ - kind: "TySlice", - format, - loc -}); +export const TypeSlice = (format: $.SliceFormat, loc: $c.Range): $.TypeSlice => + Object.freeze({ + kind: "TySlice", + format, + loc, + }); export const isTypeSlice = ($value: TypeSlice) => $value.kind === "TySlice"; export type RemFormat = $.RemFormat; export type TypeCell = $.TypeCell; -export const TypeCell = (format: $.RemFormat, loc: $c.Range): $.TypeCell => Object.freeze({ - kind: "TyCell", - format, - loc -}); +export const TypeCell = (format: $.RemFormat, loc: $c.Range): $.TypeCell => + Object.freeze({ + kind: "TyCell", + format, + loc, + }); export const isTypeCell = ($value: TypeCell) => $value.kind === "TyCell"; export type TypeBuilder = $.TypeBuilder; -export const TypeBuilder = (format: $.RemFormat, loc: $c.Range): $.TypeBuilder => Object.freeze({ - kind: "TyBuilder", - format, - loc -}); -export const isTypeBuilder = ($value: TypeBuilder) => $value.kind === "TyBuilder"; +export const TypeBuilder = ( + format: $.RemFormat, + loc: $c.Range, +): $.TypeBuilder => + Object.freeze({ + kind: "TyBuilder", + format, + loc, + }); +export const isTypeBuilder = ($value: TypeBuilder) => + $value.kind === "TyBuilder"; export type TypeUnit = $.TypeUnit; -export const TypeUnit = (loc: $c.Range): $.TypeUnit => Object.freeze({ - kind: "unit_type", - loc -}); +export const TypeUnit = (loc: $c.Range): $.TypeUnit => + Object.freeze({ + kind: "unit_type", + loc, + }); export const isTypeUnit = ($value: TypeUnit) => $value.kind === "unit_type"; export type TypeTensor = $.TypeTensor; -export const TypeTensor = (typeArgs: readonly $.Type[], loc: $c.Range): $.TypeTensor => Object.freeze({ - kind: "tensor_type", - typeArgs, - loc -}); -export const isTypeTensor = ($value: TypeTensor) => $value.kind === "tensor_type"; +export const TypeTensor = ( + typeArgs: readonly $.Type[], + loc: $c.Range, +): $.TypeTensor => + Object.freeze({ + kind: "tensor_type", + typeArgs, + loc, + }); +export const isTypeTensor = ($value: TypeTensor) => + $value.kind === "tensor_type"; export type TypeTuple = $.TypeTuple; -export const TypeTuple = (typeArgs: readonly $.Type[], loc: $c.Range): $.TypeTuple => Object.freeze({ - kind: "tuple_type", - typeArgs, - loc -}); +export const TypeTuple = ( + typeArgs: readonly $.Type[], + loc: $c.Range, +): $.TypeTuple => + Object.freeze({ + kind: "tuple_type", + typeArgs, + loc, + }); export const isTypeTuple = ($value: TypeTuple) => $value.kind === "tuple_type"; export type TypeCons = $.TypeCons; -export const TypeCons = (name: $c.TypeId, typeArgs: readonly $.Type[], loc: $c.Range): $.TypeCons => Object.freeze({ - kind: "cons_type", - name, - typeArgs, - loc -}); +export const TypeCons = ( + name: $c.TypeId, + typeArgs: readonly $.Type[], + loc: $c.Range, +): $.TypeCons => + Object.freeze({ + kind: "cons_type", + name, + typeArgs, + loc, + }); export const isTypeCons = ($value: TypeCons) => $value.kind === "cons_type"; -export type Type = $.Type; \ No newline at end of file +export type Type = $.Type; diff --git a/src/next/ast/root.ts b/src/next/ast/root.ts index cbe2bc58d8..6d07af9723 100644 --- a/src/next/ast/root.ts +++ b/src/next/ast/root.ts @@ -180,19 +180,19 @@ export type UnionDecl = { readonly typeParams: readonly TypeId[]; readonly cases: readonly UnionCase[]; readonly loc: Range; -} +}; export type AliasDecl = { readonly kind: "alias_decl"; readonly name: TypeId; readonly typeParams: readonly TypeId[]; readonly type: Type; -} +}; export type UnionCase = { readonly name: TypeId; readonly fields: readonly FieldDecl[]; -} +}; export type FieldDecl = { readonly kind: "field_decl"; diff --git a/src/next/ast/type.ts b/src/next/ast/type.ts index 177c118e22..45cdcbb26f 100644 --- a/src/next/ast/type.ts +++ b/src/next/ast/type.ts @@ -86,4 +86,3 @@ export type TypeTensor = { readonly typeArgs: readonly Type[]; readonly loc: Range; }; - diff --git a/src/next/fs/cursor.ts b/src/next/fs/cursor.ts index 024dc8102f..0996a7cabe 100644 --- a/src/next/fs/cursor.ts +++ b/src/next/fs/cursor.ts @@ -21,9 +21,8 @@ export interface Cursor { /** * Get full absolute path to a file or directory - * + * * NB! Only to be used with `log.source()` */ readonly getAbsolutePathForLog: () => string; } - diff --git a/src/next/fs/errors.ts b/src/next/fs/errors.ts index f61491de02..eb66396057 100644 --- a/src/next/fs/errors.ts +++ b/src/next/fs/errors.ts @@ -2,22 +2,22 @@ import type { Logger } from "@/error/logger-util"; export const FsErrors = (l: Logger) => { const regular = { - 'ENOENT': (absPath: string) => { + ENOENT: (absPath: string) => { return l.error(l.text`File not found: ${l.path(absPath)}`); }, - 'EACCES': (absPath: string) => { + EACCES: (absPath: string) => { return l.error(l.text`Permission denied: ${l.path(absPath)}`); }, - 'EISDIR': (absPath: string) => { + EISDIR: (absPath: string) => { return l.error(l.text`Directory is not a file: ${l.path(absPath)}`); }, - 'EMFILE': (absPath: string) => { + EMFILE: (absPath: string) => { return l.error(l.text`Too many open files: ${l.path(absPath)}`); }, - 'ENAMETOOLONG': (absPath: string) => { + ENAMETOOLONG: (absPath: string) => { return l.error(l.text`Filename too long: ${l.path(absPath)}`); }, - 'ENOSPC': (absPath: string) => { + ENOSPC: (absPath: string) => { return l.error(l.text`No space left on device: ${l.path(absPath)}`); }, } as const; @@ -27,7 +27,9 @@ export const FsErrors = (l: Logger) => { throw error; }, outOfRoot: (absPath: string) => { - return l.error(l.text`Outside of the root directory: ${l.path(absPath)}`); + return l.error( + l.text`Outside of the root directory: ${l.path(absPath)}`, + ); }, readonly: (absPath: string) => { return l.error(l.text`Filesystem is readonly: ${l.path(absPath)}`); @@ -35,4 +37,4 @@ export const FsErrors = (l: Logger) => { }; }; -export type FsErrors = ReturnType; \ No newline at end of file +export type FsErrors = ReturnType; diff --git a/src/next/fs/index.ts b/src/next/fs/index.ts index a2497776b1..f312df7a84 100644 --- a/src/next/fs/index.ts +++ b/src/next/fs/index.ts @@ -1,3 +1,3 @@ -export * from '@/next/fs/cursor'; -export * from '@/next/fs/path'; -export * from '@/next/fs/util'; +export * from "@/next/fs/cursor"; +export * from "@/next/fs/path"; +export * from "@/next/fs/util"; diff --git a/src/next/fs/memory-fs.ts b/src/next/fs/memory-fs.ts index 71022bfc41..bacd1c2576 100644 --- a/src/next/fs/memory-fs.ts +++ b/src/next/fs/memory-fs.ts @@ -33,7 +33,9 @@ export function createMemoryFs( errors.regular.ENOENT(getAbsolutePathForLog()); return; } - return new TextDecoder("utf-8").decode(await blob.arrayBuffer()); + return new TextDecoder("utf-8").decode( + await blob.arrayBuffer(), + ); }, // eslint-disable-next-line @typescript-eslint/require-await write: async (content) => { @@ -41,9 +43,12 @@ export function createMemoryFs( errors.readonly(getAbsolutePathForLog()); } const fullPath = asString(appendPath(root, currPath)); - const blob = typeof content === 'string' - ? new Blob([content], { type: "text/plain;charset=utf-8" }) - : content; + const blob = + typeof content === "string" + ? new Blob([content], { + type: "text/plain;charset=utf-8", + }) + : content; fs.set(fullPath, blob); }, }; diff --git a/src/next/fs/proxy-fs.ts b/src/next/fs/proxy-fs.ts index 6442ec15d8..d667ab4311 100644 --- a/src/next/fs/proxy-fs.ts +++ b/src/next/fs/proxy-fs.ts @@ -26,11 +26,11 @@ export function createProxyFs( try { return await cb(); } catch (error) { - if (!(error instanceof Error) || !('code' in error)) { + if (!(error instanceof Error) || !("code" in error)) { return errors.unexpected(error); } const code = error.code; - if (typeof code !== 'string') { + if (typeof code !== "string") { return errors.unexpected(error); } const handlers = asRecord(errors.regular); @@ -66,9 +66,10 @@ export function createProxyFs( await catchCommonFsErrors(async () => { const fullPath = join(root, asString(currPath)); await mkdir(dirname(fullPath), { recursive: true }); - const encodedContent = typeof content === 'string' - ? content - : Buffer.from(await content.arrayBuffer()); + const encodedContent = + typeof content === "string" + ? content + : Buffer.from(await content.arrayBuffer()); await writeFile(fullPath, encodedContent); }); }, @@ -80,4 +81,4 @@ export function createProxyFs( } return builder(emptyPath); -} \ No newline at end of file +} diff --git a/src/next/fs/util.ts b/src/next/fs/util.ts index 93f289a94c..f148ecfd60 100644 --- a/src/next/fs/util.ts +++ b/src/next/fs/util.ts @@ -41,7 +41,10 @@ export const emptyPath = RelativePath(0, []); /** * Combine two relative paths */ -export const appendPath = (left: RelativePath, right: RelativePath): RelativePath => { +export const appendPath = ( + left: RelativePath, + right: RelativePath, +): RelativePath => { const delta = right.stepsUp - left.segments.length; return RelativePath(left.stepsUp + Math.max(0, delta), [ ...left.segments.slice(0, Math.max(0, -delta)), diff --git a/src/next/grammar/errors.ts b/src/next/grammar/errors.ts index 408358f968..45edb409fb 100644 --- a/src/next/grammar/errors.ts +++ b/src/next/grammar/errors.ts @@ -204,7 +204,9 @@ export const SyntaxErrors = (l: SourceLogger) => ({ rawRemaining: () => (loc: Range) => { return l .at(loc) - .error(l.text`Remaining can only be used as storage type on Slice, cell, or Builder`); + .error( + l.text`Remaining can only be used as storage type on Slice, cell, or Builder`, + ); }, cannotHaveFormat: () => (loc: Range) => { return l.at(loc).error(l.text`This type cannot have format definition`); diff --git a/src/next/grammar/grammar.ts b/src/next/grammar/grammar.ts index c4ef8915cd..1387c33ce1 100644 --- a/src/next/grammar/grammar.ts +++ b/src/next/grammar/grammar.ts @@ -6,627 +6,2833 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ import * as $ from "@tonstudio/parser-runtime"; export namespace $ast { - export type Module = $.Located<{ - readonly $: "Module"; - readonly imports: readonly Import[]; - readonly items: readonly moduleItem[]; - }>; - export type Import = $.Located<{ - readonly $: "Import"; - readonly path: StringLiteral; - }>; - export type PrimitiveTypeDecl = $.Located<{ - readonly $: "PrimitiveTypeDecl"; - readonly name: TypeId; - }>; - export type $Function = $.Located<{ - readonly $: "Function"; - readonly attributes: readonly FunctionAttribute[]; - readonly name: Id; - readonly typeParams: typeParams | undefined; - readonly parameters: parameterList; - readonly returnType: ascription | undefined; - readonly body: FunctionDefinition | FunctionDeclaration; - }>; - export type AsmFunction = $.Located<{ - readonly $: "AsmFunction"; - readonly shuffle: shuffle | undefined; - readonly attributes: readonly FunctionAttribute[]; - readonly name: Id; - readonly typeParams: typeParams | undefined; - readonly parameters: parameterList; - readonly returnType: ascription | undefined; - readonly instructions: assembly; - }>; - export type NativeFunctionDecl = $.Located<{ - readonly $: "NativeFunctionDecl"; - readonly nativeName: FuncId; - readonly attributes: readonly FunctionAttribute[]; - readonly name: Id; - readonly typeParams: typeParams | undefined; - readonly parameters: parameterList; - readonly returnType: ascription | undefined; - }>; - export type Constant = $.Located<{ - readonly $: "Constant"; - readonly attributes: readonly ConstantAttribute[]; - readonly name: Id; - readonly type: ascription | undefined; - readonly body: ConstantDefinition | ConstantDeclaration; - }>; - export type StructDecl = $.Located<{ - readonly $: "StructDecl"; - readonly name: TypeId; - readonly typeParams: typeParams | undefined; - readonly fields: structFields; - }>; - export type MessageDecl = $.Located<{ - readonly $: "MessageDecl"; - readonly opcode: expression | undefined; - readonly name: TypeId; - readonly fields: structFields; - }>; - export type UnionDecl = $.Located<{ - readonly $: "UnionDecl"; - readonly name: TypeId; - readonly typeParams: typeParams | undefined; - readonly cases: readonly Case[]; - }>; - export type AliasDecl = $.Located<{ - readonly $: "AliasDecl"; - readonly name: TypeId; - readonly typeParams: typeParams | undefined; - readonly type: $type; - }>; - export type Contract = $.Located<{ - readonly $: "Contract"; - readonly attributes: readonly ContractAttribute[]; - readonly name: TypeId; - readonly parameters: ParameterList | undefined; - readonly traits: inheritedTraits | undefined; - readonly declarations: readonly contractItemDecl[]; - }>; - export type Trait = $.Located<{ - readonly $: "Trait"; - readonly attributes: readonly ContractAttribute[]; - readonly name: TypeId; - readonly traits: inheritedTraits | undefined; - readonly declarations: readonly traitItemDecl[]; - }>; - export type moduleItem = PrimitiveTypeDecl | $Function | AsmFunction | NativeFunctionDecl | Constant | StructDecl | MessageDecl | UnionDecl | AliasDecl | Contract | Trait; - export type ContractInit = $.Located<{ - readonly $: "ContractInit"; - readonly parameters: parameterList; - readonly body: statements; - }>; - export type Receiver = $.Located<{ - readonly $: "Receiver"; - readonly type: ReceiverType; - readonly param: receiverParam; - readonly body: statements; - }>; - export type FieldDecl = $.Located<{ - readonly $: "FieldDecl"; - readonly name: Id; - readonly type: ascription; - readonly expression: expression | undefined; - }>; - export type semicolon = ";" | "}"; - export type storageVar = FieldDecl; - export type contractItemDecl = ContractInit | Receiver | $Function | AsmFunction | Constant | storageVar; - export type traitItemDecl = Receiver | $Function | AsmFunction | Constant | storageVar; - export type FunctionDefinition = $.Located<{ - readonly $: "FunctionDefinition"; - readonly body: statements; - }>; - export type FunctionDeclaration = $.Located<{ - readonly $: "FunctionDeclaration"; - }>; - export type Id = $.Located<{ - readonly $: "Id"; - readonly name: string; - }>; - export type IntegerLiteralDec = $.Located<{ - readonly $: "IntegerLiteralDec"; - readonly digits: underscored; - }>; - export type shuffle = { - readonly ids: readonly Id[]; - readonly to: readonly IntegerLiteralDec[] | undefined; - }; - export type ConstantAttribute = $.Located<{ - readonly $: "ConstantAttribute"; - readonly name: keyword<"virtual"> | keyword<"override"> | keyword<"abstract">; - }>; - export type ConstantDefinition = $.Located<{ - readonly $: "ConstantDefinition"; - readonly expression: expression; - }>; - export type ConstantDeclaration = $.Located<{ - readonly $: "ConstantDeclaration"; - }>; - export type Case = $.Located<{ - readonly $: "Case"; - readonly name: TypeId; - readonly fields: structFields; - }>; - export type inter = { - readonly head: A; - readonly tail: readonly { - readonly op: B; - readonly right: A; - }[]; - }; - export type structFields = inter | undefined; - export type keyword = T; - export type commaList = inter; - export type TypeId = $.Located<{ - readonly $: "TypeId"; - readonly name: string; - }>; - export type inheritedTraits = commaList; - export type ContractAttribute = $.Located<{ - readonly $: "ContractAttribute"; - readonly name: StringLiteral; - }>; - export type FunctionAttribute = $.Located<{ - readonly $: "FunctionAttribute"; - readonly name: GetAttribute | keyword<"mutates"> | keyword<"extends"> | keyword<"virtual"> | keyword<"override"> | keyword<"inline"> | keyword<"abstract">; - }>; - export type GetAttribute = $.Located<{ - readonly $: "GetAttribute"; - readonly methodId: expression | undefined; - }>; - export type ReceiverType = $.Located<{ - readonly $: "ReceiverType"; - readonly name: "bounced" | keyword<"receive"> | keyword<"external">; - }>; - export type Parameter = $.Located<{ - readonly $: "Parameter"; - readonly name: Id; - readonly type: ascription; - }>; - export type StringLiteral = $.Located<{ - readonly $: "StringLiteral"; - readonly value: string; - }>; - export type receiverParam = Parameter | StringLiteral | undefined; - export type assembly = string; - export type multiLineComment = string; - export type singleLineComment = string; - export type comment = multiLineComment | singleLineComment; - export type assemblyItem = {} | comment | {} | readonly {}[]; - export type assemblySequence = readonly assemblyItem[]; - export type TypeAs = $.Located<{ - readonly $: "TypeAs"; - readonly type: TypeOptional; - readonly as: readonly storage[]; - }>; - export type $type = TypeAs; - export type ascription = $type; - export type TypeOptional = $.Located<{ - readonly $: "TypeOptional"; - readonly type: typePrimary; - readonly optionals: readonly Optional[]; - }>; - export type Optional = $.Located<{ - readonly $: "Optional"; - }>; - export type TypeGeneric = $.Located<{ - readonly $: "TypeGeneric"; - readonly name: MapKeyword | Bounced | TypeId; - readonly args: typeArgs; - }>; - export type TypeRegular = $.Located<{ - readonly $: "TypeRegular"; - readonly child: TypeId; - }>; - export type TypeStorage = $.Located<{ - readonly $: "TypeStorage"; - readonly child: storage; - }>; - export type TypeTuple = $.Located<{ - readonly $: "TypeTuple"; - readonly types: commaList<$type> | undefined; - }>; - export type TypeTensor = $.Located<{ - readonly $: "TypeTensor"; - readonly head: $type; - readonly tail: readonly $type[]; - }>; - export type TypeUnit = $.Located<{ - readonly $: "TypeUnit"; - }>; - export type typeParens = $type; - export type typePrimary = TypeGeneric | TypeRegular | TypeStorage | TypeTuple | TypeTensor | TypeUnit | typeParens; - export type MapKeyword = $.Located<{ - readonly $: "MapKeyword"; - }>; - export type Bounced = $.Located<{ - readonly $: "Bounced"; - }>; - export type IntStorage = $.Located<{ - readonly $: "IntStorage"; - readonly isVar: "var" | undefined; - readonly isUnsigned: "u" | undefined; - readonly width: string; - }>; - export type CoinsStorage = $.Located<{ - readonly $: "CoinsStorage"; - }>; - export type RemainingStorage = $.Located<{ - readonly $: "RemainingStorage"; - }>; - export type BytesStorage = $.Located<{ - readonly $: "BytesStorage"; - readonly width: string; - }>; - export type storage = IntStorage | CoinsStorage | RemainingStorage | BytesStorage; - export type generic = commaList | undefined; - export type typeParams = generic; - export type typeArgs = generic<$type>; - export type StatementLet = $.Located<{ - readonly $: "StatementLet"; - readonly name: Id; - readonly type: ascription | undefined; - readonly init: expression; - }>; - export type StatementDestruct = $.Located<{ - readonly $: "StatementDestruct"; - readonly type: TypeId; - readonly fields: inter; - readonly rest: optionalRest; - readonly init: expression; - }>; - export type StatementBlock = $.Located<{ - readonly $: "StatementBlock"; - readonly body: statements; - }>; - export type StatementReturn = $.Located<{ - readonly $: "StatementReturn"; - readonly expression: expression | undefined; - }>; - export type StatementCondition = $.Located<{ - readonly $: "StatementCondition"; - readonly condition: expression; - readonly trueBranch: statements; - readonly falseBranch: FalseBranch | StatementCondition | undefined; - }>; - export type StatementWhile = $.Located<{ - readonly $: "StatementWhile"; - readonly condition: parens; - readonly body: statements; - }>; - export type StatementRepeat = $.Located<{ - readonly $: "StatementRepeat"; - readonly condition: parens; - readonly body: statements; - }>; - export type StatementUntil = $.Located<{ - readonly $: "StatementUntil"; - readonly body: statements; - readonly condition: parens; - }>; - export type StatementTry = $.Located<{ - readonly $: "StatementTry"; - readonly body: statements; - readonly handler: { - readonly name: Id; - readonly body: statements; - } | undefined; - }>; - export type StatementForEach = $.Located<{ - readonly $: "StatementForEach"; - readonly key: Id; - readonly value: Id; - readonly expression: expression; - readonly body: statements; - }>; - export type StatementExpression = $.Located<{ - readonly $: "StatementExpression"; - readonly expression: expression; - }>; - export type StatementAssign = $.Located<{ - readonly $: "StatementAssign"; - readonly left: expression; - readonly operator: augmentedOp | "="; - readonly right: expression; - }>; - export type statement = StatementLet | StatementDestruct | StatementBlock | StatementReturn | StatementCondition | StatementWhile | StatementRepeat | StatementUntil | StatementTry | StatementForEach | StatementExpression | StatementAssign; - export type statements = readonly statement[]; - export type augmentedOp = "||=" | "&&=" | ">>=" | "<<=" | "-=" | "+=" | "*=" | "/=" | "%=" | "|=" | "&=" | "^="; - export type FalseBranch = $.Located<{ - readonly $: "FalseBranch"; - readonly body: statements; - }>; - export type RegularField = $.Located<{ - readonly $: "RegularField"; - readonly fieldName: Id; - readonly varName: Id; - }>; - export type PunnedField = $.Located<{ - readonly $: "PunnedField"; - readonly name: Id; - }>; - export type destructItem = RegularField | PunnedField; - export type RestArgument = $.Located<{ - readonly $: "RestArgument"; - }>; - export type NoRestArgument = $.Located<{ - readonly $: "NoRestArgument"; - }>; - export type optionalRest = RestArgument | NoRestArgument; - export type Conditional = $.Located<{ - readonly $: "Conditional"; - readonly head: or; - readonly tail: { - readonly thenBranch: or; - readonly elseBranch: Conditional; - } | undefined; - }>; - export type expression = Conditional; - export type Binary = $.Located<{ - readonly $: "Binary"; - readonly exprs: inter>; - }>; - export type Unary = $.Located<{ - readonly $: "Unary"; - readonly prefixes: readonly Operator<"-" | "+" | "!" | "~">[]; - readonly expression: Suffix; - }>; - export type mul = Binary; - export type add = Binary; - export type bitwiseShift = Binary>">; - export type compare = Binary=" | ">">; - export type equality = Binary; - export type bitwiseXor = Binary; - export type bitwiseOr = Binary; - export type and = Binary; - export type or = Binary; - export type Suffix = $.Located<{ - readonly $: "Suffix"; - readonly expression: primary; - readonly suffixes: readonly suffix[]; - }>; - export type Operator = $.Located<{ - readonly $: "Operator"; - readonly name: U; - }>; - export type SuffixUnboxNotNull = $.Located<{ - readonly $: "SuffixUnboxNotNull"; - }>; - export type SuffixCall = $.Located<{ - readonly $: "SuffixCall"; - readonly typeArgs: typeArgs | undefined; - readonly params: parameterList; - }>; - export type SuffixFieldAccess = $.Located<{ - readonly $: "SuffixFieldAccess"; - readonly name: Id; - }>; - export type suffix = SuffixUnboxNotNull | SuffixCall | SuffixFieldAccess; - export type Unit = $.Located<{ - readonly $: "Unit"; - }>; - export type Tensor = $.Located<{ - readonly $: "Tensor"; - readonly head: expression; - readonly tail: readonly expression[]; - }>; - export type Tuple = $.Located<{ - readonly $: "Tuple"; - readonly types: commaList | undefined; - }>; - export type Parens = $.Located<{ - readonly $: "Parens"; - readonly child: parens; - }>; - export type StructInstance = $.Located<{ - readonly $: "StructInstance"; - readonly type: TypeId; - readonly typeArgs: typeArgs | undefined; - readonly fields: commaList | undefined; - }>; - export type IntegerLiteral = $.Located<{ - readonly $: "IntegerLiteral"; - readonly value: IntegerLiteralHex | IntegerLiteralBin | IntegerLiteralOct | IntegerLiteralDec; - }>; - export type BoolLiteral = $.Located<{ - readonly $: "BoolLiteral"; - readonly value: "true" | "false"; - }>; - export type InitOf = $.Located<{ - readonly $: "InitOf"; - readonly name: TypeId; - readonly params: parameterList; - }>; - export type CodeOf = $.Located<{ - readonly $: "CodeOf"; - readonly name: TypeId; - }>; - export type Null = $.Located<{ - readonly $: "Null"; - }>; - export type primary = Unit | Tensor | Tuple | Parens | StructInstance | IntegerLiteral | BoolLiteral | InitOf | CodeOf | Null | StringLiteral | Id; - export type parens = expression; - export type StructFieldInitializer = $.Located<{ - readonly $: "StructFieldInitializer"; - readonly name: Id; - readonly init: expression | undefined; - }>; - export type ParameterList = $.Located<{ - readonly $: "ParameterList"; - readonly values: commaList | undefined; - }>; - export type parameterList = commaList | undefined; - export type IntegerLiteralHex = $.Located<{ - readonly $: "IntegerLiteralHex"; - readonly digits: underscored; - }>; - export type IntegerLiteralBin = $.Located<{ - readonly $: "IntegerLiteralBin"; - readonly digits: underscored<"0" | "1">; - }>; - export type IntegerLiteralOct = $.Located<{ - readonly $: "IntegerLiteralOct"; - readonly digits: underscored; - }>; - export type underscored = string; - export type digit = string; - export type idPart = string | string | string | "_"; - export type FuncId = $.Located<{ - readonly $: "FuncId"; - readonly accessor: "." | "~" | undefined; - readonly id: string; - }>; - export type hexDigit = string | string | string; - export type escapeChar = "\\" | "\"" | "n" | "r" | "t" | "v" | "b" | "f" | string | string | string; - export type reservedWord = keyword<"extend" | "public" | "fun" | "let" | "return" | "receive" | "native" | "primitive" | "null" | "if" | "else" | "while" | "repeat" | "do" | "until" | "try" | "catch" | "foreach" | "as" | "map" | "mutates" | "extends" | "external" | "import" | "with" | "trait" | "initOf" | "override" | "abstract" | "virtual" | "inline" | "const">; - export type space = " " | "\t" | "\r" | "\n" | comment; - export type JustImports = $.Located<{ - readonly $: "JustImports"; - readonly imports: readonly Import[]; - }>; + export type Module = $.Located<{ + readonly $: "Module"; + readonly imports: readonly Import[]; + readonly items: readonly moduleItem[]; + }>; + export type Import = $.Located<{ + readonly $: "Import"; + readonly path: StringLiteral; + }>; + export type PrimitiveTypeDecl = $.Located<{ + readonly $: "PrimitiveTypeDecl"; + readonly name: TypeId; + }>; + export type $Function = $.Located<{ + readonly $: "Function"; + readonly attributes: readonly FunctionAttribute[]; + readonly name: Id; + readonly typeParams: typeParams | undefined; + readonly parameters: parameterList; + readonly returnType: ascription | undefined; + readonly body: FunctionDefinition | FunctionDeclaration; + }>; + export type AsmFunction = $.Located<{ + readonly $: "AsmFunction"; + readonly shuffle: shuffle | undefined; + readonly attributes: readonly FunctionAttribute[]; + readonly name: Id; + readonly typeParams: typeParams | undefined; + readonly parameters: parameterList; + readonly returnType: ascription | undefined; + readonly instructions: assembly; + }>; + export type NativeFunctionDecl = $.Located<{ + readonly $: "NativeFunctionDecl"; + readonly nativeName: FuncId; + readonly attributes: readonly FunctionAttribute[]; + readonly name: Id; + readonly typeParams: typeParams | undefined; + readonly parameters: parameterList; + readonly returnType: ascription | undefined; + }>; + export type Constant = $.Located<{ + readonly $: "Constant"; + readonly attributes: readonly ConstantAttribute[]; + readonly name: Id; + readonly type: ascription | undefined; + readonly body: ConstantDefinition | ConstantDeclaration; + }>; + export type StructDecl = $.Located<{ + readonly $: "StructDecl"; + readonly name: TypeId; + readonly typeParams: typeParams | undefined; + readonly fields: structFields; + }>; + export type MessageDecl = $.Located<{ + readonly $: "MessageDecl"; + readonly opcode: expression | undefined; + readonly name: TypeId; + readonly fields: structFields; + }>; + export type UnionDecl = $.Located<{ + readonly $: "UnionDecl"; + readonly name: TypeId; + readonly typeParams: typeParams | undefined; + readonly cases: readonly Case[]; + }>; + export type AliasDecl = $.Located<{ + readonly $: "AliasDecl"; + readonly name: TypeId; + readonly typeParams: typeParams | undefined; + readonly type: $type; + }>; + export type Contract = $.Located<{ + readonly $: "Contract"; + readonly attributes: readonly ContractAttribute[]; + readonly name: TypeId; + readonly parameters: ParameterList | undefined; + readonly traits: inheritedTraits | undefined; + readonly declarations: readonly contractItemDecl[]; + }>; + export type Trait = $.Located<{ + readonly $: "Trait"; + readonly attributes: readonly ContractAttribute[]; + readonly name: TypeId; + readonly traits: inheritedTraits | undefined; + readonly declarations: readonly traitItemDecl[]; + }>; + export type moduleItem = + | PrimitiveTypeDecl + | $Function + | AsmFunction + | NativeFunctionDecl + | Constant + | StructDecl + | MessageDecl + | UnionDecl + | AliasDecl + | Contract + | Trait; + export type ContractInit = $.Located<{ + readonly $: "ContractInit"; + readonly parameters: parameterList; + readonly body: statements; + }>; + export type Receiver = $.Located<{ + readonly $: "Receiver"; + readonly type: ReceiverType; + readonly param: receiverParam; + readonly body: statements; + }>; + export type FieldDecl = $.Located<{ + readonly $: "FieldDecl"; + readonly name: Id; + readonly type: ascription; + readonly expression: expression | undefined; + }>; + export type semicolon = ";" | "}"; + export type storageVar = FieldDecl; + export type contractItemDecl = + | ContractInit + | Receiver + | $Function + | AsmFunction + | Constant + | storageVar; + export type traitItemDecl = + | Receiver + | $Function + | AsmFunction + | Constant + | storageVar; + export type FunctionDefinition = $.Located<{ + readonly $: "FunctionDefinition"; + readonly body: statements; + }>; + export type FunctionDeclaration = $.Located<{ + readonly $: "FunctionDeclaration"; + }>; + export type Id = $.Located<{ + readonly $: "Id"; + readonly name: string; + }>; + export type IntegerLiteralDec = $.Located<{ + readonly $: "IntegerLiteralDec"; + readonly digits: underscored; + }>; + export type shuffle = { + readonly ids: readonly Id[]; + readonly to: readonly IntegerLiteralDec[] | undefined; + }; + export type ConstantAttribute = $.Located<{ + readonly $: "ConstantAttribute"; + readonly name: + | keyword<"virtual"> + | keyword<"override"> + | keyword<"abstract">; + }>; + export type ConstantDefinition = $.Located<{ + readonly $: "ConstantDefinition"; + readonly expression: expression; + }>; + export type ConstantDeclaration = $.Located<{ + readonly $: "ConstantDeclaration"; + }>; + export type Case = $.Located<{ + readonly $: "Case"; + readonly name: TypeId; + readonly fields: structFields; + }>; + export type inter = { + readonly head: A; + readonly tail: readonly { + readonly op: B; + readonly right: A; + }[]; + }; + export type structFields = inter | undefined; + export type keyword = T; + export type commaList = inter; + export type TypeId = $.Located<{ + readonly $: "TypeId"; + readonly name: string; + }>; + export type inheritedTraits = commaList; + export type ContractAttribute = $.Located<{ + readonly $: "ContractAttribute"; + readonly name: StringLiteral; + }>; + export type FunctionAttribute = $.Located<{ + readonly $: "FunctionAttribute"; + readonly name: + | GetAttribute + | keyword<"mutates"> + | keyword<"extends"> + | keyword<"virtual"> + | keyword<"override"> + | keyword<"inline"> + | keyword<"abstract">; + }>; + export type GetAttribute = $.Located<{ + readonly $: "GetAttribute"; + readonly methodId: expression | undefined; + }>; + export type ReceiverType = $.Located<{ + readonly $: "ReceiverType"; + readonly name: "bounced" | keyword<"receive"> | keyword<"external">; + }>; + export type Parameter = $.Located<{ + readonly $: "Parameter"; + readonly name: Id; + readonly type: ascription; + }>; + export type StringLiteral = $.Located<{ + readonly $: "StringLiteral"; + readonly value: string; + }>; + export type receiverParam = Parameter | StringLiteral | undefined; + export type assembly = string; + export type multiLineComment = string; + export type singleLineComment = string; + export type comment = multiLineComment | singleLineComment; + export type assemblyItem = {} | comment | {} | readonly {}[]; + export type assemblySequence = readonly assemblyItem[]; + export type TypeAs = $.Located<{ + readonly $: "TypeAs"; + readonly type: TypeOptional; + readonly as: readonly storage[]; + }>; + export type $type = TypeAs; + export type ascription = $type; + export type TypeOptional = $.Located<{ + readonly $: "TypeOptional"; + readonly type: typePrimary; + readonly optionals: readonly Optional[]; + }>; + export type Optional = $.Located<{ + readonly $: "Optional"; + }>; + export type TypeGeneric = $.Located<{ + readonly $: "TypeGeneric"; + readonly name: MapKeyword | Bounced | TypeId; + readonly args: typeArgs; + }>; + export type TypeRegular = $.Located<{ + readonly $: "TypeRegular"; + readonly child: TypeId; + }>; + export type TypeStorage = $.Located<{ + readonly $: "TypeStorage"; + readonly child: storage; + }>; + export type TypeTuple = $.Located<{ + readonly $: "TypeTuple"; + readonly types: commaList<$type> | undefined; + }>; + export type TypeTensor = $.Located<{ + readonly $: "TypeTensor"; + readonly head: $type; + readonly tail: readonly $type[]; + }>; + export type TypeUnit = $.Located<{ + readonly $: "TypeUnit"; + }>; + export type typeParens = $type; + export type typePrimary = + | TypeGeneric + | TypeRegular + | TypeStorage + | TypeTuple + | TypeTensor + | TypeUnit + | typeParens; + export type MapKeyword = $.Located<{ + readonly $: "MapKeyword"; + }>; + export type Bounced = $.Located<{ + readonly $: "Bounced"; + }>; + export type IntStorage = $.Located<{ + readonly $: "IntStorage"; + readonly isVar: "var" | undefined; + readonly isUnsigned: "u" | undefined; + readonly width: string; + }>; + export type CoinsStorage = $.Located<{ + readonly $: "CoinsStorage"; + }>; + export type RemainingStorage = $.Located<{ + readonly $: "RemainingStorage"; + }>; + export type BytesStorage = $.Located<{ + readonly $: "BytesStorage"; + readonly width: string; + }>; + export type storage = + | IntStorage + | CoinsStorage + | RemainingStorage + | BytesStorage; + export type generic = commaList | undefined; + export type typeParams = generic; + export type typeArgs = generic<$type>; + export type StatementLet = $.Located<{ + readonly $: "StatementLet"; + readonly name: Id; + readonly type: ascription | undefined; + readonly init: expression; + }>; + export type StatementDestruct = $.Located<{ + readonly $: "StatementDestruct"; + readonly type: TypeId; + readonly fields: inter; + readonly rest: optionalRest; + readonly init: expression; + }>; + export type StatementBlock = $.Located<{ + readonly $: "StatementBlock"; + readonly body: statements; + }>; + export type StatementReturn = $.Located<{ + readonly $: "StatementReturn"; + readonly expression: expression | undefined; + }>; + export type StatementCondition = $.Located<{ + readonly $: "StatementCondition"; + readonly condition: expression; + readonly trueBranch: statements; + readonly falseBranch: FalseBranch | StatementCondition | undefined; + }>; + export type StatementWhile = $.Located<{ + readonly $: "StatementWhile"; + readonly condition: parens; + readonly body: statements; + }>; + export type StatementRepeat = $.Located<{ + readonly $: "StatementRepeat"; + readonly condition: parens; + readonly body: statements; + }>; + export type StatementUntil = $.Located<{ + readonly $: "StatementUntil"; + readonly body: statements; + readonly condition: parens; + }>; + export type StatementTry = $.Located<{ + readonly $: "StatementTry"; + readonly body: statements; + readonly handler: + | { + readonly name: Id; + readonly body: statements; + } + | undefined; + }>; + export type StatementForEach = $.Located<{ + readonly $: "StatementForEach"; + readonly key: Id; + readonly value: Id; + readonly expression: expression; + readonly body: statements; + }>; + export type StatementExpression = $.Located<{ + readonly $: "StatementExpression"; + readonly expression: expression; + }>; + export type StatementAssign = $.Located<{ + readonly $: "StatementAssign"; + readonly left: expression; + readonly operator: augmentedOp | "="; + readonly right: expression; + }>; + export type statement = + | StatementLet + | StatementDestruct + | StatementBlock + | StatementReturn + | StatementCondition + | StatementWhile + | StatementRepeat + | StatementUntil + | StatementTry + | StatementForEach + | StatementExpression + | StatementAssign; + export type statements = readonly statement[]; + export type augmentedOp = + | "||=" + | "&&=" + | ">>=" + | "<<=" + | "-=" + | "+=" + | "*=" + | "/=" + | "%=" + | "|=" + | "&=" + | "^="; + export type FalseBranch = $.Located<{ + readonly $: "FalseBranch"; + readonly body: statements; + }>; + export type RegularField = $.Located<{ + readonly $: "RegularField"; + readonly fieldName: Id; + readonly varName: Id; + }>; + export type PunnedField = $.Located<{ + readonly $: "PunnedField"; + readonly name: Id; + }>; + export type destructItem = RegularField | PunnedField; + export type RestArgument = $.Located<{ + readonly $: "RestArgument"; + }>; + export type NoRestArgument = $.Located<{ + readonly $: "NoRestArgument"; + }>; + export type optionalRest = RestArgument | NoRestArgument; + export type Conditional = $.Located<{ + readonly $: "Conditional"; + readonly head: or; + readonly tail: + | { + readonly thenBranch: or; + readonly elseBranch: Conditional; + } + | undefined; + }>; + export type expression = Conditional; + export type Binary = $.Located<{ + readonly $: "Binary"; + readonly exprs: inter>; + }>; + export type Unary = $.Located<{ + readonly $: "Unary"; + readonly prefixes: readonly Operator<"-" | "+" | "!" | "~">[]; + readonly expression: Suffix; + }>; + export type mul = Binary; + export type add = Binary; + export type bitwiseShift = Binary>">; + export type compare = Binary=" | ">">; + export type equality = Binary; + export type bitwiseXor = Binary; + export type bitwiseOr = Binary; + export type and = Binary; + export type or = Binary; + export type Suffix = $.Located<{ + readonly $: "Suffix"; + readonly expression: primary; + readonly suffixes: readonly suffix[]; + }>; + export type Operator = $.Located<{ + readonly $: "Operator"; + readonly name: U; + }>; + export type SuffixUnboxNotNull = $.Located<{ + readonly $: "SuffixUnboxNotNull"; + }>; + export type SuffixCall = $.Located<{ + readonly $: "SuffixCall"; + readonly typeArgs: typeArgs | undefined; + readonly params: parameterList; + }>; + export type SuffixFieldAccess = $.Located<{ + readonly $: "SuffixFieldAccess"; + readonly name: Id; + }>; + export type suffix = SuffixUnboxNotNull | SuffixCall | SuffixFieldAccess; + export type Unit = $.Located<{ + readonly $: "Unit"; + }>; + export type Tensor = $.Located<{ + readonly $: "Tensor"; + readonly head: expression; + readonly tail: readonly expression[]; + }>; + export type Tuple = $.Located<{ + readonly $: "Tuple"; + readonly types: commaList | undefined; + }>; + export type Parens = $.Located<{ + readonly $: "Parens"; + readonly child: parens; + }>; + export type StructInstance = $.Located<{ + readonly $: "StructInstance"; + readonly type: TypeId; + readonly typeArgs: typeArgs | undefined; + readonly fields: commaList | undefined; + }>; + export type IntegerLiteral = $.Located<{ + readonly $: "IntegerLiteral"; + readonly value: + | IntegerLiteralHex + | IntegerLiteralBin + | IntegerLiteralOct + | IntegerLiteralDec; + }>; + export type BoolLiteral = $.Located<{ + readonly $: "BoolLiteral"; + readonly value: "true" | "false"; + }>; + export type InitOf = $.Located<{ + readonly $: "InitOf"; + readonly name: TypeId; + readonly params: parameterList; + }>; + export type CodeOf = $.Located<{ + readonly $: "CodeOf"; + readonly name: TypeId; + }>; + export type Null = $.Located<{ + readonly $: "Null"; + }>; + export type primary = + | Unit + | Tensor + | Tuple + | Parens + | StructInstance + | IntegerLiteral + | BoolLiteral + | InitOf + | CodeOf + | Null + | StringLiteral + | Id; + export type parens = expression; + export type StructFieldInitializer = $.Located<{ + readonly $: "StructFieldInitializer"; + readonly name: Id; + readonly init: expression | undefined; + }>; + export type ParameterList = $.Located<{ + readonly $: "ParameterList"; + readonly values: commaList | undefined; + }>; + export type parameterList = commaList | undefined; + export type IntegerLiteralHex = $.Located<{ + readonly $: "IntegerLiteralHex"; + readonly digits: underscored; + }>; + export type IntegerLiteralBin = $.Located<{ + readonly $: "IntegerLiteralBin"; + readonly digits: underscored<"0" | "1">; + }>; + export type IntegerLiteralOct = $.Located<{ + readonly $: "IntegerLiteralOct"; + readonly digits: underscored; + }>; + export type underscored = string; + export type digit = string; + export type idPart = string | string | string | "_"; + export type FuncId = $.Located<{ + readonly $: "FuncId"; + readonly accessor: "." | "~" | undefined; + readonly id: string; + }>; + export type hexDigit = string | string | string; + export type escapeChar = + | "\\" + | '"' + | "n" + | "r" + | "t" + | "v" + | "b" + | "f" + | string + | string + | string; + export type reservedWord = keyword< + | "extend" + | "public" + | "fun" + | "let" + | "return" + | "receive" + | "native" + | "primitive" + | "null" + | "if" + | "else" + | "while" + | "repeat" + | "do" + | "until" + | "try" + | "catch" + | "foreach" + | "as" + | "map" + | "mutates" + | "extends" + | "external" + | "import" + | "with" + | "trait" + | "initOf" + | "override" + | "abstract" + | "virtual" + | "inline" + | "const" + >; + export type space = " " | "\t" | "\r" | "\n" | comment; + export type JustImports = $.Located<{ + readonly $: "JustImports"; + readonly imports: readonly Import[]; + }>; } -export const Module: $.Parser<$ast.Module> = $.loc($.field($.pure("Module"), "$", $.field($.star($.lazy(() => Import)), "imports", $.field($.star($.lazy(() => moduleItem)), "items", $.eps)))); -export const Import: $.Parser<$ast.Import> = $.loc($.field($.pure("Import"), "$", $.right($.lazy(() => keyword($.str("import"))), $.field($.lazy(() => StringLiteral), "path", $.right($.str(";"), $.eps))))); -export const PrimitiveTypeDecl: $.Parser<$ast.PrimitiveTypeDecl> = $.loc($.field($.pure("PrimitiveTypeDecl"), "$", $.right($.lazy(() => keyword($.str("primitive"))), $.field($.lazy(() => TypeId), "name", $.right($.str(";"), $.eps))))); -export const $Function: $.Parser<$ast.$Function> = $.loc($.field($.pure("Function"), "$", $.field($.star($.lazy(() => FunctionAttribute)), "attributes", $.right($.lazy(() => keyword($.str("fun"))), $.field($.lazy(() => Id), "name", $.field($.opt($.lazy(() => typeParams)), "typeParams", $.field($.lazy(() => parameterList($.lazy(() => Parameter))), "parameters", $.field($.opt($.lazy(() => ascription)), "returnType", $.field($.alt($.lazy(() => FunctionDefinition), $.lazy(() => FunctionDeclaration)), "body", $.eps))))))))); -export const AsmFunction: $.Parser<$ast.AsmFunction> = $.loc($.field($.pure("AsmFunction"), "$", $.right($.str("asm"), $.field($.opt($.lazy(() => shuffle)), "shuffle", $.field($.star($.lazy(() => FunctionAttribute)), "attributes", $.right($.lazy(() => keyword($.str("fun"))), $.field($.lazy(() => Id), "name", $.field($.opt($.lazy(() => typeParams)), "typeParams", $.field($.lazy(() => parameterList($.lazy(() => Parameter))), "parameters", $.field($.opt($.lazy(() => ascription)), "returnType", $.right($.str("{"), $.field($.lazy(() => assembly), "instructions", $.right($.str("}"), $.eps))))))))))))); -export const NativeFunctionDecl: $.Parser<$ast.NativeFunctionDecl> = $.loc($.field($.pure("NativeFunctionDecl"), "$", $.right($.str("@name"), $.right($.str("("), $.field($.lex($.lazy(() => FuncId)), "nativeName", $.right($.str(")"), $.field($.star($.lazy(() => FunctionAttribute)), "attributes", $.right($.lazy(() => keyword($.str("native"))), $.field($.lazy(() => Id), "name", $.field($.opt($.lazy(() => typeParams)), "typeParams", $.field($.lazy(() => parameterList($.lazy(() => Parameter))), "parameters", $.field($.opt($.lazy(() => ascription)), "returnType", $.right($.str(";"), $.eps))))))))))))); -export const Constant: $.Parser<$ast.Constant> = $.loc($.field($.pure("Constant"), "$", $.field($.star($.lazy(() => ConstantAttribute)), "attributes", $.right($.lazy(() => keyword($.str("const"))), $.field($.lazy(() => Id), "name", $.field($.opt($.lazy(() => ascription)), "type", $.field($.alt($.lazy(() => ConstantDefinition), $.lazy(() => ConstantDeclaration)), "body", $.eps))))))); -export const StructDecl: $.Parser<$ast.StructDecl> = $.loc($.field($.pure("StructDecl"), "$", $.right($.str("struct"), $.field($.lazy(() => TypeId), "name", $.field($.opt($.lazy(() => typeParams)), "typeParams", $.right($.str("{"), $.field($.lazy(() => structFields), "fields", $.right($.str("}"), $.eps)))))))); -export const MessageDecl: $.Parser<$ast.MessageDecl> = $.loc($.field($.pure("MessageDecl"), "$", $.right($.str("message"), $.field($.opt($.right($.str("("), $.left($.lazy(() => expression), $.str(")")))), "opcode", $.field($.lazy(() => TypeId), "name", $.right($.str("{"), $.field($.lazy(() => structFields), "fields", $.right($.str("}"), $.eps)))))))); -export const UnionDecl: $.Parser<$ast.UnionDecl> = $.loc($.field($.pure("UnionDecl"), "$", $.right($.str("union"), $.field($.lazy(() => TypeId), "name", $.field($.opt($.lazy(() => typeParams)), "typeParams", $.right($.str("{"), $.field($.star($.lazy(() => Case)), "cases", $.right($.str("}"), $.eps)))))))); -export const AliasDecl: $.Parser<$ast.AliasDecl> = $.loc($.field($.pure("AliasDecl"), "$", $.right($.str("type"), $.field($.lazy(() => TypeId), "name", $.field($.opt($.lazy(() => typeParams)), "typeParams", $.right($.str("="), $.field($.lazy(() => $type), "type", $.right($.str(";"), $.eps)))))))); -export const Contract: $.Parser<$ast.Contract> = $.loc($.field($.pure("Contract"), "$", $.field($.star($.lazy(() => ContractAttribute)), "attributes", $.right($.lazy(() => keyword($.str("contract"))), $.field($.lazy(() => TypeId), "name", $.field($.opt($.lazy(() => ParameterList($.lazy(() => Parameter)))), "parameters", $.field($.opt($.lazy(() => inheritedTraits)), "traits", $.right($.str("{"), $.field($.star($.lazy(() => contractItemDecl)), "declarations", $.right($.str("}"), $.eps)))))))))); -export const Trait: $.Parser<$ast.Trait> = $.loc($.field($.pure("Trait"), "$", $.field($.star($.lazy(() => ContractAttribute)), "attributes", $.right($.lazy(() => keyword($.str("trait"))), $.field($.lazy(() => TypeId), "name", $.field($.opt($.lazy(() => inheritedTraits)), "traits", $.right($.str("{"), $.field($.star($.lazy(() => traitItemDecl)), "declarations", $.right($.str("}"), $.eps))))))))); -export const moduleItem: $.Parser<$ast.moduleItem> = $.alt(PrimitiveTypeDecl, $.alt($Function, $.alt(AsmFunction, $.alt(NativeFunctionDecl, $.alt(Constant, $.alt(StructDecl, $.alt(MessageDecl, $.alt(UnionDecl, $.alt(AliasDecl, $.alt(Contract, Trait)))))))))); -export const ContractInit: $.Parser<$ast.ContractInit> = $.loc($.field($.pure("ContractInit"), "$", $.right($.str("init"), $.field($.lazy(() => parameterList($.lazy(() => Parameter))), "parameters", $.field($.lazy(() => statements), "body", $.eps))))); -export const Receiver: $.Parser<$ast.Receiver> = $.loc($.field($.pure("Receiver"), "$", $.field($.lazy(() => ReceiverType), "type", $.right($.str("("), $.field($.lazy(() => receiverParam), "param", $.right($.str(")"), $.field($.lazy(() => statements), "body", $.eps))))))); -export const FieldDecl: $.Parser<$ast.FieldDecl> = $.loc($.field($.pure("FieldDecl"), "$", $.field($.lazy(() => Id), "name", $.field($.lazy(() => ascription), "type", $.field($.opt($.right($.str("="), $.lazy(() => expression))), "expression", $.eps))))); -export const semicolon: $.Parser<$ast.semicolon> = $.alt($.str(";"), $.lookPos($.str("}"))); -export const storageVar: $.Parser<$ast.storageVar> = $.left(FieldDecl, semicolon); -export const contractItemDecl: $.Parser<$ast.contractItemDecl> = $.alt(ContractInit, $.alt(Receiver, $.alt($Function, $.alt(AsmFunction, $.alt(Constant, storageVar))))); -export const traitItemDecl: $.Parser<$ast.traitItemDecl> = $.alt(Receiver, $.alt($Function, $.alt(AsmFunction, $.alt(Constant, storageVar)))); -export const FunctionDefinition: $.Parser<$ast.FunctionDefinition> = $.loc($.field($.pure("FunctionDefinition"), "$", $.field($.lazy(() => statements), "body", $.eps))); -export const FunctionDeclaration: $.Parser<$ast.FunctionDeclaration> = $.loc($.field($.pure("FunctionDeclaration"), "$", $.right(semicolon, $.eps))); -export const Id: $.Parser<$ast.Id> = $.named("identifier", $.loc($.field($.pure("Id"), "$", $.field($.lex($.stry($.right($.lookNeg($.lazy(() => reservedWord)), $.right($.alt($.right($.regex("a-zA-Z_", [$.ExpRange("a", "z"), $.ExpRange("A", "Z"), $.ExpString("_")]), $.right($.star($.lazy(() => idPart)), $.eps)), $.str("$")), $.eps)))), "name", $.eps)))); -export const IntegerLiteralDec: $.Parser<$ast.IntegerLiteralDec> = $.loc($.field($.pure("IntegerLiteralDec"), "$", $.field($.lex($.lazy(() => underscored($.lazy(() => digit)))), "digits", $.eps))); -export const shuffle: $.Parser<$ast.shuffle> = $.right($.str("("), $.field($.star(Id), "ids", $.field($.opt($.right($.str("->"), $.plus(IntegerLiteralDec))), "to", $.right($.str(")"), $.eps)))); -export const ConstantAttribute: $.Parser<$ast.ConstantAttribute> = $.loc($.field($.pure("ConstantAttribute"), "$", $.field($.alt($.lazy(() => keyword($.str("virtual"))), $.alt($.lazy(() => keyword($.str("override"))), $.lazy(() => keyword($.str("abstract"))))), "name", $.eps))); -export const ConstantDefinition: $.Parser<$ast.ConstantDefinition> = $.loc($.field($.pure("ConstantDefinition"), "$", $.right($.str("="), $.field($.lazy(() => expression), "expression", $.right(semicolon, $.eps))))); -export const ConstantDeclaration: $.Parser<$ast.ConstantDeclaration> = $.loc($.field($.pure("ConstantDeclaration"), "$", $.right(semicolon, $.eps))); -export const Case: $.Parser<$ast.Case> = $.loc($.field($.pure("Case"), "$", $.field($.lazy(() => TypeId), "name", $.right($.str("{"), $.field($.lazy(() => structFields), "fields", $.right($.str("}"), $.eps)))))); -export const inter = (A: $.Parser, B: $.Parser): $.Parser<$ast.inter> => $.field($.lazy(() => A), "head", $.field($.star($.field($.lazy(() => B), "op", $.field($.lazy(() => A), "right", $.eps))), "tail", $.eps)); -export const structFields: $.Parser<$ast.structFields> = $.left($.opt(inter(FieldDecl, $.str(";"))), $.opt($.str(";"))); -export const keyword = (T: $.Parser): $.Parser<$ast.keyword> => $.lex($.left($.lazy(() => T), $.lookNeg($.lazy(() => idPart)))); -export const commaList = (T: $.Parser): $.Parser<$ast.commaList> => $.left(inter($.lazy(() => T), $.str(",")), $.opt($.str(","))); -export const TypeId: $.Parser<$ast.TypeId> = $.named("capitalized identifier", $.loc($.field($.pure("TypeId"), "$", $.field($.lex($.stry($.right($.regex("A-Z", [$.ExpRange("A", "Z")]), $.right($.star($.regex("a-zA-Z0-9_", [$.ExpRange("a", "z"), $.ExpRange("A", "Z"), $.ExpRange("0", "9"), $.ExpString("_")])), $.eps)))), "name", $.eps)))); -export const inheritedTraits: $.Parser<$ast.inheritedTraits> = $.right(keyword($.str("with")), commaList(TypeId)); -export const ContractAttribute: $.Parser<$ast.ContractAttribute> = $.loc($.field($.pure("ContractAttribute"), "$", $.right($.str("@interface"), $.right($.str("("), $.field($.lazy(() => StringLiteral), "name", $.right($.str(")"), $.eps)))))); -export const FunctionAttribute: $.Parser<$ast.FunctionAttribute> = $.loc($.field($.pure("FunctionAttribute"), "$", $.field($.alt($.lazy(() => GetAttribute), $.alt(keyword($.str("mutates")), $.alt(keyword($.str("extends")), $.alt(keyword($.str("virtual")), $.alt(keyword($.str("override")), $.alt(keyword($.str("inline")), keyword($.str("abstract")))))))), "name", $.eps))); -export const GetAttribute: $.Parser<$ast.GetAttribute> = $.loc($.field($.pure("GetAttribute"), "$", $.right($.str("get"), $.field($.opt($.right($.str("("), $.left($.lazy(() => expression), $.str(")")))), "methodId", $.eps)))); -export const ReceiverType: $.Parser<$ast.ReceiverType> = $.loc($.field($.pure("ReceiverType"), "$", $.field($.alt($.str("bounced"), $.alt(keyword($.str("receive")), keyword($.str("external")))), "name", $.eps))); -export const Parameter: $.Parser<$ast.Parameter> = $.loc($.field($.pure("Parameter"), "$", $.field(Id, "name", $.field($.lazy(() => ascription), "type", $.eps)))); -export const StringLiteral: $.Parser<$ast.StringLiteral> = $.loc($.field($.pure("StringLiteral"), "$", $.field($.lex($.right($.str("\""), $.left($.stry($.star($.alt($.regex<"\"" | "\\">("^\"\\\\", $.negateExps([$.ExpString("\""), $.ExpString("\\")])), $.right($.str("\\"), $.lazy(() => escapeChar))))), $.str("\"")))), "value", $.eps))); -export const receiverParam: $.Parser<$ast.receiverParam> = $.opt($.alt(Parameter, StringLiteral)); -export const assembly: $.Parser<$ast.assembly> = $.lex($.stry($.lazy(() => assemblySequence))); -export const multiLineComment: $.Parser<$ast.multiLineComment> = $.right($.str("/*"), $.left($.stry($.star($.right($.lookNeg($.str("*/")), $.right($.any, $.eps)))), $.str("*/"))); -export const singleLineComment: $.Parser<$ast.singleLineComment> = $.right($.str("//"), $.stry($.star($.regex<"\r" | "\n">("^\\r\\n", $.negateExps([$.ExpString("\r"), $.ExpString("\n")]))))); -export const comment: $.Parser<$ast.comment> = $.alt(multiLineComment, singleLineComment); -export const assemblyItem: $.Parser<$ast.assemblyItem> = $.alt($.right($.str("{"), $.right($.lazy(() => assemblySequence), $.right($.str("}"), $.eps))), $.alt(comment, $.alt($.right($.str("\""), $.right($.star($.regex<"\"">("^\"", $.negateExps([$.ExpString("\"")]))), $.right($.str("\""), $.eps))), $.plus($.right($.lookNeg($.alt($.regex<"\"" | "{" | "}">("\"{}", [$.ExpString("\""), $.ExpString("{"), $.ExpString("}")]), $.alt($.str("//"), $.str("/*")))), $.right($.any, $.eps)))))); -export const assemblySequence: $.Parser<$ast.assemblySequence> = $.star(assemblyItem); -export const TypeAs: $.Parser<$ast.TypeAs> = $.loc($.field($.pure("TypeAs"), "$", $.field($.lazy(() => TypeOptional), "type", $.field($.star($.right(keyword($.str("as")), $.lex($.lazy(() => storage)))), "as", $.eps)))); +export const Module: $.Parser<$ast.Module> = $.loc( + $.field( + $.pure("Module"), + "$", + $.field( + $.star($.lazy(() => Import)), + "imports", + $.field($.star($.lazy(() => moduleItem)), "items", $.eps), + ), + ), +); +export const Import: $.Parser<$ast.Import> = $.loc( + $.field( + $.pure("Import"), + "$", + $.right( + $.lazy(() => keyword($.str("import"))), + $.field( + $.lazy(() => StringLiteral), + "path", + $.right($.str(";"), $.eps), + ), + ), + ), +); +export const PrimitiveTypeDecl: $.Parser<$ast.PrimitiveTypeDecl> = $.loc( + $.field( + $.pure("PrimitiveTypeDecl"), + "$", + $.right( + $.lazy(() => keyword($.str("primitive"))), + $.field( + $.lazy(() => TypeId), + "name", + $.right($.str(";"), $.eps), + ), + ), + ), +); +export const $Function: $.Parser<$ast.$Function> = $.loc( + $.field( + $.pure("Function"), + "$", + $.field( + $.star($.lazy(() => FunctionAttribute)), + "attributes", + $.right( + $.lazy(() => keyword($.str("fun"))), + $.field( + $.lazy(() => Id), + "name", + $.field( + $.opt($.lazy(() => typeParams)), + "typeParams", + $.field( + $.lazy(() => + parameterList($.lazy(() => Parameter)), + ), + "parameters", + $.field( + $.opt($.lazy(() => ascription)), + "returnType", + $.field( + $.alt( + $.lazy(() => FunctionDefinition), + $.lazy(() => FunctionDeclaration), + ), + "body", + $.eps, + ), + ), + ), + ), + ), + ), + ), + ), +); +export const AsmFunction: $.Parser<$ast.AsmFunction> = $.loc( + $.field( + $.pure("AsmFunction"), + "$", + $.right( + $.str("asm"), + $.field( + $.opt($.lazy(() => shuffle)), + "shuffle", + $.field( + $.star($.lazy(() => FunctionAttribute)), + "attributes", + $.right( + $.lazy(() => keyword($.str("fun"))), + $.field( + $.lazy(() => Id), + "name", + $.field( + $.opt($.lazy(() => typeParams)), + "typeParams", + $.field( + $.lazy(() => + parameterList($.lazy(() => Parameter)), + ), + "parameters", + $.field( + $.opt($.lazy(() => ascription)), + "returnType", + $.right( + $.str("{"), + $.field( + $.lazy(() => assembly), + "instructions", + $.right($.str("}"), $.eps), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), +); +export const NativeFunctionDecl: $.Parser<$ast.NativeFunctionDecl> = $.loc( + $.field( + $.pure("NativeFunctionDecl"), + "$", + $.right( + $.str("@name"), + $.right( + $.str("("), + $.field( + $.lex($.lazy(() => FuncId)), + "nativeName", + $.right( + $.str(")"), + $.field( + $.star($.lazy(() => FunctionAttribute)), + "attributes", + $.right( + $.lazy(() => keyword($.str("native"))), + $.field( + $.lazy(() => Id), + "name", + $.field( + $.opt($.lazy(() => typeParams)), + "typeParams", + $.field( + $.lazy(() => + parameterList( + $.lazy(() => Parameter), + ), + ), + "parameters", + $.field( + $.opt($.lazy(() => ascription)), + "returnType", + $.right($.str(";"), $.eps), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), +); +export const Constant: $.Parser<$ast.Constant> = $.loc( + $.field( + $.pure("Constant"), + "$", + $.field( + $.star($.lazy(() => ConstantAttribute)), + "attributes", + $.right( + $.lazy(() => keyword($.str("const"))), + $.field( + $.lazy(() => Id), + "name", + $.field( + $.opt($.lazy(() => ascription)), + "type", + $.field( + $.alt( + $.lazy(() => ConstantDefinition), + $.lazy(() => ConstantDeclaration), + ), + "body", + $.eps, + ), + ), + ), + ), + ), + ), +); +export const StructDecl: $.Parser<$ast.StructDecl> = $.loc( + $.field( + $.pure("StructDecl"), + "$", + $.right( + $.str("struct"), + $.field( + $.lazy(() => TypeId), + "name", + $.field( + $.opt($.lazy(() => typeParams)), + "typeParams", + $.right( + $.str("{"), + $.field( + $.lazy(() => structFields), + "fields", + $.right($.str("}"), $.eps), + ), + ), + ), + ), + ), + ), +); +export const MessageDecl: $.Parser<$ast.MessageDecl> = $.loc( + $.field( + $.pure("MessageDecl"), + "$", + $.right( + $.str("message"), + $.field( + $.opt( + $.right( + $.str("("), + $.left( + $.lazy(() => expression), + $.str(")"), + ), + ), + ), + "opcode", + $.field( + $.lazy(() => TypeId), + "name", + $.right( + $.str("{"), + $.field( + $.lazy(() => structFields), + "fields", + $.right($.str("}"), $.eps), + ), + ), + ), + ), + ), + ), +); +export const UnionDecl: $.Parser<$ast.UnionDecl> = $.loc( + $.field( + $.pure("UnionDecl"), + "$", + $.right( + $.str("union"), + $.field( + $.lazy(() => TypeId), + "name", + $.field( + $.opt($.lazy(() => typeParams)), + "typeParams", + $.right( + $.str("{"), + $.field( + $.star($.lazy(() => Case)), + "cases", + $.right($.str("}"), $.eps), + ), + ), + ), + ), + ), + ), +); +export const AliasDecl: $.Parser<$ast.AliasDecl> = $.loc( + $.field( + $.pure("AliasDecl"), + "$", + $.right( + $.str("type"), + $.field( + $.lazy(() => TypeId), + "name", + $.field( + $.opt($.lazy(() => typeParams)), + "typeParams", + $.right( + $.str("="), + $.field( + $.lazy(() => $type), + "type", + $.right($.str(";"), $.eps), + ), + ), + ), + ), + ), + ), +); +export const Contract: $.Parser<$ast.Contract> = $.loc( + $.field( + $.pure("Contract"), + "$", + $.field( + $.star($.lazy(() => ContractAttribute)), + "attributes", + $.right( + $.lazy(() => keyword($.str("contract"))), + $.field( + $.lazy(() => TypeId), + "name", + $.field( + $.opt( + $.lazy(() => + ParameterList($.lazy(() => Parameter)), + ), + ), + "parameters", + $.field( + $.opt($.lazy(() => inheritedTraits)), + "traits", + $.right( + $.str("{"), + $.field( + $.star($.lazy(() => contractItemDecl)), + "declarations", + $.right($.str("}"), $.eps), + ), + ), + ), + ), + ), + ), + ), + ), +); +export const Trait: $.Parser<$ast.Trait> = $.loc( + $.field( + $.pure("Trait"), + "$", + $.field( + $.star($.lazy(() => ContractAttribute)), + "attributes", + $.right( + $.lazy(() => keyword($.str("trait"))), + $.field( + $.lazy(() => TypeId), + "name", + $.field( + $.opt($.lazy(() => inheritedTraits)), + "traits", + $.right( + $.str("{"), + $.field( + $.star($.lazy(() => traitItemDecl)), + "declarations", + $.right($.str("}"), $.eps), + ), + ), + ), + ), + ), + ), + ), +); +export const moduleItem: $.Parser<$ast.moduleItem> = $.alt( + PrimitiveTypeDecl, + $.alt( + $Function, + $.alt( + AsmFunction, + $.alt( + NativeFunctionDecl, + $.alt( + Constant, + $.alt( + StructDecl, + $.alt( + MessageDecl, + $.alt( + UnionDecl, + $.alt(AliasDecl, $.alt(Contract, Trait)), + ), + ), + ), + ), + ), + ), + ), +); +export const ContractInit: $.Parser<$ast.ContractInit> = $.loc( + $.field( + $.pure("ContractInit"), + "$", + $.right( + $.str("init"), + $.field( + $.lazy(() => parameterList($.lazy(() => Parameter))), + "parameters", + $.field( + $.lazy(() => statements), + "body", + $.eps, + ), + ), + ), + ), +); +export const Receiver: $.Parser<$ast.Receiver> = $.loc( + $.field( + $.pure("Receiver"), + "$", + $.field( + $.lazy(() => ReceiverType), + "type", + $.right( + $.str("("), + $.field( + $.lazy(() => receiverParam), + "param", + $.right( + $.str(")"), + $.field( + $.lazy(() => statements), + "body", + $.eps, + ), + ), + ), + ), + ), + ), +); +export const FieldDecl: $.Parser<$ast.FieldDecl> = $.loc( + $.field( + $.pure("FieldDecl"), + "$", + $.field( + $.lazy(() => Id), + "name", + $.field( + $.lazy(() => ascription), + "type", + $.field( + $.opt( + $.right( + $.str("="), + $.lazy(() => expression), + ), + ), + "expression", + $.eps, + ), + ), + ), + ), +); +export const semicolon: $.Parser<$ast.semicolon> = $.alt( + $.str(";"), + $.lookPos($.str("}")), +); +export const storageVar: $.Parser<$ast.storageVar> = $.left( + FieldDecl, + semicolon, +); +export const contractItemDecl: $.Parser<$ast.contractItemDecl> = $.alt( + ContractInit, + $.alt( + Receiver, + $.alt($Function, $.alt(AsmFunction, $.alt(Constant, storageVar))), + ), +); +export const traitItemDecl: $.Parser<$ast.traitItemDecl> = $.alt( + Receiver, + $.alt($Function, $.alt(AsmFunction, $.alt(Constant, storageVar))), +); +export const FunctionDefinition: $.Parser<$ast.FunctionDefinition> = $.loc( + $.field( + $.pure("FunctionDefinition"), + "$", + $.field( + $.lazy(() => statements), + "body", + $.eps, + ), + ), +); +export const FunctionDeclaration: $.Parser<$ast.FunctionDeclaration> = $.loc( + $.field($.pure("FunctionDeclaration"), "$", $.right(semicolon, $.eps)), +); +export const Id: $.Parser<$ast.Id> = $.named( + "identifier", + $.loc( + $.field( + $.pure("Id"), + "$", + $.field( + $.lex( + $.stry( + $.right( + $.lookNeg($.lazy(() => reservedWord)), + $.right( + $.alt( + $.right( + $.regex( + "a-zA-Z_", + [ + $.ExpRange("a", "z"), + $.ExpRange("A", "Z"), + $.ExpString("_"), + ], + ), + $.right( + $.star($.lazy(() => idPart)), + $.eps, + ), + ), + $.str("$"), + ), + $.eps, + ), + ), + ), + ), + "name", + $.eps, + ), + ), + ), +); +export const IntegerLiteralDec: $.Parser<$ast.IntegerLiteralDec> = $.loc( + $.field( + $.pure("IntegerLiteralDec"), + "$", + $.field( + $.lex($.lazy(() => underscored($.lazy(() => digit)))), + "digits", + $.eps, + ), + ), +); +export const shuffle: $.Parser<$ast.shuffle> = $.right( + $.str("("), + $.field( + $.star(Id), + "ids", + $.field( + $.opt($.right($.str("->"), $.plus(IntegerLiteralDec))), + "to", + $.right($.str(")"), $.eps), + ), + ), +); +export const ConstantAttribute: $.Parser<$ast.ConstantAttribute> = $.loc( + $.field( + $.pure("ConstantAttribute"), + "$", + $.field( + $.alt( + $.lazy(() => keyword($.str("virtual"))), + $.alt( + $.lazy(() => keyword($.str("override"))), + $.lazy(() => keyword($.str("abstract"))), + ), + ), + "name", + $.eps, + ), + ), +); +export const ConstantDefinition: $.Parser<$ast.ConstantDefinition> = $.loc( + $.field( + $.pure("ConstantDefinition"), + "$", + $.right( + $.str("="), + $.field( + $.lazy(() => expression), + "expression", + $.right(semicolon, $.eps), + ), + ), + ), +); +export const ConstantDeclaration: $.Parser<$ast.ConstantDeclaration> = $.loc( + $.field($.pure("ConstantDeclaration"), "$", $.right(semicolon, $.eps)), +); +export const Case: $.Parser<$ast.Case> = $.loc( + $.field( + $.pure("Case"), + "$", + $.field( + $.lazy(() => TypeId), + "name", + $.right( + $.str("{"), + $.field( + $.lazy(() => structFields), + "fields", + $.right($.str("}"), $.eps), + ), + ), + ), + ), +); +export const inter = ( + A: $.Parser, + B: $.Parser, +): $.Parser<$ast.inter> => + $.field( + $.lazy(() => A), + "head", + $.field( + $.star( + $.field( + $.lazy(() => B), + "op", + $.field( + $.lazy(() => A), + "right", + $.eps, + ), + ), + ), + "tail", + $.eps, + ), + ); +export const structFields: $.Parser<$ast.structFields> = $.left( + $.opt(inter(FieldDecl, $.str(";"))), + $.opt($.str(";")), +); +export const keyword = (T: $.Parser): $.Parser<$ast.keyword> => + $.lex( + $.left( + $.lazy(() => T), + $.lookNeg($.lazy(() => idPart)), + ), + ); +export const commaList = (T: $.Parser): $.Parser<$ast.commaList> => + $.left( + inter( + $.lazy(() => T), + $.str(","), + ), + $.opt($.str(",")), + ); +export const TypeId: $.Parser<$ast.TypeId> = $.named( + "capitalized identifier", + $.loc( + $.field( + $.pure("TypeId"), + "$", + $.field( + $.lex( + $.stry( + $.right( + $.regex("A-Z", [$.ExpRange("A", "Z")]), + $.right( + $.star( + $.regex( + "a-zA-Z0-9_", + [ + $.ExpRange("a", "z"), + $.ExpRange("A", "Z"), + $.ExpRange("0", "9"), + $.ExpString("_"), + ], + ), + ), + $.eps, + ), + ), + ), + ), + "name", + $.eps, + ), + ), + ), +); +export const inheritedTraits: $.Parser<$ast.inheritedTraits> = $.right( + keyword($.str("with")), + commaList(TypeId), +); +export const ContractAttribute: $.Parser<$ast.ContractAttribute> = $.loc( + $.field( + $.pure("ContractAttribute"), + "$", + $.right( + $.str("@interface"), + $.right( + $.str("("), + $.field( + $.lazy(() => StringLiteral), + "name", + $.right($.str(")"), $.eps), + ), + ), + ), + ), +); +export const FunctionAttribute: $.Parser<$ast.FunctionAttribute> = $.loc( + $.field( + $.pure("FunctionAttribute"), + "$", + $.field( + $.alt( + $.lazy(() => GetAttribute), + $.alt( + keyword($.str("mutates")), + $.alt( + keyword($.str("extends")), + $.alt( + keyword($.str("virtual")), + $.alt( + keyword($.str("override")), + $.alt( + keyword($.str("inline")), + keyword($.str("abstract")), + ), + ), + ), + ), + ), + ), + "name", + $.eps, + ), + ), +); +export const GetAttribute: $.Parser<$ast.GetAttribute> = $.loc( + $.field( + $.pure("GetAttribute"), + "$", + $.right( + $.str("get"), + $.field( + $.opt( + $.right( + $.str("("), + $.left( + $.lazy(() => expression), + $.str(")"), + ), + ), + ), + "methodId", + $.eps, + ), + ), + ), +); +export const ReceiverType: $.Parser<$ast.ReceiverType> = $.loc( + $.field( + $.pure("ReceiverType"), + "$", + $.field( + $.alt( + $.str("bounced"), + $.alt(keyword($.str("receive")), keyword($.str("external"))), + ), + "name", + $.eps, + ), + ), +); +export const Parameter: $.Parser<$ast.Parameter> = $.loc( + $.field( + $.pure("Parameter"), + "$", + $.field( + Id, + "name", + $.field( + $.lazy(() => ascription), + "type", + $.eps, + ), + ), + ), +); +export const StringLiteral: $.Parser<$ast.StringLiteral> = $.loc( + $.field( + $.pure("StringLiteral"), + "$", + $.field( + $.lex( + $.right( + $.str('"'), + $.left( + $.stry( + $.star( + $.alt( + $.regex<'"' | "\\">( + '^"\\\\', + $.negateExps([ + $.ExpString('"'), + $.ExpString("\\"), + ]), + ), + $.right( + $.str("\\"), + $.lazy(() => escapeChar), + ), + ), + ), + ), + $.str('"'), + ), + ), + ), + "value", + $.eps, + ), + ), +); +export const receiverParam: $.Parser<$ast.receiverParam> = $.opt( + $.alt(Parameter, StringLiteral), +); +export const assembly: $.Parser<$ast.assembly> = $.lex( + $.stry($.lazy(() => assemblySequence)), +); +export const multiLineComment: $.Parser<$ast.multiLineComment> = $.right( + $.str("/*"), + $.left( + $.stry($.star($.right($.lookNeg($.str("*/")), $.right($.any, $.eps)))), + $.str("*/"), + ), +); +export const singleLineComment: $.Parser<$ast.singleLineComment> = $.right( + $.str("//"), + $.stry( + $.star( + $.regex<"\r" | "\n">( + "^\\r\\n", + $.negateExps([$.ExpString("\r"), $.ExpString("\n")]), + ), + ), + ), +); +export const comment: $.Parser<$ast.comment> = $.alt( + multiLineComment, + singleLineComment, +); +export const assemblyItem: $.Parser<$ast.assemblyItem> = $.alt( + $.right( + $.str("{"), + $.right( + $.lazy(() => assemblySequence), + $.right($.str("}"), $.eps), + ), + ), + $.alt( + comment, + $.alt( + $.right( + $.str('"'), + $.right( + $.star( + $.regex<'"'>('^"', $.negateExps([$.ExpString('"')])), + ), + $.right($.str('"'), $.eps), + ), + ), + $.plus( + $.right( + $.lookNeg( + $.alt( + $.regex<'"' | "{" | "}">('"{}', [ + $.ExpString('"'), + $.ExpString("{"), + $.ExpString("}"), + ]), + $.alt($.str("//"), $.str("/*")), + ), + ), + $.right($.any, $.eps), + ), + ), + ), + ), +); +export const assemblySequence: $.Parser<$ast.assemblySequence> = + $.star(assemblyItem); +export const TypeAs: $.Parser<$ast.TypeAs> = $.loc( + $.field( + $.pure("TypeAs"), + "$", + $.field( + $.lazy(() => TypeOptional), + "type", + $.field( + $.star( + $.right(keyword($.str("as")), $.lex($.lazy(() => storage))), + ), + "as", + $.eps, + ), + ), + ), +); export const $type: $.Parser<$ast.$type> = TypeAs; export const ascription: $.Parser<$ast.ascription> = $.right($.str(":"), $type); -export const TypeOptional: $.Parser<$ast.TypeOptional> = $.loc($.field($.pure("TypeOptional"), "$", $.field($.lazy(() => typePrimary), "type", $.field($.star($.lazy(() => Optional)), "optionals", $.eps)))); -export const Optional: $.Parser<$ast.Optional> = $.loc($.field($.pure("Optional"), "$", $.right($.str("?"), $.eps))); -export const TypeGeneric: $.Parser<$ast.TypeGeneric> = $.loc($.field($.pure("TypeGeneric"), "$", $.field($.alt($.lazy(() => MapKeyword), $.alt($.lazy(() => Bounced), TypeId)), "name", $.field($.lazy(() => typeArgs), "args", $.eps)))); -export const TypeRegular: $.Parser<$ast.TypeRegular> = $.loc($.field($.pure("TypeRegular"), "$", $.field(TypeId, "child", $.eps))); -export const TypeStorage: $.Parser<$ast.TypeStorage> = $.loc($.field($.pure("TypeStorage"), "$", $.field($.lazy(() => storage), "child", $.eps))); -export const TypeTuple: $.Parser<$ast.TypeTuple> = $.loc($.field($.pure("TypeTuple"), "$", $.right($.str("["), $.field($.opt(commaList($type)), "types", $.right($.str("]"), $.eps))))); -export const TypeTensor: $.Parser<$ast.TypeTensor> = $.loc($.field($.pure("TypeTensor"), "$", $.right($.str("("), $.field($type, "head", $.field($.plus($.right($.str(","), $type)), "tail", $.right($.opt($.str(",")), $.right($.str(")"), $.eps))))))); -export const TypeUnit: $.Parser<$ast.TypeUnit> = $.loc($.field($.pure("TypeUnit"), "$", $.right($.right($.str("("), $.right($.str(")"), $.eps)), $.eps))); -export const typeParens: $.Parser<$ast.typeParens> = $.right($.str("("), $.left($type, $.str(")"))); -export const typePrimary: $.Parser<$ast.typePrimary> = $.alt(TypeGeneric, $.alt(TypeRegular, $.alt(TypeStorage, $.alt(TypeTuple, $.alt(TypeTensor, $.alt(TypeUnit, typeParens)))))); -export const MapKeyword: $.Parser<$ast.MapKeyword> = $.loc($.field($.pure("MapKeyword"), "$", $.right(keyword($.str("map")), $.eps))); -export const Bounced: $.Parser<$ast.Bounced> = $.loc($.field($.pure("Bounced"), "$", $.right($.str("bounced"), $.eps))); -export const IntStorage: $.Parser<$ast.IntStorage> = $.loc($.field($.pure("IntStorage"), "$", $.field($.opt($.str("var")), "isVar", $.field($.opt($.str("u")), "isUnsigned", $.right($.str("int"), $.field($.stry($.plus($.lazy(() => digit))), "width", $.eps)))))); -export const CoinsStorage: $.Parser<$ast.CoinsStorage> = $.loc($.field($.pure("CoinsStorage"), "$", $.right($.str("coins"), $.eps))); -export const RemainingStorage: $.Parser<$ast.RemainingStorage> = $.loc($.field($.pure("RemainingStorage"), "$", $.right($.str("remaining"), $.eps))); -export const BytesStorage: $.Parser<$ast.BytesStorage> = $.loc($.field($.pure("BytesStorage"), "$", $.right($.str("bytes"), $.field($.stry($.plus($.lazy(() => digit))), "width", $.eps)))); -export const storage: $.Parser<$ast.storage> = $.alt(IntStorage, $.alt(CoinsStorage, $.alt(RemainingStorage, BytesStorage))); -export const generic = (T: $.Parser): $.Parser<$ast.generic> => $.right($.str("<"), $.left($.opt(commaList($.lazy(() => T))), $.str(">"))); +export const TypeOptional: $.Parser<$ast.TypeOptional> = $.loc( + $.field( + $.pure("TypeOptional"), + "$", + $.field( + $.lazy(() => typePrimary), + "type", + $.field($.star($.lazy(() => Optional)), "optionals", $.eps), + ), + ), +); +export const Optional: $.Parser<$ast.Optional> = $.loc( + $.field($.pure("Optional"), "$", $.right($.str("?"), $.eps)), +); +export const TypeGeneric: $.Parser<$ast.TypeGeneric> = $.loc( + $.field( + $.pure("TypeGeneric"), + "$", + $.field( + $.alt( + $.lazy(() => MapKeyword), + $.alt( + $.lazy(() => Bounced), + TypeId, + ), + ), + "name", + $.field( + $.lazy(() => typeArgs), + "args", + $.eps, + ), + ), + ), +); +export const TypeRegular: $.Parser<$ast.TypeRegular> = $.loc( + $.field($.pure("TypeRegular"), "$", $.field(TypeId, "child", $.eps)), +); +export const TypeStorage: $.Parser<$ast.TypeStorage> = $.loc( + $.field( + $.pure("TypeStorage"), + "$", + $.field( + $.lazy(() => storage), + "child", + $.eps, + ), + ), +); +export const TypeTuple: $.Parser<$ast.TypeTuple> = $.loc( + $.field( + $.pure("TypeTuple"), + "$", + $.right( + $.str("["), + $.field( + $.opt(commaList($type)), + "types", + $.right($.str("]"), $.eps), + ), + ), + ), +); +export const TypeTensor: $.Parser<$ast.TypeTensor> = $.loc( + $.field( + $.pure("TypeTensor"), + "$", + $.right( + $.str("("), + $.field( + $type, + "head", + $.field( + $.plus($.right($.str(","), $type)), + "tail", + $.right($.opt($.str(",")), $.right($.str(")"), $.eps)), + ), + ), + ), + ), +); +export const TypeUnit: $.Parser<$ast.TypeUnit> = $.loc( + $.field( + $.pure("TypeUnit"), + "$", + $.right($.right($.str("("), $.right($.str(")"), $.eps)), $.eps), + ), +); +export const typeParens: $.Parser<$ast.typeParens> = $.right( + $.str("("), + $.left($type, $.str(")")), +); +export const typePrimary: $.Parser<$ast.typePrimary> = $.alt( + TypeGeneric, + $.alt( + TypeRegular, + $.alt( + TypeStorage, + $.alt(TypeTuple, $.alt(TypeTensor, $.alt(TypeUnit, typeParens))), + ), + ), +); +export const MapKeyword: $.Parser<$ast.MapKeyword> = $.loc( + $.field($.pure("MapKeyword"), "$", $.right(keyword($.str("map")), $.eps)), +); +export const Bounced: $.Parser<$ast.Bounced> = $.loc( + $.field($.pure("Bounced"), "$", $.right($.str("bounced"), $.eps)), +); +export const IntStorage: $.Parser<$ast.IntStorage> = $.loc( + $.field( + $.pure("IntStorage"), + "$", + $.field( + $.opt($.str("var")), + "isVar", + $.field( + $.opt($.str("u")), + "isUnsigned", + $.right( + $.str("int"), + $.field( + $.stry($.plus($.lazy(() => digit))), + "width", + $.eps, + ), + ), + ), + ), + ), +); +export const CoinsStorage: $.Parser<$ast.CoinsStorage> = $.loc( + $.field($.pure("CoinsStorage"), "$", $.right($.str("coins"), $.eps)), +); +export const RemainingStorage: $.Parser<$ast.RemainingStorage> = $.loc( + $.field( + $.pure("RemainingStorage"), + "$", + $.right($.str("remaining"), $.eps), + ), +); +export const BytesStorage: $.Parser<$ast.BytesStorage> = $.loc( + $.field( + $.pure("BytesStorage"), + "$", + $.right( + $.str("bytes"), + $.field($.stry($.plus($.lazy(() => digit))), "width", $.eps), + ), + ), +); +export const storage: $.Parser<$ast.storage> = $.alt( + IntStorage, + $.alt(CoinsStorage, $.alt(RemainingStorage, BytesStorage)), +); +export const generic = (T: $.Parser): $.Parser<$ast.generic> => + $.right($.str("<"), $.left($.opt(commaList($.lazy(() => T))), $.str(">"))); export const typeParams: $.Parser<$ast.typeParams> = generic(TypeId); export const typeArgs: $.Parser<$ast.typeArgs> = generic($type); -export const StatementLet: $.Parser<$ast.StatementLet> = $.loc($.field($.pure("StatementLet"), "$", $.right(keyword($.str("let")), $.field(Id, "name", $.field($.opt(ascription), "type", $.right($.str("="), $.field($.lazy(() => expression), "init", $.right(semicolon, $.eps)))))))); -export const StatementDestruct: $.Parser<$ast.StatementDestruct> = $.loc($.field($.pure("StatementDestruct"), "$", $.right(keyword($.str("let")), $.field(TypeId, "type", $.right($.str("{"), $.field(inter($.lazy(() => destructItem), $.str(",")), "fields", $.field($.lazy(() => optionalRest), "rest", $.right($.str("}"), $.right($.str("="), $.field($.lazy(() => expression), "init", $.right(semicolon, $.eps))))))))))); -export const StatementBlock: $.Parser<$ast.StatementBlock> = $.loc($.field($.pure("StatementBlock"), "$", $.field($.lazy(() => statements), "body", $.eps))); -export const StatementReturn: $.Parser<$ast.StatementReturn> = $.loc($.field($.pure("StatementReturn"), "$", $.right(keyword($.str("return")), $.field($.opt($.lazy(() => expression)), "expression", $.right(semicolon, $.eps))))); -export const StatementCondition: $.Parser<$ast.StatementCondition> = $.loc($.field($.pure("StatementCondition"), "$", $.right(keyword($.str("if")), $.field($.lazy(() => expression), "condition", $.field($.lazy(() => statements), "trueBranch", $.field($.opt($.right(keyword($.str("else")), $.alt($.lazy(() => FalseBranch), $.lazy(() => StatementCondition)))), "falseBranch", $.eps)))))); -export const StatementWhile: $.Parser<$ast.StatementWhile> = $.loc($.field($.pure("StatementWhile"), "$", $.right(keyword($.str("while")), $.field($.lazy(() => parens), "condition", $.field($.lazy(() => statements), "body", $.eps))))); -export const StatementRepeat: $.Parser<$ast.StatementRepeat> = $.loc($.field($.pure("StatementRepeat"), "$", $.right(keyword($.str("repeat")), $.field($.lazy(() => parens), "condition", $.field($.lazy(() => statements), "body", $.eps))))); -export const StatementUntil: $.Parser<$ast.StatementUntil> = $.loc($.field($.pure("StatementUntil"), "$", $.right(keyword($.str("do")), $.field($.lazy(() => statements), "body", $.right(keyword($.str("until")), $.field($.lazy(() => parens), "condition", $.right(semicolon, $.eps))))))); -export const StatementTry: $.Parser<$ast.StatementTry> = $.loc($.field($.pure("StatementTry"), "$", $.right(keyword($.str("try")), $.field($.lazy(() => statements), "body", $.field($.opt($.right(keyword($.str("catch")), $.right($.str("("), $.field(Id, "name", $.right($.str(")"), $.field($.lazy(() => statements), "body", $.eps)))))), "handler", $.eps))))); -export const StatementForEach: $.Parser<$ast.StatementForEach> = $.loc($.field($.pure("StatementForEach"), "$", $.right(keyword($.str("foreach")), $.right($.str("("), $.field(Id, "key", $.right($.str(","), $.field(Id, "value", $.right($.str("in"), $.field($.lazy(() => expression), "expression", $.right($.str(")"), $.field($.lazy(() => statements), "body", $.eps))))))))))); -export const StatementExpression: $.Parser<$ast.StatementExpression> = $.loc($.field($.pure("StatementExpression"), "$", $.field($.lazy(() => expression), "expression", $.right(semicolon, $.eps)))); -export const StatementAssign: $.Parser<$ast.StatementAssign> = $.loc($.field($.pure("StatementAssign"), "$", $.field($.lazy(() => expression), "left", $.field($.alt($.lazy(() => augmentedOp), $.str("=")), "operator", $.field($.lazy(() => expression), "right", $.right(semicolon, $.eps)))))); -export const statement: $.Parser<$ast.statement> = $.alt(StatementLet, $.alt(StatementDestruct, $.alt(StatementBlock, $.alt(StatementReturn, $.alt(StatementCondition, $.alt(StatementWhile, $.alt(StatementRepeat, $.alt(StatementUntil, $.alt(StatementTry, $.alt(StatementForEach, $.alt(StatementExpression, StatementAssign))))))))))); -export const statements: $.Parser<$ast.statements> = $.right($.str("{"), $.left($.star(statement), $.str("}"))); -export const augmentedOp: $.Parser<$ast.augmentedOp> = $.alt($.str("||="), $.alt($.str("&&="), $.alt($.str(">>="), $.alt($.str("<<="), $.alt($.str("-="), $.alt($.str("+="), $.alt($.str("*="), $.alt($.str("/="), $.alt($.str("%="), $.alt($.str("|="), $.alt($.str("&="), $.str("^=")))))))))))); -export const FalseBranch: $.Parser<$ast.FalseBranch> = $.loc($.field($.pure("FalseBranch"), "$", $.field(statements, "body", $.eps))); -export const RegularField: $.Parser<$ast.RegularField> = $.loc($.field($.pure("RegularField"), "$", $.field(Id, "fieldName", $.right($.str(":"), $.field(Id, "varName", $.eps))))); -export const PunnedField: $.Parser<$ast.PunnedField> = $.loc($.field($.pure("PunnedField"), "$", $.field(Id, "name", $.eps))); -export const destructItem: $.Parser<$ast.destructItem> = $.alt(RegularField, PunnedField); -export const RestArgument: $.Parser<$ast.RestArgument> = $.loc($.field($.pure("RestArgument"), "$", $.right($.str(".."), $.eps))); -export const NoRestArgument: $.Parser<$ast.NoRestArgument> = $.loc($.field($.pure("NoRestArgument"), "$", $.right($.opt($.str(",")), $.eps))); -export const optionalRest: $.Parser<$ast.optionalRest> = $.alt($.right($.str(","), RestArgument), NoRestArgument); -export const Conditional: $.Parser<$ast.Conditional> = $.loc($.field($.pure("Conditional"), "$", $.field($.lazy(() => or), "head", $.field($.opt($.right($.str("?"), $.field($.lazy(() => or), "thenBranch", $.right($.str(":"), $.field($.lazy(() => Conditional), "elseBranch", $.eps))))), "tail", $.eps)))); +export const StatementLet: $.Parser<$ast.StatementLet> = $.loc( + $.field( + $.pure("StatementLet"), + "$", + $.right( + keyword($.str("let")), + $.field( + Id, + "name", + $.field( + $.opt(ascription), + "type", + $.right( + $.str("="), + $.field( + $.lazy(() => expression), + "init", + $.right(semicolon, $.eps), + ), + ), + ), + ), + ), + ), +); +export const StatementDestruct: $.Parser<$ast.StatementDestruct> = $.loc( + $.field( + $.pure("StatementDestruct"), + "$", + $.right( + keyword($.str("let")), + $.field( + TypeId, + "type", + $.right( + $.str("{"), + $.field( + inter( + $.lazy(() => destructItem), + $.str(","), + ), + "fields", + $.field( + $.lazy(() => optionalRest), + "rest", + $.right( + $.str("}"), + $.right( + $.str("="), + $.field( + $.lazy(() => expression), + "init", + $.right(semicolon, $.eps), + ), + ), + ), + ), + ), + ), + ), + ), + ), +); +export const StatementBlock: $.Parser<$ast.StatementBlock> = $.loc( + $.field( + $.pure("StatementBlock"), + "$", + $.field( + $.lazy(() => statements), + "body", + $.eps, + ), + ), +); +export const StatementReturn: $.Parser<$ast.StatementReturn> = $.loc( + $.field( + $.pure("StatementReturn"), + "$", + $.right( + keyword($.str("return")), + $.field( + $.opt($.lazy(() => expression)), + "expression", + $.right(semicolon, $.eps), + ), + ), + ), +); +export const StatementCondition: $.Parser<$ast.StatementCondition> = $.loc( + $.field( + $.pure("StatementCondition"), + "$", + $.right( + keyword($.str("if")), + $.field( + $.lazy(() => expression), + "condition", + $.field( + $.lazy(() => statements), + "trueBranch", + $.field( + $.opt( + $.right( + keyword($.str("else")), + $.alt( + $.lazy(() => FalseBranch), + $.lazy(() => StatementCondition), + ), + ), + ), + "falseBranch", + $.eps, + ), + ), + ), + ), + ), +); +export const StatementWhile: $.Parser<$ast.StatementWhile> = $.loc( + $.field( + $.pure("StatementWhile"), + "$", + $.right( + keyword($.str("while")), + $.field( + $.lazy(() => parens), + "condition", + $.field( + $.lazy(() => statements), + "body", + $.eps, + ), + ), + ), + ), +); +export const StatementRepeat: $.Parser<$ast.StatementRepeat> = $.loc( + $.field( + $.pure("StatementRepeat"), + "$", + $.right( + keyword($.str("repeat")), + $.field( + $.lazy(() => parens), + "condition", + $.field( + $.lazy(() => statements), + "body", + $.eps, + ), + ), + ), + ), +); +export const StatementUntil: $.Parser<$ast.StatementUntil> = $.loc( + $.field( + $.pure("StatementUntil"), + "$", + $.right( + keyword($.str("do")), + $.field( + $.lazy(() => statements), + "body", + $.right( + keyword($.str("until")), + $.field( + $.lazy(() => parens), + "condition", + $.right(semicolon, $.eps), + ), + ), + ), + ), + ), +); +export const StatementTry: $.Parser<$ast.StatementTry> = $.loc( + $.field( + $.pure("StatementTry"), + "$", + $.right( + keyword($.str("try")), + $.field( + $.lazy(() => statements), + "body", + $.field( + $.opt( + $.right( + keyword($.str("catch")), + $.right( + $.str("("), + $.field( + Id, + "name", + $.right( + $.str(")"), + $.field( + $.lazy(() => statements), + "body", + $.eps, + ), + ), + ), + ), + ), + ), + "handler", + $.eps, + ), + ), + ), + ), +); +export const StatementForEach: $.Parser<$ast.StatementForEach> = $.loc( + $.field( + $.pure("StatementForEach"), + "$", + $.right( + keyword($.str("foreach")), + $.right( + $.str("("), + $.field( + Id, + "key", + $.right( + $.str(","), + $.field( + Id, + "value", + $.right( + $.str("in"), + $.field( + $.lazy(() => expression), + "expression", + $.right( + $.str(")"), + $.field( + $.lazy(() => statements), + "body", + $.eps, + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), +); +export const StatementExpression: $.Parser<$ast.StatementExpression> = $.loc( + $.field( + $.pure("StatementExpression"), + "$", + $.field( + $.lazy(() => expression), + "expression", + $.right(semicolon, $.eps), + ), + ), +); +export const StatementAssign: $.Parser<$ast.StatementAssign> = $.loc( + $.field( + $.pure("StatementAssign"), + "$", + $.field( + $.lazy(() => expression), + "left", + $.field( + $.alt( + $.lazy(() => augmentedOp), + $.str("="), + ), + "operator", + $.field( + $.lazy(() => expression), + "right", + $.right(semicolon, $.eps), + ), + ), + ), + ), +); +export const statement: $.Parser<$ast.statement> = $.alt( + StatementLet, + $.alt( + StatementDestruct, + $.alt( + StatementBlock, + $.alt( + StatementReturn, + $.alt( + StatementCondition, + $.alt( + StatementWhile, + $.alt( + StatementRepeat, + $.alt( + StatementUntil, + $.alt( + StatementTry, + $.alt( + StatementForEach, + $.alt( + StatementExpression, + StatementAssign, + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), +); +export const statements: $.Parser<$ast.statements> = $.right( + $.str("{"), + $.left($.star(statement), $.str("}")), +); +export const augmentedOp: $.Parser<$ast.augmentedOp> = $.alt( + $.str("||="), + $.alt( + $.str("&&="), + $.alt( + $.str(">>="), + $.alt( + $.str("<<="), + $.alt( + $.str("-="), + $.alt( + $.str("+="), + $.alt( + $.str("*="), + $.alt( + $.str("/="), + $.alt( + $.str("%="), + $.alt( + $.str("|="), + $.alt($.str("&="), $.str("^=")), + ), + ), + ), + ), + ), + ), + ), + ), + ), +); +export const FalseBranch: $.Parser<$ast.FalseBranch> = $.loc( + $.field($.pure("FalseBranch"), "$", $.field(statements, "body", $.eps)), +); +export const RegularField: $.Parser<$ast.RegularField> = $.loc( + $.field( + $.pure("RegularField"), + "$", + $.field( + Id, + "fieldName", + $.right($.str(":"), $.field(Id, "varName", $.eps)), + ), + ), +); +export const PunnedField: $.Parser<$ast.PunnedField> = $.loc( + $.field($.pure("PunnedField"), "$", $.field(Id, "name", $.eps)), +); +export const destructItem: $.Parser<$ast.destructItem> = $.alt( + RegularField, + PunnedField, +); +export const RestArgument: $.Parser<$ast.RestArgument> = $.loc( + $.field($.pure("RestArgument"), "$", $.right($.str(".."), $.eps)), +); +export const NoRestArgument: $.Parser<$ast.NoRestArgument> = $.loc( + $.field($.pure("NoRestArgument"), "$", $.right($.opt($.str(",")), $.eps)), +); +export const optionalRest: $.Parser<$ast.optionalRest> = $.alt( + $.right($.str(","), RestArgument), + NoRestArgument, +); +export const Conditional: $.Parser<$ast.Conditional> = $.loc( + $.field( + $.pure("Conditional"), + "$", + $.field( + $.lazy(() => or), + "head", + $.field( + $.opt( + $.right( + $.str("?"), + $.field( + $.lazy(() => or), + "thenBranch", + $.right( + $.str(":"), + $.field( + $.lazy(() => Conditional), + "elseBranch", + $.eps, + ), + ), + ), + ), + ), + "tail", + $.eps, + ), + ), + ), +); export const expression: $.Parser<$ast.expression> = Conditional; -export const Binary = (T: $.Parser, U: $.Parser): $.Parser<$ast.Binary> => $.loc($.field($.pure("Binary"), "$", $.field(inter($.lazy(() => T), $.lazy(() => Operator($.lazy(() => U)))), "exprs", $.eps))); -export const Unary: $.Parser<$ast.Unary> = $.loc($.field($.pure("Unary"), "$", $.field($.star($.lazy(() => Operator($.regex<"-" | "+" | "!" | "~">("-+!~", [$.ExpString("-"), $.ExpString("+"), $.ExpString("!"), $.ExpString("~")])))), "prefixes", $.field($.lazy(() => Suffix), "expression", $.eps)))); -export const mul: $.Parser<$ast.mul> = Binary(Unary, $.regex<"*" | "/" | "%">("*/%", [$.ExpString("*"), $.ExpString("/"), $.ExpString("%")])); -export const add: $.Parser<$ast.add> = Binary(mul, $.alt($.str("+"), $.str("-"))); -export const bitwiseShift: $.Parser<$ast.bitwiseShift> = Binary(add, $.alt($.str("<<"), $.str(">>"))); -export const compare: $.Parser<$ast.compare> = Binary(bitwiseShift, $.alt($.str("<="), $.alt($.str("<"), $.alt($.str(">="), $.str(">"))))); -export const equality: $.Parser<$ast.equality> = Binary(compare, $.alt($.str("!="), $.str("=="))); -export const bitwiseAnd: $.Parser<$ast.bitwiseAnd> = Binary(equality, $.str("&")); -export const bitwiseXor: $.Parser<$ast.bitwiseXor> = Binary(bitwiseAnd, $.str("^")); -export const bitwiseOr: $.Parser<$ast.bitwiseOr> = Binary(bitwiseXor, $.str("|")); +export const Binary = ( + T: $.Parser, + U: $.Parser, +): $.Parser<$ast.Binary> => + $.loc( + $.field( + $.pure("Binary"), + "$", + $.field( + inter( + $.lazy(() => T), + $.lazy(() => Operator($.lazy(() => U))), + ), + "exprs", + $.eps, + ), + ), + ); +export const Unary: $.Parser<$ast.Unary> = $.loc( + $.field( + $.pure("Unary"), + "$", + $.field( + $.star( + $.lazy(() => + Operator( + $.regex<"-" | "+" | "!" | "~">("-+!~", [ + $.ExpString("-"), + $.ExpString("+"), + $.ExpString("!"), + $.ExpString("~"), + ]), + ), + ), + ), + "prefixes", + $.field( + $.lazy(() => Suffix), + "expression", + $.eps, + ), + ), + ), +); +export const mul: $.Parser<$ast.mul> = Binary( + Unary, + $.regex<"*" | "/" | "%">("*/%", [ + $.ExpString("*"), + $.ExpString("/"), + $.ExpString("%"), + ]), +); +export const add: $.Parser<$ast.add> = Binary( + mul, + $.alt($.str("+"), $.str("-")), +); +export const bitwiseShift: $.Parser<$ast.bitwiseShift> = Binary( + add, + $.alt($.str("<<"), $.str(">>")), +); +export const compare: $.Parser<$ast.compare> = Binary( + bitwiseShift, + $.alt($.str("<="), $.alt($.str("<"), $.alt($.str(">="), $.str(">")))), +); +export const equality: $.Parser<$ast.equality> = Binary( + compare, + $.alt($.str("!="), $.str("==")), +); +export const bitwiseAnd: $.Parser<$ast.bitwiseAnd> = Binary( + equality, + $.str("&"), +); +export const bitwiseXor: $.Parser<$ast.bitwiseXor> = Binary( + bitwiseAnd, + $.str("^"), +); +export const bitwiseOr: $.Parser<$ast.bitwiseOr> = Binary( + bitwiseXor, + $.str("|"), +); export const and: $.Parser<$ast.and> = Binary(bitwiseOr, $.str("&&")); export const or: $.Parser<$ast.or> = Binary(and, $.str("||")); -export const Suffix: $.Parser<$ast.Suffix> = $.loc($.field($.pure("Suffix"), "$", $.field($.lazy(() => primary), "expression", $.field($.star($.lazy(() => suffix)), "suffixes", $.eps)))); -export const Operator = (U: $.Parser): $.Parser<$ast.Operator> => $.loc($.field($.pure("Operator"), "$", $.field($.lazy(() => U), "name", $.eps))); -export const SuffixUnboxNotNull: $.Parser<$ast.SuffixUnboxNotNull> = $.loc($.field($.pure("SuffixUnboxNotNull"), "$", $.right($.str("!!"), $.eps))); -export const SuffixCall: $.Parser<$ast.SuffixCall> = $.loc($.field($.pure("SuffixCall"), "$", $.field($.opt(typeArgs), "typeArgs", $.field($.lazy(() => parameterList(expression)), "params", $.eps)))); -export const SuffixFieldAccess: $.Parser<$ast.SuffixFieldAccess> = $.loc($.field($.pure("SuffixFieldAccess"), "$", $.right($.str("."), $.field(Id, "name", $.eps)))); -export const suffix: $.Parser<$ast.suffix> = $.alt(SuffixUnboxNotNull, $.alt(SuffixCall, SuffixFieldAccess)); -export const Unit: $.Parser<$ast.Unit> = $.loc($.field($.pure("Unit"), "$", $.right($.right($.str("("), $.right($.str(")"), $.eps)), $.eps))); -export const Tensor: $.Parser<$ast.Tensor> = $.loc($.field($.pure("Tensor"), "$", $.right($.str("("), $.field(expression, "head", $.field($.plus($.right($.str(","), expression)), "tail", $.right($.opt($.str(",")), $.right($.str(")"), $.eps))))))); -export const Tuple: $.Parser<$ast.Tuple> = $.loc($.field($.pure("Tuple"), "$", $.right($.str("["), $.field($.opt(commaList(expression)), "types", $.right($.str("]"), $.eps))))); -export const Parens: $.Parser<$ast.Parens> = $.loc($.field($.pure("Parens"), "$", $.field($.lazy(() => parens), "child", $.eps))); -export const StructInstance: $.Parser<$ast.StructInstance> = $.loc($.field($.pure("StructInstance"), "$", $.field(TypeId, "type", $.field($.opt(typeArgs), "typeArgs", $.right($.str("{"), $.field($.opt(commaList($.lazy(() => StructFieldInitializer))), "fields", $.right($.str("}"), $.eps))))))); -export const IntegerLiteral: $.Parser<$ast.IntegerLiteral> = $.loc($.field($.pure("IntegerLiteral"), "$", $.field($.alt($.lazy(() => IntegerLiteralHex), $.alt($.lazy(() => IntegerLiteralBin), $.alt($.lazy(() => IntegerLiteralOct), IntegerLiteralDec))), "value", $.eps))); -export const BoolLiteral: $.Parser<$ast.BoolLiteral> = $.loc($.field($.pure("BoolLiteral"), "$", $.field($.alt($.str("true"), $.str("false")), "value", $.right($.lookNeg($.lazy(() => idPart)), $.eps)))); -export const InitOf: $.Parser<$ast.InitOf> = $.loc($.field($.pure("InitOf"), "$", $.right(keyword($.str("initOf")), $.field(TypeId, "name", $.field($.lazy(() => parameterList(expression)), "params", $.eps))))); -export const CodeOf: $.Parser<$ast.CodeOf> = $.loc($.field($.pure("CodeOf"), "$", $.right($.str("codeOf"), $.field(TypeId, "name", $.eps)))); -export const Null: $.Parser<$ast.Null> = $.loc($.field($.pure("Null"), "$", $.right(keyword($.str("null")), $.eps))); -export const primary: $.Parser<$ast.primary> = $.alt(Unit, $.alt(Tensor, $.alt(Tuple, $.alt(Parens, $.alt(StructInstance, $.alt(IntegerLiteral, $.alt(BoolLiteral, $.alt(InitOf, $.alt(CodeOf, $.alt(Null, $.alt(StringLiteral, Id))))))))))); -export const parens: $.Parser<$ast.parens> = $.right($.str("("), $.left(expression, $.str(")"))); -export const StructFieldInitializer: $.Parser<$ast.StructFieldInitializer> = $.loc($.field($.pure("StructFieldInitializer"), "$", $.field(Id, "name", $.field($.opt($.right($.str(":"), expression)), "init", $.eps)))); -export const ParameterList = (T: $.Parser): $.Parser<$ast.ParameterList> => $.loc($.field($.pure("ParameterList"), "$", $.right($.str("("), $.field($.opt(commaList($.lazy(() => T))), "values", $.right($.str(")"), $.eps))))); -export const parameterList = (T: $.Parser): $.Parser<$ast.parameterList> => $.right($.str("("), $.left($.opt(commaList($.lazy(() => T))), $.str(")"))); -export const IntegerLiteralHex: $.Parser<$ast.IntegerLiteralHex> = $.loc($.field($.pure("IntegerLiteralHex"), "$", $.field($.lex($.right($.str("0"), $.right($.regex<"x" | "X">("xX", [$.ExpString("x"), $.ExpString("X")]), $.lazy(() => underscored($.lazy(() => hexDigit)))))), "digits", $.eps))); -export const IntegerLiteralBin: $.Parser<$ast.IntegerLiteralBin> = $.loc($.field($.pure("IntegerLiteralBin"), "$", $.field($.lex($.right($.str("0"), $.right($.regex<"b" | "B">("bB", [$.ExpString("b"), $.ExpString("B")]), $.lazy(() => underscored($.regex<"0" | "1">("01", [$.ExpString("0"), $.ExpString("1")])))))), "digits", $.eps))); -export const IntegerLiteralOct: $.Parser<$ast.IntegerLiteralOct> = $.loc($.field($.pure("IntegerLiteralOct"), "$", $.field($.lex($.right($.str("0"), $.right($.regex<"o" | "O">("oO", [$.ExpString("o"), $.ExpString("O")]), $.lazy(() => underscored($.regex("0-7", [$.ExpRange("0", "7")])))))), "digits", $.eps))); -export const underscored = (T: $.Parser): $.Parser<$ast.underscored> => $.stry($.right($.lazy(() => T), $.right($.star($.right($.opt($.str("_")), $.right($.lazy(() => T), $.eps))), $.eps))); -export const digit: $.Parser<$ast.digit> = $.named("digit", $.regex("0-9", [$.ExpRange("0", "9")])); -export const idPart: $.Parser<$ast.idPart> = $.named("identifier character", $.regex("a-zA-Z0-9_", [$.ExpRange("a", "z"), $.ExpRange("A", "Z"), $.ExpRange("0", "9"), $.ExpString("_")])); -export const FuncId: $.Parser<$ast.FuncId> = $.named("FunC identifier", $.loc($.field($.pure("FuncId"), "$", $.field($.opt($.regex<"." | "~">(".~", [$.ExpString("."), $.ExpString("~")])), "accessor", $.field($.stry($.alt($.right($.str("`"), $.right($.plus($.regex<"`" | "\r" | "\n">("^`\\r\\n", $.negateExps([$.ExpString("`"), $.ExpString("\r"), $.ExpString("\n")]))), $.right($.str("`"), $.eps))), $.plus($.regex<" " | "\t" | "\r" | "\n" | "(" | ")" | "[" | string | "," | "." | ";" | "~">("^ \\t\\r\\n()[\\],.;~", $.negateExps([$.ExpString(" "), $.ExpString("\t"), $.ExpString("\r"), $.ExpString("\n"), $.ExpString("("), $.ExpString(")"), $.ExpString("["), $.ExpString("\"\\]\""), $.ExpString(","), $.ExpString("."), $.ExpString(";"), $.ExpString("~")]))))), "id", $.eps))))); -export const hexDigit: $.Parser<$ast.hexDigit> = $.named("hexadecimal digit", $.regex("0-9a-fA-F", [$.ExpRange("0", "9"), $.ExpRange("a", "f"), $.ExpRange("A", "F")])); -export const escapeChar: $.Parser<$ast.escapeChar> = $.alt($.regex<"\\" | "\"" | "n" | "r" | "t" | "v" | "b" | "f">("\\\\\"nrtvbf", [$.ExpString("\\"), $.ExpString("\""), $.ExpString("n"), $.ExpString("r"), $.ExpString("t"), $.ExpString("v"), $.ExpString("b"), $.ExpString("f")]), $.alt($.right($.str("u{"), $.left($.stry($.right(hexDigit, $.right($.opt(hexDigit), $.right($.opt(hexDigit), $.right($.opt(hexDigit), $.right($.opt(hexDigit), $.right($.opt(hexDigit), $.eps))))))), $.str("}"))), $.alt($.right($.str("u"), $.stry($.right(hexDigit, $.right(hexDigit, $.right(hexDigit, $.right(hexDigit, $.eps)))))), $.right($.str("x"), $.stry($.right(hexDigit, $.right(hexDigit, $.eps))))))); -export const reservedWord: $.Parser<$ast.reservedWord> = $.named("reserved word", keyword($.alt($.str("extend"), $.alt($.str("public"), $.alt($.str("fun"), $.alt($.str("let"), $.alt($.str("return"), $.alt($.str("receive"), $.alt($.str("native"), $.alt($.str("primitive"), $.alt($.str("null"), $.alt($.str("if"), $.alt($.str("else"), $.alt($.str("while"), $.alt($.str("repeat"), $.alt($.str("do"), $.alt($.str("until"), $.alt($.str("try"), $.alt($.str("catch"), $.alt($.str("foreach"), $.alt($.str("as"), $.alt($.str("map"), $.alt($.str("mutates"), $.alt($.str("extends"), $.alt($.str("external"), $.alt($.str("import"), $.alt($.str("with"), $.alt($.str("trait"), $.alt($.str("initOf"), $.alt($.str("override"), $.alt($.str("abstract"), $.alt($.str("virtual"), $.alt($.str("inline"), $.str("const")))))))))))))))))))))))))))))))))); -export const space: $.Parser<$ast.space> = $.named("space", $.alt($.regex<" " | "\t" | "\r" | "\n">(" \\t\\r\\n", [$.ExpString(" "), $.ExpString("\t"), $.ExpString("\r"), $.ExpString("\n")]), comment)); -export const JustImports: $.Parser<$ast.JustImports> = $.loc($.field($.pure("JustImports"), "$", $.field($.star(Import), "imports", $.right($.star($.any), $.eps)))); \ No newline at end of file +export const Suffix: $.Parser<$ast.Suffix> = $.loc( + $.field( + $.pure("Suffix"), + "$", + $.field( + $.lazy(() => primary), + "expression", + $.field($.star($.lazy(() => suffix)), "suffixes", $.eps), + ), + ), +); +export const Operator = (U: $.Parser): $.Parser<$ast.Operator> => + $.loc( + $.field( + $.pure("Operator"), + "$", + $.field( + $.lazy(() => U), + "name", + $.eps, + ), + ), + ); +export const SuffixUnboxNotNull: $.Parser<$ast.SuffixUnboxNotNull> = $.loc( + $.field($.pure("SuffixUnboxNotNull"), "$", $.right($.str("!!"), $.eps)), +); +export const SuffixCall: $.Parser<$ast.SuffixCall> = $.loc( + $.field( + $.pure("SuffixCall"), + "$", + $.field( + $.opt(typeArgs), + "typeArgs", + $.field( + $.lazy(() => parameterList(expression)), + "params", + $.eps, + ), + ), + ), +); +export const SuffixFieldAccess: $.Parser<$ast.SuffixFieldAccess> = $.loc( + $.field( + $.pure("SuffixFieldAccess"), + "$", + $.right($.str("."), $.field(Id, "name", $.eps)), + ), +); +export const suffix: $.Parser<$ast.suffix> = $.alt( + SuffixUnboxNotNull, + $.alt(SuffixCall, SuffixFieldAccess), +); +export const Unit: $.Parser<$ast.Unit> = $.loc( + $.field( + $.pure("Unit"), + "$", + $.right($.right($.str("("), $.right($.str(")"), $.eps)), $.eps), + ), +); +export const Tensor: $.Parser<$ast.Tensor> = $.loc( + $.field( + $.pure("Tensor"), + "$", + $.right( + $.str("("), + $.field( + expression, + "head", + $.field( + $.plus($.right($.str(","), expression)), + "tail", + $.right($.opt($.str(",")), $.right($.str(")"), $.eps)), + ), + ), + ), + ), +); +export const Tuple: $.Parser<$ast.Tuple> = $.loc( + $.field( + $.pure("Tuple"), + "$", + $.right( + $.str("["), + $.field( + $.opt(commaList(expression)), + "types", + $.right($.str("]"), $.eps), + ), + ), + ), +); +export const Parens: $.Parser<$ast.Parens> = $.loc( + $.field( + $.pure("Parens"), + "$", + $.field( + $.lazy(() => parens), + "child", + $.eps, + ), + ), +); +export const StructInstance: $.Parser<$ast.StructInstance> = $.loc( + $.field( + $.pure("StructInstance"), + "$", + $.field( + TypeId, + "type", + $.field( + $.opt(typeArgs), + "typeArgs", + $.right( + $.str("{"), + $.field( + $.opt(commaList($.lazy(() => StructFieldInitializer))), + "fields", + $.right($.str("}"), $.eps), + ), + ), + ), + ), + ), +); +export const IntegerLiteral: $.Parser<$ast.IntegerLiteral> = $.loc( + $.field( + $.pure("IntegerLiteral"), + "$", + $.field( + $.alt( + $.lazy(() => IntegerLiteralHex), + $.alt( + $.lazy(() => IntegerLiteralBin), + $.alt( + $.lazy(() => IntegerLiteralOct), + IntegerLiteralDec, + ), + ), + ), + "value", + $.eps, + ), + ), +); +export const BoolLiteral: $.Parser<$ast.BoolLiteral> = $.loc( + $.field( + $.pure("BoolLiteral"), + "$", + $.field( + $.alt($.str("true"), $.str("false")), + "value", + $.right($.lookNeg($.lazy(() => idPart)), $.eps), + ), + ), +); +export const InitOf: $.Parser<$ast.InitOf> = $.loc( + $.field( + $.pure("InitOf"), + "$", + $.right( + keyword($.str("initOf")), + $.field( + TypeId, + "name", + $.field( + $.lazy(() => parameterList(expression)), + "params", + $.eps, + ), + ), + ), + ), +); +export const CodeOf: $.Parser<$ast.CodeOf> = $.loc( + $.field( + $.pure("CodeOf"), + "$", + $.right($.str("codeOf"), $.field(TypeId, "name", $.eps)), + ), +); +export const Null: $.Parser<$ast.Null> = $.loc( + $.field($.pure("Null"), "$", $.right(keyword($.str("null")), $.eps)), +); +export const primary: $.Parser<$ast.primary> = $.alt( + Unit, + $.alt( + Tensor, + $.alt( + Tuple, + $.alt( + Parens, + $.alt( + StructInstance, + $.alt( + IntegerLiteral, + $.alt( + BoolLiteral, + $.alt( + InitOf, + $.alt( + CodeOf, + $.alt(Null, $.alt(StringLiteral, Id)), + ), + ), + ), + ), + ), + ), + ), + ), +); +export const parens: $.Parser<$ast.parens> = $.right( + $.str("("), + $.left(expression, $.str(")")), +); +export const StructFieldInitializer: $.Parser<$ast.StructFieldInitializer> = + $.loc( + $.field( + $.pure("StructFieldInitializer"), + "$", + $.field( + Id, + "name", + $.field($.opt($.right($.str(":"), expression)), "init", $.eps), + ), + ), + ); +export const ParameterList = ( + T: $.Parser, +): $.Parser<$ast.ParameterList> => + $.loc( + $.field( + $.pure("ParameterList"), + "$", + $.right( + $.str("("), + $.field( + $.opt(commaList($.lazy(() => T))), + "values", + $.right($.str(")"), $.eps), + ), + ), + ), + ); +export const parameterList = ( + T: $.Parser, +): $.Parser<$ast.parameterList> => + $.right($.str("("), $.left($.opt(commaList($.lazy(() => T))), $.str(")"))); +export const IntegerLiteralHex: $.Parser<$ast.IntegerLiteralHex> = $.loc( + $.field( + $.pure("IntegerLiteralHex"), + "$", + $.field( + $.lex( + $.right( + $.str("0"), + $.right( + $.regex<"x" | "X">("xX", [ + $.ExpString("x"), + $.ExpString("X"), + ]), + $.lazy(() => underscored($.lazy(() => hexDigit))), + ), + ), + ), + "digits", + $.eps, + ), + ), +); +export const IntegerLiteralBin: $.Parser<$ast.IntegerLiteralBin> = $.loc( + $.field( + $.pure("IntegerLiteralBin"), + "$", + $.field( + $.lex( + $.right( + $.str("0"), + $.right( + $.regex<"b" | "B">("bB", [ + $.ExpString("b"), + $.ExpString("B"), + ]), + $.lazy(() => + underscored( + $.regex<"0" | "1">("01", [ + $.ExpString("0"), + $.ExpString("1"), + ]), + ), + ), + ), + ), + ), + "digits", + $.eps, + ), + ), +); +export const IntegerLiteralOct: $.Parser<$ast.IntegerLiteralOct> = $.loc( + $.field( + $.pure("IntegerLiteralOct"), + "$", + $.field( + $.lex( + $.right( + $.str("0"), + $.right( + $.regex<"o" | "O">("oO", [ + $.ExpString("o"), + $.ExpString("O"), + ]), + $.lazy(() => + underscored( + $.regex("0-7", [$.ExpRange("0", "7")]), + ), + ), + ), + ), + ), + "digits", + $.eps, + ), + ), +); +export const underscored = (T: $.Parser): $.Parser<$ast.underscored> => + $.stry( + $.right( + $.lazy(() => T), + $.right( + $.star( + $.right( + $.opt($.str("_")), + $.right( + $.lazy(() => T), + $.eps, + ), + ), + ), + $.eps, + ), + ), + ); +export const digit: $.Parser<$ast.digit> = $.named( + "digit", + $.regex("0-9", [$.ExpRange("0", "9")]), +); +export const idPart: $.Parser<$ast.idPart> = $.named( + "identifier character", + $.regex("a-zA-Z0-9_", [ + $.ExpRange("a", "z"), + $.ExpRange("A", "Z"), + $.ExpRange("0", "9"), + $.ExpString("_"), + ]), +); +export const FuncId: $.Parser<$ast.FuncId> = $.named( + "FunC identifier", + $.loc( + $.field( + $.pure("FuncId"), + "$", + $.field( + $.opt( + $.regex<"." | "~">(".~", [ + $.ExpString("."), + $.ExpString("~"), + ]), + ), + "accessor", + $.field( + $.stry( + $.alt( + $.right( + $.str("`"), + $.right( + $.plus( + $.regex<"`" | "\r" | "\n">( + "^`\\r\\n", + $.negateExps([ + $.ExpString("`"), + $.ExpString("\r"), + $.ExpString("\n"), + ]), + ), + ), + $.right($.str("`"), $.eps), + ), + ), + $.plus( + $.regex< + | " " + | "\t" + | "\r" + | "\n" + | "(" + | ")" + | "[" + | string + | "," + | "." + | ";" + | "~" + >( + "^ \\t\\r\\n()[\\],.;~", + $.negateExps([ + $.ExpString(" "), + $.ExpString("\t"), + $.ExpString("\r"), + $.ExpString("\n"), + $.ExpString("("), + $.ExpString(")"), + $.ExpString("["), + $.ExpString('"\\]"'), + $.ExpString(","), + $.ExpString("."), + $.ExpString(";"), + $.ExpString("~"), + ]), + ), + ), + ), + ), + "id", + $.eps, + ), + ), + ), + ), +); +export const hexDigit: $.Parser<$ast.hexDigit> = $.named( + "hexadecimal digit", + $.regex("0-9a-fA-F", [ + $.ExpRange("0", "9"), + $.ExpRange("a", "f"), + $.ExpRange("A", "F"), + ]), +); +export const escapeChar: $.Parser<$ast.escapeChar> = $.alt( + $.regex<"\\" | '"' | "n" | "r" | "t" | "v" | "b" | "f">('\\\\"nrtvbf', [ + $.ExpString("\\"), + $.ExpString('"'), + $.ExpString("n"), + $.ExpString("r"), + $.ExpString("t"), + $.ExpString("v"), + $.ExpString("b"), + $.ExpString("f"), + ]), + $.alt( + $.right( + $.str("u{"), + $.left( + $.stry( + $.right( + hexDigit, + $.right( + $.opt(hexDigit), + $.right( + $.opt(hexDigit), + $.right( + $.opt(hexDigit), + $.right( + $.opt(hexDigit), + $.right($.opt(hexDigit), $.eps), + ), + ), + ), + ), + ), + ), + $.str("}"), + ), + ), + $.alt( + $.right( + $.str("u"), + $.stry( + $.right( + hexDigit, + $.right( + hexDigit, + $.right(hexDigit, $.right(hexDigit, $.eps)), + ), + ), + ), + ), + $.right( + $.str("x"), + $.stry($.right(hexDigit, $.right(hexDigit, $.eps))), + ), + ), + ), +); +export const reservedWord: $.Parser<$ast.reservedWord> = $.named( + "reserved word", + keyword( + $.alt( + $.str("extend"), + $.alt( + $.str("public"), + $.alt( + $.str("fun"), + $.alt( + $.str("let"), + $.alt( + $.str("return"), + $.alt( + $.str("receive"), + $.alt( + $.str("native"), + $.alt( + $.str("primitive"), + $.alt( + $.str("null"), + $.alt( + $.str("if"), + $.alt( + $.str("else"), + $.alt( + $.str("while"), + $.alt( + $.str("repeat"), + $.alt( + $.str("do"), + $.alt( + $.str( + "until", + ), + $.alt( + $.str( + "try", + ), + $.alt( + $.str( + "catch", + ), + $.alt( + $.str( + "foreach", + ), + $.alt( + $.str( + "as", + ), + $.alt( + $.str( + "map", + ), + $.alt( + $.str( + "mutates", + ), + $.alt( + $.str( + "extends", + ), + $.alt( + $.str( + "external", + ), + $.alt( + $.str( + "import", + ), + $.alt( + $.str( + "with", + ), + $.alt( + $.str( + "trait", + ), + $.alt( + $.str( + "initOf", + ), + $.alt( + $.str( + "override", + ), + $.alt( + $.str( + "abstract", + ), + $.alt( + $.str( + "virtual", + ), + $.alt( + $.str( + "inline", + ), + $.str( + "const", + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), +); +export const space: $.Parser<$ast.space> = $.named( + "space", + $.alt( + $.regex<" " | "\t" | "\r" | "\n">(" \\t\\r\\n", [ + $.ExpString(" "), + $.ExpString("\t"), + $.ExpString("\r"), + $.ExpString("\n"), + ]), + comment, + ), +); +export const JustImports: $.Parser<$ast.JustImports> = $.loc( + $.field( + $.pure("JustImports"), + "$", + $.field($.star(Import), "imports", $.right($.star($.any), $.eps)), + ), +); diff --git a/src/next/grammar/index.ts b/src/next/grammar/index.ts index e80142604d..4d08f39fb5 100644 --- a/src/next/grammar/index.ts +++ b/src/next/grammar/index.ts @@ -327,7 +327,12 @@ const parseStructFieldInitializer = }; const parseStructInstance = - ({ type, typeArgs, fields, loc }: $ast.StructInstance): Handler => + ({ + type, + typeArgs, + fields, + loc, + }: $ast.StructInstance): Handler => (ctx) => { return Ast.StructInstance( parseTypeId(type)(ctx), @@ -486,17 +491,29 @@ const parseSuffix = ).child; }; -const parseUnit = ({ loc }: $ast.Unit): Handler => _ctx => { - return Ast.Unit(toRange(loc)); -}; +const parseUnit = + ({ loc }: $ast.Unit): Handler => + (_ctx) => { + return Ast.Unit(toRange(loc)); + }; -const parseTensor = ({ head, tail, loc }: $ast.Tensor): Handler => ctx => { - return Ast.Tensor(map([head, ...tail], parseExpression)(ctx), toRange(loc)); -}; +const parseTensor = + ({ head, tail, loc }: $ast.Tensor): Handler => + (ctx) => { + return Ast.Tensor( + map([head, ...tail], parseExpression)(ctx), + toRange(loc), + ); + }; -const parseTuple = ({ types, loc }: $ast.Tuple): Handler => ctx => { - return Ast.Tuple(map(parseList(types), parseExpression)(ctx), toRange(loc)); -}; +const parseTuple = + ({ types, loc }: $ast.Tuple): Handler => + (ctx) => { + return Ast.Tuple( + map(parseList(types), parseExpression)(ctx), + toRange(loc), + ); + }; const parseParens = ({ child }: $ast.Parens): Handler => { return parseExpression(child); @@ -887,84 +904,83 @@ const parseTypeId = return Ast.TypeId(name, toRange(loc)); }; -const parseTypeStorage = ({ child: storage, loc }: $ast.TypeStorage): Handler => ctx => { - const range = toRange(loc); - const fallback = Ast.TypeCons(Ast.TypeId("ERROR", range), [], range); - if (storage.$ === "CoinsStorage") { - return Ast.TypeInt( - Ast.IFVarInt("unsigned", "16", toRange(storage.loc)), - range, - ); - } else if (storage.$ === "IntStorage") { - const width = parseInt(storage.width, 10); - if (storage.isVar) { - if (width === 16) { - return Ast.TypeInt( - Ast.IFVarInt( - typeof storage.isUnsigned === "undefined" - ? "signed" - : "unsigned", - "16", - toRange(storage.loc), - ), - range, - ); - } else if (width === 32) { - return Ast.TypeInt( - Ast.IFVarInt( - typeof storage.isUnsigned === "undefined" - ? "signed" - : "unsigned", - "32", - toRange(storage.loc), - ), - range, - ); - } else { - ctx.err.wrongVarIntSize()(range); - return fallback; - } - } else if (storage.isUnsigned) { - if (1 <= width && width <= 256) { - return Ast.TypeInt( - Ast.IFInt("unsigned", width, range), - range, - ); +const parseTypeStorage = + ({ child: storage, loc }: $ast.TypeStorage): Handler => + (ctx) => { + const range = toRange(loc); + const fallback = Ast.TypeCons(Ast.TypeId("ERROR", range), [], range); + if (storage.$ === "CoinsStorage") { + return Ast.TypeInt( + Ast.IFVarInt("unsigned", "16", toRange(storage.loc)), + range, + ); + } else if (storage.$ === "IntStorage") { + const width = parseInt(storage.width, 10); + if (storage.isVar) { + if (width === 16) { + return Ast.TypeInt( + Ast.IFVarInt( + typeof storage.isUnsigned === "undefined" + ? "signed" + : "unsigned", + "16", + toRange(storage.loc), + ), + range, + ); + } else if (width === 32) { + return Ast.TypeInt( + Ast.IFVarInt( + typeof storage.isUnsigned === "undefined" + ? "signed" + : "unsigned", + "32", + toRange(storage.loc), + ), + range, + ); + } else { + ctx.err.wrongVarIntSize()(range); + return fallback; + } + } else if (storage.isUnsigned) { + if (1 <= width && width <= 256) { + return Ast.TypeInt( + Ast.IFInt("unsigned", width, range), + range, + ); + } else { + ctx.err.wrongUIntSize()(range); + return fallback; + } } else { - ctx.err.wrongUIntSize()(range); - return fallback; + if (1 <= width && width <= 257) { + return Ast.TypeInt( + Ast.IFInt("signed", width, range), + range, + ); + } else { + ctx.err.wrongIntSize()(range); + return fallback; + } } - } else { - if (1 <= width && width <= 257) { - return Ast.TypeInt( - Ast.IFInt("signed", width, range), - range, - ); + } else if (storage.$ === "RemainingStorage") { + ctx.err.rawRemaining()(range); + return Ast.TypeSlice(Ast.SFRemaining(range), range); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + } else if (storage.$ === "BytesStorage") { + const width = parseInt(storage.width, 10); + if (width === 32 || width === 64) { + return Ast.TypeSlice(Ast.SFBits(width * 8, range), range); } else { - ctx.err.wrongIntSize()(range); + ctx.err.wrongSliceSize()(range); return fallback; } - } - } else if (storage.$ === "RemainingStorage") { - ctx.err.rawRemaining()(range); - return Ast.TypeSlice(Ast.SFRemaining(range), range); - // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition - } else if (storage.$ === "BytesStorage") { - const width = parseInt(storage.width, 10); - if (width === 32 || width === 64) { - return Ast.TypeSlice( - Ast.SFBits(width * 8, range), - range, - ); } else { - ctx.err.wrongSliceSize()(range); + ctx.err.wrongFormat("No type")(range); return fallback; } - } else { - ctx.err.wrongFormat("No type")(range); - return fallback; - } -}; + }; const applyFormat = (type: Ast.Type, storage: $ast.storage, asLoc: Range): Handler => @@ -1550,32 +1566,48 @@ const parseNativeFunctionDecl = ); }; -const parseAlias = ({ name, typeParams, type }: $ast.AliasDecl): Handler => ctx => { - return Ast.AliasDecl( - parseTypeId(name)(ctx), - map(parseList(typeParams), parseTypeId)(ctx), - parseType(type)(ctx), - ); -}; +const parseAlias = + ({ name, typeParams, type }: $ast.AliasDecl): Handler => + (ctx) => { + return Ast.AliasDecl( + parseTypeId(name)(ctx), + map(parseList(typeParams), parseTypeId)(ctx), + parseType(type)(ctx), + ); + }; -const parseUnion = ({ name, typeParams, cases, loc }: $ast.UnionDecl): Handler => ctx => { - return Ast.UnionDecl( - parseTypeId(name)(ctx), - map(parseList(typeParams), parseTypeId)(ctx), - map(cases, parseUnionCase)(ctx), - toRange(loc), - ) -}; +const parseUnion = + ({ + name, + typeParams, + cases, + loc, + }: $ast.UnionDecl): Handler => + (ctx) => { + return Ast.UnionDecl( + parseTypeId(name)(ctx), + map(parseList(typeParams), parseTypeId)(ctx), + map(cases, parseUnionCase)(ctx), + toRange(loc), + ); + }; -const parseUnionCase = ({ name, fields }: $ast.Case): Handler => ctx => { - return Ast.UnionCase( - parseTypeId(name)(ctx), - map(parseList(fields), parseFieldDecl)(ctx), - ); -}; +const parseUnionCase = + ({ name, fields }: $ast.Case): Handler => + (ctx) => { + return Ast.UnionCase( + parseTypeId(name)(ctx), + map(parseList(fields), parseFieldDecl)(ctx), + ); + }; const parseStructDecl = - ({ name, typeParams, fields, loc }: $ast.StructDecl): Handler => + ({ + name, + typeParams, + fields, + loc, + }: $ast.StructDecl): Handler => (ctx) => { return Ast.StructDecl( parseTypeId(name)(ctx), diff --git a/src/next/index.ts b/src/next/index.ts index da8ee5648a..537ee3f1ac 100644 --- a/src/next/index.ts +++ b/src/next/index.ts @@ -2,7 +2,7 @@ import path from "path"; import { getParser } from "@/next/grammar"; import { TerminalLogger } from "@/cli/logger"; import { getAnsiMarkup, isColorSupported } from "@/cli/colors"; -import { inspect } from 'util'; +import { inspect } from "util"; import { createProxyFs } from "@/next/fs/proxy-fs"; import { fromString } from "@/imports/path"; @@ -12,13 +12,14 @@ import { fromString } from "@/imports/path"; const target = "alias.tact"; // eslint-disable-next-line @typescript-eslint/no-confusing-void-expression -const dump = (obj: unknown) => console.log(inspect(obj, { colors: true, depth: Infinity })); +const dump = (obj: unknown) => + console.log(inspect(obj, { colors: true, depth: Infinity })); const main = async () => { const ansi = getAnsiMarkup(isColorSupported()); await TerminalLogger(path, "info", ansi, async (log) => { const project = createProxyFs( - path.join(__dirname, 'example'), + path.join(__dirname, "example"), log, false, ); From 4c78f082dffaa41f0ebb68e83724c4a39b2a5d03 Mon Sep 17 00:00:00 2001 From: verytactical <186486509+verytactical@users.noreply.github.com> Date: Tue, 15 Apr 2025 07:51:42 +0400 Subject: [PATCH 08/38] fmt broke fmt --- src/next/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/next/index.ts b/src/next/index.ts index 537ee3f1ac..8ae1dd7062 100644 --- a/src/next/index.ts +++ b/src/next/index.ts @@ -11,8 +11,8 @@ import { fromString } from "@/imports/path"; // const target = "union.tact"; const target = "alias.tact"; -// eslint-disable-next-line @typescript-eslint/no-confusing-void-expression const dump = (obj: unknown) => + // eslint-disable-next-line @typescript-eslint/no-confusing-void-expression console.log(inspect(obj, { colors: true, depth: Infinity })); const main = async () => { From 87f6b0364c46f79e7258403ac45375caa34c059c Mon Sep 17 00:00:00 2001 From: verytactical <186486509+verytactical@users.noreply.github.com> Date: Tue, 15 Apr 2025 10:11:36 +0400 Subject: [PATCH 09/38] import resolution --- spell/cspell-list.txt | 1 + src/error/logger-util.ts | 9 ++- src/next/fs/index.ts | 2 + src/next/fs/memory-fs.ts | 2 +- src/next/fs/proxy-fs.ts | 2 +- src/next/fs/util.ts | 5 ++ src/next/grammar/index.ts | 38 +++++---- src/next/index.ts | 158 +++++++++++++++++++++++++++++++++----- src/next/stdlib/index.ts | 21 +++++ 9 files changed, 193 insertions(+), 45 deletions(-) create mode 100644 src/next/stdlib/index.ts diff --git a/spell/cspell-list.txt b/spell/cspell-list.txt index 2b6ff4d36c..cc331c2a8a 100644 --- a/spell/cspell-list.txt +++ b/spell/cspell-list.txt @@ -72,6 +72,7 @@ Hoppity idict Ikko Ilya +implicits infixl infixr initof diff --git a/src/error/logger-util.ts b/src/error/logger-util.ts index ee2f0b5771..8a403e1c5a 100644 --- a/src/error/logger-util.ts +++ b/src/error/logger-util.ts @@ -92,10 +92,15 @@ const mapBaseLogger = ( }, }); +/** + * `SourceLogger` or top-level `Logger` + */ +export interface AnyLogger extends Formatter, BaseLogger {} + /** * Logger that knows about currently compiled file */ -export interface SourceLogger extends Formatter, BaseLogger { +export interface SourceLogger extends AnyLogger { /** * Choose range where an error will be shown */ @@ -110,7 +115,7 @@ export interface SourceLogger extends Formatter, BaseLogger { /** * Top-level logger */ -export interface Logger extends Formatter, BaseLogger { +export interface Logger extends AnyLogger { /** * Set currently compiled source in logging context */ diff --git a/src/next/fs/index.ts b/src/next/fs/index.ts index f312df7a84..ad805f398f 100644 --- a/src/next/fs/index.ts +++ b/src/next/fs/index.ts @@ -1,3 +1,5 @@ export * from "@/next/fs/cursor"; export * from "@/next/fs/path"; export * from "@/next/fs/util"; +export * from "@/next/fs/memory-fs"; +export * from "@/next/fs/proxy-fs"; diff --git a/src/next/fs/memory-fs.ts b/src/next/fs/memory-fs.ts index bacd1c2576..da72ed1211 100644 --- a/src/next/fs/memory-fs.ts +++ b/src/next/fs/memory-fs.ts @@ -6,9 +6,9 @@ import type { Cursor } from "@/next/fs/cursor"; import type { Logger } from "@/error/logger-util"; export function createMemoryFs( + log: Logger, fs: Map, root: RelativePath, - log: Logger, isReadonly: boolean, ): Cursor { const errors = FsErrors(log); diff --git a/src/next/fs/proxy-fs.ts b/src/next/fs/proxy-fs.ts index d667ab4311..ef74c6153e 100644 --- a/src/next/fs/proxy-fs.ts +++ b/src/next/fs/proxy-fs.ts @@ -11,8 +11,8 @@ import type { Logger } from "@/error/logger-util"; const asRecord = (t: Record) => t; export function createProxyFs( - root: string, log: Logger, + root: string, isReadonly: boolean, ): Cursor { const errors = FsErrors(log); diff --git a/src/next/fs/util.ts b/src/next/fs/util.ts index f148ecfd60..fc6f84ab0e 100644 --- a/src/next/fs/util.ts +++ b/src/next/fs/util.ts @@ -38,6 +38,11 @@ export const asString = ({ stepsUp, segments }: RelativePath): string => { */ export const emptyPath = RelativePath(0, []); +/** + * Parent path, equivalent to ".." + */ +export const parentPath = RelativePath(1, []); + /** * Combine two relative paths */ diff --git a/src/next/grammar/index.ts b/src/next/grammar/index.ts index 4d08f39fb5..5dfaa7d298 100644 --- a/src/next/grammar/index.ts +++ b/src/next/grammar/index.ts @@ -1787,27 +1787,25 @@ const parseModule = // return map(imports, parseImport)(ctx); // }; -export const getParser = (logRaw: SourceLogger) => { - const err = SyntaxErrors(logRaw); - - return (text: string): Ast.Module => { - const result = $.parse({ - grammar: G.Module, - space: G.space, - text, - }); +export const parse = (log: SourceLogger, text: string): Ast.Module => { + const err = SyntaxErrors(log); - if (result.$ === "error") { - const { expected, position } = result.error; - err.expected(expected)({ - start: position, - end: position, - }); - return Ast.Module([], []); - } + const result = $.parse({ + grammar: G.Module, + space: G.space, + text, + }); - return parseModule(result.value)({ - err, + if (result.$ === "error") { + const { expected, position } = result.error; + err.expected(expected)({ + start: position, + end: position, }); - }; + return Ast.Module([], []); + } + + return parseModule(result.value)({ + err, + }); }; diff --git a/src/next/index.ts b/src/next/index.ts index 8ae1dd7062..fa03e111bc 100644 --- a/src/next/index.ts +++ b/src/next/index.ts @@ -1,41 +1,157 @@ import path from "path"; -import { getParser } from "@/next/grammar"; +import { parse } from "@/next/grammar"; import { TerminalLogger } from "@/cli/logger"; import { getAnsiMarkup, isColorSupported } from "@/cli/colors"; import { inspect } from "util"; -import { createProxyFs } from "@/next/fs/proxy-fs"; -import { fromString } from "@/imports/path"; +import { emptyPath, fromString } from "@/imports/path"; +import { parentPath, createMemoryFs, createProxyFs } from "@/next/fs"; +import { getFiles } from "@/next/stdlib"; +import type { Cursor } from "@/next/fs"; +import type { AnyLogger, Logger, SourceLogger } from "@/error/logger-util"; +import type { ModuleItem, Range } from "@/next/ast"; -// const target = "wallet-v4.tact"; +const target = "wallet-v4.tact"; // const target = "generic.tact"; // const target = "union.tact"; -const target = "alias.tact"; +// const target = "alias.tact"; const dump = (obj: unknown) => // eslint-disable-next-line @typescript-eslint/no-confusing-void-expression console.log(inspect(obj, { colors: true, depth: Infinity })); -const main = async () => { - const ansi = getAnsiMarkup(isColorSupported()); - await TerminalLogger(path, "info", ansi, async (log) => { +export type TactSource = { + readonly code: string; + readonly imports: readonly Import[]; + readonly items: readonly ModuleItem[]; +}; +export type Import = TactImport | FuncImport +export type TactImport = { + readonly kind: 'tact'; + readonly source: TactSource; + readonly loc: Range; +} +export type FuncImport = { + readonly kind: 'func'; + readonly code: string; + readonly loc: Range; +} + +const fakeSource: TactSource = { code: '', imports: [], items: [] }; + +const readSource = async ( + log: Logger, + project: Cursor, + stdlib: Cursor, + implicits: readonly Import[], + rootModule: string, +): Promise => { + const status: Map = new Map(); + + const resolveImports = async ( + log: SourceLogger, + file: Cursor, + code: string, + ): Promise => { + const { imports: rawImports, items } = parse(log, code); + const imports: Import[] = [...implicits]; + for (const { importPath, loc } of rawImports) { + const { language, path, type } = importPath; + const importedFile = type === 'relative' + ? file.focus(parentPath).focus(path) + : stdlib.focus(path); + if (language === 'tact') { + const source = await resolveSource(importedFile, log); + imports.push({ kind: 'tact', source, loc }); + } else { + imports.push({ kind: 'func', code, loc }); + } + } + return { code, imports, items }; + }; + + const resolveSource = async ( + file: Cursor, + parentLog: AnyLogger, + ): Promise => { + const path = file.getAbsolutePathForLog(); + const res = status.get(path); + if (typeof res === 'object') { + return res; + } + if (res === 'pending') { + parentLog.error(parentLog.text`Cyclic import: ${parentLog.path(path)}`); + return fakeSource; + } + status.set(path, 'pending'); + const code = await file.read(); + if (!code) { + return fakeSource; + } + const source = await log.source(path, code, (log) => { + return resolveImports(log, file, code); + }); + status.set(path, source); + return source; + }; + + return resolveSource( + project.focus(fromString(rootModule)), + log, + ); +}; + +export const ProjectReader = async (log: Logger) => { + const stdRoot = createMemoryFs( + log, + getFiles(), + emptyPath, + true, + ); + const stdLibs = stdRoot.focus(fromString("libs")); + const stdStd = await readSource( + log, + stdRoot, + stdLibs, + [], + 'std/stdlib.tact', + ); + + const read = async ( + fsRootPath: string, + tactRoot: string, + ) => { const project = createProxyFs( - path.join(__dirname, "example"), log, + fsRootPath, false, ); + return await readSource( + log, + project, + stdLibs, + [{ + kind: 'tact', + source: stdStd, + loc: { start: 0, end: 0 }, + }], + tactRoot, + ); + }; + + return { read }; +}; - const file = project.focus(fromString(target)); - const code = await file.read(); - - if (code) { - log.source(file.getAbsolutePathForLog(), code, (log) => { - log.recover((log) => { - const parse = getParser(log); - const ast = parse(code); - dump(ast); - }); - }); - } +const main = async () => { + const ansi = getAnsiMarkup(isColorSupported()); + await TerminalLogger(path, "info", ansi, async (log) => { + await log.recover(async (log) => { + const reader = await ProjectReader(log); + const root = await reader.read( + path.join(__dirname, "example"), + target, + ); + console.log(root); + }); }); }; diff --git a/src/next/stdlib/index.ts b/src/next/stdlib/index.ts new file mode 100644 index 0000000000..8818f76ac9 --- /dev/null +++ b/src/next/stdlib/index.ts @@ -0,0 +1,21 @@ +import { files as filesBase64 } from "@/stdlib/stdlib"; + +function base64ToBlob(base64: string): Blob { + const binary = atob(base64); + const len = binary.length; + const bytes = new Uint8Array(len); + for (let i = 0; i < len; ++i) { + bytes[i] = binary.charCodeAt(i); + } + return new Blob([bytes], { type: "text/plain;charset=utf-8" }); +} + +export const getFiles = () => { + const files: Map = new Map(); + + for (const [path, base64] of Object.entries(filesBase64)) { + files.set(path, base64ToBlob(base64)); + } + + return files; +} From e356219f574dd275f092717b43a8bfcd3d2745f4 Mon Sep 17 00:00:00 2001 From: verytactical <186486509+verytactical@users.noreply.github.com> Date: Tue, 15 Apr 2025 10:29:45 +0400 Subject: [PATCH 10/38] comments --- src/next/fs/memory-fs.ts | 2 ++ src/next/fs/proxy-fs.ts | 1 + src/next/index.ts | 12 ++++++++++++ 3 files changed, 15 insertions(+) diff --git a/src/next/fs/memory-fs.ts b/src/next/fs/memory-fs.ts index da72ed1211..76e43e4da9 100644 --- a/src/next/fs/memory-fs.ts +++ b/src/next/fs/memory-fs.ts @@ -5,7 +5,9 @@ import type { RelativePath } from "@/next/fs/path"; import type { Cursor } from "@/next/fs/cursor"; import type { Logger } from "@/error/logger-util"; +// FIXME: object export function createMemoryFs( + // FIXME: should we pass log here, or into functions? log: Logger, fs: Map, root: RelativePath, diff --git a/src/next/fs/proxy-fs.ts b/src/next/fs/proxy-fs.ts index ef74c6153e..2f539b0d26 100644 --- a/src/next/fs/proxy-fs.ts +++ b/src/next/fs/proxy-fs.ts @@ -10,6 +10,7 @@ import type { Logger } from "@/error/logger-util"; const asRecord = (t: Record) => t; +// FIXME: object export function createProxyFs( log: Logger, root: string, diff --git a/src/next/index.ts b/src/next/index.ts index fa03e111bc..94b4779744 100644 --- a/src/next/index.ts +++ b/src/next/index.ts @@ -38,13 +38,16 @@ export type FuncImport = { const fakeSource: TactSource = { code: '', imports: [], items: [] }; +// FIXME: object const readSource = async ( log: Logger, project: Cursor, stdlib: Cursor, + // FIXME: are FuncImport implicit imports valid? implicits: readonly Import[], rootModule: string, ): Promise => { + // FIXME: should we use a proper ADT for values? const status: Map = new Map(); const resolveImports = async ( @@ -71,6 +74,7 @@ const readSource = async ( const resolveSource = async ( file: Cursor, + // FIXME: there can't be circular imports at top level parentLog: AnyLogger, ): Promise => { const path = file.getAbsolutePathForLog(); @@ -80,6 +84,7 @@ const readSource = async ( } if (res === 'pending') { parentLog.error(parentLog.text`Cyclic import: ${parentLog.path(path)}`); + // FIXME: return undefined instead, then don't do `import.push`? return fakeSource; } status.set(path, 'pending'); @@ -100,6 +105,9 @@ const readSource = async ( ); }; +/** + * Read standard library and prepare for reading projects + */ export const ProjectReader = async (log: Logger) => { const stdRoot = createMemoryFs( log, @@ -116,6 +124,9 @@ export const ProjectReader = async (log: Logger) => { 'std/stdlib.tact', ); + /** + * Read project + */ const read = async ( fsRootPath: string, tactRoot: string, @@ -145,6 +156,7 @@ const main = async () => { const ansi = getAnsiMarkup(isColorSupported()); await TerminalLogger(path, "info", ansi, async (log) => { await log.recover(async (log) => { + // TODO: new CLI based (see typegen) const reader = await ProjectReader(log); const root = await reader.read( path.join(__dirname, "example"), From fdcb7e7e278e43f40fcbbfb4010845120aa04e21 Mon Sep 17 00:00:00 2001 From: verytactical <186486509+verytactical@users.noreply.github.com> Date: Tue, 15 Apr 2025 10:30:50 +0400 Subject: [PATCH 11/38] comments --- src/next/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/next/index.ts b/src/next/index.ts index 94b4779744..8704c6eec6 100644 --- a/src/next/index.ts +++ b/src/next/index.ts @@ -21,6 +21,7 @@ const dump = (obj: unknown) => export type TactSource = { readonly code: string; + // FIXME: should we REALLY resolve imports here? readonly imports: readonly Import[]; readonly items: readonly ModuleItem[]; }; From 197dca034e7afbf7930f4937212509269a8096d6 Mon Sep 17 00:00:00 2001 From: verytactical <186486509+verytactical@users.noreply.github.com> Date: Thu, 17 Apr 2025 03:45:25 +0400 Subject: [PATCH 12/38] refactor --- src/next/fs/memory-fs.ts | 39 ++++++++-- src/next/fs/proxy-fs.ts | 16 ++-- src/next/grammar/errors.ts | 5 +- src/next/imports/reader.ts | 141 ++++++++++++++++++++++++++++++++++ src/next/imports/source.ts | 18 +++++ src/next/index.ts | 151 +------------------------------------ 6 files changed, 205 insertions(+), 165 deletions(-) create mode 100644 src/next/imports/reader.ts create mode 100644 src/next/imports/source.ts diff --git a/src/next/fs/memory-fs.ts b/src/next/fs/memory-fs.ts index 76e43e4da9..19db1ab365 100644 --- a/src/next/fs/memory-fs.ts +++ b/src/next/fs/memory-fs.ts @@ -5,13 +5,36 @@ import type { RelativePath } from "@/next/fs/path"; import type { Cursor } from "@/next/fs/cursor"; import type { Logger } from "@/error/logger-util"; -// FIXME: object -export function createMemoryFs( +type Options = { // FIXME: should we pass log here, or into functions? - log: Logger, - fs: Map, - root: RelativePath, - isReadonly: boolean, + readonly log: Logger, + + /** + * Files present in memory file system at creation time + */ + readonly files: Map, + + /** + * Path to the root, used only for logging + * + * Absolute paths do not make sense in memory FS, as + * it doesn't have the actual root + */ + readonly root: RelativePath, + + /** + * Whether it's possible to `write` into + */ + readonly isReadonly: boolean, +} + +export const emptyFiles: Map = new Map(); + +/** + * Create in-memory file system + */ +export function createMemoryFs( + { log, files, root, isReadonly }: Options ): Cursor { const errors = FsErrors(log); @@ -30,7 +53,7 @@ export function createMemoryFs( }, read: async () => { const fullPath = asString(appendPath(root, currPath)); - const blob = fs.get(fullPath); + const blob = files.get(fullPath); if (typeof blob === "undefined") { errors.regular.ENOENT(getAbsolutePathForLog()); return; @@ -51,7 +74,7 @@ export function createMemoryFs( type: "text/plain;charset=utf-8", }) : content; - fs.set(fullPath, blob); + files.set(fullPath, blob); }, }; } diff --git a/src/next/fs/proxy-fs.ts b/src/next/fs/proxy-fs.ts index 2f539b0d26..0a9c871697 100644 --- a/src/next/fs/proxy-fs.ts +++ b/src/next/fs/proxy-fs.ts @@ -10,12 +10,16 @@ import type { Logger } from "@/error/logger-util"; const asRecord = (t: Record) => t; -// FIXME: object -export function createProxyFs( - log: Logger, - root: string, - isReadonly: boolean, -): Cursor { +type Options = { + readonly log: Logger, + readonly root: string, + readonly isReadonly: boolean, +}; + +/** + * Create file system that proxies requests to real file system + */ +export function createProxyFs({ log, root, isReadonly }: Options): Cursor { const errors = FsErrors(log); function builder(currPath: RelativePath): Cursor { diff --git a/src/next/grammar/errors.ts b/src/next/grammar/errors.ts index 45edb409fb..eeff6b55cc 100644 --- a/src/next/grammar/errors.ts +++ b/src/next/grammar/errors.ts @@ -211,8 +211,9 @@ export const SyntaxErrors = (l: SourceLogger) => ({ cannotHaveFormat: () => (loc: Range) => { return l.at(loc).error(l.text`This type cannot have format definition`); }, - deprecatedPrimitiveDecl: () => (loc: Range) => { - l.at(loc).warn(l.text`"primitive" type declaration are deprecated`); + deprecatedPrimitiveDecl: () => (_loc: Range) => { + // FIXME: enable after src2 replaces src + // l.at(loc).warn(l.text`"primitive" type declaration are deprecated`); }, constDeclNoType: () => (loc: Range) => { return l.at(loc).error(l.text`Constant declaration must have a type`); diff --git a/src/next/imports/reader.ts b/src/next/imports/reader.ts new file mode 100644 index 0000000000..5cf72db85d --- /dev/null +++ b/src/next/imports/reader.ts @@ -0,0 +1,141 @@ +import { parse } from "@/next/grammar"; +import { emptyPath, fromString } from "@/imports/path"; +import { parentPath, createMemoryFs, createProxyFs } from "@/next/fs"; +import { getFiles } from "@/next/stdlib"; +import type { Cursor } from "@/next/fs"; +import type { AnyLogger, Logger, SourceLogger } from "@/error/logger-util"; +import type { ResolvedImport, TactSource } from "@/next/imports/source"; + +type Options = { + readonly log: Logger, + /** + * Cursor to root of file system with project files + */ + readonly project: Cursor, + /** + * Cursor to root of stdlib file system + */ + readonly stdlib: Cursor, + /** + * Implicit imports (without `import "..."`) to add + * into every source + */ + readonly implicits: readonly ResolvedImport[], + /** + * Name of root source file of the project + */ + readonly root: string, +} + +const readSource = async ({ + log, project, stdlib, implicits, root +}: Options): Promise => { + const status: Map = new Map(); + + const resolveImports = async ( + log: SourceLogger, + file: Cursor, + code: string, + ): Promise => { + const { imports: rawImports, items } = parse(log, code); + const imports: ResolvedImport[] = [...implicits]; + for (const { importPath, loc } of rawImports) { + const { language, path, type } = importPath; + const importedFile = type === 'relative' + ? file.focus(parentPath).focus(path) + : stdlib.focus(path); + if (language === 'tact') { + const source = await resolveSource(importedFile, log); + if (source) { + imports.push({ kind: 'tact', source, loc }); + } + } else { + imports.push({ kind: 'func', code, loc }); + } + } + return { code, imports, items }; + }; + + const resolveSource = async ( + file: Cursor, + parentLog: AnyLogger, + ): Promise => { + const path = file.getAbsolutePathForLog(); + const res = status.get(path); + if (typeof res === 'object') { + return res; + } + if (res === 'pending') { + parentLog.error(parentLog.text`Cyclic import: ${parentLog.path(path)}`); + return; + } + status.set(path, 'pending'); + const code = await file.read(); + if (!code) { + return; + } + const source = await log.source(path, code, (log) => { + return resolveImports(log, file, code); + }); + status.set(path, source); + return source; + }; + + return resolveSource( + project.focus(fromString(root)), + log, + ); +}; + +/** + * Read standard library and prepare for reading projects + */ +export const ProjectReader = async (log: Logger) => { + const stdRoot = createMemoryFs({ + log, + files: getFiles(), + root: emptyPath, + isReadonly: true, + }); + const stdLibs = stdRoot.focus(fromString("libs")); + const stdStd = await readSource({ + log, + project: stdRoot, + stdlib: stdLibs, + implicits: [], + root: 'std/stdlib.tact', + }); + if (!stdStd) { + // Could not load standard library + // No compilation is possible + return; + } + + /** + * Read project + */ + const read = async ( + fsRootPath: string, + tactRoot: string, + ) => { + const project = createProxyFs({ + log, + root: fsRootPath, + isReadonly: false, + }); + const implicits: ResolvedImport[] = [{ + kind: 'tact', + source: stdStd, + loc: { start: 0, end: 0 }, + }]; + return await readSource({ + log, + project, + stdlib: stdLibs, + implicits, + root: tactRoot, + }); + }; + + return { read }; +}; \ No newline at end of file diff --git a/src/next/imports/source.ts b/src/next/imports/source.ts new file mode 100644 index 0000000000..bcaa7da54b --- /dev/null +++ b/src/next/imports/source.ts @@ -0,0 +1,18 @@ +import type { ModuleItem, Range } from "@/next/ast"; + +export type TactSource = { + readonly code: string; + readonly imports: readonly ResolvedImport[]; + readonly items: readonly ModuleItem[]; +}; +export type ResolvedImport = TactImport | FuncImport +export type TactImport = { + readonly kind: 'tact'; + readonly source: TactSource; + readonly loc: Range; +} +export type FuncImport = { + readonly kind: 'func'; + readonly code: string; + readonly loc: Range; +} diff --git a/src/next/index.ts b/src/next/index.ts index 8704c6eec6..fa94c1ce1d 100644 --- a/src/next/index.ts +++ b/src/next/index.ts @@ -1,157 +1,9 @@ import path from "path"; -import { parse } from "@/next/grammar"; import { TerminalLogger } from "@/cli/logger"; import { getAnsiMarkup, isColorSupported } from "@/cli/colors"; -import { inspect } from "util"; -import { emptyPath, fromString } from "@/imports/path"; -import { parentPath, createMemoryFs, createProxyFs } from "@/next/fs"; -import { getFiles } from "@/next/stdlib"; -import type { Cursor } from "@/next/fs"; -import type { AnyLogger, Logger, SourceLogger } from "@/error/logger-util"; -import type { ModuleItem, Range } from "@/next/ast"; +import { ProjectReader } from "@/next/imports/reader"; const target = "wallet-v4.tact"; -// const target = "generic.tact"; -// const target = "union.tact"; -// const target = "alias.tact"; - -const dump = (obj: unknown) => - // eslint-disable-next-line @typescript-eslint/no-confusing-void-expression - console.log(inspect(obj, { colors: true, depth: Infinity })); - -export type TactSource = { - readonly code: string; - // FIXME: should we REALLY resolve imports here? - readonly imports: readonly Import[]; - readonly items: readonly ModuleItem[]; -}; -export type Import = TactImport | FuncImport -export type TactImport = { - readonly kind: 'tact'; - readonly source: TactSource; - readonly loc: Range; -} -export type FuncImport = { - readonly kind: 'func'; - readonly code: string; - readonly loc: Range; -} - -const fakeSource: TactSource = { code: '', imports: [], items: [] }; - -// FIXME: object -const readSource = async ( - log: Logger, - project: Cursor, - stdlib: Cursor, - // FIXME: are FuncImport implicit imports valid? - implicits: readonly Import[], - rootModule: string, -): Promise => { - // FIXME: should we use a proper ADT for values? - const status: Map = new Map(); - - const resolveImports = async ( - log: SourceLogger, - file: Cursor, - code: string, - ): Promise => { - const { imports: rawImports, items } = parse(log, code); - const imports: Import[] = [...implicits]; - for (const { importPath, loc } of rawImports) { - const { language, path, type } = importPath; - const importedFile = type === 'relative' - ? file.focus(parentPath).focus(path) - : stdlib.focus(path); - if (language === 'tact') { - const source = await resolveSource(importedFile, log); - imports.push({ kind: 'tact', source, loc }); - } else { - imports.push({ kind: 'func', code, loc }); - } - } - return { code, imports, items }; - }; - - const resolveSource = async ( - file: Cursor, - // FIXME: there can't be circular imports at top level - parentLog: AnyLogger, - ): Promise => { - const path = file.getAbsolutePathForLog(); - const res = status.get(path); - if (typeof res === 'object') { - return res; - } - if (res === 'pending') { - parentLog.error(parentLog.text`Cyclic import: ${parentLog.path(path)}`); - // FIXME: return undefined instead, then don't do `import.push`? - return fakeSource; - } - status.set(path, 'pending'); - const code = await file.read(); - if (!code) { - return fakeSource; - } - const source = await log.source(path, code, (log) => { - return resolveImports(log, file, code); - }); - status.set(path, source); - return source; - }; - - return resolveSource( - project.focus(fromString(rootModule)), - log, - ); -}; - -/** - * Read standard library and prepare for reading projects - */ -export const ProjectReader = async (log: Logger) => { - const stdRoot = createMemoryFs( - log, - getFiles(), - emptyPath, - true, - ); - const stdLibs = stdRoot.focus(fromString("libs")); - const stdStd = await readSource( - log, - stdRoot, - stdLibs, - [], - 'std/stdlib.tact', - ); - - /** - * Read project - */ - const read = async ( - fsRootPath: string, - tactRoot: string, - ) => { - const project = createProxyFs( - log, - fsRootPath, - false, - ); - return await readSource( - log, - project, - stdLibs, - [{ - kind: 'tact', - source: stdStd, - loc: { start: 0, end: 0 }, - }], - tactRoot, - ); - }; - - return { read }; -}; const main = async () => { const ansi = getAnsiMarkup(isColorSupported()); @@ -159,6 +11,7 @@ const main = async () => { await log.recover(async (log) => { // TODO: new CLI based (see typegen) const reader = await ProjectReader(log); + if (!reader) return; const root = await reader.read( path.join(__dirname, "example"), target, From b8818e8b797c01445b524713b813b94bc26c327a Mon Sep 17 00:00:00 2001 From: verytactical <186486509+verytactical@users.noreply.github.com> Date: Thu, 24 Apr 2025 11:44:19 +0400 Subject: [PATCH 13/38] map literals --- src/next/ast/expression.ts | 25 +++++- src/next/ast/generated/expression.ts | 34 ++++++++ src/next/ast/generated/type.ts | 9 ++ src/next/ast/type.ts | 8 ++ src/next/fs/memory-fs.ts | 21 +++-- src/next/fs/proxy-fs.ts | 6 +- src/next/grammar/errors.ts | 8 ++ src/next/grammar/gen.sh | 2 +- .../grammar/{grammar.gg => grammar.peggy} | 17 ++++ src/next/grammar/grammar.ts | 84 +++++++++++++++++-- src/next/grammar/index.ts | 84 ++++++++++++++++++- src/next/imports/reader.ts | 71 ++++++++-------- src/next/imports/source.ts | 10 +-- src/next/stdlib/index.ts | 2 +- 14 files changed, 318 insertions(+), 63 deletions(-) rename src/next/grammar/{grammar.gg => grammar.peggy} (97%) diff --git a/src/next/ast/expression.ts b/src/next/ast/expression.ts index 91288e330b..844ea0201a 100644 --- a/src/next/ast/expression.ts +++ b/src/next/ast/expression.ts @@ -1,5 +1,5 @@ import type { Id, Range, TypeId } from "@/next/ast/common"; -import type { Type } from "@/next/ast/type"; +import type { Type, TypeMap } from "@/next/ast/type"; export type Expression = | OpBinary @@ -18,7 +18,9 @@ export type Expression = | Var | Unit | Tuple - | Tensor; + | Tensor + | MapLiteral + | SetLiteral; export type Var = { readonly kind: "var"; @@ -133,6 +135,25 @@ export type StructFieldInitializer = { readonly loc: Range; }; +export type MapLiteral = { + readonly kind: "map_literal"; + readonly type: TypeMap; + readonly fields: readonly MapField[]; + readonly loc: Range; +}; + +export type MapField = { + readonly key: Expression; + readonly value: Expression; +}; + +export type SetLiteral = { + readonly kind: "set_literal"; + readonly valueType: Type; + readonly fields: readonly Expression[]; + readonly loc: Range; +}; + export type InitOf = { readonly kind: "init_of"; readonly contract: TypeId; diff --git a/src/next/ast/generated/expression.ts b/src/next/ast/generated/expression.ts index 8aee654c2e..f426b34922 100644 --- a/src/next/ast/generated/expression.ts +++ b/src/next/ast/generated/expression.ts @@ -251,3 +251,37 @@ export const OpBinary = ( }); export const isOpBinary = ($value: OpBinary) => $value.kind === "op_binary"; export type Expression = $.Expression; +export type MapField = $.MapField; +export const MapField = (key: $.Expression, value: $.Expression): $.MapField => + Object.freeze({ + key, + value, + }); +export type MapLiteral = $.MapLiteral; +export const MapLiteral = ( + type_: $t.TypeMap, + fields: readonly $.MapField[], + loc: $c.Range, +): $.MapLiteral => + Object.freeze({ + kind: "map_literal", + type: type_, + fields, + loc, + }); +export const isMapLiteral = ($value: MapLiteral) => + $value.kind === "map_literal"; +export type SetLiteral = $.SetLiteral; +export const SetLiteral = ( + valueType: $t.Type, + fields: readonly $.Expression[], + loc: $c.Range, +): $.SetLiteral => + Object.freeze({ + kind: "set_literal", + valueType, + fields, + loc, + }); +export const isSetLiteral = ($value: SetLiteral) => + $value.kind === "set_literal"; diff --git a/src/next/ast/generated/type.ts b/src/next/ast/generated/type.ts index 22a77b21e3..14a69f30e7 100644 --- a/src/next/ast/generated/type.ts +++ b/src/next/ast/generated/type.ts @@ -138,3 +138,12 @@ export const TypeCons = ( }); export const isTypeCons = ($value: TypeCons) => $value.kind === "cons_type"; export type Type = $.Type; +export type TypeMap = $.TypeMap; +export const TypeMap = (key: $.Type, value: $.Type, loc: $c.Range): $.TypeMap => + Object.freeze({ + kind: "map_type", + key, + value, + loc, + }); +export const isTypeMap = ($value: TypeMap) => $value.kind === "map_type"; diff --git a/src/next/ast/type.ts b/src/next/ast/type.ts index 45cdcbb26f..ea5d89438c 100644 --- a/src/next/ast/type.ts +++ b/src/next/ast/type.ts @@ -1,6 +1,7 @@ import type { Range, TypeId } from "@/next/ast/common"; export type Type = + | TypeMap | TypeCons | TypeInt | TypeSlice @@ -86,3 +87,10 @@ export type TypeTensor = { readonly typeArgs: readonly Type[]; readonly loc: Range; }; + +export type TypeMap = { + readonly kind: "map_type"; + readonly key: Type; // any type except tensor + readonly value: Type; // any type except tensor + readonly loc: Range; +}; diff --git a/src/next/fs/memory-fs.ts b/src/next/fs/memory-fs.ts index 19db1ab365..ac977075e6 100644 --- a/src/next/fs/memory-fs.ts +++ b/src/next/fs/memory-fs.ts @@ -7,35 +7,38 @@ import type { Logger } from "@/error/logger-util"; type Options = { // FIXME: should we pass log here, or into functions? - readonly log: Logger, + readonly log: Logger; /** * Files present in memory file system at creation time */ - readonly files: Map, + readonly files: Map; /** * Path to the root, used only for logging - * + * * Absolute paths do not make sense in memory FS, as * it doesn't have the actual root */ - readonly root: RelativePath, + readonly root: RelativePath; /** * Whether it's possible to `write` into */ - readonly isReadonly: boolean, -} + readonly isReadonly: boolean; +}; export const emptyFiles: Map = new Map(); /** * Create in-memory file system */ -export function createMemoryFs( - { log, files, root, isReadonly }: Options -): Cursor { +export function createMemoryFs({ + log, + files, + root, + isReadonly, +}: Options): Cursor { const errors = FsErrors(log); function builder(currPath: RelativePath): Cursor { diff --git a/src/next/fs/proxy-fs.ts b/src/next/fs/proxy-fs.ts index 0a9c871697..fdc8f46343 100644 --- a/src/next/fs/proxy-fs.ts +++ b/src/next/fs/proxy-fs.ts @@ -11,9 +11,9 @@ import type { Logger } from "@/error/logger-util"; const asRecord = (t: Record) => t; type Options = { - readonly log: Logger, - readonly root: string, - readonly isReadonly: boolean, + readonly log: Logger; + readonly root: string; + readonly isReadonly: boolean; }; /** diff --git a/src/next/grammar/errors.ts b/src/next/grammar/errors.ts index eeff6b55cc..d1ebaee863 100644 --- a/src/next/grammar/errors.ts +++ b/src/next/grammar/errors.ts @@ -218,6 +218,14 @@ export const SyntaxErrors = (l: SourceLogger) => ({ constDeclNoType: () => (loc: Range) => { return l.at(loc).error(l.text`Constant declaration must have a type`); }, + mapArgCount: () => (loc: Range) => { + return l + .at(loc) + .error(l.text`map takes exactly two type arguments`); + }, + setArgCount: () => (loc: Range) => { + return l.at(loc).error(l.text`set takes exactly one type argument`); + }, }); export type SyntaxErrors = ReturnType>; diff --git a/src/next/grammar/gen.sh b/src/next/grammar/gen.sh index b7bcda7f65..a823230ecc 100755 --- a/src/next/grammar/gen.sh +++ b/src/next/grammar/gen.sh @@ -1 +1 @@ -pgen src/next/grammar/grammar.gg -o src/next/grammar/grammar.ts +pgen src/next/grammar/grammar.peggy -o src/next/grammar/grammar.ts diff --git a/src/next/grammar/grammar.gg b/src/next/grammar/grammar.peggy similarity index 97% rename from src/next/grammar/grammar.gg rename to src/next/grammar/grammar.peggy index 7dabe6e9b3..3468f9fcca 100644 --- a/src/next/grammar/grammar.gg +++ b/src/next/grammar/grammar.peggy @@ -322,6 +322,8 @@ primary / Tensor / Tuple / Parens + / MapLiteral + / SetLiteral / StructInstance / IntegerLiteral / BoolLiteral @@ -348,6 +350,21 @@ StructInstance = "}"; StructFieldInitializer = name:Id init:(":" @expression)?; +MapLiteral = + keyword<"map"> + typeArgs:typeArgs + "{" + fields:commaList? + "}"; +mapField = key:expression ":" value:expression; + +SetLiteral = + "set" + typeArgs:typeArgs + "{" + fields:commaList? + "}"; + InitOf = keyword<"initOf"> name:TypeId params:parameterList; CodeOf = "codeOf" name:TypeId; diff --git a/src/next/grammar/grammar.ts b/src/next/grammar/grammar.ts index 1387c33ce1..f2a6f24fb0 100644 --- a/src/next/grammar/grammar.ts +++ b/src/next/grammar/grammar.ts @@ -493,6 +493,16 @@ export namespace $ast { readonly $: "Parens"; readonly child: parens; }>; + export type MapLiteral = $.Located<{ + readonly $: "MapLiteral"; + readonly typeArgs: typeArgs; + readonly fields: commaList | undefined; + }>; + export type SetLiteral = $.Located<{ + readonly $: "SetLiteral"; + readonly typeArgs: typeArgs; + readonly fields: commaList | undefined; + }>; export type StructInstance = $.Located<{ readonly $: "StructInstance"; readonly type: TypeId; @@ -528,6 +538,8 @@ export namespace $ast { | Tensor | Tuple | Parens + | MapLiteral + | SetLiteral | StructInstance | IntegerLiteral | BoolLiteral @@ -542,6 +554,10 @@ export namespace $ast { readonly name: Id; readonly init: expression | undefined; }>; + export type mapField = { + readonly key: expression; + readonly value: expression; + }; export type ParameterList = $.Located<{ readonly $: "ParameterList"; readonly values: commaList | undefined; @@ -2290,6 +2306,48 @@ export const Parens: $.Parser<$ast.Parens> = $.loc( ), ), ); +export const MapLiteral: $.Parser<$ast.MapLiteral> = $.loc( + $.field( + $.pure("MapLiteral"), + "$", + $.right( + keyword($.str("map")), + $.field( + typeArgs, + "typeArgs", + $.right( + $.str("{"), + $.field( + $.opt(commaList($.lazy(() => mapField))), + "fields", + $.right($.str("}"), $.eps), + ), + ), + ), + ), + ), +); +export const SetLiteral: $.Parser<$ast.SetLiteral> = $.loc( + $.field( + $.pure("SetLiteral"), + "$", + $.right( + $.str("set"), + $.field( + typeArgs, + "typeArgs", + $.right( + $.str("{"), + $.field( + $.opt(commaList(expression)), + "fields", + $.right($.str("}"), $.eps), + ), + ), + ), + ), + ), +); export const StructInstance: $.Parser<$ast.StructInstance> = $.loc( $.field( $.pure("StructInstance"), @@ -2380,16 +2438,25 @@ export const primary: $.Parser<$ast.primary> = $.alt( $.alt( Parens, $.alt( - StructInstance, + MapLiteral, $.alt( - IntegerLiteral, + SetLiteral, $.alt( - BoolLiteral, + StructInstance, $.alt( - InitOf, + IntegerLiteral, $.alt( - CodeOf, - $.alt(Null, $.alt(StringLiteral, Id)), + BoolLiteral, + $.alt( + InitOf, + $.alt( + CodeOf, + $.alt( + Null, + $.alt(StringLiteral, Id), + ), + ), + ), ), ), ), @@ -2415,6 +2482,11 @@ export const StructFieldInitializer: $.Parser<$ast.StructFieldInitializer> = ), ), ); +export const mapField: $.Parser<$ast.mapField> = $.field( + expression, + "key", + $.right($.str(":"), $.field(expression, "value", $.eps)), +); export const ParameterList = ( T: $.Parser, ): $.Parser<$ast.ParameterList> => diff --git a/src/next/grammar/index.ts b/src/next/grammar/index.ts index 5dfaa7d298..8e3968eb05 100644 --- a/src/next/grammar/index.ts +++ b/src/next/grammar/index.ts @@ -342,6 +342,79 @@ const parseStructInstance = ); }; +const parseMapArgs = + (typeArgs: $ast.typeArgs, range: Range): Handler => + (ctx) => { + const args = parseList(typeArgs); + const [keyType, valueType] = args; + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + if (args.length !== 2 || !keyType || !valueType) { + ctx.err.mapArgCount()(range); + return Ast.TypeMap( + Ast.TypeCons(Ast.TypeId("ERROR", range), [], range), + Ast.TypeCons(Ast.TypeId("ERROR", range), [], range), + range, + ); + } + return Ast.TypeMap( + parseType(keyType)(ctx), + parseType(valueType)(ctx), + range, + ); + }; + +const parseMapLiteral = + ({ typeArgs, fields, loc }: $ast.MapLiteral): Handler => + (ctx) => { + const range = toRange(loc); + return Ast.MapLiteral( + parseMapArgs(typeArgs, range)(ctx), + map(parseList(fields), parseMapField)(ctx), + range, + ); + }; + +const parseMapField = + ({ key, value }: $ast.mapField): Handler => + (ctx) => { + return Ast.MapField( + parseExpression(key)(ctx), + parseExpression(value)(ctx), + ); + }; + +const parseSetArgs = + (typeArgs: $ast.typeArgs, range: Range): Handler => + (ctx) => { + const args = parseList(typeArgs); + const [valueType] = args; + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + if (args.length !== 1 || !valueType) { + ctx.err.setArgCount()(range); + return Ast.TypeMap( + Ast.TypeCons(Ast.TypeId("ERROR", range), [], range), + Ast.TypeUnit(range), + range, + ); + } + return Ast.TypeMap( + parseType(valueType)(ctx), + Ast.TypeUnit(range), + range, + ); + }; + +const parseSetLiteral = + ({ typeArgs, fields, loc }: $ast.SetLiteral): Handler => + (ctx) => { + const range = toRange(loc); + return Ast.SetLiteral( + parseSetArgs(typeArgs, range)(ctx), + map(parseList(fields), parseExpression)(ctx), + range, + ); + }; + const parseInitOf = ({ name, params, loc }: $ast.InitOf): Handler => (ctx) => { @@ -539,7 +612,9 @@ type Expression = | $ast.Id | $ast.Unit | $ast.Tensor - | $ast.Tuple; + | $ast.Tuple + | $ast.MapLiteral + | $ast.SetLiteral; const parseExpression: (input: Expression) => Handler = makeVisitor()({ @@ -559,6 +634,8 @@ const parseExpression: (input: Expression) => Handler = Unit: parseUnit, Tensor: parseTensor, Tuple: parseTuple, + MapLiteral: parseMapLiteral, + SetLiteral: parseSetLiteral, }); const parseStatementLet = @@ -1787,7 +1864,10 @@ const parseModule = // return map(imports, parseImport)(ctx); // }; -export const parse = (log: SourceLogger, text: string): Ast.Module => { +export const parse = ( + log: SourceLogger, + text: string, +): Ast.Module => { const err = SyntaxErrors(log); const result = $.parse({ diff --git a/src/next/imports/reader.ts b/src/next/imports/reader.ts index 5cf72db85d..6384dd588e 100644 --- a/src/next/imports/reader.ts +++ b/src/next/imports/reader.ts @@ -7,30 +7,34 @@ import type { AnyLogger, Logger, SourceLogger } from "@/error/logger-util"; import type { ResolvedImport, TactSource } from "@/next/imports/source"; type Options = { - readonly log: Logger, + readonly log: Logger; /** * Cursor to root of file system with project files */ - readonly project: Cursor, + readonly project: Cursor; /** * Cursor to root of stdlib file system */ - readonly stdlib: Cursor, + readonly stdlib: Cursor; /** * Implicit imports (without `import "..."`) to add * into every source */ - readonly implicits: readonly ResolvedImport[], + readonly implicits: readonly ResolvedImport[]; /** * Name of root source file of the project */ - readonly root: string, -} + readonly root: string; +}; const readSource = async ({ - log, project, stdlib, implicits, root + log, + project, + stdlib, + implicits, + root, }: Options): Promise => { - const status: Map = new Map(); + const status: Map = new Map(); const resolveImports = async ( log: SourceLogger, @@ -41,16 +45,17 @@ const readSource = async ({ const imports: ResolvedImport[] = [...implicits]; for (const { importPath, loc } of rawImports) { const { language, path, type } = importPath; - const importedFile = type === 'relative' - ? file.focus(parentPath).focus(path) - : stdlib.focus(path); - if (language === 'tact') { + const importedFile = + type === "relative" + ? file.focus(parentPath).focus(path) + : stdlib.focus(path); + if (language === "tact") { const source = await resolveSource(importedFile, log); if (source) { - imports.push({ kind: 'tact', source, loc }); + imports.push({ kind: "tact", source, loc }); } } else { - imports.push({ kind: 'func', code, loc }); + imports.push({ kind: "func", code, loc }); } } return { code, imports, items }; @@ -62,14 +67,16 @@ const readSource = async ({ ): Promise => { const path = file.getAbsolutePathForLog(); const res = status.get(path); - if (typeof res === 'object') { + if (typeof res === "object") { return res; } - if (res === 'pending') { - parentLog.error(parentLog.text`Cyclic import: ${parentLog.path(path)}`); + if (res === "pending") { + parentLog.error( + parentLog.text`Cyclic import: ${parentLog.path(path)}`, + ); return; } - status.set(path, 'pending'); + status.set(path, "pending"); const code = await file.read(); if (!code) { return; @@ -81,10 +88,7 @@ const readSource = async ({ return source; }; - return resolveSource( - project.focus(fromString(root)), - log, - ); + return resolveSource(project.focus(fromString(root)), log); }; /** @@ -103,7 +107,7 @@ export const ProjectReader = async (log: Logger) => { project: stdRoot, stdlib: stdLibs, implicits: [], - root: 'std/stdlib.tact', + root: "std/stdlib.tact", }); if (!stdStd) { // Could not load standard library @@ -114,20 +118,19 @@ export const ProjectReader = async (log: Logger) => { /** * Read project */ - const read = async ( - fsRootPath: string, - tactRoot: string, - ) => { + const read = async (fsRootPath: string, tactRoot: string) => { const project = createProxyFs({ log, root: fsRootPath, isReadonly: false, }); - const implicits: ResolvedImport[] = [{ - kind: 'tact', - source: stdStd, - loc: { start: 0, end: 0 }, - }]; + const implicits: ResolvedImport[] = [ + { + kind: "tact", + source: stdStd, + loc: { start: 0, end: 0 }, + }, + ]; return await readSource({ log, project, @@ -136,6 +139,6 @@ export const ProjectReader = async (log: Logger) => { root: tactRoot, }); }; - + return { read }; -}; \ No newline at end of file +}; diff --git a/src/next/imports/source.ts b/src/next/imports/source.ts index bcaa7da54b..a6a4291cbc 100644 --- a/src/next/imports/source.ts +++ b/src/next/imports/source.ts @@ -5,14 +5,14 @@ export type TactSource = { readonly imports: readonly ResolvedImport[]; readonly items: readonly ModuleItem[]; }; -export type ResolvedImport = TactImport | FuncImport +export type ResolvedImport = TactImport | FuncImport; export type TactImport = { - readonly kind: 'tact'; + readonly kind: "tact"; readonly source: TactSource; readonly loc: Range; -} +}; export type FuncImport = { - readonly kind: 'func'; + readonly kind: "func"; readonly code: string; readonly loc: Range; -} +}; diff --git a/src/next/stdlib/index.ts b/src/next/stdlib/index.ts index 8818f76ac9..c755e32bdc 100644 --- a/src/next/stdlib/index.ts +++ b/src/next/stdlib/index.ts @@ -18,4 +18,4 @@ export const getFiles = () => { } return files; -} +}; From cd3b36ff3e7a33a18fc491f6faf4b343ad6be718 Mon Sep 17 00:00:00 2001 From: verytactical <186486509+verytactical@users.noreply.github.com> Date: Fri, 25 Apr 2025 17:49:08 +0400 Subject: [PATCH 14/38] circular imports --- src/next/ast/generated/statement.ts | 26 ---- src/next/ast/statement.ts | 13 -- src/next/example/mutual1.tact | 1 + src/next/example/mutual2.tact | 1 + src/next/grammar/errors.ts | 18 +-- src/next/grammar/import-parser.ts | 98 ++++++++++++ src/next/grammar/index.ts | 77 +--------- src/next/imports/reader.ts | 229 ++++++++++++++++++++++------ src/next/imports/source.ts | 12 +- src/next/index.ts | 21 ++- 10 files changed, 310 insertions(+), 186 deletions(-) create mode 100644 src/next/example/mutual1.tact create mode 100644 src/next/example/mutual2.tact create mode 100644 src/next/grammar/import-parser.ts diff --git a/src/next/ast/generated/statement.ts b/src/next/ast/generated/statement.ts index 6a4d868319..e08108fec2 100644 --- a/src/next/ast/generated/statement.ts +++ b/src/next/ast/generated/statement.ts @@ -220,29 +220,3 @@ export const StatementCondition = ( export const isStatementCondition = ($value: StatementCondition) => $value.kind === "statement_condition"; export type Statement = $.Statement; -export type DestructMapping = $.DestructMapping; -export const DestructMapping = ( - field: $c.Id, - name: $c.Id, - loc: $c.Range, -): $.DestructMapping => - Object.freeze({ - kind: "destruct_mapping", - field, - name, - loc, - }); -export const isDestructMapping = ($value: DestructMapping) => - $value.kind === "destruct_mapping"; -export type DestructEnd = $.DestructEnd; -export const DestructEnd = ( - ignoreUnspecifiedFields: boolean, - loc: $c.Range, -): $.DestructEnd => - Object.freeze({ - kind: "destruct_end", - ignoreUnspecifiedFields, - loc, - }); -export const isDestructEnd = ($value: DestructEnd) => - $value.kind === "destruct_end"; diff --git a/src/next/ast/statement.ts b/src/next/ast/statement.ts index ef2c922d5b..5baa797bf1 100644 --- a/src/next/ast/statement.ts +++ b/src/next/ast/statement.ts @@ -131,16 +131,3 @@ export type StatementBlock = { readonly statements: readonly Statement[]; readonly loc: Range; }; - -export type DestructMapping = { - readonly kind: "destruct_mapping"; - readonly field: Id; - readonly name: Id; - readonly loc: Range; -}; - -export type DestructEnd = { - readonly kind: "destruct_end"; - readonly ignoreUnspecifiedFields: boolean; - readonly loc: Range; -}; diff --git a/src/next/example/mutual1.tact b/src/next/example/mutual1.tact new file mode 100644 index 0000000000..55be01259a --- /dev/null +++ b/src/next/example/mutual1.tact @@ -0,0 +1 @@ +import "./mutual2"; diff --git a/src/next/example/mutual2.tact b/src/next/example/mutual2.tact new file mode 100644 index 0000000000..a2c0044033 --- /dev/null +++ b/src/next/example/mutual2.tact @@ -0,0 +1 @@ +import "./mutual1"; diff --git a/src/next/grammar/errors.ts b/src/next/grammar/errors.ts index d1ebaee863..c271a7e07f 100644 --- a/src/next/grammar/errors.ts +++ b/src/next/grammar/errors.ts @@ -1,5 +1,6 @@ import type { SourceLogger } from "@/error/logger-util"; import type { Range } from "@/error/range"; +import { ImportErrors } from "@/next/grammar/import-parser"; const attributeSchema = (name: string, l: SourceLogger) => ({ duplicate: (attr: string) => (loc: Range) => { @@ -22,6 +23,7 @@ const attributeSchema = (name: string, l: SourceLogger) => ({ export const SyntaxErrors = (l: SourceLogger) => ({ constant: attributeSchema("constant", l), function: attributeSchema("function", l), + imports: ImportErrors(l), topLevelConstantWithAttribute: () => (loc: Range) => { return l @@ -46,9 +48,6 @@ export const SyntaxErrors = (l: SourceLogger) => ({ restShouldBeLast: () => (loc: Range) => { return l.at(loc).error(l.text`Rest parameter should be last`); }, - importWithBackslash: () => (loc: Range) => { - return l.at(loc).error(l.text`Import path can't contain "\\"`); - }, reservedVarPrefix: (prefix: string) => (loc: Range) => { return l .at(loc) @@ -100,19 +99,6 @@ export const SyntaxErrors = (l: SourceLogger) => ({ l.text`Numbers with leading zeroes cannot use underscores for JS compatibility`, ); }, - noFolderImports: () => (loc: Range) => { - return l.at(loc).error(l.text`Cannot import a folder`); - }, - invalidImport: () => (loc: Range) => { - return l - .at(loc) - .error(l.text`Import must start with ./, ../ or @stdlib/`); - }, - escapingImport: () => (loc: Range) => { - return l - .at(loc) - .error(l.text`Standard library imports should be inside its root`); - }, asNotAllowed: () => (loc: Range) => { return l.at(loc).error(l.text`"as" type is not allowed here`); }, diff --git a/src/next/grammar/import-parser.ts b/src/next/grammar/import-parser.ts new file mode 100644 index 0000000000..27fa1d0112 --- /dev/null +++ b/src/next/grammar/import-parser.ts @@ -0,0 +1,98 @@ +import type * as Ast from "@/next/ast"; +import { emptyPath, fromString } from "@/next/fs"; +import type { Language, Range } from "@/next/ast/common"; +import type { SourceLogger } from "@/error/logger-util"; + +const detectLanguage = (path: string): Language | undefined => { + if (path.endsWith(".fc") || path.endsWith(".func")) { + return "func"; + } + + if (path.endsWith(".tact")) { + return "tact"; + } + + return undefined; +}; + +const guessExtension = ( + importText: string, +): { language: Language; guessedPath: string } => { + const language = detectLanguage(importText); + if (language) { + return { guessedPath: importText, language }; + } else { + return { guessedPath: `${importText}.tact`, language: "tact" }; + } +}; + +const stdlibPrefix = "@stdlib/"; + +export const ImportErrors = (l: SourceLogger) => ({ + importWithBackslash: () => (loc: Range) => { + return l.at(loc).error(l.text`Import path can't contain "\\"`); + }, + noFolderImports: () => (loc: Range) => { + return l.at(loc).error(l.text`Cannot import a folder`); + }, + invalidImport: () => (loc: Range) => { + return l + .at(loc) + .error(l.text`Import must start with ./, ../ or @stdlib/`); + }, + escapingImport: () => (loc: Range) => { + return l + .at(loc) + .error(l.text`Standard library imports should be inside its root`); + }, +}); + +export type ImportErrors = ReturnType>; + +export function parseImportString( + importText: string, + range: Range, + err: ImportErrors +): Ast.ImportPath { + if (importText.endsWith("/")) { + err.noFolderImports()(range); + importText = importText.slice(0, -1); + } + + if (importText.includes("\\")) { + err.importWithBackslash()(range); + importText = importText.replace(/\\/g, "/"); + } + + const { guessedPath, language } = guessExtension(importText); + + if (guessedPath.startsWith(stdlibPrefix)) { + const path = fromString(guessedPath.substring(stdlibPrefix.length)); + + if (path.stepsUp !== 0) { + err.importWithBackslash()(range); + } + + return { + path, + type: "stdlib", + language, + }; + } else if ( + guessedPath.startsWith("./") || + guessedPath.startsWith("../") + ) { + return { + path: fromString(guessedPath), + type: "relative", + language, + }; + } else { + err.invalidImport()(range); + return { + path: emptyPath, + type: "relative", + language: "tact", + }; + } +} diff --git a/src/next/grammar/index.ts b/src/next/grammar/index.ts index 8e3968eb05..25b0f9546b 100644 --- a/src/next/grammar/index.ts +++ b/src/next/grammar/index.ts @@ -4,10 +4,10 @@ import type { $ast } from "@/next/grammar/grammar"; import * as G from "@/next/grammar/grammar"; import { SyntaxErrors } from "@/next/grammar/errors"; import { makeMakeVisitor } from "@/utils/tricks"; -import { emptyPath, fromString } from "@/next/fs"; -import type { Language, Range } from "@/next/ast/common"; +import type { Range } from "@/next/ast/common"; import { throwInternal } from "@/error/errors"; import type { SourceLogger } from "@/error/logger-util"; +import { parseImportString } from "@/next/grammar/import-parser"; const makeVisitor = makeMakeVisitor("$"); @@ -1767,84 +1767,13 @@ const parseModuleItem = return [parseModuleItemAux(node)(ctx)]; }; -const detectLanguage = (path: string): Language | undefined => { - if (path.endsWith(".fc") || path.endsWith(".func")) { - return "func"; - } - - if (path.endsWith(".tact")) { - return "tact"; - } - - return undefined; -}; - -const guessExtension = ( - importText: string, -): { language: Language; guessedPath: string } => { - const language = detectLanguage(importText); - if (language) { - return { guessedPath: importText, language }; - } else { - return { guessedPath: `${importText}.tact`, language: "tact" }; - } -}; - -const stdlibPrefix = "@stdlib/"; - -const parseImportString = - (importText: string, loc: $.Loc): Handler => - (ctx) => { - if (importText.endsWith("/")) { - ctx.err.noFolderImports()(toRange(loc)); - importText = importText.slice(0, -1); - } - - if (importText.includes("\\")) { - ctx.err.importWithBackslash()(toRange(loc)); - importText = importText.replace(/\\/g, "/"); - } - - const { guessedPath, language } = guessExtension(importText); - - if (guessedPath.startsWith(stdlibPrefix)) { - const path = fromString(guessedPath.substring(stdlibPrefix.length)); - - if (path.stepsUp !== 0) { - ctx.err.importWithBackslash()(toRange(loc)); - } - - return { - path, - type: "stdlib", - language, - }; - } else if ( - guessedPath.startsWith("./") || - guessedPath.startsWith("../") - ) { - return { - path: fromString(guessedPath), - type: "relative", - language, - }; - } else { - ctx.err.invalidImport()(toRange(loc)); - return { - path: emptyPath, - type: "relative", - language: "tact", - }; - } - }; - const parseImport = ({ path, loc }: $ast.Import): Handler => (ctx) => { const stringLiteral = parseStringLiteral(path)(ctx); const parsedString: string = JSON.parse(`"${stringLiteral.value}"`); return Ast.Import( - parseImportString(parsedString, loc)(ctx), + parseImportString(parsedString, toRange(loc), ctx.err.imports), toRange(loc), ); }; diff --git a/src/next/imports/reader.ts b/src/next/imports/reader.ts index 6384dd588e..aa14407071 100644 --- a/src/next/imports/reader.ts +++ b/src/next/imports/reader.ts @@ -3,8 +3,11 @@ import { emptyPath, fromString } from "@/imports/path"; import { parentPath, createMemoryFs, createProxyFs } from "@/next/fs"; import { getFiles } from "@/next/stdlib"; import type { Cursor } from "@/next/fs"; -import type { AnyLogger, Logger, SourceLogger } from "@/error/logger-util"; -import type { ResolvedImport, TactSource } from "@/next/imports/source"; +import type { Logger, SourceLogger } from "@/error/logger-util"; +import type { FuncImport, ResolvedImport, Source } from "@/next/imports/source"; +import type { ImportPath, ModuleItem } from "@/next/ast"; +import type { Language, Range } from "@/next/ast/common"; +import { throwInternal } from "@/error/errors"; type Options = { readonly log: Logger; @@ -24,7 +27,30 @@ type Options = { /** * Name of root source file of the project */ - readonly root: string; + readonly rootPath: ImportPath; +}; + +type DepId = string; +type RawTactSource = { + readonly code: string; + readonly imports: readonly RawImport[]; + readonly items: readonly ModuleItem[]; +}; +type RawFuncSource = { + readonly code: string; + readonly imports: readonly RawFuncImport[]; +} + +type RawImport = RawTactImport | RawFuncImport; +type RawTactImport = { + readonly language: "tact"; + readonly depId: DepId; + readonly loc: Range; +}; +type RawFuncImport = { + readonly language: "func"; + readonly depId: DepId; + readonly loc: Range; }; const readSource = async ({ @@ -32,63 +58,156 @@ const readSource = async ({ project, stdlib, implicits, - root, -}: Options): Promise => { - const status: Map = new Map(); + rootPath, +}: Options) => { + const status: Map = new Map(); + const tactRaw: Map = new Map(); + const funcRaw: Map = new Map(); - const resolveImports = async ( + const resolveTactImports = async ( log: SourceLogger, - file: Cursor, + dir: Cursor, code: string, - ): Promise => { + ): Promise => { const { imports: rawImports, items } = parse(log, code); - const imports: ResolvedImport[] = [...implicits]; - for (const { importPath, loc } of rawImports) { - const { language, path, type } = importPath; - const importedFile = - type === "relative" - ? file.focus(parentPath).focus(path) - : stdlib.focus(path); - if (language === "tact") { - const source = await resolveSource(importedFile, log); - if (source) { - imports.push({ kind: "tact", source, loc }); - } - } else { - imports.push({ kind: "func", code, loc }); - } + const imports: RawImport[] = []; + for (const { importPath: { language, path, type }, loc } of rawImports) { + imports.push({ + language, + depId: await resolveSource( + type === "relative" + ? dir.focus(path) + : stdlib.focus(path), + language, + ), + loc, + }); } return { code, imports, items }; }; - const resolveSource = async ( - file: Cursor, - parentLog: AnyLogger, - ): Promise => { + const resolveFuncImports = async ( + _log: SourceLogger, + _file: Cursor, + code: string, + // eslint-disable-next-line @typescript-eslint/require-await + ): Promise => { + // TODO: resolve imports + return { code, imports: [] }; + }; + + const resolveSource = async (file: Cursor, language: Language): Promise => { const path = file.getAbsolutePathForLog(); - const res = status.get(path); - if (typeof res === "object") { - return res; - } - if (res === "pending") { - parentLog.error( - parentLog.text`Cyclic import: ${parentLog.path(path)}`, - ); - return; + // this file is already currently being resolved + if (status.has(path)) { + return path; } - status.set(path, "pending"); + status.set(path, 'pending'); const code = await file.read(); if (!code) { - return; + status.set(path, 'errored'); + return path; } - const source = await log.source(path, code, (log) => { - return resolveImports(log, file, code); + const dir = file.focus(parentPath); + await log.source(path, code, async (log) => { + if (language === 'tact') { + tactRaw.set(path, await resolveTactImports(log, dir, code)); + } else { + funcRaw.set(path, await resolveFuncImports(log, dir, code)); + } }); - status.set(path, source); - return source; + status.set(path, 'done'); + return path; }; - return resolveSource(project.focus(fromString(root)), log); + if (rootPath.type !== 'relative') { + log.error(log.text`Cannot build standard library as root`); + return undefined; + } + if (rootPath.language !== 'tact') { + log.error(log.text`Use ${rootPath.language} compiler`); + return undefined; + } + + const rootDepId = await resolveSource(project.focus(rootPath.path), rootPath.language); + + if ([...status.values()].includes("errored")) { + return undefined; + } + + const func: Map = new Map(); + for (const [key, { code }] of funcRaw) { + func.set(key, { + kind: 'func', + code, + imports: [], + }); + } + for (const [key, { imports }] of funcRaw) { + const entry = func.get(key); + if (!entry) { + return throwInternal("Impossible"); + } + entry.imports = imports.map(({ depId, language, loc }): FuncImport => { + const source = func.get(depId); + if (!source) { + return throwInternal("Impossible"); + } + return { kind: language, source, loc }; + }); + } + + const tact: Map = new Map(); + for (const [key, { code, items }] of tactRaw) { + tact.set(key, { + kind: 'tact', + code, + imports: [], + items, + }); + } + for (const [key, { imports }] of tactRaw) { + const entry = tact.get(key); + if (!entry) { + return throwInternal("Impossible"); + } + entry.imports = [ + ...implicits, + ...imports.map((i): ResolvedImport => { + if (i.language === 'func') { + const source = func.get(i.depId); + if (!source) { + return throwInternal("Impossible"); + } + return { kind: 'func', source, loc: i.loc }; + } else { + const source = tact.get(i.depId); + if (!source) { + return throwInternal("Impossible"); + } + return { kind: 'tact', source, loc: i.loc }; + } + }), + ]; + } + + const sources: Source[] = [...func.values(), ...tact.values()]; + const root = tact.get(rootDepId); + + if (!root) { + return undefined; + } + + return { sources, root }; }; /** @@ -107,7 +226,11 @@ export const ProjectReader = async (log: Logger) => { project: stdRoot, stdlib: stdLibs, implicits: [], - root: "std/stdlib.tact", + rootPath: { + type: 'relative', + language: 'tact', + path: fromString("std/stdlib.tact"), + }, }); if (!stdStd) { // Could not load standard library @@ -118,7 +241,7 @@ export const ProjectReader = async (log: Logger) => { /** * Read project */ - const read = async (fsRootPath: string, tactRoot: string) => { + const read = async (fsRootPath: string, rootPath: ImportPath) => { const project = createProxyFs({ log, root: fsRootPath, @@ -127,17 +250,25 @@ export const ProjectReader = async (log: Logger) => { const implicits: ResolvedImport[] = [ { kind: "tact", - source: stdStd, + source: stdStd.root, loc: { start: 0, end: 0 }, }, ]; - return await readSource({ + const result = await readSource({ log, project, stdlib: stdLibs, implicits, - root: tactRoot, + rootPath, }); + if (!result) { + return undefined; + } + + return { + root: result.root, + sources: [...stdStd.sources, ...result.sources], + }; }; return { read }; diff --git a/src/next/imports/source.ts b/src/next/imports/source.ts index a6a4291cbc..46fd3b9c20 100644 --- a/src/next/imports/source.ts +++ b/src/next/imports/source.ts @@ -1,18 +1,26 @@ import type { ModuleItem, Range } from "@/next/ast"; +export type Source = TactSource | FuncSource; export type TactSource = { + readonly kind: "tact"; readonly code: string; readonly imports: readonly ResolvedImport[]; readonly items: readonly ModuleItem[]; }; +export type FuncSource = { + readonly kind: "func"; + readonly code: string; + readonly imports: readonly FuncImport[]; +} + export type ResolvedImport = TactImport | FuncImport; export type TactImport = { readonly kind: "tact"; - readonly source: TactSource; + readonly source: Source; readonly loc: Range; }; export type FuncImport = { readonly kind: "func"; - readonly code: string; + readonly source: FuncSource; readonly loc: Range; }; diff --git a/src/next/index.ts b/src/next/index.ts index fa94c1ce1d..00eae662d5 100644 --- a/src/next/index.ts +++ b/src/next/index.ts @@ -2,8 +2,10 @@ import path from "path"; import { TerminalLogger } from "@/cli/logger"; import { getAnsiMarkup, isColorSupported } from "@/cli/colors"; import { ProjectReader } from "@/next/imports/reader"; - -const target = "wallet-v4.tact"; +import { fromString } from "@/imports/path"; +import { inspect } from 'util'; +// eslint-disable-next-line @typescript-eslint/no-confusing-void-expression +const dump = (obj: unknown) => console.log(inspect(obj, { colors: false, depth: Infinity })); const main = async () => { const ansi = getAnsiMarkup(isColorSupported()); @@ -12,11 +14,18 @@ const main = async () => { // TODO: new CLI based (see typegen) const reader = await ProjectReader(log); if (!reader) return; - const root = await reader.read( - path.join(__dirname, "example"), - target, + const result = await reader.read( + path.join(__dirname, "example"), + // TODO: parseImportString(root, ImportErrors(log)) when there are CLI/config loggers + { + language: 'tact', + type: 'relative', + path: fromString("mutual1.tact"), + }, ); - console.log(root); + if (result) { + dump(result.sources.length); + } }); }); }; From 0374ebaa5e7637e28577bfeb6b1028437d2cc63a Mon Sep 17 00:00:00 2001 From: verytactical <186486509+verytactical@users.noreply.github.com> Date: Thu, 1 May 2025 16:17:38 +0400 Subject: [PATCH 15/38] scoping --- src/next/ast/generated/root.ts | 669 +++++++++++------------------- src/next/ast/root.ts | 245 +++++------ src/next/example/map-len.tact | 30 ++ src/next/example/scope1-a.tact | 2 + src/next/example/scope1-b.tact | 1 + src/next/example/scope1-c.tact | 1 + src/next/example/scope2-a.tact | 2 + src/next/example/scope2-b.tact | 1 + src/next/example/scope2-c.tact | 1 + src/next/example/scope2-d.tact | 1 + src/next/example/set.tact | 25 ++ src/next/grammar/errors.ts | 72 ++++ src/next/grammar/import-parser.ts | 7 +- src/next/grammar/index.ts | 471 +++++++++++---------- src/next/imports/reader.ts | 232 +++-------- src/next/imports/source.ts | 11 +- src/next/index.ts | 26 +- src/next/scoping/const.ts | 180 ++++++++ src/next/scoping/scoped-ast.ts | 73 ++++ src/next/scoping/tc.ts | 179 ++++++++ src/next/scoping/tc2.ts | 336 +++++++++++++++ src/utils/array.ts | 8 + src/utils/tricks.ts | 13 + 23 files changed, 1593 insertions(+), 993 deletions(-) create mode 100644 src/next/example/map-len.tact create mode 100644 src/next/example/scope1-a.tact create mode 100644 src/next/example/scope1-b.tact create mode 100644 src/next/example/scope1-c.tact create mode 100644 src/next/example/scope2-a.tact create mode 100644 src/next/example/scope2-b.tact create mode 100644 src/next/example/scope2-c.tact create mode 100644 src/next/example/scope2-d.tact create mode 100644 src/next/example/set.tact create mode 100644 src/next/scoping/const.ts create mode 100644 src/next/scoping/scoped-ast.ts create mode 100644 src/next/scoping/tc.ts create mode 100644 src/next/scoping/tc2.ts diff --git a/src/next/ast/generated/root.ts b/src/next/ast/generated/root.ts index 54bee5496f..b1a9b731bf 100644 --- a/src/next/ast/generated/root.ts +++ b/src/next/ast/generated/root.ts @@ -8,460 +8,273 @@ import type * as $ from "@/next/ast/root"; export type ImportType = $.ImportType; export const allImportType: readonly $.ImportType[] = ["stdlib", "relative"]; export type ImportPath = $.ImportPath; -export const ImportPath = ( - path: $f.RelativePath, - type_: $.ImportType, - language: $c.Language, -): $.ImportPath => - Object.freeze({ - path, - type: type_, - language, - }); +export const ImportPath = (path: $f.RelativePath, type_: $.ImportType, language: $c.Language): $.ImportPath => Object.freeze({ + path, + type: type_, + language +}); export type Import = $.Import; -export const Import = (importPath: $.ImportPath, loc: $c.Range): $.Import => - Object.freeze({ - kind: "import", - importPath, - loc, - }); +export const Import = (importPath: $.ImportPath, loc: $c.Range): $.Import => Object.freeze({ + kind: "import", + importPath, + loc +}); export const isImport = ($value: Import) => $value.kind === "import"; -export type FunctionAttributeGet = $.FunctionAttributeGet; -export const FunctionAttributeGet = ( - methodId: $e.Expression | undefined, - loc: $c.Range, -): $.FunctionAttributeGet => - Object.freeze({ - kind: "function_attribute", - type: "get", - methodId, - loc, - }); -export const isFunctionAttributeGet = ($value: FunctionAttributeGet) => - $value.kind === "function_attribute"; -export type FunctionAttributeName = $.FunctionAttributeName; -export const allFunctionAttributeName: readonly $.FunctionAttributeName[] = [ - "mutates", - "extends", - "virtual", - "abstract", - "override", - "inline", -]; -export type FunctionAttributeRest = $.FunctionAttributeRest; -export const FunctionAttributeRest = ( - type_: $.FunctionAttributeName, - loc: $c.Range, -): $.FunctionAttributeRest => - Object.freeze({ - kind: "function_attribute", - type: type_, - loc, - }); -export const isFunctionAttributeRest = ($value: FunctionAttributeRest) => - $value.kind === "function_attribute"; -export type FunctionAttribute = $.FunctionAttribute; export type TypedParameter = $.TypedParameter; -export const TypedParameter = ( - name: $c.OptionalId, - type_: $t.Type, - loc: $c.Range, -): $.TypedParameter => - Object.freeze({ - kind: "typed_parameter", - name, - type: type_, - loc, - }); -export const isTypedParameter = ($value: TypedParameter) => - $value.kind === "typed_parameter"; -export type FunctionDef = $.FunctionDef; -export const FunctionDef = ( - attributes: readonly $.FunctionAttribute[], - name: $c.Id, - typeParams: readonly $c.TypeId[], - return_: $t.Type | undefined, - params: readonly $.TypedParameter[], - statements: readonly $s.Statement[], - loc: $c.Range, -): $.FunctionDef => - Object.freeze({ - kind: "function_def", - attributes, - name, - typeParams, - return: return_, - params, - statements, - loc, - }); -export const isFunctionDef = ($value: FunctionDef) => - $value.kind === "function_def"; +export const TypedParameter = (name: $c.OptionalId, type_: $t.Type, loc: $c.Range): $.TypedParameter => Object.freeze({ + kind: "typed_parameter", + name, + type: type_, + loc +}); +export const isTypedParameter = ($value: TypedParameter) => $value.kind === "typed_parameter"; +export type RegularBody = $.RegularBody; +export const RegularBody = (statements: readonly $s.Statement[]): $.RegularBody => Object.freeze({ + kind: "regular_body", + statements +}); +export const isRegularBody = ($value: RegularBody) => $value.kind === "regular_body"; export type AsmShuffle = $.AsmShuffle; -export const AsmShuffle = ( - args: readonly $c.Id[], - ret: readonly $e.Number[], -): $.AsmShuffle => - Object.freeze({ - args, - ret, - }); +export const AsmShuffle = (args: readonly $c.Id[], ret: readonly $e.Number[]): $.AsmShuffle => Object.freeze({ + args, + ret +}); export type AsmInstruction = $.AsmInstruction; -export type AsmFunctionDef = $.AsmFunctionDef; -export const AsmFunctionDef = ( - shuffle: $.AsmShuffle, - attributes: readonly $.FunctionAttribute[], - name: $c.Id, - typeParams: readonly $c.TypeId[], - return_: $t.Type | undefined, - params: readonly $.TypedParameter[], - instructions: readonly $.AsmInstruction[], - loc: $c.Range, -): $.AsmFunctionDef => - Object.freeze({ - kind: "asm_function_def", - shuffle, - attributes, - name, - typeParams, - return: return_, - params, - instructions, - loc, - }); -export const isAsmFunctionDef = ($value: AsmFunctionDef) => - $value.kind === "asm_function_def"; -export type NativeFunctionDecl = $.NativeFunctionDecl; -export const NativeFunctionDecl = ( - attributes: readonly $.FunctionAttribute[], - name: $c.Id, - typeParams: readonly $c.TypeId[], - nativeName: $c.FuncId, - params: readonly $.TypedParameter[], - return_: $t.Type | undefined, - loc: $c.Range, -): $.NativeFunctionDecl => - Object.freeze({ - kind: "native_function_decl", - attributes, - name, - typeParams, - nativeName, - params, - return: return_, - loc, - }); -export const isNativeFunctionDecl = ($value: NativeFunctionDecl) => - $value.kind === "native_function_decl"; -export type ConstantAttributeName = $.ConstantAttributeName; -export const allConstantAttributeName: readonly $.ConstantAttributeName[] = [ - "virtual", - "override", - "abstract", -]; -export type ConstantAttribute = $.ConstantAttribute; -export const ConstantAttribute = ( - type_: $.ConstantAttributeName, - loc: $c.Range, -): $.ConstantAttribute => - Object.freeze({ - type: type_, - loc, - }); +export type AsmBody = $.AsmBody; +export const AsmBody = (shuffle: $.AsmShuffle, instructions: readonly $.AsmInstruction[]): $.AsmBody => Object.freeze({ + kind: "asm_body", + shuffle, + instructions +}); +export const isAsmBody = ($value: AsmBody) => $value.kind === "asm_body"; +export type NativeBody = $.NativeBody; +export const NativeBody = (nativeName: $c.FuncId): $.NativeBody => Object.freeze({ + kind: "native_body", + nativeName +}); +export const isNativeBody = ($value: NativeBody) => $value.kind === "native_body"; +export type AbstractBody = $.AbstractBody; +export const AbstractBody = (): $.AbstractBody => Object.freeze({ + kind: "abstract_body" +}); +export const isAbstractBody = ($value: AbstractBody) => $value.kind === "abstract_body"; +export type FunctionalBody = $.FunctionalBody; +export type Function = $.Function; +export const Function = (inline: boolean, name: $c.Id, typeParams: readonly $c.TypeId[], returnType: $t.Type | undefined, params: readonly $.TypedParameter[], body: $.FunctionalBody, loc: $c.Range): $.Function => Object.freeze({ + kind: "function", + inline, + name, + typeParams, + returnType, + params, + body, + loc +}); +export const isFunction = ($value: Function) => $value.kind === "function"; +export type GetAttribute = $.GetAttribute; +export const GetAttribute = (methodId: $e.Expression | undefined, loc: $c.Range): $.GetAttribute => Object.freeze({ + methodId, + loc +}); +export type Method = $.Method; +export const Method = (mutates: boolean, virtual: boolean, override: boolean, get: $.GetAttribute | undefined, fun: $.Function): $.Method => Object.freeze({ + kind: "method", + mutates, + virtual, + override, + get, + fun +}); +export const isMethod = ($value: Method) => $value.kind === "method"; +export type Extension = $.Extension; +export const Extension = (fun: $.Method, selfType: $t.Type): $.Extension => Object.freeze({ + kind: "extension", + fun, + selfType +}); +export const isExtension = ($value: Extension) => $value.kind === "extension"; export type ConstantDef = $.ConstantDef; -export const ConstantDef = ( - attributes: readonly $.ConstantAttribute[], - name: $c.Id, - type_: $t.Type | undefined, - initializer: $e.Expression, - loc: $c.Range, -): $.ConstantDef => - Object.freeze({ - kind: "constant_def", - attributes, - name, - type: type_, - initializer, - loc, - }); -export const isConstantDef = ($value: ConstantDef) => - $value.kind === "constant_def"; +export const ConstantDef = (type_: $t.Type | undefined, initializer: $e.Expression): $.ConstantDef => Object.freeze({ + kind: "constant_def", + type: type_, + initializer +}); +export const isConstantDef = ($value: ConstantDef) => $value.kind === "constant_def"; +export type ConstantDecl = $.ConstantDecl; +export const ConstantDecl = (type_: $t.Type): $.ConstantDecl => Object.freeze({ + kind: "constant_decl", + type: type_ +}); +export const isConstantDecl = ($value: ConstantDecl) => $value.kind === "constant_decl"; +export type ConstantInit = $.ConstantInit; +export type Constant = $.Constant; +export const Constant = (name: $c.Id, init: $.ConstantInit, loc: $c.Range): $.Constant => Object.freeze({ + kind: "constant", + name, + init, + loc +}); +export const isConstant = ($value: Constant) => $value.kind === "constant"; export type FieldDecl = $.FieldDecl; -export const FieldDecl = ( - name: $c.Id, - type_: $t.Type, - initializer: $e.Expression | undefined, - loc: $c.Range, -): $.FieldDecl => - Object.freeze({ - kind: "field_decl", - name, - type: type_, - initializer, - loc, - }); +export const FieldDecl = (name: $c.Id, type_: $t.Type, initializer: $e.Expression | undefined, loc: $c.Range): $.FieldDecl => Object.freeze({ + kind: "field_decl", + name, + type: type_, + initializer, + loc +}); export const isFieldDecl = ($value: FieldDecl) => $value.kind === "field_decl"; export type StructDecl = $.StructDecl; -export const StructDecl = ( - name: $c.TypeId, - typeParams: readonly $c.TypeId[], - fields: readonly $.FieldDecl[], - loc: $c.Range, -): $.StructDecl => - Object.freeze({ - kind: "struct_decl", - name, - typeParams, - fields, - loc, - }); -export const isStructDecl = ($value: StructDecl) => - $value.kind === "struct_decl"; +export const StructDecl = (name: $c.TypeId, typeParams: readonly $c.TypeId[], fields: readonly $.FieldDecl[], loc: $c.Range): $.StructDecl => Object.freeze({ + kind: "struct_decl", + name, + typeParams, + fields, + loc +}); +export const isStructDecl = ($value: StructDecl) => $value.kind === "struct_decl"; export type MessageDecl = $.MessageDecl; -export const MessageDecl = ( - name: $c.TypeId, - opcode: $e.Expression | undefined, - fields: readonly $.FieldDecl[], - loc: $c.Range, -): $.MessageDecl => - Object.freeze({ - kind: "message_decl", - name, - opcode, - fields, - loc, - }); -export const isMessageDecl = ($value: MessageDecl) => - $value.kind === "message_decl"; +export const MessageDecl = (name: $c.TypeId, opcode: $e.Expression | undefined, fields: readonly $.FieldDecl[], loc: $c.Range): $.MessageDecl => Object.freeze({ + kind: "message_decl", + name, + opcode, + fields, + loc +}); +export const isMessageDecl = ($value: MessageDecl) => $value.kind === "message_decl"; +export type UnionCase = $.UnionCase; +export const UnionCase = (name: $c.TypeId, fields: readonly $.FieldDecl[]): $.UnionCase => Object.freeze({ + name, + fields +}); +export type UnionDecl = $.UnionDecl; +export const UnionDecl = (name: $c.TypeId, typeParams: readonly $c.TypeId[], cases: readonly $.UnionCase[], loc: $c.Range): $.UnionDecl => Object.freeze({ + kind: "union_decl", + name, + typeParams, + cases, + loc +}); +export const isUnionDecl = ($value: UnionDecl) => $value.kind === "union_decl"; +export type AliasDecl = $.AliasDecl; +export const AliasDecl = (name: $c.TypeId, typeParams: readonly $c.TypeId[], type_: $t.Type, loc: $c.Range): $.AliasDecl => Object.freeze({ + kind: "alias_decl", + name, + typeParams, + type: type_, + loc +}); +export const isAliasDecl = ($value: AliasDecl) => $value.kind === "alias_decl"; export type ContractAttribute = $.ContractAttribute; -export const ContractAttribute = ( - name: string, - loc: $c.Range, -): $.ContractAttribute => - Object.freeze({ - type: "interface", - name, - loc, - }); -export type ContractInit = $.ContractInit; -export const ContractInit = ( - params: readonly $.TypedParameter[], - statements: readonly $s.Statement[], - loc: $c.Range, -): $.ContractInit => - Object.freeze({ - kind: "contract_init", - params, - statements, - loc, - }); -export const isContractInit = ($value: ContractInit) => - $value.kind === "contract_init"; +export const ContractAttribute = (name: string, loc: $c.Range): $.ContractAttribute => Object.freeze({ + type: "interface", + name, + loc +}); +export type InitFunction = $.InitFunction; +export const InitFunction = (params: readonly $.TypedParameter[], statements: readonly $s.Statement[], loc: $c.Range): $.InitFunction => Object.freeze({ + kind: "init_function", + params, + statements, + loc +}); +export const isInitFunction = ($value: InitFunction) => $value.kind === "init_function"; +export type InitParams = $.InitParams; +export const InitParams = (params: readonly $.FieldDecl[]): $.InitParams => Object.freeze({ + kind: "init_params", + params +}); +export const isInitParams = ($value: InitParams) => $value.kind === "init_params"; +export type Init = $.Init; export type ReceiverSimple = $.ReceiverSimple; -export const ReceiverSimple = (param: $.TypedParameter): $.ReceiverSimple => - Object.freeze({ - kind: "simple", - param, - }); -export const isReceiverSimple = ($value: ReceiverSimple) => - $value.kind === "simple"; +export const ReceiverSimple = (param: $.TypedParameter): $.ReceiverSimple => Object.freeze({ + kind: "simple", + param +}); +export const isReceiverSimple = ($value: ReceiverSimple) => $value.kind === "simple"; export type ReceiverFallback = $.ReceiverFallback; -export const ReceiverFallback = (): $.ReceiverFallback => - Object.freeze({ - kind: "fallback", - }); -export const isReceiverFallback = ($value: ReceiverFallback) => - $value.kind === "fallback"; +export const ReceiverFallback = (): $.ReceiverFallback => Object.freeze({ + kind: "fallback" +}); +export const isReceiverFallback = ($value: ReceiverFallback) => $value.kind === "fallback"; export type ReceiverComment = $.ReceiverComment; -export const ReceiverComment = (comment: $e.String): $.ReceiverComment => - Object.freeze({ - kind: "comment", - comment, - }); -export const isReceiverComment = ($value: ReceiverComment) => - $value.kind === "comment"; +export const ReceiverComment = (comment: $e.String): $.ReceiverComment => Object.freeze({ + kind: "comment", + comment +}); +export const isReceiverComment = ($value: ReceiverComment) => $value.kind === "comment"; export type ReceiverSubKind = $.ReceiverSubKind; export type ReceiverInternal = $.ReceiverInternal; -export const ReceiverInternal = ( - subKind: $.ReceiverSubKind, - loc: $c.Range, -): $.ReceiverInternal => - Object.freeze({ - kind: "internal", - subKind, - loc, - }); -export const isReceiverInternal = ($value: ReceiverInternal) => - $value.kind === "internal"; +export const ReceiverInternal = (subKind: $.ReceiverSubKind, loc: $c.Range): $.ReceiverInternal => Object.freeze({ + kind: "internal", + subKind, + loc +}); +export const isReceiverInternal = ($value: ReceiverInternal) => $value.kind === "internal"; export type ReceiverExternal = $.ReceiverExternal; -export const ReceiverExternal = ( - subKind: $.ReceiverSubKind, - loc: $c.Range, -): $.ReceiverExternal => - Object.freeze({ - kind: "external", - subKind, - loc, - }); -export const isReceiverExternal = ($value: ReceiverExternal) => - $value.kind === "external"; +export const ReceiverExternal = (subKind: $.ReceiverSubKind, loc: $c.Range): $.ReceiverExternal => Object.freeze({ + kind: "external", + subKind, + loc +}); +export const isReceiverExternal = ($value: ReceiverExternal) => $value.kind === "external"; export type ReceiverBounce = $.ReceiverBounce; -export const ReceiverBounce = ( - param: $.TypedParameter, - loc: $c.Range, -): $.ReceiverBounce => - Object.freeze({ - kind: "bounce", - param, - loc, - }); -export const isReceiverBounce = ($value: ReceiverBounce) => - $value.kind === "bounce"; +export const ReceiverBounce = (param: $.TypedParameter, loc: $c.Range): $.ReceiverBounce => Object.freeze({ + kind: "bounce", + param, + loc +}); +export const isReceiverBounce = ($value: ReceiverBounce) => $value.kind === "bounce"; export type ReceiverKind = $.ReceiverKind; export type Receiver = $.Receiver; -export const Receiver = ( - selector: $.ReceiverKind, - statements: readonly $s.Statement[], - loc: $c.Range, -): $.Receiver => - Object.freeze({ - kind: "receiver", - selector, - statements, - loc, - }); +export const Receiver = (selector: $.ReceiverKind, statements: readonly $s.Statement[], loc: $c.Range): $.Receiver => Object.freeze({ + kind: "receiver", + selector, + statements, + loc +}); export const isReceiver = ($value: Receiver) => $value.kind === "receiver"; -export type ContractItem = $.ContractItem; +export type FieldConstant = $.FieldConstant; +export const FieldConstant = (virtual: boolean, override: boolean, body: $.Constant): $.FieldConstant => Object.freeze({ + kind: "field_const", + virtual, + override, + body +}); +export const isFieldConstant = ($value: FieldConstant) => $value.kind === "field_const"; +export type LocalItem = $.LocalItem; export type Contract = $.Contract; -export const Contract = ( - name: $c.TypeId, - traits: readonly $c.TypeId[], - attributes: readonly $.ContractAttribute[], - params: readonly $.FieldDecl[] | undefined, - declarations: readonly $.ContractItem[], - loc: $c.Range, -): $.Contract => - Object.freeze({ - kind: "contract", - name, - traits, - attributes, - params, - declarations, - loc, - }); +export const Contract = (name: $c.TypeId, traits: readonly $c.TypeId[], attributes: readonly $.ContractAttribute[], init: $.Init | undefined, declarations: readonly $.LocalItem[], loc: $c.Range): $.Contract => Object.freeze({ + kind: "contract", + name, + traits, + attributes, + init, + declarations, + loc +}); export const isContract = ($value: Contract) => $value.kind === "contract"; -export type FunctionDecl = $.FunctionDecl; -export const FunctionDecl = ( - attributes: readonly $.FunctionAttribute[], - name: $c.Id, - typeParams: readonly $c.TypeId[], - return_: $t.Type | undefined, - params: readonly $.TypedParameter[], - loc: $c.Range, -): $.FunctionDecl => - Object.freeze({ - kind: "function_decl", - attributes, - name, - typeParams, - return: return_, - params, - loc, - }); -export const isFunctionDecl = ($value: FunctionDecl) => - $value.kind === "function_decl"; -export type ConstantDecl = $.ConstantDecl; -export const ConstantDecl = ( - attributes: readonly $.ConstantAttribute[], - name: $c.Id, - type_: $t.Type, - loc: $c.Range, -): $.ConstantDecl => - Object.freeze({ - kind: "constant_decl", - attributes, - name, - type: type_, - loc, - }); -export const isConstantDecl = ($value: ConstantDecl) => - $value.kind === "constant_decl"; -export type TraitItem = $.TraitItem; export type Trait = $.Trait; -export const Trait = ( - name: $c.TypeId, - traits: readonly $c.TypeId[], - attributes: readonly $.ContractAttribute[], - declarations: readonly $.TraitItem[], - loc: $c.Range, -): $.Trait => - Object.freeze({ - kind: "trait", - name, - traits, - attributes, - declarations, - loc, - }); +export const Trait = (name: $c.TypeId, traits: readonly $c.TypeId[], attributes: readonly $.ContractAttribute[], declarations: readonly $.LocalItem[], loc: $c.Range): $.Trait => Object.freeze({ + kind: "trait", + name, + traits, + attributes, + declarations, + loc +}); export const isTrait = ($value: Trait) => $value.kind === "trait"; export type ModuleItem = $.ModuleItem; export type Module = $.Module; -export const Module = ( - imports: readonly $.Import[], - items: readonly $.ModuleItem[], -): $.Module => - Object.freeze({ - kind: "module", - imports, - items, - }); +export const Module = (imports: readonly $.Import[], items: readonly $.ModuleItem[]): $.Module => Object.freeze({ + kind: "module", + imports, + items +}); export const isModule = ($value: Module) => $value.kind === "module"; export type Source = $.Source; -export const Source = ( - file: string | undefined, - contents: string, - root: $.Module, -): $.Source => - Object.freeze({ - file, - contents, - root, - }); -export type UnionCase = $.UnionCase; -export const UnionCase = ( - name: $c.TypeId, - fields: readonly $.FieldDecl[], -): $.UnionCase => - Object.freeze({ - name, - fields, - }); -export type UnionDecl = $.UnionDecl; -export const UnionDecl = ( - name: $c.TypeId, - typeParams: readonly $c.TypeId[], - cases: readonly $.UnionCase[], - loc: $c.Range, -): $.UnionDecl => - Object.freeze({ - kind: "union_decl", - name, - typeParams, - cases, - loc, - }); -export const isUnionDecl = ($value: UnionDecl) => $value.kind === "union_decl"; -export type AliasDecl = $.AliasDecl; -export const AliasDecl = ( - name: $c.TypeId, - typeParams: readonly $c.TypeId[], - type_: $t.Type, -): $.AliasDecl => - Object.freeze({ - kind: "alias_decl", - name, - typeParams, - type: type_, - }); -export const isAliasDecl = ($value: AliasDecl) => $value.kind === "alias_decl"; +export const Source = (file: string | undefined, contents: string, root: $.Module): $.Source => Object.freeze({ + file, + contents, + root +}); \ No newline at end of file diff --git a/src/next/ast/root.ts b/src/next/ast/root.ts index 6d07af9723..40b056cf30 100644 --- a/src/next/ast/root.ts +++ b/src/next/ast/root.ts @@ -22,140 +22,156 @@ export type Module = { readonly imports: readonly Import[]; readonly items: readonly ModuleItem[]; }; +export type ModuleItem = + | Function + | Extension + | Constant + | StructDecl + | MessageDecl + | UnionDecl + | AliasDecl + | Contract + | Trait; +export type Import = { + readonly kind: "import"; + readonly importPath: ImportPath; + readonly loc: Range; +}; +// Reference to source file +export type ImportPath = { + readonly path: RelativePath; + readonly type: ImportType; + readonly language: Language; +}; +// This is different from ItemOrigin, because relative import +// from standard library is still import with origin: "stdlib" +export type ImportType = "stdlib" | "relative"; export type Contract = { readonly kind: "contract"; readonly name: TypeId; readonly traits: readonly TypeId[]; readonly attributes: readonly ContractAttribute[]; - readonly params: undefined | readonly FieldDecl[]; - readonly declarations: readonly ContractItem[]; + readonly init: undefined | Init; + readonly declarations: readonly LocalItem[]; readonly loc: Range; }; +export type Init = InitFunction | InitParams; +export type InitFunction = { + readonly kind: "init_function"; + readonly params: readonly TypedParameter[]; + readonly statements: readonly Statement[]; + readonly loc: Range; +}; +export type InitParams = { + readonly kind: "init_params"; + readonly params: readonly FieldDecl[]; +}; + export type Trait = { readonly kind: "trait"; readonly name: TypeId; readonly traits: readonly TypeId[]; readonly attributes: readonly ContractAttribute[]; - readonly declarations: readonly TraitItem[]; + readonly declarations: readonly LocalItem[]; readonly loc: Range; }; -export type ModuleItem = - | FunctionDef - | AsmFunctionDef - | NativeFunctionDecl - | ConstantDef - | StructDecl - | MessageDecl - | UnionDecl - | AliasDecl - | Contract - | Trait; - -export type ContractItem = +export type LocalItem = | FieldDecl - | FunctionDef - | AsmFunctionDef - | ContractInit + | Method | Receiver - | ConstantDef; + | FieldConstant; -export type TraitItem = - | FieldDecl - | FunctionDef - | AsmFunctionDef - | FunctionDecl - | Receiver - | ConstantDef - | ConstantDecl; - -export type Import = { - readonly kind: "import"; - readonly importPath: ImportPath; +export type ContractAttribute = { + readonly type: "interface"; + readonly name: string; readonly loc: Range; }; -export type FunctionDef = { - readonly kind: "function_def"; - readonly attributes: readonly FunctionAttribute[]; - readonly name: Id; - readonly typeParams: readonly TypeId[]; - readonly return: Type | undefined; - readonly params: readonly TypedParameter[]; - readonly statements: readonly Statement[]; - readonly loc: Range; +export type Extension = { + readonly kind: "extension"; + readonly fun: Method; + readonly selfType: Type; }; -export type Receiver = { - readonly kind: "receiver"; - readonly selector: ReceiverKind; - readonly statements: readonly Statement[]; - readonly loc: Range; +export type Method = { + readonly kind: "method"; + readonly mutates: boolean; + readonly virtual: boolean; + readonly override: boolean; + readonly get: undefined | GetAttribute; + readonly fun: Function; }; -export type ContractInit = { - readonly kind: "contract_init"; - readonly params: readonly TypedParameter[]; - readonly statements: readonly Statement[]; +export type GetAttribute = { + readonly methodId: Expression | undefined; readonly loc: Range; }; -export type AsmFunctionDef = { - readonly kind: "asm_function_def"; - readonly shuffle: AsmShuffle; - readonly attributes: readonly FunctionAttribute[]; +export type Function = { + readonly kind: "function"; + readonly inline: boolean; readonly name: Id; readonly typeParams: readonly TypeId[]; - readonly return: Type | undefined; + readonly returnType: Type | undefined; readonly params: readonly TypedParameter[]; - readonly instructions: readonly AsmInstruction[]; + readonly body: FunctionalBody; readonly loc: Range; }; +export type FunctionalBody = RegularBody | AsmBody | NativeBody | AbstractBody; +export type AbstractBody = { + readonly kind: "abstract_body"; +}; +export type RegularBody = { + readonly kind: "regular_body"; + readonly statements: readonly Statement[]; +}; +export type NativeBody = { + readonly kind: "native_body"; + readonly nativeName: FuncId; +}; +export type AsmBody = { + readonly kind: "asm_body"; + readonly shuffle: AsmShuffle; + readonly instructions: readonly AsmInstruction[]; +}; export type AsmInstruction = string; export type AsmShuffle = { readonly args: readonly Id[]; readonly ret: readonly Number[]; }; -export type FunctionDecl = { - readonly kind: "function_decl"; - readonly attributes: readonly FunctionAttribute[]; - readonly name: Id; - readonly typeParams: readonly TypeId[]; - readonly return: Type | undefined; - readonly params: readonly TypedParameter[]; +export type TypedParameter = { + readonly kind: "typed_parameter"; + readonly name: OptionalId; + readonly type: Type; readonly loc: Range; }; -export type NativeFunctionDecl = { - readonly kind: "native_function_decl"; - readonly attributes: readonly FunctionAttribute[]; +export type FieldConstant = { + readonly kind: "field_const"; + readonly virtual: boolean; + readonly override: boolean; + readonly body: Constant; +} +export type Constant = { + readonly kind: "constant"; readonly name: Id; - readonly typeParams: readonly TypeId[]; - readonly nativeName: FuncId; - readonly params: readonly TypedParameter[]; - readonly return: Type | undefined; + readonly init: ConstantInit; readonly loc: Range; }; - +export type ConstantInit = ConstantDef | ConstantDecl; export type ConstantDef = { readonly kind: "constant_def"; - readonly attributes: readonly ConstantAttribute[]; - readonly name: Id; readonly type: Type | undefined; readonly initializer: Expression; - readonly loc: Range; }; - export type ConstantDecl = { readonly kind: "constant_decl"; - readonly attributes: readonly ConstantAttribute[]; - readonly name: Id; readonly type: Type; - readonly loc: Range; }; export type StructDecl = { @@ -181,17 +197,17 @@ export type UnionDecl = { readonly cases: readonly UnionCase[]; readonly loc: Range; }; +export type UnionCase = { + readonly name: TypeId; + readonly fields: readonly FieldDecl[]; +}; export type AliasDecl = { readonly kind: "alias_decl"; readonly name: TypeId; readonly typeParams: readonly TypeId[]; readonly type: Type; -}; - -export type UnionCase = { - readonly name: TypeId; - readonly fields: readonly FieldDecl[]; + readonly loc: Range; }; export type FieldDecl = { @@ -202,95 +218,40 @@ export type FieldDecl = { readonly loc: Range; }; -// Reference to source file -export type ImportPath = { - readonly path: RelativePath; - readonly type: ImportType; - readonly language: Language; -}; - -// This is different from ItemOrigin, because relative import -// from standard library is still import with origin: "stdlib" -export type ImportType = "stdlib" | "relative"; - -export type ConstantAttributeName = "virtual" | "override" | "abstract"; - -export type ConstantAttribute = { - readonly type: ConstantAttributeName; - readonly loc: Range; -}; - -export type ContractAttribute = { - readonly type: "interface"; - readonly name: string; - readonly loc: Range; -}; - -export type FunctionAttributeGet = { - readonly kind: "function_attribute"; - readonly type: "get"; - readonly methodId: Expression | undefined; - readonly loc: Range; -}; - -export type FunctionAttributeName = - | "mutates" - | "extends" - | "virtual" - | "abstract" - | "override" - | "inline"; - -export type FunctionAttributeRest = { - readonly kind: "function_attribute"; - readonly type: FunctionAttributeName; - readonly loc: Range; -}; - -export type FunctionAttribute = FunctionAttributeGet | FunctionAttributeRest; - -export type TypedParameter = { - readonly kind: "typed_parameter"; - readonly name: OptionalId; - readonly type: Type; +export type Receiver = { + readonly kind: "receiver"; + readonly selector: ReceiverKind; + readonly statements: readonly Statement[]; readonly loc: Range; }; - export type ReceiverSimple = { readonly kind: "simple"; readonly param: TypedParameter; }; - export type ReceiverFallback = { readonly kind: "fallback"; }; - export type ReceiverComment = { readonly kind: "comment"; readonly comment: String; }; - export type ReceiverSubKind = | ReceiverSimple | ReceiverFallback | ReceiverComment; - export type ReceiverInternal = { readonly kind: "internal"; readonly subKind: ReceiverSubKind; readonly loc: Range; }; - export type ReceiverExternal = { readonly kind: "external"; readonly subKind: ReceiverSubKind; readonly loc: Range; }; - export type ReceiverBounce = { readonly kind: "bounce"; readonly param: TypedParameter; readonly loc: Range; }; - export type ReceiverKind = ReceiverInternal | ReceiverExternal | ReceiverBounce; diff --git a/src/next/example/map-len.tact b/src/next/example/map-len.tact new file mode 100644 index 0000000000..feffc1ae08 --- /dev/null +++ b/src/next/example/map-len.tact @@ -0,0 +1,30 @@ +struct MapL { + m: map; + l: uint16; +} + +extends fun get(self: MapL, key: K): V? { + return self.m.get(key); +} + +extends mutates fun set(self: MapL, key: K, value: V) { + if (!self.m.exists(key)) { + self.l += 1; + } + self.m.set(key, value); +} + +message Set { + key: uint8; + value: uint8; +} + +contract Test { + state: MapL; + receive(msg: Set) { + self.state.set(msg.key, msg.value); + } + get fun state(): MapL { + return self.state; + } +} diff --git a/src/next/example/scope1-a.tact b/src/next/example/scope1-a.tact new file mode 100644 index 0000000000..558ffa99f4 --- /dev/null +++ b/src/next/example/scope1-a.tact @@ -0,0 +1,2 @@ +import "./scope1-b"; +import "./scope1-c"; diff --git a/src/next/example/scope1-b.tact b/src/next/example/scope1-b.tact new file mode 100644 index 0000000000..14f28127d3 --- /dev/null +++ b/src/next/example/scope1-b.tact @@ -0,0 +1 @@ +fun f(): Int { return 1; } \ No newline at end of file diff --git a/src/next/example/scope1-c.tact b/src/next/example/scope1-c.tact new file mode 100644 index 0000000000..14f28127d3 --- /dev/null +++ b/src/next/example/scope1-c.tact @@ -0,0 +1 @@ +fun f(): Int { return 1; } \ No newline at end of file diff --git a/src/next/example/scope2-a.tact b/src/next/example/scope2-a.tact new file mode 100644 index 0000000000..59e6cd9c25 --- /dev/null +++ b/src/next/example/scope2-a.tact @@ -0,0 +1,2 @@ +import "./scope2-b"; +import "./scope2-c"; diff --git a/src/next/example/scope2-b.tact b/src/next/example/scope2-b.tact new file mode 100644 index 0000000000..0024bfb41a --- /dev/null +++ b/src/next/example/scope2-b.tact @@ -0,0 +1 @@ +import "./scope2-d"; diff --git a/src/next/example/scope2-c.tact b/src/next/example/scope2-c.tact new file mode 100644 index 0000000000..0024bfb41a --- /dev/null +++ b/src/next/example/scope2-c.tact @@ -0,0 +1 @@ +import "./scope2-d"; diff --git a/src/next/example/scope2-d.tact b/src/next/example/scope2-d.tact new file mode 100644 index 0000000000..14f28127d3 --- /dev/null +++ b/src/next/example/scope2-d.tact @@ -0,0 +1 @@ +fun f(): Int { return 1; } \ No newline at end of file diff --git a/src/next/example/set.tact b/src/next/example/set.tact new file mode 100644 index 0000000000..eb7cd235be --- /dev/null +++ b/src/next/example/set.tact @@ -0,0 +1,25 @@ +struct Set { + m: map; +} + +extends mutates fun add(self: Set, key: K) { + self.m.set(key, true); +} + +extends fun exists(self: Set, key: K): Bool { + return self.m.exists(key); +} + +message Add { + key: uint8; +} + +contract Test { + state: Set; + receive(msg: Add) { + self.state.add(msg.key); + } + get fun exists(key: uint8): Bool { + return self.state.exists(key); + } +} diff --git a/src/next/grammar/errors.ts b/src/next/grammar/errors.ts index c271a7e07f..367b5a7267 100644 --- a/src/next/grammar/errors.ts +++ b/src/next/grammar/errors.ts @@ -212,6 +212,78 @@ export const SyntaxErrors = (l: SourceLogger) => ({ setArgCount: () => (loc: Range) => { return l.at(loc).error(l.text`set takes exactly one type argument`); }, + abstractVirtual: () => (loc: Range) => { + return l.at(loc).error(l.text`"abstract" and "virtual" attributes cannot be used at the same time`); + }, + abstractOverride: () => (loc: Range) => { + return l.at(loc).error(l.text`"abstract" and "override" attributes cannot be used at the same time`); + }, + globalGetter: () => (loc: Range) => { + return l + .at(loc) + .error(l.text`"Getters must be defined within a contract"`); + }, + mutatesWithoutExtends: () => (loc: Range) => { + return l + .at(loc) + .error(l.text`Mutating functions must be extend functions`); + }, + extendsSelf: () => (loc: Range) => { + return l + .at(loc) + .error( + l.text`Extend function must have first parameter named "self"`, + ); + }, + globalWithAttr: () => (loc: Range) => { + return l + .at(loc) + .error( + l.text`Globally defined functions cannot have "abstract", "virtual", or "override" attributes`, + ); + }, + globalConstWithAttr: () => (loc: Range) => { + return l + .at(loc) + .error( + l.text`Globally defined constants cannot have "abstract", "virtual", or "override" attributes`, + ); + }, + localExtends: () => (loc: Range) => { + return l + .at(loc) + .error( + l.text`Only globally defined function can be an extension method`, + ); + }, + tooMuchInit: () => (loc: Range) => { + return l + .at(loc) + .error( + l.text`Init function was already defined`, + ); + }, + initFnAndParams: () => (loc: Range) => { + return l + .at(loc) + .error( + l.text`Cannot define init() on a contract that has contract parameters`, + ); + }, + abstractWithBody: () => (loc: Range) => { + return l + .at(loc) + .error( + l.text`Abstract declaration cannot have a body`, + ); + }, + noBodyNoAbstract: () => (loc: Range) => { + return l + .at(loc) + .error( + l.text`Declaration without a body must be abstract`, + ); + }, }); export type SyntaxErrors = ReturnType>; diff --git a/src/next/grammar/import-parser.ts b/src/next/grammar/import-parser.ts index 27fa1d0112..f92963fcec 100644 --- a/src/next/grammar/import-parser.ts +++ b/src/next/grammar/import-parser.ts @@ -52,7 +52,7 @@ export type ImportErrors = ReturnType>; export function parseImportString( importText: string, range: Range, - err: ImportErrors + err: ImportErrors, ): Ast.ImportPath { if (importText.endsWith("/")) { err.noFolderImports()(range); @@ -78,10 +78,7 @@ export function parseImportString( type: "stdlib", language, }; - } else if ( - guessedPath.startsWith("./") || - guessedPath.startsWith("../") - ) { + } else if (guessedPath.startsWith("./") || guessedPath.startsWith("../")) { return { path: fromString(guessedPath), type: "relative", diff --git a/src/next/grammar/index.ts b/src/next/grammar/index.ts index 25b0f9546b..3fcfaffff5 100644 --- a/src/next/grammar/index.ts +++ b/src/next/grammar/index.ts @@ -888,81 +888,60 @@ const parseStatements = return map(nodes, parseStatement)(ctx); }; -const parseFunctionAttribute = - (node: $ast.FunctionAttribute): Handler => - (ctx) => { - if (typeof node.name === "string") { - return Ast.FunctionAttributeRest(node.name, toRange(node.loc)); - } - - return Ast.FunctionAttributeGet( - node.name.methodId - ? parseExpression(node.name.methodId)(ctx) - : undefined, - toRange(node.loc), - ); - }; - -const checkAttributes = - (kind: "constant" | "function") => +const parseGetAttribute = ( - ctx: Context, - isAbstract: boolean, - attributes: readonly ( - | $ast.FunctionAttribute - | $ast.ConstantAttribute - )[], - loc: $.Loc, - ) => { - const { duplicate, tooAbstract, notAbstract } = ctx.err[kind]; - const k: Set = new Set(); - for (const { name, loc } of attributes) { - const type = typeof name === "string" ? name : name.$; - if (k.has(type)) { - duplicate(type)(toRange(loc)); + nodes: readonly $ast.FunctionAttribute[], + ): Handler => + (ctx) => { + const attrs: $ast.GetAttribute[] = []; + for (const node of nodes) { + if (typeof node.name === "object") { + attrs.push(node.name); } - k.add(type); } - if (isAbstract && !k.has("abstract")) { - notAbstract()(toRange(loc)); + const [head, ...tail] = attrs; + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + if (!head) { + return undefined; } - if (!isAbstract && k.has("abstract")) { - tooAbstract()(toRange(loc)); + for (const attr of tail) { + ctx.err.function.duplicate("get")(toRange(attr.loc)); } + return Ast.GetAttribute( + head.methodId ? parseExpression(head.methodId)(ctx) : undefined, + toRange(head.loc), + ); }; -const parseFunctionAttributes = - ( - nodes: readonly $ast.FunctionAttribute[], - isAbstract: boolean, - loc: $.Loc, - ): Handler => - (ctx) => { - checkAttributes("function")(ctx, isAbstract, nodes, loc); - return map(nodes, parseFunctionAttribute)(ctx); - }; - -const parseConstantAttribute = - ({ name, loc }: $ast.ConstantAttribute): Handler => - (_ctx) => { - return Ast.ConstantAttribute(name, toRange(loc)); - }; +type NamedAttr = + | "mutates" + | "extends" + | "virtual" + | "override" + | "inline" + | "abstract"; -const parseConstantAttributes = +const parseNamedAttr = + (key: K) => ( - nodes: readonly $ast.ConstantAttribute[], - isAbstract: boolean, - loc: $.Loc, - noAttributes: boolean, - ): Handler => + nodes: readonly ($ast.FunctionAttribute | $ast.ConstantAttribute)[], + ): Handler => (ctx) => { - const [head] = nodes; + const attrs: Range[] = []; + for (const node of nodes) { + if (typeof node.name === "string" && node.name === key) { + attrs.push(toRange(node.loc)); + } + } + const [head, ...tail] = attrs; // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition - if (noAttributes && head) { - ctx.err.topLevelConstantWithAttribute()(toRange(head.loc)); + if (!head) { + return undefined; + } + for (const range of tail) { + ctx.err.function.duplicate(key)(range); } - checkAttributes("constant")(ctx, isAbstract, nodes, loc); - return map(nodes, parseConstantAttribute)(ctx); + return head; }; const parseParameter = @@ -1408,110 +1387,102 @@ const parseAsmShuffle = }; }; -const parseUnsupportedAsmFunction = - (node: $ast.AsmFunction): Handler => +const parseAsmFunctionRaw = + (node: $ast.AsmFunction): Handler => (ctx) => { - ctx.err.unsupportedAsmFunctionInContracts()(toRange(node.loc)); - return parseAsmFunction(node)(ctx); - }; - -const parseAsmFunction = - (node: $ast.AsmFunction): Handler => - (ctx) => { - return Ast.AsmFunctionDef( - parseAsmShuffle(node.shuffle)(ctx), - parseFunctionAttributes(node.attributes, false, node.loc)(ctx), + return Ast.Function( + !!parseNamedAttr("inline")(node.attributes)(ctx), parseId(node.name)(ctx), map(parseList(node.typeParams), parseTypeId)(ctx), node.returnType ? parseType(node.returnType)(ctx) : undefined, map(parseList(node.parameters), parseParameter)(ctx), - [node.instructions.trim()], + Ast.AsmBody(parseAsmShuffle(node.shuffle)(ctx), [ + node.instructions.trim(), + ]), toRange(node.loc), ); }; -const parseContractInit = - ({ parameters, body, loc }: $ast.ContractInit): Handler => - (ctx) => { - return Ast.ContractInit( - map(parseList(parameters), parseParameter)(ctx), - map(body, parseStatement)(ctx), - toRange(loc), - ); - }; - -const parseConstantDefInModule = - (node: $ast.Constant): Handler => - (ctx) => { - return parseConstantDef(node, true)(ctx); - }; - -const parseConstantDef = - (node: $ast.Constant, noAttributes: boolean): Handler => - (ctx) => { - const result = parseConstant(node, noAttributes)(ctx); +const checkNoGlobalAttrs = ( + attrs: readonly ($ast.FunctionAttribute | $ast.ConstantAttribute)[], + range: Range, +): Handler => ctx => { + const isVirtual = parseNamedAttr("virtual")(attrs)(ctx); + const isOverride = parseNamedAttr("override")(attrs)(ctx); + const isAbstract = parseNamedAttr("abstract")(attrs)(ctx); + if (isVirtual || isOverride || isAbstract) { + ctx.err.globalWithAttr()(range); + } +}; - if (result.kind !== "constant_def") { - ctx.err.noConstantDecl()(toRange(node.loc)); - return { - ...result, - kind: "constant_def", - initializer: Ast.Number("10", 0n, toRange(node.loc)), - }; +const parseInheritance = ( + hasBody: boolean, + attrs: readonly ($ast.FunctionAttribute | $ast.ConstantAttribute)[], + range: Range, +): Handler<{ override: boolean, virtual: boolean }> => ctx => { + const isVirtual = parseNamedAttr("virtual")(attrs)(ctx); + const isOverride = parseNamedAttr("override")(attrs)(ctx); + const isAbstract = parseNamedAttr("abstract")(attrs)(ctx); + if (isAbstract) { + if (isVirtual) { + ctx.err.abstractVirtual()(isVirtual); } - - return result; + if (isOverride) { + ctx.err.abstractOverride()(isOverride); + } + if (hasBody) { + ctx.err.abstractWithBody()(isAbstract); + } + } else { + if (!hasBody) { + ctx.err.noBodyNoAbstract()(range); + } + } + return { + override: !!isOverride, + virtual: !!isVirtual, }; - -const parseConstantDefLocal = (node: $ast.Constant) => - parseConstantDef(node, false); +}; const parseConstant = - ( - node: $ast.Constant, - noAttributes: boolean, - ): Handler => + (node: $ast.Constant): Handler => (ctx) => { const name = parseId(node.name)(ctx); - const type = node.type ? parseType(node.type)(ctx) : undefined; - - if (node.body.$ === "ConstantDeclaration") { - const attributes = parseConstantAttributes( - node.attributes, - true, - node.loc, - noAttributes, - )(ctx); - const range = toRange(node.loc); - if (!type) { - ctx.err.constDeclNoType()(range); - return Ast.ConstantDecl( - attributes, - name, - Ast.TypeCons(Ast.TypeId("ERROR", range), [], range), - range, + const range = toRange(node.loc); + const type = (() => { + if (node.body.$ === "ConstantDefinition") { + return Ast.ConstantDef( + node.type ? parseType(node.type)(ctx) : undefined, + parseExpression(node.body.expression)(ctx) ); + } else if (node.type) { + return Ast.ConstantDecl(parseType(node.type)(ctx)); + } else { + ctx.err.constDeclNoType()(range); + return Ast.ConstantDecl(Ast.TypeCons(Ast.TypeId("ERROR", range), [], range)); } - return Ast.ConstantDecl(attributes, name, type, range); - } else { - const attributes = parseConstantAttributes( - node.attributes, - false, - node.loc, - noAttributes, - )(ctx); - const initializer = parseExpression(node.body.expression)(ctx); - return Ast.ConstantDef( - attributes, - name, - type, - initializer, - toRange(node.loc), - ); - } + })(); + return Ast.Constant(name, type, range); }; -const parseConstantLocal = (node: $ast.Constant) => parseConstant(node, false); +const parseConstantGlobal = + (node: $ast.Constant): Handler => + (ctx) => { + checkNoGlobalAttrs(node.attributes, toRange(node.loc))(ctx); + return parseConstant(node)(ctx); + }; + +const parseFieldConstant = + (node: $ast.Constant): Handler => + (ctx) => { + const body = parseConstant(node)(ctx); + const inh = parseInheritance( + body.init.kind === 'constant_def', + node.attributes, + toRange(node.loc), + )(ctx); + return Ast.FieldConstant(inh.virtual, inh.override, body); + }; const parseContract = ({ @@ -1535,35 +1506,51 @@ const parseContract = }, ); + const initFns: $ast.ContractInit[] = []; + const locals: $ast.traitItemDecl[] = []; + for (const decl of declarations) { + if (decl.$ === 'ContractInit') { + initFns.push(decl); + } else { + locals.push(decl); + } + } + const [initFn, ...restInitFns] = initFns; + for (const fn of restInitFns) { + ctx.err.tooMuchInit()(toRange(fn.loc)); + } + + const init = (() => { + if (typeof parameters !== "undefined") { + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + if (initFn) { + ctx.err.initFnAndParams()(toRange(initFn.loc)); + } + return Ast.InitParams(params); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + } else if (initFn) { + return Ast.InitFunction( + map(parseList(initFn.parameters), parseParameter)(ctx), + map(initFn.body, parseStatement)(ctx), + toRange(loc), + ); + } else { + return undefined; + } + })(); + return Ast.Contract( parseTypeId(name)(ctx), map(parseList(traits), parseTypeId)(ctx), map(attributes, parseContractAttribute)(ctx), - typeof parameters !== "undefined" ? params : undefined, - map(declarations, parseContractItem)(ctx), + init, + map(locals, parseLocalItem)(ctx), toRange(loc), ); }; -const parseFunctionDef = - (node: $ast.$Function): Handler => - (ctx) => { - const result = parseFunction(node)(ctx); - - if (result.kind !== "function_def") { - ctx.err.noFunctionDecl()(toRange(node.loc)); - return { - ...parseFunction(node)(ctx), - kind: "function_def", - statements: [], - }; - } - - return result; - }; - -const parseFunction = - (node: $ast.$Function): Handler => +const parseFunctionRaw = + (node: $ast.$Function): Handler => (ctx) => { const name = parseId(node.name)(ctx); const returnType = node.returnType @@ -1573,38 +1560,104 @@ const parseFunction = const parameters = map(parseList(node.parameters), parseParameter)(ctx); if (node.body.$ === "FunctionDeclaration") { - const attributes = parseFunctionAttributes( - node.attributes, - true, - node.loc, - )(ctx); - return Ast.FunctionDecl( - attributes, + const inline = !!parseNamedAttr("inline")(node.attributes)(ctx); + return Ast.Function( + inline, name, typeParams, returnType, parameters, + Ast.AbstractBody(), toRange(node.loc), ); } else { - const attributes = parseFunctionAttributes( - node.attributes, - false, - node.loc, - )(ctx); + const inline = !!parseNamedAttr("inline")(node.attributes)(ctx); const statements = map(node.body.body, parseStatement)(ctx); - return Ast.FunctionDef( - attributes, + return Ast.Function( + inline, name, typeParams, returnType, parameters, - statements, + Ast.RegularBody(statements), toRange(node.loc), ); } }; +const parseExtension = + ( + parseFunction: (node: T) => Handler, + ) => + (node: T): Handler => + (ctx) => { + const fn = parseFunction(node)(ctx); + const get = parseGetAttribute(node.attributes)(ctx); + if (get) { + ctx.err.globalGetter()(get.loc); + } + checkNoGlobalAttrs(node.attributes, toRange(node.loc))(ctx); + const isMutates = parseNamedAttr("mutates")(node.attributes)(ctx); + const isExtends = parseNamedAttr("extends")(node.attributes)(ctx); + if (!isExtends) { + if (isMutates) { + ctx.err.mutatesWithoutExtends()(isMutates); + } + return fn; + } + const [first, ...rest] = fn.params; + const selfType = (() => { + if ( + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + !first || + first.name.kind !== "id" || + first.name.text !== "self" + ) { + const range = toRange(node.loc); + ctx.err.extendsSelf()(range); + return Ast.TypeCons(Ast.TypeId("ERROR", range), [], range); + } + return first.type; + })(); + return Ast.Extension( + Ast.Method( + !!isMutates, + false, + false, + undefined, + { ...fn, params: rest } + ), + selfType, + ); + }; + +const parseMethod = + ( + parseFunction: (node: T) => Handler, + ) => + (node: T): Handler => + (ctx) => { + const fn = parseFunction(node)(ctx); + const get = parseGetAttribute(node.attributes)(ctx); + const inh = parseInheritance( + fn.body.kind !== 'abstract_body', + node.attributes, + toRange(node.loc), + )(ctx); + const isMutates = parseNamedAttr("mutates")(node.attributes)(ctx); + const isExtends = parseNamedAttr("extends")(node.attributes)(ctx); + if (isExtends) { + ctx.err.localExtends()(toRange(node.loc)); + } + return Ast.Method( + !!isMutates, + inh.virtual, + inh.override, + get, + fn, + ); + }; + const parseMessageDecl = ({ name, @@ -1630,26 +1683,27 @@ const parseNativeFunctionDecl = parameters, returnType, loc, - }: $ast.NativeFunctionDecl): Handler => + }: $ast.NativeFunctionDecl): Handler => (ctx) => { - return Ast.NativeFunctionDecl( - map(attributes, parseFunctionAttribute)(ctx), + return Ast.Function( + !!parseNamedAttr("inline")(attributes)(ctx), parseId(name)(ctx), map(parseList(typeParams), parseTypeId)(ctx), - parseFuncId(nativeName)(ctx), - map(parseList(parameters), parseParameter)(ctx), returnType ? parseType(returnType)(ctx) : undefined, + map(parseList(parameters), parseParameter)(ctx), + Ast.NativeBody(parseFuncId(nativeName)(ctx)), toRange(loc), ); }; const parseAlias = - ({ name, typeParams, type }: $ast.AliasDecl): Handler => + ({ name, typeParams, type, loc }: $ast.AliasDecl): Handler => (ctx) => { return Ast.AliasDecl( parseTypeId(name)(ctx), map(parseList(typeParams), parseTypeId)(ctx), parseType(type)(ctx), + toRange(loc), ); }; @@ -1716,39 +1770,28 @@ const parseTrait = parseTypeId(name)(ctx), traits ? map(parseList(traits), parseTypeId)(ctx) : [], map(attributes, parseContractAttribute)(ctx), - map(declarations, parseTraitItem)(ctx), + map(declarations, parseLocalItem)(ctx), toRange(loc), ); }; - -const parseContractItem: ( - input: $ast.contractItemDecl, -) => Handler = makeVisitor<$ast.contractItemDecl>()({ - ContractInit: parseContractInit, +const parseLocalItem: ( + input: $ast.traitItemDecl, +) => Handler = makeVisitor<$ast.traitItemDecl>()({ FieldDecl: parseFieldDecl, Receiver: parseReceiver, - Function: parseFunctionDef, - AsmFunction: parseUnsupportedAsmFunction, - Constant: parseConstantDefLocal, + Function: parseMethod(parseFunctionRaw), + AsmFunction: parseMethod(parseAsmFunctionRaw), + Constant: parseFieldConstant, }); -const parseTraitItem: (input: $ast.traitItemDecl) => Handler = - makeVisitor<$ast.traitItemDecl>()({ - FieldDecl: parseFieldDecl, - Receiver: parseReceiver, - Function: parseFunction, - AsmFunction: parseUnsupportedAsmFunction, - Constant: parseConstantLocal, - }); - type ModuleItemAux = Exclude<$ast.moduleItem, $ast.PrimitiveTypeDecl>; const parseModuleItemAux: (input: ModuleItemAux) => Handler = makeVisitor()({ - Function: parseFunctionDef, - AsmFunction: parseAsmFunction, - NativeFunctionDecl: parseNativeFunctionDecl, - Constant: parseConstantDefInModule, + Function: parseExtension(parseFunctionRaw), + AsmFunction: parseExtension(parseAsmFunctionRaw), + NativeFunctionDecl: parseExtension(parseNativeFunctionDecl), + Constant: parseConstantGlobal, StructDecl: parseStructDecl, MessageDecl: parseMessageDecl, Contract: parseContract, @@ -1787,12 +1830,6 @@ const parseModule = ); }; -// const parseJustImports = -// ({ imports }: $ast.JustImports): Handler => -// (ctx) => { -// return map(imports, parseImport)(ctx); -// }; - export const parse = ( log: SourceLogger, text: string, diff --git a/src/next/imports/reader.ts b/src/next/imports/reader.ts index aa14407071..2da8bf2d88 100644 --- a/src/next/imports/reader.ts +++ b/src/next/imports/reader.ts @@ -3,11 +3,8 @@ import { emptyPath, fromString } from "@/imports/path"; import { parentPath, createMemoryFs, createProxyFs } from "@/next/fs"; import { getFiles } from "@/next/stdlib"; import type { Cursor } from "@/next/fs"; -import type { Logger, SourceLogger } from "@/error/logger-util"; -import type { FuncImport, ResolvedImport, Source } from "@/next/imports/source"; -import type { ImportPath, ModuleItem } from "@/next/ast"; -import type { Language, Range } from "@/next/ast/common"; -import { throwInternal } from "@/error/errors"; +import type { AnyLogger, Logger, SourceLogger } from "@/error/logger-util"; +import type { ResolvedImport, TactSource } from "@/next/imports/source"; type Options = { readonly log: Logger; @@ -27,30 +24,7 @@ type Options = { /** * Name of root source file of the project */ - readonly rootPath: ImportPath; -}; - -type DepId = string; -type RawTactSource = { - readonly code: string; - readonly imports: readonly RawImport[]; - readonly items: readonly ModuleItem[]; -}; -type RawFuncSource = { - readonly code: string; - readonly imports: readonly RawFuncImport[]; -} - -type RawImport = RawTactImport | RawFuncImport; -type RawTactImport = { - readonly language: "tact"; - readonly depId: DepId; - readonly loc: Range; -}; -type RawFuncImport = { - readonly language: "func"; - readonly depId: DepId; - readonly loc: Range; + readonly root: string; }; const readSource = async ({ @@ -58,156 +32,64 @@ const readSource = async ({ project, stdlib, implicits, - rootPath, -}: Options) => { - const status: Map = new Map(); - const tactRaw: Map = new Map(); - const funcRaw: Map = new Map(); + root, +}: Options): Promise => { + const status: Map = new Map(); - const resolveTactImports = async ( + const resolveImports = async ( + path: string, log: SourceLogger, - dir: Cursor, + file: Cursor, code: string, - ): Promise => { + ): Promise => { const { imports: rawImports, items } = parse(log, code); - const imports: RawImport[] = []; - for (const { importPath: { language, path, type }, loc } of rawImports) { - imports.push({ - language, - depId: await resolveSource( - type === "relative" - ? dir.focus(path) - : stdlib.focus(path), - language, - ), - loc, - }); + const imports: ResolvedImport[] = [...implicits]; + for (const { importPath, loc } of rawImports) { + const { language, path, type } = importPath; + const importedFile = + type === "relative" + ? file.focus(parentPath).focus(path) + : stdlib.focus(path); + if (language === "tact") { + const source = await resolveSource(importedFile, log); + if (source) { + imports.push({ kind: "tact", source, loc }); + } + } else { + imports.push({ kind: "func", code, loc }); + } } - return { code, imports, items }; - }; - - const resolveFuncImports = async ( - _log: SourceLogger, - _file: Cursor, - code: string, - // eslint-disable-next-line @typescript-eslint/require-await - ): Promise => { - // TODO: resolve imports - return { code, imports: [] }; + return { kind: 'tact', path, code, imports, items }; }; - const resolveSource = async (file: Cursor, language: Language): Promise => { + const resolveSource = async ( + file: Cursor, + parentLog: AnyLogger, + ): Promise => { const path = file.getAbsolutePathForLog(); - // this file is already currently being resolved - if (status.has(path)) { - return path; + const res = status.get(path); + if (typeof res === "object") { + return res; + } + if (res === "pending") { + parentLog.error( + parentLog.text`Cyclic import: ${parentLog.path(path)}`, + ); + return; } - status.set(path, 'pending'); + status.set(path, "pending"); const code = await file.read(); if (!code) { - status.set(path, 'errored'); - return path; + return; } - const dir = file.focus(parentPath); - await log.source(path, code, async (log) => { - if (language === 'tact') { - tactRaw.set(path, await resolveTactImports(log, dir, code)); - } else { - funcRaw.set(path, await resolveFuncImports(log, dir, code)); - } + const source = await log.source(path, code, (log) => { + return resolveImports(path, log, file, code); }); - status.set(path, 'done'); - return path; + status.set(path, source); + return source; }; - if (rootPath.type !== 'relative') { - log.error(log.text`Cannot build standard library as root`); - return undefined; - } - if (rootPath.language !== 'tact') { - log.error(log.text`Use ${rootPath.language} compiler`); - return undefined; - } - - const rootDepId = await resolveSource(project.focus(rootPath.path), rootPath.language); - - if ([...status.values()].includes("errored")) { - return undefined; - } - - const func: Map = new Map(); - for (const [key, { code }] of funcRaw) { - func.set(key, { - kind: 'func', - code, - imports: [], - }); - } - for (const [key, { imports }] of funcRaw) { - const entry = func.get(key); - if (!entry) { - return throwInternal("Impossible"); - } - entry.imports = imports.map(({ depId, language, loc }): FuncImport => { - const source = func.get(depId); - if (!source) { - return throwInternal("Impossible"); - } - return { kind: language, source, loc }; - }); - } - - const tact: Map = new Map(); - for (const [key, { code, items }] of tactRaw) { - tact.set(key, { - kind: 'tact', - code, - imports: [], - items, - }); - } - for (const [key, { imports }] of tactRaw) { - const entry = tact.get(key); - if (!entry) { - return throwInternal("Impossible"); - } - entry.imports = [ - ...implicits, - ...imports.map((i): ResolvedImport => { - if (i.language === 'func') { - const source = func.get(i.depId); - if (!source) { - return throwInternal("Impossible"); - } - return { kind: 'func', source, loc: i.loc }; - } else { - const source = tact.get(i.depId); - if (!source) { - return throwInternal("Impossible"); - } - return { kind: 'tact', source, loc: i.loc }; - } - }), - ]; - } - - const sources: Source[] = [...func.values(), ...tact.values()]; - const root = tact.get(rootDepId); - - if (!root) { - return undefined; - } - - return { sources, root }; + return resolveSource(project.focus(fromString(root)), log); }; /** @@ -226,11 +108,7 @@ export const ProjectReader = async (log: Logger) => { project: stdRoot, stdlib: stdLibs, implicits: [], - rootPath: { - type: 'relative', - language: 'tact', - path: fromString("std/stdlib.tact"), - }, + root: "std/stdlib.tact", }); if (!stdStd) { // Could not load standard library @@ -241,7 +119,7 @@ export const ProjectReader = async (log: Logger) => { /** * Read project */ - const read = async (fsRootPath: string, rootPath: ImportPath) => { + const read = async (fsRootPath: string, tactRoot: string) => { const project = createProxyFs({ log, root: fsRootPath, @@ -250,25 +128,17 @@ export const ProjectReader = async (log: Logger) => { const implicits: ResolvedImport[] = [ { kind: "tact", - source: stdStd.root, + source: stdStd, loc: { start: 0, end: 0 }, }, ]; - const result = await readSource({ + return await readSource({ log, project, stdlib: stdLibs, implicits, - rootPath, + root: tactRoot, }); - if (!result) { - return undefined; - } - - return { - root: result.root, - sources: [...stdStd.sources, ...result.sources], - }; }; return { read }; diff --git a/src/next/imports/source.ts b/src/next/imports/source.ts index 46fd3b9c20..cd7f229857 100644 --- a/src/next/imports/source.ts +++ b/src/next/imports/source.ts @@ -1,26 +1,21 @@ import type { ModuleItem, Range } from "@/next/ast"; -export type Source = TactSource | FuncSource; export type TactSource = { readonly kind: "tact"; + readonly path: string; readonly code: string; readonly imports: readonly ResolvedImport[]; readonly items: readonly ModuleItem[]; }; -export type FuncSource = { - readonly kind: "func"; - readonly code: string; - readonly imports: readonly FuncImport[]; -} export type ResolvedImport = TactImport | FuncImport; export type TactImport = { readonly kind: "tact"; - readonly source: Source; + readonly source: TactSource; readonly loc: Range; }; export type FuncImport = { readonly kind: "func"; - readonly source: FuncSource; + readonly code: string; readonly loc: Range; }; diff --git a/src/next/index.ts b/src/next/index.ts index 00eae662d5..df5fc9ac5a 100644 --- a/src/next/index.ts +++ b/src/next/index.ts @@ -2,10 +2,13 @@ import path from "path"; import { TerminalLogger } from "@/cli/logger"; import { getAnsiMarkup, isColorSupported } from "@/cli/colors"; import { ProjectReader } from "@/next/imports/reader"; -import { fromString } from "@/imports/path"; -import { inspect } from 'util'; -// eslint-disable-next-line @typescript-eslint/no-confusing-void-expression -const dump = (obj: unknown) => console.log(inspect(obj, { colors: false, depth: Infinity })); +import { inspect } from "util"; +import { scope } from "@/next/scoping/tc2"; + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +const dump = (obj: unknown) => + // eslint-disable-next-line @typescript-eslint/no-confusing-void-expression + console.log(inspect(obj, { colors: false, depth: Infinity })); const main = async () => { const ansi = getAnsiMarkup(isColorSupported()); @@ -15,17 +18,16 @@ const main = async () => { const reader = await ProjectReader(log); if (!reader) return; const result = await reader.read( - path.join(__dirname, "example"), + path.join(__dirname, "example"), // TODO: parseImportString(root, ImportErrors(log)) when there are CLI/config loggers - { - language: 'tact', - type: 'relative', - path: fromString("mutual1.tact"), - }, + "scope2-a.tact", ); - if (result) { - dump(result.sources.length); + if (!result) { + return; } + // dump(result.sources.length); + // dump(result); + scope(log, result); }); }); }; diff --git a/src/next/scoping/const.ts b/src/next/scoping/const.ts new file mode 100644 index 0000000000..3b274cd087 --- /dev/null +++ b/src/next/scoping/const.ts @@ -0,0 +1,180 @@ +import type { ConstantDecl, ConstantDef, Expression } from "@/next/ast"; +import type { Id } from "@/next/ast/common"; +import type { Var } from "@/next/ast/expression"; +import type { TactSource } from "@/next/imports/source"; + +const ensureMap = (m: Map, k: K, v: V): V => { + const prev = m.get(k); + if (prev) { + return prev; + } else { + const x = {...v}; + m.set(k, x); + return x; + } +}; + +// constDefs: Map +// freeVars: Map +// varsInConst: Map + +// TactSource . items . ConstantDef . Expr/Var . name . !(TactSource . items . ConstantDef . name) +// TactSource . items . ConstantDef . name . !(TactSource . items . ConstantDef . name) +// TactSource . items . ConstantDef . (Expr/Var . name . !(ConstantDef . name))* . name + +type GlobalEnv = { + readonly freeVars: Map>; + readonly definedConsts: Set; + readonly constDefByName: Map; + readonly transitiveUse: Map; +} + +// const x = (Foo {}).y; +// struct Foo { +// y: Int as int32 = x; +// } + + +type Env = Map; + readonly usedBy: Set; +}> +const empty = { + definedBy: new Set(), + usedBy: new Set(), +} as const; +const define = (env: Env, id: Id) => ensureMap(env, id.text, empty).definedBy.add(id); +const use = (env: Env, id: Id) => ensureMap(env, id.text, empty).usedBy.add(id); + +// const c1 = 42; +// const c2 = c1 + 5; + +type Name = string; +interface Scope { + readonly constants: Env; + readonly children: Scope[]; +} +const Scope = (parent?: Scope): Scope => { + const scope: Scope = { constants: new Map(), children: [] }; + parent?.children.push(scope); + return scope; +}; + +export const resolve = (node: TactSource) => { + const global = Scope() + resolveTop(node, global); + // TODO: flatten scope + const flatGlobal = global; + checkDefinedOnce(flatGlobal); + checkSortable(flatGlobal); +}; + +const checkDefinedOnce = (scope: Scope) => { + for (const { definedBy, usedBy } of scope.constants.values()) { + if (definedBy.size === 0) { + for (const use of usedBy) { + console.error(`Constant was not defined ${use.loc.start}`); + } + } else if (definedBy.size > 1) { + for (const def of definedBy) { + console.error(`Constant was already defined ${def.loc.start}`); + } + } + } +} + +const checkSortable = (scope: Scope) => { + scope.constants +}; + +const resolveTop = ({ items }: TactSource, scope: Scope) => { + for (const item of items) { + switch (item.kind) { + case "constant_def": { + const { attributes: _a, initializer, name, type } = item; + define(scope.constants, name); + const child = resolveExpr(initializer, scope); + return; + } + case "function_def": + case "asm_function_def": + case "native_function_decl": + return; + case "struct_decl": + case "message_decl": + case "union_decl": + case "alias_decl": + case "contract": + case "trait": + return; + } + } +}; + +const resolveExpr = (root: Expression, parentScope: Scope) => { + const scope = Scope(parentScope); + const recAll = (nodes: readonly Expression[]) => { + for (const node of nodes) { + rec(node); + } + }; + const rec = (node: Expression) => { + switch (node.kind) { + case "var": + use(scope.constants, node.name); + return; + case "string": + case "number": + case "boolean": + return; + case "op_binary": + rec(node.left); + rec(node.right); + return; + case "op_unary": + rec(node.operand); + return; + case "conditional": + rec(node.condition); + rec(node.thenBranch); + rec(node.elseBranch); + return; + case "method_call": + rec(node.self); + recAll(node.args); + return; + case "field_access": + rec(node.aggregate); + return; + case "static_call": + recAll(node.args); + return; + case "struct_instance": + recAll(node.args.map(x => x.initializer)); + return; + case "init_of": + recAll(node.args); + return; + case "code_of": + return; + case "null": + return; + case "unit": + return; + case "tuple": + recAll(node.children); + return; + case "tensor": + recAll(node.children); + return; + case "map_literal": + recAll(node.fields.flatMap(({ key, value }) => [key, value])); + return; + case "set_literal": + recAll(node.fields); + return; + } + }; + rec(root); + return scope; +}; \ No newline at end of file diff --git a/src/next/scoping/scoped-ast.ts b/src/next/scoping/scoped-ast.ts new file mode 100644 index 0000000000..f913768e63 --- /dev/null +++ b/src/next/scoping/scoped-ast.ts @@ -0,0 +1,73 @@ +export type ScopeId = string; + +export type Constraint = + | Define + | Use + | Child + +export type Define = { + readonly kind: 'define'; + readonly name: string; + readonly scope: ScopeId; +} + +export type Use = { + readonly kind: 'use'; + readonly name: string; + readonly scope: ScopeId; +} + +type Name = string +export type Scope = StmtScope + +type StmtScope = { + readonly kind: 'stmt_scope'; + readonly parent: Scope | undefined; + readonly vars: Map; + definedBy: Set; + }>; + readonly types: Map; + readonly functions: Map; +} + +fun f(y: Int) { + let x = y + 1; + { + let z = 0; + } + let z = 0; + return x + z; +} + +ensureMap(s.vars, "y", def) + +getVar(s, "y").definedBy.add(f) + +for (const s of scopes) { + for (const [k, { usedBy, definedBy }] of s.vars) { + if (definedBy.size === 0) { + for (const usage of usedBy) { + error(`Variable ${k} was not defined`, usage.loc); + } + } else if (definedBy.size > 1) { + const [head, ...tail] = definedBy; + for (const def of tail) { + error(`Variable ${k} is already defined`, def.loc); + } + } else { + + } + } +} + +const ensureMap = (m: Map, k: K, v: V): V => { + const prev = m.get(k); + if (prev) { + return prev; + } else { + const x = {...v}; + m.set(k, x); + return x; + } +}; diff --git a/src/next/scoping/tc.ts b/src/next/scoping/tc.ts new file mode 100644 index 0000000000..97fc4bfea9 --- /dev/null +++ b/src/next/scoping/tc.ts @@ -0,0 +1,179 @@ +import { makeVisitor } from "@/utils/tricks"; +import type { Range } from "@/next/ast"; +import type { Logger, SourceLogger } from "@/error/logger-util"; +import type { TactSource } from "@/next/imports/source"; +import type * as Ast from "@/next/ast/root"; + +const TcErrors = (l: SourceLogger) => ({ + // FIXME + foo: () => (loc: Range) => { + return l.at(loc).error(l.text`Bar`); + }, + + duplicateParam: () => (loc: Range) => { + return l.at(loc).error(l.text`Duplicate parameter`); + }, + duplicateDecl: () => (loc: Range) => { + return l.at(loc).error(l.text`Duplicate declaration`); + }, +}); + +type TcErrors = ReturnType>; + +type Name = string; +type Context = { + log: Logger; + err: TcErrors; + + typeNames: Map; +}; +type Tc = (ctx: Context) => void; + +const tcDummy = (): Tc => () => {}; + +const map = + (ts: readonly T[], handler: (t: T) => Tc): Tc => + (ctx) => { + for (const t of ts) { + handler(t)(ctx); + } + }; + +export const tcSource = + ({ path, code, imports, items }: TactSource): Tc => + (ctx) => { + ctx.log.source(path, code, (log) => { + const newCtx: Context = { + log: ctx.log, + err: TcErrors(log), + typeNames: new Map(), + }; + map(items, collectTypeEnv)(newCtx); + map(items, tcModuleItem)(newCtx); + }); + }; + +type TypeDecls = + | Ast.StructDecl + | Ast.MessageDecl + | Ast.UnionDecl + | Ast.AliasDecl + | Ast.Contract + | Ast.Trait; + +const collectTypeEnvStruct = + (node: TypeDecls): Tc => + (ctx) => { + const prev = ctx.typeNames.get(node.name.text); + if (typeof prev !== "undefined") { + ctx.err.duplicateDecl()(node.loc); + } else { + ctx.typeNames.set(node.name.text, node); + } + }; + +const collectTypeEnv = makeVisitor()({ + function_def: tcDummy, + asm_function_def: tcDummy, + native_function_decl: tcDummy, + constant_def: tcDummy, + + struct_decl: collectTypeEnvStruct, + message_decl: collectTypeEnvStruct, + union_decl: collectTypeEnvStruct, + alias_decl: collectTypeEnvStruct, + contract: collectTypeEnvStruct, + trait: collectTypeEnvStruct, +}); + +const checkParamDuplicates = + (params: readonly Ast.AsmTypedParameter[]): Tc => + (ctx) => { + const names: Set = new Set(); + for (const { + name: { text }, + loc, + } of params) { + if (names.has(text)) { + ctx.err.duplicateParam()(loc); + } else { + names.add(text); + } + } + }; + +// AsmFunctionDef: +// Cannot use ... attrubute on global assembly functions +// attributes kind == "get" +// attributes kind == "virtual" | "abstract" | "override" | "inline" + +// Only a method can be mutating. Did you forget "extends"? +// attributes kind has "mutates", doesn't have "extends" + +// Duplicate function definition +// (imports* AsmFunctionDef name) . size > 1 + +// Duplicate parameter +// asm fun f(x: Int, x: Foo) {} +// (Source AsmFunctionDef params name) . size > 1 + +// Type is not defined +// asm fun f(x: Nonexist) {} +// AsmFunctionDef (params type | retType) Type/TypeCons: +// .name !in (imports* TypeDecl name | .typeParams) + +// `F` expects 1 argument. Passed 2 arguments. +// struct F {} asm fun f(x: F) {} +// AsmFunctionDef (params type | retType) Type/TypeCons typeArgs length +// != imports* TypeDecl typeParams length + +// `F` type parameter is shadowing globally defined type +// struct F {} asm fun f(x: F) {} +// AsmFunctionDef typeParams name +// in imports* TypeDecl name + +// TypeDecl = StructDecl | MessageDecl | UnionDecl | AliasDecl | Contract | Trait + +// Duplicate type parameter +// (Source AsmFunctionDef typeParams name) . size > 1 + +// Shuffle must be a permutation of all function parameters +// asm(c c) extends fun f(self: Builder, c: Cell?) {} +// AsmFunctionDef: (.shuffle args text).sort() = (.params name text).sort() + +// extends fun попадают в скоуп self +// trait A { abstract fun f(): Int; } +// contract B {} +// override extends asm fun f(self: B): Int {} + +const tcAsmFunction = + ({ + attributes, + name, + params, + return: retType, + shuffle, + typeParams, + loc, + }: Ast.AsmFunctionDef): Tc => + (ctx) => { + checkParamDuplicates(params)(ctx); + + for (const arg of shuffle.args) { + arg.text; + } + }; + +const tcModuleItem = makeVisitor()({ + function_def: tcDummy, + asm_function_def: tcAsmFunction, + native_function_decl: tcDummy, + constant_def: tcDummy, + + struct_decl: tcDummy, + message_decl: tcDummy, + union_decl: tcDummy, + alias_decl: tcDummy, + contract: tcDummy, + trait: tcDummy, +}); diff --git a/src/next/scoping/tc2.ts b/src/next/scoping/tc2.ts new file mode 100644 index 0000000000..47c3e91f31 --- /dev/null +++ b/src/next/scoping/tc2.ts @@ -0,0 +1,336 @@ +import { entries, makeVisitor, memo } from "@/utils/tricks"; +import type { Range } from "@/next/ast"; +import type { Logger, SourceLogger } from "@/error/logger-util"; +import type { TactImport, TactSource } from "@/next/imports/source"; +import type * as Ast from "@/next/ast"; +import { mapValues } from "@/utils/array"; + +const TcErrors = (l: SourceLogger) => ({ + // FIXME + foo: () => (loc: Range) => { + return l.at(loc).error(l.text`Bar`); + }, + + attrNotAllowed: (name: string) => (loc: Range) => { + return l.at(loc).error(l.text`Attribute ${name} not allowed here`); + }, + duplicateParam: () => (loc: Range) => { + return l.at(loc).error(l.text`Duplicate parameter`); + }, + duplicateDecl: () => (loc: Range) => { + return l.at(loc).error(l.text`Duplicate declaration`); + }, + duplicateImport: () => (loc: Range) => { + return l.at(loc).error(l.text`Duplicate import`); + }, + selfImport: () => (loc: Range) => { + return l.at(loc).error(l.text`Cannot self-import`); + }, + mutatesWithoutExtends: () => (loc: Range) => { + return l + .at(loc) + .error( + l.text`Only a method can be mutating. Did you forget "extends"?`, + ); + }, + shadowsImported: (name: string, prevPath: string, prevRange: Range) => (loc: Range) => { + return l + .at(loc) + .error(l.text`Declaration of "${name}" shadows previous declaration "${l.locatedId(name, prevPath, prevRange)}"`); + }, +}); + +type TcErrors = ReturnType>; + +type SourceScope = Map + +export const scope = ( + log: Logger, + root: TactSource, +) => { + const rec = (source: TactSource): SourceScope => { + const logger = log.source(source.path, source.code, (logger) => logger); + const err = TcErrors(logger); + // map with all the currently available functions in current source + const functions: Map = new Map(); + // for every import of current source + for (const imp of source.imports) { + if (imp.kind !== 'tact') { + continue; + } + // get definitions along with the original source + const s = memoedRec(imp.source); + for (const [name, originalSource] of s) { + const prev = functions.get(name); + // prev.source -- original source of top import + // prev.place.loc -- place to complain (second arg) + // originalSource -- original source of bottom import + // imp.loc -- place to complain (first arg) + if (typeof prev === 'undefined') { + functions.set(name, { + source: originalSource, + place: imp, + }); + } else if (prev.source !== originalSource) { + err.shadowsImported( + name, + source.path, + prev.place.loc, + )(imp.loc); + } + } + } + for (const item of source.items) { + if (item.kind === 'function') { + const { text, loc } = item.name; + const prev = functions.get(text); + if (typeof prev === 'undefined') { + functions.set(text, { + source, + place: item.name, + }); + } else { + err.shadowsImported( + text, + source.path, + prev.place.loc, + )(loc); + } + } + } + return mapValues(functions, ({ source }) => source); + }; + const memoedRec = memo(rec); + memoedRec(root); +}; + +// const addId = (set: Set, id: Ast.Id | Ast.TypeId, err: (loc: Range) => void) => { +// if (set.has(id.text)) { +// err(id.loc); +// } else { +// set.add(id.text); +// } +// }; + +// type SourceScope = { +// readonly functions: Map; +// readonly constants: Set; +// readonly types: Set; +// readonly traits: Map; +// readonly contracts: Map; +// } + +// const mergeSourceScope = (scopes: SourceScope[]): SourceScope => { +// const functions: Set = new Set(); +// const constants: Set = new Set(); +// const types: Set = new Set(); +// const traits: Map = new Map(); +// const contracts: Map = new Map(); +// for (const scope of scopes) { +// for (const fn of scope.functions) { +// addId(functions, fn, () => {}); +// } +// } +// return { +// functions, +// constants, +// types, +// traits, +// contracts, +// }; +// }; + +// type LocalScope = { +// readonly constants: Set; +// readonly fields: Set; +// readonly methods: Set; +// } + +// const scopeAll = (root: TactSource) => { +// const rec = (source: TactSource) => { +// const scope = scopeSource(source); +// const scopes: SourceScope[] = []; +// for (const imp of source.imports) { +// if (imp.kind === 'tact') { +// scopes.push(rec(imp.source)); +// } +// } +// return mergeSourceScope([scope, ]); +// }; +// rec(root); +// }; + +// const scopeSource = (source: TactSource): SourceScope => { +// const functions: Set = new Set(); +// const constants: Set = new Set(); +// const types: Set = new Set(); +// const traits: Map = new Map(); +// const contracts: Map = new Map(); + +// for (const item of source.items) { +// switch (item.kind) { +// case "function": +// addId(functions, item.name, () => {}); +// continue; +// case "extension": +// // ???? +// continue; +// case "constant": +// addId(constants, item.name, () => {}); +// continue; +// case "struct_decl": +// case "message_decl": +// case "union_decl": +// case "alias_decl": +// addId(types, item.name, () => {}); +// continue; +// case "trait": { +// if (traits.has(item.name.text)) { +// // duplicate +// } else { +// traits.set(item.name.text, scopeLocal(item.declarations)); +// } +// continue; +// } +// case "contract": { +// if (contracts.has(item.name.text)) { +// // duplicate +// } else { +// contracts.set(item.name.text, scopeLocal(item.declarations)); +// } +// continue; +// } +// } +// } + +// return { +// functions, +// constants, +// types, +// traits, +// contracts, +// }; +// }; + +// export const scopeLocal = (declarations: readonly Ast.LocalItem[]): LocalScope => { +// const constants: Set = new Set(); +// const fields: Set = new Set(); +// const methods: Set = new Set(); +// for (const decl of declarations) { +// switch (decl.kind) { +// case "field_decl": { +// addId(fields, decl.name, () => {}); +// continue; +// } +// case "method": { +// addId(methods, decl.fun.name, () => {}); +// continue; +// } +// case "receiver": { +// // ??? +// continue; +// } +// case "field_const": { +// addId(constants, decl.body.name, () => {}); +// continue; +// } +// } +// } +// return { +// constants, +// fields, +// methods, +// }; +// }; + +// export const typecheck = (log: Logger, source: TactSource) => { +// const logger = log.source(source.path, source.code, (logger) => logger); +// const err = TcErrors(logger); + +// // get list of all imported tact sources +// const sources: Set = new Set(); +// for (const imp of source.imports) { +// if (imp.kind === "tact") { +// sources.add(imp.source); +// } +// } + +// // combine all items from current source and imported sources +// const importedItems = [...sources].flatMap((source) => source.items); + +// // check imported function shadowing +// const importedFunctionNames: Set = new Set(); +// for (const item of importedItems) { +// if (item.kind === "function") { +// const name = item.name.text; +// if (importedFunctionNames.has(name)) { +// err.functionShadowsImported()(item.name.loc); +// } else { +// importedFunctionNames.add(name); +// } +// } +// } + +// for (const item of source.items) { +// switch (item.kind) { +// case "function": { +// const { +// body, +// name, +// params, +// returnType, +// typeParams +// } = item; +// } +// case "extension": +// case "constant_def": +// case "struct_decl": +// case "message_decl": +// case "union_decl": +// case "alias_decl": +// case "contract": +// case "trait": +// } +// } + +// // Duplicate function definition +// // (imports* AsmFunctionDef name) . size > 1 + +// // Duplicate parameter +// // asm fun f(x: Int, x: Foo) {} +// // (Source AsmFunctionDef params name) . size > 1 + +// // Type is not defined +// // asm fun f(x: Nonexist) {} +// // AsmFunctionDef (params type | retType) Type/TypeCons: +// // .name !in (imports* TypeDecl name | .typeParams) + +// // `F` expects 1 argument. Passed 2 arguments. +// // struct F {} asm fun f(x: F) {} +// // AsmFunctionDef (params type | retType) Type/TypeCons typeArgs length +// // != imports* TypeDecl typeParams length + +// // `F` type parameter is shadowing globally defined type +// // struct F {} asm fun f(x: F) {} +// // AsmFunctionDef typeParams name +// // in imports* TypeDecl name + +// // TypeDecl = StructDecl | MessageDecl | UnionDecl | AliasDecl | Contract | Trait + +// // Duplicate type parameter +// // (Source AsmFunctionDef typeParams name) . size > 1 + +// // Shuffle must be a permutation of all function parameters +// // asm(c c) extends fun f(self: Builder, c: Cell?) {} +// // AsmFunctionDef: (.shuffle args text).sort() = (.params name text).sort() + +// // extends fun попадают в скоуп self +// // trait A { abstract fun f(): Int; } +// // contract B {} +// // override extends asm fun f(self: B): Int {} +// }; diff --git a/src/utils/array.ts b/src/utils/array.ts index 5ab0ead8c8..f8d440d967 100644 --- a/src/utils/array.ts +++ b/src/utils/array.ts @@ -1,3 +1,11 @@ +export const mapValues = (map: Map, f: (a: A) => B): Map => { + const result: [K, B][] = []; + for (const [k, a] of map) { + result.push([k, f(a)]); + } + return new Map(result); +}; + export const zip = (arr1: T[], arr2: U[]): [T, U][] => { const length = Math.min(arr1.length, arr2.length); return arr1.slice(0, length).flatMap((item1, index) => { diff --git a/src/utils/tricks.ts b/src/utils/tricks.ts index f50e6903b5..2a5663ee67 100644 --- a/src/utils/tricks.ts +++ b/src/utils/tricks.ts @@ -148,3 +148,16 @@ export const entries = Object.entries as ( ) => { [K in keyof O]: [K, O[K]] }[keyof O][]; export const keys = Object.keys as (o: O) => (keyof O)[]; + +export const memo = (f: (a: A) => B) => { + const cache: Map = new Map(); + return (a: A): B => { + const mem = cache.get(a); + if (typeof mem !== 'undefined') { + return mem; + } + const b = f(a); + cache.set(a, b); + return b; + }; +}; From f297ec4d7b84740cadabe6be837fb5c256397f22 Mon Sep 17 00:00:00 2001 From: verytactical <186486509+verytactical@users.noreply.github.com> Date: Thu, 1 May 2025 17:48:52 +0400 Subject: [PATCH 16/38] scoping --- result.js | 165818 ++++++++++++++++++++++++++++++ src/next/ast/generated/root.ts | 5 +- src/next/ast/root.ts | 9 +- src/next/index.ts | 4 +- src/next/scoping/tc2.ts | 411 +- 5 files changed, 165939 insertions(+), 308 deletions(-) create mode 100644 result.js diff --git a/result.js b/result.js new file mode 100644 index 0000000000..9f97d7b68e --- /dev/null +++ b/result.js @@ -0,0 +1,165818 @@ +Error: ./src/next/example/scope1-a.tact:2:1 - Declaration of "f" shadows previous declaration "f" + 1 | import "./scope1-b"; +> 2 | import "./scope1-c"; + ^~~~~~~~~~~~~~~~~~~~ + 3 | +{ + functions: Map(81) { + 'beginCell' => { + kind: 'tact', + path: 'std/internal/cells.tact', + code: '//\n' + + '// Builder\n' + + '//\n' + + '\n' + + '/// Creates a new empty `Builder`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#begincell\n' + + '///\n' + + 'asm fun beginCell(): Builder { NEWC }\n' + + '\n' + + '/// Extension function for the `Builder` type.\n' + + '///\n' + + '/// Stores a signed `bits`-bit `value` into the copy of the `Builder` for 0 ≤ `bits` ≤ 257.\n' + + '/// Returns that copy of the `Builder`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b.storeInt(42, 7);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to provide an insufficient or out-of-bounds `bits` number.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#builderstoreint\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + '@name(store_int) // special treatment in Func compiler, so not replaced with asm "STIX"\n' + + 'extends native storeInt(self: Builder, value: Int, bits: Int): Builder;\n' + + '\n' + + '/// Extension function for the `Builder` type.\n' + + '///\n' + + '/// Stores an unsigned `bits`-bit `value` into the copy of the `Builder` for 0 ≤ `bits` ≤ 256.\n' + + '/// Returns that copy of the `Builder`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b.storeUint(42, 6);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to store a negative `value` or provide an insufficient or out-of-bounds `bits` number.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#builderstoreuint\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + '@name(store_uint) // special treatment in Func compiler, so not replaced with asm "STUX"\n' + + 'extends native storeUint(self: Builder, value: Int, bits: Int): Builder;\n' + + '\n' + + '/// Extension function for the `Builder` type.\n' + + '///\n' + + '/// Stores a `Bool` `value` into the copy of the `Builder`.\n' + + '/// Writes 1 as a single bit if `value` is `true`, and writes 0 otherwise.\n' + + '/// Returns that copy of the `Builder`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b.storeBool(true); // writes 1\n' + + '/// let buzz: Builder = b.storeBool(false); // writes 0\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#builderstorebool\n' + + '///\n' + + 'asm(value self) extends fun storeBool(self: Builder, value: Bool): Builder { 1 STI }\n' + + '\n' + + '/// Extension function for the `Builder` type. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Alias to `Builder.storeBool()`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b.storeBit(true); // writes 1\n' + + '/// let buzz: Builder = b.storeBit(false); // writes 0\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#builderstorebit\n' + + '///\n' + + 'asm(value self) extends fun storeBit(self: Builder, value: Bool): Builder { 1 STI }\n' + + '\n' + + '/// Extension function for the `Builder` type.\n' + + '///\n' + + '/// Stores (serializes) an unsigned `Int` `value` in the range from 0 to 2^120 − 1 inclusive into the copy of the `Builder`. The serialization of `value` consists of a 4-bit unsigned big-endian integer `l`, which is the smallest integer `l` ≥ 0, such that `value` < 2^(8 * `l`), followed by an 8 * `l`-bit unsigned big-endian representation of `value`. Returns that copy of the `Builder`.\n' + + '///\n' + + '/// This is the most common way of storing nanoToncoins.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b.storeCoins(42);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to store an out-of-bounds `value`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#builderstorecoins\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm extends fun storeCoins(self: Builder, value: Int): Builder { STVARUINT16 }\n' + + '\n' + + '/// Extension function for the `Builder` type. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Alias to `Builder.storeCoins()`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b.storeVarUint16(42);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#builderstorevaruint16\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#builderstorecoins\n' + + '///\n' + + 'asm extends fun storeVarUint16(self: Builder, value: Int): Builder { STVARUINT16 }\n' + + '\n' + + '/// Extension function for the `Builder` type. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Similar to `Builder.storeCoins()`, but with a different `value` range: from -2^119 to 2^119 - 1 inclusive.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b.storeVarInt16(-42);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to store an out-of-bounds `value`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#builderstorevarint16\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm extends fun storeVarInt16(self: Builder, value: Int): Builder { STVARINT16 }\n' + + '\n' + + '/// Extension function for the `Builder` type. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Stores (serializes) an unsigned `Int` `value` in the range from 0 to 2^248 − 1 inclusive into the copy of the `Builder`. The serialization of `value` consists of a 5-bit unsigned big-endian integer `l`, which is the smallest integer `l` ≥ 0, such that `value` < 2^8 * `l`, followed by an 8 * `l`-bit unsigned big-endian representation of `value`. Returns that copy of the `Builder`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b.storeVarUint32(420000);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to store an out-of-bounds `value`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#builderstorevaruint32\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm extends fun storeVarUint32(self: Builder, value: Int): Builder { STVARUINT32 }\n' + + '\n' + + '/// Extension function for the `Builder` type. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Similar to `Builder.storeVarUint32()`, but with a different `value` range: from -2^247 to 2^247 - 1 inclusive.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b.storeVarInt32(-420000);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to store an out-of-bounds `value`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#builderstorevarint32\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm extends fun storeVarInt32(self: Builder, value: Int): Builder { STVARINT32 }\n' + + '\n' + + '/// Extension function for the `Builder` type.\n' + + '///\n' + + '/// Stores a reference `cell` into a copy of the `Builder`.\n' + + '/// Returns that copy of the `Builder`.\n' + + '///\n' + + '/// Note that a single `Cell` can contain up to 4 references.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b.storeRef(emptyCell());\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 8: [Cell overflow] — Thrown when attempting to store more than 4 references in a single `Cell`.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#builderstoreref\n' + + '///\n' + + '/// [Cell overflow]: https://docs.tact-lang.org/book/exit-codes#8\n' + + '///\n' + + 'asm(cell self) extends fun storeRef(self: Builder, cell: Cell): Builder { STREF }\n' + + '\n' + + '/// Extension function for the `Builder` type.\n' + + '///\n' + + '/// Stores a `slice` into a copy of the `Builder`.\n' + + '/// Returns that copy of the `Builder`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let s: Slice = emptyCell().asSlice();\n' + + '/// let fizz: Builder = b.storeSlice(s);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#builderstoreslice\n' + + '///\n' + + 'asm extends fun storeSlice(self: Builder, slice: Slice): Builder { STSLICER }\n' + + '\n' + + '/// Extension function for the `Builder` type. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Appends all data from the `other` builder to the copy of the `self` builder. Returns that copy.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example(op: Int, queryId: Int, payload: Builder) {\n' + + '/// let msgBody = beginCell().storeUint(op, 32).storeUint(queryId, 64);\n' + + '/// if (payload.bits() != 0) {\n' + + '/// msgBody = msgBody.storeBuilder(payload); // assignment is important here\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#builderstorebuilder\n' + + '///\n' + + 'asm extends fun storeBuilder(self: Builder, other: Builder): Builder { STBR }\n' + + '\n' + + '/// Extension function for the `Builder` type. Available since Tact 1.5.0.\n' + + '///\n' + + '/// If the `cell` is not `null`, stores 1 as a single bit and then reference `cell` into the copy of the `Builder`. Returns that copy.\n' + + '///\n' + + '/// If the `cell` is `null`, only stores 0 as a single bit into the copy of the `Builder`. Returns that copy.\n' + + '///\n' + + '/// Note that a single `Cell` can contain up to 4 references.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b\n' + + '/// .storeMaybeRef(emptyCell()) // 1, then empty cell\n' + + '/// .storeMaybeRef(null); // 0\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 8: [Cell overflow] — Thrown when attempting to store more than 4 references in a single `Cell`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#builderstoremayberef\n' + + '///\n' + + '/// [Cell overflow]: https://docs.tact-lang.org/book/exit-codes#8\n' + + '///\n' + + 'asm(cell self) extends fun storeMaybeRef(self: Builder, cell: Cell?): Builder { STOPTREF }\n' + + '\n' + + '/// Extension function for the `Builder` type.\n' + + '///\n' + + '/// Converts a `Builder` into an ordinary `Cell`.\n' + + '///\n' + + '/// NOTE: **Gas expensive!** This function uses 500 gas units or more.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let c: Cell = b.endCell();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/'... 40707 more characters, + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'beginCell', + loc: { start: 218, end: 227 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 231, end: 238 } }, + loc: { start: 231, end: 238 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'NEWC' ] + }, + loc: { start: 210, end: 247 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeInt', + loc: { start: 984, end: 992 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 1032, end: 1039 } }, + loc: { start: 1032, end: 1039 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'value', + loc: { start: 1008, end: 1013 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1015, end: 1018 } + }, + loc: { start: 1015, end: 1018 } + }, + loc: { start: 1008, end: 1018 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 1020, end: 1024 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1026, end: 1029 } + }, + loc: { start: 1026, end: 1029 } + }, + loc: { start: 1020, end: 1029 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'store_int', + loc: { start: 887, end: 896 } + } + }, + loc: { start: 881, end: 1040 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 999, end: 1006 } }, + loc: { start: 999, end: 1006 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeUint', + loc: { start: 1817, end: 1826 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 1866, end: 1873 } }, + loc: { start: 1866, end: 1873 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'value', + loc: { start: 1842, end: 1847 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1849, end: 1852 } + }, + loc: { start: 1849, end: 1852 } + }, + loc: { start: 1842, end: 1852 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 1854, end: 1858 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1860, end: 1863 } + }, + loc: { start: 1860, end: 1863 } + }, + loc: { start: 1854, end: 1863 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'store_uint', + loc: { start: 1719, end: 1729 } + } + }, + loc: { start: 1713, end: 1874 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 1833, end: 1840 } }, + loc: { start: 1833, end: 1840 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeBool', + loc: { start: 2420, end: 2429 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 2459, end: 2466 } }, + loc: { start: 2459, end: 2466 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'value', + loc: { start: 2445, end: 2450 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 2452, end: 2456 } + }, + typeArgs: [], + loc: { start: 2452, end: 2456 } + }, + loc: { start: 2445, end: 2456 } + } + ], + body: { + kind: 'asm_body', + shuffle: { + args: [ + { + kind: 'id', + text: 'value', + loc: { start: 2396, end: 2401 } + }, + { + kind: 'id', + text: 'self', + loc: { start: 2402, end: 2406 } + } + ], + ret: [] + }, + instructions: [ '1 STI' ] + }, + loc: { start: 2392, end: 2476 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 2436, end: 2443 } }, + loc: { start: 2436, end: 2443 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeBit', + loc: { start: 2902, end: 2910 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 2940, end: 2947 } }, + loc: { start: 2940, end: 2947 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'value', + loc: { start: 2926, end: 2931 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 2933, end: 2937 } + }, + typeArgs: [], + loc: { start: 2933, end: 2937 } + }, + loc: { start: 2926, end: 2937 } + } + ], + body: { + kind: 'asm_body', + shuffle: { + args: [ + { + kind: 'id', + text: 'value', + loc: { start: 2878, end: 2883 } + }, + { + kind: 'id', + text: 'self', + loc: { start: 2884, end: 2888 } + } + ], + ret: [] + }, + instructions: [ '1 STI' ] + }, + loc: { start: 2874, end: 2957 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 2917, end: 2924 } }, + loc: { start: 2917, end: 2924 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeCoins', + loc: { start: 3902, end: 3912 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 3941, end: 3948 } }, + loc: { start: 3941, end: 3948 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'value', + loc: { start: 3928, end: 3933 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3935, end: 3938 } + }, + loc: { start: 3935, end: 3938 } + }, + loc: { start: 3928, end: 3938 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'STVARUINT16' ] + }, + loc: { start: 3886, end: 3964 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 3919, end: 3926 } }, + loc: { start: 3919, end: 3926 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeVarUint16', + loc: { start: 4389, end: 4403 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 4432, end: 4439 } }, + loc: { start: 4432, end: 4439 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'value', + loc: { start: 4419, end: 4424 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4426, end: 4429 } + }, + loc: { start: 4426, end: 4429 } + }, + loc: { start: 4419, end: 4429 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'STVARUINT16' ] + }, + loc: { start: 4373, end: 4455 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 4410, end: 4417 } }, + loc: { start: 4410, end: 4417 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeVarInt16', + loc: { start: 5096, end: 5109 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 5138, end: 5145 } }, + loc: { start: 5138, end: 5145 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'value', + loc: { start: 5125, end: 5130 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5132, end: 5135 } + }, + loc: { start: 5132, end: 5135 } + }, + loc: { start: 5125, end: 5135 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'STVARINT16' ] + }, + loc: { start: 5080, end: 5160 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 5116, end: 5123 } }, + loc: { start: 5116, end: 5123 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeVarUint32', + loc: { start: 6082, end: 6096 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 6125, end: 6132 } }, + loc: { start: 6125, end: 6132 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'value', + loc: { start: 6112, end: 6117 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6119, end: 6122 } + }, + loc: { start: 6119, end: 6122 } + }, + loc: { start: 6112, end: 6122 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'STVARUINT32' ] + }, + loc: { start: 6066, end: 6148 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 6103, end: 6110 } }, + loc: { start: 6103, end: 6110 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeVarInt32', + loc: { start: 6797, end: 6810 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 6839, end: 6846 } }, + loc: { start: 6839, end: 6846 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'value', + loc: { start: 6826, end: 6831 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6833, end: 6836 } + }, + loc: { start: 6833, end: 6836 } + }, + loc: { start: 6826, end: 6836 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'STVARINT32' ] + }, + loc: { start: 6781, end: 6861 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 6817, end: 6824 } }, + loc: { start: 6817, end: 6824 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeRef', + loc: { start: 7529, end: 7537 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 7566, end: 7573 } }, + loc: { start: 7566, end: 7573 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cell', + loc: { start: 7553, end: 7557 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 7559, end: 7563 } + }, + loc: { start: 7559, end: 7563 } + }, + loc: { start: 7553, end: 7563 } + } + ], + body: { + kind: 'asm_body', + shuffle: { + args: [ + { + kind: 'id', + text: 'cell', + loc: { start: 7506, end: 7510 } + }, + { + kind: 'id', + text: 'self', + loc: { start: 7511, end: 7515 } + } + ], + ret: [] + }, + instructions: [ 'STREF' ] + }, + loc: { start: 7502, end: 7583 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 7544, end: 7551 } }, + loc: { start: 7544, end: 7551 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeSlice', + loc: { start: 8005, end: 8015 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 8046, end: 8053 } }, + loc: { start: 8046, end: 8053 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'slice', + loc: { start: 8031, end: 8036 } + }, + type: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 8038, end: 8043 } + }, + loc: { start: 8038, end: 8043 } + }, + loc: { start: 8031, end: 8043 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'STSLICER' ] + }, + loc: { start: 7989, end: 8066 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 8022, end: 8029 } }, + loc: { start: 8022, end: 8029 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeBuilder', + loc: { start: 8633, end: 8645 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 8678, end: 8685 } }, + loc: { start: 8678, end: 8685 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'other', + loc: { start: 8661, end: 8666 } + }, + type: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 8668, end: 8675 } + }, + loc: { start: 8668, end: 8675 } + }, + loc: { start: 8661, end: 8675 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'STBR' ] + }, + loc: { start: 8617, end: 8694 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 8652, end: 8659 } }, + loc: { start: 8652, end: 8659 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeMaybeRef', + loc: { start: 9622, end: 9635 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 9665, end: 9672 } }, + loc: { start: 9665, end: 9672 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cell', + loc: { start: 9651, end: 9655 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 9661, end: 9662 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 9657, end: 9661 } + }, + loc: { start: 9657, end: 9661 } + } + ], + loc: { start: 9661, end: 9662 } + }, + loc: { start: 9651, end: 9662 } + } + ], + body: { + kind: 'asm_body', + shuffle: { + args: [ + { + kind: 'id', + text: 'cell', + loc: { start: 9599, end: 9603 } + }, + { + kind: 'id', + text: 'self', + loc: { start: 9604, end: 9608 } + } + ], + ret: [] + }, + instructions: [ 'STOPTREF' ] + }, + loc: { start: 9595, end: 9685 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 9642, end: 9649 } }, + loc: { start: 9642, end: 9649 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'endCell', + loc: { start: 10082, end: 10089 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 10106, end: 10110 } + }, + loc: { start: 10106, end: 10110 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ENDC' ] + }, + loc: { start: 10066, end: 10119 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 10096, end: 10103 } }, + loc: { start: 10096, end: 10103 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'refs', + loc: { start: 10479, end: 10483 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10500, end: 10503 } + }, + loc: { start: 10500, end: 10503 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'BREFS' ] + }, + loc: { start: 10463, end: 10513 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 10490, end: 10497 } }, + loc: { start: 10490, end: 10497 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'bits', + loc: { start: 10867, end: 10871 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10888, end: 10891 } + }, + loc: { start: 10888, end: 10891 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'BBITS' ] + }, + loc: { start: 10851, end: 10901 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 10878, end: 10885 } }, + loc: { start: 10878, end: 10885 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'depth', + loc: { start: 11403, end: 11408 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11425, end: 11428 } + }, + loc: { start: 11425, end: 11428 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'BDEPTH' ] + }, + loc: { start: 11387, end: 11439 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 11415, end: 11422 } }, + loc: { start: 11415, end: 11422 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'beginParse', + loc: { start: 11787, end: 11797 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 11811, end: 11816 } + }, + loc: { start: 11811, end: 11816 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'CTOS' ] + }, + loc: { start: 11771, end: 11825 } + } + }, + selfType: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 11804, end: 11808 } }, + loc: { start: 11804, end: 11808 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadRef', + loc: { start: 12822, end: 12829 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 12844, end: 12848 } + }, + loc: { start: 12844, end: 12848 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { + args: [], + ret: [ + { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 12797, end: 12798 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 12799, end: 12800 } + } + ] + }, + instructions: [ 'LDREF' ] + }, + loc: { start: 12790, end: 12858 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 12836, end: 12841 } }, + loc: { start: 12836, end: 12841 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'skipRef', + loc: { start: 13772, end: 13779 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LDREF NIP' ] + }, + loc: { start: 13748, end: 13806 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 13786, end: 13791 } }, + loc: { start: 13786, end: 13791 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'preloadRef', + loc: { start: 14937, end: 14947 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 14962, end: 14966 } + }, + loc: { start: 14962, end: 14966 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'PLDREF' ] + }, + loc: { start: 14921, end: 14977 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 14954, end: 14959 } }, + loc: { start: 14954, end: 14959 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadMaybeRef', + loc: { start: 16024, end: 16036 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 16055, end: 16056 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 16051, end: 16055 } + }, + loc: { start: 16051, end: 16055 } + } + ], + loc: { start: 16055, end: 16056 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { + args: [], + ret: [ + { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15999, end: 16000 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 16001, end: 16002 } + } + ] + }, + instructions: [ 'LDOPTREF' ] + }, + loc: { start: 15992, end: 16069 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 16043, end: 16048 } }, + loc: { start: 16043, end: 16048 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'skipMaybeRef', + loc: { start: 17041, end: 17053 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LDOPTREF NIP' ] + }, + loc: { start: 17017, end: 17083 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 17060, end: 17065 } }, + loc: { start: 17060, end: 17065 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'preloadMaybeRef', + loc: { start: 18449, end: 18464 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 18483, end: 18484 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 18479, end: 18483 } + }, + loc: { start: 18479, end: 18483 } + } + ], + loc: { start: 18483, end: 18484 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'PLDOPTREF' ] + }, + loc: { start: 18433, end: 18498 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 18471, end: 18476 } }, + loc: { start: 18471, end: 18476 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadBits', + loc: { start: 19377, end: 19385 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 19408, end: 19413 } + }, + loc: { start: 19408, end: 19413 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'l', + loc: { start: 19399, end: 19400 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 19402, end: 19405 } + }, + loc: { start: 19402, end: 19405 } + }, + loc: { start: 19399, end: 19405 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'load_bits', + loc: { start: 19268, end: 19277 } + } + }, + loc: { start: 19262, end: 19414 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 19392, end: 19397 } }, + loc: { start: 19392, end: 19397 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'preloadBits', + loc: { start: 20333, end: 20344 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 20367, end: 20372 } + }, + loc: { start: 20367, end: 20372 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'l', + loc: { start: 20358, end: 20359 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 20361, end: 20364 } + }, + loc: { start: 20361, end: 20364 } + }, + loc: { start: 20358, end: 20364 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'preload_bits', + loc: { start: 20228, end: 20240 } + } + }, + loc: { start: 20222, end: 20373 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 20351, end: 20356 } }, + loc: { start: 20351, end: 20356 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadInt', + loc: { start: 21236, end: 21243 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 21266, end: 21269 } + }, + loc: { start: 21266, end: 21269 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'l', + loc: { start: 21257, end: 21258 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 21260, end: 21263 } + }, + loc: { start: 21260, end: 21263 } + }, + loc: { start: 21257, end: 21263 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'load_int', + loc: { start: 21132, end: 21140 } + } + }, + loc: { start: 21126, end: 21270 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 21250, end: 21255 } }, + loc: { start: 21250, end: 21255 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'preloadInt', + loc: { start: 22164, end: 22174 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 22197, end: 22200 } + }, + loc: { start: 22197, end: 22200 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'l', + loc: { start: 22188, end: 22189 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 22191, end: 22194 } + }, + loc: { start: 22191, end: 22194 } + }, + loc: { start: 22188, end: 22194 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'preload_int', + loc: { start: 22064, end: 22075 } + } + }, + loc: { start: 22058, end: 22201 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 22181, end: 22186 } }, + loc: { start: 22181, end: 22186 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadUint', + loc: { start: 23071, end: 23079 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 23102, end: 23105 } + }, + loc: { start: 23102, end: 23105 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'l', + loc: { start: 23093, end: 23094 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 23096, end: 23099 } + }, + loc: { start: 23096, end: 23099 } + }, + loc: { start: 23093, end: 23099 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'load_uint', + loc: { start: 22966, end: 22975 } + } + }, + loc: { start: 22960, end: 23106 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 23086, end: 23091 } }, + loc: { start: 23086, end: 23091 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'preloadUint', + loc: { start: 24007, end: 24018 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 24041, end: 24044 } + }, + loc: { start: 24041, end: 24044 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'l', + loc: { start: 24032, end: 24033 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 24035, end: 24038 } + }, + loc: { start: 24035, end: 24038 } + }, + loc: { start: 24032, end: 24038 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'preload_uint', + loc: { start: 23906, end: 23918 } + } + }, + loc: { start: 23900, end: 24045 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 24025, end: 24030 } }, + loc: { start: 24025, end: 24030 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadBool', + loc: { start: 24834, end: 24842 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 24857, end: 24861 } + }, + typeArgs: [], + loc: { start: 24857, end: 24861 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { + args: [], + ret: [ + { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 24809, end: 24810 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 24811, end: 24812 } + } + ] + }, + instructions: [ '1 LDI' ] + }, + loc: { start: 24802, end: 24871 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 24849, end: 24854 } }, + loc: { start: 24849, end: 24854 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'skipBool', + loc: { start: 25769, end: 25777 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ '1 LDI NIP' ] + }, + loc: { start: 25745, end: 25804 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 25784, end: 25789 } }, + loc: { start: 25784, end: 25789 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadBit', + loc: { start: 26558, end: 26565 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 26580, end: 26584 } + }, + typeArgs: [], + loc: { start: 26580, end: 26584 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { + args: [], + ret: [ + { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 26533, end: 26534 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 26535, end: 26536 } + } + ] + }, + instructions: [ '1 LDI' ] + }, + loc: { start: 26526, end: 26594 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 26572, end: 26577 } }, + loc: { start: 26572, end: 26577 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadCoins', + loc: { start: 27454, end: 27463 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 27478, end: 27481 } + }, + loc: { start: 27478, end: 27481 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { + args: [], + ret: [ + { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 27429, end: 27430 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 27431, end: 27432 } + } + ] + }, + instructions: [ 'LDVARUINT16' ] + }, + loc: { start: 27422, end: 27497 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 27470, end: 27475 } }, + loc: { start: 27470, end: 27475 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'skipCoins', + loc: { start: 28454, end: 28463 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LDVARUINT16 NIP' ] + }, + loc: { start: 28430, end: 28496 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 28470, end: 28475 } }, + loc: { start: 28470, end: 28475 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadVarUint16', + loc: { start: 29318, end: 29331 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 29346, end: 29349 } + }, + loc: { start: 29346, end: 29349 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { + args: [], + ret: [ + { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 29293, end: 29294 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 29295, end: 29296 } + } + ] + }, + instructions: [ 'LDVARUINT16' ] + }, + loc: { start: 29286, end: 29365 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 29338, end: 29343 } }, + loc: { start: 29338, end: 29343 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'skipVarUint16', + loc: { start: 30263, end: 30276 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LDVARUINT16 NIP' ] + }, + loc: { start: 30239, end: 30309 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 30283, end: 30288 } }, + loc: { start: 30283, end: 30288 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadVarInt16', + loc: { start: 31141, end: 31153 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 31168, end: 31171 } + }, + loc: { start: 31168, end: 31171 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { + args: [], + ret: [ + { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 31116, end: 31117 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 31118, end: 31119 } + } + ] + }, + instructions: [ 'LDVARINT16' ] + }, + loc: { start: 31109, end: 31186 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 31160, end: 31165 } }, + loc: { start: 31160, end: 31165 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'skipVarInt16', + loc: { start: 32093, end: 32105 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LDVARINT16 NIP' ] + }, + loc: { start: 32069, end: 32137 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 32112, end: 32117 } }, + loc: { start: 32112, end: 32117 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadVarUint32', + loc: { start: 32987, end: 33000 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 33015, end: 33018 } + }, + loc: { start: 33015, end: 33018 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { + args: [], + ret: [ + { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 32962, end: 32963 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 32964, end: 32965 } + } + ] + }, + instructions: [ 'LDVARUINT32' ] + }, + loc: { start: 32955, end: 33034 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 33007, end: 33012 } }, + loc: { start: 33007, end: 33012 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'skipVarUint32', + loc: { start: 34007, end: 34020 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LDVARUINT32 NIP' ] + }, + loc: { start: 33983, end: 34053 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 34027, end: 34032 } }, + loc: { start: 34027, end: 34032 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadVarInt32', + loc: { start: 34897, end: 34909 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 34924, end: 34927 } + }, + loc: { start: 34924, end: 34927 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { + args: [], + ret: [ + { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 34872, end: 34873 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 34874, end: 34875 } + } + ] + }, + instructions: [ 'LDVARINT32' ] + }, + loc: { start: 34865, end: 34942 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 34916, end: 34921 } }, + loc: { start: 34916, end: 34921 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'skipVarInt32', + loc: { start: 35854, end: 35866 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LDVARINT32 NIP' ] + }, + loc: { start: 35830, end: 35898 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 35873, end: 35878 } }, + loc: { start: 35873, end: 35878 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'skipBits', + loc: { start: 36746, end: 36754 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'l', + loc: { start: 36768, end: 36769 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 36771, end: 36774 } + }, + loc: { start: 36771, end: 36774 } + }, + loc: { start: 36768, end: 36774 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SDSKIPFIRST' ] + }, + loc: { start: 36722, end: 36791 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 36761, end: 36766 } }, + loc: { start: 36761, end: 36766 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'endParse', + loc: { start: 37397, end: 37405 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ENDS' ] + }, + loc: { start: 37381, end: 37427 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 37412, end: 37417 } }, + loc: { start: 37412, end: 37417 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'skipLastBits', + loc: { start: 38319, end: 38331 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 38356, end: 38361 } + }, + loc: { start: 38356, end: 38361 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'len', + loc: { start: 38345, end: 38348 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 38350, end: 38353 } + }, + loc: { start: 38350, end: 38353 } + }, + loc: { start: 38345, end: 38353 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SDSKIPLAST' ] + }, + loc: { start: 38303, end: 38376 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 38338, end: 38343 } }, + loc: { start: 38338, end: 38343 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'firstBits', + loc: { start: 39373, end: 39382 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 39407, end: 39412 } + }, + loc: { start: 39407, end: 39412 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'len', + loc: { start: 39396, end: 39399 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 39401, end: 39404 } + }, + loc: { start: 39401, end: 39404 } + }, + loc: { start: 39396, end: 39404 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SDCUTFIRST' ] + }, + loc: { start: 39357, end: 39427 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 39389, end: 39394 } }, + loc: { start: 39389, end: 39394 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'lastBits', + loc: { start: 40218, end: 40226 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 40251, end: 40256 } + }, + loc: { start: 40251, end: 40256 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'len', + loc: { start: 40240, end: 40243 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 40245, end: 40248 } + }, + loc: { start: 40245, end: 40248 } + }, + loc: { start: 40240, end: 40248 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SDCUTLAST' ] + }, + loc: { start: 40202, end: 40270 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 40233, end: 40238 } }, + loc: { start: 40233, end: 40238 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'depth', + loc: { start: 40758, end: 40763 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 40778, end: 40781 } + }, + loc: { start: 40778, end: 40781 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SDEPTH' ] + }, + loc: { start: 40742, end: 40792 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 40770, end: 40775 } }, + loc: { start: 40770, end: 40775 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'refs', + loc: { start: 41166, end: 41170 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 41185, end: 41188 } + }, + loc: { start: 41185, end: 41188 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SREFS' ] + }, + loc: { start: 41150, end: 41198 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 41177, end: 41182 } }, + loc: { start: 41177, end: 41182 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'bits', + loc: { start: 41550, end: 41554 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 41569, end: 41572 } + }, + loc: { start: 41569, end: 41572 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SBITS' ] + }, + loc: { start: 41534, end: 41582 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 41561, end: 41566 } }, + loc: { start: 41561, end: 41566 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'empty', + loc: { start: 42117, end: 42122 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 42137, end: 42141 } + }, + typeArgs: [], + loc: { start: 42137, end: 42141 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SEMPTY' ] + }, + loc: { start: 42101, end: 42152 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 42129, end: 42134 } }, + loc: { start: 42129, end: 42134 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'dataEmpty', + loc: { start: 42682, end: 42691 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 42706, end: 42710 } + }, + typeArgs: [], + loc: { start: 42706, end: 42710 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SDEMPTY' ] + }, + loc: { start: 42666, end: 42722 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 42698, end: 42703 } }, + loc: { start: 42698, end: 42703 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'refsEmpty', + loc: { start: 43231, end: 43240 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 43255, end: 43259 } + }, + typeArgs: [], + loc: { start: 43255, end: 43259 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SREMPTY' ] + }, + loc: { start: 43215, end: 43271 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 43247, end: 43252 } }, + loc: { start: 43247, end: 43252 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'asSlice', + loc: { start: 43671, end: 43678 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 43695, end: 43700 } + }, + loc: { start: 43695, end: 43700 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 43714, end: 43718 } + }, + method: { + kind: 'id', + text: 'endCell', + loc: { start: 43719, end: 43726 } + }, + typeArgs: [], + args: [], + loc: { start: 43714, end: 43728 } + }, + method: { + kind: 'id', + text: 'beginParse', + loc: { start: 43729, end: 43739 } + }, + typeArgs: [], + args: [], + loc: { start: 43714, end: 43741 } + }, + loc: { start: 43707, end: 43742 } + } + ] + }, + loc: { start: 43652, end: 43744 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 43685, end: 43692 } }, + loc: { start: 43685, end: 43692 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'asSlice', + loc: { start: 44098, end: 44105 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 44119, end: 44124 } + }, + loc: { start: 44119, end: 44124 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 44138, end: 44142 } + }, + method: { + kind: 'id', + text: 'beginParse', + loc: { start: 44143, end: 44153 } + }, + typeArgs: [], + args: [], + loc: { start: 44138, end: 44155 } + }, + loc: { start: 44131, end: 44156 } + } + ] + }, + loc: { start: 44079, end: 44158 } + } + }, + selfType: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 44112, end: 44116 } }, + loc: { start: 44112, end: 44116 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'asCell', + loc: { start: 44714, end: 44720 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 44735, end: 44739 } + }, + loc: { start: 44735, end: 44739 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'static_call', + function: { + kind: 'id', + text: 'beginCell', + loc: { start: 44753, end: 44762 } + }, + typeArgs: [], + args: [], + loc: { start: 44753, end: 44764 } + }, + method: { + kind: 'id', + text: 'storeSlice', + loc: { start: 44774, end: 44784 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'self', + loc: { start: 44785, end: 44789 } + } + ], + loc: { start: 44753, end: 44790 } + }, + method: { + kind: 'id', + text: 'endCell', + loc: { start: 44800, end: 44807 } + }, + typeArgs: [], + args: [], + loc: { start: 44753, end: 44809 } + }, + loc: { start: 44746, end: 44810 } + } + ] + }, + loc: { start: 44695, end: 44812 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 44727, end: 44732 } }, + loc: { start: 44727, end: 44732 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'asCell', + loc: { start: 45173, end: 45179 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 45196, end: 45200 } + }, + loc: { start: 45196, end: 45200 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 45214, end: 45218 } + }, + method: { + kind: 'id', + text: 'endCell', + loc: { start: 45219, end: 45226 } + }, + typeArgs: [], + args: [], + loc: { start: 45214, end: 45228 } + }, + loc: { start: 45207, end: 45229 } + } + ] + }, + loc: { start: 45154, end: 45231 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 45186, end: 45193 } }, + loc: { start: 45186, end: 45193 } + } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'emptyCell', + loc: { start: 45592, end: 45601 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 45605, end: 45609 } }, + loc: { start: 45605, end: 45609 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + ' PUSHREF // Pure Fift: "" turns it into a cell at compile time' + ] + }, + loc: { start: 45584, end: 45711 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'emptySlice', + loc: { start: 46077, end: 46087 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 46091, end: 46096 } }, + loc: { start: 46091, end: 46096 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'b{} PUSHSLICE' ] + }, + loc: { start: 46069, end: 46118 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'DataSize', + loc: { start: 46431, end: 46439 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'cells', + loc: { start: 46516, end: 46521 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 46523, end: 46526 } + }, + loc: { start: 46523, end: 46526 } + }, + initializer: undefined, + loc: { start: 46516, end: 46526 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bits', + loc: { start: 46615, end: 46619 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 46621, end: 46624 } + }, + loc: { start: 46621, end: 46624 } + }, + initializer: undefined, + loc: { start: 46615, end: 46624 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'refs', + loc: { start: 46713, end: 46717 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 46719, end: 46722 } + }, + loc: { start: 46719, end: 46722 } + }, + initializer: undefined, + loc: { start: 46713, end: 46722 } + } + ], + loc: { start: 46424, end: 46725 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'computeDataSize', + loc: { start: 48450, end: 48465 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'DataSize', + loc: { start: 48495, end: 48503 } + }, + typeArgs: [], + loc: { start: 48495, end: 48503 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'maxCells', + loc: { start: 48479, end: 48487 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 48489, end: 48492 } + }, + loc: { start: 48489, end: 48492 } + }, + loc: { start: 48479, end: 48492 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'CDATASIZE' ] + }, + loc: { start: 48434, end: 48517 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 48476, end: 48477 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 48472, end: 48476 } + }, + loc: { start: 48472, end: 48476 } + } + ], + loc: { start: 48476, end: 48477 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'computeDataSize', + loc: { start: 50094, end: 50109 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'DataSize', + loc: { start: 50139, end: 50147 } + }, + typeArgs: [], + loc: { start: 50139, end: 50147 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'maxCells', + loc: { start: 50123, end: 50131 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 50133, end: 50136 } + }, + loc: { start: 50133, end: 50136 } + }, + loc: { start: 50123, end: 50136 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SDATASIZE' ] + }, + loc: { start: 50078, end: 50161 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 50116, end: 50121 } }, + loc: { start: 50116, end: 50121 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'depth', + loc: { start: 50672, end: 50677 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 50692, end: 50695 } + }, + loc: { start: 50692, end: 50695 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'CDEPTH' ] + }, + loc: { start: 50656, end: 50706 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 50688, end: 50689 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 50684, end: 50688 } + }, + loc: { start: 50684, end: 50688 } + } + ], + loc: { start: 50688, end: 50689 } + } + } + ] + }, + 'emptyCell' => { + kind: 'tact', + path: 'std/internal/cells.tact', + code: '//\n' + + '// Builder\n' + + '//\n' + + '\n' + + '/// Creates a new empty `Builder`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#begincell\n' + + '///\n' + + 'asm fun beginCell(): Builder { NEWC }\n' + + '\n' + + '/// Extension function for the `Builder` type.\n' + + '///\n' + + '/// Stores a signed `bits`-bit `value` into the copy of the `Builder` for 0 ≤ `bits` ≤ 257.\n' + + '/// Returns that copy of the `Builder`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b.storeInt(42, 7);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to provide an insufficient or out-of-bounds `bits` number.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#builderstoreint\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + '@name(store_int) // special treatment in Func compiler, so not replaced with asm "STIX"\n' + + 'extends native storeInt(self: Builder, value: Int, bits: Int): Builder;\n' + + '\n' + + '/// Extension function for the `Builder` type.\n' + + '///\n' + + '/// Stores an unsigned `bits`-bit `value` into the copy of the `Builder` for 0 ≤ `bits` ≤ 256.\n' + + '/// Returns that copy of the `Builder`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b.storeUint(42, 6);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to store a negative `value` or provide an insufficient or out-of-bounds `bits` number.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#builderstoreuint\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + '@name(store_uint) // special treatment in Func compiler, so not replaced with asm "STUX"\n' + + 'extends native storeUint(self: Builder, value: Int, bits: Int): Builder;\n' + + '\n' + + '/// Extension function for the `Builder` type.\n' + + '///\n' + + '/// Stores a `Bool` `value` into the copy of the `Builder`.\n' + + '/// Writes 1 as a single bit if `value` is `true`, and writes 0 otherwise.\n' + + '/// Returns that copy of the `Builder`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b.storeBool(true); // writes 1\n' + + '/// let buzz: Builder = b.storeBool(false); // writes 0\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#builderstorebool\n' + + '///\n' + + 'asm(value self) extends fun storeBool(self: Builder, value: Bool): Builder { 1 STI }\n' + + '\n' + + '/// Extension function for the `Builder` type. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Alias to `Builder.storeBool()`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b.storeBit(true); // writes 1\n' + + '/// let buzz: Builder = b.storeBit(false); // writes 0\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#builderstorebit\n' + + '///\n' + + 'asm(value self) extends fun storeBit(self: Builder, value: Bool): Builder { 1 STI }\n' + + '\n' + + '/// Extension function for the `Builder` type.\n' + + '///\n' + + '/// Stores (serializes) an unsigned `Int` `value` in the range from 0 to 2^120 − 1 inclusive into the copy of the `Builder`. The serialization of `value` consists of a 4-bit unsigned big-endian integer `l`, which is the smallest integer `l` ≥ 0, such that `value` < 2^(8 * `l`), followed by an 8 * `l`-bit unsigned big-endian representation of `value`. Returns that copy of the `Builder`.\n' + + '///\n' + + '/// This is the most common way of storing nanoToncoins.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b.storeCoins(42);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to store an out-of-bounds `value`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#builderstorecoins\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm extends fun storeCoins(self: Builder, value: Int): Builder { STVARUINT16 }\n' + + '\n' + + '/// Extension function for the `Builder` type. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Alias to `Builder.storeCoins()`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b.storeVarUint16(42);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#builderstorevaruint16\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#builderstorecoins\n' + + '///\n' + + 'asm extends fun storeVarUint16(self: Builder, value: Int): Builder { STVARUINT16 }\n' + + '\n' + + '/// Extension function for the `Builder` type. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Similar to `Builder.storeCoins()`, but with a different `value` range: from -2^119 to 2^119 - 1 inclusive.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b.storeVarInt16(-42);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to store an out-of-bounds `value`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#builderstorevarint16\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm extends fun storeVarInt16(self: Builder, value: Int): Builder { STVARINT16 }\n' + + '\n' + + '/// Extension function for the `Builder` type. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Stores (serializes) an unsigned `Int` `value` in the range from 0 to 2^248 − 1 inclusive into the copy of the `Builder`. The serialization of `value` consists of a 5-bit unsigned big-endian integer `l`, which is the smallest integer `l` ≥ 0, such that `value` < 2^8 * `l`, followed by an 8 * `l`-bit unsigned big-endian representation of `value`. Returns that copy of the `Builder`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b.storeVarUint32(420000);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to store an out-of-bounds `value`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#builderstorevaruint32\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm extends fun storeVarUint32(self: Builder, value: Int): Builder { STVARUINT32 }\n' + + '\n' + + '/// Extension function for the `Builder` type. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Similar to `Builder.storeVarUint32()`, but with a different `value` range: from -2^247 to 2^247 - 1 inclusive.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b.storeVarInt32(-420000);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to store an out-of-bounds `value`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#builderstorevarint32\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm extends fun storeVarInt32(self: Builder, value: Int): Builder { STVARINT32 }\n' + + '\n' + + '/// Extension function for the `Builder` type.\n' + + '///\n' + + '/// Stores a reference `cell` into a copy of the `Builder`.\n' + + '/// Returns that copy of the `Builder`.\n' + + '///\n' + + '/// Note that a single `Cell` can contain up to 4 references.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b.storeRef(emptyCell());\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 8: [Cell overflow] — Thrown when attempting to store more than 4 references in a single `Cell`.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#builderstoreref\n' + + '///\n' + + '/// [Cell overflow]: https://docs.tact-lang.org/book/exit-codes#8\n' + + '///\n' + + 'asm(cell self) extends fun storeRef(self: Builder, cell: Cell): Builder { STREF }\n' + + '\n' + + '/// Extension function for the `Builder` type.\n' + + '///\n' + + '/// Stores a `slice` into a copy of the `Builder`.\n' + + '/// Returns that copy of the `Builder`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let s: Slice = emptyCell().asSlice();\n' + + '/// let fizz: Builder = b.storeSlice(s);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#builderstoreslice\n' + + '///\n' + + 'asm extends fun storeSlice(self: Builder, slice: Slice): Builder { STSLICER }\n' + + '\n' + + '/// Extension function for the `Builder` type. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Appends all data from the `other` builder to the copy of the `self` builder. Returns that copy.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example(op: Int, queryId: Int, payload: Builder) {\n' + + '/// let msgBody = beginCell().storeUint(op, 32).storeUint(queryId, 64);\n' + + '/// if (payload.bits() != 0) {\n' + + '/// msgBody = msgBody.storeBuilder(payload); // assignment is important here\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#builderstorebuilder\n' + + '///\n' + + 'asm extends fun storeBuilder(self: Builder, other: Builder): Builder { STBR }\n' + + '\n' + + '/// Extension function for the `Builder` type. Available since Tact 1.5.0.\n' + + '///\n' + + '/// If the `cell` is not `null`, stores 1 as a single bit and then reference `cell` into the copy of the `Builder`. Returns that copy.\n' + + '///\n' + + '/// If the `cell` is `null`, only stores 0 as a single bit into the copy of the `Builder`. Returns that copy.\n' + + '///\n' + + '/// Note that a single `Cell` can contain up to 4 references.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b\n' + + '/// .storeMaybeRef(emptyCell()) // 1, then empty cell\n' + + '/// .storeMaybeRef(null); // 0\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 8: [Cell overflow] — Thrown when attempting to store more than 4 references in a single `Cell`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#builderstoremayberef\n' + + '///\n' + + '/// [Cell overflow]: https://docs.tact-lang.org/book/exit-codes#8\n' + + '///\n' + + 'asm(cell self) extends fun storeMaybeRef(self: Builder, cell: Cell?): Builder { STOPTREF }\n' + + '\n' + + '/// Extension function for the `Builder` type.\n' + + '///\n' + + '/// Converts a `Builder` into an ordinary `Cell`.\n' + + '///\n' + + '/// NOTE: **Gas expensive!** This function uses 500 gas units or more.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let c: Cell = b.endCell();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/'... 40707 more characters, + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'beginCell', + loc: { start: 218, end: 227 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 231, end: 238 } }, + loc: { start: 231, end: 238 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'NEWC' ] + }, + loc: { start: 210, end: 247 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeInt', + loc: { start: 984, end: 992 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 1032, end: 1039 } }, + loc: { start: 1032, end: 1039 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'value', + loc: { start: 1008, end: 1013 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1015, end: 1018 } + }, + loc: { start: 1015, end: 1018 } + }, + loc: { start: 1008, end: 1018 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 1020, end: 1024 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1026, end: 1029 } + }, + loc: { start: 1026, end: 1029 } + }, + loc: { start: 1020, end: 1029 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'store_int', + loc: { start: 887, end: 896 } + } + }, + loc: { start: 881, end: 1040 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 999, end: 1006 } }, + loc: { start: 999, end: 1006 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeUint', + loc: { start: 1817, end: 1826 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 1866, end: 1873 } }, + loc: { start: 1866, end: 1873 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'value', + loc: { start: 1842, end: 1847 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1849, end: 1852 } + }, + loc: { start: 1849, end: 1852 } + }, + loc: { start: 1842, end: 1852 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 1854, end: 1858 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1860, end: 1863 } + }, + loc: { start: 1860, end: 1863 } + }, + loc: { start: 1854, end: 1863 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'store_uint', + loc: { start: 1719, end: 1729 } + } + }, + loc: { start: 1713, end: 1874 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 1833, end: 1840 } }, + loc: { start: 1833, end: 1840 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeBool', + loc: { start: 2420, end: 2429 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 2459, end: 2466 } }, + loc: { start: 2459, end: 2466 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'value', + loc: { start: 2445, end: 2450 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 2452, end: 2456 } + }, + typeArgs: [], + loc: { start: 2452, end: 2456 } + }, + loc: { start: 2445, end: 2456 } + } + ], + body: { + kind: 'asm_body', + shuffle: { + args: [ + { + kind: 'id', + text: 'value', + loc: { start: 2396, end: 2401 } + }, + { + kind: 'id', + text: 'self', + loc: { start: 2402, end: 2406 } + } + ], + ret: [] + }, + instructions: [ '1 STI' ] + }, + loc: { start: 2392, end: 2476 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 2436, end: 2443 } }, + loc: { start: 2436, end: 2443 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeBit', + loc: { start: 2902, end: 2910 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 2940, end: 2947 } }, + loc: { start: 2940, end: 2947 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'value', + loc: { start: 2926, end: 2931 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 2933, end: 2937 } + }, + typeArgs: [], + loc: { start: 2933, end: 2937 } + }, + loc: { start: 2926, end: 2937 } + } + ], + body: { + kind: 'asm_body', + shuffle: { + args: [ + { + kind: 'id', + text: 'value', + loc: { start: 2878, end: 2883 } + }, + { + kind: 'id', + text: 'self', + loc: { start: 2884, end: 2888 } + } + ], + ret: [] + }, + instructions: [ '1 STI' ] + }, + loc: { start: 2874, end: 2957 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 2917, end: 2924 } }, + loc: { start: 2917, end: 2924 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeCoins', + loc: { start: 3902, end: 3912 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 3941, end: 3948 } }, + loc: { start: 3941, end: 3948 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'value', + loc: { start: 3928, end: 3933 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3935, end: 3938 } + }, + loc: { start: 3935, end: 3938 } + }, + loc: { start: 3928, end: 3938 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'STVARUINT16' ] + }, + loc: { start: 3886, end: 3964 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 3919, end: 3926 } }, + loc: { start: 3919, end: 3926 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeVarUint16', + loc: { start: 4389, end: 4403 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 4432, end: 4439 } }, + loc: { start: 4432, end: 4439 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'value', + loc: { start: 4419, end: 4424 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4426, end: 4429 } + }, + loc: { start: 4426, end: 4429 } + }, + loc: { start: 4419, end: 4429 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'STVARUINT16' ] + }, + loc: { start: 4373, end: 4455 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 4410, end: 4417 } }, + loc: { start: 4410, end: 4417 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeVarInt16', + loc: { start: 5096, end: 5109 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 5138, end: 5145 } }, + loc: { start: 5138, end: 5145 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'value', + loc: { start: 5125, end: 5130 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5132, end: 5135 } + }, + loc: { start: 5132, end: 5135 } + }, + loc: { start: 5125, end: 5135 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'STVARINT16' ] + }, + loc: { start: 5080, end: 5160 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 5116, end: 5123 } }, + loc: { start: 5116, end: 5123 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeVarUint32', + loc: { start: 6082, end: 6096 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 6125, end: 6132 } }, + loc: { start: 6125, end: 6132 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'value', + loc: { start: 6112, end: 6117 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6119, end: 6122 } + }, + loc: { start: 6119, end: 6122 } + }, + loc: { start: 6112, end: 6122 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'STVARUINT32' ] + }, + loc: { start: 6066, end: 6148 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 6103, end: 6110 } }, + loc: { start: 6103, end: 6110 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeVarInt32', + loc: { start: 6797, end: 6810 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 6839, end: 6846 } }, + loc: { start: 6839, end: 6846 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'value', + loc: { start: 6826, end: 6831 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6833, end: 6836 } + }, + loc: { start: 6833, end: 6836 } + }, + loc: { start: 6826, end: 6836 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'STVARINT32' ] + }, + loc: { start: 6781, end: 6861 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 6817, end: 6824 } }, + loc: { start: 6817, end: 6824 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeRef', + loc: { start: 7529, end: 7537 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 7566, end: 7573 } }, + loc: { start: 7566, end: 7573 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cell', + loc: { start: 7553, end: 7557 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 7559, end: 7563 } + }, + loc: { start: 7559, end: 7563 } + }, + loc: { start: 7553, end: 7563 } + } + ], + body: { + kind: 'asm_body', + shuffle: { + args: [ + { + kind: 'id', + text: 'cell', + loc: { start: 7506, end: 7510 } + }, + { + kind: 'id', + text: 'self', + loc: { start: 7511, end: 7515 } + } + ], + ret: [] + }, + instructions: [ 'STREF' ] + }, + loc: { start: 7502, end: 7583 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 7544, end: 7551 } }, + loc: { start: 7544, end: 7551 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeSlice', + loc: { start: 8005, end: 8015 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 8046, end: 8053 } }, + loc: { start: 8046, end: 8053 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'slice', + loc: { start: 8031, end: 8036 } + }, + type: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 8038, end: 8043 } + }, + loc: { start: 8038, end: 8043 } + }, + loc: { start: 8031, end: 8043 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'STSLICER' ] + }, + loc: { start: 7989, end: 8066 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 8022, end: 8029 } }, + loc: { start: 8022, end: 8029 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeBuilder', + loc: { start: 8633, end: 8645 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 8678, end: 8685 } }, + loc: { start: 8678, end: 8685 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'other', + loc: { start: 8661, end: 8666 } + }, + type: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 8668, end: 8675 } + }, + loc: { start: 8668, end: 8675 } + }, + loc: { start: 8661, end: 8675 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'STBR' ] + }, + loc: { start: 8617, end: 8694 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 8652, end: 8659 } }, + loc: { start: 8652, end: 8659 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeMaybeRef', + loc: { start: 9622, end: 9635 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 9665, end: 9672 } }, + loc: { start: 9665, end: 9672 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cell', + loc: { start: 9651, end: 9655 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 9661, end: 9662 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 9657, end: 9661 } + }, + loc: { start: 9657, end: 9661 } + } + ], + loc: { start: 9661, end: 9662 } + }, + loc: { start: 9651, end: 9662 } + } + ], + body: { + kind: 'asm_body', + shuffle: { + args: [ + { + kind: 'id', + text: 'cell', + loc: { start: 9599, end: 9603 } + }, + { + kind: 'id', + text: 'self', + loc: { start: 9604, end: 9608 } + } + ], + ret: [] + }, + instructions: [ 'STOPTREF' ] + }, + loc: { start: 9595, end: 9685 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 9642, end: 9649 } }, + loc: { start: 9642, end: 9649 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'endCell', + loc: { start: 10082, end: 10089 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 10106, end: 10110 } + }, + loc: { start: 10106, end: 10110 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ENDC' ] + }, + loc: { start: 10066, end: 10119 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 10096, end: 10103 } }, + loc: { start: 10096, end: 10103 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'refs', + loc: { start: 10479, end: 10483 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10500, end: 10503 } + }, + loc: { start: 10500, end: 10503 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'BREFS' ] + }, + loc: { start: 10463, end: 10513 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 10490, end: 10497 } }, + loc: { start: 10490, end: 10497 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'bits', + loc: { start: 10867, end: 10871 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10888, end: 10891 } + }, + loc: { start: 10888, end: 10891 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'BBITS' ] + }, + loc: { start: 10851, end: 10901 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 10878, end: 10885 } }, + loc: { start: 10878, end: 10885 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'depth', + loc: { start: 11403, end: 11408 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11425, end: 11428 } + }, + loc: { start: 11425, end: 11428 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'BDEPTH' ] + }, + loc: { start: 11387, end: 11439 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 11415, end: 11422 } }, + loc: { start: 11415, end: 11422 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'beginParse', + loc: { start: 11787, end: 11797 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 11811, end: 11816 } + }, + loc: { start: 11811, end: 11816 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'CTOS' ] + }, + loc: { start: 11771, end: 11825 } + } + }, + selfType: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 11804, end: 11808 } }, + loc: { start: 11804, end: 11808 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadRef', + loc: { start: 12822, end: 12829 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 12844, end: 12848 } + }, + loc: { start: 12844, end: 12848 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { + args: [], + ret: [ + { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 12797, end: 12798 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 12799, end: 12800 } + } + ] + }, + instructions: [ 'LDREF' ] + }, + loc: { start: 12790, end: 12858 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 12836, end: 12841 } }, + loc: { start: 12836, end: 12841 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'skipRef', + loc: { start: 13772, end: 13779 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LDREF NIP' ] + }, + loc: { start: 13748, end: 13806 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 13786, end: 13791 } }, + loc: { start: 13786, end: 13791 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'preloadRef', + loc: { start: 14937, end: 14947 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 14962, end: 14966 } + }, + loc: { start: 14962, end: 14966 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'PLDREF' ] + }, + loc: { start: 14921, end: 14977 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 14954, end: 14959 } }, + loc: { start: 14954, end: 14959 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadMaybeRef', + loc: { start: 16024, end: 16036 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 16055, end: 16056 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 16051, end: 16055 } + }, + loc: { start: 16051, end: 16055 } + } + ], + loc: { start: 16055, end: 16056 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { + args: [], + ret: [ + { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15999, end: 16000 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 16001, end: 16002 } + } + ] + }, + instructions: [ 'LDOPTREF' ] + }, + loc: { start: 15992, end: 16069 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 16043, end: 16048 } }, + loc: { start: 16043, end: 16048 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'skipMaybeRef', + loc: { start: 17041, end: 17053 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LDOPTREF NIP' ] + }, + loc: { start: 17017, end: 17083 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 17060, end: 17065 } }, + loc: { start: 17060, end: 17065 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'preloadMaybeRef', + loc: { start: 18449, end: 18464 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 18483, end: 18484 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 18479, end: 18483 } + }, + loc: { start: 18479, end: 18483 } + } + ], + loc: { start: 18483, end: 18484 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'PLDOPTREF' ] + }, + loc: { start: 18433, end: 18498 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 18471, end: 18476 } }, + loc: { start: 18471, end: 18476 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadBits', + loc: { start: 19377, end: 19385 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 19408, end: 19413 } + }, + loc: { start: 19408, end: 19413 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'l', + loc: { start: 19399, end: 19400 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 19402, end: 19405 } + }, + loc: { start: 19402, end: 19405 } + }, + loc: { start: 19399, end: 19405 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'load_bits', + loc: { start: 19268, end: 19277 } + } + }, + loc: { start: 19262, end: 19414 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 19392, end: 19397 } }, + loc: { start: 19392, end: 19397 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'preloadBits', + loc: { start: 20333, end: 20344 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 20367, end: 20372 } + }, + loc: { start: 20367, end: 20372 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'l', + loc: { start: 20358, end: 20359 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 20361, end: 20364 } + }, + loc: { start: 20361, end: 20364 } + }, + loc: { start: 20358, end: 20364 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'preload_bits', + loc: { start: 20228, end: 20240 } + } + }, + loc: { start: 20222, end: 20373 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 20351, end: 20356 } }, + loc: { start: 20351, end: 20356 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadInt', + loc: { start: 21236, end: 21243 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 21266, end: 21269 } + }, + loc: { start: 21266, end: 21269 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'l', + loc: { start: 21257, end: 21258 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 21260, end: 21263 } + }, + loc: { start: 21260, end: 21263 } + }, + loc: { start: 21257, end: 21263 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'load_int', + loc: { start: 21132, end: 21140 } + } + }, + loc: { start: 21126, end: 21270 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 21250, end: 21255 } }, + loc: { start: 21250, end: 21255 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'preloadInt', + loc: { start: 22164, end: 22174 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 22197, end: 22200 } + }, + loc: { start: 22197, end: 22200 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'l', + loc: { start: 22188, end: 22189 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 22191, end: 22194 } + }, + loc: { start: 22191, end: 22194 } + }, + loc: { start: 22188, end: 22194 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'preload_int', + loc: { start: 22064, end: 22075 } + } + }, + loc: { start: 22058, end: 22201 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 22181, end: 22186 } }, + loc: { start: 22181, end: 22186 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadUint', + loc: { start: 23071, end: 23079 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 23102, end: 23105 } + }, + loc: { start: 23102, end: 23105 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'l', + loc: { start: 23093, end: 23094 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 23096, end: 23099 } + }, + loc: { start: 23096, end: 23099 } + }, + loc: { start: 23093, end: 23099 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'load_uint', + loc: { start: 22966, end: 22975 } + } + }, + loc: { start: 22960, end: 23106 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 23086, end: 23091 } }, + loc: { start: 23086, end: 23091 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'preloadUint', + loc: { start: 24007, end: 24018 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 24041, end: 24044 } + }, + loc: { start: 24041, end: 24044 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'l', + loc: { start: 24032, end: 24033 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 24035, end: 24038 } + }, + loc: { start: 24035, end: 24038 } + }, + loc: { start: 24032, end: 24038 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'preload_uint', + loc: { start: 23906, end: 23918 } + } + }, + loc: { start: 23900, end: 24045 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 24025, end: 24030 } }, + loc: { start: 24025, end: 24030 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadBool', + loc: { start: 24834, end: 24842 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 24857, end: 24861 } + }, + typeArgs: [], + loc: { start: 24857, end: 24861 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { + args: [], + ret: [ + { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 24809, end: 24810 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 24811, end: 24812 } + } + ] + }, + instructions: [ '1 LDI' ] + }, + loc: { start: 24802, end: 24871 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 24849, end: 24854 } }, + loc: { start: 24849, end: 24854 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'skipBool', + loc: { start: 25769, end: 25777 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ '1 LDI NIP' ] + }, + loc: { start: 25745, end: 25804 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 25784, end: 25789 } }, + loc: { start: 25784, end: 25789 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadBit', + loc: { start: 26558, end: 26565 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 26580, end: 26584 } + }, + typeArgs: [], + loc: { start: 26580, end: 26584 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { + args: [], + ret: [ + { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 26533, end: 26534 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 26535, end: 26536 } + } + ] + }, + instructions: [ '1 LDI' ] + }, + loc: { start: 26526, end: 26594 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 26572, end: 26577 } }, + loc: { start: 26572, end: 26577 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadCoins', + loc: { start: 27454, end: 27463 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 27478, end: 27481 } + }, + loc: { start: 27478, end: 27481 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { + args: [], + ret: [ + { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 27429, end: 27430 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 27431, end: 27432 } + } + ] + }, + instructions: [ 'LDVARUINT16' ] + }, + loc: { start: 27422, end: 27497 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 27470, end: 27475 } }, + loc: { start: 27470, end: 27475 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'skipCoins', + loc: { start: 28454, end: 28463 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LDVARUINT16 NIP' ] + }, + loc: { start: 28430, end: 28496 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 28470, end: 28475 } }, + loc: { start: 28470, end: 28475 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadVarUint16', + loc: { start: 29318, end: 29331 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 29346, end: 29349 } + }, + loc: { start: 29346, end: 29349 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { + args: [], + ret: [ + { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 29293, end: 29294 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 29295, end: 29296 } + } + ] + }, + instructions: [ 'LDVARUINT16' ] + }, + loc: { start: 29286, end: 29365 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 29338, end: 29343 } }, + loc: { start: 29338, end: 29343 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'skipVarUint16', + loc: { start: 30263, end: 30276 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LDVARUINT16 NIP' ] + }, + loc: { start: 30239, end: 30309 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 30283, end: 30288 } }, + loc: { start: 30283, end: 30288 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadVarInt16', + loc: { start: 31141, end: 31153 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 31168, end: 31171 } + }, + loc: { start: 31168, end: 31171 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { + args: [], + ret: [ + { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 31116, end: 31117 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 31118, end: 31119 } + } + ] + }, + instructions: [ 'LDVARINT16' ] + }, + loc: { start: 31109, end: 31186 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 31160, end: 31165 } }, + loc: { start: 31160, end: 31165 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'skipVarInt16', + loc: { start: 32093, end: 32105 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LDVARINT16 NIP' ] + }, + loc: { start: 32069, end: 32137 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 32112, end: 32117 } }, + loc: { start: 32112, end: 32117 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadVarUint32', + loc: { start: 32987, end: 33000 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 33015, end: 33018 } + }, + loc: { start: 33015, end: 33018 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { + args: [], + ret: [ + { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 32962, end: 32963 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 32964, end: 32965 } + } + ] + }, + instructions: [ 'LDVARUINT32' ] + }, + loc: { start: 32955, end: 33034 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 33007, end: 33012 } }, + loc: { start: 33007, end: 33012 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'skipVarUint32', + loc: { start: 34007, end: 34020 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LDVARUINT32 NIP' ] + }, + loc: { start: 33983, end: 34053 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 34027, end: 34032 } }, + loc: { start: 34027, end: 34032 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadVarInt32', + loc: { start: 34897, end: 34909 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 34924, end: 34927 } + }, + loc: { start: 34924, end: 34927 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { + args: [], + ret: [ + { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 34872, end: 34873 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 34874, end: 34875 } + } + ] + }, + instructions: [ 'LDVARINT32' ] + }, + loc: { start: 34865, end: 34942 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 34916, end: 34921 } }, + loc: { start: 34916, end: 34921 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'skipVarInt32', + loc: { start: 35854, end: 35866 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LDVARINT32 NIP' ] + }, + loc: { start: 35830, end: 35898 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 35873, end: 35878 } }, + loc: { start: 35873, end: 35878 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'skipBits', + loc: { start: 36746, end: 36754 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'l', + loc: { start: 36768, end: 36769 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 36771, end: 36774 } + }, + loc: { start: 36771, end: 36774 } + }, + loc: { start: 36768, end: 36774 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SDSKIPFIRST' ] + }, + loc: { start: 36722, end: 36791 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 36761, end: 36766 } }, + loc: { start: 36761, end: 36766 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'endParse', + loc: { start: 37397, end: 37405 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ENDS' ] + }, + loc: { start: 37381, end: 37427 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 37412, end: 37417 } }, + loc: { start: 37412, end: 37417 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'skipLastBits', + loc: { start: 38319, end: 38331 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 38356, end: 38361 } + }, + loc: { start: 38356, end: 38361 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'len', + loc: { start: 38345, end: 38348 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 38350, end: 38353 } + }, + loc: { start: 38350, end: 38353 } + }, + loc: { start: 38345, end: 38353 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SDSKIPLAST' ] + }, + loc: { start: 38303, end: 38376 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 38338, end: 38343 } }, + loc: { start: 38338, end: 38343 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'firstBits', + loc: { start: 39373, end: 39382 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 39407, end: 39412 } + }, + loc: { start: 39407, end: 39412 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'len', + loc: { start: 39396, end: 39399 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 39401, end: 39404 } + }, + loc: { start: 39401, end: 39404 } + }, + loc: { start: 39396, end: 39404 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SDCUTFIRST' ] + }, + loc: { start: 39357, end: 39427 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 39389, end: 39394 } }, + loc: { start: 39389, end: 39394 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'lastBits', + loc: { start: 40218, end: 40226 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 40251, end: 40256 } + }, + loc: { start: 40251, end: 40256 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'len', + loc: { start: 40240, end: 40243 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 40245, end: 40248 } + }, + loc: { start: 40245, end: 40248 } + }, + loc: { start: 40240, end: 40248 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SDCUTLAST' ] + }, + loc: { start: 40202, end: 40270 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 40233, end: 40238 } }, + loc: { start: 40233, end: 40238 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'depth', + loc: { start: 40758, end: 40763 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 40778, end: 40781 } + }, + loc: { start: 40778, end: 40781 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SDEPTH' ] + }, + loc: { start: 40742, end: 40792 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 40770, end: 40775 } }, + loc: { start: 40770, end: 40775 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'refs', + loc: { start: 41166, end: 41170 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 41185, end: 41188 } + }, + loc: { start: 41185, end: 41188 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SREFS' ] + }, + loc: { start: 41150, end: 41198 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 41177, end: 41182 } }, + loc: { start: 41177, end: 41182 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'bits', + loc: { start: 41550, end: 41554 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 41569, end: 41572 } + }, + loc: { start: 41569, end: 41572 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SBITS' ] + }, + loc: { start: 41534, end: 41582 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 41561, end: 41566 } }, + loc: { start: 41561, end: 41566 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'empty', + loc: { start: 42117, end: 42122 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 42137, end: 42141 } + }, + typeArgs: [], + loc: { start: 42137, end: 42141 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SEMPTY' ] + }, + loc: { start: 42101, end: 42152 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 42129, end: 42134 } }, + loc: { start: 42129, end: 42134 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'dataEmpty', + loc: { start: 42682, end: 42691 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 42706, end: 42710 } + }, + typeArgs: [], + loc: { start: 42706, end: 42710 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SDEMPTY' ] + }, + loc: { start: 42666, end: 42722 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 42698, end: 42703 } }, + loc: { start: 42698, end: 42703 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'refsEmpty', + loc: { start: 43231, end: 43240 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 43255, end: 43259 } + }, + typeArgs: [], + loc: { start: 43255, end: 43259 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SREMPTY' ] + }, + loc: { start: 43215, end: 43271 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 43247, end: 43252 } }, + loc: { start: 43247, end: 43252 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'asSlice', + loc: { start: 43671, end: 43678 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 43695, end: 43700 } + }, + loc: { start: 43695, end: 43700 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 43714, end: 43718 } + }, + method: { + kind: 'id', + text: 'endCell', + loc: { start: 43719, end: 43726 } + }, + typeArgs: [], + args: [], + loc: { start: 43714, end: 43728 } + }, + method: { + kind: 'id', + text: 'beginParse', + loc: { start: 43729, end: 43739 } + }, + typeArgs: [], + args: [], + loc: { start: 43714, end: 43741 } + }, + loc: { start: 43707, end: 43742 } + } + ] + }, + loc: { start: 43652, end: 43744 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 43685, end: 43692 } }, + loc: { start: 43685, end: 43692 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'asSlice', + loc: { start: 44098, end: 44105 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 44119, end: 44124 } + }, + loc: { start: 44119, end: 44124 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 44138, end: 44142 } + }, + method: { + kind: 'id', + text: 'beginParse', + loc: { start: 44143, end: 44153 } + }, + typeArgs: [], + args: [], + loc: { start: 44138, end: 44155 } + }, + loc: { start: 44131, end: 44156 } + } + ] + }, + loc: { start: 44079, end: 44158 } + } + }, + selfType: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 44112, end: 44116 } }, + loc: { start: 44112, end: 44116 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'asCell', + loc: { start: 44714, end: 44720 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 44735, end: 44739 } + }, + loc: { start: 44735, end: 44739 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'static_call', + function: { + kind: 'id', + text: 'beginCell', + loc: { start: 44753, end: 44762 } + }, + typeArgs: [], + args: [], + loc: { start: 44753, end: 44764 } + }, + method: { + kind: 'id', + text: 'storeSlice', + loc: { start: 44774, end: 44784 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'self', + loc: { start: 44785, end: 44789 } + } + ], + loc: { start: 44753, end: 44790 } + }, + method: { + kind: 'id', + text: 'endCell', + loc: { start: 44800, end: 44807 } + }, + typeArgs: [], + args: [], + loc: { start: 44753, end: 44809 } + }, + loc: { start: 44746, end: 44810 } + } + ] + }, + loc: { start: 44695, end: 44812 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 44727, end: 44732 } }, + loc: { start: 44727, end: 44732 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'asCell', + loc: { start: 45173, end: 45179 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 45196, end: 45200 } + }, + loc: { start: 45196, end: 45200 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 45214, end: 45218 } + }, + method: { + kind: 'id', + text: 'endCell', + loc: { start: 45219, end: 45226 } + }, + typeArgs: [], + args: [], + loc: { start: 45214, end: 45228 } + }, + loc: { start: 45207, end: 45229 } + } + ] + }, + loc: { start: 45154, end: 45231 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 45186, end: 45193 } }, + loc: { start: 45186, end: 45193 } + } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'emptyCell', + loc: { start: 45592, end: 45601 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 45605, end: 45609 } }, + loc: { start: 45605, end: 45609 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + ' PUSHREF // Pure Fift: "" turns it into a cell at compile time' + ] + }, + loc: { start: 45584, end: 45711 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'emptySlice', + loc: { start: 46077, end: 46087 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 46091, end: 46096 } }, + loc: { start: 46091, end: 46096 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'b{} PUSHSLICE' ] + }, + loc: { start: 46069, end: 46118 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'DataSize', + loc: { start: 46431, end: 46439 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'cells', + loc: { start: 46516, end: 46521 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 46523, end: 46526 } + }, + loc: { start: 46523, end: 46526 } + }, + initializer: undefined, + loc: { start: 46516, end: 46526 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bits', + loc: { start: 46615, end: 46619 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 46621, end: 46624 } + }, + loc: { start: 46621, end: 46624 } + }, + initializer: undefined, + loc: { start: 46615, end: 46624 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'refs', + loc: { start: 46713, end: 46717 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 46719, end: 46722 } + }, + loc: { start: 46719, end: 46722 } + }, + initializer: undefined, + loc: { start: 46713, end: 46722 } + } + ], + loc: { start: 46424, end: 46725 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'computeDataSize', + loc: { start: 48450, end: 48465 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'DataSize', + loc: { start: 48495, end: 48503 } + }, + typeArgs: [], + loc: { start: 48495, end: 48503 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'maxCells', + loc: { start: 48479, end: 48487 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 48489, end: 48492 } + }, + loc: { start: 48489, end: 48492 } + }, + loc: { start: 48479, end: 48492 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'CDATASIZE' ] + }, + loc: { start: 48434, end: 48517 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 48476, end: 48477 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 48472, end: 48476 } + }, + loc: { start: 48472, end: 48476 } + } + ], + loc: { start: 48476, end: 48477 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'computeDataSize', + loc: { start: 50094, end: 50109 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'DataSize', + loc: { start: 50139, end: 50147 } + }, + typeArgs: [], + loc: { start: 50139, end: 50147 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'maxCells', + loc: { start: 50123, end: 50131 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 50133, end: 50136 } + }, + loc: { start: 50133, end: 50136 } + }, + loc: { start: 50123, end: 50136 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SDATASIZE' ] + }, + loc: { start: 50078, end: 50161 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 50116, end: 50121 } }, + loc: { start: 50116, end: 50121 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'depth', + loc: { start: 50672, end: 50677 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 50692, end: 50695 } + }, + loc: { start: 50692, end: 50695 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'CDEPTH' ] + }, + loc: { start: 50656, end: 50706 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 50688, end: 50689 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 50684, end: 50688 } + }, + loc: { start: 50684, end: 50688 } + } + ], + loc: { start: 50688, end: 50689 } + } + } + ] + }, + 'emptySlice' => { + kind: 'tact', + path: 'std/internal/cells.tact', + code: '//\n' + + '// Builder\n' + + '//\n' + + '\n' + + '/// Creates a new empty `Builder`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#begincell\n' + + '///\n' + + 'asm fun beginCell(): Builder { NEWC }\n' + + '\n' + + '/// Extension function for the `Builder` type.\n' + + '///\n' + + '/// Stores a signed `bits`-bit `value` into the copy of the `Builder` for 0 ≤ `bits` ≤ 257.\n' + + '/// Returns that copy of the `Builder`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b.storeInt(42, 7);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to provide an insufficient or out-of-bounds `bits` number.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#builderstoreint\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + '@name(store_int) // special treatment in Func compiler, so not replaced with asm "STIX"\n' + + 'extends native storeInt(self: Builder, value: Int, bits: Int): Builder;\n' + + '\n' + + '/// Extension function for the `Builder` type.\n' + + '///\n' + + '/// Stores an unsigned `bits`-bit `value` into the copy of the `Builder` for 0 ≤ `bits` ≤ 256.\n' + + '/// Returns that copy of the `Builder`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b.storeUint(42, 6);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to store a negative `value` or provide an insufficient or out-of-bounds `bits` number.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#builderstoreuint\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + '@name(store_uint) // special treatment in Func compiler, so not replaced with asm "STUX"\n' + + 'extends native storeUint(self: Builder, value: Int, bits: Int): Builder;\n' + + '\n' + + '/// Extension function for the `Builder` type.\n' + + '///\n' + + '/// Stores a `Bool` `value` into the copy of the `Builder`.\n' + + '/// Writes 1 as a single bit if `value` is `true`, and writes 0 otherwise.\n' + + '/// Returns that copy of the `Builder`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b.storeBool(true); // writes 1\n' + + '/// let buzz: Builder = b.storeBool(false); // writes 0\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#builderstorebool\n' + + '///\n' + + 'asm(value self) extends fun storeBool(self: Builder, value: Bool): Builder { 1 STI }\n' + + '\n' + + '/// Extension function for the `Builder` type. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Alias to `Builder.storeBool()`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b.storeBit(true); // writes 1\n' + + '/// let buzz: Builder = b.storeBit(false); // writes 0\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#builderstorebit\n' + + '///\n' + + 'asm(value self) extends fun storeBit(self: Builder, value: Bool): Builder { 1 STI }\n' + + '\n' + + '/// Extension function for the `Builder` type.\n' + + '///\n' + + '/// Stores (serializes) an unsigned `Int` `value` in the range from 0 to 2^120 − 1 inclusive into the copy of the `Builder`. The serialization of `value` consists of a 4-bit unsigned big-endian integer `l`, which is the smallest integer `l` ≥ 0, such that `value` < 2^(8 * `l`), followed by an 8 * `l`-bit unsigned big-endian representation of `value`. Returns that copy of the `Builder`.\n' + + '///\n' + + '/// This is the most common way of storing nanoToncoins.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b.storeCoins(42);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to store an out-of-bounds `value`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#builderstorecoins\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm extends fun storeCoins(self: Builder, value: Int): Builder { STVARUINT16 }\n' + + '\n' + + '/// Extension function for the `Builder` type. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Alias to `Builder.storeCoins()`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b.storeVarUint16(42);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#builderstorevaruint16\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#builderstorecoins\n' + + '///\n' + + 'asm extends fun storeVarUint16(self: Builder, value: Int): Builder { STVARUINT16 }\n' + + '\n' + + '/// Extension function for the `Builder` type. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Similar to `Builder.storeCoins()`, but with a different `value` range: from -2^119 to 2^119 - 1 inclusive.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b.storeVarInt16(-42);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to store an out-of-bounds `value`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#builderstorevarint16\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm extends fun storeVarInt16(self: Builder, value: Int): Builder { STVARINT16 }\n' + + '\n' + + '/// Extension function for the `Builder` type. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Stores (serializes) an unsigned `Int` `value` in the range from 0 to 2^248 − 1 inclusive into the copy of the `Builder`. The serialization of `value` consists of a 5-bit unsigned big-endian integer `l`, which is the smallest integer `l` ≥ 0, such that `value` < 2^8 * `l`, followed by an 8 * `l`-bit unsigned big-endian representation of `value`. Returns that copy of the `Builder`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b.storeVarUint32(420000);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to store an out-of-bounds `value`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#builderstorevaruint32\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm extends fun storeVarUint32(self: Builder, value: Int): Builder { STVARUINT32 }\n' + + '\n' + + '/// Extension function for the `Builder` type. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Similar to `Builder.storeVarUint32()`, but with a different `value` range: from -2^247 to 2^247 - 1 inclusive.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b.storeVarInt32(-420000);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to store an out-of-bounds `value`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#builderstorevarint32\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm extends fun storeVarInt32(self: Builder, value: Int): Builder { STVARINT32 }\n' + + '\n' + + '/// Extension function for the `Builder` type.\n' + + '///\n' + + '/// Stores a reference `cell` into a copy of the `Builder`.\n' + + '/// Returns that copy of the `Builder`.\n' + + '///\n' + + '/// Note that a single `Cell` can contain up to 4 references.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b.storeRef(emptyCell());\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 8: [Cell overflow] — Thrown when attempting to store more than 4 references in a single `Cell`.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#builderstoreref\n' + + '///\n' + + '/// [Cell overflow]: https://docs.tact-lang.org/book/exit-codes#8\n' + + '///\n' + + 'asm(cell self) extends fun storeRef(self: Builder, cell: Cell): Builder { STREF }\n' + + '\n' + + '/// Extension function for the `Builder` type.\n' + + '///\n' + + '/// Stores a `slice` into a copy of the `Builder`.\n' + + '/// Returns that copy of the `Builder`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let s: Slice = emptyCell().asSlice();\n' + + '/// let fizz: Builder = b.storeSlice(s);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#builderstoreslice\n' + + '///\n' + + 'asm extends fun storeSlice(self: Builder, slice: Slice): Builder { STSLICER }\n' + + '\n' + + '/// Extension function for the `Builder` type. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Appends all data from the `other` builder to the copy of the `self` builder. Returns that copy.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example(op: Int, queryId: Int, payload: Builder) {\n' + + '/// let msgBody = beginCell().storeUint(op, 32).storeUint(queryId, 64);\n' + + '/// if (payload.bits() != 0) {\n' + + '/// msgBody = msgBody.storeBuilder(payload); // assignment is important here\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#builderstorebuilder\n' + + '///\n' + + 'asm extends fun storeBuilder(self: Builder, other: Builder): Builder { STBR }\n' + + '\n' + + '/// Extension function for the `Builder` type. Available since Tact 1.5.0.\n' + + '///\n' + + '/// If the `cell` is not `null`, stores 1 as a single bit and then reference `cell` into the copy of the `Builder`. Returns that copy.\n' + + '///\n' + + '/// If the `cell` is `null`, only stores 0 as a single bit into the copy of the `Builder`. Returns that copy.\n' + + '///\n' + + '/// Note that a single `Cell` can contain up to 4 references.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b\n' + + '/// .storeMaybeRef(emptyCell()) // 1, then empty cell\n' + + '/// .storeMaybeRef(null); // 0\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 8: [Cell overflow] — Thrown when attempting to store more than 4 references in a single `Cell`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#builderstoremayberef\n' + + '///\n' + + '/// [Cell overflow]: https://docs.tact-lang.org/book/exit-codes#8\n' + + '///\n' + + 'asm(cell self) extends fun storeMaybeRef(self: Builder, cell: Cell?): Builder { STOPTREF }\n' + + '\n' + + '/// Extension function for the `Builder` type.\n' + + '///\n' + + '/// Converts a `Builder` into an ordinary `Cell`.\n' + + '///\n' + + '/// NOTE: **Gas expensive!** This function uses 500 gas units or more.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let c: Cell = b.endCell();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/'... 40707 more characters, + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'beginCell', + loc: { start: 218, end: 227 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 231, end: 238 } }, + loc: { start: 231, end: 238 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'NEWC' ] + }, + loc: { start: 210, end: 247 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeInt', + loc: { start: 984, end: 992 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 1032, end: 1039 } }, + loc: { start: 1032, end: 1039 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'value', + loc: { start: 1008, end: 1013 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1015, end: 1018 } + }, + loc: { start: 1015, end: 1018 } + }, + loc: { start: 1008, end: 1018 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 1020, end: 1024 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1026, end: 1029 } + }, + loc: { start: 1026, end: 1029 } + }, + loc: { start: 1020, end: 1029 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'store_int', + loc: { start: 887, end: 896 } + } + }, + loc: { start: 881, end: 1040 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 999, end: 1006 } }, + loc: { start: 999, end: 1006 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeUint', + loc: { start: 1817, end: 1826 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 1866, end: 1873 } }, + loc: { start: 1866, end: 1873 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'value', + loc: { start: 1842, end: 1847 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1849, end: 1852 } + }, + loc: { start: 1849, end: 1852 } + }, + loc: { start: 1842, end: 1852 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 1854, end: 1858 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1860, end: 1863 } + }, + loc: { start: 1860, end: 1863 } + }, + loc: { start: 1854, end: 1863 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'store_uint', + loc: { start: 1719, end: 1729 } + } + }, + loc: { start: 1713, end: 1874 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 1833, end: 1840 } }, + loc: { start: 1833, end: 1840 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeBool', + loc: { start: 2420, end: 2429 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 2459, end: 2466 } }, + loc: { start: 2459, end: 2466 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'value', + loc: { start: 2445, end: 2450 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 2452, end: 2456 } + }, + typeArgs: [], + loc: { start: 2452, end: 2456 } + }, + loc: { start: 2445, end: 2456 } + } + ], + body: { + kind: 'asm_body', + shuffle: { + args: [ + { + kind: 'id', + text: 'value', + loc: { start: 2396, end: 2401 } + }, + { + kind: 'id', + text: 'self', + loc: { start: 2402, end: 2406 } + } + ], + ret: [] + }, + instructions: [ '1 STI' ] + }, + loc: { start: 2392, end: 2476 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 2436, end: 2443 } }, + loc: { start: 2436, end: 2443 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeBit', + loc: { start: 2902, end: 2910 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 2940, end: 2947 } }, + loc: { start: 2940, end: 2947 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'value', + loc: { start: 2926, end: 2931 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 2933, end: 2937 } + }, + typeArgs: [], + loc: { start: 2933, end: 2937 } + }, + loc: { start: 2926, end: 2937 } + } + ], + body: { + kind: 'asm_body', + shuffle: { + args: [ + { + kind: 'id', + text: 'value', + loc: { start: 2878, end: 2883 } + }, + { + kind: 'id', + text: 'self', + loc: { start: 2884, end: 2888 } + } + ], + ret: [] + }, + instructions: [ '1 STI' ] + }, + loc: { start: 2874, end: 2957 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 2917, end: 2924 } }, + loc: { start: 2917, end: 2924 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeCoins', + loc: { start: 3902, end: 3912 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 3941, end: 3948 } }, + loc: { start: 3941, end: 3948 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'value', + loc: { start: 3928, end: 3933 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3935, end: 3938 } + }, + loc: { start: 3935, end: 3938 } + }, + loc: { start: 3928, end: 3938 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'STVARUINT16' ] + }, + loc: { start: 3886, end: 3964 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 3919, end: 3926 } }, + loc: { start: 3919, end: 3926 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeVarUint16', + loc: { start: 4389, end: 4403 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 4432, end: 4439 } }, + loc: { start: 4432, end: 4439 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'value', + loc: { start: 4419, end: 4424 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4426, end: 4429 } + }, + loc: { start: 4426, end: 4429 } + }, + loc: { start: 4419, end: 4429 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'STVARUINT16' ] + }, + loc: { start: 4373, end: 4455 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 4410, end: 4417 } }, + loc: { start: 4410, end: 4417 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeVarInt16', + loc: { start: 5096, end: 5109 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 5138, end: 5145 } }, + loc: { start: 5138, end: 5145 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'value', + loc: { start: 5125, end: 5130 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5132, end: 5135 } + }, + loc: { start: 5132, end: 5135 } + }, + loc: { start: 5125, end: 5135 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'STVARINT16' ] + }, + loc: { start: 5080, end: 5160 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 5116, end: 5123 } }, + loc: { start: 5116, end: 5123 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeVarUint32', + loc: { start: 6082, end: 6096 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 6125, end: 6132 } }, + loc: { start: 6125, end: 6132 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'value', + loc: { start: 6112, end: 6117 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6119, end: 6122 } + }, + loc: { start: 6119, end: 6122 } + }, + loc: { start: 6112, end: 6122 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'STVARUINT32' ] + }, + loc: { start: 6066, end: 6148 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 6103, end: 6110 } }, + loc: { start: 6103, end: 6110 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeVarInt32', + loc: { start: 6797, end: 6810 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 6839, end: 6846 } }, + loc: { start: 6839, end: 6846 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'value', + loc: { start: 6826, end: 6831 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6833, end: 6836 } + }, + loc: { start: 6833, end: 6836 } + }, + loc: { start: 6826, end: 6836 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'STVARINT32' ] + }, + loc: { start: 6781, end: 6861 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 6817, end: 6824 } }, + loc: { start: 6817, end: 6824 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeRef', + loc: { start: 7529, end: 7537 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 7566, end: 7573 } }, + loc: { start: 7566, end: 7573 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cell', + loc: { start: 7553, end: 7557 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 7559, end: 7563 } + }, + loc: { start: 7559, end: 7563 } + }, + loc: { start: 7553, end: 7563 } + } + ], + body: { + kind: 'asm_body', + shuffle: { + args: [ + { + kind: 'id', + text: 'cell', + loc: { start: 7506, end: 7510 } + }, + { + kind: 'id', + text: 'self', + loc: { start: 7511, end: 7515 } + } + ], + ret: [] + }, + instructions: [ 'STREF' ] + }, + loc: { start: 7502, end: 7583 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 7544, end: 7551 } }, + loc: { start: 7544, end: 7551 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeSlice', + loc: { start: 8005, end: 8015 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 8046, end: 8053 } }, + loc: { start: 8046, end: 8053 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'slice', + loc: { start: 8031, end: 8036 } + }, + type: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 8038, end: 8043 } + }, + loc: { start: 8038, end: 8043 } + }, + loc: { start: 8031, end: 8043 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'STSLICER' ] + }, + loc: { start: 7989, end: 8066 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 8022, end: 8029 } }, + loc: { start: 8022, end: 8029 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeBuilder', + loc: { start: 8633, end: 8645 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 8678, end: 8685 } }, + loc: { start: 8678, end: 8685 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'other', + loc: { start: 8661, end: 8666 } + }, + type: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 8668, end: 8675 } + }, + loc: { start: 8668, end: 8675 } + }, + loc: { start: 8661, end: 8675 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'STBR' ] + }, + loc: { start: 8617, end: 8694 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 8652, end: 8659 } }, + loc: { start: 8652, end: 8659 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeMaybeRef', + loc: { start: 9622, end: 9635 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 9665, end: 9672 } }, + loc: { start: 9665, end: 9672 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cell', + loc: { start: 9651, end: 9655 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 9661, end: 9662 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 9657, end: 9661 } + }, + loc: { start: 9657, end: 9661 } + } + ], + loc: { start: 9661, end: 9662 } + }, + loc: { start: 9651, end: 9662 } + } + ], + body: { + kind: 'asm_body', + shuffle: { + args: [ + { + kind: 'id', + text: 'cell', + loc: { start: 9599, end: 9603 } + }, + { + kind: 'id', + text: 'self', + loc: { start: 9604, end: 9608 } + } + ], + ret: [] + }, + instructions: [ 'STOPTREF' ] + }, + loc: { start: 9595, end: 9685 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 9642, end: 9649 } }, + loc: { start: 9642, end: 9649 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'endCell', + loc: { start: 10082, end: 10089 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 10106, end: 10110 } + }, + loc: { start: 10106, end: 10110 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ENDC' ] + }, + loc: { start: 10066, end: 10119 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 10096, end: 10103 } }, + loc: { start: 10096, end: 10103 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'refs', + loc: { start: 10479, end: 10483 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10500, end: 10503 } + }, + loc: { start: 10500, end: 10503 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'BREFS' ] + }, + loc: { start: 10463, end: 10513 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 10490, end: 10497 } }, + loc: { start: 10490, end: 10497 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'bits', + loc: { start: 10867, end: 10871 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10888, end: 10891 } + }, + loc: { start: 10888, end: 10891 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'BBITS' ] + }, + loc: { start: 10851, end: 10901 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 10878, end: 10885 } }, + loc: { start: 10878, end: 10885 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'depth', + loc: { start: 11403, end: 11408 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11425, end: 11428 } + }, + loc: { start: 11425, end: 11428 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'BDEPTH' ] + }, + loc: { start: 11387, end: 11439 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 11415, end: 11422 } }, + loc: { start: 11415, end: 11422 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'beginParse', + loc: { start: 11787, end: 11797 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 11811, end: 11816 } + }, + loc: { start: 11811, end: 11816 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'CTOS' ] + }, + loc: { start: 11771, end: 11825 } + } + }, + selfType: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 11804, end: 11808 } }, + loc: { start: 11804, end: 11808 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadRef', + loc: { start: 12822, end: 12829 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 12844, end: 12848 } + }, + loc: { start: 12844, end: 12848 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { + args: [], + ret: [ + { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 12797, end: 12798 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 12799, end: 12800 } + } + ] + }, + instructions: [ 'LDREF' ] + }, + loc: { start: 12790, end: 12858 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 12836, end: 12841 } }, + loc: { start: 12836, end: 12841 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'skipRef', + loc: { start: 13772, end: 13779 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LDREF NIP' ] + }, + loc: { start: 13748, end: 13806 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 13786, end: 13791 } }, + loc: { start: 13786, end: 13791 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'preloadRef', + loc: { start: 14937, end: 14947 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 14962, end: 14966 } + }, + loc: { start: 14962, end: 14966 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'PLDREF' ] + }, + loc: { start: 14921, end: 14977 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 14954, end: 14959 } }, + loc: { start: 14954, end: 14959 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadMaybeRef', + loc: { start: 16024, end: 16036 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 16055, end: 16056 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 16051, end: 16055 } + }, + loc: { start: 16051, end: 16055 } + } + ], + loc: { start: 16055, end: 16056 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { + args: [], + ret: [ + { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15999, end: 16000 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 16001, end: 16002 } + } + ] + }, + instructions: [ 'LDOPTREF' ] + }, + loc: { start: 15992, end: 16069 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 16043, end: 16048 } }, + loc: { start: 16043, end: 16048 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'skipMaybeRef', + loc: { start: 17041, end: 17053 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LDOPTREF NIP' ] + }, + loc: { start: 17017, end: 17083 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 17060, end: 17065 } }, + loc: { start: 17060, end: 17065 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'preloadMaybeRef', + loc: { start: 18449, end: 18464 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 18483, end: 18484 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 18479, end: 18483 } + }, + loc: { start: 18479, end: 18483 } + } + ], + loc: { start: 18483, end: 18484 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'PLDOPTREF' ] + }, + loc: { start: 18433, end: 18498 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 18471, end: 18476 } }, + loc: { start: 18471, end: 18476 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadBits', + loc: { start: 19377, end: 19385 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 19408, end: 19413 } + }, + loc: { start: 19408, end: 19413 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'l', + loc: { start: 19399, end: 19400 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 19402, end: 19405 } + }, + loc: { start: 19402, end: 19405 } + }, + loc: { start: 19399, end: 19405 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'load_bits', + loc: { start: 19268, end: 19277 } + } + }, + loc: { start: 19262, end: 19414 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 19392, end: 19397 } }, + loc: { start: 19392, end: 19397 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'preloadBits', + loc: { start: 20333, end: 20344 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 20367, end: 20372 } + }, + loc: { start: 20367, end: 20372 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'l', + loc: { start: 20358, end: 20359 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 20361, end: 20364 } + }, + loc: { start: 20361, end: 20364 } + }, + loc: { start: 20358, end: 20364 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'preload_bits', + loc: { start: 20228, end: 20240 } + } + }, + loc: { start: 20222, end: 20373 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 20351, end: 20356 } }, + loc: { start: 20351, end: 20356 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadInt', + loc: { start: 21236, end: 21243 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 21266, end: 21269 } + }, + loc: { start: 21266, end: 21269 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'l', + loc: { start: 21257, end: 21258 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 21260, end: 21263 } + }, + loc: { start: 21260, end: 21263 } + }, + loc: { start: 21257, end: 21263 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'load_int', + loc: { start: 21132, end: 21140 } + } + }, + loc: { start: 21126, end: 21270 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 21250, end: 21255 } }, + loc: { start: 21250, end: 21255 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'preloadInt', + loc: { start: 22164, end: 22174 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 22197, end: 22200 } + }, + loc: { start: 22197, end: 22200 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'l', + loc: { start: 22188, end: 22189 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 22191, end: 22194 } + }, + loc: { start: 22191, end: 22194 } + }, + loc: { start: 22188, end: 22194 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'preload_int', + loc: { start: 22064, end: 22075 } + } + }, + loc: { start: 22058, end: 22201 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 22181, end: 22186 } }, + loc: { start: 22181, end: 22186 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadUint', + loc: { start: 23071, end: 23079 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 23102, end: 23105 } + }, + loc: { start: 23102, end: 23105 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'l', + loc: { start: 23093, end: 23094 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 23096, end: 23099 } + }, + loc: { start: 23096, end: 23099 } + }, + loc: { start: 23093, end: 23099 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'load_uint', + loc: { start: 22966, end: 22975 } + } + }, + loc: { start: 22960, end: 23106 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 23086, end: 23091 } }, + loc: { start: 23086, end: 23091 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'preloadUint', + loc: { start: 24007, end: 24018 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 24041, end: 24044 } + }, + loc: { start: 24041, end: 24044 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'l', + loc: { start: 24032, end: 24033 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 24035, end: 24038 } + }, + loc: { start: 24035, end: 24038 } + }, + loc: { start: 24032, end: 24038 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'preload_uint', + loc: { start: 23906, end: 23918 } + } + }, + loc: { start: 23900, end: 24045 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 24025, end: 24030 } }, + loc: { start: 24025, end: 24030 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadBool', + loc: { start: 24834, end: 24842 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 24857, end: 24861 } + }, + typeArgs: [], + loc: { start: 24857, end: 24861 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { + args: [], + ret: [ + { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 24809, end: 24810 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 24811, end: 24812 } + } + ] + }, + instructions: [ '1 LDI' ] + }, + loc: { start: 24802, end: 24871 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 24849, end: 24854 } }, + loc: { start: 24849, end: 24854 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'skipBool', + loc: { start: 25769, end: 25777 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ '1 LDI NIP' ] + }, + loc: { start: 25745, end: 25804 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 25784, end: 25789 } }, + loc: { start: 25784, end: 25789 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadBit', + loc: { start: 26558, end: 26565 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 26580, end: 26584 } + }, + typeArgs: [], + loc: { start: 26580, end: 26584 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { + args: [], + ret: [ + { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 26533, end: 26534 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 26535, end: 26536 } + } + ] + }, + instructions: [ '1 LDI' ] + }, + loc: { start: 26526, end: 26594 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 26572, end: 26577 } }, + loc: { start: 26572, end: 26577 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadCoins', + loc: { start: 27454, end: 27463 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 27478, end: 27481 } + }, + loc: { start: 27478, end: 27481 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { + args: [], + ret: [ + { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 27429, end: 27430 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 27431, end: 27432 } + } + ] + }, + instructions: [ 'LDVARUINT16' ] + }, + loc: { start: 27422, end: 27497 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 27470, end: 27475 } }, + loc: { start: 27470, end: 27475 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'skipCoins', + loc: { start: 28454, end: 28463 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LDVARUINT16 NIP' ] + }, + loc: { start: 28430, end: 28496 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 28470, end: 28475 } }, + loc: { start: 28470, end: 28475 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadVarUint16', + loc: { start: 29318, end: 29331 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 29346, end: 29349 } + }, + loc: { start: 29346, end: 29349 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { + args: [], + ret: [ + { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 29293, end: 29294 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 29295, end: 29296 } + } + ] + }, + instructions: [ 'LDVARUINT16' ] + }, + loc: { start: 29286, end: 29365 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 29338, end: 29343 } }, + loc: { start: 29338, end: 29343 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'skipVarUint16', + loc: { start: 30263, end: 30276 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LDVARUINT16 NIP' ] + }, + loc: { start: 30239, end: 30309 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 30283, end: 30288 } }, + loc: { start: 30283, end: 30288 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadVarInt16', + loc: { start: 31141, end: 31153 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 31168, end: 31171 } + }, + loc: { start: 31168, end: 31171 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { + args: [], + ret: [ + { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 31116, end: 31117 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 31118, end: 31119 } + } + ] + }, + instructions: [ 'LDVARINT16' ] + }, + loc: { start: 31109, end: 31186 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 31160, end: 31165 } }, + loc: { start: 31160, end: 31165 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'skipVarInt16', + loc: { start: 32093, end: 32105 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LDVARINT16 NIP' ] + }, + loc: { start: 32069, end: 32137 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 32112, end: 32117 } }, + loc: { start: 32112, end: 32117 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadVarUint32', + loc: { start: 32987, end: 33000 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 33015, end: 33018 } + }, + loc: { start: 33015, end: 33018 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { + args: [], + ret: [ + { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 32962, end: 32963 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 32964, end: 32965 } + } + ] + }, + instructions: [ 'LDVARUINT32' ] + }, + loc: { start: 32955, end: 33034 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 33007, end: 33012 } }, + loc: { start: 33007, end: 33012 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'skipVarUint32', + loc: { start: 34007, end: 34020 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LDVARUINT32 NIP' ] + }, + loc: { start: 33983, end: 34053 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 34027, end: 34032 } }, + loc: { start: 34027, end: 34032 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadVarInt32', + loc: { start: 34897, end: 34909 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 34924, end: 34927 } + }, + loc: { start: 34924, end: 34927 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { + args: [], + ret: [ + { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 34872, end: 34873 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 34874, end: 34875 } + } + ] + }, + instructions: [ 'LDVARINT32' ] + }, + loc: { start: 34865, end: 34942 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 34916, end: 34921 } }, + loc: { start: 34916, end: 34921 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'skipVarInt32', + loc: { start: 35854, end: 35866 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LDVARINT32 NIP' ] + }, + loc: { start: 35830, end: 35898 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 35873, end: 35878 } }, + loc: { start: 35873, end: 35878 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'skipBits', + loc: { start: 36746, end: 36754 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'l', + loc: { start: 36768, end: 36769 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 36771, end: 36774 } + }, + loc: { start: 36771, end: 36774 } + }, + loc: { start: 36768, end: 36774 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SDSKIPFIRST' ] + }, + loc: { start: 36722, end: 36791 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 36761, end: 36766 } }, + loc: { start: 36761, end: 36766 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'endParse', + loc: { start: 37397, end: 37405 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ENDS' ] + }, + loc: { start: 37381, end: 37427 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 37412, end: 37417 } }, + loc: { start: 37412, end: 37417 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'skipLastBits', + loc: { start: 38319, end: 38331 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 38356, end: 38361 } + }, + loc: { start: 38356, end: 38361 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'len', + loc: { start: 38345, end: 38348 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 38350, end: 38353 } + }, + loc: { start: 38350, end: 38353 } + }, + loc: { start: 38345, end: 38353 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SDSKIPLAST' ] + }, + loc: { start: 38303, end: 38376 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 38338, end: 38343 } }, + loc: { start: 38338, end: 38343 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'firstBits', + loc: { start: 39373, end: 39382 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 39407, end: 39412 } + }, + loc: { start: 39407, end: 39412 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'len', + loc: { start: 39396, end: 39399 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 39401, end: 39404 } + }, + loc: { start: 39401, end: 39404 } + }, + loc: { start: 39396, end: 39404 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SDCUTFIRST' ] + }, + loc: { start: 39357, end: 39427 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 39389, end: 39394 } }, + loc: { start: 39389, end: 39394 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'lastBits', + loc: { start: 40218, end: 40226 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 40251, end: 40256 } + }, + loc: { start: 40251, end: 40256 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'len', + loc: { start: 40240, end: 40243 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 40245, end: 40248 } + }, + loc: { start: 40245, end: 40248 } + }, + loc: { start: 40240, end: 40248 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SDCUTLAST' ] + }, + loc: { start: 40202, end: 40270 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 40233, end: 40238 } }, + loc: { start: 40233, end: 40238 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'depth', + loc: { start: 40758, end: 40763 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 40778, end: 40781 } + }, + loc: { start: 40778, end: 40781 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SDEPTH' ] + }, + loc: { start: 40742, end: 40792 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 40770, end: 40775 } }, + loc: { start: 40770, end: 40775 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'refs', + loc: { start: 41166, end: 41170 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 41185, end: 41188 } + }, + loc: { start: 41185, end: 41188 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SREFS' ] + }, + loc: { start: 41150, end: 41198 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 41177, end: 41182 } }, + loc: { start: 41177, end: 41182 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'bits', + loc: { start: 41550, end: 41554 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 41569, end: 41572 } + }, + loc: { start: 41569, end: 41572 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SBITS' ] + }, + loc: { start: 41534, end: 41582 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 41561, end: 41566 } }, + loc: { start: 41561, end: 41566 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'empty', + loc: { start: 42117, end: 42122 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 42137, end: 42141 } + }, + typeArgs: [], + loc: { start: 42137, end: 42141 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SEMPTY' ] + }, + loc: { start: 42101, end: 42152 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 42129, end: 42134 } }, + loc: { start: 42129, end: 42134 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'dataEmpty', + loc: { start: 42682, end: 42691 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 42706, end: 42710 } + }, + typeArgs: [], + loc: { start: 42706, end: 42710 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SDEMPTY' ] + }, + loc: { start: 42666, end: 42722 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 42698, end: 42703 } }, + loc: { start: 42698, end: 42703 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'refsEmpty', + loc: { start: 43231, end: 43240 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 43255, end: 43259 } + }, + typeArgs: [], + loc: { start: 43255, end: 43259 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SREMPTY' ] + }, + loc: { start: 43215, end: 43271 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 43247, end: 43252 } }, + loc: { start: 43247, end: 43252 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'asSlice', + loc: { start: 43671, end: 43678 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 43695, end: 43700 } + }, + loc: { start: 43695, end: 43700 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 43714, end: 43718 } + }, + method: { + kind: 'id', + text: 'endCell', + loc: { start: 43719, end: 43726 } + }, + typeArgs: [], + args: [], + loc: { start: 43714, end: 43728 } + }, + method: { + kind: 'id', + text: 'beginParse', + loc: { start: 43729, end: 43739 } + }, + typeArgs: [], + args: [], + loc: { start: 43714, end: 43741 } + }, + loc: { start: 43707, end: 43742 } + } + ] + }, + loc: { start: 43652, end: 43744 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 43685, end: 43692 } }, + loc: { start: 43685, end: 43692 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'asSlice', + loc: { start: 44098, end: 44105 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 44119, end: 44124 } + }, + loc: { start: 44119, end: 44124 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 44138, end: 44142 } + }, + method: { + kind: 'id', + text: 'beginParse', + loc: { start: 44143, end: 44153 } + }, + typeArgs: [], + args: [], + loc: { start: 44138, end: 44155 } + }, + loc: { start: 44131, end: 44156 } + } + ] + }, + loc: { start: 44079, end: 44158 } + } + }, + selfType: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 44112, end: 44116 } }, + loc: { start: 44112, end: 44116 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'asCell', + loc: { start: 44714, end: 44720 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 44735, end: 44739 } + }, + loc: { start: 44735, end: 44739 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'static_call', + function: { + kind: 'id', + text: 'beginCell', + loc: { start: 44753, end: 44762 } + }, + typeArgs: [], + args: [], + loc: { start: 44753, end: 44764 } + }, + method: { + kind: 'id', + text: 'storeSlice', + loc: { start: 44774, end: 44784 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'self', + loc: { start: 44785, end: 44789 } + } + ], + loc: { start: 44753, end: 44790 } + }, + method: { + kind: 'id', + text: 'endCell', + loc: { start: 44800, end: 44807 } + }, + typeArgs: [], + args: [], + loc: { start: 44753, end: 44809 } + }, + loc: { start: 44746, end: 44810 } + } + ] + }, + loc: { start: 44695, end: 44812 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 44727, end: 44732 } }, + loc: { start: 44727, end: 44732 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'asCell', + loc: { start: 45173, end: 45179 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 45196, end: 45200 } + }, + loc: { start: 45196, end: 45200 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 45214, end: 45218 } + }, + method: { + kind: 'id', + text: 'endCell', + loc: { start: 45219, end: 45226 } + }, + typeArgs: [], + args: [], + loc: { start: 45214, end: 45228 } + }, + loc: { start: 45207, end: 45229 } + } + ] + }, + loc: { start: 45154, end: 45231 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 45186, end: 45193 } }, + loc: { start: 45186, end: 45193 } + } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'emptyCell', + loc: { start: 45592, end: 45601 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 45605, end: 45609 } }, + loc: { start: 45605, end: 45609 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + ' PUSHREF // Pure Fift: "" turns it into a cell at compile time' + ] + }, + loc: { start: 45584, end: 45711 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'emptySlice', + loc: { start: 46077, end: 46087 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 46091, end: 46096 } }, + loc: { start: 46091, end: 46096 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'b{} PUSHSLICE' ] + }, + loc: { start: 46069, end: 46118 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'DataSize', + loc: { start: 46431, end: 46439 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'cells', + loc: { start: 46516, end: 46521 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 46523, end: 46526 } + }, + loc: { start: 46523, end: 46526 } + }, + initializer: undefined, + loc: { start: 46516, end: 46526 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bits', + loc: { start: 46615, end: 46619 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 46621, end: 46624 } + }, + loc: { start: 46621, end: 46624 } + }, + initializer: undefined, + loc: { start: 46615, end: 46624 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'refs', + loc: { start: 46713, end: 46717 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 46719, end: 46722 } + }, + loc: { start: 46719, end: 46722 } + }, + initializer: undefined, + loc: { start: 46713, end: 46722 } + } + ], + loc: { start: 46424, end: 46725 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'computeDataSize', + loc: { start: 48450, end: 48465 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'DataSize', + loc: { start: 48495, end: 48503 } + }, + typeArgs: [], + loc: { start: 48495, end: 48503 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'maxCells', + loc: { start: 48479, end: 48487 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 48489, end: 48492 } + }, + loc: { start: 48489, end: 48492 } + }, + loc: { start: 48479, end: 48492 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'CDATASIZE' ] + }, + loc: { start: 48434, end: 48517 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 48476, end: 48477 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 48472, end: 48476 } + }, + loc: { start: 48472, end: 48476 } + } + ], + loc: { start: 48476, end: 48477 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'computeDataSize', + loc: { start: 50094, end: 50109 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'DataSize', + loc: { start: 50139, end: 50147 } + }, + typeArgs: [], + loc: { start: 50139, end: 50147 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'maxCells', + loc: { start: 50123, end: 50131 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 50133, end: 50136 } + }, + loc: { start: 50133, end: 50136 } + }, + loc: { start: 50123, end: 50136 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SDATASIZE' ] + }, + loc: { start: 50078, end: 50161 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 50116, end: 50121 } }, + loc: { start: 50116, end: 50121 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'depth', + loc: { start: 50672, end: 50677 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 50692, end: 50695 } + }, + loc: { start: 50692, end: 50695 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'CDEPTH' ] + }, + loc: { start: 50656, end: 50706 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 50688, end: 50689 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 50684, end: 50688 } + }, + loc: { start: 50684, end: 50688 } + } + ], + loc: { start: 50688, end: 50689 } + } + } + ] + }, + 'checkSignature' => { + kind: 'tact', + path: 'std/internal/crypto.tact', + code: '/// Extension function for the `Cell` type.\n' + + '///\n' + + '/// Calculates and returns an `Int` value of the [SHA-256] hash of the\n' + + '/// [standard `Cell` representation][std-representation] of the given `Cell`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let c: Cell = emptyCell();\n' + + '/// let fizz: Int = c.hash();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#cellhash\n' + + '///\n' + + '/// [SHA-256]: https://en.wikipedia.org/wiki/SHA-2#Hash_standard\n' + + '/// [std-representation]: https://docs.tact-lang.org/book/cells#cells-representation\n' + + '///\n' + + 'asm extends fun hash(self: Cell): Int { HASHCU }\n' + + '\n' + + '/// Extension function for the `Slice` type.\n' + + '///\n' + + '/// Calculates and returns an `Int` value of the [SHA-256] hash of the\n' + + '/// [standard `Slice` representation][std-representation] of the given `Slice`.\n' + + '///\n' + + '/// NOTE: **Gas expensive!** This function uses 500 gas units or more.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let s: Slice = beginCell().asSlice();\n' + + '/// let fizz: Int = s.hash();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#slicehash\n' + + '///\n' + + '/// [SHA-256]: https://en.wikipedia.org/wiki/SHA-2#Hash_standard\n' + + '/// [std-representation]: https://docs.tact-lang.org/book/cells#cells-representation\n' + + '///\n' + + 'asm extends fun hash(self: Slice): Int { HASHSU }\n' + + '\n' + + '/// Extension function for the `Slice` type. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Calculates and returns an `Int` value of the SHA-256 hash of the data bits from the given `Slice`, which should have a number of bits divisible by 8.\n' + + '///\n' + + '/// Unlike `sha256()`, this function is gas-efficient and **only** hashes the data of the given `Slice`, i.e. up to 1023 bits, ignoring the refs.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// // Base64-encoded BoC with "Hello, World!"\n' + + '/// let short: Slice = slice("te6cckEBAQEADgAAGEhlbGxvIHdvcmxkIXgtxbw=");\n' + + '///\n' + + "/// // It's enough to only take the hash of the data\n" + + '/// sha256(short) == short.hashData(); // true\n' + + '///\n' + + '/// // But if we construct a slice larger than 1023 bits with all refs combined,\n' + + "/// // we must use sha256() or we'll get skewed results or even collisions\n" + + '///\n' + + '/// let tmp: Builder = beginCell();\n' + + '/// repeat (127) { tmp = tmp.storeUint(69, 8) } // storing 127 bytes\n' + + '/// let ref: Cell = beginCell().storeUint(33, 8).endCell();\n' + + '/// let long: Slice = tmp.storeRef(ref).asSlice(); // plus a ref with a single byte\n' + + '///\n' + + "/// // Hashing just the data bits in the current slice isn't enough\n" + + '/// sha256(long) == long.hashData(); // false!\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 9: [Cell underflow] — Thrown when attempting to specify a `Slice` with number of bits **not** divisible by 8.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#slicehashdata\n' + + '///\n' + + '/// [Cell underflow]: https://docs.tact-lang.org/book/exit-codes#9\n' + + '///\n' + + 'asm extends fun hashData(self: Slice): Int { ONE HASHEXT_SHA256 }\n' + + '\n' + + '/// Extension function for the `String` type. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Calculates and returns an `Int` value of the SHA-256 hash of the data bits from the given `String`, which should have a number of bits divisible by 8.\n' + + '///\n' + + '/// Unlike `sha256()`, this function is gas-efficient and **only** hashes up to 127 bytes of the given string. Using longer strings would cause collisions if their first 127 bytes are the same.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let roll: Int = "Never gonna give you up!".hashData(); // just the hash of the data\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 9: [Cell underflow] — Thrown when attempting to specify a `String` with number of bits **not** divisible by 8.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#stringhashdata\n' + + '///\n' + + '/// [Cell underflow]: https://docs.tact-lang.org/book/exit-codes#9\n' + + '///\n' + + 'asm extends fun hashData(self: String): Int { ONE HASHEXT_SHA256 }\n' + + '\n' + + '/// Checks the [Ed25519] `signature` of the 256-bit unsigned `Int` `hash` using a `publicKey`,\n' + + '/// represented by a 256-bit unsigned `Int`. The signature must contain at least 512 bits of data, but\n' + + '/// only the first 512 bits are used.\n' + + '///\n' + + '/// Returns `true` if the signature is valid, `false` otherwise.\n' + + '///\n' + + '/// ```tact\n' + + '/// message ExtMsg {\n' + + '/// signature: Slice;\n' + + '/// data: Cell;\n' + + '/// }\n' + + '///\n' + + '/// contract Showcase {\n' + + '/// /// Persistent state variables\n' + + '/// pub: Int as uint256; // public key as a 256-bit unsigned Int\n' + + '///\n' + + '/// /// Constructor function init(), where all variables are initialized\n' + + '/// init(pub: Int) {\n' + + '/// self.pub = pub; // storing the public key upon contract initialization\n' + + '/// }\n' + + '///\n' + + '/// /// External message receiver, which accepts message ExtMsg\n' + + '/// external(msg: ExtMsg) {\n' + + '/// let hash: Int = beginCell().storeRef(msg.data).endCell().hash();\n' + + '/// let check: Bool = checkSignature(hash, msg.signature, self.pub);\n' + + '/// // ---- ------------- --------\n' + + '/// // ↑ ↑ ↑\n' + + '/// // | | publicKey stored in our contract\n' + + '/// // | signature obtained from the received message\n' + + '/// // hash calculated using the data from the received message\n' + + '/// // ... follow-up logic ...\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// NOTE: The first 10 calls of this function are very cheap regarding gas usage. However,\n' + + '/// the 11th call and onward consume more than 4 thousand gas units.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-crypto#checksignature\n' + + '///\n' + + '/// [Ed25519]: https://en.wikipedia.org/wiki/EdDSA#Ed25519\n' + + '///\n' + + 'asm fun checkSignature(hash: Int, signature: Slice, publicKey: Int): Bool { CHKSIGNU }\n' + + '\n' + + '/// Checks the [Ed25519] `signature` of the `data` using a `publicKey`, similar to `checkSignature()`.\n' + + '/// Verification itself is done indirectly on a [SHA-256] hash of the `data`.\n' + + '///\n' + + '/// Returns `true` if the signature is valid, `false` otherwise.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let data: Slice = someData;\n' + + '/// let signature: Slice = someSignature;\n' + + '/// let publicKey: Int = 42;\n' + + '///\n' + + '/// let check: Bool = checkDataSignature(data, signature, publicKey);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// NOTE: The first 10 calls of this function are very cheap regarding gas usage. However,\n' + + '/// the 11th call and onward consume more than 4 thousand gas units.\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 9: [Cell underflow] — Thrown when the bit length of `data` is **not** divisible by 8.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-crypto#checkdatasignature\n' + + '///\n' + + '/// [Cell underflow]: https://docs.tact-lang.org/book/exit-codes#9\n' + + '/// [Ed25519]: https://en.wikipedia.org/wiki/EdDSA#Ed25519\n' + + '/// [SHA-256]: https://en.wikipedia.org/wiki/SHA-2#Hash_standard\n' + + '///\n' + + 'asm fun checkDataSignature(data: Slice, signature: Slice, publicKey: Int): Bool { CHKSIGNS }\n' + + '\n' + + '/// A struct that contains a 512-bit [Ed25519] signature and the data it signs.\n' + + '///\n' + + '/// ```tact\n' + + '/// message MessageWithSignedData {\n' + + '/// // The `bundle.signature` contains the 512-bit Ed25519 signature\n' + + '/// // of the remaining data fields of this message struct,\n' + + '/// // while `bundle.signedData` references those data fields.\n' + + '/// // In this case, the fields are `walletId` and `seqno`.\n' + + '/// bundle: SignedBundle;\n' + + '///\n' + + '/// // These fields are common to external messages to user wallets.\n' + + '/// walletId: Int as int32;\n' + + '/// seqno: Int as uint32;\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-crypto#signedbundle\n' + + '/// * https://docs.tact-lang.org/ref/core-crypto#signedbundleverifysignature\n' + + '///\n' + + '/// [Ed25519]: https://en.wikipedia.org/wiki/EdDSA#Ed25519\n' + + '///\n' + + 'struct SignedBundle {\n' + + ' /// A 512-bit Ed25519 signature of the `signedData`.\n' + + ' signature: Slice as bytes64;\n' + + '\n' + + ' /// The remaining non-serialized data of the enclosing struct or message struct,\n' + + ' /// which was used to obtain the 512-bit Ed25519 `signature`.\n' + + ' signedData: Slice as remaining;\n' + + '}\n' + + '\n' + + '/// Extension function for the `SignedBundle` struct. Available since Tact 1.6.6.\n' + + '///\n' + + '/// Checks whether `self.signedData` was signed by the 512-bit [Ed25519] signature `self.signature`,\n' + + '/// using the given `publicKey`. Returns `true` if the signature is valid, `false` otherwise.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Example(publicKey: Int as uint256) {\n' + + '/// external(msg: MessageWithSignedData) {\n' + + '/// // Checks that the signature of the SignedBundle from the incoming external\n' + + "/// // message wasn't forged and made by the owner of this self.publicKey with\n" + + '/// // its respective private key managed elsewhere.\n' + + '/// throwUnless(35, msg.bundle.verifySignature(self.publicKey));\n' + + '///\n' + + '/// // ...rest of the checks and code...\n' + + '/// }\n' + + '/// }\n' + + '///\n' + + '/// message MessageWithSignedData {\n' + + '/// // The `bundle.signature` contains the 512-bit Ed25519 signature\n' + + '/// // of the remaining data fields of this message struct,\n' + + '/// // while `bundle.signedData` references those data fields.\n' + + '/// // In this case, the fields are `walletId` and `seqno`.\n' + + '/// bundle: SignedBundle;\n' + + '///\n' + + '/// // These fields are common to external messages to user wallets.\n' + + '/// walletId: Int as int32;\n' + + '/// seqno: Int as uint32;\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-crypto#signedbundleverifysignature\n' + + '///\n' + + '/// [Ed25519]: https://en.wikipedia.org/wiki/EdDSA#Ed25519\n' + + '///\n' + + 'inline extends fun verifySignature(self: SignedBundle, publicKey: Int): Bool {\n' + + ' return checkSignature(self.signedData.hash(), self.signature, publicKey);\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.6.\n' + + '///\n' + + '/// Computes and returns the Ethereum-compatible [Keccak-256] hash as a 256-bit unsigned `Int` from the passed `Slice` `data`.\n' + + '///\n' + + '/// The `data` slice should have a number of bits divisible by 8 and no more than a single reference per cell, because only the first reference of each nested cell will be taken into account.\n' + + '///\n' + + '/// #### Usage\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Examples() {\n' + + '/// receive(rawMsg: Slice) {\n' + + '/// // Hash incoming messa'... 1135 more characters, + imports: [], + items: [ + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'hash', + loc: { start: 554, end: 558 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 572, end: 575 } + }, + loc: { start: 572, end: 575 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'HASHCU' ] + }, + loc: { start: 538, end: 586 } + } + }, + selfType: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 565, end: 569 } }, + loc: { start: 565, end: 569 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'hash', + loc: { start: 1232, end: 1236 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1251, end: 1254 } + }, + loc: { start: 1251, end: 1254 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'HASHSU' ] + }, + loc: { start: 1216, end: 1265 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 1243, end: 1248 } }, + loc: { start: 1243, end: 1248 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'hashData', + loc: { start: 2808, end: 2816 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2831, end: 2834 } + }, + loc: { start: 2831, end: 2834 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ONE HASHEXT_SHA256' ] + }, + loc: { start: 2792, end: 2857 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 2823, end: 2828 } }, + loc: { start: 2823, end: 2828 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'hashData', + loc: { start: 3740, end: 3748 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3764, end: 3767 } + }, + loc: { start: 3764, end: 3767 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ONE HASHEXT_SHA256' ] + }, + loc: { start: 3724, end: 3790 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 3755, end: 3761 } + }, + typeArgs: [], + loc: { start: 3755, end: 3761 } + } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'checkSignature', + loc: { start: 5592, end: 5606 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 5653, end: 5657 } + }, + typeArgs: [], + loc: { start: 5653, end: 5657 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'hash', + loc: { start: 5607, end: 5611 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5613, end: 5616 } + }, + loc: { start: 5613, end: 5616 } + }, + loc: { start: 5607, end: 5616 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'signature', + loc: { start: 5618, end: 5627 } + }, + type: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 5629, end: 5634 } }, + loc: { start: 5629, end: 5634 } + }, + loc: { start: 5618, end: 5634 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'publicKey', + loc: { start: 5636, end: 5645 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5647, end: 5650 } + }, + loc: { start: 5647, end: 5650 } + }, + loc: { start: 5636, end: 5650 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'CHKSIGNU' ] + }, + loc: { start: 5584, end: 5670 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'checkDataSignature', + loc: { start: 6731, end: 6749 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 6798, end: 6802 } + }, + typeArgs: [], + loc: { start: 6798, end: 6802 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'data', + loc: { start: 6750, end: 6754 } + }, + type: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 6756, end: 6761 } }, + loc: { start: 6756, end: 6761 } + }, + loc: { start: 6750, end: 6761 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'signature', + loc: { start: 6763, end: 6772 } + }, + type: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 6774, end: 6779 } }, + loc: { start: 6774, end: 6779 } + }, + loc: { start: 6763, end: 6779 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'publicKey', + loc: { start: 6781, end: 6790 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6792, end: 6795 } + }, + loc: { start: 6792, end: 6795 } + }, + loc: { start: 6781, end: 6795 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'CHKSIGNS' ] + }, + loc: { start: 6723, end: 6815 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'SignedBundle', + loc: { start: 7626, end: 7638 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'signature', + loc: { start: 7702, end: 7711 } + }, + type: { + kind: 'TySlice', + format: { + kind: 'SFBits', + bits: 512, + loc: { start: 7713, end: 7729 } + }, + loc: { start: 7713, end: 7718 } + }, + initializer: undefined, + loc: { start: 7702, end: 7729 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'signedData', + loc: { start: 7887, end: 7897 } + }, + type: { + kind: 'TySlice', + format: { + kind: 'SFRemaining', + loc: { start: 7899, end: 7917 } + }, + loc: { start: 7899, end: 7904 } + }, + initializer: undefined, + loc: { start: 7887, end: 7917 } + } + ], + loc: { start: 7619, end: 7920 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'verifySignature', + loc: { start: 9355, end: 9370 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 9408, end: 9412 } + }, + typeArgs: [], + loc: { start: 9408, end: 9412 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'publicKey', + loc: { start: 9391, end: 9400 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9402, end: 9405 } + }, + loc: { start: 9402, end: 9405 } + }, + loc: { start: 9391, end: 9405 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'checkSignature', + loc: { start: 9426, end: 9440 } + }, + typeArgs: [], + args: [ + { + kind: 'method_call', + self: { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'self', + loc: { start: 9441, end: 9445 } + }, + field: { + kind: 'id', + text: 'signedData', + loc: { start: 9446, end: 9456 } + }, + loc: { start: 9441, end: 9456 } + }, + method: { + kind: 'id', + text: 'hash', + loc: { start: 9457, end: 9461 } + }, + typeArgs: [], + args: [], + loc: { start: 9441, end: 9463 } + }, + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'self', + loc: { start: 9465, end: 9469 } + }, + field: { + kind: 'id', + text: 'signature', + loc: { start: 9470, end: 9479 } + }, + loc: { start: 9465, end: 9479 } + }, + { + kind: 'var', + name: 'publicKey', + loc: { start: 9481, end: 9490 } + } + ], + loc: { start: 9426, end: 9491 } + }, + loc: { start: 9419, end: 9492 } + } + ] + }, + loc: { start: 9336, end: 9494 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'SignedBundle', + loc: { start: 9377, end: 9389 } + }, + typeArgs: [], + loc: { start: 9377, end: 9389 } + } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'keccak256', + loc: { start: 10942, end: 10951 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10966, end: 10969 } + }, + loc: { start: 10966, end: 10969 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'data', + loc: { start: 10952, end: 10956 } + }, + type: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 10958, end: 10963 } + }, + loc: { start: 10958, end: 10963 } + }, + loc: { start: 10952, end: 10963 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '<{\n' + + ' <{ DUP SREFS }> PUSHCONT\n' + + ' <{ LDREFRTOS }> PUSHCONT\n' + + ' WHILE\n' + + ' DEPTH\n' + + ' HASHEXT_KECCAK256\n' + + ' }> PUSHCONT\n' + + ' 1 1 CALLXARGS' + ] + }, + loc: { start: 10934, end: 11134 } + } + ] + }, + 'checkDataSignature' => { + kind: 'tact', + path: 'std/internal/crypto.tact', + code: '/// Extension function for the `Cell` type.\n' + + '///\n' + + '/// Calculates and returns an `Int` value of the [SHA-256] hash of the\n' + + '/// [standard `Cell` representation][std-representation] of the given `Cell`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let c: Cell = emptyCell();\n' + + '/// let fizz: Int = c.hash();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#cellhash\n' + + '///\n' + + '/// [SHA-256]: https://en.wikipedia.org/wiki/SHA-2#Hash_standard\n' + + '/// [std-representation]: https://docs.tact-lang.org/book/cells#cells-representation\n' + + '///\n' + + 'asm extends fun hash(self: Cell): Int { HASHCU }\n' + + '\n' + + '/// Extension function for the `Slice` type.\n' + + '///\n' + + '/// Calculates and returns an `Int` value of the [SHA-256] hash of the\n' + + '/// [standard `Slice` representation][std-representation] of the given `Slice`.\n' + + '///\n' + + '/// NOTE: **Gas expensive!** This function uses 500 gas units or more.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let s: Slice = beginCell().asSlice();\n' + + '/// let fizz: Int = s.hash();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#slicehash\n' + + '///\n' + + '/// [SHA-256]: https://en.wikipedia.org/wiki/SHA-2#Hash_standard\n' + + '/// [std-representation]: https://docs.tact-lang.org/book/cells#cells-representation\n' + + '///\n' + + 'asm extends fun hash(self: Slice): Int { HASHSU }\n' + + '\n' + + '/// Extension function for the `Slice` type. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Calculates and returns an `Int` value of the SHA-256 hash of the data bits from the given `Slice`, which should have a number of bits divisible by 8.\n' + + '///\n' + + '/// Unlike `sha256()`, this function is gas-efficient and **only** hashes the data of the given `Slice`, i.e. up to 1023 bits, ignoring the refs.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// // Base64-encoded BoC with "Hello, World!"\n' + + '/// let short: Slice = slice("te6cckEBAQEADgAAGEhlbGxvIHdvcmxkIXgtxbw=");\n' + + '///\n' + + "/// // It's enough to only take the hash of the data\n" + + '/// sha256(short) == short.hashData(); // true\n' + + '///\n' + + '/// // But if we construct a slice larger than 1023 bits with all refs combined,\n' + + "/// // we must use sha256() or we'll get skewed results or even collisions\n" + + '///\n' + + '/// let tmp: Builder = beginCell();\n' + + '/// repeat (127) { tmp = tmp.storeUint(69, 8) } // storing 127 bytes\n' + + '/// let ref: Cell = beginCell().storeUint(33, 8).endCell();\n' + + '/// let long: Slice = tmp.storeRef(ref).asSlice(); // plus a ref with a single byte\n' + + '///\n' + + "/// // Hashing just the data bits in the current slice isn't enough\n" + + '/// sha256(long) == long.hashData(); // false!\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 9: [Cell underflow] — Thrown when attempting to specify a `Slice` with number of bits **not** divisible by 8.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#slicehashdata\n' + + '///\n' + + '/// [Cell underflow]: https://docs.tact-lang.org/book/exit-codes#9\n' + + '///\n' + + 'asm extends fun hashData(self: Slice): Int { ONE HASHEXT_SHA256 }\n' + + '\n' + + '/// Extension function for the `String` type. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Calculates and returns an `Int` value of the SHA-256 hash of the data bits from the given `String`, which should have a number of bits divisible by 8.\n' + + '///\n' + + '/// Unlike `sha256()`, this function is gas-efficient and **only** hashes up to 127 bytes of the given string. Using longer strings would cause collisions if their first 127 bytes are the same.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let roll: Int = "Never gonna give you up!".hashData(); // just the hash of the data\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 9: [Cell underflow] — Thrown when attempting to specify a `String` with number of bits **not** divisible by 8.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#stringhashdata\n' + + '///\n' + + '/// [Cell underflow]: https://docs.tact-lang.org/book/exit-codes#9\n' + + '///\n' + + 'asm extends fun hashData(self: String): Int { ONE HASHEXT_SHA256 }\n' + + '\n' + + '/// Checks the [Ed25519] `signature` of the 256-bit unsigned `Int` `hash` using a `publicKey`,\n' + + '/// represented by a 256-bit unsigned `Int`. The signature must contain at least 512 bits of data, but\n' + + '/// only the first 512 bits are used.\n' + + '///\n' + + '/// Returns `true` if the signature is valid, `false` otherwise.\n' + + '///\n' + + '/// ```tact\n' + + '/// message ExtMsg {\n' + + '/// signature: Slice;\n' + + '/// data: Cell;\n' + + '/// }\n' + + '///\n' + + '/// contract Showcase {\n' + + '/// /// Persistent state variables\n' + + '/// pub: Int as uint256; // public key as a 256-bit unsigned Int\n' + + '///\n' + + '/// /// Constructor function init(), where all variables are initialized\n' + + '/// init(pub: Int) {\n' + + '/// self.pub = pub; // storing the public key upon contract initialization\n' + + '/// }\n' + + '///\n' + + '/// /// External message receiver, which accepts message ExtMsg\n' + + '/// external(msg: ExtMsg) {\n' + + '/// let hash: Int = beginCell().storeRef(msg.data).endCell().hash();\n' + + '/// let check: Bool = checkSignature(hash, msg.signature, self.pub);\n' + + '/// // ---- ------------- --------\n' + + '/// // ↑ ↑ ↑\n' + + '/// // | | publicKey stored in our contract\n' + + '/// // | signature obtained from the received message\n' + + '/// // hash calculated using the data from the received message\n' + + '/// // ... follow-up logic ...\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// NOTE: The first 10 calls of this function are very cheap regarding gas usage. However,\n' + + '/// the 11th call and onward consume more than 4 thousand gas units.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-crypto#checksignature\n' + + '///\n' + + '/// [Ed25519]: https://en.wikipedia.org/wiki/EdDSA#Ed25519\n' + + '///\n' + + 'asm fun checkSignature(hash: Int, signature: Slice, publicKey: Int): Bool { CHKSIGNU }\n' + + '\n' + + '/// Checks the [Ed25519] `signature` of the `data` using a `publicKey`, similar to `checkSignature()`.\n' + + '/// Verification itself is done indirectly on a [SHA-256] hash of the `data`.\n' + + '///\n' + + '/// Returns `true` if the signature is valid, `false` otherwise.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let data: Slice = someData;\n' + + '/// let signature: Slice = someSignature;\n' + + '/// let publicKey: Int = 42;\n' + + '///\n' + + '/// let check: Bool = checkDataSignature(data, signature, publicKey);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// NOTE: The first 10 calls of this function are very cheap regarding gas usage. However,\n' + + '/// the 11th call and onward consume more than 4 thousand gas units.\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 9: [Cell underflow] — Thrown when the bit length of `data` is **not** divisible by 8.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-crypto#checkdatasignature\n' + + '///\n' + + '/// [Cell underflow]: https://docs.tact-lang.org/book/exit-codes#9\n' + + '/// [Ed25519]: https://en.wikipedia.org/wiki/EdDSA#Ed25519\n' + + '/// [SHA-256]: https://en.wikipedia.org/wiki/SHA-2#Hash_standard\n' + + '///\n' + + 'asm fun checkDataSignature(data: Slice, signature: Slice, publicKey: Int): Bool { CHKSIGNS }\n' + + '\n' + + '/// A struct that contains a 512-bit [Ed25519] signature and the data it signs.\n' + + '///\n' + + '/// ```tact\n' + + '/// message MessageWithSignedData {\n' + + '/// // The `bundle.signature` contains the 512-bit Ed25519 signature\n' + + '/// // of the remaining data fields of this message struct,\n' + + '/// // while `bundle.signedData` references those data fields.\n' + + '/// // In this case, the fields are `walletId` and `seqno`.\n' + + '/// bundle: SignedBundle;\n' + + '///\n' + + '/// // These fields are common to external messages to user wallets.\n' + + '/// walletId: Int as int32;\n' + + '/// seqno: Int as uint32;\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-crypto#signedbundle\n' + + '/// * https://docs.tact-lang.org/ref/core-crypto#signedbundleverifysignature\n' + + '///\n' + + '/// [Ed25519]: https://en.wikipedia.org/wiki/EdDSA#Ed25519\n' + + '///\n' + + 'struct SignedBundle {\n' + + ' /// A 512-bit Ed25519 signature of the `signedData`.\n' + + ' signature: Slice as bytes64;\n' + + '\n' + + ' /// The remaining non-serialized data of the enclosing struct or message struct,\n' + + ' /// which was used to obtain the 512-bit Ed25519 `signature`.\n' + + ' signedData: Slice as remaining;\n' + + '}\n' + + '\n' + + '/// Extension function for the `SignedBundle` struct. Available since Tact 1.6.6.\n' + + '///\n' + + '/// Checks whether `self.signedData` was signed by the 512-bit [Ed25519] signature `self.signature`,\n' + + '/// using the given `publicKey`. Returns `true` if the signature is valid, `false` otherwise.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Example(publicKey: Int as uint256) {\n' + + '/// external(msg: MessageWithSignedData) {\n' + + '/// // Checks that the signature of the SignedBundle from the incoming external\n' + + "/// // message wasn't forged and made by the owner of this self.publicKey with\n" + + '/// // its respective private key managed elsewhere.\n' + + '/// throwUnless(35, msg.bundle.verifySignature(self.publicKey));\n' + + '///\n' + + '/// // ...rest of the checks and code...\n' + + '/// }\n' + + '/// }\n' + + '///\n' + + '/// message MessageWithSignedData {\n' + + '/// // The `bundle.signature` contains the 512-bit Ed25519 signature\n' + + '/// // of the remaining data fields of this message struct,\n' + + '/// // while `bundle.signedData` references those data fields.\n' + + '/// // In this case, the fields are `walletId` and `seqno`.\n' + + '/// bundle: SignedBundle;\n' + + '///\n' + + '/// // These fields are common to external messages to user wallets.\n' + + '/// walletId: Int as int32;\n' + + '/// seqno: Int as uint32;\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-crypto#signedbundleverifysignature\n' + + '///\n' + + '/// [Ed25519]: https://en.wikipedia.org/wiki/EdDSA#Ed25519\n' + + '///\n' + + 'inline extends fun verifySignature(self: SignedBundle, publicKey: Int): Bool {\n' + + ' return checkSignature(self.signedData.hash(), self.signature, publicKey);\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.6.\n' + + '///\n' + + '/// Computes and returns the Ethereum-compatible [Keccak-256] hash as a 256-bit unsigned `Int` from the passed `Slice` `data`.\n' + + '///\n' + + '/// The `data` slice should have a number of bits divisible by 8 and no more than a single reference per cell, because only the first reference of each nested cell will be taken into account.\n' + + '///\n' + + '/// #### Usage\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Examples() {\n' + + '/// receive(rawMsg: Slice) {\n' + + '/// // Hash incoming messa'... 1135 more characters, + imports: [], + items: [ + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'hash', + loc: { start: 554, end: 558 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 572, end: 575 } + }, + loc: { start: 572, end: 575 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'HASHCU' ] + }, + loc: { start: 538, end: 586 } + } + }, + selfType: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 565, end: 569 } }, + loc: { start: 565, end: 569 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'hash', + loc: { start: 1232, end: 1236 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1251, end: 1254 } + }, + loc: { start: 1251, end: 1254 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'HASHSU' ] + }, + loc: { start: 1216, end: 1265 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 1243, end: 1248 } }, + loc: { start: 1243, end: 1248 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'hashData', + loc: { start: 2808, end: 2816 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2831, end: 2834 } + }, + loc: { start: 2831, end: 2834 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ONE HASHEXT_SHA256' ] + }, + loc: { start: 2792, end: 2857 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 2823, end: 2828 } }, + loc: { start: 2823, end: 2828 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'hashData', + loc: { start: 3740, end: 3748 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3764, end: 3767 } + }, + loc: { start: 3764, end: 3767 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ONE HASHEXT_SHA256' ] + }, + loc: { start: 3724, end: 3790 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 3755, end: 3761 } + }, + typeArgs: [], + loc: { start: 3755, end: 3761 } + } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'checkSignature', + loc: { start: 5592, end: 5606 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 5653, end: 5657 } + }, + typeArgs: [], + loc: { start: 5653, end: 5657 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'hash', + loc: { start: 5607, end: 5611 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5613, end: 5616 } + }, + loc: { start: 5613, end: 5616 } + }, + loc: { start: 5607, end: 5616 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'signature', + loc: { start: 5618, end: 5627 } + }, + type: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 5629, end: 5634 } }, + loc: { start: 5629, end: 5634 } + }, + loc: { start: 5618, end: 5634 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'publicKey', + loc: { start: 5636, end: 5645 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5647, end: 5650 } + }, + loc: { start: 5647, end: 5650 } + }, + loc: { start: 5636, end: 5650 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'CHKSIGNU' ] + }, + loc: { start: 5584, end: 5670 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'checkDataSignature', + loc: { start: 6731, end: 6749 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 6798, end: 6802 } + }, + typeArgs: [], + loc: { start: 6798, end: 6802 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'data', + loc: { start: 6750, end: 6754 } + }, + type: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 6756, end: 6761 } }, + loc: { start: 6756, end: 6761 } + }, + loc: { start: 6750, end: 6761 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'signature', + loc: { start: 6763, end: 6772 } + }, + type: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 6774, end: 6779 } }, + loc: { start: 6774, end: 6779 } + }, + loc: { start: 6763, end: 6779 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'publicKey', + loc: { start: 6781, end: 6790 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6792, end: 6795 } + }, + loc: { start: 6792, end: 6795 } + }, + loc: { start: 6781, end: 6795 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'CHKSIGNS' ] + }, + loc: { start: 6723, end: 6815 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'SignedBundle', + loc: { start: 7626, end: 7638 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'signature', + loc: { start: 7702, end: 7711 } + }, + type: { + kind: 'TySlice', + format: { + kind: 'SFBits', + bits: 512, + loc: { start: 7713, end: 7729 } + }, + loc: { start: 7713, end: 7718 } + }, + initializer: undefined, + loc: { start: 7702, end: 7729 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'signedData', + loc: { start: 7887, end: 7897 } + }, + type: { + kind: 'TySlice', + format: { + kind: 'SFRemaining', + loc: { start: 7899, end: 7917 } + }, + loc: { start: 7899, end: 7904 } + }, + initializer: undefined, + loc: { start: 7887, end: 7917 } + } + ], + loc: { start: 7619, end: 7920 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'verifySignature', + loc: { start: 9355, end: 9370 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 9408, end: 9412 } + }, + typeArgs: [], + loc: { start: 9408, end: 9412 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'publicKey', + loc: { start: 9391, end: 9400 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9402, end: 9405 } + }, + loc: { start: 9402, end: 9405 } + }, + loc: { start: 9391, end: 9405 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'checkSignature', + loc: { start: 9426, end: 9440 } + }, + typeArgs: [], + args: [ + { + kind: 'method_call', + self: { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'self', + loc: { start: 9441, end: 9445 } + }, + field: { + kind: 'id', + text: 'signedData', + loc: { start: 9446, end: 9456 } + }, + loc: { start: 9441, end: 9456 } + }, + method: { + kind: 'id', + text: 'hash', + loc: { start: 9457, end: 9461 } + }, + typeArgs: [], + args: [], + loc: { start: 9441, end: 9463 } + }, + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'self', + loc: { start: 9465, end: 9469 } + }, + field: { + kind: 'id', + text: 'signature', + loc: { start: 9470, end: 9479 } + }, + loc: { start: 9465, end: 9479 } + }, + { + kind: 'var', + name: 'publicKey', + loc: { start: 9481, end: 9490 } + } + ], + loc: { start: 9426, end: 9491 } + }, + loc: { start: 9419, end: 9492 } + } + ] + }, + loc: { start: 9336, end: 9494 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'SignedBundle', + loc: { start: 9377, end: 9389 } + }, + typeArgs: [], + loc: { start: 9377, end: 9389 } + } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'keccak256', + loc: { start: 10942, end: 10951 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10966, end: 10969 } + }, + loc: { start: 10966, end: 10969 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'data', + loc: { start: 10952, end: 10956 } + }, + type: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 10958, end: 10963 } + }, + loc: { start: 10958, end: 10963 } + }, + loc: { start: 10952, end: 10963 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '<{\n' + + ' <{ DUP SREFS }> PUSHCONT\n' + + ' <{ LDREFRTOS }> PUSHCONT\n' + + ' WHILE\n' + + ' DEPTH\n' + + ' HASHEXT_KECCAK256\n' + + ' }> PUSHCONT\n' + + ' 1 1 CALLXARGS' + ] + }, + loc: { start: 10934, end: 11134 } + } + ] + }, + 'keccak256' => { + kind: 'tact', + path: 'std/internal/crypto.tact', + code: '/// Extension function for the `Cell` type.\n' + + '///\n' + + '/// Calculates and returns an `Int` value of the [SHA-256] hash of the\n' + + '/// [standard `Cell` representation][std-representation] of the given `Cell`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let c: Cell = emptyCell();\n' + + '/// let fizz: Int = c.hash();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#cellhash\n' + + '///\n' + + '/// [SHA-256]: https://en.wikipedia.org/wiki/SHA-2#Hash_standard\n' + + '/// [std-representation]: https://docs.tact-lang.org/book/cells#cells-representation\n' + + '///\n' + + 'asm extends fun hash(self: Cell): Int { HASHCU }\n' + + '\n' + + '/// Extension function for the `Slice` type.\n' + + '///\n' + + '/// Calculates and returns an `Int` value of the [SHA-256] hash of the\n' + + '/// [standard `Slice` representation][std-representation] of the given `Slice`.\n' + + '///\n' + + '/// NOTE: **Gas expensive!** This function uses 500 gas units or more.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let s: Slice = beginCell().asSlice();\n' + + '/// let fizz: Int = s.hash();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#slicehash\n' + + '///\n' + + '/// [SHA-256]: https://en.wikipedia.org/wiki/SHA-2#Hash_standard\n' + + '/// [std-representation]: https://docs.tact-lang.org/book/cells#cells-representation\n' + + '///\n' + + 'asm extends fun hash(self: Slice): Int { HASHSU }\n' + + '\n' + + '/// Extension function for the `Slice` type. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Calculates and returns an `Int` value of the SHA-256 hash of the data bits from the given `Slice`, which should have a number of bits divisible by 8.\n' + + '///\n' + + '/// Unlike `sha256()`, this function is gas-efficient and **only** hashes the data of the given `Slice`, i.e. up to 1023 bits, ignoring the refs.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// // Base64-encoded BoC with "Hello, World!"\n' + + '/// let short: Slice = slice("te6cckEBAQEADgAAGEhlbGxvIHdvcmxkIXgtxbw=");\n' + + '///\n' + + "/// // It's enough to only take the hash of the data\n" + + '/// sha256(short) == short.hashData(); // true\n' + + '///\n' + + '/// // But if we construct a slice larger than 1023 bits with all refs combined,\n' + + "/// // we must use sha256() or we'll get skewed results or even collisions\n" + + '///\n' + + '/// let tmp: Builder = beginCell();\n' + + '/// repeat (127) { tmp = tmp.storeUint(69, 8) } // storing 127 bytes\n' + + '/// let ref: Cell = beginCell().storeUint(33, 8).endCell();\n' + + '/// let long: Slice = tmp.storeRef(ref).asSlice(); // plus a ref with a single byte\n' + + '///\n' + + "/// // Hashing just the data bits in the current slice isn't enough\n" + + '/// sha256(long) == long.hashData(); // false!\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 9: [Cell underflow] — Thrown when attempting to specify a `Slice` with number of bits **not** divisible by 8.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#slicehashdata\n' + + '///\n' + + '/// [Cell underflow]: https://docs.tact-lang.org/book/exit-codes#9\n' + + '///\n' + + 'asm extends fun hashData(self: Slice): Int { ONE HASHEXT_SHA256 }\n' + + '\n' + + '/// Extension function for the `String` type. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Calculates and returns an `Int` value of the SHA-256 hash of the data bits from the given `String`, which should have a number of bits divisible by 8.\n' + + '///\n' + + '/// Unlike `sha256()`, this function is gas-efficient and **only** hashes up to 127 bytes of the given string. Using longer strings would cause collisions if their first 127 bytes are the same.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let roll: Int = "Never gonna give you up!".hashData(); // just the hash of the data\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 9: [Cell underflow] — Thrown when attempting to specify a `String` with number of bits **not** divisible by 8.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#stringhashdata\n' + + '///\n' + + '/// [Cell underflow]: https://docs.tact-lang.org/book/exit-codes#9\n' + + '///\n' + + 'asm extends fun hashData(self: String): Int { ONE HASHEXT_SHA256 }\n' + + '\n' + + '/// Checks the [Ed25519] `signature` of the 256-bit unsigned `Int` `hash` using a `publicKey`,\n' + + '/// represented by a 256-bit unsigned `Int`. The signature must contain at least 512 bits of data, but\n' + + '/// only the first 512 bits are used.\n' + + '///\n' + + '/// Returns `true` if the signature is valid, `false` otherwise.\n' + + '///\n' + + '/// ```tact\n' + + '/// message ExtMsg {\n' + + '/// signature: Slice;\n' + + '/// data: Cell;\n' + + '/// }\n' + + '///\n' + + '/// contract Showcase {\n' + + '/// /// Persistent state variables\n' + + '/// pub: Int as uint256; // public key as a 256-bit unsigned Int\n' + + '///\n' + + '/// /// Constructor function init(), where all variables are initialized\n' + + '/// init(pub: Int) {\n' + + '/// self.pub = pub; // storing the public key upon contract initialization\n' + + '/// }\n' + + '///\n' + + '/// /// External message receiver, which accepts message ExtMsg\n' + + '/// external(msg: ExtMsg) {\n' + + '/// let hash: Int = beginCell().storeRef(msg.data).endCell().hash();\n' + + '/// let check: Bool = checkSignature(hash, msg.signature, self.pub);\n' + + '/// // ---- ------------- --------\n' + + '/// // ↑ ↑ ↑\n' + + '/// // | | publicKey stored in our contract\n' + + '/// // | signature obtained from the received message\n' + + '/// // hash calculated using the data from the received message\n' + + '/// // ... follow-up logic ...\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// NOTE: The first 10 calls of this function are very cheap regarding gas usage. However,\n' + + '/// the 11th call and onward consume more than 4 thousand gas units.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-crypto#checksignature\n' + + '///\n' + + '/// [Ed25519]: https://en.wikipedia.org/wiki/EdDSA#Ed25519\n' + + '///\n' + + 'asm fun checkSignature(hash: Int, signature: Slice, publicKey: Int): Bool { CHKSIGNU }\n' + + '\n' + + '/// Checks the [Ed25519] `signature` of the `data` using a `publicKey`, similar to `checkSignature()`.\n' + + '/// Verification itself is done indirectly on a [SHA-256] hash of the `data`.\n' + + '///\n' + + '/// Returns `true` if the signature is valid, `false` otherwise.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let data: Slice = someData;\n' + + '/// let signature: Slice = someSignature;\n' + + '/// let publicKey: Int = 42;\n' + + '///\n' + + '/// let check: Bool = checkDataSignature(data, signature, publicKey);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// NOTE: The first 10 calls of this function are very cheap regarding gas usage. However,\n' + + '/// the 11th call and onward consume more than 4 thousand gas units.\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 9: [Cell underflow] — Thrown when the bit length of `data` is **not** divisible by 8.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-crypto#checkdatasignature\n' + + '///\n' + + '/// [Cell underflow]: https://docs.tact-lang.org/book/exit-codes#9\n' + + '/// [Ed25519]: https://en.wikipedia.org/wiki/EdDSA#Ed25519\n' + + '/// [SHA-256]: https://en.wikipedia.org/wiki/SHA-2#Hash_standard\n' + + '///\n' + + 'asm fun checkDataSignature(data: Slice, signature: Slice, publicKey: Int): Bool { CHKSIGNS }\n' + + '\n' + + '/// A struct that contains a 512-bit [Ed25519] signature and the data it signs.\n' + + '///\n' + + '/// ```tact\n' + + '/// message MessageWithSignedData {\n' + + '/// // The `bundle.signature` contains the 512-bit Ed25519 signature\n' + + '/// // of the remaining data fields of this message struct,\n' + + '/// // while `bundle.signedData` references those data fields.\n' + + '/// // In this case, the fields are `walletId` and `seqno`.\n' + + '/// bundle: SignedBundle;\n' + + '///\n' + + '/// // These fields are common to external messages to user wallets.\n' + + '/// walletId: Int as int32;\n' + + '/// seqno: Int as uint32;\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-crypto#signedbundle\n' + + '/// * https://docs.tact-lang.org/ref/core-crypto#signedbundleverifysignature\n' + + '///\n' + + '/// [Ed25519]: https://en.wikipedia.org/wiki/EdDSA#Ed25519\n' + + '///\n' + + 'struct SignedBundle {\n' + + ' /// A 512-bit Ed25519 signature of the `signedData`.\n' + + ' signature: Slice as bytes64;\n' + + '\n' + + ' /// The remaining non-serialized data of the enclosing struct or message struct,\n' + + ' /// which was used to obtain the 512-bit Ed25519 `signature`.\n' + + ' signedData: Slice as remaining;\n' + + '}\n' + + '\n' + + '/// Extension function for the `SignedBundle` struct. Available since Tact 1.6.6.\n' + + '///\n' + + '/// Checks whether `self.signedData` was signed by the 512-bit [Ed25519] signature `self.signature`,\n' + + '/// using the given `publicKey`. Returns `true` if the signature is valid, `false` otherwise.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Example(publicKey: Int as uint256) {\n' + + '/// external(msg: MessageWithSignedData) {\n' + + '/// // Checks that the signature of the SignedBundle from the incoming external\n' + + "/// // message wasn't forged and made by the owner of this self.publicKey with\n" + + '/// // its respective private key managed elsewhere.\n' + + '/// throwUnless(35, msg.bundle.verifySignature(self.publicKey));\n' + + '///\n' + + '/// // ...rest of the checks and code...\n' + + '/// }\n' + + '/// }\n' + + '///\n' + + '/// message MessageWithSignedData {\n' + + '/// // The `bundle.signature` contains the 512-bit Ed25519 signature\n' + + '/// // of the remaining data fields of this message struct,\n' + + '/// // while `bundle.signedData` references those data fields.\n' + + '/// // In this case, the fields are `walletId` and `seqno`.\n' + + '/// bundle: SignedBundle;\n' + + '///\n' + + '/// // These fields are common to external messages to user wallets.\n' + + '/// walletId: Int as int32;\n' + + '/// seqno: Int as uint32;\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-crypto#signedbundleverifysignature\n' + + '///\n' + + '/// [Ed25519]: https://en.wikipedia.org/wiki/EdDSA#Ed25519\n' + + '///\n' + + 'inline extends fun verifySignature(self: SignedBundle, publicKey: Int): Bool {\n' + + ' return checkSignature(self.signedData.hash(), self.signature, publicKey);\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.6.\n' + + '///\n' + + '/// Computes and returns the Ethereum-compatible [Keccak-256] hash as a 256-bit unsigned `Int` from the passed `Slice` `data`.\n' + + '///\n' + + '/// The `data` slice should have a number of bits divisible by 8 and no more than a single reference per cell, because only the first reference of each nested cell will be taken into account.\n' + + '///\n' + + '/// #### Usage\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Examples() {\n' + + '/// receive(rawMsg: Slice) {\n' + + '/// // Hash incoming messa'... 1135 more characters, + imports: [], + items: [ + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'hash', + loc: { start: 554, end: 558 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 572, end: 575 } + }, + loc: { start: 572, end: 575 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'HASHCU' ] + }, + loc: { start: 538, end: 586 } + } + }, + selfType: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 565, end: 569 } }, + loc: { start: 565, end: 569 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'hash', + loc: { start: 1232, end: 1236 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1251, end: 1254 } + }, + loc: { start: 1251, end: 1254 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'HASHSU' ] + }, + loc: { start: 1216, end: 1265 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 1243, end: 1248 } }, + loc: { start: 1243, end: 1248 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'hashData', + loc: { start: 2808, end: 2816 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2831, end: 2834 } + }, + loc: { start: 2831, end: 2834 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ONE HASHEXT_SHA256' ] + }, + loc: { start: 2792, end: 2857 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 2823, end: 2828 } }, + loc: { start: 2823, end: 2828 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'hashData', + loc: { start: 3740, end: 3748 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3764, end: 3767 } + }, + loc: { start: 3764, end: 3767 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ONE HASHEXT_SHA256' ] + }, + loc: { start: 3724, end: 3790 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 3755, end: 3761 } + }, + typeArgs: [], + loc: { start: 3755, end: 3761 } + } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'checkSignature', + loc: { start: 5592, end: 5606 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 5653, end: 5657 } + }, + typeArgs: [], + loc: { start: 5653, end: 5657 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'hash', + loc: { start: 5607, end: 5611 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5613, end: 5616 } + }, + loc: { start: 5613, end: 5616 } + }, + loc: { start: 5607, end: 5616 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'signature', + loc: { start: 5618, end: 5627 } + }, + type: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 5629, end: 5634 } }, + loc: { start: 5629, end: 5634 } + }, + loc: { start: 5618, end: 5634 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'publicKey', + loc: { start: 5636, end: 5645 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5647, end: 5650 } + }, + loc: { start: 5647, end: 5650 } + }, + loc: { start: 5636, end: 5650 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'CHKSIGNU' ] + }, + loc: { start: 5584, end: 5670 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'checkDataSignature', + loc: { start: 6731, end: 6749 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 6798, end: 6802 } + }, + typeArgs: [], + loc: { start: 6798, end: 6802 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'data', + loc: { start: 6750, end: 6754 } + }, + type: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 6756, end: 6761 } }, + loc: { start: 6756, end: 6761 } + }, + loc: { start: 6750, end: 6761 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'signature', + loc: { start: 6763, end: 6772 } + }, + type: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 6774, end: 6779 } }, + loc: { start: 6774, end: 6779 } + }, + loc: { start: 6763, end: 6779 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'publicKey', + loc: { start: 6781, end: 6790 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6792, end: 6795 } + }, + loc: { start: 6792, end: 6795 } + }, + loc: { start: 6781, end: 6795 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'CHKSIGNS' ] + }, + loc: { start: 6723, end: 6815 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'SignedBundle', + loc: { start: 7626, end: 7638 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'signature', + loc: { start: 7702, end: 7711 } + }, + type: { + kind: 'TySlice', + format: { + kind: 'SFBits', + bits: 512, + loc: { start: 7713, end: 7729 } + }, + loc: { start: 7713, end: 7718 } + }, + initializer: undefined, + loc: { start: 7702, end: 7729 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'signedData', + loc: { start: 7887, end: 7897 } + }, + type: { + kind: 'TySlice', + format: { + kind: 'SFRemaining', + loc: { start: 7899, end: 7917 } + }, + loc: { start: 7899, end: 7904 } + }, + initializer: undefined, + loc: { start: 7887, end: 7917 } + } + ], + loc: { start: 7619, end: 7920 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'verifySignature', + loc: { start: 9355, end: 9370 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 9408, end: 9412 } + }, + typeArgs: [], + loc: { start: 9408, end: 9412 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'publicKey', + loc: { start: 9391, end: 9400 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9402, end: 9405 } + }, + loc: { start: 9402, end: 9405 } + }, + loc: { start: 9391, end: 9405 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'checkSignature', + loc: { start: 9426, end: 9440 } + }, + typeArgs: [], + args: [ + { + kind: 'method_call', + self: { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'self', + loc: { start: 9441, end: 9445 } + }, + field: { + kind: 'id', + text: 'signedData', + loc: { start: 9446, end: 9456 } + }, + loc: { start: 9441, end: 9456 } + }, + method: { + kind: 'id', + text: 'hash', + loc: { start: 9457, end: 9461 } + }, + typeArgs: [], + args: [], + loc: { start: 9441, end: 9463 } + }, + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'self', + loc: { start: 9465, end: 9469 } + }, + field: { + kind: 'id', + text: 'signature', + loc: { start: 9470, end: 9479 } + }, + loc: { start: 9465, end: 9479 } + }, + { + kind: 'var', + name: 'publicKey', + loc: { start: 9481, end: 9490 } + } + ], + loc: { start: 9426, end: 9491 } + }, + loc: { start: 9419, end: 9492 } + } + ] + }, + loc: { start: 9336, end: 9494 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'SignedBundle', + loc: { start: 9377, end: 9389 } + }, + typeArgs: [], + loc: { start: 9377, end: 9389 } + } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'keccak256', + loc: { start: 10942, end: 10951 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10966, end: 10969 } + }, + loc: { start: 10966, end: 10969 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'data', + loc: { start: 10952, end: 10956 } + }, + type: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 10958, end: 10963 } + }, + loc: { start: 10958, end: 10963 } + }, + loc: { start: 10952, end: 10963 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '<{\n' + + ' <{ DUP SREFS }> PUSHCONT\n' + + ' <{ LDREFRTOS }> PUSHCONT\n' + + ' WHILE\n' + + ' DEPTH\n' + + ' HASHEXT_KECCAK256\n' + + ' }> PUSHCONT\n' + + ' 1 1 CALLXARGS' + ] + }, + loc: { start: 10934, end: 11134 } + } + ] + }, + 'beginString' => { + kind: 'tact', + path: 'std/internal/text.tact', + code: '//\n' + + '// String builder\n' + + '//\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Creates and returns an empty `StringBuilder`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example(): String {\n' + + '/// let fizz: StringBuilder = beginString();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#beginstring\n' + + '///\n' + + '@name(__tact_string_builder_start_string)\n' + + 'native beginString(): StringBuilder;\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Creates and returns an empty `StringBuilder` for building a comment string, which prefixes\n' + + '/// the resulting `String` with four null bytes. This format is used for passing text comments\n' + + '/// as message bodies.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example(): String {\n' + + '/// let fizz: StringBuilder = beginComment();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#begincomment\n' + + '///\n' + + '@name(__tact_string_builder_start_comment)\n' + + 'native beginComment(): StringBuilder;\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Creates and returns an empty `StringBuilder` for building a tail string, which prefixes\n' + + '/// the resulting `String` with a single null byte. This format is used in various standards\n' + + '/// such as NFT or Jetton.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example(): String {\n' + + '/// let fizz: StringBuilder = beginTailString();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#begintailstring\n' + + '///\n' + + '@name(__tact_string_builder_start_tail_string)\n' + + 'native beginTailString(): StringBuilder;\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Creates and returns a new `StringBuilder` from an existing `StringBuilder` `b`. Useful when\n' + + '/// you need to serialize an existing `String` to a `Cell` along with other data.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example(): String {\n' + + '/// let fizz: StringBuilder = beginStringFromBuilder(beginString());\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#beginstringfrombuilder\n' + + '///\n' + + '@name(__tact_string_builder_start)\n' + + 'native beginStringFromBuilder(b: Builder): StringBuilder;\n' + + '\n' + + '/// Extension mutation function for the `StringBuilder` type.\n' + + '///\n' + + '/// Appends a `String` `s` to the `StringBuilder`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fizz: StringBuilder = beginString();\n' + + '/// fizz.append("oh");\n' + + '/// fizz.append("my");\n' + + '/// fizz.append("Tact!");\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#stringbuilderappend\n' + + '///\n' + + '@name(__tact_string_builder_append)\n' + + 'extends mutates native append(self: StringBuilder, s: String);\n' + + '\n' + + '/// Extension function for the `StringBuilder` type.\n' + + '///\n' + + '/// Returns a new `StringBuilder` after concatenating it with a `String` `s`. It can be chained,\n' + + '/// unlike `StringBuilder.append()`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fizz: StringBuilder = beginString()\n' + + '/// .concat("oh")\n' + + '/// .concat("my")\n' + + '/// .concat("Tact!");\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#stringbuilderconcat\n' + + '///\n' + + '@name(__tact_string_builder_append_not_mut)\n' + + 'extends native concat(self: StringBuilder, s: String): StringBuilder;\n' + + '\n' + + '/// Extension function for the `StringBuilder` type.\n' + + '///\n' + + '/// Returns an assembled `Cell` from a `StringBuilder`.\n' + + '///\n' + + '/// NOTE: **Gas expensive!** This function uses 500 gas units or more.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fizz: StringBuilder = beginString();\n' + + '/// let buzz: Cell = fizz.toCell();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#stringbuildertocell\n' + + '///\n' + + '@name(__tact_string_builder_end)\n' + + 'extends native toCell(self: StringBuilder): Cell;\n' + + '\n' + + '/// Extension function for the `StringBuilder` type.\n' + + '///\n' + + '/// Returns a built `String` from a `StringBuilder`.\n' + + '///\n' + + '/// NOTE: **Gas expensive!** This function uses 500 gas units or more.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fizz: StringBuilder = beginString();\n' + + '/// let buzz: String = fizz.toString();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#stringbuildertostring\n' + + '///\n' + + '@name(__tact_string_builder_end_slice)\n' + + 'extends native toString(self: StringBuilder): String;\n' + + '\n' + + '/// Extension function for the `StringBuilder` type.\n' + + '///\n' + + '/// Returns an assembled `Cell` as a `Slice` from a `StringBuilder`.\n' + + '/// An alias to `self.toCell().asSlice()`.\n' + + '///\n' + + '/// NOTE: **Gas expensive!** This function uses 500 gas units or more.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let s: StringBuilder = beginString();\n' + + '/// let fizz: Slice = s.toSlice();\n' + + '/// let buzz: Slice = s.toCell().asSlice();\n' + + '///\n' + + '/// fizz == buzz; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#stringbuildertoslice\n' + + '///\n' + + '@name(__tact_string_builder_end_slice)\n' + + 'extends native toSlice(self: StringBuilder): Slice;\n' + + '\n' + + '//\n' + + '// String conversion\n' + + '//\n' + + '\n' + + '/// Extension function for the `Int` type.\n' + + '///\n' + + '/// Returns a `String` from an `Int` value.\n' + + '///\n' + + '/// NOTE: **Gas expensive!** This function uses 500 gas units or more.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fizz: String = (84 - 42).toString();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#inttostring\n' + + '///\n' + + 'asm extends fun toString(self: Int): String {\n' + + ' // x\n' + + '\n' + + ' <{\n' + + ' // x\n' + + ' NEWC // x b\n' + + ' OVER // x b x\n' + + ' 0 LESSINT // x b <0?\n' + + ' <{\n' + + ' // x b\n' + + ' 45 PUSHINT // x b 45\n' + + ' SWAP // x 45 b\n' + + ' 8 STU // x b\n' + + ' SWAP // b x\n' + + ' NEGATE // b -x\n' + + ' SWAP // -x b\n' + + ' }>CONT IF\n' + + ' // x b\n' + + '\n' + + ' SWAP // b x\n' + + '\n' + + ' <{\n' + + ' // b x\n' + + ' 10 PUSHINT DIVMOD // b x/10 x%10\n' + + ' 48 ADDCONST // b x/10 (x%10+48)\n' + + ' s2 s2 s0 XC2PU ISZERO // (x%10+48) b x/10 x/10==0?\n' + + ' }>CONT UNTIL\n' + + ' // ... b x\n' + + '\n' + + ' DROP // ... b\n' + + ' DEPTH DEC // ... b n\n' + + ' <{ 8 STU }>CONT REPEAT // b\n' + + ' }>CONT 1 1 CALLXARGS\n' + + ' // b\n' + + '\n' + + ' ENDC CTOS // s\n' + + '}\n' + + '\n' + + '/// Extension function for the `Int` type.\n' + + '///\n' + + '/// Returns a `String` from an `Int` value using a [fixed-point representation] of a fractional\n' + + '/// number, where `self` is the significant part of the number and `digits` is the number\n' + + '/// of digits in the fractional part.\n' + + '///\n' + + '/// NOTE: **Gas expensive!** This function uses 500 gas units or more.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fizz: String = (42).toFloatString(9); // "0.000000042"\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 134: [Invalid argument] — Thrown when the given `digits` value is out of range.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#inttofloatstring\n' + + '///\n' + + '/// [fixed-point representation]: https://en.wikipedia.org/wiki/Fixed-point_arithmetic\n' + + '/// [Invalid argument]: https://docs.tact-lang.org/book/exit-codes#134\n' + + '///\n' + + 'asm extends fun toFloatString(self: Int, digits: Int): String {\n' + + ' // x digits\n' + + '\n' + + ' DUP // x digits digits\n' + + ' 1 LESSINT // x digits digits<=0\n' + + ' 134 THROWIF // x digits\n' + + ' DUP // x digits digits\n' + + ' 77 GTINT // x digits digits>77\n' + + ' 134 THROWIF // x digits\n' + + '\n' + + ' NEWC // x digits b\n' + + ' ROTREV // b x digits\n' + + ' s1 PUSH // b x digits x\n' + + ' 0 LESSINT // b x digits x<0?\n' + + '\n' + + ' <{\n' + + ' // b x digits\n' + + ' ROT // x digits b\n' + + ' x{2d} STSLICECONST // x digits b\n' + + ' ROT // digits b x\n' + + ' NEGATE // digits b -x\n' + + ' ROT // b -x digits\n' + + ' }>CONT IF\n' + + '\n' + + ' // b x digits\n' + + ' ONE // b x digits 1\n' + + ' OVER // b x digits 1 digits\n' + + '\n' + + ' <{ 10 MULCONST }>CONT REPEAT // b x digits 10^digits\n' + + '\n' + + ' s1 s2 XCHG // b digits x 10^digits\n' + + ' DIVMOD // b digits left right\n' + + ' s3 s3 XCHG2 // right digits b left\n' + + '\n' + + ' <{\n' + + ' // b x\n' + + '\n' + + ' <{\n' + + ' // b x\n' + + ' 10 PUSHINT DIVMOD // b x/10 x%10\n' + + ' 48 ADDCONST // b x/10 (x%10+48)\n' + + ' s2 s2 s0 XC2PU ISZERO // (x%10+48) b x/10 x/10==0?\n' + + ' }>CONT UNTIL\n' + + ' // ... b x\n' + + '\n' + + ' DROP // ... b\n' + + ' DEPTH DEC // ... b n\n' + + ' <{ 8 STU }>CONT REPEAT // b\n' + + ' }>CONT 2 1 CALLXARGS\n' + + '\n' + + ' // right digits "left"\n' + + '\n' + + ' ROT // digits "left" right\n' + + ' DUP // digits "left" right right\n' + + ' ISZERO // digits "left" right right==0?\n' + + '\n' + + ' <{\n' + + ' // digits "left" right\n' + + ' DROP // digits "left"\n' + + ' NIP // "left"\n' + + ' }>CONT\n' + + '\n' + + ' <{\n' + + ' // digits "left" right\n' + + ' ZERO // digits "left" right 0\n' + + ' SWAP // digits "left" 0 right\n' + + '\n' + + ' <{\n' + + ' // digits "left" i right\n' + + ' DUP // digits "left" i right right\n' + + ' 10 PUSHINT // digits "left" i right right 10\n' + + ' MOD // digits "left" i right right%10\n' + + ' ISZERO // digits "left" i right right%10==0?\n' + + ' }>CONT\n' + + '\n' + + ' <{\n' + + ' // digits "left" i right\n' + + ' 10 PUSHINT // digits "left" i right 10\n' + + ' DIV // digits "left" i right/10\n' + + ' SWAP // digits "left" right/10 i\n' + + ' INC // digits "left" right/10 i+1\n' + + ' SWAP // digits "left" i+1 right/10\n' + + ' }>CONT\n' + + '\n' + + ' WHILE // digits "left" i right\n' + + '\n' + + ' <{\n' + + ' // x\n' + + ' NEWC // x b\n' + + ' SWAP // b x\n' + + '\n' + + ' <{\n' + + ' // b x\n' + + ' 10 PUSHINT DIVMOD // b x/10 x%10\n' + + ' 48 ADDCONST // b x/10 (x%10+48)\n' + + ' s2 s2 s0 XC2PU ISZERO // (x%10+48) b x/10 x/10==0?\n' + + ' }>CONT UNTIL\n' + + ' // ... b x\n' + + '\n' + + ' DROP // ... b\n' + + ' DEPTH DEC DUP // ... b n n\n' + + ' ROTREV // ... n b n\n' + + ' <{\n' + + ' // ... c n b\n' + + ' s1 s2 XCHG // ... n c b\n' + + ' 8 STU // ... n b\n' + + ' }>CONT REPEAT // n b\n' + + ' }>CONT 1 2 CALLXARGS\n' + + ' // digits "left" i right_digits "right"\n' + + ' ROTREV // digits "left" "right" i right_digits\n' + + ' ADD // digits "left" "right" right_digits\n' + + '\n' + + ' s3 s1 XCHG // "right" "left" digits right_digits\n' + + ' SUB // "right" "left" digits_diff\n' + + ' SWAP // "right" digits_diff "left"\n' + + ' x{2e} STSLICECONST // "right" digits_diff "left."\n' + + ' SWAP // "right" "left." digits_diff\n' + + '\n' + + ' <{\n' + + ' // "right" "left."\n' + + ' x{30} STSLICECONST // "right" "left.0"\n' + + ' }>CONT REPEAT // "right" "left.000"\n' + + '\n' + + ' STB // "left.000right"\n' + + ' }>CONT\n' + + '\n' + + ' IFELSE // b\n' + + '\n' + + ' ENDC CTOS // s\n' + + '}\n' + + '\n' + + '/// Extension function for the `Int` type.\n' + + '///\n' + + '/// Returns a `String` from an `Int` value using a [fixed-point representatio'... 6219 more characters, + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'beginString', + loc: { start: 329, end: 340 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 344, end: 357 } + }, + typeArgs: [], + loc: { start: 344, end: 357 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_string_builder_start_string', + loc: { start: 286, end: 320 } + } + }, + loc: { start: 280, end: 358 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'beginComment', + loc: { start: 830, end: 842 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 846, end: 859 } + }, + typeArgs: [], + loc: { start: 846, end: 859 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_string_builder_start_comment', + loc: { start: 786, end: 821 } + } + }, + loc: { start: 780, end: 860 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'beginTailString', + loc: { start: 1341, end: 1356 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 1360, end: 1373 } + }, + typeArgs: [], + loc: { start: 1360, end: 1373 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_string_builder_start_tail_string', + loc: { start: 1293, end: 1332 } + } + }, + loc: { start: 1287, end: 1374 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'beginStringFromBuilder', + loc: { start: 1836, end: 1858 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 1872, end: 1885 } + }, + typeArgs: [], + loc: { start: 1872, end: 1885 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'b', + loc: { start: 1859, end: 1860 } + }, + type: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 1862, end: 1869 } }, + loc: { start: 1862, end: 1869 } + }, + loc: { start: 1859, end: 1869 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_string_builder_start', + loc: { start: 1800, end: 1827 } + } + }, + loc: { start: 1794, end: 1886 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'append', + loc: { start: 2328, end: 2334 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 's', + loc: { start: 2356, end: 2357 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 2359, end: 2365 } + }, + typeArgs: [], + loc: { start: 2359, end: 2365 } + }, + loc: { start: 2356, end: 2365 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_string_builder_append', + loc: { start: 2275, end: 2303 } + } + }, + loc: { start: 2269, end: 2367 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 2341, end: 2354 } + }, + typeArgs: [], + loc: { start: 2341, end: 2354 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'concat', + loc: { start: 2880, end: 2886 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 2920, end: 2933 } + }, + typeArgs: [], + loc: { start: 2920, end: 2933 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 's', + loc: { start: 2908, end: 2909 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 2911, end: 2917 } + }, + typeArgs: [], + loc: { start: 2911, end: 2917 } + }, + loc: { start: 2908, end: 2917 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_string_builder_append_not_mut', + loc: { start: 2827, end: 2863 } + } + }, + loc: { start: 2821, end: 2934 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 2893, end: 2906 } + }, + typeArgs: [], + loc: { start: 2893, end: 2906 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'toCell', + loc: { start: 3392, end: 3398 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3421, end: 3425 } }, + loc: { start: 3421, end: 3425 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_string_builder_end', + loc: { start: 3350, end: 3375 } + } + }, + loc: { start: 3344, end: 3426 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 3405, end: 3418 } + }, + typeArgs: [], + loc: { start: 3405, end: 3418 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'toString', + loc: { start: 3893, end: 3901 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 3924, end: 3930 } + }, + typeArgs: [], + loc: { start: 3924, end: 3930 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_string_builder_end_slice', + loc: { start: 3845, end: 3876 } + } + }, + loc: { start: 3839, end: 3931 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 3908, end: 3921 } + }, + typeArgs: [], + loc: { start: 3908, end: 3921 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'toSlice', + loc: { start: 4530, end: 4537 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 4560, end: 4565 } }, + loc: { start: 4560, end: 4565 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_string_builder_end_slice', + loc: { start: 4482, end: 4513 } + } + }, + loc: { start: 4476, end: 4566 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 4544, end: 4557 } + }, + typeArgs: [], + loc: { start: 4544, end: 4557 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'toString', + loc: { start: 4950, end: 4958 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 4971, end: 4977 } + }, + typeArgs: [], + loc: { start: 4971, end: 4977 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '<{\n' + + ' // x\n' + + ' NEWC // x b\n' + + ' OVER // x b x\n' + + ' 0 LESSINT // x b <0?\n' + + ' <{\n' + + ' // x b\n' + + ' 45 PUSHINT // x b 45\n' + + ' SWAP // x 45 b\n' + + ' 8 STU // x b\n' + + ' SWAP // b x\n' + + ' NEGATE // b -x\n' + + ' SWAP // -x b\n' + + ' }>CONT IF\n' + + ' // x b\n' + + '\n' + + ' SWAP // b x\n' + + '\n' + + ' <{\n' + + ' // b x\n' + + ' 10 PUSHINT DIVMOD // b x/10 x%10\n' + + ' 48 ADDCONST // b x/10 (x%10+48)\n' + + ' s2 s2 s0 XC2PU ISZERO // (x%10+48) b x/10 x/10==0?\n' + + ' }>CONT UNTIL\n' + + ' // ... b x\n' + + '\n' + + ' DROP // ... b\n' + + ' DEPTH DEC // ... b n\n' + + ' <{ 8 STU }>CONT REPEAT // b\n' + + ' }>CONT 1 1 CALLXARGS\n' + + ' // b\n' + + '\n' + + ' ENDC CTOS // s' + ] + }, + loc: { start: 4934, end: 5692 } + } + }, + selfType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4965, end: 4968 } + }, + loc: { start: 4965, end: 4968 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'toFloatString', + loc: { start: 6527, end: 6540 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 6566, end: 6572 } + }, + typeArgs: [], + loc: { start: 6566, end: 6572 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'digits', + loc: { start: 6552, end: 6558 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6560, end: 6563 } + }, + loc: { start: 6560, end: 6563 } + }, + loc: { start: 6552, end: 6563 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'DUP // x digits digits\n' + + ' 1 LESSINT // x digits digits<=0\n' + + ' 134 THROWIF // x digits\n' + + ' DUP // x digits digits\n' + + ' 77 GTINT // x digits digits>77\n' + + ' 134 THROWIF // x digits\n' + + '\n' + + ' NEWC // x digits b\n' + + ' ROTREV // b x digits\n' + + ' s1 PUSH // b x digits x\n' + + ' 0 LESSINT // b x digits x<0?\n' + + '\n' + + ' <{\n' + + ' // b x digits\n' + + ' ROT // x digits b\n' + + ' x{2d} STSLICECONST // x digits b\n' + + ' ROT // digits b x\n' + + ' NEGATE // digits b -x\n' + + ' ROT // b -x digits\n' + + ' }>CONT IF\n' + + '\n' + + ' // b x digits\n' + + ' ONE // b x digits 1\n' + + ' OVER // b x digits 1 digits\n' + + '\n' + + ' <{ 10 MULCONST }>CONT REPEAT // b x digits 10^digits\n' + + '\n' + + ' s1 s2 XCHG // b digits x 10^digits\n' + + ' DIVMOD // b digits left right\n' + + ' s3 s3 XCHG2 // right digits b left\n' + + '\n' + + ' <{\n' + + ' // b x\n' + + '\n' + + ' <{\n' + + ' // b x\n' + + ' 10 PUSHINT DIVMOD // b x/10 x%10\n' + + ' 48 ADDCONST // b x/10 (x%10+48)\n' + + ' s2 s2 s0 XC2PU ISZERO // (x%10+48) b x/10 x/10==0?\n' + + ' }>CONT UNTIL\n' + + ' // ... b x\n' + + '\n' + + ' DROP // ... b\n' + + ' DEPTH DEC // ... b n\n' + + ' <{ 8 STU }>CONT REPEAT // b\n' + + ' }>CONT 2 1 CALLXARGS\n' + + '\n' + + ' // right digits "left"\n' + + '\n' + + ' ROT // digits "left" right\n' + + ' DUP // digits "left" right right\n' + + ' ISZERO // digits "left" right right==0?\n' + + '\n' + + ' <{\n' + + ' // digits "left" right\n' + + ' DROP // digits "left"\n' + + ' NIP // "left"\n' + + ' }>CONT\n' + + '\n' + + ' <{\n' + + ' // digits "left" right\n' + + ' ZERO // digits "left" right 0\n' + + ' SWAP // digits "left" 0 right\n' + + '\n' + + ' <{\n' + + ' // digits "left" i right\n' + + ' DUP // digits "left" i right right\n' + + ' 10 PUSHINT // digits "left" i right right 10\n' + + ' MOD // digits "left" i right right%10\n' + + ' ISZERO // digits "left" i right right%10==0?\n' + + ' }>CONT\n' + + '\n' + + ' <{\n' + + ' // digits "left" i right\n' + + ' 10 PUSHINT // digits "left" i right 10\n' + + ' DIV // digits "left" i right/10\n' + + ' SWAP // digits "left" right/10 i\n' + + ' INC // digits "left" right/10 i+1\n' + + ' SWAP // digits "left" i+1 right/10\n' + + ' }>CONT\n' + + '\n' + + ' WHILE // digits "left" i right\n' + + '\n' + + ' <{\n' + + ' // x\n' + + ' NEWC // x b\n' + + ' SWAP // b x\n' + + '\n' + + ' <{\n' + + ' // b x\n' + + ' 10 PUSHINT DIVMOD // b x/10 x%10\n' + + ' 48 ADDCONST // b x/10 (x%10+48)\n' + + ' s2 s2 s0 XC2PU ISZERO // (x%10+48) b x/10 x/10==0?\n' + + ' }>CONT UNTIL\n' + + ' // ... b x\n' + + '\n' + + ' DROP // ... b\n' + + ' DEPTH DEC DUP // ... b n n\n' + + ' ROTREV // ... n b n\n' + + ' <{\n' + + ' // ... c n b\n' + + ' s1 s2 XCHG // ... n c b\n' + + ' 8 STU // ... n b\n' + + ' }>CONT REPEAT // n b\n' + + ' }>CONT 1 2 CALLXARGS\n' + + ' // digits "left" i right_digits "right"\n' + + ' ROTREV // digits "left" "right" i right_digits\n' + + ' ADD // digits "left" "right" right_digits\n' + + '\n' + + ' s3 s1 XCHG // "right" "left" digits right_digits\n' + + ' SUB // "right" "left" digits_diff\n' + + ' SWAP // "right" digits_diff "left"\n' + + ' x{2e} STSLICECONST // "right" digits_diff "left."\n' + + ' SWAP // "right" "left." digits_diff\n' + + '\n' + + ' <{\n' + + ' // "right" "left."\n' + + ' x{30} STSLICECONST // "right" "left.0"\n' + + ' }>CONT REPEAT // "right" "left.000"\n' + + '\n' + + ' STB // "left.000right"\n' + + ' }>CONT\n' + + '\n' + + ' IFELSE // b\n' + + '\n' + + ' ENDC CTOS // s' + ] + }, + loc: { start: 6511, end: 9874 } + } + }, + selfType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6547, end: 6550 } + }, + loc: { start: 6547, end: 6550 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'toCoinsString', + loc: { start: 10653, end: 10666 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 10679, end: 10685 } + }, + typeArgs: [], + loc: { start: 10679, end: 10685 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 10699, end: 10703 } + }, + method: { + kind: 'id', + text: 'toFloatString', + loc: { start: 10704, end: 10717 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 9n, + loc: { start: 10718, end: 10719 } + } + ], + loc: { start: 10699, end: 10720 } + }, + loc: { start: 10692, end: 10721 } + } + ] + }, + loc: { start: 10634, end: 10723 } + } + }, + selfType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10673, end: 10676 } + }, + loc: { start: 10673, end: 10676 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'asComment', + loc: { start: 11442, end: 11451 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 11467, end: 11471 } + }, + loc: { start: 11467, end: 11471 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'b', + loc: { start: 11482, end: 11483 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 11485, end: 11498 } + }, + typeArgs: [], + loc: { start: 11485, end: 11498 } + }, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'beginComment', + loc: { start: 11501, end: 11513 } + }, + typeArgs: [], + args: [], + loc: { start: 11501, end: 11515 } + }, + loc: { start: 11478, end: 11516 } + }, + { + kind: 'statement_expression', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'b', + loc: { start: 11521, end: 11522 } + }, + method: { + kind: 'id', + text: 'append', + loc: { start: 11523, end: 11529 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'self', + loc: { start: 11530, end: 11534 } + } + ], + loc: { start: 11521, end: 11535 } + }, + loc: { start: 11521, end: 11536 } + }, + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'b', + loc: { start: 11548, end: 11549 } + }, + method: { + kind: 'id', + text: 'toCell', + loc: { start: 11550, end: 11556 } + }, + typeArgs: [], + args: [], + loc: { start: 11548, end: 11558 } + }, + loc: { start: 11541, end: 11559 } + } + ] + }, + loc: { start: 11430, end: 11561 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 11458, end: 11464 } + }, + typeArgs: [], + loc: { start: 11458, end: 11464 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'asSlice', + loc: { start: 12075, end: 12082 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 12098, end: 12103 } + }, + loc: { start: 12098, end: 12103 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_str_to_slice', + loc: { start: 12039, end: 12058 } + } + }, + loc: { start: 12033, end: 12104 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 12089, end: 12095 } + }, + typeArgs: [], + loc: { start: 12089, end: 12095 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'asString', + loc: { start: 12598, end: 12606 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 12621, end: 12627 } + }, + typeArgs: [], + loc: { start: 12621, end: 12627 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_slice_to_str', + loc: { start: 12562, end: 12581 } + } + }, + loc: { start: 12556, end: 12628 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 12613, end: 12618 } }, + loc: { start: 12613, end: 12618 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'fromBase64', + loc: { start: 13537, end: 13547 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 13563, end: 13568 } + }, + loc: { start: 13563, end: 13568 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 13582, end: 13586 } + }, + method: { + kind: 'id', + text: 'asSlice', + loc: { start: 13587, end: 13594 } + }, + typeArgs: [], + args: [], + loc: { start: 13582, end: 13596 } + }, + method: { + kind: 'id', + text: 'fromBase64', + loc: { start: 13597, end: 13607 } + }, + typeArgs: [], + args: [], + loc: { start: 13582, end: 13609 } + }, + loc: { start: 13575, end: 13610 } + } + ] + }, + loc: { start: 13518, end: 13612 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 13554, end: 13560 } + }, + typeArgs: [], + loc: { start: 13554, end: 13560 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'fromBase64', + loc: { start: 14642, end: 14652 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 14667, end: 14672 } + }, + loc: { start: 14667, end: 14672 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'size', + loc: { start: 14683, end: 14687 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14689, end: 14692 } + }, + loc: { start: 14689, end: 14692 } + }, + expression: { + kind: 'op_binary', + op: '/', + left: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 14695, end: 14699 } + }, + method: { + kind: 'id', + text: 'bits', + loc: { start: 14700, end: 14704 } + }, + typeArgs: [], + args: [], + loc: { start: 14695, end: 14706 } + }, + right: { + kind: 'number', + base: '10', + value: 8n, + loc: { start: 14709, end: 14710 } + }, + loc: { start: 14695, end: 14710 } + }, + loc: { start: 14679, end: 14711 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'result', + loc: { start: 14720, end: 14726 } + }, + type: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 14728, end: 14735 } + }, + loc: { start: 14728, end: 14735 } + }, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'beginCell', + loc: { start: 14738, end: 14747 } + }, + typeArgs: [], + args: [], + loc: { start: 14738, end: 14749 } + }, + loc: { start: 14716, end: 14750 } + }, + { + kind: 'statement_repeat', + iterations: { + kind: 'var', + name: 'size', + loc: { start: 14764, end: 14768 } + }, + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'code', + loc: { start: 14784, end: 14788 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14790, end: 14793 } + }, + loc: { start: 14790, end: 14793 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 14796, end: 14800 } + }, + method: { + kind: 'id', + text: 'loadUint', + loc: { start: 14801, end: 14809 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 8n, + loc: { start: 14810, end: 14811 } + } + ], + loc: { start: 14796, end: 14812 } + }, + loc: { start: 14780, end: 14813 } + }, + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '&&', + left: { + kind: 'op_binary', + op: '>=', + left: { + kind: 'var', + name: 'code', + loc: { start: 14826, end: 14830 } + }, + right: { + kind: 'number', + base: '10', + value: 65n, + loc: { start: 14834, end: 14836 } + }, + loc: { start: 14826, end: 14836 } + }, + right: { + kind: 'op_binary', + op: '<=', + left: { + kind: 'var', + name: 'code', + loc: { start: 14840, end: 14844 } + }, + right: { + kind: 'number', + base: '10', + value: 90n, + loc: { start: 14848, end: 14850 } + }, + loc: { start: 14840, end: 14850 } + }, + loc: { start: 14826, end: 14850 } + }, + trueStatements: [ + { + kind: 'statement_assign', + path: { + kind: 'var', + name: 'result', + loc: { start: 14873, end: 14879 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'result', + loc: { start: 14882, end: 14888 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 14889, end: 14898 } + }, + typeArgs: [], + args: [ + { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'code', + loc: { start: 14899, end: 14903 } + }, + right: { + kind: 'number', + base: '10', + value: 65n, + loc: { start: 14906, end: 14908 } + }, + loc: { start: 14899, end: 14908 } + }, + { + kind: 'number', + base: '10', + value: 6n, + loc: { start: 14910, end: 14911 } + } + ], + loc: { start: 14882, end: 14912 } + }, + loc: { start: 14873, end: 14913 } + } + ], + falseStatements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '&&', + left: { + kind: 'op_binary', + op: '>=', + left: { + kind: 'var', + name: 'code', + loc: { start: 14933, end: 14937 } + }, + right: { + kind: 'number', + base: '10', + value: 97n, + loc: { start: 14941, end: 14943 } + }, + loc: { start: 14933, end: 14943 } + }, + right: { + kind: 'op_binary', + op: '<=', + left: { + kind: 'var', + name: 'code', + loc: { start: 14947, end: 14951 } + }, + right: { + kind: 'number', + base: '10', + value: 122n, + loc: { start: 14955, end: 14958 } + }, + loc: { start: 14947, end: 14958 } + }, + loc: { start: 14933, end: 14958 } + }, + trueStatements: [ + { + kind: 'statement_assign', + path: { + kind: 'var', + name: 'result', + loc: { start: 14981, end: 14987 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'result', + loc: { start: 14990, end: 14996 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 14997, end: 15006 } + }, + typeArgs: [], + args: [ + { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'code', + loc: { start: 15007, end: 15011 } + }, + right: { + kind: 'op_binary', + op: '-', + left: { + kind: 'number', + base: '10', + value: 97n, + loc: { start: 15015, end: 15017 } + }, + right: { + kind: 'number', + base: '10', + value: 26n, + loc: { start: 15020, end: 15022 } + }, + loc: { start: 15015, end: 15022 } + }, + loc: { start: 15007, end: 15023 } + }, + { + kind: 'number', + base: '10', + value: 6n, + loc: { start: 15025, end: 15026 } + } + ], + loc: { start: 14990, end: 15027 } + }, + loc: { start: 14981, end: 15028 } + } + ], + falseStatements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '&&', + left: { + kind: 'op_binary', + op: '>=', + left: { + kind: 'var', + name: 'code', + loc: { start: 15048, end: 15052 } + }, + right: { + kind: 'number', + base: '10', + value: 48n, + loc: { start: 15056, end: 15058 } + }, + loc: { start: 15048, end: 15058 } + }, + right: { + kind: 'op_binary', + op: '<=', + left: { + kind: 'var', + name: 'code', + loc: { start: 15062, end: 15066 } + }, + right: { + kind: 'number', + base: '10', + value: 57n, + loc: { start: 15070, end: 15072 } + }, + loc: { start: 15062, end: 15072 } + }, + loc: { start: 15048, end: 15072 } + }, + trueStatements: [ + { + kind: 'statement_assign', + path: { + kind: 'var', + name: 'result', + loc: { start: 15095, end: 15101 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'result', + loc: { start: 15104, end: 15110 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 15111, end: 15120 } + }, + typeArgs: [], + args: [ + { + kind: 'op_binary', + op: '+', + left: { + kind: 'var', + name: 'code', + loc: { + start: 15121, + end: 15125 + } + }, + right: { + kind: 'op_binary', + op: '-', + left: { + kind: 'number', + base: '10', + value: 52n, + loc: { + start: 15129, + end: 15131 + } + }, + right: { + kind: 'number', + base: '10', + value: 48n, + loc: { + start: 15134, + end: 15136 + } + }, + loc: { + start: 15129, + end: 15136 + } + }, + loc: { start: 15121, end: 15137 } + }, + { + kind: 'number', + base: '10', + value: 6n, + loc: { start: 15139, end: 15140 } + } + ], + loc: { start: 15104, end: 15141 } + }, + loc: { start: 15095, end: 15142 } + } + ], + falseStatements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '||', + left: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'code', + loc: { start: 15162, end: 15166 } + }, + right: { + kind: 'number', + base: '10', + value: 45n, + loc: { start: 15170, end: 15172 } + }, + loc: { start: 15162, end: 15172 } + }, + right: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'code', + loc: { start: 15176, end: 15180 } + }, + right: { + kind: 'number', + base: '10', + value: 43n, + loc: { start: 15184, end: 15186 } + }, + loc: { start: 15176, end: 15186 } + }, + loc: { start: 15162, end: 15186 } + }, + trueStatements: [ + { + kind: 'statement_assign', + path: { + kind: 'var', + name: 'result', + loc: { start: 15212, end: 15218 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'result', + loc: { + start: 15221, + end: 15227 + } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { + start: 15228, + end: 15237 + } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 62n, + loc: { + start: 15238, + end: 15240 + } + }, + { + kind: 'number', + base: '10', + value: 6n, + loc: { + start: 15242, + end: 15243 + } + } + ], + loc: { start: 15221, end: 15244 } + }, + loc: { start: 15212, end: 15245 } + } + ], + falseStatements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '||', + left: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'code', + loc: { + start: 15265, + end: 15269 + } + }, + right: { + kind: 'number', + base: '10', + value: 95n, + loc: { + start: 15273, + end: 15275 + } + }, + loc: { + start: 15265, + end: 15275 + } + }, + right: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'code', + loc: { + start: 15279, + end: 15283 + } + }, + right: { + kind: 'number', + base: '10', + value: 47n, + loc: { + start: 15287, + end: 15289 + } + }, + loc: { + start: 15279, + end: 15289 + } + }, + loc: { start: 15265, end: 15289 } + }, + trueStatements: [ + { + kind: 'statement_assign', + path: { + kind: 'var', + name: 'result', + loc: { + start: 15315, + end: 15321 + } + }, + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'result', + loc: { + start: 15324, + end: 15330 + } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { + start: 15331, + end: 15340 + } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 63n, + loc: { + start: 15341, + end: 15343 + } + }, + { + kind: 'number', + base: '10', + value: 6n, + loc: { + start: 15345, + end: 15346 + } + } + ], + loc: { + start: 15324, + end: 15347 + } + }, + loc: { + start: 15315, + end: 15348 + } + } + ], + falseStatements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'code', + loc: { + start: 15368, + end: 15372 + } + }, + right: { + kind: 'number', + base: '10', + value: 61n, + loc: { + start: 15376, + end: 15378 + } + }, + loc: { + start: 15368, + end: 15378 + } + }, + trueStatements: [], + falseStatements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throw', + loc: { + start: 15436, + end: 15441 + } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'TactExitCodeInvalidArgument', + loc: { + start: 15442, + end: 15469 + } + } + ], + loc: { + start: 15436, + end: 15470 + } + }, + loc: { + start: 15436, + end: 15471 + } + } + ], + loc: { + start: 15364, + end: 15481 + } + } + ], + loc: { start: 15261, end: 15481 } + } + ], + loc: { start: 15158, end: 15481 } + } + ], + loc: { start: 15044, end: 15481 } + } + ], + loc: { start: 14929, end: 15481 } + } + ], + loc: { start: 14822, end: 15481 } + } + ], + loc: { start: 14756, end: 15487 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'total', + loc: { start: 15512, end: 15517 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15519, end: 15522 } + }, + loc: { start: 15519, end: 15522 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'result', + loc: { start: 15525, end: 15531 } + }, + method: { + kind: 'id', + text: 'bits', + loc: { start: 15532, end: 15536 } + }, + typeArgs: [], + args: [], + loc: { start: 15525, end: 15538 } + }, + loc: { start: 15508, end: 15539 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'padding', + loc: { start: 15548, end: 15555 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15557, end: 15560 } + }, + loc: { start: 15557, end: 15560 } + }, + expression: { + kind: 'op_binary', + op: '%', + left: { + kind: 'var', + name: 'total', + loc: { start: 15563, end: 15568 } + }, + right: { + kind: 'number', + base: '10', + value: 8n, + loc: { start: 15571, end: 15572 } + }, + loc: { start: 15563, end: 15572 } + }, + loc: { start: 15544, end: 15573 } + }, + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '!=', + left: { + kind: 'var', + name: 'padding', + loc: { start: 15582, end: 15589 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15593, end: 15594 } + }, + loc: { start: 15582, end: 15594 } + }, + trueStatements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 's', + loc: { start: 15610, end: 15611 } + }, + type: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 15613, end: 15618 } + }, + loc: { start: 15613, end: 15618 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'result', + loc: { start: 15621, end: 15627 } + }, + method: { + kind: 'id', + text: 'asSlice', + loc: { start: 15628, end: 15635 } + }, + typeArgs: [], + args: [], + loc: { start: 15621, end: 15637 } + }, + loc: { start: 15606, end: 15638 } + }, + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 's', + loc: { start: 15654, end: 15655 } + }, + method: { + kind: 'id', + text: 'loadBits', + loc: { start: 15656, end: 15664 } + }, + typeArgs: [], + args: [ + { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'total', + loc: { start: 15665, end: 15670 } + }, + right: { + kind: 'var', + name: 'padding', + loc: { start: 15673, end: 15680 } + }, + loc: { start: 15665, end: 15680 } + } + ], + loc: { start: 15654, end: 15681 } + }, + loc: { start: 15647, end: 15682 } + } + ], + falseStatements: [ + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'result', + loc: { start: 15711, end: 15717 } + }, + method: { + kind: 'id', + text: 'asSlice', + loc: { start: 15718, end: 15725 } + }, + typeArgs: [], + args: [], + loc: { start: 15711, end: 15727 } + }, + loc: { start: 15704, end: 15728 } + } + ], + loc: { start: 15578, end: 15734 } + } + ] + }, + loc: { start: 14630, end: 15736 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 14659, end: 14664 } }, + loc: { start: 14659, end: 14664 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'toString', + loc: { start: 16186, end: 16194 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 16211, end: 16217 } + }, + typeArgs: [], + loc: { start: 16211, end: 16217 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_address_to_user_friendly', + loc: { start: 16138, end: 16169 } + } + }, + loc: { start: 16132, end: 16218 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 16201, end: 16208 } + }, + typeArgs: [], + loc: { start: 16201, end: 16208 } + } + } + ] + }, + 'beginComment' => { + kind: 'tact', + path: 'std/internal/text.tact', + code: '//\n' + + '// String builder\n' + + '//\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Creates and returns an empty `StringBuilder`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example(): String {\n' + + '/// let fizz: StringBuilder = beginString();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#beginstring\n' + + '///\n' + + '@name(__tact_string_builder_start_string)\n' + + 'native beginString(): StringBuilder;\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Creates and returns an empty `StringBuilder` for building a comment string, which prefixes\n' + + '/// the resulting `String` with four null bytes. This format is used for passing text comments\n' + + '/// as message bodies.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example(): String {\n' + + '/// let fizz: StringBuilder = beginComment();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#begincomment\n' + + '///\n' + + '@name(__tact_string_builder_start_comment)\n' + + 'native beginComment(): StringBuilder;\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Creates and returns an empty `StringBuilder` for building a tail string, which prefixes\n' + + '/// the resulting `String` with a single null byte. This format is used in various standards\n' + + '/// such as NFT or Jetton.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example(): String {\n' + + '/// let fizz: StringBuilder = beginTailString();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#begintailstring\n' + + '///\n' + + '@name(__tact_string_builder_start_tail_string)\n' + + 'native beginTailString(): StringBuilder;\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Creates and returns a new `StringBuilder` from an existing `StringBuilder` `b`. Useful when\n' + + '/// you need to serialize an existing `String` to a `Cell` along with other data.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example(): String {\n' + + '/// let fizz: StringBuilder = beginStringFromBuilder(beginString());\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#beginstringfrombuilder\n' + + '///\n' + + '@name(__tact_string_builder_start)\n' + + 'native beginStringFromBuilder(b: Builder): StringBuilder;\n' + + '\n' + + '/// Extension mutation function for the `StringBuilder` type.\n' + + '///\n' + + '/// Appends a `String` `s` to the `StringBuilder`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fizz: StringBuilder = beginString();\n' + + '/// fizz.append("oh");\n' + + '/// fizz.append("my");\n' + + '/// fizz.append("Tact!");\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#stringbuilderappend\n' + + '///\n' + + '@name(__tact_string_builder_append)\n' + + 'extends mutates native append(self: StringBuilder, s: String);\n' + + '\n' + + '/// Extension function for the `StringBuilder` type.\n' + + '///\n' + + '/// Returns a new `StringBuilder` after concatenating it with a `String` `s`. It can be chained,\n' + + '/// unlike `StringBuilder.append()`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fizz: StringBuilder = beginString()\n' + + '/// .concat("oh")\n' + + '/// .concat("my")\n' + + '/// .concat("Tact!");\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#stringbuilderconcat\n' + + '///\n' + + '@name(__tact_string_builder_append_not_mut)\n' + + 'extends native concat(self: StringBuilder, s: String): StringBuilder;\n' + + '\n' + + '/// Extension function for the `StringBuilder` type.\n' + + '///\n' + + '/// Returns an assembled `Cell` from a `StringBuilder`.\n' + + '///\n' + + '/// NOTE: **Gas expensive!** This function uses 500 gas units or more.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fizz: StringBuilder = beginString();\n' + + '/// let buzz: Cell = fizz.toCell();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#stringbuildertocell\n' + + '///\n' + + '@name(__tact_string_builder_end)\n' + + 'extends native toCell(self: StringBuilder): Cell;\n' + + '\n' + + '/// Extension function for the `StringBuilder` type.\n' + + '///\n' + + '/// Returns a built `String` from a `StringBuilder`.\n' + + '///\n' + + '/// NOTE: **Gas expensive!** This function uses 500 gas units or more.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fizz: StringBuilder = beginString();\n' + + '/// let buzz: String = fizz.toString();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#stringbuildertostring\n' + + '///\n' + + '@name(__tact_string_builder_end_slice)\n' + + 'extends native toString(self: StringBuilder): String;\n' + + '\n' + + '/// Extension function for the `StringBuilder` type.\n' + + '///\n' + + '/// Returns an assembled `Cell` as a `Slice` from a `StringBuilder`.\n' + + '/// An alias to `self.toCell().asSlice()`.\n' + + '///\n' + + '/// NOTE: **Gas expensive!** This function uses 500 gas units or more.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let s: StringBuilder = beginString();\n' + + '/// let fizz: Slice = s.toSlice();\n' + + '/// let buzz: Slice = s.toCell().asSlice();\n' + + '///\n' + + '/// fizz == buzz; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#stringbuildertoslice\n' + + '///\n' + + '@name(__tact_string_builder_end_slice)\n' + + 'extends native toSlice(self: StringBuilder): Slice;\n' + + '\n' + + '//\n' + + '// String conversion\n' + + '//\n' + + '\n' + + '/// Extension function for the `Int` type.\n' + + '///\n' + + '/// Returns a `String` from an `Int` value.\n' + + '///\n' + + '/// NOTE: **Gas expensive!** This function uses 500 gas units or more.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fizz: String = (84 - 42).toString();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#inttostring\n' + + '///\n' + + 'asm extends fun toString(self: Int): String {\n' + + ' // x\n' + + '\n' + + ' <{\n' + + ' // x\n' + + ' NEWC // x b\n' + + ' OVER // x b x\n' + + ' 0 LESSINT // x b <0?\n' + + ' <{\n' + + ' // x b\n' + + ' 45 PUSHINT // x b 45\n' + + ' SWAP // x 45 b\n' + + ' 8 STU // x b\n' + + ' SWAP // b x\n' + + ' NEGATE // b -x\n' + + ' SWAP // -x b\n' + + ' }>CONT IF\n' + + ' // x b\n' + + '\n' + + ' SWAP // b x\n' + + '\n' + + ' <{\n' + + ' // b x\n' + + ' 10 PUSHINT DIVMOD // b x/10 x%10\n' + + ' 48 ADDCONST // b x/10 (x%10+48)\n' + + ' s2 s2 s0 XC2PU ISZERO // (x%10+48) b x/10 x/10==0?\n' + + ' }>CONT UNTIL\n' + + ' // ... b x\n' + + '\n' + + ' DROP // ... b\n' + + ' DEPTH DEC // ... b n\n' + + ' <{ 8 STU }>CONT REPEAT // b\n' + + ' }>CONT 1 1 CALLXARGS\n' + + ' // b\n' + + '\n' + + ' ENDC CTOS // s\n' + + '}\n' + + '\n' + + '/// Extension function for the `Int` type.\n' + + '///\n' + + '/// Returns a `String` from an `Int` value using a [fixed-point representation] of a fractional\n' + + '/// number, where `self` is the significant part of the number and `digits` is the number\n' + + '/// of digits in the fractional part.\n' + + '///\n' + + '/// NOTE: **Gas expensive!** This function uses 500 gas units or more.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fizz: String = (42).toFloatString(9); // "0.000000042"\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 134: [Invalid argument] — Thrown when the given `digits` value is out of range.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#inttofloatstring\n' + + '///\n' + + '/// [fixed-point representation]: https://en.wikipedia.org/wiki/Fixed-point_arithmetic\n' + + '/// [Invalid argument]: https://docs.tact-lang.org/book/exit-codes#134\n' + + '///\n' + + 'asm extends fun toFloatString(self: Int, digits: Int): String {\n' + + ' // x digits\n' + + '\n' + + ' DUP // x digits digits\n' + + ' 1 LESSINT // x digits digits<=0\n' + + ' 134 THROWIF // x digits\n' + + ' DUP // x digits digits\n' + + ' 77 GTINT // x digits digits>77\n' + + ' 134 THROWIF // x digits\n' + + '\n' + + ' NEWC // x digits b\n' + + ' ROTREV // b x digits\n' + + ' s1 PUSH // b x digits x\n' + + ' 0 LESSINT // b x digits x<0?\n' + + '\n' + + ' <{\n' + + ' // b x digits\n' + + ' ROT // x digits b\n' + + ' x{2d} STSLICECONST // x digits b\n' + + ' ROT // digits b x\n' + + ' NEGATE // digits b -x\n' + + ' ROT // b -x digits\n' + + ' }>CONT IF\n' + + '\n' + + ' // b x digits\n' + + ' ONE // b x digits 1\n' + + ' OVER // b x digits 1 digits\n' + + '\n' + + ' <{ 10 MULCONST }>CONT REPEAT // b x digits 10^digits\n' + + '\n' + + ' s1 s2 XCHG // b digits x 10^digits\n' + + ' DIVMOD // b digits left right\n' + + ' s3 s3 XCHG2 // right digits b left\n' + + '\n' + + ' <{\n' + + ' // b x\n' + + '\n' + + ' <{\n' + + ' // b x\n' + + ' 10 PUSHINT DIVMOD // b x/10 x%10\n' + + ' 48 ADDCONST // b x/10 (x%10+48)\n' + + ' s2 s2 s0 XC2PU ISZERO // (x%10+48) b x/10 x/10==0?\n' + + ' }>CONT UNTIL\n' + + ' // ... b x\n' + + '\n' + + ' DROP // ... b\n' + + ' DEPTH DEC // ... b n\n' + + ' <{ 8 STU }>CONT REPEAT // b\n' + + ' }>CONT 2 1 CALLXARGS\n' + + '\n' + + ' // right digits "left"\n' + + '\n' + + ' ROT // digits "left" right\n' + + ' DUP // digits "left" right right\n' + + ' ISZERO // digits "left" right right==0?\n' + + '\n' + + ' <{\n' + + ' // digits "left" right\n' + + ' DROP // digits "left"\n' + + ' NIP // "left"\n' + + ' }>CONT\n' + + '\n' + + ' <{\n' + + ' // digits "left" right\n' + + ' ZERO // digits "left" right 0\n' + + ' SWAP // digits "left" 0 right\n' + + '\n' + + ' <{\n' + + ' // digits "left" i right\n' + + ' DUP // digits "left" i right right\n' + + ' 10 PUSHINT // digits "left" i right right 10\n' + + ' MOD // digits "left" i right right%10\n' + + ' ISZERO // digits "left" i right right%10==0?\n' + + ' }>CONT\n' + + '\n' + + ' <{\n' + + ' // digits "left" i right\n' + + ' 10 PUSHINT // digits "left" i right 10\n' + + ' DIV // digits "left" i right/10\n' + + ' SWAP // digits "left" right/10 i\n' + + ' INC // digits "left" right/10 i+1\n' + + ' SWAP // digits "left" i+1 right/10\n' + + ' }>CONT\n' + + '\n' + + ' WHILE // digits "left" i right\n' + + '\n' + + ' <{\n' + + ' // x\n' + + ' NEWC // x b\n' + + ' SWAP // b x\n' + + '\n' + + ' <{\n' + + ' // b x\n' + + ' 10 PUSHINT DIVMOD // b x/10 x%10\n' + + ' 48 ADDCONST // b x/10 (x%10+48)\n' + + ' s2 s2 s0 XC2PU ISZERO // (x%10+48) b x/10 x/10==0?\n' + + ' }>CONT UNTIL\n' + + ' // ... b x\n' + + '\n' + + ' DROP // ... b\n' + + ' DEPTH DEC DUP // ... b n n\n' + + ' ROTREV // ... n b n\n' + + ' <{\n' + + ' // ... c n b\n' + + ' s1 s2 XCHG // ... n c b\n' + + ' 8 STU // ... n b\n' + + ' }>CONT REPEAT // n b\n' + + ' }>CONT 1 2 CALLXARGS\n' + + ' // digits "left" i right_digits "right"\n' + + ' ROTREV // digits "left" "right" i right_digits\n' + + ' ADD // digits "left" "right" right_digits\n' + + '\n' + + ' s3 s1 XCHG // "right" "left" digits right_digits\n' + + ' SUB // "right" "left" digits_diff\n' + + ' SWAP // "right" digits_diff "left"\n' + + ' x{2e} STSLICECONST // "right" digits_diff "left."\n' + + ' SWAP // "right" "left." digits_diff\n' + + '\n' + + ' <{\n' + + ' // "right" "left."\n' + + ' x{30} STSLICECONST // "right" "left.0"\n' + + ' }>CONT REPEAT // "right" "left.000"\n' + + '\n' + + ' STB // "left.000right"\n' + + ' }>CONT\n' + + '\n' + + ' IFELSE // b\n' + + '\n' + + ' ENDC CTOS // s\n' + + '}\n' + + '\n' + + '/// Extension function for the `Int` type.\n' + + '///\n' + + '/// Returns a `String` from an `Int` value using a [fixed-point representatio'... 6219 more characters, + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'beginString', + loc: { start: 329, end: 340 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 344, end: 357 } + }, + typeArgs: [], + loc: { start: 344, end: 357 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_string_builder_start_string', + loc: { start: 286, end: 320 } + } + }, + loc: { start: 280, end: 358 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'beginComment', + loc: { start: 830, end: 842 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 846, end: 859 } + }, + typeArgs: [], + loc: { start: 846, end: 859 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_string_builder_start_comment', + loc: { start: 786, end: 821 } + } + }, + loc: { start: 780, end: 860 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'beginTailString', + loc: { start: 1341, end: 1356 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 1360, end: 1373 } + }, + typeArgs: [], + loc: { start: 1360, end: 1373 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_string_builder_start_tail_string', + loc: { start: 1293, end: 1332 } + } + }, + loc: { start: 1287, end: 1374 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'beginStringFromBuilder', + loc: { start: 1836, end: 1858 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 1872, end: 1885 } + }, + typeArgs: [], + loc: { start: 1872, end: 1885 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'b', + loc: { start: 1859, end: 1860 } + }, + type: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 1862, end: 1869 } }, + loc: { start: 1862, end: 1869 } + }, + loc: { start: 1859, end: 1869 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_string_builder_start', + loc: { start: 1800, end: 1827 } + } + }, + loc: { start: 1794, end: 1886 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'append', + loc: { start: 2328, end: 2334 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 's', + loc: { start: 2356, end: 2357 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 2359, end: 2365 } + }, + typeArgs: [], + loc: { start: 2359, end: 2365 } + }, + loc: { start: 2356, end: 2365 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_string_builder_append', + loc: { start: 2275, end: 2303 } + } + }, + loc: { start: 2269, end: 2367 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 2341, end: 2354 } + }, + typeArgs: [], + loc: { start: 2341, end: 2354 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'concat', + loc: { start: 2880, end: 2886 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 2920, end: 2933 } + }, + typeArgs: [], + loc: { start: 2920, end: 2933 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 's', + loc: { start: 2908, end: 2909 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 2911, end: 2917 } + }, + typeArgs: [], + loc: { start: 2911, end: 2917 } + }, + loc: { start: 2908, end: 2917 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_string_builder_append_not_mut', + loc: { start: 2827, end: 2863 } + } + }, + loc: { start: 2821, end: 2934 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 2893, end: 2906 } + }, + typeArgs: [], + loc: { start: 2893, end: 2906 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'toCell', + loc: { start: 3392, end: 3398 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3421, end: 3425 } }, + loc: { start: 3421, end: 3425 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_string_builder_end', + loc: { start: 3350, end: 3375 } + } + }, + loc: { start: 3344, end: 3426 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 3405, end: 3418 } + }, + typeArgs: [], + loc: { start: 3405, end: 3418 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'toString', + loc: { start: 3893, end: 3901 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 3924, end: 3930 } + }, + typeArgs: [], + loc: { start: 3924, end: 3930 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_string_builder_end_slice', + loc: { start: 3845, end: 3876 } + } + }, + loc: { start: 3839, end: 3931 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 3908, end: 3921 } + }, + typeArgs: [], + loc: { start: 3908, end: 3921 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'toSlice', + loc: { start: 4530, end: 4537 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 4560, end: 4565 } }, + loc: { start: 4560, end: 4565 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_string_builder_end_slice', + loc: { start: 4482, end: 4513 } + } + }, + loc: { start: 4476, end: 4566 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 4544, end: 4557 } + }, + typeArgs: [], + loc: { start: 4544, end: 4557 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'toString', + loc: { start: 4950, end: 4958 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 4971, end: 4977 } + }, + typeArgs: [], + loc: { start: 4971, end: 4977 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '<{\n' + + ' // x\n' + + ' NEWC // x b\n' + + ' OVER // x b x\n' + + ' 0 LESSINT // x b <0?\n' + + ' <{\n' + + ' // x b\n' + + ' 45 PUSHINT // x b 45\n' + + ' SWAP // x 45 b\n' + + ' 8 STU // x b\n' + + ' SWAP // b x\n' + + ' NEGATE // b -x\n' + + ' SWAP // -x b\n' + + ' }>CONT IF\n' + + ' // x b\n' + + '\n' + + ' SWAP // b x\n' + + '\n' + + ' <{\n' + + ' // b x\n' + + ' 10 PUSHINT DIVMOD // b x/10 x%10\n' + + ' 48 ADDCONST // b x/10 (x%10+48)\n' + + ' s2 s2 s0 XC2PU ISZERO // (x%10+48) b x/10 x/10==0?\n' + + ' }>CONT UNTIL\n' + + ' // ... b x\n' + + '\n' + + ' DROP // ... b\n' + + ' DEPTH DEC // ... b n\n' + + ' <{ 8 STU }>CONT REPEAT // b\n' + + ' }>CONT 1 1 CALLXARGS\n' + + ' // b\n' + + '\n' + + ' ENDC CTOS // s' + ] + }, + loc: { start: 4934, end: 5692 } + } + }, + selfType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4965, end: 4968 } + }, + loc: { start: 4965, end: 4968 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'toFloatString', + loc: { start: 6527, end: 6540 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 6566, end: 6572 } + }, + typeArgs: [], + loc: { start: 6566, end: 6572 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'digits', + loc: { start: 6552, end: 6558 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6560, end: 6563 } + }, + loc: { start: 6560, end: 6563 } + }, + loc: { start: 6552, end: 6563 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'DUP // x digits digits\n' + + ' 1 LESSINT // x digits digits<=0\n' + + ' 134 THROWIF // x digits\n' + + ' DUP // x digits digits\n' + + ' 77 GTINT // x digits digits>77\n' + + ' 134 THROWIF // x digits\n' + + '\n' + + ' NEWC // x digits b\n' + + ' ROTREV // b x digits\n' + + ' s1 PUSH // b x digits x\n' + + ' 0 LESSINT // b x digits x<0?\n' + + '\n' + + ' <{\n' + + ' // b x digits\n' + + ' ROT // x digits b\n' + + ' x{2d} STSLICECONST // x digits b\n' + + ' ROT // digits b x\n' + + ' NEGATE // digits b -x\n' + + ' ROT // b -x digits\n' + + ' }>CONT IF\n' + + '\n' + + ' // b x digits\n' + + ' ONE // b x digits 1\n' + + ' OVER // b x digits 1 digits\n' + + '\n' + + ' <{ 10 MULCONST }>CONT REPEAT // b x digits 10^digits\n' + + '\n' + + ' s1 s2 XCHG // b digits x 10^digits\n' + + ' DIVMOD // b digits left right\n' + + ' s3 s3 XCHG2 // right digits b left\n' + + '\n' + + ' <{\n' + + ' // b x\n' + + '\n' + + ' <{\n' + + ' // b x\n' + + ' 10 PUSHINT DIVMOD // b x/10 x%10\n' + + ' 48 ADDCONST // b x/10 (x%10+48)\n' + + ' s2 s2 s0 XC2PU ISZERO // (x%10+48) b x/10 x/10==0?\n' + + ' }>CONT UNTIL\n' + + ' // ... b x\n' + + '\n' + + ' DROP // ... b\n' + + ' DEPTH DEC // ... b n\n' + + ' <{ 8 STU }>CONT REPEAT // b\n' + + ' }>CONT 2 1 CALLXARGS\n' + + '\n' + + ' // right digits "left"\n' + + '\n' + + ' ROT // digits "left" right\n' + + ' DUP // digits "left" right right\n' + + ' ISZERO // digits "left" right right==0?\n' + + '\n' + + ' <{\n' + + ' // digits "left" right\n' + + ' DROP // digits "left"\n' + + ' NIP // "left"\n' + + ' }>CONT\n' + + '\n' + + ' <{\n' + + ' // digits "left" right\n' + + ' ZERO // digits "left" right 0\n' + + ' SWAP // digits "left" 0 right\n' + + '\n' + + ' <{\n' + + ' // digits "left" i right\n' + + ' DUP // digits "left" i right right\n' + + ' 10 PUSHINT // digits "left" i right right 10\n' + + ' MOD // digits "left" i right right%10\n' + + ' ISZERO // digits "left" i right right%10==0?\n' + + ' }>CONT\n' + + '\n' + + ' <{\n' + + ' // digits "left" i right\n' + + ' 10 PUSHINT // digits "left" i right 10\n' + + ' DIV // digits "left" i right/10\n' + + ' SWAP // digits "left" right/10 i\n' + + ' INC // digits "left" right/10 i+1\n' + + ' SWAP // digits "left" i+1 right/10\n' + + ' }>CONT\n' + + '\n' + + ' WHILE // digits "left" i right\n' + + '\n' + + ' <{\n' + + ' // x\n' + + ' NEWC // x b\n' + + ' SWAP // b x\n' + + '\n' + + ' <{\n' + + ' // b x\n' + + ' 10 PUSHINT DIVMOD // b x/10 x%10\n' + + ' 48 ADDCONST // b x/10 (x%10+48)\n' + + ' s2 s2 s0 XC2PU ISZERO // (x%10+48) b x/10 x/10==0?\n' + + ' }>CONT UNTIL\n' + + ' // ... b x\n' + + '\n' + + ' DROP // ... b\n' + + ' DEPTH DEC DUP // ... b n n\n' + + ' ROTREV // ... n b n\n' + + ' <{\n' + + ' // ... c n b\n' + + ' s1 s2 XCHG // ... n c b\n' + + ' 8 STU // ... n b\n' + + ' }>CONT REPEAT // n b\n' + + ' }>CONT 1 2 CALLXARGS\n' + + ' // digits "left" i right_digits "right"\n' + + ' ROTREV // digits "left" "right" i right_digits\n' + + ' ADD // digits "left" "right" right_digits\n' + + '\n' + + ' s3 s1 XCHG // "right" "left" digits right_digits\n' + + ' SUB // "right" "left" digits_diff\n' + + ' SWAP // "right" digits_diff "left"\n' + + ' x{2e} STSLICECONST // "right" digits_diff "left."\n' + + ' SWAP // "right" "left." digits_diff\n' + + '\n' + + ' <{\n' + + ' // "right" "left."\n' + + ' x{30} STSLICECONST // "right" "left.0"\n' + + ' }>CONT REPEAT // "right" "left.000"\n' + + '\n' + + ' STB // "left.000right"\n' + + ' }>CONT\n' + + '\n' + + ' IFELSE // b\n' + + '\n' + + ' ENDC CTOS // s' + ] + }, + loc: { start: 6511, end: 9874 } + } + }, + selfType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6547, end: 6550 } + }, + loc: { start: 6547, end: 6550 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'toCoinsString', + loc: { start: 10653, end: 10666 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 10679, end: 10685 } + }, + typeArgs: [], + loc: { start: 10679, end: 10685 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 10699, end: 10703 } + }, + method: { + kind: 'id', + text: 'toFloatString', + loc: { start: 10704, end: 10717 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 9n, + loc: { start: 10718, end: 10719 } + } + ], + loc: { start: 10699, end: 10720 } + }, + loc: { start: 10692, end: 10721 } + } + ] + }, + loc: { start: 10634, end: 10723 } + } + }, + selfType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10673, end: 10676 } + }, + loc: { start: 10673, end: 10676 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'asComment', + loc: { start: 11442, end: 11451 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 11467, end: 11471 } + }, + loc: { start: 11467, end: 11471 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'b', + loc: { start: 11482, end: 11483 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 11485, end: 11498 } + }, + typeArgs: [], + loc: { start: 11485, end: 11498 } + }, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'beginComment', + loc: { start: 11501, end: 11513 } + }, + typeArgs: [], + args: [], + loc: { start: 11501, end: 11515 } + }, + loc: { start: 11478, end: 11516 } + }, + { + kind: 'statement_expression', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'b', + loc: { start: 11521, end: 11522 } + }, + method: { + kind: 'id', + text: 'append', + loc: { start: 11523, end: 11529 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'self', + loc: { start: 11530, end: 11534 } + } + ], + loc: { start: 11521, end: 11535 } + }, + loc: { start: 11521, end: 11536 } + }, + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'b', + loc: { start: 11548, end: 11549 } + }, + method: { + kind: 'id', + text: 'toCell', + loc: { start: 11550, end: 11556 } + }, + typeArgs: [], + args: [], + loc: { start: 11548, end: 11558 } + }, + loc: { start: 11541, end: 11559 } + } + ] + }, + loc: { start: 11430, end: 11561 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 11458, end: 11464 } + }, + typeArgs: [], + loc: { start: 11458, end: 11464 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'asSlice', + loc: { start: 12075, end: 12082 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 12098, end: 12103 } + }, + loc: { start: 12098, end: 12103 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_str_to_slice', + loc: { start: 12039, end: 12058 } + } + }, + loc: { start: 12033, end: 12104 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 12089, end: 12095 } + }, + typeArgs: [], + loc: { start: 12089, end: 12095 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'asString', + loc: { start: 12598, end: 12606 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 12621, end: 12627 } + }, + typeArgs: [], + loc: { start: 12621, end: 12627 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_slice_to_str', + loc: { start: 12562, end: 12581 } + } + }, + loc: { start: 12556, end: 12628 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 12613, end: 12618 } }, + loc: { start: 12613, end: 12618 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'fromBase64', + loc: { start: 13537, end: 13547 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 13563, end: 13568 } + }, + loc: { start: 13563, end: 13568 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 13582, end: 13586 } + }, + method: { + kind: 'id', + text: 'asSlice', + loc: { start: 13587, end: 13594 } + }, + typeArgs: [], + args: [], + loc: { start: 13582, end: 13596 } + }, + method: { + kind: 'id', + text: 'fromBase64', + loc: { start: 13597, end: 13607 } + }, + typeArgs: [], + args: [], + loc: { start: 13582, end: 13609 } + }, + loc: { start: 13575, end: 13610 } + } + ] + }, + loc: { start: 13518, end: 13612 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 13554, end: 13560 } + }, + typeArgs: [], + loc: { start: 13554, end: 13560 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'fromBase64', + loc: { start: 14642, end: 14652 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 14667, end: 14672 } + }, + loc: { start: 14667, end: 14672 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'size', + loc: { start: 14683, end: 14687 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14689, end: 14692 } + }, + loc: { start: 14689, end: 14692 } + }, + expression: { + kind: 'op_binary', + op: '/', + left: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 14695, end: 14699 } + }, + method: { + kind: 'id', + text: 'bits', + loc: { start: 14700, end: 14704 } + }, + typeArgs: [], + args: [], + loc: { start: 14695, end: 14706 } + }, + right: { + kind: 'number', + base: '10', + value: 8n, + loc: { start: 14709, end: 14710 } + }, + loc: { start: 14695, end: 14710 } + }, + loc: { start: 14679, end: 14711 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'result', + loc: { start: 14720, end: 14726 } + }, + type: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 14728, end: 14735 } + }, + loc: { start: 14728, end: 14735 } + }, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'beginCell', + loc: { start: 14738, end: 14747 } + }, + typeArgs: [], + args: [], + loc: { start: 14738, end: 14749 } + }, + loc: { start: 14716, end: 14750 } + }, + { + kind: 'statement_repeat', + iterations: { + kind: 'var', + name: 'size', + loc: { start: 14764, end: 14768 } + }, + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'code', + loc: { start: 14784, end: 14788 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14790, end: 14793 } + }, + loc: { start: 14790, end: 14793 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 14796, end: 14800 } + }, + method: { + kind: 'id', + text: 'loadUint', + loc: { start: 14801, end: 14809 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 8n, + loc: { start: 14810, end: 14811 } + } + ], + loc: { start: 14796, end: 14812 } + }, + loc: { start: 14780, end: 14813 } + }, + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '&&', + left: { + kind: 'op_binary', + op: '>=', + left: { + kind: 'var', + name: 'code', + loc: { start: 14826, end: 14830 } + }, + right: { + kind: 'number', + base: '10', + value: 65n, + loc: { start: 14834, end: 14836 } + }, + loc: { start: 14826, end: 14836 } + }, + right: { + kind: 'op_binary', + op: '<=', + left: { + kind: 'var', + name: 'code', + loc: { start: 14840, end: 14844 } + }, + right: { + kind: 'number', + base: '10', + value: 90n, + loc: { start: 14848, end: 14850 } + }, + loc: { start: 14840, end: 14850 } + }, + loc: { start: 14826, end: 14850 } + }, + trueStatements: [ + { + kind: 'statement_assign', + path: { + kind: 'var', + name: 'result', + loc: { start: 14873, end: 14879 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'result', + loc: { start: 14882, end: 14888 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 14889, end: 14898 } + }, + typeArgs: [], + args: [ + { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'code', + loc: { start: 14899, end: 14903 } + }, + right: { + kind: 'number', + base: '10', + value: 65n, + loc: { start: 14906, end: 14908 } + }, + loc: { start: 14899, end: 14908 } + }, + { + kind: 'number', + base: '10', + value: 6n, + loc: { start: 14910, end: 14911 } + } + ], + loc: { start: 14882, end: 14912 } + }, + loc: { start: 14873, end: 14913 } + } + ], + falseStatements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '&&', + left: { + kind: 'op_binary', + op: '>=', + left: { + kind: 'var', + name: 'code', + loc: { start: 14933, end: 14937 } + }, + right: { + kind: 'number', + base: '10', + value: 97n, + loc: { start: 14941, end: 14943 } + }, + loc: { start: 14933, end: 14943 } + }, + right: { + kind: 'op_binary', + op: '<=', + left: { + kind: 'var', + name: 'code', + loc: { start: 14947, end: 14951 } + }, + right: { + kind: 'number', + base: '10', + value: 122n, + loc: { start: 14955, end: 14958 } + }, + loc: { start: 14947, end: 14958 } + }, + loc: { start: 14933, end: 14958 } + }, + trueStatements: [ + { + kind: 'statement_assign', + path: { + kind: 'var', + name: 'result', + loc: { start: 14981, end: 14987 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'result', + loc: { start: 14990, end: 14996 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 14997, end: 15006 } + }, + typeArgs: [], + args: [ + { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'code', + loc: { start: 15007, end: 15011 } + }, + right: { + kind: 'op_binary', + op: '-', + left: { + kind: 'number', + base: '10', + value: 97n, + loc: { start: 15015, end: 15017 } + }, + right: { + kind: 'number', + base: '10', + value: 26n, + loc: { start: 15020, end: 15022 } + }, + loc: { start: 15015, end: 15022 } + }, + loc: { start: 15007, end: 15023 } + }, + { + kind: 'number', + base: '10', + value: 6n, + loc: { start: 15025, end: 15026 } + } + ], + loc: { start: 14990, end: 15027 } + }, + loc: { start: 14981, end: 15028 } + } + ], + falseStatements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '&&', + left: { + kind: 'op_binary', + op: '>=', + left: { + kind: 'var', + name: 'code', + loc: { start: 15048, end: 15052 } + }, + right: { + kind: 'number', + base: '10', + value: 48n, + loc: { start: 15056, end: 15058 } + }, + loc: { start: 15048, end: 15058 } + }, + right: { + kind: 'op_binary', + op: '<=', + left: { + kind: 'var', + name: 'code', + loc: { start: 15062, end: 15066 } + }, + right: { + kind: 'number', + base: '10', + value: 57n, + loc: { start: 15070, end: 15072 } + }, + loc: { start: 15062, end: 15072 } + }, + loc: { start: 15048, end: 15072 } + }, + trueStatements: [ + { + kind: 'statement_assign', + path: { + kind: 'var', + name: 'result', + loc: { start: 15095, end: 15101 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'result', + loc: { start: 15104, end: 15110 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 15111, end: 15120 } + }, + typeArgs: [], + args: [ + { + kind: 'op_binary', + op: '+', + left: { + kind: 'var', + name: 'code', + loc: { + start: 15121, + end: 15125 + } + }, + right: { + kind: 'op_binary', + op: '-', + left: { + kind: 'number', + base: '10', + value: 52n, + loc: { + start: 15129, + end: 15131 + } + }, + right: { + kind: 'number', + base: '10', + value: 48n, + loc: { + start: 15134, + end: 15136 + } + }, + loc: { + start: 15129, + end: 15136 + } + }, + loc: { start: 15121, end: 15137 } + }, + { + kind: 'number', + base: '10', + value: 6n, + loc: { start: 15139, end: 15140 } + } + ], + loc: { start: 15104, end: 15141 } + }, + loc: { start: 15095, end: 15142 } + } + ], + falseStatements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '||', + left: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'code', + loc: { start: 15162, end: 15166 } + }, + right: { + kind: 'number', + base: '10', + value: 45n, + loc: { start: 15170, end: 15172 } + }, + loc: { start: 15162, end: 15172 } + }, + right: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'code', + loc: { start: 15176, end: 15180 } + }, + right: { + kind: 'number', + base: '10', + value: 43n, + loc: { start: 15184, end: 15186 } + }, + loc: { start: 15176, end: 15186 } + }, + loc: { start: 15162, end: 15186 } + }, + trueStatements: [ + { + kind: 'statement_assign', + path: { + kind: 'var', + name: 'result', + loc: { start: 15212, end: 15218 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'result', + loc: { + start: 15221, + end: 15227 + } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { + start: 15228, + end: 15237 + } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 62n, + loc: { + start: 15238, + end: 15240 + } + }, + { + kind: 'number', + base: '10', + value: 6n, + loc: { + start: 15242, + end: 15243 + } + } + ], + loc: { start: 15221, end: 15244 } + }, + loc: { start: 15212, end: 15245 } + } + ], + falseStatements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '||', + left: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'code', + loc: { + start: 15265, + end: 15269 + } + }, + right: { + kind: 'number', + base: '10', + value: 95n, + loc: { + start: 15273, + end: 15275 + } + }, + loc: { + start: 15265, + end: 15275 + } + }, + right: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'code', + loc: { + start: 15279, + end: 15283 + } + }, + right: { + kind: 'number', + base: '10', + value: 47n, + loc: { + start: 15287, + end: 15289 + } + }, + loc: { + start: 15279, + end: 15289 + } + }, + loc: { start: 15265, end: 15289 } + }, + trueStatements: [ + { + kind: 'statement_assign', + path: { + kind: 'var', + name: 'result', + loc: { + start: 15315, + end: 15321 + } + }, + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'result', + loc: { + start: 15324, + end: 15330 + } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { + start: 15331, + end: 15340 + } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 63n, + loc: { + start: 15341, + end: 15343 + } + }, + { + kind: 'number', + base: '10', + value: 6n, + loc: { + start: 15345, + end: 15346 + } + } + ], + loc: { + start: 15324, + end: 15347 + } + }, + loc: { + start: 15315, + end: 15348 + } + } + ], + falseStatements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'code', + loc: { + start: 15368, + end: 15372 + } + }, + right: { + kind: 'number', + base: '10', + value: 61n, + loc: { + start: 15376, + end: 15378 + } + }, + loc: { + start: 15368, + end: 15378 + } + }, + trueStatements: [], + falseStatements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throw', + loc: { + start: 15436, + end: 15441 + } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'TactExitCodeInvalidArgument', + loc: { + start: 15442, + end: 15469 + } + } + ], + loc: { + start: 15436, + end: 15470 + } + }, + loc: { + start: 15436, + end: 15471 + } + } + ], + loc: { + start: 15364, + end: 15481 + } + } + ], + loc: { start: 15261, end: 15481 } + } + ], + loc: { start: 15158, end: 15481 } + } + ], + loc: { start: 15044, end: 15481 } + } + ], + loc: { start: 14929, end: 15481 } + } + ], + loc: { start: 14822, end: 15481 } + } + ], + loc: { start: 14756, end: 15487 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'total', + loc: { start: 15512, end: 15517 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15519, end: 15522 } + }, + loc: { start: 15519, end: 15522 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'result', + loc: { start: 15525, end: 15531 } + }, + method: { + kind: 'id', + text: 'bits', + loc: { start: 15532, end: 15536 } + }, + typeArgs: [], + args: [], + loc: { start: 15525, end: 15538 } + }, + loc: { start: 15508, end: 15539 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'padding', + loc: { start: 15548, end: 15555 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15557, end: 15560 } + }, + loc: { start: 15557, end: 15560 } + }, + expression: { + kind: 'op_binary', + op: '%', + left: { + kind: 'var', + name: 'total', + loc: { start: 15563, end: 15568 } + }, + right: { + kind: 'number', + base: '10', + value: 8n, + loc: { start: 15571, end: 15572 } + }, + loc: { start: 15563, end: 15572 } + }, + loc: { start: 15544, end: 15573 } + }, + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '!=', + left: { + kind: 'var', + name: 'padding', + loc: { start: 15582, end: 15589 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15593, end: 15594 } + }, + loc: { start: 15582, end: 15594 } + }, + trueStatements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 's', + loc: { start: 15610, end: 15611 } + }, + type: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 15613, end: 15618 } + }, + loc: { start: 15613, end: 15618 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'result', + loc: { start: 15621, end: 15627 } + }, + method: { + kind: 'id', + text: 'asSlice', + loc: { start: 15628, end: 15635 } + }, + typeArgs: [], + args: [], + loc: { start: 15621, end: 15637 } + }, + loc: { start: 15606, end: 15638 } + }, + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 's', + loc: { start: 15654, end: 15655 } + }, + method: { + kind: 'id', + text: 'loadBits', + loc: { start: 15656, end: 15664 } + }, + typeArgs: [], + args: [ + { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'total', + loc: { start: 15665, end: 15670 } + }, + right: { + kind: 'var', + name: 'padding', + loc: { start: 15673, end: 15680 } + }, + loc: { start: 15665, end: 15680 } + } + ], + loc: { start: 15654, end: 15681 } + }, + loc: { start: 15647, end: 15682 } + } + ], + falseStatements: [ + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'result', + loc: { start: 15711, end: 15717 } + }, + method: { + kind: 'id', + text: 'asSlice', + loc: { start: 15718, end: 15725 } + }, + typeArgs: [], + args: [], + loc: { start: 15711, end: 15727 } + }, + loc: { start: 15704, end: 15728 } + } + ], + loc: { start: 15578, end: 15734 } + } + ] + }, + loc: { start: 14630, end: 15736 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 14659, end: 14664 } }, + loc: { start: 14659, end: 14664 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'toString', + loc: { start: 16186, end: 16194 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 16211, end: 16217 } + }, + typeArgs: [], + loc: { start: 16211, end: 16217 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_address_to_user_friendly', + loc: { start: 16138, end: 16169 } + } + }, + loc: { start: 16132, end: 16218 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 16201, end: 16208 } + }, + typeArgs: [], + loc: { start: 16201, end: 16208 } + } + } + ] + }, + 'beginTailString' => { + kind: 'tact', + path: 'std/internal/text.tact', + code: '//\n' + + '// String builder\n' + + '//\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Creates and returns an empty `StringBuilder`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example(): String {\n' + + '/// let fizz: StringBuilder = beginString();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#beginstring\n' + + '///\n' + + '@name(__tact_string_builder_start_string)\n' + + 'native beginString(): StringBuilder;\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Creates and returns an empty `StringBuilder` for building a comment string, which prefixes\n' + + '/// the resulting `String` with four null bytes. This format is used for passing text comments\n' + + '/// as message bodies.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example(): String {\n' + + '/// let fizz: StringBuilder = beginComment();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#begincomment\n' + + '///\n' + + '@name(__tact_string_builder_start_comment)\n' + + 'native beginComment(): StringBuilder;\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Creates and returns an empty `StringBuilder` for building a tail string, which prefixes\n' + + '/// the resulting `String` with a single null byte. This format is used in various standards\n' + + '/// such as NFT or Jetton.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example(): String {\n' + + '/// let fizz: StringBuilder = beginTailString();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#begintailstring\n' + + '///\n' + + '@name(__tact_string_builder_start_tail_string)\n' + + 'native beginTailString(): StringBuilder;\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Creates and returns a new `StringBuilder` from an existing `StringBuilder` `b`. Useful when\n' + + '/// you need to serialize an existing `String` to a `Cell` along with other data.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example(): String {\n' + + '/// let fizz: StringBuilder = beginStringFromBuilder(beginString());\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#beginstringfrombuilder\n' + + '///\n' + + '@name(__tact_string_builder_start)\n' + + 'native beginStringFromBuilder(b: Builder): StringBuilder;\n' + + '\n' + + '/// Extension mutation function for the `StringBuilder` type.\n' + + '///\n' + + '/// Appends a `String` `s` to the `StringBuilder`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fizz: StringBuilder = beginString();\n' + + '/// fizz.append("oh");\n' + + '/// fizz.append("my");\n' + + '/// fizz.append("Tact!");\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#stringbuilderappend\n' + + '///\n' + + '@name(__tact_string_builder_append)\n' + + 'extends mutates native append(self: StringBuilder, s: String);\n' + + '\n' + + '/// Extension function for the `StringBuilder` type.\n' + + '///\n' + + '/// Returns a new `StringBuilder` after concatenating it with a `String` `s`. It can be chained,\n' + + '/// unlike `StringBuilder.append()`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fizz: StringBuilder = beginString()\n' + + '/// .concat("oh")\n' + + '/// .concat("my")\n' + + '/// .concat("Tact!");\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#stringbuilderconcat\n' + + '///\n' + + '@name(__tact_string_builder_append_not_mut)\n' + + 'extends native concat(self: StringBuilder, s: String): StringBuilder;\n' + + '\n' + + '/// Extension function for the `StringBuilder` type.\n' + + '///\n' + + '/// Returns an assembled `Cell` from a `StringBuilder`.\n' + + '///\n' + + '/// NOTE: **Gas expensive!** This function uses 500 gas units or more.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fizz: StringBuilder = beginString();\n' + + '/// let buzz: Cell = fizz.toCell();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#stringbuildertocell\n' + + '///\n' + + '@name(__tact_string_builder_end)\n' + + 'extends native toCell(self: StringBuilder): Cell;\n' + + '\n' + + '/// Extension function for the `StringBuilder` type.\n' + + '///\n' + + '/// Returns a built `String` from a `StringBuilder`.\n' + + '///\n' + + '/// NOTE: **Gas expensive!** This function uses 500 gas units or more.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fizz: StringBuilder = beginString();\n' + + '/// let buzz: String = fizz.toString();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#stringbuildertostring\n' + + '///\n' + + '@name(__tact_string_builder_end_slice)\n' + + 'extends native toString(self: StringBuilder): String;\n' + + '\n' + + '/// Extension function for the `StringBuilder` type.\n' + + '///\n' + + '/// Returns an assembled `Cell` as a `Slice` from a `StringBuilder`.\n' + + '/// An alias to `self.toCell().asSlice()`.\n' + + '///\n' + + '/// NOTE: **Gas expensive!** This function uses 500 gas units or more.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let s: StringBuilder = beginString();\n' + + '/// let fizz: Slice = s.toSlice();\n' + + '/// let buzz: Slice = s.toCell().asSlice();\n' + + '///\n' + + '/// fizz == buzz; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#stringbuildertoslice\n' + + '///\n' + + '@name(__tact_string_builder_end_slice)\n' + + 'extends native toSlice(self: StringBuilder): Slice;\n' + + '\n' + + '//\n' + + '// String conversion\n' + + '//\n' + + '\n' + + '/// Extension function for the `Int` type.\n' + + '///\n' + + '/// Returns a `String` from an `Int` value.\n' + + '///\n' + + '/// NOTE: **Gas expensive!** This function uses 500 gas units or more.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fizz: String = (84 - 42).toString();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#inttostring\n' + + '///\n' + + 'asm extends fun toString(self: Int): String {\n' + + ' // x\n' + + '\n' + + ' <{\n' + + ' // x\n' + + ' NEWC // x b\n' + + ' OVER // x b x\n' + + ' 0 LESSINT // x b <0?\n' + + ' <{\n' + + ' // x b\n' + + ' 45 PUSHINT // x b 45\n' + + ' SWAP // x 45 b\n' + + ' 8 STU // x b\n' + + ' SWAP // b x\n' + + ' NEGATE // b -x\n' + + ' SWAP // -x b\n' + + ' }>CONT IF\n' + + ' // x b\n' + + '\n' + + ' SWAP // b x\n' + + '\n' + + ' <{\n' + + ' // b x\n' + + ' 10 PUSHINT DIVMOD // b x/10 x%10\n' + + ' 48 ADDCONST // b x/10 (x%10+48)\n' + + ' s2 s2 s0 XC2PU ISZERO // (x%10+48) b x/10 x/10==0?\n' + + ' }>CONT UNTIL\n' + + ' // ... b x\n' + + '\n' + + ' DROP // ... b\n' + + ' DEPTH DEC // ... b n\n' + + ' <{ 8 STU }>CONT REPEAT // b\n' + + ' }>CONT 1 1 CALLXARGS\n' + + ' // b\n' + + '\n' + + ' ENDC CTOS // s\n' + + '}\n' + + '\n' + + '/// Extension function for the `Int` type.\n' + + '///\n' + + '/// Returns a `String` from an `Int` value using a [fixed-point representation] of a fractional\n' + + '/// number, where `self` is the significant part of the number and `digits` is the number\n' + + '/// of digits in the fractional part.\n' + + '///\n' + + '/// NOTE: **Gas expensive!** This function uses 500 gas units or more.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fizz: String = (42).toFloatString(9); // "0.000000042"\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 134: [Invalid argument] — Thrown when the given `digits` value is out of range.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#inttofloatstring\n' + + '///\n' + + '/// [fixed-point representation]: https://en.wikipedia.org/wiki/Fixed-point_arithmetic\n' + + '/// [Invalid argument]: https://docs.tact-lang.org/book/exit-codes#134\n' + + '///\n' + + 'asm extends fun toFloatString(self: Int, digits: Int): String {\n' + + ' // x digits\n' + + '\n' + + ' DUP // x digits digits\n' + + ' 1 LESSINT // x digits digits<=0\n' + + ' 134 THROWIF // x digits\n' + + ' DUP // x digits digits\n' + + ' 77 GTINT // x digits digits>77\n' + + ' 134 THROWIF // x digits\n' + + '\n' + + ' NEWC // x digits b\n' + + ' ROTREV // b x digits\n' + + ' s1 PUSH // b x digits x\n' + + ' 0 LESSINT // b x digits x<0?\n' + + '\n' + + ' <{\n' + + ' // b x digits\n' + + ' ROT // x digits b\n' + + ' x{2d} STSLICECONST // x digits b\n' + + ' ROT // digits b x\n' + + ' NEGATE // digits b -x\n' + + ' ROT // b -x digits\n' + + ' }>CONT IF\n' + + '\n' + + ' // b x digits\n' + + ' ONE // b x digits 1\n' + + ' OVER // b x digits 1 digits\n' + + '\n' + + ' <{ 10 MULCONST }>CONT REPEAT // b x digits 10^digits\n' + + '\n' + + ' s1 s2 XCHG // b digits x 10^digits\n' + + ' DIVMOD // b digits left right\n' + + ' s3 s3 XCHG2 // right digits b left\n' + + '\n' + + ' <{\n' + + ' // b x\n' + + '\n' + + ' <{\n' + + ' // b x\n' + + ' 10 PUSHINT DIVMOD // b x/10 x%10\n' + + ' 48 ADDCONST // b x/10 (x%10+48)\n' + + ' s2 s2 s0 XC2PU ISZERO // (x%10+48) b x/10 x/10==0?\n' + + ' }>CONT UNTIL\n' + + ' // ... b x\n' + + '\n' + + ' DROP // ... b\n' + + ' DEPTH DEC // ... b n\n' + + ' <{ 8 STU }>CONT REPEAT // b\n' + + ' }>CONT 2 1 CALLXARGS\n' + + '\n' + + ' // right digits "left"\n' + + '\n' + + ' ROT // digits "left" right\n' + + ' DUP // digits "left" right right\n' + + ' ISZERO // digits "left" right right==0?\n' + + '\n' + + ' <{\n' + + ' // digits "left" right\n' + + ' DROP // digits "left"\n' + + ' NIP // "left"\n' + + ' }>CONT\n' + + '\n' + + ' <{\n' + + ' // digits "left" right\n' + + ' ZERO // digits "left" right 0\n' + + ' SWAP // digits "left" 0 right\n' + + '\n' + + ' <{\n' + + ' // digits "left" i right\n' + + ' DUP // digits "left" i right right\n' + + ' 10 PUSHINT // digits "left" i right right 10\n' + + ' MOD // digits "left" i right right%10\n' + + ' ISZERO // digits "left" i right right%10==0?\n' + + ' }>CONT\n' + + '\n' + + ' <{\n' + + ' // digits "left" i right\n' + + ' 10 PUSHINT // digits "left" i right 10\n' + + ' DIV // digits "left" i right/10\n' + + ' SWAP // digits "left" right/10 i\n' + + ' INC // digits "left" right/10 i+1\n' + + ' SWAP // digits "left" i+1 right/10\n' + + ' }>CONT\n' + + '\n' + + ' WHILE // digits "left" i right\n' + + '\n' + + ' <{\n' + + ' // x\n' + + ' NEWC // x b\n' + + ' SWAP // b x\n' + + '\n' + + ' <{\n' + + ' // b x\n' + + ' 10 PUSHINT DIVMOD // b x/10 x%10\n' + + ' 48 ADDCONST // b x/10 (x%10+48)\n' + + ' s2 s2 s0 XC2PU ISZERO // (x%10+48) b x/10 x/10==0?\n' + + ' }>CONT UNTIL\n' + + ' // ... b x\n' + + '\n' + + ' DROP // ... b\n' + + ' DEPTH DEC DUP // ... b n n\n' + + ' ROTREV // ... n b n\n' + + ' <{\n' + + ' // ... c n b\n' + + ' s1 s2 XCHG // ... n c b\n' + + ' 8 STU // ... n b\n' + + ' }>CONT REPEAT // n b\n' + + ' }>CONT 1 2 CALLXARGS\n' + + ' // digits "left" i right_digits "right"\n' + + ' ROTREV // digits "left" "right" i right_digits\n' + + ' ADD // digits "left" "right" right_digits\n' + + '\n' + + ' s3 s1 XCHG // "right" "left" digits right_digits\n' + + ' SUB // "right" "left" digits_diff\n' + + ' SWAP // "right" digits_diff "left"\n' + + ' x{2e} STSLICECONST // "right" digits_diff "left."\n' + + ' SWAP // "right" "left." digits_diff\n' + + '\n' + + ' <{\n' + + ' // "right" "left."\n' + + ' x{30} STSLICECONST // "right" "left.0"\n' + + ' }>CONT REPEAT // "right" "left.000"\n' + + '\n' + + ' STB // "left.000right"\n' + + ' }>CONT\n' + + '\n' + + ' IFELSE // b\n' + + '\n' + + ' ENDC CTOS // s\n' + + '}\n' + + '\n' + + '/// Extension function for the `Int` type.\n' + + '///\n' + + '/// Returns a `String` from an `Int` value using a [fixed-point representatio'... 6219 more characters, + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'beginString', + loc: { start: 329, end: 340 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 344, end: 357 } + }, + typeArgs: [], + loc: { start: 344, end: 357 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_string_builder_start_string', + loc: { start: 286, end: 320 } + } + }, + loc: { start: 280, end: 358 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'beginComment', + loc: { start: 830, end: 842 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 846, end: 859 } + }, + typeArgs: [], + loc: { start: 846, end: 859 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_string_builder_start_comment', + loc: { start: 786, end: 821 } + } + }, + loc: { start: 780, end: 860 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'beginTailString', + loc: { start: 1341, end: 1356 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 1360, end: 1373 } + }, + typeArgs: [], + loc: { start: 1360, end: 1373 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_string_builder_start_tail_string', + loc: { start: 1293, end: 1332 } + } + }, + loc: { start: 1287, end: 1374 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'beginStringFromBuilder', + loc: { start: 1836, end: 1858 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 1872, end: 1885 } + }, + typeArgs: [], + loc: { start: 1872, end: 1885 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'b', + loc: { start: 1859, end: 1860 } + }, + type: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 1862, end: 1869 } }, + loc: { start: 1862, end: 1869 } + }, + loc: { start: 1859, end: 1869 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_string_builder_start', + loc: { start: 1800, end: 1827 } + } + }, + loc: { start: 1794, end: 1886 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'append', + loc: { start: 2328, end: 2334 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 's', + loc: { start: 2356, end: 2357 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 2359, end: 2365 } + }, + typeArgs: [], + loc: { start: 2359, end: 2365 } + }, + loc: { start: 2356, end: 2365 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_string_builder_append', + loc: { start: 2275, end: 2303 } + } + }, + loc: { start: 2269, end: 2367 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 2341, end: 2354 } + }, + typeArgs: [], + loc: { start: 2341, end: 2354 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'concat', + loc: { start: 2880, end: 2886 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 2920, end: 2933 } + }, + typeArgs: [], + loc: { start: 2920, end: 2933 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 's', + loc: { start: 2908, end: 2909 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 2911, end: 2917 } + }, + typeArgs: [], + loc: { start: 2911, end: 2917 } + }, + loc: { start: 2908, end: 2917 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_string_builder_append_not_mut', + loc: { start: 2827, end: 2863 } + } + }, + loc: { start: 2821, end: 2934 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 2893, end: 2906 } + }, + typeArgs: [], + loc: { start: 2893, end: 2906 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'toCell', + loc: { start: 3392, end: 3398 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3421, end: 3425 } }, + loc: { start: 3421, end: 3425 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_string_builder_end', + loc: { start: 3350, end: 3375 } + } + }, + loc: { start: 3344, end: 3426 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 3405, end: 3418 } + }, + typeArgs: [], + loc: { start: 3405, end: 3418 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'toString', + loc: { start: 3893, end: 3901 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 3924, end: 3930 } + }, + typeArgs: [], + loc: { start: 3924, end: 3930 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_string_builder_end_slice', + loc: { start: 3845, end: 3876 } + } + }, + loc: { start: 3839, end: 3931 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 3908, end: 3921 } + }, + typeArgs: [], + loc: { start: 3908, end: 3921 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'toSlice', + loc: { start: 4530, end: 4537 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 4560, end: 4565 } }, + loc: { start: 4560, end: 4565 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_string_builder_end_slice', + loc: { start: 4482, end: 4513 } + } + }, + loc: { start: 4476, end: 4566 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 4544, end: 4557 } + }, + typeArgs: [], + loc: { start: 4544, end: 4557 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'toString', + loc: { start: 4950, end: 4958 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 4971, end: 4977 } + }, + typeArgs: [], + loc: { start: 4971, end: 4977 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '<{\n' + + ' // x\n' + + ' NEWC // x b\n' + + ' OVER // x b x\n' + + ' 0 LESSINT // x b <0?\n' + + ' <{\n' + + ' // x b\n' + + ' 45 PUSHINT // x b 45\n' + + ' SWAP // x 45 b\n' + + ' 8 STU // x b\n' + + ' SWAP // b x\n' + + ' NEGATE // b -x\n' + + ' SWAP // -x b\n' + + ' }>CONT IF\n' + + ' // x b\n' + + '\n' + + ' SWAP // b x\n' + + '\n' + + ' <{\n' + + ' // b x\n' + + ' 10 PUSHINT DIVMOD // b x/10 x%10\n' + + ' 48 ADDCONST // b x/10 (x%10+48)\n' + + ' s2 s2 s0 XC2PU ISZERO // (x%10+48) b x/10 x/10==0?\n' + + ' }>CONT UNTIL\n' + + ' // ... b x\n' + + '\n' + + ' DROP // ... b\n' + + ' DEPTH DEC // ... b n\n' + + ' <{ 8 STU }>CONT REPEAT // b\n' + + ' }>CONT 1 1 CALLXARGS\n' + + ' // b\n' + + '\n' + + ' ENDC CTOS // s' + ] + }, + loc: { start: 4934, end: 5692 } + } + }, + selfType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4965, end: 4968 } + }, + loc: { start: 4965, end: 4968 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'toFloatString', + loc: { start: 6527, end: 6540 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 6566, end: 6572 } + }, + typeArgs: [], + loc: { start: 6566, end: 6572 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'digits', + loc: { start: 6552, end: 6558 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6560, end: 6563 } + }, + loc: { start: 6560, end: 6563 } + }, + loc: { start: 6552, end: 6563 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'DUP // x digits digits\n' + + ' 1 LESSINT // x digits digits<=0\n' + + ' 134 THROWIF // x digits\n' + + ' DUP // x digits digits\n' + + ' 77 GTINT // x digits digits>77\n' + + ' 134 THROWIF // x digits\n' + + '\n' + + ' NEWC // x digits b\n' + + ' ROTREV // b x digits\n' + + ' s1 PUSH // b x digits x\n' + + ' 0 LESSINT // b x digits x<0?\n' + + '\n' + + ' <{\n' + + ' // b x digits\n' + + ' ROT // x digits b\n' + + ' x{2d} STSLICECONST // x digits b\n' + + ' ROT // digits b x\n' + + ' NEGATE // digits b -x\n' + + ' ROT // b -x digits\n' + + ' }>CONT IF\n' + + '\n' + + ' // b x digits\n' + + ' ONE // b x digits 1\n' + + ' OVER // b x digits 1 digits\n' + + '\n' + + ' <{ 10 MULCONST }>CONT REPEAT // b x digits 10^digits\n' + + '\n' + + ' s1 s2 XCHG // b digits x 10^digits\n' + + ' DIVMOD // b digits left right\n' + + ' s3 s3 XCHG2 // right digits b left\n' + + '\n' + + ' <{\n' + + ' // b x\n' + + '\n' + + ' <{\n' + + ' // b x\n' + + ' 10 PUSHINT DIVMOD // b x/10 x%10\n' + + ' 48 ADDCONST // b x/10 (x%10+48)\n' + + ' s2 s2 s0 XC2PU ISZERO // (x%10+48) b x/10 x/10==0?\n' + + ' }>CONT UNTIL\n' + + ' // ... b x\n' + + '\n' + + ' DROP // ... b\n' + + ' DEPTH DEC // ... b n\n' + + ' <{ 8 STU }>CONT REPEAT // b\n' + + ' }>CONT 2 1 CALLXARGS\n' + + '\n' + + ' // right digits "left"\n' + + '\n' + + ' ROT // digits "left" right\n' + + ' DUP // digits "left" right right\n' + + ' ISZERO // digits "left" right right==0?\n' + + '\n' + + ' <{\n' + + ' // digits "left" right\n' + + ' DROP // digits "left"\n' + + ' NIP // "left"\n' + + ' }>CONT\n' + + '\n' + + ' <{\n' + + ' // digits "left" right\n' + + ' ZERO // digits "left" right 0\n' + + ' SWAP // digits "left" 0 right\n' + + '\n' + + ' <{\n' + + ' // digits "left" i right\n' + + ' DUP // digits "left" i right right\n' + + ' 10 PUSHINT // digits "left" i right right 10\n' + + ' MOD // digits "left" i right right%10\n' + + ' ISZERO // digits "left" i right right%10==0?\n' + + ' }>CONT\n' + + '\n' + + ' <{\n' + + ' // digits "left" i right\n' + + ' 10 PUSHINT // digits "left" i right 10\n' + + ' DIV // digits "left" i right/10\n' + + ' SWAP // digits "left" right/10 i\n' + + ' INC // digits "left" right/10 i+1\n' + + ' SWAP // digits "left" i+1 right/10\n' + + ' }>CONT\n' + + '\n' + + ' WHILE // digits "left" i right\n' + + '\n' + + ' <{\n' + + ' // x\n' + + ' NEWC // x b\n' + + ' SWAP // b x\n' + + '\n' + + ' <{\n' + + ' // b x\n' + + ' 10 PUSHINT DIVMOD // b x/10 x%10\n' + + ' 48 ADDCONST // b x/10 (x%10+48)\n' + + ' s2 s2 s0 XC2PU ISZERO // (x%10+48) b x/10 x/10==0?\n' + + ' }>CONT UNTIL\n' + + ' // ... b x\n' + + '\n' + + ' DROP // ... b\n' + + ' DEPTH DEC DUP // ... b n n\n' + + ' ROTREV // ... n b n\n' + + ' <{\n' + + ' // ... c n b\n' + + ' s1 s2 XCHG // ... n c b\n' + + ' 8 STU // ... n b\n' + + ' }>CONT REPEAT // n b\n' + + ' }>CONT 1 2 CALLXARGS\n' + + ' // digits "left" i right_digits "right"\n' + + ' ROTREV // digits "left" "right" i right_digits\n' + + ' ADD // digits "left" "right" right_digits\n' + + '\n' + + ' s3 s1 XCHG // "right" "left" digits right_digits\n' + + ' SUB // "right" "left" digits_diff\n' + + ' SWAP // "right" digits_diff "left"\n' + + ' x{2e} STSLICECONST // "right" digits_diff "left."\n' + + ' SWAP // "right" "left." digits_diff\n' + + '\n' + + ' <{\n' + + ' // "right" "left."\n' + + ' x{30} STSLICECONST // "right" "left.0"\n' + + ' }>CONT REPEAT // "right" "left.000"\n' + + '\n' + + ' STB // "left.000right"\n' + + ' }>CONT\n' + + '\n' + + ' IFELSE // b\n' + + '\n' + + ' ENDC CTOS // s' + ] + }, + loc: { start: 6511, end: 9874 } + } + }, + selfType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6547, end: 6550 } + }, + loc: { start: 6547, end: 6550 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'toCoinsString', + loc: { start: 10653, end: 10666 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 10679, end: 10685 } + }, + typeArgs: [], + loc: { start: 10679, end: 10685 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 10699, end: 10703 } + }, + method: { + kind: 'id', + text: 'toFloatString', + loc: { start: 10704, end: 10717 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 9n, + loc: { start: 10718, end: 10719 } + } + ], + loc: { start: 10699, end: 10720 } + }, + loc: { start: 10692, end: 10721 } + } + ] + }, + loc: { start: 10634, end: 10723 } + } + }, + selfType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10673, end: 10676 } + }, + loc: { start: 10673, end: 10676 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'asComment', + loc: { start: 11442, end: 11451 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 11467, end: 11471 } + }, + loc: { start: 11467, end: 11471 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'b', + loc: { start: 11482, end: 11483 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 11485, end: 11498 } + }, + typeArgs: [], + loc: { start: 11485, end: 11498 } + }, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'beginComment', + loc: { start: 11501, end: 11513 } + }, + typeArgs: [], + args: [], + loc: { start: 11501, end: 11515 } + }, + loc: { start: 11478, end: 11516 } + }, + { + kind: 'statement_expression', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'b', + loc: { start: 11521, end: 11522 } + }, + method: { + kind: 'id', + text: 'append', + loc: { start: 11523, end: 11529 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'self', + loc: { start: 11530, end: 11534 } + } + ], + loc: { start: 11521, end: 11535 } + }, + loc: { start: 11521, end: 11536 } + }, + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'b', + loc: { start: 11548, end: 11549 } + }, + method: { + kind: 'id', + text: 'toCell', + loc: { start: 11550, end: 11556 } + }, + typeArgs: [], + args: [], + loc: { start: 11548, end: 11558 } + }, + loc: { start: 11541, end: 11559 } + } + ] + }, + loc: { start: 11430, end: 11561 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 11458, end: 11464 } + }, + typeArgs: [], + loc: { start: 11458, end: 11464 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'asSlice', + loc: { start: 12075, end: 12082 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 12098, end: 12103 } + }, + loc: { start: 12098, end: 12103 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_str_to_slice', + loc: { start: 12039, end: 12058 } + } + }, + loc: { start: 12033, end: 12104 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 12089, end: 12095 } + }, + typeArgs: [], + loc: { start: 12089, end: 12095 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'asString', + loc: { start: 12598, end: 12606 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 12621, end: 12627 } + }, + typeArgs: [], + loc: { start: 12621, end: 12627 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_slice_to_str', + loc: { start: 12562, end: 12581 } + } + }, + loc: { start: 12556, end: 12628 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 12613, end: 12618 } }, + loc: { start: 12613, end: 12618 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'fromBase64', + loc: { start: 13537, end: 13547 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 13563, end: 13568 } + }, + loc: { start: 13563, end: 13568 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 13582, end: 13586 } + }, + method: { + kind: 'id', + text: 'asSlice', + loc: { start: 13587, end: 13594 } + }, + typeArgs: [], + args: [], + loc: { start: 13582, end: 13596 } + }, + method: { + kind: 'id', + text: 'fromBase64', + loc: { start: 13597, end: 13607 } + }, + typeArgs: [], + args: [], + loc: { start: 13582, end: 13609 } + }, + loc: { start: 13575, end: 13610 } + } + ] + }, + loc: { start: 13518, end: 13612 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 13554, end: 13560 } + }, + typeArgs: [], + loc: { start: 13554, end: 13560 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'fromBase64', + loc: { start: 14642, end: 14652 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 14667, end: 14672 } + }, + loc: { start: 14667, end: 14672 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'size', + loc: { start: 14683, end: 14687 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14689, end: 14692 } + }, + loc: { start: 14689, end: 14692 } + }, + expression: { + kind: 'op_binary', + op: '/', + left: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 14695, end: 14699 } + }, + method: { + kind: 'id', + text: 'bits', + loc: { start: 14700, end: 14704 } + }, + typeArgs: [], + args: [], + loc: { start: 14695, end: 14706 } + }, + right: { + kind: 'number', + base: '10', + value: 8n, + loc: { start: 14709, end: 14710 } + }, + loc: { start: 14695, end: 14710 } + }, + loc: { start: 14679, end: 14711 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'result', + loc: { start: 14720, end: 14726 } + }, + type: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 14728, end: 14735 } + }, + loc: { start: 14728, end: 14735 } + }, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'beginCell', + loc: { start: 14738, end: 14747 } + }, + typeArgs: [], + args: [], + loc: { start: 14738, end: 14749 } + }, + loc: { start: 14716, end: 14750 } + }, + { + kind: 'statement_repeat', + iterations: { + kind: 'var', + name: 'size', + loc: { start: 14764, end: 14768 } + }, + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'code', + loc: { start: 14784, end: 14788 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14790, end: 14793 } + }, + loc: { start: 14790, end: 14793 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 14796, end: 14800 } + }, + method: { + kind: 'id', + text: 'loadUint', + loc: { start: 14801, end: 14809 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 8n, + loc: { start: 14810, end: 14811 } + } + ], + loc: { start: 14796, end: 14812 } + }, + loc: { start: 14780, end: 14813 } + }, + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '&&', + left: { + kind: 'op_binary', + op: '>=', + left: { + kind: 'var', + name: 'code', + loc: { start: 14826, end: 14830 } + }, + right: { + kind: 'number', + base: '10', + value: 65n, + loc: { start: 14834, end: 14836 } + }, + loc: { start: 14826, end: 14836 } + }, + right: { + kind: 'op_binary', + op: '<=', + left: { + kind: 'var', + name: 'code', + loc: { start: 14840, end: 14844 } + }, + right: { + kind: 'number', + base: '10', + value: 90n, + loc: { start: 14848, end: 14850 } + }, + loc: { start: 14840, end: 14850 } + }, + loc: { start: 14826, end: 14850 } + }, + trueStatements: [ + { + kind: 'statement_assign', + path: { + kind: 'var', + name: 'result', + loc: { start: 14873, end: 14879 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'result', + loc: { start: 14882, end: 14888 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 14889, end: 14898 } + }, + typeArgs: [], + args: [ + { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'code', + loc: { start: 14899, end: 14903 } + }, + right: { + kind: 'number', + base: '10', + value: 65n, + loc: { start: 14906, end: 14908 } + }, + loc: { start: 14899, end: 14908 } + }, + { + kind: 'number', + base: '10', + value: 6n, + loc: { start: 14910, end: 14911 } + } + ], + loc: { start: 14882, end: 14912 } + }, + loc: { start: 14873, end: 14913 } + } + ], + falseStatements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '&&', + left: { + kind: 'op_binary', + op: '>=', + left: { + kind: 'var', + name: 'code', + loc: { start: 14933, end: 14937 } + }, + right: { + kind: 'number', + base: '10', + value: 97n, + loc: { start: 14941, end: 14943 } + }, + loc: { start: 14933, end: 14943 } + }, + right: { + kind: 'op_binary', + op: '<=', + left: { + kind: 'var', + name: 'code', + loc: { start: 14947, end: 14951 } + }, + right: { + kind: 'number', + base: '10', + value: 122n, + loc: { start: 14955, end: 14958 } + }, + loc: { start: 14947, end: 14958 } + }, + loc: { start: 14933, end: 14958 } + }, + trueStatements: [ + { + kind: 'statement_assign', + path: { + kind: 'var', + name: 'result', + loc: { start: 14981, end: 14987 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'result', + loc: { start: 14990, end: 14996 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 14997, end: 15006 } + }, + typeArgs: [], + args: [ + { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'code', + loc: { start: 15007, end: 15011 } + }, + right: { + kind: 'op_binary', + op: '-', + left: { + kind: 'number', + base: '10', + value: 97n, + loc: { start: 15015, end: 15017 } + }, + right: { + kind: 'number', + base: '10', + value: 26n, + loc: { start: 15020, end: 15022 } + }, + loc: { start: 15015, end: 15022 } + }, + loc: { start: 15007, end: 15023 } + }, + { + kind: 'number', + base: '10', + value: 6n, + loc: { start: 15025, end: 15026 } + } + ], + loc: { start: 14990, end: 15027 } + }, + loc: { start: 14981, end: 15028 } + } + ], + falseStatements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '&&', + left: { + kind: 'op_binary', + op: '>=', + left: { + kind: 'var', + name: 'code', + loc: { start: 15048, end: 15052 } + }, + right: { + kind: 'number', + base: '10', + value: 48n, + loc: { start: 15056, end: 15058 } + }, + loc: { start: 15048, end: 15058 } + }, + right: { + kind: 'op_binary', + op: '<=', + left: { + kind: 'var', + name: 'code', + loc: { start: 15062, end: 15066 } + }, + right: { + kind: 'number', + base: '10', + value: 57n, + loc: { start: 15070, end: 15072 } + }, + loc: { start: 15062, end: 15072 } + }, + loc: { start: 15048, end: 15072 } + }, + trueStatements: [ + { + kind: 'statement_assign', + path: { + kind: 'var', + name: 'result', + loc: { start: 15095, end: 15101 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'result', + loc: { start: 15104, end: 15110 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 15111, end: 15120 } + }, + typeArgs: [], + args: [ + { + kind: 'op_binary', + op: '+', + left: { + kind: 'var', + name: 'code', + loc: { + start: 15121, + end: 15125 + } + }, + right: { + kind: 'op_binary', + op: '-', + left: { + kind: 'number', + base: '10', + value: 52n, + loc: { + start: 15129, + end: 15131 + } + }, + right: { + kind: 'number', + base: '10', + value: 48n, + loc: { + start: 15134, + end: 15136 + } + }, + loc: { + start: 15129, + end: 15136 + } + }, + loc: { start: 15121, end: 15137 } + }, + { + kind: 'number', + base: '10', + value: 6n, + loc: { start: 15139, end: 15140 } + } + ], + loc: { start: 15104, end: 15141 } + }, + loc: { start: 15095, end: 15142 } + } + ], + falseStatements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '||', + left: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'code', + loc: { start: 15162, end: 15166 } + }, + right: { + kind: 'number', + base: '10', + value: 45n, + loc: { start: 15170, end: 15172 } + }, + loc: { start: 15162, end: 15172 } + }, + right: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'code', + loc: { start: 15176, end: 15180 } + }, + right: { + kind: 'number', + base: '10', + value: 43n, + loc: { start: 15184, end: 15186 } + }, + loc: { start: 15176, end: 15186 } + }, + loc: { start: 15162, end: 15186 } + }, + trueStatements: [ + { + kind: 'statement_assign', + path: { + kind: 'var', + name: 'result', + loc: { start: 15212, end: 15218 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'result', + loc: { + start: 15221, + end: 15227 + } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { + start: 15228, + end: 15237 + } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 62n, + loc: { + start: 15238, + end: 15240 + } + }, + { + kind: 'number', + base: '10', + value: 6n, + loc: { + start: 15242, + end: 15243 + } + } + ], + loc: { start: 15221, end: 15244 } + }, + loc: { start: 15212, end: 15245 } + } + ], + falseStatements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '||', + left: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'code', + loc: { + start: 15265, + end: 15269 + } + }, + right: { + kind: 'number', + base: '10', + value: 95n, + loc: { + start: 15273, + end: 15275 + } + }, + loc: { + start: 15265, + end: 15275 + } + }, + right: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'code', + loc: { + start: 15279, + end: 15283 + } + }, + right: { + kind: 'number', + base: '10', + value: 47n, + loc: { + start: 15287, + end: 15289 + } + }, + loc: { + start: 15279, + end: 15289 + } + }, + loc: { start: 15265, end: 15289 } + }, + trueStatements: [ + { + kind: 'statement_assign', + path: { + kind: 'var', + name: 'result', + loc: { + start: 15315, + end: 15321 + } + }, + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'result', + loc: { + start: 15324, + end: 15330 + } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { + start: 15331, + end: 15340 + } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 63n, + loc: { + start: 15341, + end: 15343 + } + }, + { + kind: 'number', + base: '10', + value: 6n, + loc: { + start: 15345, + end: 15346 + } + } + ], + loc: { + start: 15324, + end: 15347 + } + }, + loc: { + start: 15315, + end: 15348 + } + } + ], + falseStatements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'code', + loc: { + start: 15368, + end: 15372 + } + }, + right: { + kind: 'number', + base: '10', + value: 61n, + loc: { + start: 15376, + end: 15378 + } + }, + loc: { + start: 15368, + end: 15378 + } + }, + trueStatements: [], + falseStatements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throw', + loc: { + start: 15436, + end: 15441 + } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'TactExitCodeInvalidArgument', + loc: { + start: 15442, + end: 15469 + } + } + ], + loc: { + start: 15436, + end: 15470 + } + }, + loc: { + start: 15436, + end: 15471 + } + } + ], + loc: { + start: 15364, + end: 15481 + } + } + ], + loc: { start: 15261, end: 15481 } + } + ], + loc: { start: 15158, end: 15481 } + } + ], + loc: { start: 15044, end: 15481 } + } + ], + loc: { start: 14929, end: 15481 } + } + ], + loc: { start: 14822, end: 15481 } + } + ], + loc: { start: 14756, end: 15487 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'total', + loc: { start: 15512, end: 15517 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15519, end: 15522 } + }, + loc: { start: 15519, end: 15522 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'result', + loc: { start: 15525, end: 15531 } + }, + method: { + kind: 'id', + text: 'bits', + loc: { start: 15532, end: 15536 } + }, + typeArgs: [], + args: [], + loc: { start: 15525, end: 15538 } + }, + loc: { start: 15508, end: 15539 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'padding', + loc: { start: 15548, end: 15555 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15557, end: 15560 } + }, + loc: { start: 15557, end: 15560 } + }, + expression: { + kind: 'op_binary', + op: '%', + left: { + kind: 'var', + name: 'total', + loc: { start: 15563, end: 15568 } + }, + right: { + kind: 'number', + base: '10', + value: 8n, + loc: { start: 15571, end: 15572 } + }, + loc: { start: 15563, end: 15572 } + }, + loc: { start: 15544, end: 15573 } + }, + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '!=', + left: { + kind: 'var', + name: 'padding', + loc: { start: 15582, end: 15589 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15593, end: 15594 } + }, + loc: { start: 15582, end: 15594 } + }, + trueStatements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 's', + loc: { start: 15610, end: 15611 } + }, + type: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 15613, end: 15618 } + }, + loc: { start: 15613, end: 15618 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'result', + loc: { start: 15621, end: 15627 } + }, + method: { + kind: 'id', + text: 'asSlice', + loc: { start: 15628, end: 15635 } + }, + typeArgs: [], + args: [], + loc: { start: 15621, end: 15637 } + }, + loc: { start: 15606, end: 15638 } + }, + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 's', + loc: { start: 15654, end: 15655 } + }, + method: { + kind: 'id', + text: 'loadBits', + loc: { start: 15656, end: 15664 } + }, + typeArgs: [], + args: [ + { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'total', + loc: { start: 15665, end: 15670 } + }, + right: { + kind: 'var', + name: 'padding', + loc: { start: 15673, end: 15680 } + }, + loc: { start: 15665, end: 15680 } + } + ], + loc: { start: 15654, end: 15681 } + }, + loc: { start: 15647, end: 15682 } + } + ], + falseStatements: [ + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'result', + loc: { start: 15711, end: 15717 } + }, + method: { + kind: 'id', + text: 'asSlice', + loc: { start: 15718, end: 15725 } + }, + typeArgs: [], + args: [], + loc: { start: 15711, end: 15727 } + }, + loc: { start: 15704, end: 15728 } + } + ], + loc: { start: 15578, end: 15734 } + } + ] + }, + loc: { start: 14630, end: 15736 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 14659, end: 14664 } }, + loc: { start: 14659, end: 14664 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'toString', + loc: { start: 16186, end: 16194 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 16211, end: 16217 } + }, + typeArgs: [], + loc: { start: 16211, end: 16217 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_address_to_user_friendly', + loc: { start: 16138, end: 16169 } + } + }, + loc: { start: 16132, end: 16218 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 16201, end: 16208 } + }, + typeArgs: [], + loc: { start: 16201, end: 16208 } + } + } + ] + }, + 'beginStringFromBuilder' => { + kind: 'tact', + path: 'std/internal/text.tact', + code: '//\n' + + '// String builder\n' + + '//\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Creates and returns an empty `StringBuilder`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example(): String {\n' + + '/// let fizz: StringBuilder = beginString();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#beginstring\n' + + '///\n' + + '@name(__tact_string_builder_start_string)\n' + + 'native beginString(): StringBuilder;\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Creates and returns an empty `StringBuilder` for building a comment string, which prefixes\n' + + '/// the resulting `String` with four null bytes. This format is used for passing text comments\n' + + '/// as message bodies.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example(): String {\n' + + '/// let fizz: StringBuilder = beginComment();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#begincomment\n' + + '///\n' + + '@name(__tact_string_builder_start_comment)\n' + + 'native beginComment(): StringBuilder;\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Creates and returns an empty `StringBuilder` for building a tail string, which prefixes\n' + + '/// the resulting `String` with a single null byte. This format is used in various standards\n' + + '/// such as NFT or Jetton.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example(): String {\n' + + '/// let fizz: StringBuilder = beginTailString();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#begintailstring\n' + + '///\n' + + '@name(__tact_string_builder_start_tail_string)\n' + + 'native beginTailString(): StringBuilder;\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Creates and returns a new `StringBuilder` from an existing `StringBuilder` `b`. Useful when\n' + + '/// you need to serialize an existing `String` to a `Cell` along with other data.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example(): String {\n' + + '/// let fizz: StringBuilder = beginStringFromBuilder(beginString());\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#beginstringfrombuilder\n' + + '///\n' + + '@name(__tact_string_builder_start)\n' + + 'native beginStringFromBuilder(b: Builder): StringBuilder;\n' + + '\n' + + '/// Extension mutation function for the `StringBuilder` type.\n' + + '///\n' + + '/// Appends a `String` `s` to the `StringBuilder`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fizz: StringBuilder = beginString();\n' + + '/// fizz.append("oh");\n' + + '/// fizz.append("my");\n' + + '/// fizz.append("Tact!");\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#stringbuilderappend\n' + + '///\n' + + '@name(__tact_string_builder_append)\n' + + 'extends mutates native append(self: StringBuilder, s: String);\n' + + '\n' + + '/// Extension function for the `StringBuilder` type.\n' + + '///\n' + + '/// Returns a new `StringBuilder` after concatenating it with a `String` `s`. It can be chained,\n' + + '/// unlike `StringBuilder.append()`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fizz: StringBuilder = beginString()\n' + + '/// .concat("oh")\n' + + '/// .concat("my")\n' + + '/// .concat("Tact!");\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#stringbuilderconcat\n' + + '///\n' + + '@name(__tact_string_builder_append_not_mut)\n' + + 'extends native concat(self: StringBuilder, s: String): StringBuilder;\n' + + '\n' + + '/// Extension function for the `StringBuilder` type.\n' + + '///\n' + + '/// Returns an assembled `Cell` from a `StringBuilder`.\n' + + '///\n' + + '/// NOTE: **Gas expensive!** This function uses 500 gas units or more.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fizz: StringBuilder = beginString();\n' + + '/// let buzz: Cell = fizz.toCell();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#stringbuildertocell\n' + + '///\n' + + '@name(__tact_string_builder_end)\n' + + 'extends native toCell(self: StringBuilder): Cell;\n' + + '\n' + + '/// Extension function for the `StringBuilder` type.\n' + + '///\n' + + '/// Returns a built `String` from a `StringBuilder`.\n' + + '///\n' + + '/// NOTE: **Gas expensive!** This function uses 500 gas units or more.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fizz: StringBuilder = beginString();\n' + + '/// let buzz: String = fizz.toString();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#stringbuildertostring\n' + + '///\n' + + '@name(__tact_string_builder_end_slice)\n' + + 'extends native toString(self: StringBuilder): String;\n' + + '\n' + + '/// Extension function for the `StringBuilder` type.\n' + + '///\n' + + '/// Returns an assembled `Cell` as a `Slice` from a `StringBuilder`.\n' + + '/// An alias to `self.toCell().asSlice()`.\n' + + '///\n' + + '/// NOTE: **Gas expensive!** This function uses 500 gas units or more.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let s: StringBuilder = beginString();\n' + + '/// let fizz: Slice = s.toSlice();\n' + + '/// let buzz: Slice = s.toCell().asSlice();\n' + + '///\n' + + '/// fizz == buzz; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#stringbuildertoslice\n' + + '///\n' + + '@name(__tact_string_builder_end_slice)\n' + + 'extends native toSlice(self: StringBuilder): Slice;\n' + + '\n' + + '//\n' + + '// String conversion\n' + + '//\n' + + '\n' + + '/// Extension function for the `Int` type.\n' + + '///\n' + + '/// Returns a `String` from an `Int` value.\n' + + '///\n' + + '/// NOTE: **Gas expensive!** This function uses 500 gas units or more.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fizz: String = (84 - 42).toString();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#inttostring\n' + + '///\n' + + 'asm extends fun toString(self: Int): String {\n' + + ' // x\n' + + '\n' + + ' <{\n' + + ' // x\n' + + ' NEWC // x b\n' + + ' OVER // x b x\n' + + ' 0 LESSINT // x b <0?\n' + + ' <{\n' + + ' // x b\n' + + ' 45 PUSHINT // x b 45\n' + + ' SWAP // x 45 b\n' + + ' 8 STU // x b\n' + + ' SWAP // b x\n' + + ' NEGATE // b -x\n' + + ' SWAP // -x b\n' + + ' }>CONT IF\n' + + ' // x b\n' + + '\n' + + ' SWAP // b x\n' + + '\n' + + ' <{\n' + + ' // b x\n' + + ' 10 PUSHINT DIVMOD // b x/10 x%10\n' + + ' 48 ADDCONST // b x/10 (x%10+48)\n' + + ' s2 s2 s0 XC2PU ISZERO // (x%10+48) b x/10 x/10==0?\n' + + ' }>CONT UNTIL\n' + + ' // ... b x\n' + + '\n' + + ' DROP // ... b\n' + + ' DEPTH DEC // ... b n\n' + + ' <{ 8 STU }>CONT REPEAT // b\n' + + ' }>CONT 1 1 CALLXARGS\n' + + ' // b\n' + + '\n' + + ' ENDC CTOS // s\n' + + '}\n' + + '\n' + + '/// Extension function for the `Int` type.\n' + + '///\n' + + '/// Returns a `String` from an `Int` value using a [fixed-point representation] of a fractional\n' + + '/// number, where `self` is the significant part of the number and `digits` is the number\n' + + '/// of digits in the fractional part.\n' + + '///\n' + + '/// NOTE: **Gas expensive!** This function uses 500 gas units or more.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fizz: String = (42).toFloatString(9); // "0.000000042"\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 134: [Invalid argument] — Thrown when the given `digits` value is out of range.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#inttofloatstring\n' + + '///\n' + + '/// [fixed-point representation]: https://en.wikipedia.org/wiki/Fixed-point_arithmetic\n' + + '/// [Invalid argument]: https://docs.tact-lang.org/book/exit-codes#134\n' + + '///\n' + + 'asm extends fun toFloatString(self: Int, digits: Int): String {\n' + + ' // x digits\n' + + '\n' + + ' DUP // x digits digits\n' + + ' 1 LESSINT // x digits digits<=0\n' + + ' 134 THROWIF // x digits\n' + + ' DUP // x digits digits\n' + + ' 77 GTINT // x digits digits>77\n' + + ' 134 THROWIF // x digits\n' + + '\n' + + ' NEWC // x digits b\n' + + ' ROTREV // b x digits\n' + + ' s1 PUSH // b x digits x\n' + + ' 0 LESSINT // b x digits x<0?\n' + + '\n' + + ' <{\n' + + ' // b x digits\n' + + ' ROT // x digits b\n' + + ' x{2d} STSLICECONST // x digits b\n' + + ' ROT // digits b x\n' + + ' NEGATE // digits b -x\n' + + ' ROT // b -x digits\n' + + ' }>CONT IF\n' + + '\n' + + ' // b x digits\n' + + ' ONE // b x digits 1\n' + + ' OVER // b x digits 1 digits\n' + + '\n' + + ' <{ 10 MULCONST }>CONT REPEAT // b x digits 10^digits\n' + + '\n' + + ' s1 s2 XCHG // b digits x 10^digits\n' + + ' DIVMOD // b digits left right\n' + + ' s3 s3 XCHG2 // right digits b left\n' + + '\n' + + ' <{\n' + + ' // b x\n' + + '\n' + + ' <{\n' + + ' // b x\n' + + ' 10 PUSHINT DIVMOD // b x/10 x%10\n' + + ' 48 ADDCONST // b x/10 (x%10+48)\n' + + ' s2 s2 s0 XC2PU ISZERO // (x%10+48) b x/10 x/10==0?\n' + + ' }>CONT UNTIL\n' + + ' // ... b x\n' + + '\n' + + ' DROP // ... b\n' + + ' DEPTH DEC // ... b n\n' + + ' <{ 8 STU }>CONT REPEAT // b\n' + + ' }>CONT 2 1 CALLXARGS\n' + + '\n' + + ' // right digits "left"\n' + + '\n' + + ' ROT // digits "left" right\n' + + ' DUP // digits "left" right right\n' + + ' ISZERO // digits "left" right right==0?\n' + + '\n' + + ' <{\n' + + ' // digits "left" right\n' + + ' DROP // digits "left"\n' + + ' NIP // "left"\n' + + ' }>CONT\n' + + '\n' + + ' <{\n' + + ' // digits "left" right\n' + + ' ZERO // digits "left" right 0\n' + + ' SWAP // digits "left" 0 right\n' + + '\n' + + ' <{\n' + + ' // digits "left" i right\n' + + ' DUP // digits "left" i right right\n' + + ' 10 PUSHINT // digits "left" i right right 10\n' + + ' MOD // digits "left" i right right%10\n' + + ' ISZERO // digits "left" i right right%10==0?\n' + + ' }>CONT\n' + + '\n' + + ' <{\n' + + ' // digits "left" i right\n' + + ' 10 PUSHINT // digits "left" i right 10\n' + + ' DIV // digits "left" i right/10\n' + + ' SWAP // digits "left" right/10 i\n' + + ' INC // digits "left" right/10 i+1\n' + + ' SWAP // digits "left" i+1 right/10\n' + + ' }>CONT\n' + + '\n' + + ' WHILE // digits "left" i right\n' + + '\n' + + ' <{\n' + + ' // x\n' + + ' NEWC // x b\n' + + ' SWAP // b x\n' + + '\n' + + ' <{\n' + + ' // b x\n' + + ' 10 PUSHINT DIVMOD // b x/10 x%10\n' + + ' 48 ADDCONST // b x/10 (x%10+48)\n' + + ' s2 s2 s0 XC2PU ISZERO // (x%10+48) b x/10 x/10==0?\n' + + ' }>CONT UNTIL\n' + + ' // ... b x\n' + + '\n' + + ' DROP // ... b\n' + + ' DEPTH DEC DUP // ... b n n\n' + + ' ROTREV // ... n b n\n' + + ' <{\n' + + ' // ... c n b\n' + + ' s1 s2 XCHG // ... n c b\n' + + ' 8 STU // ... n b\n' + + ' }>CONT REPEAT // n b\n' + + ' }>CONT 1 2 CALLXARGS\n' + + ' // digits "left" i right_digits "right"\n' + + ' ROTREV // digits "left" "right" i right_digits\n' + + ' ADD // digits "left" "right" right_digits\n' + + '\n' + + ' s3 s1 XCHG // "right" "left" digits right_digits\n' + + ' SUB // "right" "left" digits_diff\n' + + ' SWAP // "right" digits_diff "left"\n' + + ' x{2e} STSLICECONST // "right" digits_diff "left."\n' + + ' SWAP // "right" "left." digits_diff\n' + + '\n' + + ' <{\n' + + ' // "right" "left."\n' + + ' x{30} STSLICECONST // "right" "left.0"\n' + + ' }>CONT REPEAT // "right" "left.000"\n' + + '\n' + + ' STB // "left.000right"\n' + + ' }>CONT\n' + + '\n' + + ' IFELSE // b\n' + + '\n' + + ' ENDC CTOS // s\n' + + '}\n' + + '\n' + + '/// Extension function for the `Int` type.\n' + + '///\n' + + '/// Returns a `String` from an `Int` value using a [fixed-point representatio'... 6219 more characters, + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'beginString', + loc: { start: 329, end: 340 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 344, end: 357 } + }, + typeArgs: [], + loc: { start: 344, end: 357 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_string_builder_start_string', + loc: { start: 286, end: 320 } + } + }, + loc: { start: 280, end: 358 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'beginComment', + loc: { start: 830, end: 842 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 846, end: 859 } + }, + typeArgs: [], + loc: { start: 846, end: 859 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_string_builder_start_comment', + loc: { start: 786, end: 821 } + } + }, + loc: { start: 780, end: 860 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'beginTailString', + loc: { start: 1341, end: 1356 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 1360, end: 1373 } + }, + typeArgs: [], + loc: { start: 1360, end: 1373 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_string_builder_start_tail_string', + loc: { start: 1293, end: 1332 } + } + }, + loc: { start: 1287, end: 1374 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'beginStringFromBuilder', + loc: { start: 1836, end: 1858 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 1872, end: 1885 } + }, + typeArgs: [], + loc: { start: 1872, end: 1885 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'b', + loc: { start: 1859, end: 1860 } + }, + type: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 1862, end: 1869 } }, + loc: { start: 1862, end: 1869 } + }, + loc: { start: 1859, end: 1869 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_string_builder_start', + loc: { start: 1800, end: 1827 } + } + }, + loc: { start: 1794, end: 1886 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'append', + loc: { start: 2328, end: 2334 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 's', + loc: { start: 2356, end: 2357 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 2359, end: 2365 } + }, + typeArgs: [], + loc: { start: 2359, end: 2365 } + }, + loc: { start: 2356, end: 2365 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_string_builder_append', + loc: { start: 2275, end: 2303 } + } + }, + loc: { start: 2269, end: 2367 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 2341, end: 2354 } + }, + typeArgs: [], + loc: { start: 2341, end: 2354 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'concat', + loc: { start: 2880, end: 2886 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 2920, end: 2933 } + }, + typeArgs: [], + loc: { start: 2920, end: 2933 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 's', + loc: { start: 2908, end: 2909 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 2911, end: 2917 } + }, + typeArgs: [], + loc: { start: 2911, end: 2917 } + }, + loc: { start: 2908, end: 2917 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_string_builder_append_not_mut', + loc: { start: 2827, end: 2863 } + } + }, + loc: { start: 2821, end: 2934 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 2893, end: 2906 } + }, + typeArgs: [], + loc: { start: 2893, end: 2906 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'toCell', + loc: { start: 3392, end: 3398 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3421, end: 3425 } }, + loc: { start: 3421, end: 3425 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_string_builder_end', + loc: { start: 3350, end: 3375 } + } + }, + loc: { start: 3344, end: 3426 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 3405, end: 3418 } + }, + typeArgs: [], + loc: { start: 3405, end: 3418 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'toString', + loc: { start: 3893, end: 3901 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 3924, end: 3930 } + }, + typeArgs: [], + loc: { start: 3924, end: 3930 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_string_builder_end_slice', + loc: { start: 3845, end: 3876 } + } + }, + loc: { start: 3839, end: 3931 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 3908, end: 3921 } + }, + typeArgs: [], + loc: { start: 3908, end: 3921 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'toSlice', + loc: { start: 4530, end: 4537 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 4560, end: 4565 } }, + loc: { start: 4560, end: 4565 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_string_builder_end_slice', + loc: { start: 4482, end: 4513 } + } + }, + loc: { start: 4476, end: 4566 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 4544, end: 4557 } + }, + typeArgs: [], + loc: { start: 4544, end: 4557 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'toString', + loc: { start: 4950, end: 4958 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 4971, end: 4977 } + }, + typeArgs: [], + loc: { start: 4971, end: 4977 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '<{\n' + + ' // x\n' + + ' NEWC // x b\n' + + ' OVER // x b x\n' + + ' 0 LESSINT // x b <0?\n' + + ' <{\n' + + ' // x b\n' + + ' 45 PUSHINT // x b 45\n' + + ' SWAP // x 45 b\n' + + ' 8 STU // x b\n' + + ' SWAP // b x\n' + + ' NEGATE // b -x\n' + + ' SWAP // -x b\n' + + ' }>CONT IF\n' + + ' // x b\n' + + '\n' + + ' SWAP // b x\n' + + '\n' + + ' <{\n' + + ' // b x\n' + + ' 10 PUSHINT DIVMOD // b x/10 x%10\n' + + ' 48 ADDCONST // b x/10 (x%10+48)\n' + + ' s2 s2 s0 XC2PU ISZERO // (x%10+48) b x/10 x/10==0?\n' + + ' }>CONT UNTIL\n' + + ' // ... b x\n' + + '\n' + + ' DROP // ... b\n' + + ' DEPTH DEC // ... b n\n' + + ' <{ 8 STU }>CONT REPEAT // b\n' + + ' }>CONT 1 1 CALLXARGS\n' + + ' // b\n' + + '\n' + + ' ENDC CTOS // s' + ] + }, + loc: { start: 4934, end: 5692 } + } + }, + selfType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4965, end: 4968 } + }, + loc: { start: 4965, end: 4968 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'toFloatString', + loc: { start: 6527, end: 6540 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 6566, end: 6572 } + }, + typeArgs: [], + loc: { start: 6566, end: 6572 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'digits', + loc: { start: 6552, end: 6558 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6560, end: 6563 } + }, + loc: { start: 6560, end: 6563 } + }, + loc: { start: 6552, end: 6563 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'DUP // x digits digits\n' + + ' 1 LESSINT // x digits digits<=0\n' + + ' 134 THROWIF // x digits\n' + + ' DUP // x digits digits\n' + + ' 77 GTINT // x digits digits>77\n' + + ' 134 THROWIF // x digits\n' + + '\n' + + ' NEWC // x digits b\n' + + ' ROTREV // b x digits\n' + + ' s1 PUSH // b x digits x\n' + + ' 0 LESSINT // b x digits x<0?\n' + + '\n' + + ' <{\n' + + ' // b x digits\n' + + ' ROT // x digits b\n' + + ' x{2d} STSLICECONST // x digits b\n' + + ' ROT // digits b x\n' + + ' NEGATE // digits b -x\n' + + ' ROT // b -x digits\n' + + ' }>CONT IF\n' + + '\n' + + ' // b x digits\n' + + ' ONE // b x digits 1\n' + + ' OVER // b x digits 1 digits\n' + + '\n' + + ' <{ 10 MULCONST }>CONT REPEAT // b x digits 10^digits\n' + + '\n' + + ' s1 s2 XCHG // b digits x 10^digits\n' + + ' DIVMOD // b digits left right\n' + + ' s3 s3 XCHG2 // right digits b left\n' + + '\n' + + ' <{\n' + + ' // b x\n' + + '\n' + + ' <{\n' + + ' // b x\n' + + ' 10 PUSHINT DIVMOD // b x/10 x%10\n' + + ' 48 ADDCONST // b x/10 (x%10+48)\n' + + ' s2 s2 s0 XC2PU ISZERO // (x%10+48) b x/10 x/10==0?\n' + + ' }>CONT UNTIL\n' + + ' // ... b x\n' + + '\n' + + ' DROP // ... b\n' + + ' DEPTH DEC // ... b n\n' + + ' <{ 8 STU }>CONT REPEAT // b\n' + + ' }>CONT 2 1 CALLXARGS\n' + + '\n' + + ' // right digits "left"\n' + + '\n' + + ' ROT // digits "left" right\n' + + ' DUP // digits "left" right right\n' + + ' ISZERO // digits "left" right right==0?\n' + + '\n' + + ' <{\n' + + ' // digits "left" right\n' + + ' DROP // digits "left"\n' + + ' NIP // "left"\n' + + ' }>CONT\n' + + '\n' + + ' <{\n' + + ' // digits "left" right\n' + + ' ZERO // digits "left" right 0\n' + + ' SWAP // digits "left" 0 right\n' + + '\n' + + ' <{\n' + + ' // digits "left" i right\n' + + ' DUP // digits "left" i right right\n' + + ' 10 PUSHINT // digits "left" i right right 10\n' + + ' MOD // digits "left" i right right%10\n' + + ' ISZERO // digits "left" i right right%10==0?\n' + + ' }>CONT\n' + + '\n' + + ' <{\n' + + ' // digits "left" i right\n' + + ' 10 PUSHINT // digits "left" i right 10\n' + + ' DIV // digits "left" i right/10\n' + + ' SWAP // digits "left" right/10 i\n' + + ' INC // digits "left" right/10 i+1\n' + + ' SWAP // digits "left" i+1 right/10\n' + + ' }>CONT\n' + + '\n' + + ' WHILE // digits "left" i right\n' + + '\n' + + ' <{\n' + + ' // x\n' + + ' NEWC // x b\n' + + ' SWAP // b x\n' + + '\n' + + ' <{\n' + + ' // b x\n' + + ' 10 PUSHINT DIVMOD // b x/10 x%10\n' + + ' 48 ADDCONST // b x/10 (x%10+48)\n' + + ' s2 s2 s0 XC2PU ISZERO // (x%10+48) b x/10 x/10==0?\n' + + ' }>CONT UNTIL\n' + + ' // ... b x\n' + + '\n' + + ' DROP // ... b\n' + + ' DEPTH DEC DUP // ... b n n\n' + + ' ROTREV // ... n b n\n' + + ' <{\n' + + ' // ... c n b\n' + + ' s1 s2 XCHG // ... n c b\n' + + ' 8 STU // ... n b\n' + + ' }>CONT REPEAT // n b\n' + + ' }>CONT 1 2 CALLXARGS\n' + + ' // digits "left" i right_digits "right"\n' + + ' ROTREV // digits "left" "right" i right_digits\n' + + ' ADD // digits "left" "right" right_digits\n' + + '\n' + + ' s3 s1 XCHG // "right" "left" digits right_digits\n' + + ' SUB // "right" "left" digits_diff\n' + + ' SWAP // "right" digits_diff "left"\n' + + ' x{2e} STSLICECONST // "right" digits_diff "left."\n' + + ' SWAP // "right" "left." digits_diff\n' + + '\n' + + ' <{\n' + + ' // "right" "left."\n' + + ' x{30} STSLICECONST // "right" "left.0"\n' + + ' }>CONT REPEAT // "right" "left.000"\n' + + '\n' + + ' STB // "left.000right"\n' + + ' }>CONT\n' + + '\n' + + ' IFELSE // b\n' + + '\n' + + ' ENDC CTOS // s' + ] + }, + loc: { start: 6511, end: 9874 } + } + }, + selfType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6547, end: 6550 } + }, + loc: { start: 6547, end: 6550 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'toCoinsString', + loc: { start: 10653, end: 10666 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 10679, end: 10685 } + }, + typeArgs: [], + loc: { start: 10679, end: 10685 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 10699, end: 10703 } + }, + method: { + kind: 'id', + text: 'toFloatString', + loc: { start: 10704, end: 10717 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 9n, + loc: { start: 10718, end: 10719 } + } + ], + loc: { start: 10699, end: 10720 } + }, + loc: { start: 10692, end: 10721 } + } + ] + }, + loc: { start: 10634, end: 10723 } + } + }, + selfType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10673, end: 10676 } + }, + loc: { start: 10673, end: 10676 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'asComment', + loc: { start: 11442, end: 11451 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 11467, end: 11471 } + }, + loc: { start: 11467, end: 11471 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'b', + loc: { start: 11482, end: 11483 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 11485, end: 11498 } + }, + typeArgs: [], + loc: { start: 11485, end: 11498 } + }, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'beginComment', + loc: { start: 11501, end: 11513 } + }, + typeArgs: [], + args: [], + loc: { start: 11501, end: 11515 } + }, + loc: { start: 11478, end: 11516 } + }, + { + kind: 'statement_expression', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'b', + loc: { start: 11521, end: 11522 } + }, + method: { + kind: 'id', + text: 'append', + loc: { start: 11523, end: 11529 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'self', + loc: { start: 11530, end: 11534 } + } + ], + loc: { start: 11521, end: 11535 } + }, + loc: { start: 11521, end: 11536 } + }, + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'b', + loc: { start: 11548, end: 11549 } + }, + method: { + kind: 'id', + text: 'toCell', + loc: { start: 11550, end: 11556 } + }, + typeArgs: [], + args: [], + loc: { start: 11548, end: 11558 } + }, + loc: { start: 11541, end: 11559 } + } + ] + }, + loc: { start: 11430, end: 11561 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 11458, end: 11464 } + }, + typeArgs: [], + loc: { start: 11458, end: 11464 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'asSlice', + loc: { start: 12075, end: 12082 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 12098, end: 12103 } + }, + loc: { start: 12098, end: 12103 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_str_to_slice', + loc: { start: 12039, end: 12058 } + } + }, + loc: { start: 12033, end: 12104 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 12089, end: 12095 } + }, + typeArgs: [], + loc: { start: 12089, end: 12095 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'asString', + loc: { start: 12598, end: 12606 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 12621, end: 12627 } + }, + typeArgs: [], + loc: { start: 12621, end: 12627 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_slice_to_str', + loc: { start: 12562, end: 12581 } + } + }, + loc: { start: 12556, end: 12628 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 12613, end: 12618 } }, + loc: { start: 12613, end: 12618 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'fromBase64', + loc: { start: 13537, end: 13547 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 13563, end: 13568 } + }, + loc: { start: 13563, end: 13568 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 13582, end: 13586 } + }, + method: { + kind: 'id', + text: 'asSlice', + loc: { start: 13587, end: 13594 } + }, + typeArgs: [], + args: [], + loc: { start: 13582, end: 13596 } + }, + method: { + kind: 'id', + text: 'fromBase64', + loc: { start: 13597, end: 13607 } + }, + typeArgs: [], + args: [], + loc: { start: 13582, end: 13609 } + }, + loc: { start: 13575, end: 13610 } + } + ] + }, + loc: { start: 13518, end: 13612 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 13554, end: 13560 } + }, + typeArgs: [], + loc: { start: 13554, end: 13560 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'fromBase64', + loc: { start: 14642, end: 14652 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 14667, end: 14672 } + }, + loc: { start: 14667, end: 14672 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'size', + loc: { start: 14683, end: 14687 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14689, end: 14692 } + }, + loc: { start: 14689, end: 14692 } + }, + expression: { + kind: 'op_binary', + op: '/', + left: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 14695, end: 14699 } + }, + method: { + kind: 'id', + text: 'bits', + loc: { start: 14700, end: 14704 } + }, + typeArgs: [], + args: [], + loc: { start: 14695, end: 14706 } + }, + right: { + kind: 'number', + base: '10', + value: 8n, + loc: { start: 14709, end: 14710 } + }, + loc: { start: 14695, end: 14710 } + }, + loc: { start: 14679, end: 14711 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'result', + loc: { start: 14720, end: 14726 } + }, + type: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 14728, end: 14735 } + }, + loc: { start: 14728, end: 14735 } + }, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'beginCell', + loc: { start: 14738, end: 14747 } + }, + typeArgs: [], + args: [], + loc: { start: 14738, end: 14749 } + }, + loc: { start: 14716, end: 14750 } + }, + { + kind: 'statement_repeat', + iterations: { + kind: 'var', + name: 'size', + loc: { start: 14764, end: 14768 } + }, + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'code', + loc: { start: 14784, end: 14788 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14790, end: 14793 } + }, + loc: { start: 14790, end: 14793 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 14796, end: 14800 } + }, + method: { + kind: 'id', + text: 'loadUint', + loc: { start: 14801, end: 14809 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 8n, + loc: { start: 14810, end: 14811 } + } + ], + loc: { start: 14796, end: 14812 } + }, + loc: { start: 14780, end: 14813 } + }, + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '&&', + left: { + kind: 'op_binary', + op: '>=', + left: { + kind: 'var', + name: 'code', + loc: { start: 14826, end: 14830 } + }, + right: { + kind: 'number', + base: '10', + value: 65n, + loc: { start: 14834, end: 14836 } + }, + loc: { start: 14826, end: 14836 } + }, + right: { + kind: 'op_binary', + op: '<=', + left: { + kind: 'var', + name: 'code', + loc: { start: 14840, end: 14844 } + }, + right: { + kind: 'number', + base: '10', + value: 90n, + loc: { start: 14848, end: 14850 } + }, + loc: { start: 14840, end: 14850 } + }, + loc: { start: 14826, end: 14850 } + }, + trueStatements: [ + { + kind: 'statement_assign', + path: { + kind: 'var', + name: 'result', + loc: { start: 14873, end: 14879 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'result', + loc: { start: 14882, end: 14888 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 14889, end: 14898 } + }, + typeArgs: [], + args: [ + { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'code', + loc: { start: 14899, end: 14903 } + }, + right: { + kind: 'number', + base: '10', + value: 65n, + loc: { start: 14906, end: 14908 } + }, + loc: { start: 14899, end: 14908 } + }, + { + kind: 'number', + base: '10', + value: 6n, + loc: { start: 14910, end: 14911 } + } + ], + loc: { start: 14882, end: 14912 } + }, + loc: { start: 14873, end: 14913 } + } + ], + falseStatements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '&&', + left: { + kind: 'op_binary', + op: '>=', + left: { + kind: 'var', + name: 'code', + loc: { start: 14933, end: 14937 } + }, + right: { + kind: 'number', + base: '10', + value: 97n, + loc: { start: 14941, end: 14943 } + }, + loc: { start: 14933, end: 14943 } + }, + right: { + kind: 'op_binary', + op: '<=', + left: { + kind: 'var', + name: 'code', + loc: { start: 14947, end: 14951 } + }, + right: { + kind: 'number', + base: '10', + value: 122n, + loc: { start: 14955, end: 14958 } + }, + loc: { start: 14947, end: 14958 } + }, + loc: { start: 14933, end: 14958 } + }, + trueStatements: [ + { + kind: 'statement_assign', + path: { + kind: 'var', + name: 'result', + loc: { start: 14981, end: 14987 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'result', + loc: { start: 14990, end: 14996 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 14997, end: 15006 } + }, + typeArgs: [], + args: [ + { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'code', + loc: { start: 15007, end: 15011 } + }, + right: { + kind: 'op_binary', + op: '-', + left: { + kind: 'number', + base: '10', + value: 97n, + loc: { start: 15015, end: 15017 } + }, + right: { + kind: 'number', + base: '10', + value: 26n, + loc: { start: 15020, end: 15022 } + }, + loc: { start: 15015, end: 15022 } + }, + loc: { start: 15007, end: 15023 } + }, + { + kind: 'number', + base: '10', + value: 6n, + loc: { start: 15025, end: 15026 } + } + ], + loc: { start: 14990, end: 15027 } + }, + loc: { start: 14981, end: 15028 } + } + ], + falseStatements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '&&', + left: { + kind: 'op_binary', + op: '>=', + left: { + kind: 'var', + name: 'code', + loc: { start: 15048, end: 15052 } + }, + right: { + kind: 'number', + base: '10', + value: 48n, + loc: { start: 15056, end: 15058 } + }, + loc: { start: 15048, end: 15058 } + }, + right: { + kind: 'op_binary', + op: '<=', + left: { + kind: 'var', + name: 'code', + loc: { start: 15062, end: 15066 } + }, + right: { + kind: 'number', + base: '10', + value: 57n, + loc: { start: 15070, end: 15072 } + }, + loc: { start: 15062, end: 15072 } + }, + loc: { start: 15048, end: 15072 } + }, + trueStatements: [ + { + kind: 'statement_assign', + path: { + kind: 'var', + name: 'result', + loc: { start: 15095, end: 15101 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'result', + loc: { start: 15104, end: 15110 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 15111, end: 15120 } + }, + typeArgs: [], + args: [ + { + kind: 'op_binary', + op: '+', + left: { + kind: 'var', + name: 'code', + loc: { + start: 15121, + end: 15125 + } + }, + right: { + kind: 'op_binary', + op: '-', + left: { + kind: 'number', + base: '10', + value: 52n, + loc: { + start: 15129, + end: 15131 + } + }, + right: { + kind: 'number', + base: '10', + value: 48n, + loc: { + start: 15134, + end: 15136 + } + }, + loc: { + start: 15129, + end: 15136 + } + }, + loc: { start: 15121, end: 15137 } + }, + { + kind: 'number', + base: '10', + value: 6n, + loc: { start: 15139, end: 15140 } + } + ], + loc: { start: 15104, end: 15141 } + }, + loc: { start: 15095, end: 15142 } + } + ], + falseStatements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '||', + left: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'code', + loc: { start: 15162, end: 15166 } + }, + right: { + kind: 'number', + base: '10', + value: 45n, + loc: { start: 15170, end: 15172 } + }, + loc: { start: 15162, end: 15172 } + }, + right: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'code', + loc: { start: 15176, end: 15180 } + }, + right: { + kind: 'number', + base: '10', + value: 43n, + loc: { start: 15184, end: 15186 } + }, + loc: { start: 15176, end: 15186 } + }, + loc: { start: 15162, end: 15186 } + }, + trueStatements: [ + { + kind: 'statement_assign', + path: { + kind: 'var', + name: 'result', + loc: { start: 15212, end: 15218 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'result', + loc: { + start: 15221, + end: 15227 + } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { + start: 15228, + end: 15237 + } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 62n, + loc: { + start: 15238, + end: 15240 + } + }, + { + kind: 'number', + base: '10', + value: 6n, + loc: { + start: 15242, + end: 15243 + } + } + ], + loc: { start: 15221, end: 15244 } + }, + loc: { start: 15212, end: 15245 } + } + ], + falseStatements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '||', + left: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'code', + loc: { + start: 15265, + end: 15269 + } + }, + right: { + kind: 'number', + base: '10', + value: 95n, + loc: { + start: 15273, + end: 15275 + } + }, + loc: { + start: 15265, + end: 15275 + } + }, + right: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'code', + loc: { + start: 15279, + end: 15283 + } + }, + right: { + kind: 'number', + base: '10', + value: 47n, + loc: { + start: 15287, + end: 15289 + } + }, + loc: { + start: 15279, + end: 15289 + } + }, + loc: { start: 15265, end: 15289 } + }, + trueStatements: [ + { + kind: 'statement_assign', + path: { + kind: 'var', + name: 'result', + loc: { + start: 15315, + end: 15321 + } + }, + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'result', + loc: { + start: 15324, + end: 15330 + } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { + start: 15331, + end: 15340 + } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 63n, + loc: { + start: 15341, + end: 15343 + } + }, + { + kind: 'number', + base: '10', + value: 6n, + loc: { + start: 15345, + end: 15346 + } + } + ], + loc: { + start: 15324, + end: 15347 + } + }, + loc: { + start: 15315, + end: 15348 + } + } + ], + falseStatements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'code', + loc: { + start: 15368, + end: 15372 + } + }, + right: { + kind: 'number', + base: '10', + value: 61n, + loc: { + start: 15376, + end: 15378 + } + }, + loc: { + start: 15368, + end: 15378 + } + }, + trueStatements: [], + falseStatements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throw', + loc: { + start: 15436, + end: 15441 + } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'TactExitCodeInvalidArgument', + loc: { + start: 15442, + end: 15469 + } + } + ], + loc: { + start: 15436, + end: 15470 + } + }, + loc: { + start: 15436, + end: 15471 + } + } + ], + loc: { + start: 15364, + end: 15481 + } + } + ], + loc: { start: 15261, end: 15481 } + } + ], + loc: { start: 15158, end: 15481 } + } + ], + loc: { start: 15044, end: 15481 } + } + ], + loc: { start: 14929, end: 15481 } + } + ], + loc: { start: 14822, end: 15481 } + } + ], + loc: { start: 14756, end: 15487 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'total', + loc: { start: 15512, end: 15517 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15519, end: 15522 } + }, + loc: { start: 15519, end: 15522 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'result', + loc: { start: 15525, end: 15531 } + }, + method: { + kind: 'id', + text: 'bits', + loc: { start: 15532, end: 15536 } + }, + typeArgs: [], + args: [], + loc: { start: 15525, end: 15538 } + }, + loc: { start: 15508, end: 15539 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'padding', + loc: { start: 15548, end: 15555 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15557, end: 15560 } + }, + loc: { start: 15557, end: 15560 } + }, + expression: { + kind: 'op_binary', + op: '%', + left: { + kind: 'var', + name: 'total', + loc: { start: 15563, end: 15568 } + }, + right: { + kind: 'number', + base: '10', + value: 8n, + loc: { start: 15571, end: 15572 } + }, + loc: { start: 15563, end: 15572 } + }, + loc: { start: 15544, end: 15573 } + }, + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '!=', + left: { + kind: 'var', + name: 'padding', + loc: { start: 15582, end: 15589 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15593, end: 15594 } + }, + loc: { start: 15582, end: 15594 } + }, + trueStatements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 's', + loc: { start: 15610, end: 15611 } + }, + type: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 15613, end: 15618 } + }, + loc: { start: 15613, end: 15618 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'result', + loc: { start: 15621, end: 15627 } + }, + method: { + kind: 'id', + text: 'asSlice', + loc: { start: 15628, end: 15635 } + }, + typeArgs: [], + args: [], + loc: { start: 15621, end: 15637 } + }, + loc: { start: 15606, end: 15638 } + }, + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 's', + loc: { start: 15654, end: 15655 } + }, + method: { + kind: 'id', + text: 'loadBits', + loc: { start: 15656, end: 15664 } + }, + typeArgs: [], + args: [ + { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'total', + loc: { start: 15665, end: 15670 } + }, + right: { + kind: 'var', + name: 'padding', + loc: { start: 15673, end: 15680 } + }, + loc: { start: 15665, end: 15680 } + } + ], + loc: { start: 15654, end: 15681 } + }, + loc: { start: 15647, end: 15682 } + } + ], + falseStatements: [ + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'result', + loc: { start: 15711, end: 15717 } + }, + method: { + kind: 'id', + text: 'asSlice', + loc: { start: 15718, end: 15725 } + }, + typeArgs: [], + args: [], + loc: { start: 15711, end: 15727 } + }, + loc: { start: 15704, end: 15728 } + } + ], + loc: { start: 15578, end: 15734 } + } + ] + }, + loc: { start: 14630, end: 15736 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 14659, end: 14664 } }, + loc: { start: 14659, end: 14664 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'toString', + loc: { start: 16186, end: 16194 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 16211, end: 16217 } + }, + typeArgs: [], + loc: { start: 16211, end: 16217 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_address_to_user_friendly', + loc: { start: 16138, end: 16169 } + } + }, + loc: { start: 16132, end: 16218 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 16201, end: 16208 } + }, + typeArgs: [], + loc: { start: 16201, end: 16208 } + } + } + ] + }, + 'nativeRandomize' => { + kind: 'tact', + path: 'std/internal/math.tact', + code: '// Prepare random\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Randomizes the pseudorandom number generator with the specified unsigned 256-bit `Int` `x` by mixing it with the current seed. The new seed is the unsigned 256-bit `Int` value of the SHA-256 hash of concatenated old seed and `x` in their 32-byte strings big-endian representation.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativeRandomize(42); // now, random numbers are less predictable\n' + + "/// let idk: Int = randomInt(); // ???, it's random,\n" + + '/// // but the seed was adjusted deterministically!\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify a negative value of `x`.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomize\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun nativeRandomize(x: Int) { ADDRAND }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Randomizes the random number generator with the logical time of the current transaction. Equivalent to calling `nativeRandomize(curLt())`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativeRandomizeLt(); // now, random numbers are unpredictable for users,\n' + + '/// // but still may be affected by validators or collators\n' + + '/// // as they determine the seed of the current block.\n' + + "/// let idk: Int = randomInt(); // ???, it's random!\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomizelt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomize\n' + + '/// * https://docs.tact-lang.org/ref/core-contextstate#curlt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + 'asm fun nativeRandomizeLt() { LTIME ADDRAND }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Prepares a random number generator by using `nativeRandomizeLt()`. Automatically called by `randomInt()` and `random()` functions.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativePrepareRandom(); // prepare the RNG\n' + + '/// // ... do your random things ...\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativepreparerandom\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomizelt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '/// * https://docs.tact-lang.org/ref/core-random#random\n' + + '///\n' + + '@name(__tact_prepare_random)\n' + + 'native nativePrepareRandom();\n' + + '\n' + + '// Random\n' + + '\n' + + '// Generates a new pseudo-random unsigned 256-bit integer x.\n' + + '// The algorithm is as follows: if r is the old value of the random seed,\n' + + '// considered as a 32-byte array (by constructing the big-endian representation\n' + + '// of an unsigned 256-bit integer), then its sha512(r) is computed;\n' + + "// the first 32 bytes of this hash are stored as the new value r' of the random seed,\n" + + '// and the remaining 32 bytes are returned as the next random value x.\n' + + 'asm fun nativeRandom(): Int { RANDU256 }\n' + + '\n' + + '// Generates a new pseudo-random integer z in the range 0..range−1\n' + + '// (or range..−1, if range < 0).\n' + + '// More precisely, an unsigned random value x is generated as in `nativeRandom`;\n' + + '// then z := x * range / 2^256 is computed.\n' + + 'asm fun nativeRandomInterval(max: Int): Int { RAND }\n' + + '\n' + + '/// Generates and returns a new pseudo-random unsigned 256-bit `Int` value `x`.\n' + + '///\n' + + '/// The algorithm works as follows: first, the `sha512(r)` is computed. There, `r` is an old\n' + + '/// value of the random seed, which is taken as a 32-byte array constructed from the big-endian\n' + + '/// representation of an unsigned 256-bit `Int`. The first 32 bytes of this hash are stored as the new\n' + + "/// value `r'` of the random seed, and the remaining 32 bytes are returned as the next random value `x`.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + "/// let allYourRandomBelongToUs: Int = randomInt(); // ???, it's random :)\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + 'inline fun randomInt(): Int {\n' + + ' nativePrepareRandom();\n' + + ' return nativeRandom();\n' + + '}\n' + + '\n' + + '/// Generates and returns a new pseudo-random unsigned `Int` value `x` in the provided semi-closed\n' + + '/// interval: `min` ≤ `x` < `max`, or `min` ≥ `x` > `max` if both `min` and `max` are negative.\n' + + '///\n' + + '/// Note that the `max` value is never included in the interval.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// random(42, 43); // 42, always\n' + + '/// random(0, 42); // 0-41, but never 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-random#random\n' + + '///\n' + + 'inline fun random(min: Int, max: Int): Int {\n' + + ' nativePrepareRandom();\n' + + ' return min + nativeRandomInterval(max - min);\n' + + '}\n' + + '\n' + + '// Math\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the minimum of two `Int` values `x` and `y`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// min(1, 2); // 1\n' + + '/// min(2, 2); // 2\n' + + '/// min(007, 3); // 3\n' + + '/// min(0x45, 3_0_0); // 69, nice\n' + + '/// // ↑ ↑\n' + + '/// // 69 300\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#min\n' + + '///\n' + + 'asm fun min(x: Int, y: Int): Int { MIN }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the maximum of two `Int` values `x` and `y`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// max(1, 2); // 2\n' + + '/// max(2, 2); // 2\n' + + '/// max(007, 3); // 7\n' + + '/// max(0x45, 3_0_0); // 300\n' + + '/// // ↑ ↑\n' + + '/// // 69 300\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#max\n' + + '///\n' + + 'asm fun max(x: Int, y: Int): Int { MAX }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the absolute value of the `Int` value `x`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// abs(42); // 42\n' + + '/// abs(-42); // 42\n' + + '/// abs(-(-(-42))); // 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#abs\n' + + '///\n' + + 'asm fun abs(x: Int): Int { ABS }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the logarithm of a number `num` > 0 to the base `base` ≥ 1. Results are rounded down.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// log(1000, 10); // 3, as 10^3 is 1000\n' + + '/// // ↑ ↑ ↑ ↑\n' + + '/// // num base base num\n' + + '///\n' + + '/// log(1001, 10); // 3\n' + + '/// log(999, 10); // 2\n' + + '/// try {\n' + + '/// log(-1000, 10); // exit code 5 because of the non-positive num\n' + + '/// }\n' + + '/// log(1024, 2); // 10\n' + + '/// try {\n' + + '/// log(1024, -2); // exit code 5 because the base is less than 1\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `num` value is non-positive\n' + + '/// or the given `base` value is less than 1.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log2\n' + + '///\n' + + '@name(__tact_log)\n' + + 'native log(num: Int, base: Int): Int;\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Similar to `log()`, but sets the `base` to 2.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// log2(1024); // 10, as 2^10 is 1024\n' + + '/// // ↑ ↑ ↑\n' + + '/// // num base₂ num\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `num` value is non-positive.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log2\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log.\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes/#5\n' + + '///\n' + + 'asm fun log2(num: Int): Int { DUP 5 THROWIFNOT UBITSIZE DEC }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the exponentiation involving two numbers: the `base` and the exponent (or _power_) `exp`.\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Example {\n' + + '/// // Persistent state variables\n' + + '/// p23: Int = pow(2, 3); // raises 2 to the 3rd power, which is 8\n' + + '/// one: Int = pow(5, 0); // raises 5 to the power 0, which always produces 1\n' + + '/// // works at compile-time!\n' + + '///\n' + + '/// // Internal message receiver\n' + + '/// receive() {\n' + + '/// pow(self.p23, self.one + 1); // 64, works at run-time too!\n' + + '/// try {\n' + + '/// pow(0, -1); // exit code 5: Integer out of expected range\n' + + '/// }\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `exp` value is negative.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow2\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes/#5\n' + + '///\n' + + 'inline fun pow(base: Int, exp: Int): Int {\n' + + ' throwUnless(5, exp >= 0);\n' + + ' let result = 1;\n' + + ' repeat (exp) {\n' + + ' result *= base;\n' + + ' }\n' + + ' return result;\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Similar to `pow()`, but sets the `base` to 2.\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Example {\n' + + '/// // Persistent state variables\n' + + '/// p23: Int = pow2(3); // raises 2 to the 3rd power, which is 8\n' + + '/// one: Int = pow2(0); // raises 2 to the power 0, which always produces 1\n' + + '/// // works at compile-time!\n' + + '///\n' + + '/// // Internal message receiver, which accepts message ExtMsg\n' + + '/// receive() {\n' + + '/// pow2(self.one + 1); // 4, works at run-time too!\n' + + '/// try {\n' + + '/// pow(-1); // exit code 5: Integer out of expected range\n' + + '/// }\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify a negative value of `exp`.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow2\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun pow2(exp: Int): Int { POW2 }\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Computes and returns the sign of the `Int` value `x`. Produces 1 if the `x` is positive, -1 if the `x` is negative, and 0 if the `x` is 0.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// '... 5983 more characters, + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomize', + loc: { start: 965, end: 980 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { kind: 'id', text: 'x', loc: { start: 981, end: 982 } }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 984, end: 987 } + }, + loc: { start: 984, end: 987 } + }, + loc: { start: 981, end: 987 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ADDRAND' ] + }, + loc: { start: 957, end: 1000 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomizeLt', + loc: { start: 1822, end: 1839 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LTIME ADDRAND' ] + }, + loc: { start: 1814, end: 1859 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 2466, end: 2485 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_prepare_random', + loc: { start: 2436, end: 2457 } + } + }, + loc: { start: 2430, end: 2488 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandom', + loc: { start: 2949, end: 2961 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2965, end: 2968 } + }, + loc: { start: 2965, end: 2968 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RANDU256' ] + }, + loc: { start: 2941, end: 2981 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomInterval', + loc: { start: 3216, end: 3236 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3248, end: 3251 } + }, + loc: { start: 3248, end: 3251 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'max', + loc: { start: 3237, end: 3240 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3242, end: 3245 } + }, + loc: { start: 3242, end: 3245 } + }, + loc: { start: 3237, end: 3245 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RAND' ] + }, + loc: { start: 3208, end: 3260 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'randomInt', + loc: { start: 3953, end: 3962 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3966, end: 3969 } + }, + loc: { start: 3966, end: 3969 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 3976, end: 3995 } + }, + typeArgs: [], + args: [], + loc: { start: 3976, end: 3997 } + }, + loc: { start: 3976, end: 3998 } + }, + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativeRandom', + loc: { start: 4010, end: 4022 } + }, + typeArgs: [], + args: [], + loc: { start: 4010, end: 4024 } + }, + loc: { start: 4003, end: 4025 } + } + ] + }, + loc: { start: 3942, end: 4027 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'random', + loc: { start: 4505, end: 4511 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4533, end: 4536 } + }, + loc: { start: 4533, end: 4536 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'min', + loc: { start: 4512, end: 4515 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4517, end: 4520 } + }, + loc: { start: 4517, end: 4520 } + }, + loc: { start: 4512, end: 4520 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'max', + loc: { start: 4522, end: 4525 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4527, end: 4530 } + }, + loc: { start: 4527, end: 4530 } + }, + loc: { start: 4522, end: 4530 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 4543, end: 4562 } + }, + typeArgs: [], + args: [], + loc: { start: 4543, end: 4564 } + }, + loc: { start: 4543, end: 4565 } + }, + { + kind: 'statement_return', + expression: { + kind: 'op_binary', + op: '+', + left: { + kind: 'var', + name: 'min', + loc: { start: 4577, end: 4580 } + }, + right: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativeRandomInterval', + loc: { start: 4583, end: 4603 } + }, + typeArgs: [], + args: [ + { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'max', + loc: { start: 4604, end: 4607 } + }, + right: { + kind: 'var', + name: 'min', + loc: { start: 4610, end: 4613 } + }, + loc: { start: 4604, end: 4613 } + } + ], + loc: { start: 4583, end: 4614 } + }, + loc: { start: 4577, end: 4614 } + }, + loc: { start: 4570, end: 4615 } + } + ] + }, + loc: { start: 4494, end: 4617 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'min', loc: { start: 5017, end: 5020 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5038, end: 5041 } + }, + loc: { start: 5038, end: 5041 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5021, end: 5022 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5024, end: 5027 } + }, + loc: { start: 5024, end: 5027 } + }, + loc: { start: 5021, end: 5027 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 5029, end: 5030 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5032, end: 5035 } + }, + loc: { start: 5032, end: 5035 } + }, + loc: { start: 5029, end: 5035 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MIN' ] + }, + loc: { start: 5009, end: 5049 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'max', loc: { start: 5435, end: 5438 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5456, end: 5459 } + }, + loc: { start: 5456, end: 5459 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5439, end: 5440 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5442, end: 5445 } + }, + loc: { start: 5442, end: 5445 } + }, + loc: { start: 5439, end: 5445 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 5447, end: 5448 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5450, end: 5453 } + }, + loc: { start: 5450, end: 5453 } + }, + loc: { start: 5447, end: 5453 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MAX' ] + }, + loc: { start: 5427, end: 5467 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'abs', loc: { start: 5773, end: 5776 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5786, end: 5789 } + }, + loc: { start: 5786, end: 5789 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5777, end: 5778 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5780, end: 5783 } + }, + loc: { start: 5780, end: 5783 } + }, + loc: { start: 5777, end: 5783 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ABS' ] + }, + loc: { start: 5765, end: 5797 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'log', loc: { start: 6721, end: 6724 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6747, end: 6750 } + }, + loc: { start: 6747, end: 6750 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 6725, end: 6728 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6730, end: 6733 } + }, + loc: { start: 6730, end: 6733 } + }, + loc: { start: 6725, end: 6733 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'base', + loc: { start: 6735, end: 6739 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6741, end: 6744 } + }, + loc: { start: 6741, end: 6744 } + }, + loc: { start: 6735, end: 6744 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_log', + loc: { start: 6702, end: 6712 } + } + }, + loc: { start: 6696, end: 6751 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'log2', loc: { start: 7341, end: 7345 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7357, end: 7360 } + }, + loc: { start: 7357, end: 7360 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 7346, end: 7349 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7351, end: 7354 } + }, + loc: { start: 7351, end: 7354 } + }, + loc: { start: 7346, end: 7354 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DUP 5 THROWIFNOT UBITSIZE DEC' ] + }, + loc: { start: 7333, end: 7394 } + }, + { + kind: 'function', + inline: true, + name: { kind: 'id', text: 'pow', loc: { start: 8510, end: 8513 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8536, end: 8539 } + }, + loc: { start: 8536, end: 8539 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'base', + loc: { start: 8514, end: 8518 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8520, end: 8523 } + }, + loc: { start: 8520, end: 8523 } + }, + loc: { start: 8514, end: 8523 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'exp', + loc: { start: 8525, end: 8528 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8530, end: 8533 } + }, + loc: { start: 8530, end: 8533 } + }, + loc: { start: 8525, end: 8533 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throwUnless', + loc: { start: 8546, end: 8557 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 5n, + loc: { start: 8558, end: 8559 } + }, + { + kind: 'op_binary', + op: '>=', + left: { + kind: 'var', + name: 'exp', + loc: { start: 8561, end: 8564 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 8568, end: 8569 } + }, + loc: { start: 8561, end: 8569 } + } + ], + loc: { start: 8546, end: 8570 } + }, + loc: { start: 8546, end: 8571 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'result', + loc: { start: 8580, end: 8586 } + }, + type: undefined, + expression: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 8589, end: 8590 } + }, + loc: { start: 8576, end: 8591 } + }, + { + kind: 'statement_repeat', + iterations: { + kind: 'var', + name: 'exp', + loc: { start: 8604, end: 8607 } + }, + statements: [ + { + kind: 'statement_augmentedassign', + op: '*=', + path: { + kind: 'var', + name: 'result', + loc: { start: 8619, end: 8625 } + }, + expression: { + kind: 'var', + name: 'base', + loc: { start: 8629, end: 8633 } + }, + loc: { start: 8619, end: 8634 } + } + ], + loc: { start: 8596, end: 8640 } + }, + { + kind: 'statement_return', + expression: { + kind: 'var', + name: 'result', + loc: { start: 8652, end: 8658 } + }, + loc: { start: 8645, end: 8659 } + } + ] + }, + loc: { start: 8499, end: 8661 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'pow2', loc: { start: 9733, end: 9737 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9749, end: 9752 } + }, + loc: { start: 9749, end: 9752 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'exp', + loc: { start: 9738, end: 9741 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9743, end: 9746 } + }, + loc: { start: 9743, end: 9746 } + }, + loc: { start: 9738, end: 9746 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'POW2' ] + }, + loc: { start: 9725, end: 9761 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sign', + loc: { start: 10233, end: 10237 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10247, end: 10250 } + }, + loc: { start: 10247, end: 10250 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 10238, end: 10239 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10241, end: 10244 } + }, + loc: { start: 10241, end: 10244 } + }, + loc: { start: 10238, end: 10244 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SGN' ] + }, + loc: { start: 10225, end: 10258 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'divc', + loc: { start: 10814, end: 10818 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10836, end: 10839 } + }, + loc: { start: 10836, end: 10839 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 10819, end: 10820 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10822, end: 10825 } + }, + loc: { start: 10822, end: 10825 } + }, + loc: { start: 10819, end: 10825 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 10827, end: 10828 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10830, end: 10833 } + }, + loc: { start: 10830, end: 10833 } + }, + loc: { start: 10827, end: 10833 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DIVC' ] + }, + loc: { start: 10806, end: 10848 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'muldivc', + loc: { start: 11615, end: 11622 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11648, end: 11651 } + }, + loc: { start: 11648, end: 11651 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 11623, end: 11624 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11626, end: 11629 } + }, + loc: { start: 11626, end: 11629 } + }, + loc: { start: 11623, end: 11629 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 11631, end: 11632 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11634, end: 11637 } + }, + loc: { start: 11634, end: 11637 } + }, + loc: { start: 11631, end: 11637 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 11639, end: 11640 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11642, end: 11645 } + }, + loc: { start: 11642, end: 11645 } + }, + loc: { start: 11639, end: 11645 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULDIVC' ] + }, + loc: { start: 11607, end: 11663 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRight', + loc: { start: 12751, end: 12764 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12790, end: 12793 } + }, + loc: { start: 12790, end: 12793 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 12765, end: 12766 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12768, end: 12771 } + }, + loc: { start: 12768, end: 12771 } + }, + loc: { start: 12765, end: 12771 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 12773, end: 12774 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12776, end: 12779 } + }, + loc: { start: 12776, end: 12779 } + }, + loc: { start: 12773, end: 12779 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 12781, end: 12782 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12784, end: 12787 } + }, + loc: { start: 12784, end: 12787 } + }, + loc: { start: 12781, end: 12787 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFT' ] + }, + loc: { start: 12743, end: 12807 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRightRound', + loc: { start: 13862, end: 13880 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13906, end: 13909 } + }, + loc: { start: 13906, end: 13909 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 13881, end: 13882 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13884, end: 13887 } + }, + loc: { start: 13884, end: 13887 } + }, + loc: { start: 13881, end: 13887 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 13889, end: 13890 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13892, end: 13895 } + }, + loc: { start: 13892, end: 13895 } + }, + loc: { start: 13889, end: 13895 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 13897, end: 13898 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13900, end: 13903 } + }, + loc: { start: 13900, end: 13903 } + }, + loc: { start: 13897, end: 13903 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFTR' ] + }, + loc: { start: 13854, end: 13924 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRightCeil', + loc: { start: 14875, end: 14892 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14918, end: 14921 } + }, + loc: { start: 14918, end: 14921 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 14893, end: 14894 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14896, end: 14899 } + }, + loc: { start: 14896, end: 14899 } + }, + loc: { start: 14893, end: 14899 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 14901, end: 14902 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14904, end: 14907 } + }, + loc: { start: 14904, end: 14907 } + }, + loc: { start: 14901, end: 14907 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 14909, end: 14910 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14912, end: 14915 } + }, + loc: { start: 14912, end: 14915 } + }, + loc: { start: 14909, end: 14915 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFTC' ] + }, + loc: { start: 14867, end: 14936 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sqrt', + loc: { start: 15698, end: 15702 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15714, end: 15717 } + }, + loc: { start: 15714, end: 15717 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 15703, end: 15706 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15708, end: 15711 } + }, + loc: { start: 15708, end: 15711 } + }, + loc: { start: 15703, end: 15711 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'num', + loc: { start: 15728, end: 15731 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15735, end: 15736 } + }, + loc: { start: 15728, end: 15736 } + }, + trueStatements: [ + { + kind: 'statement_return', + expression: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15755, end: 15756 } + }, + loc: { start: 15748, end: 15757 } + } + ], + falseStatements: undefined, + loc: { start: 15724, end: 15763 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 's', + loc: { start: 15773, end: 15774 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15776, end: 15779 } + }, + loc: { start: 15776, end: 15779 } + }, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'log2', + loc: { start: 15782, end: 15786 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'num', + loc: { start: 15787, end: 15790 } + } + ], + loc: { start: 15782, end: 15791 } + }, + loc: { start: 15769, end: 15792 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'x', + loc: { start: 15801, end: 15802 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15804, end: 15807 } + }, + loc: { start: 15804, end: 15807 } + }, + expression: { + kind: 'conditional', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 's', + loc: { start: 15811, end: 15812 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15816, end: 15817 } + }, + loc: { start: 15811, end: 15817 } + }, + thenBranch: { + kind: 'op_binary', + op: '+', + left: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'num', + loc: { start: 15821, end: 15824 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15827, end: 15828 } + }, + loc: { start: 15821, end: 15828 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15832, end: 15833 } + }, + loc: { start: 15820, end: 15833 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15836, end: 15837 } + }, + loc: { start: 15820, end: 15837 } + }, + elseBranch: { + kind: 'op_binary', + op: '<<', + left: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15840, end: 15841 } + }, + right: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '+', + left: { + kind: 'var', + name: 's', + loc: { start: 15847, end: 15848 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15851, end: 15852 } + }, + loc: { start: 15847, end: 15852 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15856, end: 15857 } + }, + loc: { start: 15846, end: 15857 } + }, + loc: { start: 15840, end: 15858 } + }, + loc: { start: 15811, end: 15858 } + }, + loc: { start: 15797, end: 15860 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'q', + loc: { start: 15870, end: 15871 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15873, end: 15876 } + }, + loc: { start: 15873, end: 15876 } + }, + expression: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15879, end: 15880 } + }, + loc: { start: 15866, end: 15881 } + }, + { + kind: 'statement_until', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'q', + loc: { start: 15957, end: 15958 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15962, end: 15963 } + }, + loc: { start: 15957, end: 15963 } + }, + statements: [ + { + kind: 'statement_assign', + path: { + kind: 'var', + name: 'q', + loc: { start: 15900, end: 15901 } + }, + expression: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '-', + left: { + kind: 'static_call', + function: { + kind: 'id', + text: 'divc', + loc: { start: 15905, end: 15909 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'num', + loc: { start: 15910, end: 15913 } + }, + { + kind: 'var', + name: 'x', + loc: { start: 15915, end: 15916 } + } + ], + loc: { start: 15905, end: 15917 } + }, + right: { + kind: 'var', + name: 'x', + loc: { start: 15920, end: 15921 } + }, + loc: { start: 15905, end: 15921 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15925, end: 15926 } + }, + loc: { start: 15904, end: 15926 } + }, + loc: { start: 15900, end: 15927 } + }, + { + kind: 'statement_augmentedassign', + op: '+=', + path: { + kind: 'var', + name: 'x', + loc: { start: 15936, end: 15937 } + }, + expression: { + kind: 'var', + name: 'q', + loc: { start: 15941, end: 15942 } + }, + loc: { start: 15936, end: 15943 } + } + ], + loc: { start: 15887, end: 15965 } + }, + { + kind: 'statement_return', + expression: { + kind: 'var', + name: 'x', + loc: { start: 15978, end: 15979 } + }, + loc: { start: 15971, end: 15980 } + } + ] + }, + loc: { start: 15694, end: 15982 } + } + ] + }, + 'nativeRandomizeLt' => { + kind: 'tact', + path: 'std/internal/math.tact', + code: '// Prepare random\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Randomizes the pseudorandom number generator with the specified unsigned 256-bit `Int` `x` by mixing it with the current seed. The new seed is the unsigned 256-bit `Int` value of the SHA-256 hash of concatenated old seed and `x` in their 32-byte strings big-endian representation.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativeRandomize(42); // now, random numbers are less predictable\n' + + "/// let idk: Int = randomInt(); // ???, it's random,\n" + + '/// // but the seed was adjusted deterministically!\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify a negative value of `x`.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomize\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun nativeRandomize(x: Int) { ADDRAND }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Randomizes the random number generator with the logical time of the current transaction. Equivalent to calling `nativeRandomize(curLt())`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativeRandomizeLt(); // now, random numbers are unpredictable for users,\n' + + '/// // but still may be affected by validators or collators\n' + + '/// // as they determine the seed of the current block.\n' + + "/// let idk: Int = randomInt(); // ???, it's random!\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomizelt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomize\n' + + '/// * https://docs.tact-lang.org/ref/core-contextstate#curlt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + 'asm fun nativeRandomizeLt() { LTIME ADDRAND }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Prepares a random number generator by using `nativeRandomizeLt()`. Automatically called by `randomInt()` and `random()` functions.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativePrepareRandom(); // prepare the RNG\n' + + '/// // ... do your random things ...\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativepreparerandom\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomizelt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '/// * https://docs.tact-lang.org/ref/core-random#random\n' + + '///\n' + + '@name(__tact_prepare_random)\n' + + 'native nativePrepareRandom();\n' + + '\n' + + '// Random\n' + + '\n' + + '// Generates a new pseudo-random unsigned 256-bit integer x.\n' + + '// The algorithm is as follows: if r is the old value of the random seed,\n' + + '// considered as a 32-byte array (by constructing the big-endian representation\n' + + '// of an unsigned 256-bit integer), then its sha512(r) is computed;\n' + + "// the first 32 bytes of this hash are stored as the new value r' of the random seed,\n" + + '// and the remaining 32 bytes are returned as the next random value x.\n' + + 'asm fun nativeRandom(): Int { RANDU256 }\n' + + '\n' + + '// Generates a new pseudo-random integer z in the range 0..range−1\n' + + '// (or range..−1, if range < 0).\n' + + '// More precisely, an unsigned random value x is generated as in `nativeRandom`;\n' + + '// then z := x * range / 2^256 is computed.\n' + + 'asm fun nativeRandomInterval(max: Int): Int { RAND }\n' + + '\n' + + '/// Generates and returns a new pseudo-random unsigned 256-bit `Int` value `x`.\n' + + '///\n' + + '/// The algorithm works as follows: first, the `sha512(r)` is computed. There, `r` is an old\n' + + '/// value of the random seed, which is taken as a 32-byte array constructed from the big-endian\n' + + '/// representation of an unsigned 256-bit `Int`. The first 32 bytes of this hash are stored as the new\n' + + "/// value `r'` of the random seed, and the remaining 32 bytes are returned as the next random value `x`.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + "/// let allYourRandomBelongToUs: Int = randomInt(); // ???, it's random :)\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + 'inline fun randomInt(): Int {\n' + + ' nativePrepareRandom();\n' + + ' return nativeRandom();\n' + + '}\n' + + '\n' + + '/// Generates and returns a new pseudo-random unsigned `Int` value `x` in the provided semi-closed\n' + + '/// interval: `min` ≤ `x` < `max`, or `min` ≥ `x` > `max` if both `min` and `max` are negative.\n' + + '///\n' + + '/// Note that the `max` value is never included in the interval.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// random(42, 43); // 42, always\n' + + '/// random(0, 42); // 0-41, but never 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-random#random\n' + + '///\n' + + 'inline fun random(min: Int, max: Int): Int {\n' + + ' nativePrepareRandom();\n' + + ' return min + nativeRandomInterval(max - min);\n' + + '}\n' + + '\n' + + '// Math\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the minimum of two `Int` values `x` and `y`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// min(1, 2); // 1\n' + + '/// min(2, 2); // 2\n' + + '/// min(007, 3); // 3\n' + + '/// min(0x45, 3_0_0); // 69, nice\n' + + '/// // ↑ ↑\n' + + '/// // 69 300\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#min\n' + + '///\n' + + 'asm fun min(x: Int, y: Int): Int { MIN }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the maximum of two `Int` values `x` and `y`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// max(1, 2); // 2\n' + + '/// max(2, 2); // 2\n' + + '/// max(007, 3); // 7\n' + + '/// max(0x45, 3_0_0); // 300\n' + + '/// // ↑ ↑\n' + + '/// // 69 300\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#max\n' + + '///\n' + + 'asm fun max(x: Int, y: Int): Int { MAX }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the absolute value of the `Int` value `x`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// abs(42); // 42\n' + + '/// abs(-42); // 42\n' + + '/// abs(-(-(-42))); // 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#abs\n' + + '///\n' + + 'asm fun abs(x: Int): Int { ABS }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the logarithm of a number `num` > 0 to the base `base` ≥ 1. Results are rounded down.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// log(1000, 10); // 3, as 10^3 is 1000\n' + + '/// // ↑ ↑ ↑ ↑\n' + + '/// // num base base num\n' + + '///\n' + + '/// log(1001, 10); // 3\n' + + '/// log(999, 10); // 2\n' + + '/// try {\n' + + '/// log(-1000, 10); // exit code 5 because of the non-positive num\n' + + '/// }\n' + + '/// log(1024, 2); // 10\n' + + '/// try {\n' + + '/// log(1024, -2); // exit code 5 because the base is less than 1\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `num` value is non-positive\n' + + '/// or the given `base` value is less than 1.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log2\n' + + '///\n' + + '@name(__tact_log)\n' + + 'native log(num: Int, base: Int): Int;\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Similar to `log()`, but sets the `base` to 2.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// log2(1024); // 10, as 2^10 is 1024\n' + + '/// // ↑ ↑ ↑\n' + + '/// // num base₂ num\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `num` value is non-positive.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log2\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log.\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes/#5\n' + + '///\n' + + 'asm fun log2(num: Int): Int { DUP 5 THROWIFNOT UBITSIZE DEC }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the exponentiation involving two numbers: the `base` and the exponent (or _power_) `exp`.\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Example {\n' + + '/// // Persistent state variables\n' + + '/// p23: Int = pow(2, 3); // raises 2 to the 3rd power, which is 8\n' + + '/// one: Int = pow(5, 0); // raises 5 to the power 0, which always produces 1\n' + + '/// // works at compile-time!\n' + + '///\n' + + '/// // Internal message receiver\n' + + '/// receive() {\n' + + '/// pow(self.p23, self.one + 1); // 64, works at run-time too!\n' + + '/// try {\n' + + '/// pow(0, -1); // exit code 5: Integer out of expected range\n' + + '/// }\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `exp` value is negative.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow2\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes/#5\n' + + '///\n' + + 'inline fun pow(base: Int, exp: Int): Int {\n' + + ' throwUnless(5, exp >= 0);\n' + + ' let result = 1;\n' + + ' repeat (exp) {\n' + + ' result *= base;\n' + + ' }\n' + + ' return result;\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Similar to `pow()`, but sets the `base` to 2.\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Example {\n' + + '/// // Persistent state variables\n' + + '/// p23: Int = pow2(3); // raises 2 to the 3rd power, which is 8\n' + + '/// one: Int = pow2(0); // raises 2 to the power 0, which always produces 1\n' + + '/// // works at compile-time!\n' + + '///\n' + + '/// // Internal message receiver, which accepts message ExtMsg\n' + + '/// receive() {\n' + + '/// pow2(self.one + 1); // 4, works at run-time too!\n' + + '/// try {\n' + + '/// pow(-1); // exit code 5: Integer out of expected range\n' + + '/// }\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify a negative value of `exp`.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow2\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun pow2(exp: Int): Int { POW2 }\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Computes and returns the sign of the `Int` value `x`. Produces 1 if the `x` is positive, -1 if the `x` is negative, and 0 if the `x` is 0.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// '... 5983 more characters, + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomize', + loc: { start: 965, end: 980 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { kind: 'id', text: 'x', loc: { start: 981, end: 982 } }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 984, end: 987 } + }, + loc: { start: 984, end: 987 } + }, + loc: { start: 981, end: 987 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ADDRAND' ] + }, + loc: { start: 957, end: 1000 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomizeLt', + loc: { start: 1822, end: 1839 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LTIME ADDRAND' ] + }, + loc: { start: 1814, end: 1859 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 2466, end: 2485 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_prepare_random', + loc: { start: 2436, end: 2457 } + } + }, + loc: { start: 2430, end: 2488 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandom', + loc: { start: 2949, end: 2961 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2965, end: 2968 } + }, + loc: { start: 2965, end: 2968 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RANDU256' ] + }, + loc: { start: 2941, end: 2981 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomInterval', + loc: { start: 3216, end: 3236 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3248, end: 3251 } + }, + loc: { start: 3248, end: 3251 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'max', + loc: { start: 3237, end: 3240 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3242, end: 3245 } + }, + loc: { start: 3242, end: 3245 } + }, + loc: { start: 3237, end: 3245 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RAND' ] + }, + loc: { start: 3208, end: 3260 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'randomInt', + loc: { start: 3953, end: 3962 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3966, end: 3969 } + }, + loc: { start: 3966, end: 3969 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 3976, end: 3995 } + }, + typeArgs: [], + args: [], + loc: { start: 3976, end: 3997 } + }, + loc: { start: 3976, end: 3998 } + }, + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativeRandom', + loc: { start: 4010, end: 4022 } + }, + typeArgs: [], + args: [], + loc: { start: 4010, end: 4024 } + }, + loc: { start: 4003, end: 4025 } + } + ] + }, + loc: { start: 3942, end: 4027 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'random', + loc: { start: 4505, end: 4511 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4533, end: 4536 } + }, + loc: { start: 4533, end: 4536 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'min', + loc: { start: 4512, end: 4515 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4517, end: 4520 } + }, + loc: { start: 4517, end: 4520 } + }, + loc: { start: 4512, end: 4520 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'max', + loc: { start: 4522, end: 4525 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4527, end: 4530 } + }, + loc: { start: 4527, end: 4530 } + }, + loc: { start: 4522, end: 4530 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 4543, end: 4562 } + }, + typeArgs: [], + args: [], + loc: { start: 4543, end: 4564 } + }, + loc: { start: 4543, end: 4565 } + }, + { + kind: 'statement_return', + expression: { + kind: 'op_binary', + op: '+', + left: { + kind: 'var', + name: 'min', + loc: { start: 4577, end: 4580 } + }, + right: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativeRandomInterval', + loc: { start: 4583, end: 4603 } + }, + typeArgs: [], + args: [ + { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'max', + loc: { start: 4604, end: 4607 } + }, + right: { + kind: 'var', + name: 'min', + loc: { start: 4610, end: 4613 } + }, + loc: { start: 4604, end: 4613 } + } + ], + loc: { start: 4583, end: 4614 } + }, + loc: { start: 4577, end: 4614 } + }, + loc: { start: 4570, end: 4615 } + } + ] + }, + loc: { start: 4494, end: 4617 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'min', loc: { start: 5017, end: 5020 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5038, end: 5041 } + }, + loc: { start: 5038, end: 5041 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5021, end: 5022 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5024, end: 5027 } + }, + loc: { start: 5024, end: 5027 } + }, + loc: { start: 5021, end: 5027 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 5029, end: 5030 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5032, end: 5035 } + }, + loc: { start: 5032, end: 5035 } + }, + loc: { start: 5029, end: 5035 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MIN' ] + }, + loc: { start: 5009, end: 5049 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'max', loc: { start: 5435, end: 5438 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5456, end: 5459 } + }, + loc: { start: 5456, end: 5459 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5439, end: 5440 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5442, end: 5445 } + }, + loc: { start: 5442, end: 5445 } + }, + loc: { start: 5439, end: 5445 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 5447, end: 5448 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5450, end: 5453 } + }, + loc: { start: 5450, end: 5453 } + }, + loc: { start: 5447, end: 5453 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MAX' ] + }, + loc: { start: 5427, end: 5467 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'abs', loc: { start: 5773, end: 5776 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5786, end: 5789 } + }, + loc: { start: 5786, end: 5789 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5777, end: 5778 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5780, end: 5783 } + }, + loc: { start: 5780, end: 5783 } + }, + loc: { start: 5777, end: 5783 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ABS' ] + }, + loc: { start: 5765, end: 5797 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'log', loc: { start: 6721, end: 6724 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6747, end: 6750 } + }, + loc: { start: 6747, end: 6750 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 6725, end: 6728 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6730, end: 6733 } + }, + loc: { start: 6730, end: 6733 } + }, + loc: { start: 6725, end: 6733 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'base', + loc: { start: 6735, end: 6739 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6741, end: 6744 } + }, + loc: { start: 6741, end: 6744 } + }, + loc: { start: 6735, end: 6744 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_log', + loc: { start: 6702, end: 6712 } + } + }, + loc: { start: 6696, end: 6751 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'log2', loc: { start: 7341, end: 7345 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7357, end: 7360 } + }, + loc: { start: 7357, end: 7360 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 7346, end: 7349 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7351, end: 7354 } + }, + loc: { start: 7351, end: 7354 } + }, + loc: { start: 7346, end: 7354 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DUP 5 THROWIFNOT UBITSIZE DEC' ] + }, + loc: { start: 7333, end: 7394 } + }, + { + kind: 'function', + inline: true, + name: { kind: 'id', text: 'pow', loc: { start: 8510, end: 8513 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8536, end: 8539 } + }, + loc: { start: 8536, end: 8539 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'base', + loc: { start: 8514, end: 8518 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8520, end: 8523 } + }, + loc: { start: 8520, end: 8523 } + }, + loc: { start: 8514, end: 8523 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'exp', + loc: { start: 8525, end: 8528 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8530, end: 8533 } + }, + loc: { start: 8530, end: 8533 } + }, + loc: { start: 8525, end: 8533 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throwUnless', + loc: { start: 8546, end: 8557 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 5n, + loc: { start: 8558, end: 8559 } + }, + { + kind: 'op_binary', + op: '>=', + left: { + kind: 'var', + name: 'exp', + loc: { start: 8561, end: 8564 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 8568, end: 8569 } + }, + loc: { start: 8561, end: 8569 } + } + ], + loc: { start: 8546, end: 8570 } + }, + loc: { start: 8546, end: 8571 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'result', + loc: { start: 8580, end: 8586 } + }, + type: undefined, + expression: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 8589, end: 8590 } + }, + loc: { start: 8576, end: 8591 } + }, + { + kind: 'statement_repeat', + iterations: { + kind: 'var', + name: 'exp', + loc: { start: 8604, end: 8607 } + }, + statements: [ + { + kind: 'statement_augmentedassign', + op: '*=', + path: { + kind: 'var', + name: 'result', + loc: { start: 8619, end: 8625 } + }, + expression: { + kind: 'var', + name: 'base', + loc: { start: 8629, end: 8633 } + }, + loc: { start: 8619, end: 8634 } + } + ], + loc: { start: 8596, end: 8640 } + }, + { + kind: 'statement_return', + expression: { + kind: 'var', + name: 'result', + loc: { start: 8652, end: 8658 } + }, + loc: { start: 8645, end: 8659 } + } + ] + }, + loc: { start: 8499, end: 8661 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'pow2', loc: { start: 9733, end: 9737 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9749, end: 9752 } + }, + loc: { start: 9749, end: 9752 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'exp', + loc: { start: 9738, end: 9741 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9743, end: 9746 } + }, + loc: { start: 9743, end: 9746 } + }, + loc: { start: 9738, end: 9746 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'POW2' ] + }, + loc: { start: 9725, end: 9761 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sign', + loc: { start: 10233, end: 10237 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10247, end: 10250 } + }, + loc: { start: 10247, end: 10250 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 10238, end: 10239 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10241, end: 10244 } + }, + loc: { start: 10241, end: 10244 } + }, + loc: { start: 10238, end: 10244 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SGN' ] + }, + loc: { start: 10225, end: 10258 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'divc', + loc: { start: 10814, end: 10818 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10836, end: 10839 } + }, + loc: { start: 10836, end: 10839 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 10819, end: 10820 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10822, end: 10825 } + }, + loc: { start: 10822, end: 10825 } + }, + loc: { start: 10819, end: 10825 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 10827, end: 10828 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10830, end: 10833 } + }, + loc: { start: 10830, end: 10833 } + }, + loc: { start: 10827, end: 10833 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DIVC' ] + }, + loc: { start: 10806, end: 10848 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'muldivc', + loc: { start: 11615, end: 11622 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11648, end: 11651 } + }, + loc: { start: 11648, end: 11651 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 11623, end: 11624 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11626, end: 11629 } + }, + loc: { start: 11626, end: 11629 } + }, + loc: { start: 11623, end: 11629 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 11631, end: 11632 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11634, end: 11637 } + }, + loc: { start: 11634, end: 11637 } + }, + loc: { start: 11631, end: 11637 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 11639, end: 11640 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11642, end: 11645 } + }, + loc: { start: 11642, end: 11645 } + }, + loc: { start: 11639, end: 11645 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULDIVC' ] + }, + loc: { start: 11607, end: 11663 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRight', + loc: { start: 12751, end: 12764 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12790, end: 12793 } + }, + loc: { start: 12790, end: 12793 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 12765, end: 12766 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12768, end: 12771 } + }, + loc: { start: 12768, end: 12771 } + }, + loc: { start: 12765, end: 12771 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 12773, end: 12774 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12776, end: 12779 } + }, + loc: { start: 12776, end: 12779 } + }, + loc: { start: 12773, end: 12779 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 12781, end: 12782 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12784, end: 12787 } + }, + loc: { start: 12784, end: 12787 } + }, + loc: { start: 12781, end: 12787 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFT' ] + }, + loc: { start: 12743, end: 12807 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRightRound', + loc: { start: 13862, end: 13880 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13906, end: 13909 } + }, + loc: { start: 13906, end: 13909 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 13881, end: 13882 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13884, end: 13887 } + }, + loc: { start: 13884, end: 13887 } + }, + loc: { start: 13881, end: 13887 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 13889, end: 13890 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13892, end: 13895 } + }, + loc: { start: 13892, end: 13895 } + }, + loc: { start: 13889, end: 13895 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 13897, end: 13898 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13900, end: 13903 } + }, + loc: { start: 13900, end: 13903 } + }, + loc: { start: 13897, end: 13903 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFTR' ] + }, + loc: { start: 13854, end: 13924 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRightCeil', + loc: { start: 14875, end: 14892 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14918, end: 14921 } + }, + loc: { start: 14918, end: 14921 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 14893, end: 14894 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14896, end: 14899 } + }, + loc: { start: 14896, end: 14899 } + }, + loc: { start: 14893, end: 14899 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 14901, end: 14902 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14904, end: 14907 } + }, + loc: { start: 14904, end: 14907 } + }, + loc: { start: 14901, end: 14907 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 14909, end: 14910 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14912, end: 14915 } + }, + loc: { start: 14912, end: 14915 } + }, + loc: { start: 14909, end: 14915 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFTC' ] + }, + loc: { start: 14867, end: 14936 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sqrt', + loc: { start: 15698, end: 15702 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15714, end: 15717 } + }, + loc: { start: 15714, end: 15717 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 15703, end: 15706 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15708, end: 15711 } + }, + loc: { start: 15708, end: 15711 } + }, + loc: { start: 15703, end: 15711 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'num', + loc: { start: 15728, end: 15731 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15735, end: 15736 } + }, + loc: { start: 15728, end: 15736 } + }, + trueStatements: [ + { + kind: 'statement_return', + expression: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15755, end: 15756 } + }, + loc: { start: 15748, end: 15757 } + } + ], + falseStatements: undefined, + loc: { start: 15724, end: 15763 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 's', + loc: { start: 15773, end: 15774 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15776, end: 15779 } + }, + loc: { start: 15776, end: 15779 } + }, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'log2', + loc: { start: 15782, end: 15786 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'num', + loc: { start: 15787, end: 15790 } + } + ], + loc: { start: 15782, end: 15791 } + }, + loc: { start: 15769, end: 15792 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'x', + loc: { start: 15801, end: 15802 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15804, end: 15807 } + }, + loc: { start: 15804, end: 15807 } + }, + expression: { + kind: 'conditional', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 's', + loc: { start: 15811, end: 15812 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15816, end: 15817 } + }, + loc: { start: 15811, end: 15817 } + }, + thenBranch: { + kind: 'op_binary', + op: '+', + left: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'num', + loc: { start: 15821, end: 15824 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15827, end: 15828 } + }, + loc: { start: 15821, end: 15828 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15832, end: 15833 } + }, + loc: { start: 15820, end: 15833 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15836, end: 15837 } + }, + loc: { start: 15820, end: 15837 } + }, + elseBranch: { + kind: 'op_binary', + op: '<<', + left: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15840, end: 15841 } + }, + right: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '+', + left: { + kind: 'var', + name: 's', + loc: { start: 15847, end: 15848 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15851, end: 15852 } + }, + loc: { start: 15847, end: 15852 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15856, end: 15857 } + }, + loc: { start: 15846, end: 15857 } + }, + loc: { start: 15840, end: 15858 } + }, + loc: { start: 15811, end: 15858 } + }, + loc: { start: 15797, end: 15860 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'q', + loc: { start: 15870, end: 15871 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15873, end: 15876 } + }, + loc: { start: 15873, end: 15876 } + }, + expression: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15879, end: 15880 } + }, + loc: { start: 15866, end: 15881 } + }, + { + kind: 'statement_until', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'q', + loc: { start: 15957, end: 15958 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15962, end: 15963 } + }, + loc: { start: 15957, end: 15963 } + }, + statements: [ + { + kind: 'statement_assign', + path: { + kind: 'var', + name: 'q', + loc: { start: 15900, end: 15901 } + }, + expression: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '-', + left: { + kind: 'static_call', + function: { + kind: 'id', + text: 'divc', + loc: { start: 15905, end: 15909 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'num', + loc: { start: 15910, end: 15913 } + }, + { + kind: 'var', + name: 'x', + loc: { start: 15915, end: 15916 } + } + ], + loc: { start: 15905, end: 15917 } + }, + right: { + kind: 'var', + name: 'x', + loc: { start: 15920, end: 15921 } + }, + loc: { start: 15905, end: 15921 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15925, end: 15926 } + }, + loc: { start: 15904, end: 15926 } + }, + loc: { start: 15900, end: 15927 } + }, + { + kind: 'statement_augmentedassign', + op: '+=', + path: { + kind: 'var', + name: 'x', + loc: { start: 15936, end: 15937 } + }, + expression: { + kind: 'var', + name: 'q', + loc: { start: 15941, end: 15942 } + }, + loc: { start: 15936, end: 15943 } + } + ], + loc: { start: 15887, end: 15965 } + }, + { + kind: 'statement_return', + expression: { + kind: 'var', + name: 'x', + loc: { start: 15978, end: 15979 } + }, + loc: { start: 15971, end: 15980 } + } + ] + }, + loc: { start: 15694, end: 15982 } + } + ] + }, + 'nativePrepareRandom' => { + kind: 'tact', + path: 'std/internal/math.tact', + code: '// Prepare random\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Randomizes the pseudorandom number generator with the specified unsigned 256-bit `Int` `x` by mixing it with the current seed. The new seed is the unsigned 256-bit `Int` value of the SHA-256 hash of concatenated old seed and `x` in their 32-byte strings big-endian representation.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativeRandomize(42); // now, random numbers are less predictable\n' + + "/// let idk: Int = randomInt(); // ???, it's random,\n" + + '/// // but the seed was adjusted deterministically!\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify a negative value of `x`.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomize\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun nativeRandomize(x: Int) { ADDRAND }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Randomizes the random number generator with the logical time of the current transaction. Equivalent to calling `nativeRandomize(curLt())`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativeRandomizeLt(); // now, random numbers are unpredictable for users,\n' + + '/// // but still may be affected by validators or collators\n' + + '/// // as they determine the seed of the current block.\n' + + "/// let idk: Int = randomInt(); // ???, it's random!\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomizelt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomize\n' + + '/// * https://docs.tact-lang.org/ref/core-contextstate#curlt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + 'asm fun nativeRandomizeLt() { LTIME ADDRAND }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Prepares a random number generator by using `nativeRandomizeLt()`. Automatically called by `randomInt()` and `random()` functions.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativePrepareRandom(); // prepare the RNG\n' + + '/// // ... do your random things ...\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativepreparerandom\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomizelt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '/// * https://docs.tact-lang.org/ref/core-random#random\n' + + '///\n' + + '@name(__tact_prepare_random)\n' + + 'native nativePrepareRandom();\n' + + '\n' + + '// Random\n' + + '\n' + + '// Generates a new pseudo-random unsigned 256-bit integer x.\n' + + '// The algorithm is as follows: if r is the old value of the random seed,\n' + + '// considered as a 32-byte array (by constructing the big-endian representation\n' + + '// of an unsigned 256-bit integer), then its sha512(r) is computed;\n' + + "// the first 32 bytes of this hash are stored as the new value r' of the random seed,\n" + + '// and the remaining 32 bytes are returned as the next random value x.\n' + + 'asm fun nativeRandom(): Int { RANDU256 }\n' + + '\n' + + '// Generates a new pseudo-random integer z in the range 0..range−1\n' + + '// (or range..−1, if range < 0).\n' + + '// More precisely, an unsigned random value x is generated as in `nativeRandom`;\n' + + '// then z := x * range / 2^256 is computed.\n' + + 'asm fun nativeRandomInterval(max: Int): Int { RAND }\n' + + '\n' + + '/// Generates and returns a new pseudo-random unsigned 256-bit `Int` value `x`.\n' + + '///\n' + + '/// The algorithm works as follows: first, the `sha512(r)` is computed. There, `r` is an old\n' + + '/// value of the random seed, which is taken as a 32-byte array constructed from the big-endian\n' + + '/// representation of an unsigned 256-bit `Int`. The first 32 bytes of this hash are stored as the new\n' + + "/// value `r'` of the random seed, and the remaining 32 bytes are returned as the next random value `x`.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + "/// let allYourRandomBelongToUs: Int = randomInt(); // ???, it's random :)\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + 'inline fun randomInt(): Int {\n' + + ' nativePrepareRandom();\n' + + ' return nativeRandom();\n' + + '}\n' + + '\n' + + '/// Generates and returns a new pseudo-random unsigned `Int` value `x` in the provided semi-closed\n' + + '/// interval: `min` ≤ `x` < `max`, or `min` ≥ `x` > `max` if both `min` and `max` are negative.\n' + + '///\n' + + '/// Note that the `max` value is never included in the interval.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// random(42, 43); // 42, always\n' + + '/// random(0, 42); // 0-41, but never 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-random#random\n' + + '///\n' + + 'inline fun random(min: Int, max: Int): Int {\n' + + ' nativePrepareRandom();\n' + + ' return min + nativeRandomInterval(max - min);\n' + + '}\n' + + '\n' + + '// Math\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the minimum of two `Int` values `x` and `y`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// min(1, 2); // 1\n' + + '/// min(2, 2); // 2\n' + + '/// min(007, 3); // 3\n' + + '/// min(0x45, 3_0_0); // 69, nice\n' + + '/// // ↑ ↑\n' + + '/// // 69 300\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#min\n' + + '///\n' + + 'asm fun min(x: Int, y: Int): Int { MIN }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the maximum of two `Int` values `x` and `y`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// max(1, 2); // 2\n' + + '/// max(2, 2); // 2\n' + + '/// max(007, 3); // 7\n' + + '/// max(0x45, 3_0_0); // 300\n' + + '/// // ↑ ↑\n' + + '/// // 69 300\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#max\n' + + '///\n' + + 'asm fun max(x: Int, y: Int): Int { MAX }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the absolute value of the `Int` value `x`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// abs(42); // 42\n' + + '/// abs(-42); // 42\n' + + '/// abs(-(-(-42))); // 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#abs\n' + + '///\n' + + 'asm fun abs(x: Int): Int { ABS }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the logarithm of a number `num` > 0 to the base `base` ≥ 1. Results are rounded down.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// log(1000, 10); // 3, as 10^3 is 1000\n' + + '/// // ↑ ↑ ↑ ↑\n' + + '/// // num base base num\n' + + '///\n' + + '/// log(1001, 10); // 3\n' + + '/// log(999, 10); // 2\n' + + '/// try {\n' + + '/// log(-1000, 10); // exit code 5 because of the non-positive num\n' + + '/// }\n' + + '/// log(1024, 2); // 10\n' + + '/// try {\n' + + '/// log(1024, -2); // exit code 5 because the base is less than 1\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `num` value is non-positive\n' + + '/// or the given `base` value is less than 1.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log2\n' + + '///\n' + + '@name(__tact_log)\n' + + 'native log(num: Int, base: Int): Int;\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Similar to `log()`, but sets the `base` to 2.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// log2(1024); // 10, as 2^10 is 1024\n' + + '/// // ↑ ↑ ↑\n' + + '/// // num base₂ num\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `num` value is non-positive.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log2\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log.\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes/#5\n' + + '///\n' + + 'asm fun log2(num: Int): Int { DUP 5 THROWIFNOT UBITSIZE DEC }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the exponentiation involving two numbers: the `base` and the exponent (or _power_) `exp`.\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Example {\n' + + '/// // Persistent state variables\n' + + '/// p23: Int = pow(2, 3); // raises 2 to the 3rd power, which is 8\n' + + '/// one: Int = pow(5, 0); // raises 5 to the power 0, which always produces 1\n' + + '/// // works at compile-time!\n' + + '///\n' + + '/// // Internal message receiver\n' + + '/// receive() {\n' + + '/// pow(self.p23, self.one + 1); // 64, works at run-time too!\n' + + '/// try {\n' + + '/// pow(0, -1); // exit code 5: Integer out of expected range\n' + + '/// }\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `exp` value is negative.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow2\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes/#5\n' + + '///\n' + + 'inline fun pow(base: Int, exp: Int): Int {\n' + + ' throwUnless(5, exp >= 0);\n' + + ' let result = 1;\n' + + ' repeat (exp) {\n' + + ' result *= base;\n' + + ' }\n' + + ' return result;\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Similar to `pow()`, but sets the `base` to 2.\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Example {\n' + + '/// // Persistent state variables\n' + + '/// p23: Int = pow2(3); // raises 2 to the 3rd power, which is 8\n' + + '/// one: Int = pow2(0); // raises 2 to the power 0, which always produces 1\n' + + '/// // works at compile-time!\n' + + '///\n' + + '/// // Internal message receiver, which accepts message ExtMsg\n' + + '/// receive() {\n' + + '/// pow2(self.one + 1); // 4, works at run-time too!\n' + + '/// try {\n' + + '/// pow(-1); // exit code 5: Integer out of expected range\n' + + '/// }\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify a negative value of `exp`.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow2\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun pow2(exp: Int): Int { POW2 }\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Computes and returns the sign of the `Int` value `x`. Produces 1 if the `x` is positive, -1 if the `x` is negative, and 0 if the `x` is 0.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// '... 5983 more characters, + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomize', + loc: { start: 965, end: 980 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { kind: 'id', text: 'x', loc: { start: 981, end: 982 } }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 984, end: 987 } + }, + loc: { start: 984, end: 987 } + }, + loc: { start: 981, end: 987 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ADDRAND' ] + }, + loc: { start: 957, end: 1000 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomizeLt', + loc: { start: 1822, end: 1839 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LTIME ADDRAND' ] + }, + loc: { start: 1814, end: 1859 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 2466, end: 2485 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_prepare_random', + loc: { start: 2436, end: 2457 } + } + }, + loc: { start: 2430, end: 2488 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandom', + loc: { start: 2949, end: 2961 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2965, end: 2968 } + }, + loc: { start: 2965, end: 2968 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RANDU256' ] + }, + loc: { start: 2941, end: 2981 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomInterval', + loc: { start: 3216, end: 3236 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3248, end: 3251 } + }, + loc: { start: 3248, end: 3251 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'max', + loc: { start: 3237, end: 3240 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3242, end: 3245 } + }, + loc: { start: 3242, end: 3245 } + }, + loc: { start: 3237, end: 3245 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RAND' ] + }, + loc: { start: 3208, end: 3260 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'randomInt', + loc: { start: 3953, end: 3962 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3966, end: 3969 } + }, + loc: { start: 3966, end: 3969 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 3976, end: 3995 } + }, + typeArgs: [], + args: [], + loc: { start: 3976, end: 3997 } + }, + loc: { start: 3976, end: 3998 } + }, + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativeRandom', + loc: { start: 4010, end: 4022 } + }, + typeArgs: [], + args: [], + loc: { start: 4010, end: 4024 } + }, + loc: { start: 4003, end: 4025 } + } + ] + }, + loc: { start: 3942, end: 4027 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'random', + loc: { start: 4505, end: 4511 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4533, end: 4536 } + }, + loc: { start: 4533, end: 4536 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'min', + loc: { start: 4512, end: 4515 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4517, end: 4520 } + }, + loc: { start: 4517, end: 4520 } + }, + loc: { start: 4512, end: 4520 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'max', + loc: { start: 4522, end: 4525 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4527, end: 4530 } + }, + loc: { start: 4527, end: 4530 } + }, + loc: { start: 4522, end: 4530 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 4543, end: 4562 } + }, + typeArgs: [], + args: [], + loc: { start: 4543, end: 4564 } + }, + loc: { start: 4543, end: 4565 } + }, + { + kind: 'statement_return', + expression: { + kind: 'op_binary', + op: '+', + left: { + kind: 'var', + name: 'min', + loc: { start: 4577, end: 4580 } + }, + right: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativeRandomInterval', + loc: { start: 4583, end: 4603 } + }, + typeArgs: [], + args: [ + { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'max', + loc: { start: 4604, end: 4607 } + }, + right: { + kind: 'var', + name: 'min', + loc: { start: 4610, end: 4613 } + }, + loc: { start: 4604, end: 4613 } + } + ], + loc: { start: 4583, end: 4614 } + }, + loc: { start: 4577, end: 4614 } + }, + loc: { start: 4570, end: 4615 } + } + ] + }, + loc: { start: 4494, end: 4617 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'min', loc: { start: 5017, end: 5020 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5038, end: 5041 } + }, + loc: { start: 5038, end: 5041 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5021, end: 5022 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5024, end: 5027 } + }, + loc: { start: 5024, end: 5027 } + }, + loc: { start: 5021, end: 5027 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 5029, end: 5030 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5032, end: 5035 } + }, + loc: { start: 5032, end: 5035 } + }, + loc: { start: 5029, end: 5035 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MIN' ] + }, + loc: { start: 5009, end: 5049 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'max', loc: { start: 5435, end: 5438 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5456, end: 5459 } + }, + loc: { start: 5456, end: 5459 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5439, end: 5440 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5442, end: 5445 } + }, + loc: { start: 5442, end: 5445 } + }, + loc: { start: 5439, end: 5445 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 5447, end: 5448 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5450, end: 5453 } + }, + loc: { start: 5450, end: 5453 } + }, + loc: { start: 5447, end: 5453 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MAX' ] + }, + loc: { start: 5427, end: 5467 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'abs', loc: { start: 5773, end: 5776 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5786, end: 5789 } + }, + loc: { start: 5786, end: 5789 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5777, end: 5778 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5780, end: 5783 } + }, + loc: { start: 5780, end: 5783 } + }, + loc: { start: 5777, end: 5783 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ABS' ] + }, + loc: { start: 5765, end: 5797 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'log', loc: { start: 6721, end: 6724 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6747, end: 6750 } + }, + loc: { start: 6747, end: 6750 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 6725, end: 6728 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6730, end: 6733 } + }, + loc: { start: 6730, end: 6733 } + }, + loc: { start: 6725, end: 6733 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'base', + loc: { start: 6735, end: 6739 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6741, end: 6744 } + }, + loc: { start: 6741, end: 6744 } + }, + loc: { start: 6735, end: 6744 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_log', + loc: { start: 6702, end: 6712 } + } + }, + loc: { start: 6696, end: 6751 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'log2', loc: { start: 7341, end: 7345 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7357, end: 7360 } + }, + loc: { start: 7357, end: 7360 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 7346, end: 7349 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7351, end: 7354 } + }, + loc: { start: 7351, end: 7354 } + }, + loc: { start: 7346, end: 7354 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DUP 5 THROWIFNOT UBITSIZE DEC' ] + }, + loc: { start: 7333, end: 7394 } + }, + { + kind: 'function', + inline: true, + name: { kind: 'id', text: 'pow', loc: { start: 8510, end: 8513 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8536, end: 8539 } + }, + loc: { start: 8536, end: 8539 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'base', + loc: { start: 8514, end: 8518 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8520, end: 8523 } + }, + loc: { start: 8520, end: 8523 } + }, + loc: { start: 8514, end: 8523 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'exp', + loc: { start: 8525, end: 8528 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8530, end: 8533 } + }, + loc: { start: 8530, end: 8533 } + }, + loc: { start: 8525, end: 8533 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throwUnless', + loc: { start: 8546, end: 8557 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 5n, + loc: { start: 8558, end: 8559 } + }, + { + kind: 'op_binary', + op: '>=', + left: { + kind: 'var', + name: 'exp', + loc: { start: 8561, end: 8564 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 8568, end: 8569 } + }, + loc: { start: 8561, end: 8569 } + } + ], + loc: { start: 8546, end: 8570 } + }, + loc: { start: 8546, end: 8571 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'result', + loc: { start: 8580, end: 8586 } + }, + type: undefined, + expression: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 8589, end: 8590 } + }, + loc: { start: 8576, end: 8591 } + }, + { + kind: 'statement_repeat', + iterations: { + kind: 'var', + name: 'exp', + loc: { start: 8604, end: 8607 } + }, + statements: [ + { + kind: 'statement_augmentedassign', + op: '*=', + path: { + kind: 'var', + name: 'result', + loc: { start: 8619, end: 8625 } + }, + expression: { + kind: 'var', + name: 'base', + loc: { start: 8629, end: 8633 } + }, + loc: { start: 8619, end: 8634 } + } + ], + loc: { start: 8596, end: 8640 } + }, + { + kind: 'statement_return', + expression: { + kind: 'var', + name: 'result', + loc: { start: 8652, end: 8658 } + }, + loc: { start: 8645, end: 8659 } + } + ] + }, + loc: { start: 8499, end: 8661 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'pow2', loc: { start: 9733, end: 9737 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9749, end: 9752 } + }, + loc: { start: 9749, end: 9752 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'exp', + loc: { start: 9738, end: 9741 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9743, end: 9746 } + }, + loc: { start: 9743, end: 9746 } + }, + loc: { start: 9738, end: 9746 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'POW2' ] + }, + loc: { start: 9725, end: 9761 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sign', + loc: { start: 10233, end: 10237 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10247, end: 10250 } + }, + loc: { start: 10247, end: 10250 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 10238, end: 10239 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10241, end: 10244 } + }, + loc: { start: 10241, end: 10244 } + }, + loc: { start: 10238, end: 10244 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SGN' ] + }, + loc: { start: 10225, end: 10258 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'divc', + loc: { start: 10814, end: 10818 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10836, end: 10839 } + }, + loc: { start: 10836, end: 10839 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 10819, end: 10820 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10822, end: 10825 } + }, + loc: { start: 10822, end: 10825 } + }, + loc: { start: 10819, end: 10825 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 10827, end: 10828 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10830, end: 10833 } + }, + loc: { start: 10830, end: 10833 } + }, + loc: { start: 10827, end: 10833 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DIVC' ] + }, + loc: { start: 10806, end: 10848 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'muldivc', + loc: { start: 11615, end: 11622 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11648, end: 11651 } + }, + loc: { start: 11648, end: 11651 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 11623, end: 11624 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11626, end: 11629 } + }, + loc: { start: 11626, end: 11629 } + }, + loc: { start: 11623, end: 11629 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 11631, end: 11632 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11634, end: 11637 } + }, + loc: { start: 11634, end: 11637 } + }, + loc: { start: 11631, end: 11637 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 11639, end: 11640 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11642, end: 11645 } + }, + loc: { start: 11642, end: 11645 } + }, + loc: { start: 11639, end: 11645 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULDIVC' ] + }, + loc: { start: 11607, end: 11663 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRight', + loc: { start: 12751, end: 12764 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12790, end: 12793 } + }, + loc: { start: 12790, end: 12793 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 12765, end: 12766 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12768, end: 12771 } + }, + loc: { start: 12768, end: 12771 } + }, + loc: { start: 12765, end: 12771 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 12773, end: 12774 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12776, end: 12779 } + }, + loc: { start: 12776, end: 12779 } + }, + loc: { start: 12773, end: 12779 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 12781, end: 12782 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12784, end: 12787 } + }, + loc: { start: 12784, end: 12787 } + }, + loc: { start: 12781, end: 12787 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFT' ] + }, + loc: { start: 12743, end: 12807 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRightRound', + loc: { start: 13862, end: 13880 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13906, end: 13909 } + }, + loc: { start: 13906, end: 13909 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 13881, end: 13882 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13884, end: 13887 } + }, + loc: { start: 13884, end: 13887 } + }, + loc: { start: 13881, end: 13887 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 13889, end: 13890 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13892, end: 13895 } + }, + loc: { start: 13892, end: 13895 } + }, + loc: { start: 13889, end: 13895 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 13897, end: 13898 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13900, end: 13903 } + }, + loc: { start: 13900, end: 13903 } + }, + loc: { start: 13897, end: 13903 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFTR' ] + }, + loc: { start: 13854, end: 13924 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRightCeil', + loc: { start: 14875, end: 14892 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14918, end: 14921 } + }, + loc: { start: 14918, end: 14921 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 14893, end: 14894 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14896, end: 14899 } + }, + loc: { start: 14896, end: 14899 } + }, + loc: { start: 14893, end: 14899 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 14901, end: 14902 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14904, end: 14907 } + }, + loc: { start: 14904, end: 14907 } + }, + loc: { start: 14901, end: 14907 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 14909, end: 14910 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14912, end: 14915 } + }, + loc: { start: 14912, end: 14915 } + }, + loc: { start: 14909, end: 14915 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFTC' ] + }, + loc: { start: 14867, end: 14936 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sqrt', + loc: { start: 15698, end: 15702 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15714, end: 15717 } + }, + loc: { start: 15714, end: 15717 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 15703, end: 15706 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15708, end: 15711 } + }, + loc: { start: 15708, end: 15711 } + }, + loc: { start: 15703, end: 15711 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'num', + loc: { start: 15728, end: 15731 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15735, end: 15736 } + }, + loc: { start: 15728, end: 15736 } + }, + trueStatements: [ + { + kind: 'statement_return', + expression: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15755, end: 15756 } + }, + loc: { start: 15748, end: 15757 } + } + ], + falseStatements: undefined, + loc: { start: 15724, end: 15763 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 's', + loc: { start: 15773, end: 15774 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15776, end: 15779 } + }, + loc: { start: 15776, end: 15779 } + }, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'log2', + loc: { start: 15782, end: 15786 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'num', + loc: { start: 15787, end: 15790 } + } + ], + loc: { start: 15782, end: 15791 } + }, + loc: { start: 15769, end: 15792 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'x', + loc: { start: 15801, end: 15802 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15804, end: 15807 } + }, + loc: { start: 15804, end: 15807 } + }, + expression: { + kind: 'conditional', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 's', + loc: { start: 15811, end: 15812 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15816, end: 15817 } + }, + loc: { start: 15811, end: 15817 } + }, + thenBranch: { + kind: 'op_binary', + op: '+', + left: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'num', + loc: { start: 15821, end: 15824 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15827, end: 15828 } + }, + loc: { start: 15821, end: 15828 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15832, end: 15833 } + }, + loc: { start: 15820, end: 15833 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15836, end: 15837 } + }, + loc: { start: 15820, end: 15837 } + }, + elseBranch: { + kind: 'op_binary', + op: '<<', + left: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15840, end: 15841 } + }, + right: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '+', + left: { + kind: 'var', + name: 's', + loc: { start: 15847, end: 15848 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15851, end: 15852 } + }, + loc: { start: 15847, end: 15852 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15856, end: 15857 } + }, + loc: { start: 15846, end: 15857 } + }, + loc: { start: 15840, end: 15858 } + }, + loc: { start: 15811, end: 15858 } + }, + loc: { start: 15797, end: 15860 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'q', + loc: { start: 15870, end: 15871 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15873, end: 15876 } + }, + loc: { start: 15873, end: 15876 } + }, + expression: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15879, end: 15880 } + }, + loc: { start: 15866, end: 15881 } + }, + { + kind: 'statement_until', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'q', + loc: { start: 15957, end: 15958 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15962, end: 15963 } + }, + loc: { start: 15957, end: 15963 } + }, + statements: [ + { + kind: 'statement_assign', + path: { + kind: 'var', + name: 'q', + loc: { start: 15900, end: 15901 } + }, + expression: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '-', + left: { + kind: 'static_call', + function: { + kind: 'id', + text: 'divc', + loc: { start: 15905, end: 15909 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'num', + loc: { start: 15910, end: 15913 } + }, + { + kind: 'var', + name: 'x', + loc: { start: 15915, end: 15916 } + } + ], + loc: { start: 15905, end: 15917 } + }, + right: { + kind: 'var', + name: 'x', + loc: { start: 15920, end: 15921 } + }, + loc: { start: 15905, end: 15921 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15925, end: 15926 } + }, + loc: { start: 15904, end: 15926 } + }, + loc: { start: 15900, end: 15927 } + }, + { + kind: 'statement_augmentedassign', + op: '+=', + path: { + kind: 'var', + name: 'x', + loc: { start: 15936, end: 15937 } + }, + expression: { + kind: 'var', + name: 'q', + loc: { start: 15941, end: 15942 } + }, + loc: { start: 15936, end: 15943 } + } + ], + loc: { start: 15887, end: 15965 } + }, + { + kind: 'statement_return', + expression: { + kind: 'var', + name: 'x', + loc: { start: 15978, end: 15979 } + }, + loc: { start: 15971, end: 15980 } + } + ] + }, + loc: { start: 15694, end: 15982 } + } + ] + }, + 'nativeRandom' => { + kind: 'tact', + path: 'std/internal/math.tact', + code: '// Prepare random\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Randomizes the pseudorandom number generator with the specified unsigned 256-bit `Int` `x` by mixing it with the current seed. The new seed is the unsigned 256-bit `Int` value of the SHA-256 hash of concatenated old seed and `x` in their 32-byte strings big-endian representation.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativeRandomize(42); // now, random numbers are less predictable\n' + + "/// let idk: Int = randomInt(); // ???, it's random,\n" + + '/// // but the seed was adjusted deterministically!\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify a negative value of `x`.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomize\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun nativeRandomize(x: Int) { ADDRAND }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Randomizes the random number generator with the logical time of the current transaction. Equivalent to calling `nativeRandomize(curLt())`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativeRandomizeLt(); // now, random numbers are unpredictable for users,\n' + + '/// // but still may be affected by validators or collators\n' + + '/// // as they determine the seed of the current block.\n' + + "/// let idk: Int = randomInt(); // ???, it's random!\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomizelt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomize\n' + + '/// * https://docs.tact-lang.org/ref/core-contextstate#curlt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + 'asm fun nativeRandomizeLt() { LTIME ADDRAND }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Prepares a random number generator by using `nativeRandomizeLt()`. Automatically called by `randomInt()` and `random()` functions.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativePrepareRandom(); // prepare the RNG\n' + + '/// // ... do your random things ...\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativepreparerandom\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomizelt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '/// * https://docs.tact-lang.org/ref/core-random#random\n' + + '///\n' + + '@name(__tact_prepare_random)\n' + + 'native nativePrepareRandom();\n' + + '\n' + + '// Random\n' + + '\n' + + '// Generates a new pseudo-random unsigned 256-bit integer x.\n' + + '// The algorithm is as follows: if r is the old value of the random seed,\n' + + '// considered as a 32-byte array (by constructing the big-endian representation\n' + + '// of an unsigned 256-bit integer), then its sha512(r) is computed;\n' + + "// the first 32 bytes of this hash are stored as the new value r' of the random seed,\n" + + '// and the remaining 32 bytes are returned as the next random value x.\n' + + 'asm fun nativeRandom(): Int { RANDU256 }\n' + + '\n' + + '// Generates a new pseudo-random integer z in the range 0..range−1\n' + + '// (or range..−1, if range < 0).\n' + + '// More precisely, an unsigned random value x is generated as in `nativeRandom`;\n' + + '// then z := x * range / 2^256 is computed.\n' + + 'asm fun nativeRandomInterval(max: Int): Int { RAND }\n' + + '\n' + + '/// Generates and returns a new pseudo-random unsigned 256-bit `Int` value `x`.\n' + + '///\n' + + '/// The algorithm works as follows: first, the `sha512(r)` is computed. There, `r` is an old\n' + + '/// value of the random seed, which is taken as a 32-byte array constructed from the big-endian\n' + + '/// representation of an unsigned 256-bit `Int`. The first 32 bytes of this hash are stored as the new\n' + + "/// value `r'` of the random seed, and the remaining 32 bytes are returned as the next random value `x`.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + "/// let allYourRandomBelongToUs: Int = randomInt(); // ???, it's random :)\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + 'inline fun randomInt(): Int {\n' + + ' nativePrepareRandom();\n' + + ' return nativeRandom();\n' + + '}\n' + + '\n' + + '/// Generates and returns a new pseudo-random unsigned `Int` value `x` in the provided semi-closed\n' + + '/// interval: `min` ≤ `x` < `max`, or `min` ≥ `x` > `max` if both `min` and `max` are negative.\n' + + '///\n' + + '/// Note that the `max` value is never included in the interval.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// random(42, 43); // 42, always\n' + + '/// random(0, 42); // 0-41, but never 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-random#random\n' + + '///\n' + + 'inline fun random(min: Int, max: Int): Int {\n' + + ' nativePrepareRandom();\n' + + ' return min + nativeRandomInterval(max - min);\n' + + '}\n' + + '\n' + + '// Math\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the minimum of two `Int` values `x` and `y`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// min(1, 2); // 1\n' + + '/// min(2, 2); // 2\n' + + '/// min(007, 3); // 3\n' + + '/// min(0x45, 3_0_0); // 69, nice\n' + + '/// // ↑ ↑\n' + + '/// // 69 300\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#min\n' + + '///\n' + + 'asm fun min(x: Int, y: Int): Int { MIN }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the maximum of two `Int` values `x` and `y`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// max(1, 2); // 2\n' + + '/// max(2, 2); // 2\n' + + '/// max(007, 3); // 7\n' + + '/// max(0x45, 3_0_0); // 300\n' + + '/// // ↑ ↑\n' + + '/// // 69 300\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#max\n' + + '///\n' + + 'asm fun max(x: Int, y: Int): Int { MAX }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the absolute value of the `Int` value `x`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// abs(42); // 42\n' + + '/// abs(-42); // 42\n' + + '/// abs(-(-(-42))); // 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#abs\n' + + '///\n' + + 'asm fun abs(x: Int): Int { ABS }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the logarithm of a number `num` > 0 to the base `base` ≥ 1. Results are rounded down.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// log(1000, 10); // 3, as 10^3 is 1000\n' + + '/// // ↑ ↑ ↑ ↑\n' + + '/// // num base base num\n' + + '///\n' + + '/// log(1001, 10); // 3\n' + + '/// log(999, 10); // 2\n' + + '/// try {\n' + + '/// log(-1000, 10); // exit code 5 because of the non-positive num\n' + + '/// }\n' + + '/// log(1024, 2); // 10\n' + + '/// try {\n' + + '/// log(1024, -2); // exit code 5 because the base is less than 1\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `num` value is non-positive\n' + + '/// or the given `base` value is less than 1.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log2\n' + + '///\n' + + '@name(__tact_log)\n' + + 'native log(num: Int, base: Int): Int;\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Similar to `log()`, but sets the `base` to 2.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// log2(1024); // 10, as 2^10 is 1024\n' + + '/// // ↑ ↑ ↑\n' + + '/// // num base₂ num\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `num` value is non-positive.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log2\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log.\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes/#5\n' + + '///\n' + + 'asm fun log2(num: Int): Int { DUP 5 THROWIFNOT UBITSIZE DEC }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the exponentiation involving two numbers: the `base` and the exponent (or _power_) `exp`.\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Example {\n' + + '/// // Persistent state variables\n' + + '/// p23: Int = pow(2, 3); // raises 2 to the 3rd power, which is 8\n' + + '/// one: Int = pow(5, 0); // raises 5 to the power 0, which always produces 1\n' + + '/// // works at compile-time!\n' + + '///\n' + + '/// // Internal message receiver\n' + + '/// receive() {\n' + + '/// pow(self.p23, self.one + 1); // 64, works at run-time too!\n' + + '/// try {\n' + + '/// pow(0, -1); // exit code 5: Integer out of expected range\n' + + '/// }\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `exp` value is negative.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow2\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes/#5\n' + + '///\n' + + 'inline fun pow(base: Int, exp: Int): Int {\n' + + ' throwUnless(5, exp >= 0);\n' + + ' let result = 1;\n' + + ' repeat (exp) {\n' + + ' result *= base;\n' + + ' }\n' + + ' return result;\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Similar to `pow()`, but sets the `base` to 2.\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Example {\n' + + '/// // Persistent state variables\n' + + '/// p23: Int = pow2(3); // raises 2 to the 3rd power, which is 8\n' + + '/// one: Int = pow2(0); // raises 2 to the power 0, which always produces 1\n' + + '/// // works at compile-time!\n' + + '///\n' + + '/// // Internal message receiver, which accepts message ExtMsg\n' + + '/// receive() {\n' + + '/// pow2(self.one + 1); // 4, works at run-time too!\n' + + '/// try {\n' + + '/// pow(-1); // exit code 5: Integer out of expected range\n' + + '/// }\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify a negative value of `exp`.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow2\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun pow2(exp: Int): Int { POW2 }\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Computes and returns the sign of the `Int` value `x`. Produces 1 if the `x` is positive, -1 if the `x` is negative, and 0 if the `x` is 0.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// '... 5983 more characters, + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomize', + loc: { start: 965, end: 980 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { kind: 'id', text: 'x', loc: { start: 981, end: 982 } }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 984, end: 987 } + }, + loc: { start: 984, end: 987 } + }, + loc: { start: 981, end: 987 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ADDRAND' ] + }, + loc: { start: 957, end: 1000 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomizeLt', + loc: { start: 1822, end: 1839 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LTIME ADDRAND' ] + }, + loc: { start: 1814, end: 1859 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 2466, end: 2485 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_prepare_random', + loc: { start: 2436, end: 2457 } + } + }, + loc: { start: 2430, end: 2488 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandom', + loc: { start: 2949, end: 2961 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2965, end: 2968 } + }, + loc: { start: 2965, end: 2968 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RANDU256' ] + }, + loc: { start: 2941, end: 2981 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomInterval', + loc: { start: 3216, end: 3236 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3248, end: 3251 } + }, + loc: { start: 3248, end: 3251 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'max', + loc: { start: 3237, end: 3240 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3242, end: 3245 } + }, + loc: { start: 3242, end: 3245 } + }, + loc: { start: 3237, end: 3245 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RAND' ] + }, + loc: { start: 3208, end: 3260 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'randomInt', + loc: { start: 3953, end: 3962 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3966, end: 3969 } + }, + loc: { start: 3966, end: 3969 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 3976, end: 3995 } + }, + typeArgs: [], + args: [], + loc: { start: 3976, end: 3997 } + }, + loc: { start: 3976, end: 3998 } + }, + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativeRandom', + loc: { start: 4010, end: 4022 } + }, + typeArgs: [], + args: [], + loc: { start: 4010, end: 4024 } + }, + loc: { start: 4003, end: 4025 } + } + ] + }, + loc: { start: 3942, end: 4027 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'random', + loc: { start: 4505, end: 4511 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4533, end: 4536 } + }, + loc: { start: 4533, end: 4536 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'min', + loc: { start: 4512, end: 4515 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4517, end: 4520 } + }, + loc: { start: 4517, end: 4520 } + }, + loc: { start: 4512, end: 4520 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'max', + loc: { start: 4522, end: 4525 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4527, end: 4530 } + }, + loc: { start: 4527, end: 4530 } + }, + loc: { start: 4522, end: 4530 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 4543, end: 4562 } + }, + typeArgs: [], + args: [], + loc: { start: 4543, end: 4564 } + }, + loc: { start: 4543, end: 4565 } + }, + { + kind: 'statement_return', + expression: { + kind: 'op_binary', + op: '+', + left: { + kind: 'var', + name: 'min', + loc: { start: 4577, end: 4580 } + }, + right: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativeRandomInterval', + loc: { start: 4583, end: 4603 } + }, + typeArgs: [], + args: [ + { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'max', + loc: { start: 4604, end: 4607 } + }, + right: { + kind: 'var', + name: 'min', + loc: { start: 4610, end: 4613 } + }, + loc: { start: 4604, end: 4613 } + } + ], + loc: { start: 4583, end: 4614 } + }, + loc: { start: 4577, end: 4614 } + }, + loc: { start: 4570, end: 4615 } + } + ] + }, + loc: { start: 4494, end: 4617 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'min', loc: { start: 5017, end: 5020 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5038, end: 5041 } + }, + loc: { start: 5038, end: 5041 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5021, end: 5022 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5024, end: 5027 } + }, + loc: { start: 5024, end: 5027 } + }, + loc: { start: 5021, end: 5027 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 5029, end: 5030 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5032, end: 5035 } + }, + loc: { start: 5032, end: 5035 } + }, + loc: { start: 5029, end: 5035 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MIN' ] + }, + loc: { start: 5009, end: 5049 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'max', loc: { start: 5435, end: 5438 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5456, end: 5459 } + }, + loc: { start: 5456, end: 5459 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5439, end: 5440 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5442, end: 5445 } + }, + loc: { start: 5442, end: 5445 } + }, + loc: { start: 5439, end: 5445 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 5447, end: 5448 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5450, end: 5453 } + }, + loc: { start: 5450, end: 5453 } + }, + loc: { start: 5447, end: 5453 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MAX' ] + }, + loc: { start: 5427, end: 5467 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'abs', loc: { start: 5773, end: 5776 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5786, end: 5789 } + }, + loc: { start: 5786, end: 5789 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5777, end: 5778 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5780, end: 5783 } + }, + loc: { start: 5780, end: 5783 } + }, + loc: { start: 5777, end: 5783 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ABS' ] + }, + loc: { start: 5765, end: 5797 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'log', loc: { start: 6721, end: 6724 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6747, end: 6750 } + }, + loc: { start: 6747, end: 6750 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 6725, end: 6728 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6730, end: 6733 } + }, + loc: { start: 6730, end: 6733 } + }, + loc: { start: 6725, end: 6733 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'base', + loc: { start: 6735, end: 6739 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6741, end: 6744 } + }, + loc: { start: 6741, end: 6744 } + }, + loc: { start: 6735, end: 6744 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_log', + loc: { start: 6702, end: 6712 } + } + }, + loc: { start: 6696, end: 6751 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'log2', loc: { start: 7341, end: 7345 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7357, end: 7360 } + }, + loc: { start: 7357, end: 7360 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 7346, end: 7349 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7351, end: 7354 } + }, + loc: { start: 7351, end: 7354 } + }, + loc: { start: 7346, end: 7354 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DUP 5 THROWIFNOT UBITSIZE DEC' ] + }, + loc: { start: 7333, end: 7394 } + }, + { + kind: 'function', + inline: true, + name: { kind: 'id', text: 'pow', loc: { start: 8510, end: 8513 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8536, end: 8539 } + }, + loc: { start: 8536, end: 8539 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'base', + loc: { start: 8514, end: 8518 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8520, end: 8523 } + }, + loc: { start: 8520, end: 8523 } + }, + loc: { start: 8514, end: 8523 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'exp', + loc: { start: 8525, end: 8528 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8530, end: 8533 } + }, + loc: { start: 8530, end: 8533 } + }, + loc: { start: 8525, end: 8533 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throwUnless', + loc: { start: 8546, end: 8557 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 5n, + loc: { start: 8558, end: 8559 } + }, + { + kind: 'op_binary', + op: '>=', + left: { + kind: 'var', + name: 'exp', + loc: { start: 8561, end: 8564 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 8568, end: 8569 } + }, + loc: { start: 8561, end: 8569 } + } + ], + loc: { start: 8546, end: 8570 } + }, + loc: { start: 8546, end: 8571 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'result', + loc: { start: 8580, end: 8586 } + }, + type: undefined, + expression: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 8589, end: 8590 } + }, + loc: { start: 8576, end: 8591 } + }, + { + kind: 'statement_repeat', + iterations: { + kind: 'var', + name: 'exp', + loc: { start: 8604, end: 8607 } + }, + statements: [ + { + kind: 'statement_augmentedassign', + op: '*=', + path: { + kind: 'var', + name: 'result', + loc: { start: 8619, end: 8625 } + }, + expression: { + kind: 'var', + name: 'base', + loc: { start: 8629, end: 8633 } + }, + loc: { start: 8619, end: 8634 } + } + ], + loc: { start: 8596, end: 8640 } + }, + { + kind: 'statement_return', + expression: { + kind: 'var', + name: 'result', + loc: { start: 8652, end: 8658 } + }, + loc: { start: 8645, end: 8659 } + } + ] + }, + loc: { start: 8499, end: 8661 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'pow2', loc: { start: 9733, end: 9737 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9749, end: 9752 } + }, + loc: { start: 9749, end: 9752 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'exp', + loc: { start: 9738, end: 9741 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9743, end: 9746 } + }, + loc: { start: 9743, end: 9746 } + }, + loc: { start: 9738, end: 9746 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'POW2' ] + }, + loc: { start: 9725, end: 9761 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sign', + loc: { start: 10233, end: 10237 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10247, end: 10250 } + }, + loc: { start: 10247, end: 10250 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 10238, end: 10239 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10241, end: 10244 } + }, + loc: { start: 10241, end: 10244 } + }, + loc: { start: 10238, end: 10244 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SGN' ] + }, + loc: { start: 10225, end: 10258 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'divc', + loc: { start: 10814, end: 10818 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10836, end: 10839 } + }, + loc: { start: 10836, end: 10839 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 10819, end: 10820 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10822, end: 10825 } + }, + loc: { start: 10822, end: 10825 } + }, + loc: { start: 10819, end: 10825 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 10827, end: 10828 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10830, end: 10833 } + }, + loc: { start: 10830, end: 10833 } + }, + loc: { start: 10827, end: 10833 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DIVC' ] + }, + loc: { start: 10806, end: 10848 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'muldivc', + loc: { start: 11615, end: 11622 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11648, end: 11651 } + }, + loc: { start: 11648, end: 11651 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 11623, end: 11624 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11626, end: 11629 } + }, + loc: { start: 11626, end: 11629 } + }, + loc: { start: 11623, end: 11629 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 11631, end: 11632 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11634, end: 11637 } + }, + loc: { start: 11634, end: 11637 } + }, + loc: { start: 11631, end: 11637 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 11639, end: 11640 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11642, end: 11645 } + }, + loc: { start: 11642, end: 11645 } + }, + loc: { start: 11639, end: 11645 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULDIVC' ] + }, + loc: { start: 11607, end: 11663 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRight', + loc: { start: 12751, end: 12764 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12790, end: 12793 } + }, + loc: { start: 12790, end: 12793 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 12765, end: 12766 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12768, end: 12771 } + }, + loc: { start: 12768, end: 12771 } + }, + loc: { start: 12765, end: 12771 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 12773, end: 12774 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12776, end: 12779 } + }, + loc: { start: 12776, end: 12779 } + }, + loc: { start: 12773, end: 12779 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 12781, end: 12782 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12784, end: 12787 } + }, + loc: { start: 12784, end: 12787 } + }, + loc: { start: 12781, end: 12787 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFT' ] + }, + loc: { start: 12743, end: 12807 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRightRound', + loc: { start: 13862, end: 13880 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13906, end: 13909 } + }, + loc: { start: 13906, end: 13909 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 13881, end: 13882 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13884, end: 13887 } + }, + loc: { start: 13884, end: 13887 } + }, + loc: { start: 13881, end: 13887 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 13889, end: 13890 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13892, end: 13895 } + }, + loc: { start: 13892, end: 13895 } + }, + loc: { start: 13889, end: 13895 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 13897, end: 13898 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13900, end: 13903 } + }, + loc: { start: 13900, end: 13903 } + }, + loc: { start: 13897, end: 13903 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFTR' ] + }, + loc: { start: 13854, end: 13924 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRightCeil', + loc: { start: 14875, end: 14892 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14918, end: 14921 } + }, + loc: { start: 14918, end: 14921 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 14893, end: 14894 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14896, end: 14899 } + }, + loc: { start: 14896, end: 14899 } + }, + loc: { start: 14893, end: 14899 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 14901, end: 14902 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14904, end: 14907 } + }, + loc: { start: 14904, end: 14907 } + }, + loc: { start: 14901, end: 14907 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 14909, end: 14910 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14912, end: 14915 } + }, + loc: { start: 14912, end: 14915 } + }, + loc: { start: 14909, end: 14915 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFTC' ] + }, + loc: { start: 14867, end: 14936 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sqrt', + loc: { start: 15698, end: 15702 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15714, end: 15717 } + }, + loc: { start: 15714, end: 15717 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 15703, end: 15706 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15708, end: 15711 } + }, + loc: { start: 15708, end: 15711 } + }, + loc: { start: 15703, end: 15711 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'num', + loc: { start: 15728, end: 15731 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15735, end: 15736 } + }, + loc: { start: 15728, end: 15736 } + }, + trueStatements: [ + { + kind: 'statement_return', + expression: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15755, end: 15756 } + }, + loc: { start: 15748, end: 15757 } + } + ], + falseStatements: undefined, + loc: { start: 15724, end: 15763 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 's', + loc: { start: 15773, end: 15774 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15776, end: 15779 } + }, + loc: { start: 15776, end: 15779 } + }, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'log2', + loc: { start: 15782, end: 15786 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'num', + loc: { start: 15787, end: 15790 } + } + ], + loc: { start: 15782, end: 15791 } + }, + loc: { start: 15769, end: 15792 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'x', + loc: { start: 15801, end: 15802 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15804, end: 15807 } + }, + loc: { start: 15804, end: 15807 } + }, + expression: { + kind: 'conditional', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 's', + loc: { start: 15811, end: 15812 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15816, end: 15817 } + }, + loc: { start: 15811, end: 15817 } + }, + thenBranch: { + kind: 'op_binary', + op: '+', + left: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'num', + loc: { start: 15821, end: 15824 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15827, end: 15828 } + }, + loc: { start: 15821, end: 15828 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15832, end: 15833 } + }, + loc: { start: 15820, end: 15833 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15836, end: 15837 } + }, + loc: { start: 15820, end: 15837 } + }, + elseBranch: { + kind: 'op_binary', + op: '<<', + left: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15840, end: 15841 } + }, + right: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '+', + left: { + kind: 'var', + name: 's', + loc: { start: 15847, end: 15848 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15851, end: 15852 } + }, + loc: { start: 15847, end: 15852 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15856, end: 15857 } + }, + loc: { start: 15846, end: 15857 } + }, + loc: { start: 15840, end: 15858 } + }, + loc: { start: 15811, end: 15858 } + }, + loc: { start: 15797, end: 15860 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'q', + loc: { start: 15870, end: 15871 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15873, end: 15876 } + }, + loc: { start: 15873, end: 15876 } + }, + expression: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15879, end: 15880 } + }, + loc: { start: 15866, end: 15881 } + }, + { + kind: 'statement_until', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'q', + loc: { start: 15957, end: 15958 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15962, end: 15963 } + }, + loc: { start: 15957, end: 15963 } + }, + statements: [ + { + kind: 'statement_assign', + path: { + kind: 'var', + name: 'q', + loc: { start: 15900, end: 15901 } + }, + expression: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '-', + left: { + kind: 'static_call', + function: { + kind: 'id', + text: 'divc', + loc: { start: 15905, end: 15909 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'num', + loc: { start: 15910, end: 15913 } + }, + { + kind: 'var', + name: 'x', + loc: { start: 15915, end: 15916 } + } + ], + loc: { start: 15905, end: 15917 } + }, + right: { + kind: 'var', + name: 'x', + loc: { start: 15920, end: 15921 } + }, + loc: { start: 15905, end: 15921 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15925, end: 15926 } + }, + loc: { start: 15904, end: 15926 } + }, + loc: { start: 15900, end: 15927 } + }, + { + kind: 'statement_augmentedassign', + op: '+=', + path: { + kind: 'var', + name: 'x', + loc: { start: 15936, end: 15937 } + }, + expression: { + kind: 'var', + name: 'q', + loc: { start: 15941, end: 15942 } + }, + loc: { start: 15936, end: 15943 } + } + ], + loc: { start: 15887, end: 15965 } + }, + { + kind: 'statement_return', + expression: { + kind: 'var', + name: 'x', + loc: { start: 15978, end: 15979 } + }, + loc: { start: 15971, end: 15980 } + } + ] + }, + loc: { start: 15694, end: 15982 } + } + ] + }, + 'nativeRandomInterval' => { + kind: 'tact', + path: 'std/internal/math.tact', + code: '// Prepare random\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Randomizes the pseudorandom number generator with the specified unsigned 256-bit `Int` `x` by mixing it with the current seed. The new seed is the unsigned 256-bit `Int` value of the SHA-256 hash of concatenated old seed and `x` in their 32-byte strings big-endian representation.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativeRandomize(42); // now, random numbers are less predictable\n' + + "/// let idk: Int = randomInt(); // ???, it's random,\n" + + '/// // but the seed was adjusted deterministically!\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify a negative value of `x`.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomize\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun nativeRandomize(x: Int) { ADDRAND }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Randomizes the random number generator with the logical time of the current transaction. Equivalent to calling `nativeRandomize(curLt())`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativeRandomizeLt(); // now, random numbers are unpredictable for users,\n' + + '/// // but still may be affected by validators or collators\n' + + '/// // as they determine the seed of the current block.\n' + + "/// let idk: Int = randomInt(); // ???, it's random!\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomizelt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomize\n' + + '/// * https://docs.tact-lang.org/ref/core-contextstate#curlt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + 'asm fun nativeRandomizeLt() { LTIME ADDRAND }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Prepares a random number generator by using `nativeRandomizeLt()`. Automatically called by `randomInt()` and `random()` functions.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativePrepareRandom(); // prepare the RNG\n' + + '/// // ... do your random things ...\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativepreparerandom\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomizelt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '/// * https://docs.tact-lang.org/ref/core-random#random\n' + + '///\n' + + '@name(__tact_prepare_random)\n' + + 'native nativePrepareRandom();\n' + + '\n' + + '// Random\n' + + '\n' + + '// Generates a new pseudo-random unsigned 256-bit integer x.\n' + + '// The algorithm is as follows: if r is the old value of the random seed,\n' + + '// considered as a 32-byte array (by constructing the big-endian representation\n' + + '// of an unsigned 256-bit integer), then its sha512(r) is computed;\n' + + "// the first 32 bytes of this hash are stored as the new value r' of the random seed,\n" + + '// and the remaining 32 bytes are returned as the next random value x.\n' + + 'asm fun nativeRandom(): Int { RANDU256 }\n' + + '\n' + + '// Generates a new pseudo-random integer z in the range 0..range−1\n' + + '// (or range..−1, if range < 0).\n' + + '// More precisely, an unsigned random value x is generated as in `nativeRandom`;\n' + + '// then z := x * range / 2^256 is computed.\n' + + 'asm fun nativeRandomInterval(max: Int): Int { RAND }\n' + + '\n' + + '/// Generates and returns a new pseudo-random unsigned 256-bit `Int` value `x`.\n' + + '///\n' + + '/// The algorithm works as follows: first, the `sha512(r)` is computed. There, `r` is an old\n' + + '/// value of the random seed, which is taken as a 32-byte array constructed from the big-endian\n' + + '/// representation of an unsigned 256-bit `Int`. The first 32 bytes of this hash are stored as the new\n' + + "/// value `r'` of the random seed, and the remaining 32 bytes are returned as the next random value `x`.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + "/// let allYourRandomBelongToUs: Int = randomInt(); // ???, it's random :)\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + 'inline fun randomInt(): Int {\n' + + ' nativePrepareRandom();\n' + + ' return nativeRandom();\n' + + '}\n' + + '\n' + + '/// Generates and returns a new pseudo-random unsigned `Int` value `x` in the provided semi-closed\n' + + '/// interval: `min` ≤ `x` < `max`, or `min` ≥ `x` > `max` if both `min` and `max` are negative.\n' + + '///\n' + + '/// Note that the `max` value is never included in the interval.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// random(42, 43); // 42, always\n' + + '/// random(0, 42); // 0-41, but never 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-random#random\n' + + '///\n' + + 'inline fun random(min: Int, max: Int): Int {\n' + + ' nativePrepareRandom();\n' + + ' return min + nativeRandomInterval(max - min);\n' + + '}\n' + + '\n' + + '// Math\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the minimum of two `Int` values `x` and `y`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// min(1, 2); // 1\n' + + '/// min(2, 2); // 2\n' + + '/// min(007, 3); // 3\n' + + '/// min(0x45, 3_0_0); // 69, nice\n' + + '/// // ↑ ↑\n' + + '/// // 69 300\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#min\n' + + '///\n' + + 'asm fun min(x: Int, y: Int): Int { MIN }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the maximum of two `Int` values `x` and `y`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// max(1, 2); // 2\n' + + '/// max(2, 2); // 2\n' + + '/// max(007, 3); // 7\n' + + '/// max(0x45, 3_0_0); // 300\n' + + '/// // ↑ ↑\n' + + '/// // 69 300\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#max\n' + + '///\n' + + 'asm fun max(x: Int, y: Int): Int { MAX }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the absolute value of the `Int` value `x`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// abs(42); // 42\n' + + '/// abs(-42); // 42\n' + + '/// abs(-(-(-42))); // 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#abs\n' + + '///\n' + + 'asm fun abs(x: Int): Int { ABS }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the logarithm of a number `num` > 0 to the base `base` ≥ 1. Results are rounded down.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// log(1000, 10); // 3, as 10^3 is 1000\n' + + '/// // ↑ ↑ ↑ ↑\n' + + '/// // num base base num\n' + + '///\n' + + '/// log(1001, 10); // 3\n' + + '/// log(999, 10); // 2\n' + + '/// try {\n' + + '/// log(-1000, 10); // exit code 5 because of the non-positive num\n' + + '/// }\n' + + '/// log(1024, 2); // 10\n' + + '/// try {\n' + + '/// log(1024, -2); // exit code 5 because the base is less than 1\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `num` value is non-positive\n' + + '/// or the given `base` value is less than 1.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log2\n' + + '///\n' + + '@name(__tact_log)\n' + + 'native log(num: Int, base: Int): Int;\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Similar to `log()`, but sets the `base` to 2.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// log2(1024); // 10, as 2^10 is 1024\n' + + '/// // ↑ ↑ ↑\n' + + '/// // num base₂ num\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `num` value is non-positive.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log2\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log.\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes/#5\n' + + '///\n' + + 'asm fun log2(num: Int): Int { DUP 5 THROWIFNOT UBITSIZE DEC }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the exponentiation involving two numbers: the `base` and the exponent (or _power_) `exp`.\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Example {\n' + + '/// // Persistent state variables\n' + + '/// p23: Int = pow(2, 3); // raises 2 to the 3rd power, which is 8\n' + + '/// one: Int = pow(5, 0); // raises 5 to the power 0, which always produces 1\n' + + '/// // works at compile-time!\n' + + '///\n' + + '/// // Internal message receiver\n' + + '/// receive() {\n' + + '/// pow(self.p23, self.one + 1); // 64, works at run-time too!\n' + + '/// try {\n' + + '/// pow(0, -1); // exit code 5: Integer out of expected range\n' + + '/// }\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `exp` value is negative.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow2\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes/#5\n' + + '///\n' + + 'inline fun pow(base: Int, exp: Int): Int {\n' + + ' throwUnless(5, exp >= 0);\n' + + ' let result = 1;\n' + + ' repeat (exp) {\n' + + ' result *= base;\n' + + ' }\n' + + ' return result;\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Similar to `pow()`, but sets the `base` to 2.\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Example {\n' + + '/// // Persistent state variables\n' + + '/// p23: Int = pow2(3); // raises 2 to the 3rd power, which is 8\n' + + '/// one: Int = pow2(0); // raises 2 to the power 0, which always produces 1\n' + + '/// // works at compile-time!\n' + + '///\n' + + '/// // Internal message receiver, which accepts message ExtMsg\n' + + '/// receive() {\n' + + '/// pow2(self.one + 1); // 4, works at run-time too!\n' + + '/// try {\n' + + '/// pow(-1); // exit code 5: Integer out of expected range\n' + + '/// }\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify a negative value of `exp`.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow2\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun pow2(exp: Int): Int { POW2 }\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Computes and returns the sign of the `Int` value `x`. Produces 1 if the `x` is positive, -1 if the `x` is negative, and 0 if the `x` is 0.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// '... 5983 more characters, + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomize', + loc: { start: 965, end: 980 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { kind: 'id', text: 'x', loc: { start: 981, end: 982 } }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 984, end: 987 } + }, + loc: { start: 984, end: 987 } + }, + loc: { start: 981, end: 987 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ADDRAND' ] + }, + loc: { start: 957, end: 1000 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomizeLt', + loc: { start: 1822, end: 1839 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LTIME ADDRAND' ] + }, + loc: { start: 1814, end: 1859 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 2466, end: 2485 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_prepare_random', + loc: { start: 2436, end: 2457 } + } + }, + loc: { start: 2430, end: 2488 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandom', + loc: { start: 2949, end: 2961 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2965, end: 2968 } + }, + loc: { start: 2965, end: 2968 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RANDU256' ] + }, + loc: { start: 2941, end: 2981 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomInterval', + loc: { start: 3216, end: 3236 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3248, end: 3251 } + }, + loc: { start: 3248, end: 3251 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'max', + loc: { start: 3237, end: 3240 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3242, end: 3245 } + }, + loc: { start: 3242, end: 3245 } + }, + loc: { start: 3237, end: 3245 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RAND' ] + }, + loc: { start: 3208, end: 3260 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'randomInt', + loc: { start: 3953, end: 3962 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3966, end: 3969 } + }, + loc: { start: 3966, end: 3969 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 3976, end: 3995 } + }, + typeArgs: [], + args: [], + loc: { start: 3976, end: 3997 } + }, + loc: { start: 3976, end: 3998 } + }, + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativeRandom', + loc: { start: 4010, end: 4022 } + }, + typeArgs: [], + args: [], + loc: { start: 4010, end: 4024 } + }, + loc: { start: 4003, end: 4025 } + } + ] + }, + loc: { start: 3942, end: 4027 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'random', + loc: { start: 4505, end: 4511 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4533, end: 4536 } + }, + loc: { start: 4533, end: 4536 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'min', + loc: { start: 4512, end: 4515 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4517, end: 4520 } + }, + loc: { start: 4517, end: 4520 } + }, + loc: { start: 4512, end: 4520 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'max', + loc: { start: 4522, end: 4525 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4527, end: 4530 } + }, + loc: { start: 4527, end: 4530 } + }, + loc: { start: 4522, end: 4530 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 4543, end: 4562 } + }, + typeArgs: [], + args: [], + loc: { start: 4543, end: 4564 } + }, + loc: { start: 4543, end: 4565 } + }, + { + kind: 'statement_return', + expression: { + kind: 'op_binary', + op: '+', + left: { + kind: 'var', + name: 'min', + loc: { start: 4577, end: 4580 } + }, + right: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativeRandomInterval', + loc: { start: 4583, end: 4603 } + }, + typeArgs: [], + args: [ + { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'max', + loc: { start: 4604, end: 4607 } + }, + right: { + kind: 'var', + name: 'min', + loc: { start: 4610, end: 4613 } + }, + loc: { start: 4604, end: 4613 } + } + ], + loc: { start: 4583, end: 4614 } + }, + loc: { start: 4577, end: 4614 } + }, + loc: { start: 4570, end: 4615 } + } + ] + }, + loc: { start: 4494, end: 4617 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'min', loc: { start: 5017, end: 5020 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5038, end: 5041 } + }, + loc: { start: 5038, end: 5041 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5021, end: 5022 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5024, end: 5027 } + }, + loc: { start: 5024, end: 5027 } + }, + loc: { start: 5021, end: 5027 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 5029, end: 5030 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5032, end: 5035 } + }, + loc: { start: 5032, end: 5035 } + }, + loc: { start: 5029, end: 5035 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MIN' ] + }, + loc: { start: 5009, end: 5049 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'max', loc: { start: 5435, end: 5438 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5456, end: 5459 } + }, + loc: { start: 5456, end: 5459 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5439, end: 5440 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5442, end: 5445 } + }, + loc: { start: 5442, end: 5445 } + }, + loc: { start: 5439, end: 5445 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 5447, end: 5448 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5450, end: 5453 } + }, + loc: { start: 5450, end: 5453 } + }, + loc: { start: 5447, end: 5453 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MAX' ] + }, + loc: { start: 5427, end: 5467 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'abs', loc: { start: 5773, end: 5776 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5786, end: 5789 } + }, + loc: { start: 5786, end: 5789 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5777, end: 5778 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5780, end: 5783 } + }, + loc: { start: 5780, end: 5783 } + }, + loc: { start: 5777, end: 5783 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ABS' ] + }, + loc: { start: 5765, end: 5797 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'log', loc: { start: 6721, end: 6724 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6747, end: 6750 } + }, + loc: { start: 6747, end: 6750 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 6725, end: 6728 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6730, end: 6733 } + }, + loc: { start: 6730, end: 6733 } + }, + loc: { start: 6725, end: 6733 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'base', + loc: { start: 6735, end: 6739 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6741, end: 6744 } + }, + loc: { start: 6741, end: 6744 } + }, + loc: { start: 6735, end: 6744 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_log', + loc: { start: 6702, end: 6712 } + } + }, + loc: { start: 6696, end: 6751 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'log2', loc: { start: 7341, end: 7345 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7357, end: 7360 } + }, + loc: { start: 7357, end: 7360 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 7346, end: 7349 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7351, end: 7354 } + }, + loc: { start: 7351, end: 7354 } + }, + loc: { start: 7346, end: 7354 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DUP 5 THROWIFNOT UBITSIZE DEC' ] + }, + loc: { start: 7333, end: 7394 } + }, + { + kind: 'function', + inline: true, + name: { kind: 'id', text: 'pow', loc: { start: 8510, end: 8513 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8536, end: 8539 } + }, + loc: { start: 8536, end: 8539 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'base', + loc: { start: 8514, end: 8518 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8520, end: 8523 } + }, + loc: { start: 8520, end: 8523 } + }, + loc: { start: 8514, end: 8523 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'exp', + loc: { start: 8525, end: 8528 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8530, end: 8533 } + }, + loc: { start: 8530, end: 8533 } + }, + loc: { start: 8525, end: 8533 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throwUnless', + loc: { start: 8546, end: 8557 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 5n, + loc: { start: 8558, end: 8559 } + }, + { + kind: 'op_binary', + op: '>=', + left: { + kind: 'var', + name: 'exp', + loc: { start: 8561, end: 8564 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 8568, end: 8569 } + }, + loc: { start: 8561, end: 8569 } + } + ], + loc: { start: 8546, end: 8570 } + }, + loc: { start: 8546, end: 8571 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'result', + loc: { start: 8580, end: 8586 } + }, + type: undefined, + expression: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 8589, end: 8590 } + }, + loc: { start: 8576, end: 8591 } + }, + { + kind: 'statement_repeat', + iterations: { + kind: 'var', + name: 'exp', + loc: { start: 8604, end: 8607 } + }, + statements: [ + { + kind: 'statement_augmentedassign', + op: '*=', + path: { + kind: 'var', + name: 'result', + loc: { start: 8619, end: 8625 } + }, + expression: { + kind: 'var', + name: 'base', + loc: { start: 8629, end: 8633 } + }, + loc: { start: 8619, end: 8634 } + } + ], + loc: { start: 8596, end: 8640 } + }, + { + kind: 'statement_return', + expression: { + kind: 'var', + name: 'result', + loc: { start: 8652, end: 8658 } + }, + loc: { start: 8645, end: 8659 } + } + ] + }, + loc: { start: 8499, end: 8661 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'pow2', loc: { start: 9733, end: 9737 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9749, end: 9752 } + }, + loc: { start: 9749, end: 9752 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'exp', + loc: { start: 9738, end: 9741 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9743, end: 9746 } + }, + loc: { start: 9743, end: 9746 } + }, + loc: { start: 9738, end: 9746 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'POW2' ] + }, + loc: { start: 9725, end: 9761 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sign', + loc: { start: 10233, end: 10237 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10247, end: 10250 } + }, + loc: { start: 10247, end: 10250 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 10238, end: 10239 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10241, end: 10244 } + }, + loc: { start: 10241, end: 10244 } + }, + loc: { start: 10238, end: 10244 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SGN' ] + }, + loc: { start: 10225, end: 10258 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'divc', + loc: { start: 10814, end: 10818 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10836, end: 10839 } + }, + loc: { start: 10836, end: 10839 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 10819, end: 10820 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10822, end: 10825 } + }, + loc: { start: 10822, end: 10825 } + }, + loc: { start: 10819, end: 10825 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 10827, end: 10828 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10830, end: 10833 } + }, + loc: { start: 10830, end: 10833 } + }, + loc: { start: 10827, end: 10833 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DIVC' ] + }, + loc: { start: 10806, end: 10848 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'muldivc', + loc: { start: 11615, end: 11622 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11648, end: 11651 } + }, + loc: { start: 11648, end: 11651 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 11623, end: 11624 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11626, end: 11629 } + }, + loc: { start: 11626, end: 11629 } + }, + loc: { start: 11623, end: 11629 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 11631, end: 11632 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11634, end: 11637 } + }, + loc: { start: 11634, end: 11637 } + }, + loc: { start: 11631, end: 11637 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 11639, end: 11640 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11642, end: 11645 } + }, + loc: { start: 11642, end: 11645 } + }, + loc: { start: 11639, end: 11645 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULDIVC' ] + }, + loc: { start: 11607, end: 11663 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRight', + loc: { start: 12751, end: 12764 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12790, end: 12793 } + }, + loc: { start: 12790, end: 12793 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 12765, end: 12766 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12768, end: 12771 } + }, + loc: { start: 12768, end: 12771 } + }, + loc: { start: 12765, end: 12771 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 12773, end: 12774 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12776, end: 12779 } + }, + loc: { start: 12776, end: 12779 } + }, + loc: { start: 12773, end: 12779 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 12781, end: 12782 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12784, end: 12787 } + }, + loc: { start: 12784, end: 12787 } + }, + loc: { start: 12781, end: 12787 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFT' ] + }, + loc: { start: 12743, end: 12807 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRightRound', + loc: { start: 13862, end: 13880 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13906, end: 13909 } + }, + loc: { start: 13906, end: 13909 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 13881, end: 13882 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13884, end: 13887 } + }, + loc: { start: 13884, end: 13887 } + }, + loc: { start: 13881, end: 13887 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 13889, end: 13890 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13892, end: 13895 } + }, + loc: { start: 13892, end: 13895 } + }, + loc: { start: 13889, end: 13895 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 13897, end: 13898 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13900, end: 13903 } + }, + loc: { start: 13900, end: 13903 } + }, + loc: { start: 13897, end: 13903 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFTR' ] + }, + loc: { start: 13854, end: 13924 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRightCeil', + loc: { start: 14875, end: 14892 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14918, end: 14921 } + }, + loc: { start: 14918, end: 14921 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 14893, end: 14894 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14896, end: 14899 } + }, + loc: { start: 14896, end: 14899 } + }, + loc: { start: 14893, end: 14899 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 14901, end: 14902 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14904, end: 14907 } + }, + loc: { start: 14904, end: 14907 } + }, + loc: { start: 14901, end: 14907 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 14909, end: 14910 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14912, end: 14915 } + }, + loc: { start: 14912, end: 14915 } + }, + loc: { start: 14909, end: 14915 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFTC' ] + }, + loc: { start: 14867, end: 14936 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sqrt', + loc: { start: 15698, end: 15702 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15714, end: 15717 } + }, + loc: { start: 15714, end: 15717 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 15703, end: 15706 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15708, end: 15711 } + }, + loc: { start: 15708, end: 15711 } + }, + loc: { start: 15703, end: 15711 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'num', + loc: { start: 15728, end: 15731 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15735, end: 15736 } + }, + loc: { start: 15728, end: 15736 } + }, + trueStatements: [ + { + kind: 'statement_return', + expression: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15755, end: 15756 } + }, + loc: { start: 15748, end: 15757 } + } + ], + falseStatements: undefined, + loc: { start: 15724, end: 15763 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 's', + loc: { start: 15773, end: 15774 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15776, end: 15779 } + }, + loc: { start: 15776, end: 15779 } + }, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'log2', + loc: { start: 15782, end: 15786 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'num', + loc: { start: 15787, end: 15790 } + } + ], + loc: { start: 15782, end: 15791 } + }, + loc: { start: 15769, end: 15792 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'x', + loc: { start: 15801, end: 15802 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15804, end: 15807 } + }, + loc: { start: 15804, end: 15807 } + }, + expression: { + kind: 'conditional', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 's', + loc: { start: 15811, end: 15812 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15816, end: 15817 } + }, + loc: { start: 15811, end: 15817 } + }, + thenBranch: { + kind: 'op_binary', + op: '+', + left: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'num', + loc: { start: 15821, end: 15824 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15827, end: 15828 } + }, + loc: { start: 15821, end: 15828 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15832, end: 15833 } + }, + loc: { start: 15820, end: 15833 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15836, end: 15837 } + }, + loc: { start: 15820, end: 15837 } + }, + elseBranch: { + kind: 'op_binary', + op: '<<', + left: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15840, end: 15841 } + }, + right: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '+', + left: { + kind: 'var', + name: 's', + loc: { start: 15847, end: 15848 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15851, end: 15852 } + }, + loc: { start: 15847, end: 15852 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15856, end: 15857 } + }, + loc: { start: 15846, end: 15857 } + }, + loc: { start: 15840, end: 15858 } + }, + loc: { start: 15811, end: 15858 } + }, + loc: { start: 15797, end: 15860 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'q', + loc: { start: 15870, end: 15871 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15873, end: 15876 } + }, + loc: { start: 15873, end: 15876 } + }, + expression: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15879, end: 15880 } + }, + loc: { start: 15866, end: 15881 } + }, + { + kind: 'statement_until', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'q', + loc: { start: 15957, end: 15958 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15962, end: 15963 } + }, + loc: { start: 15957, end: 15963 } + }, + statements: [ + { + kind: 'statement_assign', + path: { + kind: 'var', + name: 'q', + loc: { start: 15900, end: 15901 } + }, + expression: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '-', + left: { + kind: 'static_call', + function: { + kind: 'id', + text: 'divc', + loc: { start: 15905, end: 15909 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'num', + loc: { start: 15910, end: 15913 } + }, + { + kind: 'var', + name: 'x', + loc: { start: 15915, end: 15916 } + } + ], + loc: { start: 15905, end: 15917 } + }, + right: { + kind: 'var', + name: 'x', + loc: { start: 15920, end: 15921 } + }, + loc: { start: 15905, end: 15921 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15925, end: 15926 } + }, + loc: { start: 15904, end: 15926 } + }, + loc: { start: 15900, end: 15927 } + }, + { + kind: 'statement_augmentedassign', + op: '+=', + path: { + kind: 'var', + name: 'x', + loc: { start: 15936, end: 15937 } + }, + expression: { + kind: 'var', + name: 'q', + loc: { start: 15941, end: 15942 } + }, + loc: { start: 15936, end: 15943 } + } + ], + loc: { start: 15887, end: 15965 } + }, + { + kind: 'statement_return', + expression: { + kind: 'var', + name: 'x', + loc: { start: 15978, end: 15979 } + }, + loc: { start: 15971, end: 15980 } + } + ] + }, + loc: { start: 15694, end: 15982 } + } + ] + }, + 'randomInt' => { + kind: 'tact', + path: 'std/internal/math.tact', + code: '// Prepare random\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Randomizes the pseudorandom number generator with the specified unsigned 256-bit `Int` `x` by mixing it with the current seed. The new seed is the unsigned 256-bit `Int` value of the SHA-256 hash of concatenated old seed and `x` in their 32-byte strings big-endian representation.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativeRandomize(42); // now, random numbers are less predictable\n' + + "/// let idk: Int = randomInt(); // ???, it's random,\n" + + '/// // but the seed was adjusted deterministically!\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify a negative value of `x`.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomize\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun nativeRandomize(x: Int) { ADDRAND }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Randomizes the random number generator with the logical time of the current transaction. Equivalent to calling `nativeRandomize(curLt())`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativeRandomizeLt(); // now, random numbers are unpredictable for users,\n' + + '/// // but still may be affected by validators or collators\n' + + '/// // as they determine the seed of the current block.\n' + + "/// let idk: Int = randomInt(); // ???, it's random!\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomizelt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomize\n' + + '/// * https://docs.tact-lang.org/ref/core-contextstate#curlt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + 'asm fun nativeRandomizeLt() { LTIME ADDRAND }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Prepares a random number generator by using `nativeRandomizeLt()`. Automatically called by `randomInt()` and `random()` functions.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativePrepareRandom(); // prepare the RNG\n' + + '/// // ... do your random things ...\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativepreparerandom\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomizelt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '/// * https://docs.tact-lang.org/ref/core-random#random\n' + + '///\n' + + '@name(__tact_prepare_random)\n' + + 'native nativePrepareRandom();\n' + + '\n' + + '// Random\n' + + '\n' + + '// Generates a new pseudo-random unsigned 256-bit integer x.\n' + + '// The algorithm is as follows: if r is the old value of the random seed,\n' + + '// considered as a 32-byte array (by constructing the big-endian representation\n' + + '// of an unsigned 256-bit integer), then its sha512(r) is computed;\n' + + "// the first 32 bytes of this hash are stored as the new value r' of the random seed,\n" + + '// and the remaining 32 bytes are returned as the next random value x.\n' + + 'asm fun nativeRandom(): Int { RANDU256 }\n' + + '\n' + + '// Generates a new pseudo-random integer z in the range 0..range−1\n' + + '// (or range..−1, if range < 0).\n' + + '// More precisely, an unsigned random value x is generated as in `nativeRandom`;\n' + + '// then z := x * range / 2^256 is computed.\n' + + 'asm fun nativeRandomInterval(max: Int): Int { RAND }\n' + + '\n' + + '/// Generates and returns a new pseudo-random unsigned 256-bit `Int` value `x`.\n' + + '///\n' + + '/// The algorithm works as follows: first, the `sha512(r)` is computed. There, `r` is an old\n' + + '/// value of the random seed, which is taken as a 32-byte array constructed from the big-endian\n' + + '/// representation of an unsigned 256-bit `Int`. The first 32 bytes of this hash are stored as the new\n' + + "/// value `r'` of the random seed, and the remaining 32 bytes are returned as the next random value `x`.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + "/// let allYourRandomBelongToUs: Int = randomInt(); // ???, it's random :)\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + 'inline fun randomInt(): Int {\n' + + ' nativePrepareRandom();\n' + + ' return nativeRandom();\n' + + '}\n' + + '\n' + + '/// Generates and returns a new pseudo-random unsigned `Int` value `x` in the provided semi-closed\n' + + '/// interval: `min` ≤ `x` < `max`, or `min` ≥ `x` > `max` if both `min` and `max` are negative.\n' + + '///\n' + + '/// Note that the `max` value is never included in the interval.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// random(42, 43); // 42, always\n' + + '/// random(0, 42); // 0-41, but never 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-random#random\n' + + '///\n' + + 'inline fun random(min: Int, max: Int): Int {\n' + + ' nativePrepareRandom();\n' + + ' return min + nativeRandomInterval(max - min);\n' + + '}\n' + + '\n' + + '// Math\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the minimum of two `Int` values `x` and `y`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// min(1, 2); // 1\n' + + '/// min(2, 2); // 2\n' + + '/// min(007, 3); // 3\n' + + '/// min(0x45, 3_0_0); // 69, nice\n' + + '/// // ↑ ↑\n' + + '/// // 69 300\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#min\n' + + '///\n' + + 'asm fun min(x: Int, y: Int): Int { MIN }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the maximum of two `Int` values `x` and `y`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// max(1, 2); // 2\n' + + '/// max(2, 2); // 2\n' + + '/// max(007, 3); // 7\n' + + '/// max(0x45, 3_0_0); // 300\n' + + '/// // ↑ ↑\n' + + '/// // 69 300\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#max\n' + + '///\n' + + 'asm fun max(x: Int, y: Int): Int { MAX }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the absolute value of the `Int` value `x`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// abs(42); // 42\n' + + '/// abs(-42); // 42\n' + + '/// abs(-(-(-42))); // 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#abs\n' + + '///\n' + + 'asm fun abs(x: Int): Int { ABS }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the logarithm of a number `num` > 0 to the base `base` ≥ 1. Results are rounded down.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// log(1000, 10); // 3, as 10^3 is 1000\n' + + '/// // ↑ ↑ ↑ ↑\n' + + '/// // num base base num\n' + + '///\n' + + '/// log(1001, 10); // 3\n' + + '/// log(999, 10); // 2\n' + + '/// try {\n' + + '/// log(-1000, 10); // exit code 5 because of the non-positive num\n' + + '/// }\n' + + '/// log(1024, 2); // 10\n' + + '/// try {\n' + + '/// log(1024, -2); // exit code 5 because the base is less than 1\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `num` value is non-positive\n' + + '/// or the given `base` value is less than 1.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log2\n' + + '///\n' + + '@name(__tact_log)\n' + + 'native log(num: Int, base: Int): Int;\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Similar to `log()`, but sets the `base` to 2.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// log2(1024); // 10, as 2^10 is 1024\n' + + '/// // ↑ ↑ ↑\n' + + '/// // num base₂ num\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `num` value is non-positive.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log2\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log.\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes/#5\n' + + '///\n' + + 'asm fun log2(num: Int): Int { DUP 5 THROWIFNOT UBITSIZE DEC }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the exponentiation involving two numbers: the `base` and the exponent (or _power_) `exp`.\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Example {\n' + + '/// // Persistent state variables\n' + + '/// p23: Int = pow(2, 3); // raises 2 to the 3rd power, which is 8\n' + + '/// one: Int = pow(5, 0); // raises 5 to the power 0, which always produces 1\n' + + '/// // works at compile-time!\n' + + '///\n' + + '/// // Internal message receiver\n' + + '/// receive() {\n' + + '/// pow(self.p23, self.one + 1); // 64, works at run-time too!\n' + + '/// try {\n' + + '/// pow(0, -1); // exit code 5: Integer out of expected range\n' + + '/// }\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `exp` value is negative.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow2\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes/#5\n' + + '///\n' + + 'inline fun pow(base: Int, exp: Int): Int {\n' + + ' throwUnless(5, exp >= 0);\n' + + ' let result = 1;\n' + + ' repeat (exp) {\n' + + ' result *= base;\n' + + ' }\n' + + ' return result;\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Similar to `pow()`, but sets the `base` to 2.\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Example {\n' + + '/// // Persistent state variables\n' + + '/// p23: Int = pow2(3); // raises 2 to the 3rd power, which is 8\n' + + '/// one: Int = pow2(0); // raises 2 to the power 0, which always produces 1\n' + + '/// // works at compile-time!\n' + + '///\n' + + '/// // Internal message receiver, which accepts message ExtMsg\n' + + '/// receive() {\n' + + '/// pow2(self.one + 1); // 4, works at run-time too!\n' + + '/// try {\n' + + '/// pow(-1); // exit code 5: Integer out of expected range\n' + + '/// }\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify a negative value of `exp`.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow2\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun pow2(exp: Int): Int { POW2 }\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Computes and returns the sign of the `Int` value `x`. Produces 1 if the `x` is positive, -1 if the `x` is negative, and 0 if the `x` is 0.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// '... 5983 more characters, + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomize', + loc: { start: 965, end: 980 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { kind: 'id', text: 'x', loc: { start: 981, end: 982 } }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 984, end: 987 } + }, + loc: { start: 984, end: 987 } + }, + loc: { start: 981, end: 987 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ADDRAND' ] + }, + loc: { start: 957, end: 1000 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomizeLt', + loc: { start: 1822, end: 1839 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LTIME ADDRAND' ] + }, + loc: { start: 1814, end: 1859 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 2466, end: 2485 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_prepare_random', + loc: { start: 2436, end: 2457 } + } + }, + loc: { start: 2430, end: 2488 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandom', + loc: { start: 2949, end: 2961 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2965, end: 2968 } + }, + loc: { start: 2965, end: 2968 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RANDU256' ] + }, + loc: { start: 2941, end: 2981 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomInterval', + loc: { start: 3216, end: 3236 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3248, end: 3251 } + }, + loc: { start: 3248, end: 3251 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'max', + loc: { start: 3237, end: 3240 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3242, end: 3245 } + }, + loc: { start: 3242, end: 3245 } + }, + loc: { start: 3237, end: 3245 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RAND' ] + }, + loc: { start: 3208, end: 3260 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'randomInt', + loc: { start: 3953, end: 3962 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3966, end: 3969 } + }, + loc: { start: 3966, end: 3969 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 3976, end: 3995 } + }, + typeArgs: [], + args: [], + loc: { start: 3976, end: 3997 } + }, + loc: { start: 3976, end: 3998 } + }, + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativeRandom', + loc: { start: 4010, end: 4022 } + }, + typeArgs: [], + args: [], + loc: { start: 4010, end: 4024 } + }, + loc: { start: 4003, end: 4025 } + } + ] + }, + loc: { start: 3942, end: 4027 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'random', + loc: { start: 4505, end: 4511 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4533, end: 4536 } + }, + loc: { start: 4533, end: 4536 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'min', + loc: { start: 4512, end: 4515 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4517, end: 4520 } + }, + loc: { start: 4517, end: 4520 } + }, + loc: { start: 4512, end: 4520 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'max', + loc: { start: 4522, end: 4525 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4527, end: 4530 } + }, + loc: { start: 4527, end: 4530 } + }, + loc: { start: 4522, end: 4530 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 4543, end: 4562 } + }, + typeArgs: [], + args: [], + loc: { start: 4543, end: 4564 } + }, + loc: { start: 4543, end: 4565 } + }, + { + kind: 'statement_return', + expression: { + kind: 'op_binary', + op: '+', + left: { + kind: 'var', + name: 'min', + loc: { start: 4577, end: 4580 } + }, + right: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativeRandomInterval', + loc: { start: 4583, end: 4603 } + }, + typeArgs: [], + args: [ + { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'max', + loc: { start: 4604, end: 4607 } + }, + right: { + kind: 'var', + name: 'min', + loc: { start: 4610, end: 4613 } + }, + loc: { start: 4604, end: 4613 } + } + ], + loc: { start: 4583, end: 4614 } + }, + loc: { start: 4577, end: 4614 } + }, + loc: { start: 4570, end: 4615 } + } + ] + }, + loc: { start: 4494, end: 4617 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'min', loc: { start: 5017, end: 5020 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5038, end: 5041 } + }, + loc: { start: 5038, end: 5041 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5021, end: 5022 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5024, end: 5027 } + }, + loc: { start: 5024, end: 5027 } + }, + loc: { start: 5021, end: 5027 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 5029, end: 5030 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5032, end: 5035 } + }, + loc: { start: 5032, end: 5035 } + }, + loc: { start: 5029, end: 5035 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MIN' ] + }, + loc: { start: 5009, end: 5049 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'max', loc: { start: 5435, end: 5438 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5456, end: 5459 } + }, + loc: { start: 5456, end: 5459 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5439, end: 5440 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5442, end: 5445 } + }, + loc: { start: 5442, end: 5445 } + }, + loc: { start: 5439, end: 5445 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 5447, end: 5448 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5450, end: 5453 } + }, + loc: { start: 5450, end: 5453 } + }, + loc: { start: 5447, end: 5453 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MAX' ] + }, + loc: { start: 5427, end: 5467 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'abs', loc: { start: 5773, end: 5776 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5786, end: 5789 } + }, + loc: { start: 5786, end: 5789 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5777, end: 5778 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5780, end: 5783 } + }, + loc: { start: 5780, end: 5783 } + }, + loc: { start: 5777, end: 5783 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ABS' ] + }, + loc: { start: 5765, end: 5797 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'log', loc: { start: 6721, end: 6724 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6747, end: 6750 } + }, + loc: { start: 6747, end: 6750 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 6725, end: 6728 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6730, end: 6733 } + }, + loc: { start: 6730, end: 6733 } + }, + loc: { start: 6725, end: 6733 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'base', + loc: { start: 6735, end: 6739 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6741, end: 6744 } + }, + loc: { start: 6741, end: 6744 } + }, + loc: { start: 6735, end: 6744 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_log', + loc: { start: 6702, end: 6712 } + } + }, + loc: { start: 6696, end: 6751 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'log2', loc: { start: 7341, end: 7345 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7357, end: 7360 } + }, + loc: { start: 7357, end: 7360 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 7346, end: 7349 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7351, end: 7354 } + }, + loc: { start: 7351, end: 7354 } + }, + loc: { start: 7346, end: 7354 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DUP 5 THROWIFNOT UBITSIZE DEC' ] + }, + loc: { start: 7333, end: 7394 } + }, + { + kind: 'function', + inline: true, + name: { kind: 'id', text: 'pow', loc: { start: 8510, end: 8513 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8536, end: 8539 } + }, + loc: { start: 8536, end: 8539 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'base', + loc: { start: 8514, end: 8518 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8520, end: 8523 } + }, + loc: { start: 8520, end: 8523 } + }, + loc: { start: 8514, end: 8523 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'exp', + loc: { start: 8525, end: 8528 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8530, end: 8533 } + }, + loc: { start: 8530, end: 8533 } + }, + loc: { start: 8525, end: 8533 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throwUnless', + loc: { start: 8546, end: 8557 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 5n, + loc: { start: 8558, end: 8559 } + }, + { + kind: 'op_binary', + op: '>=', + left: { + kind: 'var', + name: 'exp', + loc: { start: 8561, end: 8564 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 8568, end: 8569 } + }, + loc: { start: 8561, end: 8569 } + } + ], + loc: { start: 8546, end: 8570 } + }, + loc: { start: 8546, end: 8571 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'result', + loc: { start: 8580, end: 8586 } + }, + type: undefined, + expression: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 8589, end: 8590 } + }, + loc: { start: 8576, end: 8591 } + }, + { + kind: 'statement_repeat', + iterations: { + kind: 'var', + name: 'exp', + loc: { start: 8604, end: 8607 } + }, + statements: [ + { + kind: 'statement_augmentedassign', + op: '*=', + path: { + kind: 'var', + name: 'result', + loc: { start: 8619, end: 8625 } + }, + expression: { + kind: 'var', + name: 'base', + loc: { start: 8629, end: 8633 } + }, + loc: { start: 8619, end: 8634 } + } + ], + loc: { start: 8596, end: 8640 } + }, + { + kind: 'statement_return', + expression: { + kind: 'var', + name: 'result', + loc: { start: 8652, end: 8658 } + }, + loc: { start: 8645, end: 8659 } + } + ] + }, + loc: { start: 8499, end: 8661 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'pow2', loc: { start: 9733, end: 9737 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9749, end: 9752 } + }, + loc: { start: 9749, end: 9752 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'exp', + loc: { start: 9738, end: 9741 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9743, end: 9746 } + }, + loc: { start: 9743, end: 9746 } + }, + loc: { start: 9738, end: 9746 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'POW2' ] + }, + loc: { start: 9725, end: 9761 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sign', + loc: { start: 10233, end: 10237 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10247, end: 10250 } + }, + loc: { start: 10247, end: 10250 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 10238, end: 10239 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10241, end: 10244 } + }, + loc: { start: 10241, end: 10244 } + }, + loc: { start: 10238, end: 10244 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SGN' ] + }, + loc: { start: 10225, end: 10258 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'divc', + loc: { start: 10814, end: 10818 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10836, end: 10839 } + }, + loc: { start: 10836, end: 10839 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 10819, end: 10820 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10822, end: 10825 } + }, + loc: { start: 10822, end: 10825 } + }, + loc: { start: 10819, end: 10825 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 10827, end: 10828 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10830, end: 10833 } + }, + loc: { start: 10830, end: 10833 } + }, + loc: { start: 10827, end: 10833 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DIVC' ] + }, + loc: { start: 10806, end: 10848 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'muldivc', + loc: { start: 11615, end: 11622 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11648, end: 11651 } + }, + loc: { start: 11648, end: 11651 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 11623, end: 11624 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11626, end: 11629 } + }, + loc: { start: 11626, end: 11629 } + }, + loc: { start: 11623, end: 11629 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 11631, end: 11632 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11634, end: 11637 } + }, + loc: { start: 11634, end: 11637 } + }, + loc: { start: 11631, end: 11637 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 11639, end: 11640 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11642, end: 11645 } + }, + loc: { start: 11642, end: 11645 } + }, + loc: { start: 11639, end: 11645 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULDIVC' ] + }, + loc: { start: 11607, end: 11663 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRight', + loc: { start: 12751, end: 12764 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12790, end: 12793 } + }, + loc: { start: 12790, end: 12793 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 12765, end: 12766 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12768, end: 12771 } + }, + loc: { start: 12768, end: 12771 } + }, + loc: { start: 12765, end: 12771 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 12773, end: 12774 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12776, end: 12779 } + }, + loc: { start: 12776, end: 12779 } + }, + loc: { start: 12773, end: 12779 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 12781, end: 12782 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12784, end: 12787 } + }, + loc: { start: 12784, end: 12787 } + }, + loc: { start: 12781, end: 12787 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFT' ] + }, + loc: { start: 12743, end: 12807 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRightRound', + loc: { start: 13862, end: 13880 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13906, end: 13909 } + }, + loc: { start: 13906, end: 13909 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 13881, end: 13882 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13884, end: 13887 } + }, + loc: { start: 13884, end: 13887 } + }, + loc: { start: 13881, end: 13887 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 13889, end: 13890 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13892, end: 13895 } + }, + loc: { start: 13892, end: 13895 } + }, + loc: { start: 13889, end: 13895 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 13897, end: 13898 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13900, end: 13903 } + }, + loc: { start: 13900, end: 13903 } + }, + loc: { start: 13897, end: 13903 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFTR' ] + }, + loc: { start: 13854, end: 13924 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRightCeil', + loc: { start: 14875, end: 14892 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14918, end: 14921 } + }, + loc: { start: 14918, end: 14921 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 14893, end: 14894 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14896, end: 14899 } + }, + loc: { start: 14896, end: 14899 } + }, + loc: { start: 14893, end: 14899 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 14901, end: 14902 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14904, end: 14907 } + }, + loc: { start: 14904, end: 14907 } + }, + loc: { start: 14901, end: 14907 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 14909, end: 14910 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14912, end: 14915 } + }, + loc: { start: 14912, end: 14915 } + }, + loc: { start: 14909, end: 14915 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFTC' ] + }, + loc: { start: 14867, end: 14936 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sqrt', + loc: { start: 15698, end: 15702 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15714, end: 15717 } + }, + loc: { start: 15714, end: 15717 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 15703, end: 15706 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15708, end: 15711 } + }, + loc: { start: 15708, end: 15711 } + }, + loc: { start: 15703, end: 15711 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'num', + loc: { start: 15728, end: 15731 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15735, end: 15736 } + }, + loc: { start: 15728, end: 15736 } + }, + trueStatements: [ + { + kind: 'statement_return', + expression: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15755, end: 15756 } + }, + loc: { start: 15748, end: 15757 } + } + ], + falseStatements: undefined, + loc: { start: 15724, end: 15763 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 's', + loc: { start: 15773, end: 15774 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15776, end: 15779 } + }, + loc: { start: 15776, end: 15779 } + }, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'log2', + loc: { start: 15782, end: 15786 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'num', + loc: { start: 15787, end: 15790 } + } + ], + loc: { start: 15782, end: 15791 } + }, + loc: { start: 15769, end: 15792 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'x', + loc: { start: 15801, end: 15802 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15804, end: 15807 } + }, + loc: { start: 15804, end: 15807 } + }, + expression: { + kind: 'conditional', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 's', + loc: { start: 15811, end: 15812 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15816, end: 15817 } + }, + loc: { start: 15811, end: 15817 } + }, + thenBranch: { + kind: 'op_binary', + op: '+', + left: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'num', + loc: { start: 15821, end: 15824 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15827, end: 15828 } + }, + loc: { start: 15821, end: 15828 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15832, end: 15833 } + }, + loc: { start: 15820, end: 15833 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15836, end: 15837 } + }, + loc: { start: 15820, end: 15837 } + }, + elseBranch: { + kind: 'op_binary', + op: '<<', + left: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15840, end: 15841 } + }, + right: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '+', + left: { + kind: 'var', + name: 's', + loc: { start: 15847, end: 15848 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15851, end: 15852 } + }, + loc: { start: 15847, end: 15852 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15856, end: 15857 } + }, + loc: { start: 15846, end: 15857 } + }, + loc: { start: 15840, end: 15858 } + }, + loc: { start: 15811, end: 15858 } + }, + loc: { start: 15797, end: 15860 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'q', + loc: { start: 15870, end: 15871 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15873, end: 15876 } + }, + loc: { start: 15873, end: 15876 } + }, + expression: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15879, end: 15880 } + }, + loc: { start: 15866, end: 15881 } + }, + { + kind: 'statement_until', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'q', + loc: { start: 15957, end: 15958 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15962, end: 15963 } + }, + loc: { start: 15957, end: 15963 } + }, + statements: [ + { + kind: 'statement_assign', + path: { + kind: 'var', + name: 'q', + loc: { start: 15900, end: 15901 } + }, + expression: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '-', + left: { + kind: 'static_call', + function: { + kind: 'id', + text: 'divc', + loc: { start: 15905, end: 15909 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'num', + loc: { start: 15910, end: 15913 } + }, + { + kind: 'var', + name: 'x', + loc: { start: 15915, end: 15916 } + } + ], + loc: { start: 15905, end: 15917 } + }, + right: { + kind: 'var', + name: 'x', + loc: { start: 15920, end: 15921 } + }, + loc: { start: 15905, end: 15921 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15925, end: 15926 } + }, + loc: { start: 15904, end: 15926 } + }, + loc: { start: 15900, end: 15927 } + }, + { + kind: 'statement_augmentedassign', + op: '+=', + path: { + kind: 'var', + name: 'x', + loc: { start: 15936, end: 15937 } + }, + expression: { + kind: 'var', + name: 'q', + loc: { start: 15941, end: 15942 } + }, + loc: { start: 15936, end: 15943 } + } + ], + loc: { start: 15887, end: 15965 } + }, + { + kind: 'statement_return', + expression: { + kind: 'var', + name: 'x', + loc: { start: 15978, end: 15979 } + }, + loc: { start: 15971, end: 15980 } + } + ] + }, + loc: { start: 15694, end: 15982 } + } + ] + }, + 'random' => { + kind: 'tact', + path: 'std/internal/math.tact', + code: '// Prepare random\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Randomizes the pseudorandom number generator with the specified unsigned 256-bit `Int` `x` by mixing it with the current seed. The new seed is the unsigned 256-bit `Int` value of the SHA-256 hash of concatenated old seed and `x` in their 32-byte strings big-endian representation.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativeRandomize(42); // now, random numbers are less predictable\n' + + "/// let idk: Int = randomInt(); // ???, it's random,\n" + + '/// // but the seed was adjusted deterministically!\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify a negative value of `x`.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomize\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun nativeRandomize(x: Int) { ADDRAND }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Randomizes the random number generator with the logical time of the current transaction. Equivalent to calling `nativeRandomize(curLt())`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativeRandomizeLt(); // now, random numbers are unpredictable for users,\n' + + '/// // but still may be affected by validators or collators\n' + + '/// // as they determine the seed of the current block.\n' + + "/// let idk: Int = randomInt(); // ???, it's random!\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomizelt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomize\n' + + '/// * https://docs.tact-lang.org/ref/core-contextstate#curlt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + 'asm fun nativeRandomizeLt() { LTIME ADDRAND }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Prepares a random number generator by using `nativeRandomizeLt()`. Automatically called by `randomInt()` and `random()` functions.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativePrepareRandom(); // prepare the RNG\n' + + '/// // ... do your random things ...\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativepreparerandom\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomizelt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '/// * https://docs.tact-lang.org/ref/core-random#random\n' + + '///\n' + + '@name(__tact_prepare_random)\n' + + 'native nativePrepareRandom();\n' + + '\n' + + '// Random\n' + + '\n' + + '// Generates a new pseudo-random unsigned 256-bit integer x.\n' + + '// The algorithm is as follows: if r is the old value of the random seed,\n' + + '// considered as a 32-byte array (by constructing the big-endian representation\n' + + '// of an unsigned 256-bit integer), then its sha512(r) is computed;\n' + + "// the first 32 bytes of this hash are stored as the new value r' of the random seed,\n" + + '// and the remaining 32 bytes are returned as the next random value x.\n' + + 'asm fun nativeRandom(): Int { RANDU256 }\n' + + '\n' + + '// Generates a new pseudo-random integer z in the range 0..range−1\n' + + '// (or range..−1, if range < 0).\n' + + '// More precisely, an unsigned random value x is generated as in `nativeRandom`;\n' + + '// then z := x * range / 2^256 is computed.\n' + + 'asm fun nativeRandomInterval(max: Int): Int { RAND }\n' + + '\n' + + '/// Generates and returns a new pseudo-random unsigned 256-bit `Int` value `x`.\n' + + '///\n' + + '/// The algorithm works as follows: first, the `sha512(r)` is computed. There, `r` is an old\n' + + '/// value of the random seed, which is taken as a 32-byte array constructed from the big-endian\n' + + '/// representation of an unsigned 256-bit `Int`. The first 32 bytes of this hash are stored as the new\n' + + "/// value `r'` of the random seed, and the remaining 32 bytes are returned as the next random value `x`.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + "/// let allYourRandomBelongToUs: Int = randomInt(); // ???, it's random :)\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + 'inline fun randomInt(): Int {\n' + + ' nativePrepareRandom();\n' + + ' return nativeRandom();\n' + + '}\n' + + '\n' + + '/// Generates and returns a new pseudo-random unsigned `Int` value `x` in the provided semi-closed\n' + + '/// interval: `min` ≤ `x` < `max`, or `min` ≥ `x` > `max` if both `min` and `max` are negative.\n' + + '///\n' + + '/// Note that the `max` value is never included in the interval.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// random(42, 43); // 42, always\n' + + '/// random(0, 42); // 0-41, but never 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-random#random\n' + + '///\n' + + 'inline fun random(min: Int, max: Int): Int {\n' + + ' nativePrepareRandom();\n' + + ' return min + nativeRandomInterval(max - min);\n' + + '}\n' + + '\n' + + '// Math\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the minimum of two `Int` values `x` and `y`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// min(1, 2); // 1\n' + + '/// min(2, 2); // 2\n' + + '/// min(007, 3); // 3\n' + + '/// min(0x45, 3_0_0); // 69, nice\n' + + '/// // ↑ ↑\n' + + '/// // 69 300\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#min\n' + + '///\n' + + 'asm fun min(x: Int, y: Int): Int { MIN }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the maximum of two `Int` values `x` and `y`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// max(1, 2); // 2\n' + + '/// max(2, 2); // 2\n' + + '/// max(007, 3); // 7\n' + + '/// max(0x45, 3_0_0); // 300\n' + + '/// // ↑ ↑\n' + + '/// // 69 300\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#max\n' + + '///\n' + + 'asm fun max(x: Int, y: Int): Int { MAX }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the absolute value of the `Int` value `x`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// abs(42); // 42\n' + + '/// abs(-42); // 42\n' + + '/// abs(-(-(-42))); // 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#abs\n' + + '///\n' + + 'asm fun abs(x: Int): Int { ABS }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the logarithm of a number `num` > 0 to the base `base` ≥ 1. Results are rounded down.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// log(1000, 10); // 3, as 10^3 is 1000\n' + + '/// // ↑ ↑ ↑ ↑\n' + + '/// // num base base num\n' + + '///\n' + + '/// log(1001, 10); // 3\n' + + '/// log(999, 10); // 2\n' + + '/// try {\n' + + '/// log(-1000, 10); // exit code 5 because of the non-positive num\n' + + '/// }\n' + + '/// log(1024, 2); // 10\n' + + '/// try {\n' + + '/// log(1024, -2); // exit code 5 because the base is less than 1\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `num` value is non-positive\n' + + '/// or the given `base` value is less than 1.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log2\n' + + '///\n' + + '@name(__tact_log)\n' + + 'native log(num: Int, base: Int): Int;\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Similar to `log()`, but sets the `base` to 2.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// log2(1024); // 10, as 2^10 is 1024\n' + + '/// // ↑ ↑ ↑\n' + + '/// // num base₂ num\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `num` value is non-positive.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log2\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log.\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes/#5\n' + + '///\n' + + 'asm fun log2(num: Int): Int { DUP 5 THROWIFNOT UBITSIZE DEC }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the exponentiation involving two numbers: the `base` and the exponent (or _power_) `exp`.\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Example {\n' + + '/// // Persistent state variables\n' + + '/// p23: Int = pow(2, 3); // raises 2 to the 3rd power, which is 8\n' + + '/// one: Int = pow(5, 0); // raises 5 to the power 0, which always produces 1\n' + + '/// // works at compile-time!\n' + + '///\n' + + '/// // Internal message receiver\n' + + '/// receive() {\n' + + '/// pow(self.p23, self.one + 1); // 64, works at run-time too!\n' + + '/// try {\n' + + '/// pow(0, -1); // exit code 5: Integer out of expected range\n' + + '/// }\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `exp` value is negative.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow2\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes/#5\n' + + '///\n' + + 'inline fun pow(base: Int, exp: Int): Int {\n' + + ' throwUnless(5, exp >= 0);\n' + + ' let result = 1;\n' + + ' repeat (exp) {\n' + + ' result *= base;\n' + + ' }\n' + + ' return result;\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Similar to `pow()`, but sets the `base` to 2.\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Example {\n' + + '/// // Persistent state variables\n' + + '/// p23: Int = pow2(3); // raises 2 to the 3rd power, which is 8\n' + + '/// one: Int = pow2(0); // raises 2 to the power 0, which always produces 1\n' + + '/// // works at compile-time!\n' + + '///\n' + + '/// // Internal message receiver, which accepts message ExtMsg\n' + + '/// receive() {\n' + + '/// pow2(self.one + 1); // 4, works at run-time too!\n' + + '/// try {\n' + + '/// pow(-1); // exit code 5: Integer out of expected range\n' + + '/// }\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify a negative value of `exp`.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow2\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun pow2(exp: Int): Int { POW2 }\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Computes and returns the sign of the `Int` value `x`. Produces 1 if the `x` is positive, -1 if the `x` is negative, and 0 if the `x` is 0.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// '... 5983 more characters, + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomize', + loc: { start: 965, end: 980 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { kind: 'id', text: 'x', loc: { start: 981, end: 982 } }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 984, end: 987 } + }, + loc: { start: 984, end: 987 } + }, + loc: { start: 981, end: 987 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ADDRAND' ] + }, + loc: { start: 957, end: 1000 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomizeLt', + loc: { start: 1822, end: 1839 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LTIME ADDRAND' ] + }, + loc: { start: 1814, end: 1859 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 2466, end: 2485 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_prepare_random', + loc: { start: 2436, end: 2457 } + } + }, + loc: { start: 2430, end: 2488 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandom', + loc: { start: 2949, end: 2961 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2965, end: 2968 } + }, + loc: { start: 2965, end: 2968 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RANDU256' ] + }, + loc: { start: 2941, end: 2981 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomInterval', + loc: { start: 3216, end: 3236 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3248, end: 3251 } + }, + loc: { start: 3248, end: 3251 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'max', + loc: { start: 3237, end: 3240 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3242, end: 3245 } + }, + loc: { start: 3242, end: 3245 } + }, + loc: { start: 3237, end: 3245 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RAND' ] + }, + loc: { start: 3208, end: 3260 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'randomInt', + loc: { start: 3953, end: 3962 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3966, end: 3969 } + }, + loc: { start: 3966, end: 3969 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 3976, end: 3995 } + }, + typeArgs: [], + args: [], + loc: { start: 3976, end: 3997 } + }, + loc: { start: 3976, end: 3998 } + }, + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativeRandom', + loc: { start: 4010, end: 4022 } + }, + typeArgs: [], + args: [], + loc: { start: 4010, end: 4024 } + }, + loc: { start: 4003, end: 4025 } + } + ] + }, + loc: { start: 3942, end: 4027 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'random', + loc: { start: 4505, end: 4511 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4533, end: 4536 } + }, + loc: { start: 4533, end: 4536 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'min', + loc: { start: 4512, end: 4515 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4517, end: 4520 } + }, + loc: { start: 4517, end: 4520 } + }, + loc: { start: 4512, end: 4520 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'max', + loc: { start: 4522, end: 4525 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4527, end: 4530 } + }, + loc: { start: 4527, end: 4530 } + }, + loc: { start: 4522, end: 4530 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 4543, end: 4562 } + }, + typeArgs: [], + args: [], + loc: { start: 4543, end: 4564 } + }, + loc: { start: 4543, end: 4565 } + }, + { + kind: 'statement_return', + expression: { + kind: 'op_binary', + op: '+', + left: { + kind: 'var', + name: 'min', + loc: { start: 4577, end: 4580 } + }, + right: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativeRandomInterval', + loc: { start: 4583, end: 4603 } + }, + typeArgs: [], + args: [ + { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'max', + loc: { start: 4604, end: 4607 } + }, + right: { + kind: 'var', + name: 'min', + loc: { start: 4610, end: 4613 } + }, + loc: { start: 4604, end: 4613 } + } + ], + loc: { start: 4583, end: 4614 } + }, + loc: { start: 4577, end: 4614 } + }, + loc: { start: 4570, end: 4615 } + } + ] + }, + loc: { start: 4494, end: 4617 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'min', loc: { start: 5017, end: 5020 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5038, end: 5041 } + }, + loc: { start: 5038, end: 5041 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5021, end: 5022 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5024, end: 5027 } + }, + loc: { start: 5024, end: 5027 } + }, + loc: { start: 5021, end: 5027 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 5029, end: 5030 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5032, end: 5035 } + }, + loc: { start: 5032, end: 5035 } + }, + loc: { start: 5029, end: 5035 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MIN' ] + }, + loc: { start: 5009, end: 5049 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'max', loc: { start: 5435, end: 5438 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5456, end: 5459 } + }, + loc: { start: 5456, end: 5459 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5439, end: 5440 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5442, end: 5445 } + }, + loc: { start: 5442, end: 5445 } + }, + loc: { start: 5439, end: 5445 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 5447, end: 5448 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5450, end: 5453 } + }, + loc: { start: 5450, end: 5453 } + }, + loc: { start: 5447, end: 5453 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MAX' ] + }, + loc: { start: 5427, end: 5467 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'abs', loc: { start: 5773, end: 5776 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5786, end: 5789 } + }, + loc: { start: 5786, end: 5789 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5777, end: 5778 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5780, end: 5783 } + }, + loc: { start: 5780, end: 5783 } + }, + loc: { start: 5777, end: 5783 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ABS' ] + }, + loc: { start: 5765, end: 5797 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'log', loc: { start: 6721, end: 6724 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6747, end: 6750 } + }, + loc: { start: 6747, end: 6750 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 6725, end: 6728 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6730, end: 6733 } + }, + loc: { start: 6730, end: 6733 } + }, + loc: { start: 6725, end: 6733 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'base', + loc: { start: 6735, end: 6739 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6741, end: 6744 } + }, + loc: { start: 6741, end: 6744 } + }, + loc: { start: 6735, end: 6744 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_log', + loc: { start: 6702, end: 6712 } + } + }, + loc: { start: 6696, end: 6751 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'log2', loc: { start: 7341, end: 7345 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7357, end: 7360 } + }, + loc: { start: 7357, end: 7360 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 7346, end: 7349 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7351, end: 7354 } + }, + loc: { start: 7351, end: 7354 } + }, + loc: { start: 7346, end: 7354 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DUP 5 THROWIFNOT UBITSIZE DEC' ] + }, + loc: { start: 7333, end: 7394 } + }, + { + kind: 'function', + inline: true, + name: { kind: 'id', text: 'pow', loc: { start: 8510, end: 8513 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8536, end: 8539 } + }, + loc: { start: 8536, end: 8539 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'base', + loc: { start: 8514, end: 8518 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8520, end: 8523 } + }, + loc: { start: 8520, end: 8523 } + }, + loc: { start: 8514, end: 8523 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'exp', + loc: { start: 8525, end: 8528 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8530, end: 8533 } + }, + loc: { start: 8530, end: 8533 } + }, + loc: { start: 8525, end: 8533 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throwUnless', + loc: { start: 8546, end: 8557 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 5n, + loc: { start: 8558, end: 8559 } + }, + { + kind: 'op_binary', + op: '>=', + left: { + kind: 'var', + name: 'exp', + loc: { start: 8561, end: 8564 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 8568, end: 8569 } + }, + loc: { start: 8561, end: 8569 } + } + ], + loc: { start: 8546, end: 8570 } + }, + loc: { start: 8546, end: 8571 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'result', + loc: { start: 8580, end: 8586 } + }, + type: undefined, + expression: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 8589, end: 8590 } + }, + loc: { start: 8576, end: 8591 } + }, + { + kind: 'statement_repeat', + iterations: { + kind: 'var', + name: 'exp', + loc: { start: 8604, end: 8607 } + }, + statements: [ + { + kind: 'statement_augmentedassign', + op: '*=', + path: { + kind: 'var', + name: 'result', + loc: { start: 8619, end: 8625 } + }, + expression: { + kind: 'var', + name: 'base', + loc: { start: 8629, end: 8633 } + }, + loc: { start: 8619, end: 8634 } + } + ], + loc: { start: 8596, end: 8640 } + }, + { + kind: 'statement_return', + expression: { + kind: 'var', + name: 'result', + loc: { start: 8652, end: 8658 } + }, + loc: { start: 8645, end: 8659 } + } + ] + }, + loc: { start: 8499, end: 8661 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'pow2', loc: { start: 9733, end: 9737 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9749, end: 9752 } + }, + loc: { start: 9749, end: 9752 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'exp', + loc: { start: 9738, end: 9741 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9743, end: 9746 } + }, + loc: { start: 9743, end: 9746 } + }, + loc: { start: 9738, end: 9746 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'POW2' ] + }, + loc: { start: 9725, end: 9761 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sign', + loc: { start: 10233, end: 10237 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10247, end: 10250 } + }, + loc: { start: 10247, end: 10250 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 10238, end: 10239 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10241, end: 10244 } + }, + loc: { start: 10241, end: 10244 } + }, + loc: { start: 10238, end: 10244 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SGN' ] + }, + loc: { start: 10225, end: 10258 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'divc', + loc: { start: 10814, end: 10818 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10836, end: 10839 } + }, + loc: { start: 10836, end: 10839 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 10819, end: 10820 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10822, end: 10825 } + }, + loc: { start: 10822, end: 10825 } + }, + loc: { start: 10819, end: 10825 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 10827, end: 10828 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10830, end: 10833 } + }, + loc: { start: 10830, end: 10833 } + }, + loc: { start: 10827, end: 10833 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DIVC' ] + }, + loc: { start: 10806, end: 10848 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'muldivc', + loc: { start: 11615, end: 11622 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11648, end: 11651 } + }, + loc: { start: 11648, end: 11651 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 11623, end: 11624 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11626, end: 11629 } + }, + loc: { start: 11626, end: 11629 } + }, + loc: { start: 11623, end: 11629 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 11631, end: 11632 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11634, end: 11637 } + }, + loc: { start: 11634, end: 11637 } + }, + loc: { start: 11631, end: 11637 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 11639, end: 11640 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11642, end: 11645 } + }, + loc: { start: 11642, end: 11645 } + }, + loc: { start: 11639, end: 11645 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULDIVC' ] + }, + loc: { start: 11607, end: 11663 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRight', + loc: { start: 12751, end: 12764 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12790, end: 12793 } + }, + loc: { start: 12790, end: 12793 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 12765, end: 12766 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12768, end: 12771 } + }, + loc: { start: 12768, end: 12771 } + }, + loc: { start: 12765, end: 12771 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 12773, end: 12774 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12776, end: 12779 } + }, + loc: { start: 12776, end: 12779 } + }, + loc: { start: 12773, end: 12779 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 12781, end: 12782 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12784, end: 12787 } + }, + loc: { start: 12784, end: 12787 } + }, + loc: { start: 12781, end: 12787 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFT' ] + }, + loc: { start: 12743, end: 12807 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRightRound', + loc: { start: 13862, end: 13880 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13906, end: 13909 } + }, + loc: { start: 13906, end: 13909 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 13881, end: 13882 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13884, end: 13887 } + }, + loc: { start: 13884, end: 13887 } + }, + loc: { start: 13881, end: 13887 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 13889, end: 13890 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13892, end: 13895 } + }, + loc: { start: 13892, end: 13895 } + }, + loc: { start: 13889, end: 13895 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 13897, end: 13898 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13900, end: 13903 } + }, + loc: { start: 13900, end: 13903 } + }, + loc: { start: 13897, end: 13903 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFTR' ] + }, + loc: { start: 13854, end: 13924 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRightCeil', + loc: { start: 14875, end: 14892 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14918, end: 14921 } + }, + loc: { start: 14918, end: 14921 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 14893, end: 14894 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14896, end: 14899 } + }, + loc: { start: 14896, end: 14899 } + }, + loc: { start: 14893, end: 14899 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 14901, end: 14902 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14904, end: 14907 } + }, + loc: { start: 14904, end: 14907 } + }, + loc: { start: 14901, end: 14907 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 14909, end: 14910 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14912, end: 14915 } + }, + loc: { start: 14912, end: 14915 } + }, + loc: { start: 14909, end: 14915 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFTC' ] + }, + loc: { start: 14867, end: 14936 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sqrt', + loc: { start: 15698, end: 15702 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15714, end: 15717 } + }, + loc: { start: 15714, end: 15717 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 15703, end: 15706 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15708, end: 15711 } + }, + loc: { start: 15708, end: 15711 } + }, + loc: { start: 15703, end: 15711 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'num', + loc: { start: 15728, end: 15731 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15735, end: 15736 } + }, + loc: { start: 15728, end: 15736 } + }, + trueStatements: [ + { + kind: 'statement_return', + expression: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15755, end: 15756 } + }, + loc: { start: 15748, end: 15757 } + } + ], + falseStatements: undefined, + loc: { start: 15724, end: 15763 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 's', + loc: { start: 15773, end: 15774 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15776, end: 15779 } + }, + loc: { start: 15776, end: 15779 } + }, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'log2', + loc: { start: 15782, end: 15786 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'num', + loc: { start: 15787, end: 15790 } + } + ], + loc: { start: 15782, end: 15791 } + }, + loc: { start: 15769, end: 15792 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'x', + loc: { start: 15801, end: 15802 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15804, end: 15807 } + }, + loc: { start: 15804, end: 15807 } + }, + expression: { + kind: 'conditional', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 's', + loc: { start: 15811, end: 15812 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15816, end: 15817 } + }, + loc: { start: 15811, end: 15817 } + }, + thenBranch: { + kind: 'op_binary', + op: '+', + left: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'num', + loc: { start: 15821, end: 15824 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15827, end: 15828 } + }, + loc: { start: 15821, end: 15828 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15832, end: 15833 } + }, + loc: { start: 15820, end: 15833 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15836, end: 15837 } + }, + loc: { start: 15820, end: 15837 } + }, + elseBranch: { + kind: 'op_binary', + op: '<<', + left: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15840, end: 15841 } + }, + right: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '+', + left: { + kind: 'var', + name: 's', + loc: { start: 15847, end: 15848 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15851, end: 15852 } + }, + loc: { start: 15847, end: 15852 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15856, end: 15857 } + }, + loc: { start: 15846, end: 15857 } + }, + loc: { start: 15840, end: 15858 } + }, + loc: { start: 15811, end: 15858 } + }, + loc: { start: 15797, end: 15860 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'q', + loc: { start: 15870, end: 15871 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15873, end: 15876 } + }, + loc: { start: 15873, end: 15876 } + }, + expression: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15879, end: 15880 } + }, + loc: { start: 15866, end: 15881 } + }, + { + kind: 'statement_until', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'q', + loc: { start: 15957, end: 15958 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15962, end: 15963 } + }, + loc: { start: 15957, end: 15963 } + }, + statements: [ + { + kind: 'statement_assign', + path: { + kind: 'var', + name: 'q', + loc: { start: 15900, end: 15901 } + }, + expression: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '-', + left: { + kind: 'static_call', + function: { + kind: 'id', + text: 'divc', + loc: { start: 15905, end: 15909 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'num', + loc: { start: 15910, end: 15913 } + }, + { + kind: 'var', + name: 'x', + loc: { start: 15915, end: 15916 } + } + ], + loc: { start: 15905, end: 15917 } + }, + right: { + kind: 'var', + name: 'x', + loc: { start: 15920, end: 15921 } + }, + loc: { start: 15905, end: 15921 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15925, end: 15926 } + }, + loc: { start: 15904, end: 15926 } + }, + loc: { start: 15900, end: 15927 } + }, + { + kind: 'statement_augmentedassign', + op: '+=', + path: { + kind: 'var', + name: 'x', + loc: { start: 15936, end: 15937 } + }, + expression: { + kind: 'var', + name: 'q', + loc: { start: 15941, end: 15942 } + }, + loc: { start: 15936, end: 15943 } + } + ], + loc: { start: 15887, end: 15965 } + }, + { + kind: 'statement_return', + expression: { + kind: 'var', + name: 'x', + loc: { start: 15978, end: 15979 } + }, + loc: { start: 15971, end: 15980 } + } + ] + }, + loc: { start: 15694, end: 15982 } + } + ] + }, + 'min' => { + kind: 'tact', + path: 'std/internal/math.tact', + code: '// Prepare random\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Randomizes the pseudorandom number generator with the specified unsigned 256-bit `Int` `x` by mixing it with the current seed. The new seed is the unsigned 256-bit `Int` value of the SHA-256 hash of concatenated old seed and `x` in their 32-byte strings big-endian representation.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativeRandomize(42); // now, random numbers are less predictable\n' + + "/// let idk: Int = randomInt(); // ???, it's random,\n" + + '/// // but the seed was adjusted deterministically!\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify a negative value of `x`.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomize\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun nativeRandomize(x: Int) { ADDRAND }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Randomizes the random number generator with the logical time of the current transaction. Equivalent to calling `nativeRandomize(curLt())`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativeRandomizeLt(); // now, random numbers are unpredictable for users,\n' + + '/// // but still may be affected by validators or collators\n' + + '/// // as they determine the seed of the current block.\n' + + "/// let idk: Int = randomInt(); // ???, it's random!\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomizelt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomize\n' + + '/// * https://docs.tact-lang.org/ref/core-contextstate#curlt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + 'asm fun nativeRandomizeLt() { LTIME ADDRAND }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Prepares a random number generator by using `nativeRandomizeLt()`. Automatically called by `randomInt()` and `random()` functions.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativePrepareRandom(); // prepare the RNG\n' + + '/// // ... do your random things ...\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativepreparerandom\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomizelt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '/// * https://docs.tact-lang.org/ref/core-random#random\n' + + '///\n' + + '@name(__tact_prepare_random)\n' + + 'native nativePrepareRandom();\n' + + '\n' + + '// Random\n' + + '\n' + + '// Generates a new pseudo-random unsigned 256-bit integer x.\n' + + '// The algorithm is as follows: if r is the old value of the random seed,\n' + + '// considered as a 32-byte array (by constructing the big-endian representation\n' + + '// of an unsigned 256-bit integer), then its sha512(r) is computed;\n' + + "// the first 32 bytes of this hash are stored as the new value r' of the random seed,\n" + + '// and the remaining 32 bytes are returned as the next random value x.\n' + + 'asm fun nativeRandom(): Int { RANDU256 }\n' + + '\n' + + '// Generates a new pseudo-random integer z in the range 0..range−1\n' + + '// (or range..−1, if range < 0).\n' + + '// More precisely, an unsigned random value x is generated as in `nativeRandom`;\n' + + '// then z := x * range / 2^256 is computed.\n' + + 'asm fun nativeRandomInterval(max: Int): Int { RAND }\n' + + '\n' + + '/// Generates and returns a new pseudo-random unsigned 256-bit `Int` value `x`.\n' + + '///\n' + + '/// The algorithm works as follows: first, the `sha512(r)` is computed. There, `r` is an old\n' + + '/// value of the random seed, which is taken as a 32-byte array constructed from the big-endian\n' + + '/// representation of an unsigned 256-bit `Int`. The first 32 bytes of this hash are stored as the new\n' + + "/// value `r'` of the random seed, and the remaining 32 bytes are returned as the next random value `x`.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + "/// let allYourRandomBelongToUs: Int = randomInt(); // ???, it's random :)\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + 'inline fun randomInt(): Int {\n' + + ' nativePrepareRandom();\n' + + ' return nativeRandom();\n' + + '}\n' + + '\n' + + '/// Generates and returns a new pseudo-random unsigned `Int` value `x` in the provided semi-closed\n' + + '/// interval: `min` ≤ `x` < `max`, or `min` ≥ `x` > `max` if both `min` and `max` are negative.\n' + + '///\n' + + '/// Note that the `max` value is never included in the interval.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// random(42, 43); // 42, always\n' + + '/// random(0, 42); // 0-41, but never 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-random#random\n' + + '///\n' + + 'inline fun random(min: Int, max: Int): Int {\n' + + ' nativePrepareRandom();\n' + + ' return min + nativeRandomInterval(max - min);\n' + + '}\n' + + '\n' + + '// Math\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the minimum of two `Int` values `x` and `y`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// min(1, 2); // 1\n' + + '/// min(2, 2); // 2\n' + + '/// min(007, 3); // 3\n' + + '/// min(0x45, 3_0_0); // 69, nice\n' + + '/// // ↑ ↑\n' + + '/// // 69 300\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#min\n' + + '///\n' + + 'asm fun min(x: Int, y: Int): Int { MIN }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the maximum of two `Int` values `x` and `y`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// max(1, 2); // 2\n' + + '/// max(2, 2); // 2\n' + + '/// max(007, 3); // 7\n' + + '/// max(0x45, 3_0_0); // 300\n' + + '/// // ↑ ↑\n' + + '/// // 69 300\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#max\n' + + '///\n' + + 'asm fun max(x: Int, y: Int): Int { MAX }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the absolute value of the `Int` value `x`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// abs(42); // 42\n' + + '/// abs(-42); // 42\n' + + '/// abs(-(-(-42))); // 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#abs\n' + + '///\n' + + 'asm fun abs(x: Int): Int { ABS }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the logarithm of a number `num` > 0 to the base `base` ≥ 1. Results are rounded down.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// log(1000, 10); // 3, as 10^3 is 1000\n' + + '/// // ↑ ↑ ↑ ↑\n' + + '/// // num base base num\n' + + '///\n' + + '/// log(1001, 10); // 3\n' + + '/// log(999, 10); // 2\n' + + '/// try {\n' + + '/// log(-1000, 10); // exit code 5 because of the non-positive num\n' + + '/// }\n' + + '/// log(1024, 2); // 10\n' + + '/// try {\n' + + '/// log(1024, -2); // exit code 5 because the base is less than 1\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `num` value is non-positive\n' + + '/// or the given `base` value is less than 1.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log2\n' + + '///\n' + + '@name(__tact_log)\n' + + 'native log(num: Int, base: Int): Int;\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Similar to `log()`, but sets the `base` to 2.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// log2(1024); // 10, as 2^10 is 1024\n' + + '/// // ↑ ↑ ↑\n' + + '/// // num base₂ num\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `num` value is non-positive.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log2\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log.\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes/#5\n' + + '///\n' + + 'asm fun log2(num: Int): Int { DUP 5 THROWIFNOT UBITSIZE DEC }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the exponentiation involving two numbers: the `base` and the exponent (or _power_) `exp`.\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Example {\n' + + '/// // Persistent state variables\n' + + '/// p23: Int = pow(2, 3); // raises 2 to the 3rd power, which is 8\n' + + '/// one: Int = pow(5, 0); // raises 5 to the power 0, which always produces 1\n' + + '/// // works at compile-time!\n' + + '///\n' + + '/// // Internal message receiver\n' + + '/// receive() {\n' + + '/// pow(self.p23, self.one + 1); // 64, works at run-time too!\n' + + '/// try {\n' + + '/// pow(0, -1); // exit code 5: Integer out of expected range\n' + + '/// }\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `exp` value is negative.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow2\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes/#5\n' + + '///\n' + + 'inline fun pow(base: Int, exp: Int): Int {\n' + + ' throwUnless(5, exp >= 0);\n' + + ' let result = 1;\n' + + ' repeat (exp) {\n' + + ' result *= base;\n' + + ' }\n' + + ' return result;\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Similar to `pow()`, but sets the `base` to 2.\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Example {\n' + + '/// // Persistent state variables\n' + + '/// p23: Int = pow2(3); // raises 2 to the 3rd power, which is 8\n' + + '/// one: Int = pow2(0); // raises 2 to the power 0, which always produces 1\n' + + '/// // works at compile-time!\n' + + '///\n' + + '/// // Internal message receiver, which accepts message ExtMsg\n' + + '/// receive() {\n' + + '/// pow2(self.one + 1); // 4, works at run-time too!\n' + + '/// try {\n' + + '/// pow(-1); // exit code 5: Integer out of expected range\n' + + '/// }\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify a negative value of `exp`.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow2\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun pow2(exp: Int): Int { POW2 }\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Computes and returns the sign of the `Int` value `x`. Produces 1 if the `x` is positive, -1 if the `x` is negative, and 0 if the `x` is 0.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// '... 5983 more characters, + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomize', + loc: { start: 965, end: 980 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { kind: 'id', text: 'x', loc: { start: 981, end: 982 } }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 984, end: 987 } + }, + loc: { start: 984, end: 987 } + }, + loc: { start: 981, end: 987 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ADDRAND' ] + }, + loc: { start: 957, end: 1000 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomizeLt', + loc: { start: 1822, end: 1839 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LTIME ADDRAND' ] + }, + loc: { start: 1814, end: 1859 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 2466, end: 2485 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_prepare_random', + loc: { start: 2436, end: 2457 } + } + }, + loc: { start: 2430, end: 2488 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandom', + loc: { start: 2949, end: 2961 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2965, end: 2968 } + }, + loc: { start: 2965, end: 2968 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RANDU256' ] + }, + loc: { start: 2941, end: 2981 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomInterval', + loc: { start: 3216, end: 3236 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3248, end: 3251 } + }, + loc: { start: 3248, end: 3251 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'max', + loc: { start: 3237, end: 3240 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3242, end: 3245 } + }, + loc: { start: 3242, end: 3245 } + }, + loc: { start: 3237, end: 3245 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RAND' ] + }, + loc: { start: 3208, end: 3260 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'randomInt', + loc: { start: 3953, end: 3962 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3966, end: 3969 } + }, + loc: { start: 3966, end: 3969 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 3976, end: 3995 } + }, + typeArgs: [], + args: [], + loc: { start: 3976, end: 3997 } + }, + loc: { start: 3976, end: 3998 } + }, + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativeRandom', + loc: { start: 4010, end: 4022 } + }, + typeArgs: [], + args: [], + loc: { start: 4010, end: 4024 } + }, + loc: { start: 4003, end: 4025 } + } + ] + }, + loc: { start: 3942, end: 4027 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'random', + loc: { start: 4505, end: 4511 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4533, end: 4536 } + }, + loc: { start: 4533, end: 4536 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'min', + loc: { start: 4512, end: 4515 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4517, end: 4520 } + }, + loc: { start: 4517, end: 4520 } + }, + loc: { start: 4512, end: 4520 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'max', + loc: { start: 4522, end: 4525 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4527, end: 4530 } + }, + loc: { start: 4527, end: 4530 } + }, + loc: { start: 4522, end: 4530 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 4543, end: 4562 } + }, + typeArgs: [], + args: [], + loc: { start: 4543, end: 4564 } + }, + loc: { start: 4543, end: 4565 } + }, + { + kind: 'statement_return', + expression: { + kind: 'op_binary', + op: '+', + left: { + kind: 'var', + name: 'min', + loc: { start: 4577, end: 4580 } + }, + right: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativeRandomInterval', + loc: { start: 4583, end: 4603 } + }, + typeArgs: [], + args: [ + { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'max', + loc: { start: 4604, end: 4607 } + }, + right: { + kind: 'var', + name: 'min', + loc: { start: 4610, end: 4613 } + }, + loc: { start: 4604, end: 4613 } + } + ], + loc: { start: 4583, end: 4614 } + }, + loc: { start: 4577, end: 4614 } + }, + loc: { start: 4570, end: 4615 } + } + ] + }, + loc: { start: 4494, end: 4617 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'min', loc: { start: 5017, end: 5020 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5038, end: 5041 } + }, + loc: { start: 5038, end: 5041 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5021, end: 5022 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5024, end: 5027 } + }, + loc: { start: 5024, end: 5027 } + }, + loc: { start: 5021, end: 5027 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 5029, end: 5030 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5032, end: 5035 } + }, + loc: { start: 5032, end: 5035 } + }, + loc: { start: 5029, end: 5035 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MIN' ] + }, + loc: { start: 5009, end: 5049 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'max', loc: { start: 5435, end: 5438 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5456, end: 5459 } + }, + loc: { start: 5456, end: 5459 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5439, end: 5440 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5442, end: 5445 } + }, + loc: { start: 5442, end: 5445 } + }, + loc: { start: 5439, end: 5445 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 5447, end: 5448 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5450, end: 5453 } + }, + loc: { start: 5450, end: 5453 } + }, + loc: { start: 5447, end: 5453 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MAX' ] + }, + loc: { start: 5427, end: 5467 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'abs', loc: { start: 5773, end: 5776 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5786, end: 5789 } + }, + loc: { start: 5786, end: 5789 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5777, end: 5778 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5780, end: 5783 } + }, + loc: { start: 5780, end: 5783 } + }, + loc: { start: 5777, end: 5783 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ABS' ] + }, + loc: { start: 5765, end: 5797 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'log', loc: { start: 6721, end: 6724 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6747, end: 6750 } + }, + loc: { start: 6747, end: 6750 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 6725, end: 6728 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6730, end: 6733 } + }, + loc: { start: 6730, end: 6733 } + }, + loc: { start: 6725, end: 6733 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'base', + loc: { start: 6735, end: 6739 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6741, end: 6744 } + }, + loc: { start: 6741, end: 6744 } + }, + loc: { start: 6735, end: 6744 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_log', + loc: { start: 6702, end: 6712 } + } + }, + loc: { start: 6696, end: 6751 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'log2', loc: { start: 7341, end: 7345 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7357, end: 7360 } + }, + loc: { start: 7357, end: 7360 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 7346, end: 7349 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7351, end: 7354 } + }, + loc: { start: 7351, end: 7354 } + }, + loc: { start: 7346, end: 7354 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DUP 5 THROWIFNOT UBITSIZE DEC' ] + }, + loc: { start: 7333, end: 7394 } + }, + { + kind: 'function', + inline: true, + name: { kind: 'id', text: 'pow', loc: { start: 8510, end: 8513 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8536, end: 8539 } + }, + loc: { start: 8536, end: 8539 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'base', + loc: { start: 8514, end: 8518 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8520, end: 8523 } + }, + loc: { start: 8520, end: 8523 } + }, + loc: { start: 8514, end: 8523 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'exp', + loc: { start: 8525, end: 8528 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8530, end: 8533 } + }, + loc: { start: 8530, end: 8533 } + }, + loc: { start: 8525, end: 8533 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throwUnless', + loc: { start: 8546, end: 8557 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 5n, + loc: { start: 8558, end: 8559 } + }, + { + kind: 'op_binary', + op: '>=', + left: { + kind: 'var', + name: 'exp', + loc: { start: 8561, end: 8564 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 8568, end: 8569 } + }, + loc: { start: 8561, end: 8569 } + } + ], + loc: { start: 8546, end: 8570 } + }, + loc: { start: 8546, end: 8571 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'result', + loc: { start: 8580, end: 8586 } + }, + type: undefined, + expression: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 8589, end: 8590 } + }, + loc: { start: 8576, end: 8591 } + }, + { + kind: 'statement_repeat', + iterations: { + kind: 'var', + name: 'exp', + loc: { start: 8604, end: 8607 } + }, + statements: [ + { + kind: 'statement_augmentedassign', + op: '*=', + path: { + kind: 'var', + name: 'result', + loc: { start: 8619, end: 8625 } + }, + expression: { + kind: 'var', + name: 'base', + loc: { start: 8629, end: 8633 } + }, + loc: { start: 8619, end: 8634 } + } + ], + loc: { start: 8596, end: 8640 } + }, + { + kind: 'statement_return', + expression: { + kind: 'var', + name: 'result', + loc: { start: 8652, end: 8658 } + }, + loc: { start: 8645, end: 8659 } + } + ] + }, + loc: { start: 8499, end: 8661 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'pow2', loc: { start: 9733, end: 9737 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9749, end: 9752 } + }, + loc: { start: 9749, end: 9752 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'exp', + loc: { start: 9738, end: 9741 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9743, end: 9746 } + }, + loc: { start: 9743, end: 9746 } + }, + loc: { start: 9738, end: 9746 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'POW2' ] + }, + loc: { start: 9725, end: 9761 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sign', + loc: { start: 10233, end: 10237 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10247, end: 10250 } + }, + loc: { start: 10247, end: 10250 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 10238, end: 10239 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10241, end: 10244 } + }, + loc: { start: 10241, end: 10244 } + }, + loc: { start: 10238, end: 10244 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SGN' ] + }, + loc: { start: 10225, end: 10258 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'divc', + loc: { start: 10814, end: 10818 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10836, end: 10839 } + }, + loc: { start: 10836, end: 10839 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 10819, end: 10820 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10822, end: 10825 } + }, + loc: { start: 10822, end: 10825 } + }, + loc: { start: 10819, end: 10825 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 10827, end: 10828 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10830, end: 10833 } + }, + loc: { start: 10830, end: 10833 } + }, + loc: { start: 10827, end: 10833 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DIVC' ] + }, + loc: { start: 10806, end: 10848 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'muldivc', + loc: { start: 11615, end: 11622 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11648, end: 11651 } + }, + loc: { start: 11648, end: 11651 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 11623, end: 11624 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11626, end: 11629 } + }, + loc: { start: 11626, end: 11629 } + }, + loc: { start: 11623, end: 11629 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 11631, end: 11632 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11634, end: 11637 } + }, + loc: { start: 11634, end: 11637 } + }, + loc: { start: 11631, end: 11637 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 11639, end: 11640 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11642, end: 11645 } + }, + loc: { start: 11642, end: 11645 } + }, + loc: { start: 11639, end: 11645 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULDIVC' ] + }, + loc: { start: 11607, end: 11663 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRight', + loc: { start: 12751, end: 12764 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12790, end: 12793 } + }, + loc: { start: 12790, end: 12793 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 12765, end: 12766 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12768, end: 12771 } + }, + loc: { start: 12768, end: 12771 } + }, + loc: { start: 12765, end: 12771 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 12773, end: 12774 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12776, end: 12779 } + }, + loc: { start: 12776, end: 12779 } + }, + loc: { start: 12773, end: 12779 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 12781, end: 12782 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12784, end: 12787 } + }, + loc: { start: 12784, end: 12787 } + }, + loc: { start: 12781, end: 12787 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFT' ] + }, + loc: { start: 12743, end: 12807 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRightRound', + loc: { start: 13862, end: 13880 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13906, end: 13909 } + }, + loc: { start: 13906, end: 13909 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 13881, end: 13882 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13884, end: 13887 } + }, + loc: { start: 13884, end: 13887 } + }, + loc: { start: 13881, end: 13887 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 13889, end: 13890 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13892, end: 13895 } + }, + loc: { start: 13892, end: 13895 } + }, + loc: { start: 13889, end: 13895 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 13897, end: 13898 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13900, end: 13903 } + }, + loc: { start: 13900, end: 13903 } + }, + loc: { start: 13897, end: 13903 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFTR' ] + }, + loc: { start: 13854, end: 13924 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRightCeil', + loc: { start: 14875, end: 14892 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14918, end: 14921 } + }, + loc: { start: 14918, end: 14921 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 14893, end: 14894 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14896, end: 14899 } + }, + loc: { start: 14896, end: 14899 } + }, + loc: { start: 14893, end: 14899 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 14901, end: 14902 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14904, end: 14907 } + }, + loc: { start: 14904, end: 14907 } + }, + loc: { start: 14901, end: 14907 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 14909, end: 14910 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14912, end: 14915 } + }, + loc: { start: 14912, end: 14915 } + }, + loc: { start: 14909, end: 14915 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFTC' ] + }, + loc: { start: 14867, end: 14936 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sqrt', + loc: { start: 15698, end: 15702 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15714, end: 15717 } + }, + loc: { start: 15714, end: 15717 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 15703, end: 15706 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15708, end: 15711 } + }, + loc: { start: 15708, end: 15711 } + }, + loc: { start: 15703, end: 15711 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'num', + loc: { start: 15728, end: 15731 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15735, end: 15736 } + }, + loc: { start: 15728, end: 15736 } + }, + trueStatements: [ + { + kind: 'statement_return', + expression: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15755, end: 15756 } + }, + loc: { start: 15748, end: 15757 } + } + ], + falseStatements: undefined, + loc: { start: 15724, end: 15763 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 's', + loc: { start: 15773, end: 15774 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15776, end: 15779 } + }, + loc: { start: 15776, end: 15779 } + }, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'log2', + loc: { start: 15782, end: 15786 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'num', + loc: { start: 15787, end: 15790 } + } + ], + loc: { start: 15782, end: 15791 } + }, + loc: { start: 15769, end: 15792 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'x', + loc: { start: 15801, end: 15802 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15804, end: 15807 } + }, + loc: { start: 15804, end: 15807 } + }, + expression: { + kind: 'conditional', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 's', + loc: { start: 15811, end: 15812 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15816, end: 15817 } + }, + loc: { start: 15811, end: 15817 } + }, + thenBranch: { + kind: 'op_binary', + op: '+', + left: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'num', + loc: { start: 15821, end: 15824 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15827, end: 15828 } + }, + loc: { start: 15821, end: 15828 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15832, end: 15833 } + }, + loc: { start: 15820, end: 15833 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15836, end: 15837 } + }, + loc: { start: 15820, end: 15837 } + }, + elseBranch: { + kind: 'op_binary', + op: '<<', + left: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15840, end: 15841 } + }, + right: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '+', + left: { + kind: 'var', + name: 's', + loc: { start: 15847, end: 15848 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15851, end: 15852 } + }, + loc: { start: 15847, end: 15852 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15856, end: 15857 } + }, + loc: { start: 15846, end: 15857 } + }, + loc: { start: 15840, end: 15858 } + }, + loc: { start: 15811, end: 15858 } + }, + loc: { start: 15797, end: 15860 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'q', + loc: { start: 15870, end: 15871 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15873, end: 15876 } + }, + loc: { start: 15873, end: 15876 } + }, + expression: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15879, end: 15880 } + }, + loc: { start: 15866, end: 15881 } + }, + { + kind: 'statement_until', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'q', + loc: { start: 15957, end: 15958 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15962, end: 15963 } + }, + loc: { start: 15957, end: 15963 } + }, + statements: [ + { + kind: 'statement_assign', + path: { + kind: 'var', + name: 'q', + loc: { start: 15900, end: 15901 } + }, + expression: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '-', + left: { + kind: 'static_call', + function: { + kind: 'id', + text: 'divc', + loc: { start: 15905, end: 15909 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'num', + loc: { start: 15910, end: 15913 } + }, + { + kind: 'var', + name: 'x', + loc: { start: 15915, end: 15916 } + } + ], + loc: { start: 15905, end: 15917 } + }, + right: { + kind: 'var', + name: 'x', + loc: { start: 15920, end: 15921 } + }, + loc: { start: 15905, end: 15921 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15925, end: 15926 } + }, + loc: { start: 15904, end: 15926 } + }, + loc: { start: 15900, end: 15927 } + }, + { + kind: 'statement_augmentedassign', + op: '+=', + path: { + kind: 'var', + name: 'x', + loc: { start: 15936, end: 15937 } + }, + expression: { + kind: 'var', + name: 'q', + loc: { start: 15941, end: 15942 } + }, + loc: { start: 15936, end: 15943 } + } + ], + loc: { start: 15887, end: 15965 } + }, + { + kind: 'statement_return', + expression: { + kind: 'var', + name: 'x', + loc: { start: 15978, end: 15979 } + }, + loc: { start: 15971, end: 15980 } + } + ] + }, + loc: { start: 15694, end: 15982 } + } + ] + }, + 'max' => { + kind: 'tact', + path: 'std/internal/math.tact', + code: '// Prepare random\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Randomizes the pseudorandom number generator with the specified unsigned 256-bit `Int` `x` by mixing it with the current seed. The new seed is the unsigned 256-bit `Int` value of the SHA-256 hash of concatenated old seed and `x` in their 32-byte strings big-endian representation.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativeRandomize(42); // now, random numbers are less predictable\n' + + "/// let idk: Int = randomInt(); // ???, it's random,\n" + + '/// // but the seed was adjusted deterministically!\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify a negative value of `x`.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomize\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun nativeRandomize(x: Int) { ADDRAND }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Randomizes the random number generator with the logical time of the current transaction. Equivalent to calling `nativeRandomize(curLt())`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativeRandomizeLt(); // now, random numbers are unpredictable for users,\n' + + '/// // but still may be affected by validators or collators\n' + + '/// // as they determine the seed of the current block.\n' + + "/// let idk: Int = randomInt(); // ???, it's random!\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomizelt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomize\n' + + '/// * https://docs.tact-lang.org/ref/core-contextstate#curlt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + 'asm fun nativeRandomizeLt() { LTIME ADDRAND }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Prepares a random number generator by using `nativeRandomizeLt()`. Automatically called by `randomInt()` and `random()` functions.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativePrepareRandom(); // prepare the RNG\n' + + '/// // ... do your random things ...\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativepreparerandom\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomizelt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '/// * https://docs.tact-lang.org/ref/core-random#random\n' + + '///\n' + + '@name(__tact_prepare_random)\n' + + 'native nativePrepareRandom();\n' + + '\n' + + '// Random\n' + + '\n' + + '// Generates a new pseudo-random unsigned 256-bit integer x.\n' + + '// The algorithm is as follows: if r is the old value of the random seed,\n' + + '// considered as a 32-byte array (by constructing the big-endian representation\n' + + '// of an unsigned 256-bit integer), then its sha512(r) is computed;\n' + + "// the first 32 bytes of this hash are stored as the new value r' of the random seed,\n" + + '// and the remaining 32 bytes are returned as the next random value x.\n' + + 'asm fun nativeRandom(): Int { RANDU256 }\n' + + '\n' + + '// Generates a new pseudo-random integer z in the range 0..range−1\n' + + '// (or range..−1, if range < 0).\n' + + '// More precisely, an unsigned random value x is generated as in `nativeRandom`;\n' + + '// then z := x * range / 2^256 is computed.\n' + + 'asm fun nativeRandomInterval(max: Int): Int { RAND }\n' + + '\n' + + '/// Generates and returns a new pseudo-random unsigned 256-bit `Int` value `x`.\n' + + '///\n' + + '/// The algorithm works as follows: first, the `sha512(r)` is computed. There, `r` is an old\n' + + '/// value of the random seed, which is taken as a 32-byte array constructed from the big-endian\n' + + '/// representation of an unsigned 256-bit `Int`. The first 32 bytes of this hash are stored as the new\n' + + "/// value `r'` of the random seed, and the remaining 32 bytes are returned as the next random value `x`.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + "/// let allYourRandomBelongToUs: Int = randomInt(); // ???, it's random :)\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + 'inline fun randomInt(): Int {\n' + + ' nativePrepareRandom();\n' + + ' return nativeRandom();\n' + + '}\n' + + '\n' + + '/// Generates and returns a new pseudo-random unsigned `Int` value `x` in the provided semi-closed\n' + + '/// interval: `min` ≤ `x` < `max`, or `min` ≥ `x` > `max` if both `min` and `max` are negative.\n' + + '///\n' + + '/// Note that the `max` value is never included in the interval.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// random(42, 43); // 42, always\n' + + '/// random(0, 42); // 0-41, but never 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-random#random\n' + + '///\n' + + 'inline fun random(min: Int, max: Int): Int {\n' + + ' nativePrepareRandom();\n' + + ' return min + nativeRandomInterval(max - min);\n' + + '}\n' + + '\n' + + '// Math\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the minimum of two `Int` values `x` and `y`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// min(1, 2); // 1\n' + + '/// min(2, 2); // 2\n' + + '/// min(007, 3); // 3\n' + + '/// min(0x45, 3_0_0); // 69, nice\n' + + '/// // ↑ ↑\n' + + '/// // 69 300\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#min\n' + + '///\n' + + 'asm fun min(x: Int, y: Int): Int { MIN }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the maximum of two `Int` values `x` and `y`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// max(1, 2); // 2\n' + + '/// max(2, 2); // 2\n' + + '/// max(007, 3); // 7\n' + + '/// max(0x45, 3_0_0); // 300\n' + + '/// // ↑ ↑\n' + + '/// // 69 300\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#max\n' + + '///\n' + + 'asm fun max(x: Int, y: Int): Int { MAX }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the absolute value of the `Int` value `x`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// abs(42); // 42\n' + + '/// abs(-42); // 42\n' + + '/// abs(-(-(-42))); // 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#abs\n' + + '///\n' + + 'asm fun abs(x: Int): Int { ABS }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the logarithm of a number `num` > 0 to the base `base` ≥ 1. Results are rounded down.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// log(1000, 10); // 3, as 10^3 is 1000\n' + + '/// // ↑ ↑ ↑ ↑\n' + + '/// // num base base num\n' + + '///\n' + + '/// log(1001, 10); // 3\n' + + '/// log(999, 10); // 2\n' + + '/// try {\n' + + '/// log(-1000, 10); // exit code 5 because of the non-positive num\n' + + '/// }\n' + + '/// log(1024, 2); // 10\n' + + '/// try {\n' + + '/// log(1024, -2); // exit code 5 because the base is less than 1\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `num` value is non-positive\n' + + '/// or the given `base` value is less than 1.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log2\n' + + '///\n' + + '@name(__tact_log)\n' + + 'native log(num: Int, base: Int): Int;\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Similar to `log()`, but sets the `base` to 2.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// log2(1024); // 10, as 2^10 is 1024\n' + + '/// // ↑ ↑ ↑\n' + + '/// // num base₂ num\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `num` value is non-positive.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log2\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log.\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes/#5\n' + + '///\n' + + 'asm fun log2(num: Int): Int { DUP 5 THROWIFNOT UBITSIZE DEC }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the exponentiation involving two numbers: the `base` and the exponent (or _power_) `exp`.\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Example {\n' + + '/// // Persistent state variables\n' + + '/// p23: Int = pow(2, 3); // raises 2 to the 3rd power, which is 8\n' + + '/// one: Int = pow(5, 0); // raises 5 to the power 0, which always produces 1\n' + + '/// // works at compile-time!\n' + + '///\n' + + '/// // Internal message receiver\n' + + '/// receive() {\n' + + '/// pow(self.p23, self.one + 1); // 64, works at run-time too!\n' + + '/// try {\n' + + '/// pow(0, -1); // exit code 5: Integer out of expected range\n' + + '/// }\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `exp` value is negative.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow2\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes/#5\n' + + '///\n' + + 'inline fun pow(base: Int, exp: Int): Int {\n' + + ' throwUnless(5, exp >= 0);\n' + + ' let result = 1;\n' + + ' repeat (exp) {\n' + + ' result *= base;\n' + + ' }\n' + + ' return result;\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Similar to `pow()`, but sets the `base` to 2.\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Example {\n' + + '/// // Persistent state variables\n' + + '/// p23: Int = pow2(3); // raises 2 to the 3rd power, which is 8\n' + + '/// one: Int = pow2(0); // raises 2 to the power 0, which always produces 1\n' + + '/// // works at compile-time!\n' + + '///\n' + + '/// // Internal message receiver, which accepts message ExtMsg\n' + + '/// receive() {\n' + + '/// pow2(self.one + 1); // 4, works at run-time too!\n' + + '/// try {\n' + + '/// pow(-1); // exit code 5: Integer out of expected range\n' + + '/// }\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify a negative value of `exp`.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow2\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun pow2(exp: Int): Int { POW2 }\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Computes and returns the sign of the `Int` value `x`. Produces 1 if the `x` is positive, -1 if the `x` is negative, and 0 if the `x` is 0.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// '... 5983 more characters, + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomize', + loc: { start: 965, end: 980 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { kind: 'id', text: 'x', loc: { start: 981, end: 982 } }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 984, end: 987 } + }, + loc: { start: 984, end: 987 } + }, + loc: { start: 981, end: 987 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ADDRAND' ] + }, + loc: { start: 957, end: 1000 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomizeLt', + loc: { start: 1822, end: 1839 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LTIME ADDRAND' ] + }, + loc: { start: 1814, end: 1859 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 2466, end: 2485 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_prepare_random', + loc: { start: 2436, end: 2457 } + } + }, + loc: { start: 2430, end: 2488 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandom', + loc: { start: 2949, end: 2961 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2965, end: 2968 } + }, + loc: { start: 2965, end: 2968 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RANDU256' ] + }, + loc: { start: 2941, end: 2981 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomInterval', + loc: { start: 3216, end: 3236 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3248, end: 3251 } + }, + loc: { start: 3248, end: 3251 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'max', + loc: { start: 3237, end: 3240 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3242, end: 3245 } + }, + loc: { start: 3242, end: 3245 } + }, + loc: { start: 3237, end: 3245 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RAND' ] + }, + loc: { start: 3208, end: 3260 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'randomInt', + loc: { start: 3953, end: 3962 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3966, end: 3969 } + }, + loc: { start: 3966, end: 3969 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 3976, end: 3995 } + }, + typeArgs: [], + args: [], + loc: { start: 3976, end: 3997 } + }, + loc: { start: 3976, end: 3998 } + }, + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativeRandom', + loc: { start: 4010, end: 4022 } + }, + typeArgs: [], + args: [], + loc: { start: 4010, end: 4024 } + }, + loc: { start: 4003, end: 4025 } + } + ] + }, + loc: { start: 3942, end: 4027 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'random', + loc: { start: 4505, end: 4511 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4533, end: 4536 } + }, + loc: { start: 4533, end: 4536 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'min', + loc: { start: 4512, end: 4515 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4517, end: 4520 } + }, + loc: { start: 4517, end: 4520 } + }, + loc: { start: 4512, end: 4520 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'max', + loc: { start: 4522, end: 4525 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4527, end: 4530 } + }, + loc: { start: 4527, end: 4530 } + }, + loc: { start: 4522, end: 4530 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 4543, end: 4562 } + }, + typeArgs: [], + args: [], + loc: { start: 4543, end: 4564 } + }, + loc: { start: 4543, end: 4565 } + }, + { + kind: 'statement_return', + expression: { + kind: 'op_binary', + op: '+', + left: { + kind: 'var', + name: 'min', + loc: { start: 4577, end: 4580 } + }, + right: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativeRandomInterval', + loc: { start: 4583, end: 4603 } + }, + typeArgs: [], + args: [ + { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'max', + loc: { start: 4604, end: 4607 } + }, + right: { + kind: 'var', + name: 'min', + loc: { start: 4610, end: 4613 } + }, + loc: { start: 4604, end: 4613 } + } + ], + loc: { start: 4583, end: 4614 } + }, + loc: { start: 4577, end: 4614 } + }, + loc: { start: 4570, end: 4615 } + } + ] + }, + loc: { start: 4494, end: 4617 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'min', loc: { start: 5017, end: 5020 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5038, end: 5041 } + }, + loc: { start: 5038, end: 5041 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5021, end: 5022 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5024, end: 5027 } + }, + loc: { start: 5024, end: 5027 } + }, + loc: { start: 5021, end: 5027 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 5029, end: 5030 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5032, end: 5035 } + }, + loc: { start: 5032, end: 5035 } + }, + loc: { start: 5029, end: 5035 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MIN' ] + }, + loc: { start: 5009, end: 5049 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'max', loc: { start: 5435, end: 5438 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5456, end: 5459 } + }, + loc: { start: 5456, end: 5459 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5439, end: 5440 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5442, end: 5445 } + }, + loc: { start: 5442, end: 5445 } + }, + loc: { start: 5439, end: 5445 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 5447, end: 5448 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5450, end: 5453 } + }, + loc: { start: 5450, end: 5453 } + }, + loc: { start: 5447, end: 5453 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MAX' ] + }, + loc: { start: 5427, end: 5467 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'abs', loc: { start: 5773, end: 5776 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5786, end: 5789 } + }, + loc: { start: 5786, end: 5789 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5777, end: 5778 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5780, end: 5783 } + }, + loc: { start: 5780, end: 5783 } + }, + loc: { start: 5777, end: 5783 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ABS' ] + }, + loc: { start: 5765, end: 5797 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'log', loc: { start: 6721, end: 6724 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6747, end: 6750 } + }, + loc: { start: 6747, end: 6750 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 6725, end: 6728 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6730, end: 6733 } + }, + loc: { start: 6730, end: 6733 } + }, + loc: { start: 6725, end: 6733 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'base', + loc: { start: 6735, end: 6739 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6741, end: 6744 } + }, + loc: { start: 6741, end: 6744 } + }, + loc: { start: 6735, end: 6744 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_log', + loc: { start: 6702, end: 6712 } + } + }, + loc: { start: 6696, end: 6751 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'log2', loc: { start: 7341, end: 7345 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7357, end: 7360 } + }, + loc: { start: 7357, end: 7360 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 7346, end: 7349 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7351, end: 7354 } + }, + loc: { start: 7351, end: 7354 } + }, + loc: { start: 7346, end: 7354 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DUP 5 THROWIFNOT UBITSIZE DEC' ] + }, + loc: { start: 7333, end: 7394 } + }, + { + kind: 'function', + inline: true, + name: { kind: 'id', text: 'pow', loc: { start: 8510, end: 8513 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8536, end: 8539 } + }, + loc: { start: 8536, end: 8539 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'base', + loc: { start: 8514, end: 8518 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8520, end: 8523 } + }, + loc: { start: 8520, end: 8523 } + }, + loc: { start: 8514, end: 8523 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'exp', + loc: { start: 8525, end: 8528 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8530, end: 8533 } + }, + loc: { start: 8530, end: 8533 } + }, + loc: { start: 8525, end: 8533 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throwUnless', + loc: { start: 8546, end: 8557 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 5n, + loc: { start: 8558, end: 8559 } + }, + { + kind: 'op_binary', + op: '>=', + left: { + kind: 'var', + name: 'exp', + loc: { start: 8561, end: 8564 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 8568, end: 8569 } + }, + loc: { start: 8561, end: 8569 } + } + ], + loc: { start: 8546, end: 8570 } + }, + loc: { start: 8546, end: 8571 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'result', + loc: { start: 8580, end: 8586 } + }, + type: undefined, + expression: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 8589, end: 8590 } + }, + loc: { start: 8576, end: 8591 } + }, + { + kind: 'statement_repeat', + iterations: { + kind: 'var', + name: 'exp', + loc: { start: 8604, end: 8607 } + }, + statements: [ + { + kind: 'statement_augmentedassign', + op: '*=', + path: { + kind: 'var', + name: 'result', + loc: { start: 8619, end: 8625 } + }, + expression: { + kind: 'var', + name: 'base', + loc: { start: 8629, end: 8633 } + }, + loc: { start: 8619, end: 8634 } + } + ], + loc: { start: 8596, end: 8640 } + }, + { + kind: 'statement_return', + expression: { + kind: 'var', + name: 'result', + loc: { start: 8652, end: 8658 } + }, + loc: { start: 8645, end: 8659 } + } + ] + }, + loc: { start: 8499, end: 8661 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'pow2', loc: { start: 9733, end: 9737 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9749, end: 9752 } + }, + loc: { start: 9749, end: 9752 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'exp', + loc: { start: 9738, end: 9741 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9743, end: 9746 } + }, + loc: { start: 9743, end: 9746 } + }, + loc: { start: 9738, end: 9746 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'POW2' ] + }, + loc: { start: 9725, end: 9761 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sign', + loc: { start: 10233, end: 10237 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10247, end: 10250 } + }, + loc: { start: 10247, end: 10250 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 10238, end: 10239 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10241, end: 10244 } + }, + loc: { start: 10241, end: 10244 } + }, + loc: { start: 10238, end: 10244 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SGN' ] + }, + loc: { start: 10225, end: 10258 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'divc', + loc: { start: 10814, end: 10818 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10836, end: 10839 } + }, + loc: { start: 10836, end: 10839 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 10819, end: 10820 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10822, end: 10825 } + }, + loc: { start: 10822, end: 10825 } + }, + loc: { start: 10819, end: 10825 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 10827, end: 10828 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10830, end: 10833 } + }, + loc: { start: 10830, end: 10833 } + }, + loc: { start: 10827, end: 10833 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DIVC' ] + }, + loc: { start: 10806, end: 10848 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'muldivc', + loc: { start: 11615, end: 11622 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11648, end: 11651 } + }, + loc: { start: 11648, end: 11651 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 11623, end: 11624 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11626, end: 11629 } + }, + loc: { start: 11626, end: 11629 } + }, + loc: { start: 11623, end: 11629 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 11631, end: 11632 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11634, end: 11637 } + }, + loc: { start: 11634, end: 11637 } + }, + loc: { start: 11631, end: 11637 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 11639, end: 11640 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11642, end: 11645 } + }, + loc: { start: 11642, end: 11645 } + }, + loc: { start: 11639, end: 11645 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULDIVC' ] + }, + loc: { start: 11607, end: 11663 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRight', + loc: { start: 12751, end: 12764 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12790, end: 12793 } + }, + loc: { start: 12790, end: 12793 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 12765, end: 12766 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12768, end: 12771 } + }, + loc: { start: 12768, end: 12771 } + }, + loc: { start: 12765, end: 12771 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 12773, end: 12774 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12776, end: 12779 } + }, + loc: { start: 12776, end: 12779 } + }, + loc: { start: 12773, end: 12779 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 12781, end: 12782 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12784, end: 12787 } + }, + loc: { start: 12784, end: 12787 } + }, + loc: { start: 12781, end: 12787 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFT' ] + }, + loc: { start: 12743, end: 12807 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRightRound', + loc: { start: 13862, end: 13880 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13906, end: 13909 } + }, + loc: { start: 13906, end: 13909 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 13881, end: 13882 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13884, end: 13887 } + }, + loc: { start: 13884, end: 13887 } + }, + loc: { start: 13881, end: 13887 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 13889, end: 13890 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13892, end: 13895 } + }, + loc: { start: 13892, end: 13895 } + }, + loc: { start: 13889, end: 13895 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 13897, end: 13898 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13900, end: 13903 } + }, + loc: { start: 13900, end: 13903 } + }, + loc: { start: 13897, end: 13903 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFTR' ] + }, + loc: { start: 13854, end: 13924 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRightCeil', + loc: { start: 14875, end: 14892 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14918, end: 14921 } + }, + loc: { start: 14918, end: 14921 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 14893, end: 14894 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14896, end: 14899 } + }, + loc: { start: 14896, end: 14899 } + }, + loc: { start: 14893, end: 14899 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 14901, end: 14902 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14904, end: 14907 } + }, + loc: { start: 14904, end: 14907 } + }, + loc: { start: 14901, end: 14907 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 14909, end: 14910 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14912, end: 14915 } + }, + loc: { start: 14912, end: 14915 } + }, + loc: { start: 14909, end: 14915 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFTC' ] + }, + loc: { start: 14867, end: 14936 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sqrt', + loc: { start: 15698, end: 15702 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15714, end: 15717 } + }, + loc: { start: 15714, end: 15717 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 15703, end: 15706 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15708, end: 15711 } + }, + loc: { start: 15708, end: 15711 } + }, + loc: { start: 15703, end: 15711 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'num', + loc: { start: 15728, end: 15731 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15735, end: 15736 } + }, + loc: { start: 15728, end: 15736 } + }, + trueStatements: [ + { + kind: 'statement_return', + expression: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15755, end: 15756 } + }, + loc: { start: 15748, end: 15757 } + } + ], + falseStatements: undefined, + loc: { start: 15724, end: 15763 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 's', + loc: { start: 15773, end: 15774 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15776, end: 15779 } + }, + loc: { start: 15776, end: 15779 } + }, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'log2', + loc: { start: 15782, end: 15786 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'num', + loc: { start: 15787, end: 15790 } + } + ], + loc: { start: 15782, end: 15791 } + }, + loc: { start: 15769, end: 15792 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'x', + loc: { start: 15801, end: 15802 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15804, end: 15807 } + }, + loc: { start: 15804, end: 15807 } + }, + expression: { + kind: 'conditional', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 's', + loc: { start: 15811, end: 15812 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15816, end: 15817 } + }, + loc: { start: 15811, end: 15817 } + }, + thenBranch: { + kind: 'op_binary', + op: '+', + left: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'num', + loc: { start: 15821, end: 15824 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15827, end: 15828 } + }, + loc: { start: 15821, end: 15828 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15832, end: 15833 } + }, + loc: { start: 15820, end: 15833 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15836, end: 15837 } + }, + loc: { start: 15820, end: 15837 } + }, + elseBranch: { + kind: 'op_binary', + op: '<<', + left: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15840, end: 15841 } + }, + right: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '+', + left: { + kind: 'var', + name: 's', + loc: { start: 15847, end: 15848 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15851, end: 15852 } + }, + loc: { start: 15847, end: 15852 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15856, end: 15857 } + }, + loc: { start: 15846, end: 15857 } + }, + loc: { start: 15840, end: 15858 } + }, + loc: { start: 15811, end: 15858 } + }, + loc: { start: 15797, end: 15860 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'q', + loc: { start: 15870, end: 15871 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15873, end: 15876 } + }, + loc: { start: 15873, end: 15876 } + }, + expression: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15879, end: 15880 } + }, + loc: { start: 15866, end: 15881 } + }, + { + kind: 'statement_until', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'q', + loc: { start: 15957, end: 15958 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15962, end: 15963 } + }, + loc: { start: 15957, end: 15963 } + }, + statements: [ + { + kind: 'statement_assign', + path: { + kind: 'var', + name: 'q', + loc: { start: 15900, end: 15901 } + }, + expression: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '-', + left: { + kind: 'static_call', + function: { + kind: 'id', + text: 'divc', + loc: { start: 15905, end: 15909 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'num', + loc: { start: 15910, end: 15913 } + }, + { + kind: 'var', + name: 'x', + loc: { start: 15915, end: 15916 } + } + ], + loc: { start: 15905, end: 15917 } + }, + right: { + kind: 'var', + name: 'x', + loc: { start: 15920, end: 15921 } + }, + loc: { start: 15905, end: 15921 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15925, end: 15926 } + }, + loc: { start: 15904, end: 15926 } + }, + loc: { start: 15900, end: 15927 } + }, + { + kind: 'statement_augmentedassign', + op: '+=', + path: { + kind: 'var', + name: 'x', + loc: { start: 15936, end: 15937 } + }, + expression: { + kind: 'var', + name: 'q', + loc: { start: 15941, end: 15942 } + }, + loc: { start: 15936, end: 15943 } + } + ], + loc: { start: 15887, end: 15965 } + }, + { + kind: 'statement_return', + expression: { + kind: 'var', + name: 'x', + loc: { start: 15978, end: 15979 } + }, + loc: { start: 15971, end: 15980 } + } + ] + }, + loc: { start: 15694, end: 15982 } + } + ] + }, + 'abs' => { + kind: 'tact', + path: 'std/internal/math.tact', + code: '// Prepare random\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Randomizes the pseudorandom number generator with the specified unsigned 256-bit `Int` `x` by mixing it with the current seed. The new seed is the unsigned 256-bit `Int` value of the SHA-256 hash of concatenated old seed and `x` in their 32-byte strings big-endian representation.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativeRandomize(42); // now, random numbers are less predictable\n' + + "/// let idk: Int = randomInt(); // ???, it's random,\n" + + '/// // but the seed was adjusted deterministically!\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify a negative value of `x`.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomize\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun nativeRandomize(x: Int) { ADDRAND }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Randomizes the random number generator with the logical time of the current transaction. Equivalent to calling `nativeRandomize(curLt())`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativeRandomizeLt(); // now, random numbers are unpredictable for users,\n' + + '/// // but still may be affected by validators or collators\n' + + '/// // as they determine the seed of the current block.\n' + + "/// let idk: Int = randomInt(); // ???, it's random!\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomizelt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomize\n' + + '/// * https://docs.tact-lang.org/ref/core-contextstate#curlt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + 'asm fun nativeRandomizeLt() { LTIME ADDRAND }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Prepares a random number generator by using `nativeRandomizeLt()`. Automatically called by `randomInt()` and `random()` functions.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativePrepareRandom(); // prepare the RNG\n' + + '/// // ... do your random things ...\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativepreparerandom\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomizelt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '/// * https://docs.tact-lang.org/ref/core-random#random\n' + + '///\n' + + '@name(__tact_prepare_random)\n' + + 'native nativePrepareRandom();\n' + + '\n' + + '// Random\n' + + '\n' + + '// Generates a new pseudo-random unsigned 256-bit integer x.\n' + + '// The algorithm is as follows: if r is the old value of the random seed,\n' + + '// considered as a 32-byte array (by constructing the big-endian representation\n' + + '// of an unsigned 256-bit integer), then its sha512(r) is computed;\n' + + "// the first 32 bytes of this hash are stored as the new value r' of the random seed,\n" + + '// and the remaining 32 bytes are returned as the next random value x.\n' + + 'asm fun nativeRandom(): Int { RANDU256 }\n' + + '\n' + + '// Generates a new pseudo-random integer z in the range 0..range−1\n' + + '// (or range..−1, if range < 0).\n' + + '// More precisely, an unsigned random value x is generated as in `nativeRandom`;\n' + + '// then z := x * range / 2^256 is computed.\n' + + 'asm fun nativeRandomInterval(max: Int): Int { RAND }\n' + + '\n' + + '/// Generates and returns a new pseudo-random unsigned 256-bit `Int` value `x`.\n' + + '///\n' + + '/// The algorithm works as follows: first, the `sha512(r)` is computed. There, `r` is an old\n' + + '/// value of the random seed, which is taken as a 32-byte array constructed from the big-endian\n' + + '/// representation of an unsigned 256-bit `Int`. The first 32 bytes of this hash are stored as the new\n' + + "/// value `r'` of the random seed, and the remaining 32 bytes are returned as the next random value `x`.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + "/// let allYourRandomBelongToUs: Int = randomInt(); // ???, it's random :)\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + 'inline fun randomInt(): Int {\n' + + ' nativePrepareRandom();\n' + + ' return nativeRandom();\n' + + '}\n' + + '\n' + + '/// Generates and returns a new pseudo-random unsigned `Int` value `x` in the provided semi-closed\n' + + '/// interval: `min` ≤ `x` < `max`, or `min` ≥ `x` > `max` if both `min` and `max` are negative.\n' + + '///\n' + + '/// Note that the `max` value is never included in the interval.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// random(42, 43); // 42, always\n' + + '/// random(0, 42); // 0-41, but never 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-random#random\n' + + '///\n' + + 'inline fun random(min: Int, max: Int): Int {\n' + + ' nativePrepareRandom();\n' + + ' return min + nativeRandomInterval(max - min);\n' + + '}\n' + + '\n' + + '// Math\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the minimum of two `Int` values `x` and `y`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// min(1, 2); // 1\n' + + '/// min(2, 2); // 2\n' + + '/// min(007, 3); // 3\n' + + '/// min(0x45, 3_0_0); // 69, nice\n' + + '/// // ↑ ↑\n' + + '/// // 69 300\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#min\n' + + '///\n' + + 'asm fun min(x: Int, y: Int): Int { MIN }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the maximum of two `Int` values `x` and `y`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// max(1, 2); // 2\n' + + '/// max(2, 2); // 2\n' + + '/// max(007, 3); // 7\n' + + '/// max(0x45, 3_0_0); // 300\n' + + '/// // ↑ ↑\n' + + '/// // 69 300\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#max\n' + + '///\n' + + 'asm fun max(x: Int, y: Int): Int { MAX }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the absolute value of the `Int` value `x`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// abs(42); // 42\n' + + '/// abs(-42); // 42\n' + + '/// abs(-(-(-42))); // 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#abs\n' + + '///\n' + + 'asm fun abs(x: Int): Int { ABS }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the logarithm of a number `num` > 0 to the base `base` ≥ 1. Results are rounded down.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// log(1000, 10); // 3, as 10^3 is 1000\n' + + '/// // ↑ ↑ ↑ ↑\n' + + '/// // num base base num\n' + + '///\n' + + '/// log(1001, 10); // 3\n' + + '/// log(999, 10); // 2\n' + + '/// try {\n' + + '/// log(-1000, 10); // exit code 5 because of the non-positive num\n' + + '/// }\n' + + '/// log(1024, 2); // 10\n' + + '/// try {\n' + + '/// log(1024, -2); // exit code 5 because the base is less than 1\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `num` value is non-positive\n' + + '/// or the given `base` value is less than 1.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log2\n' + + '///\n' + + '@name(__tact_log)\n' + + 'native log(num: Int, base: Int): Int;\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Similar to `log()`, but sets the `base` to 2.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// log2(1024); // 10, as 2^10 is 1024\n' + + '/// // ↑ ↑ ↑\n' + + '/// // num base₂ num\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `num` value is non-positive.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log2\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log.\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes/#5\n' + + '///\n' + + 'asm fun log2(num: Int): Int { DUP 5 THROWIFNOT UBITSIZE DEC }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the exponentiation involving two numbers: the `base` and the exponent (or _power_) `exp`.\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Example {\n' + + '/// // Persistent state variables\n' + + '/// p23: Int = pow(2, 3); // raises 2 to the 3rd power, which is 8\n' + + '/// one: Int = pow(5, 0); // raises 5 to the power 0, which always produces 1\n' + + '/// // works at compile-time!\n' + + '///\n' + + '/// // Internal message receiver\n' + + '/// receive() {\n' + + '/// pow(self.p23, self.one + 1); // 64, works at run-time too!\n' + + '/// try {\n' + + '/// pow(0, -1); // exit code 5: Integer out of expected range\n' + + '/// }\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `exp` value is negative.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow2\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes/#5\n' + + '///\n' + + 'inline fun pow(base: Int, exp: Int): Int {\n' + + ' throwUnless(5, exp >= 0);\n' + + ' let result = 1;\n' + + ' repeat (exp) {\n' + + ' result *= base;\n' + + ' }\n' + + ' return result;\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Similar to `pow()`, but sets the `base` to 2.\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Example {\n' + + '/// // Persistent state variables\n' + + '/// p23: Int = pow2(3); // raises 2 to the 3rd power, which is 8\n' + + '/// one: Int = pow2(0); // raises 2 to the power 0, which always produces 1\n' + + '/// // works at compile-time!\n' + + '///\n' + + '/// // Internal message receiver, which accepts message ExtMsg\n' + + '/// receive() {\n' + + '/// pow2(self.one + 1); // 4, works at run-time too!\n' + + '/// try {\n' + + '/// pow(-1); // exit code 5: Integer out of expected range\n' + + '/// }\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify a negative value of `exp`.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow2\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun pow2(exp: Int): Int { POW2 }\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Computes and returns the sign of the `Int` value `x`. Produces 1 if the `x` is positive, -1 if the `x` is negative, and 0 if the `x` is 0.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// '... 5983 more characters, + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomize', + loc: { start: 965, end: 980 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { kind: 'id', text: 'x', loc: { start: 981, end: 982 } }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 984, end: 987 } + }, + loc: { start: 984, end: 987 } + }, + loc: { start: 981, end: 987 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ADDRAND' ] + }, + loc: { start: 957, end: 1000 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomizeLt', + loc: { start: 1822, end: 1839 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LTIME ADDRAND' ] + }, + loc: { start: 1814, end: 1859 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 2466, end: 2485 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_prepare_random', + loc: { start: 2436, end: 2457 } + } + }, + loc: { start: 2430, end: 2488 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandom', + loc: { start: 2949, end: 2961 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2965, end: 2968 } + }, + loc: { start: 2965, end: 2968 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RANDU256' ] + }, + loc: { start: 2941, end: 2981 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomInterval', + loc: { start: 3216, end: 3236 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3248, end: 3251 } + }, + loc: { start: 3248, end: 3251 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'max', + loc: { start: 3237, end: 3240 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3242, end: 3245 } + }, + loc: { start: 3242, end: 3245 } + }, + loc: { start: 3237, end: 3245 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RAND' ] + }, + loc: { start: 3208, end: 3260 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'randomInt', + loc: { start: 3953, end: 3962 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3966, end: 3969 } + }, + loc: { start: 3966, end: 3969 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 3976, end: 3995 } + }, + typeArgs: [], + args: [], + loc: { start: 3976, end: 3997 } + }, + loc: { start: 3976, end: 3998 } + }, + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativeRandom', + loc: { start: 4010, end: 4022 } + }, + typeArgs: [], + args: [], + loc: { start: 4010, end: 4024 } + }, + loc: { start: 4003, end: 4025 } + } + ] + }, + loc: { start: 3942, end: 4027 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'random', + loc: { start: 4505, end: 4511 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4533, end: 4536 } + }, + loc: { start: 4533, end: 4536 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'min', + loc: { start: 4512, end: 4515 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4517, end: 4520 } + }, + loc: { start: 4517, end: 4520 } + }, + loc: { start: 4512, end: 4520 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'max', + loc: { start: 4522, end: 4525 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4527, end: 4530 } + }, + loc: { start: 4527, end: 4530 } + }, + loc: { start: 4522, end: 4530 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 4543, end: 4562 } + }, + typeArgs: [], + args: [], + loc: { start: 4543, end: 4564 } + }, + loc: { start: 4543, end: 4565 } + }, + { + kind: 'statement_return', + expression: { + kind: 'op_binary', + op: '+', + left: { + kind: 'var', + name: 'min', + loc: { start: 4577, end: 4580 } + }, + right: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativeRandomInterval', + loc: { start: 4583, end: 4603 } + }, + typeArgs: [], + args: [ + { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'max', + loc: { start: 4604, end: 4607 } + }, + right: { + kind: 'var', + name: 'min', + loc: { start: 4610, end: 4613 } + }, + loc: { start: 4604, end: 4613 } + } + ], + loc: { start: 4583, end: 4614 } + }, + loc: { start: 4577, end: 4614 } + }, + loc: { start: 4570, end: 4615 } + } + ] + }, + loc: { start: 4494, end: 4617 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'min', loc: { start: 5017, end: 5020 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5038, end: 5041 } + }, + loc: { start: 5038, end: 5041 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5021, end: 5022 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5024, end: 5027 } + }, + loc: { start: 5024, end: 5027 } + }, + loc: { start: 5021, end: 5027 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 5029, end: 5030 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5032, end: 5035 } + }, + loc: { start: 5032, end: 5035 } + }, + loc: { start: 5029, end: 5035 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MIN' ] + }, + loc: { start: 5009, end: 5049 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'max', loc: { start: 5435, end: 5438 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5456, end: 5459 } + }, + loc: { start: 5456, end: 5459 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5439, end: 5440 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5442, end: 5445 } + }, + loc: { start: 5442, end: 5445 } + }, + loc: { start: 5439, end: 5445 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 5447, end: 5448 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5450, end: 5453 } + }, + loc: { start: 5450, end: 5453 } + }, + loc: { start: 5447, end: 5453 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MAX' ] + }, + loc: { start: 5427, end: 5467 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'abs', loc: { start: 5773, end: 5776 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5786, end: 5789 } + }, + loc: { start: 5786, end: 5789 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5777, end: 5778 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5780, end: 5783 } + }, + loc: { start: 5780, end: 5783 } + }, + loc: { start: 5777, end: 5783 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ABS' ] + }, + loc: { start: 5765, end: 5797 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'log', loc: { start: 6721, end: 6724 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6747, end: 6750 } + }, + loc: { start: 6747, end: 6750 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 6725, end: 6728 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6730, end: 6733 } + }, + loc: { start: 6730, end: 6733 } + }, + loc: { start: 6725, end: 6733 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'base', + loc: { start: 6735, end: 6739 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6741, end: 6744 } + }, + loc: { start: 6741, end: 6744 } + }, + loc: { start: 6735, end: 6744 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_log', + loc: { start: 6702, end: 6712 } + } + }, + loc: { start: 6696, end: 6751 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'log2', loc: { start: 7341, end: 7345 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7357, end: 7360 } + }, + loc: { start: 7357, end: 7360 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 7346, end: 7349 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7351, end: 7354 } + }, + loc: { start: 7351, end: 7354 } + }, + loc: { start: 7346, end: 7354 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DUP 5 THROWIFNOT UBITSIZE DEC' ] + }, + loc: { start: 7333, end: 7394 } + }, + { + kind: 'function', + inline: true, + name: { kind: 'id', text: 'pow', loc: { start: 8510, end: 8513 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8536, end: 8539 } + }, + loc: { start: 8536, end: 8539 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'base', + loc: { start: 8514, end: 8518 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8520, end: 8523 } + }, + loc: { start: 8520, end: 8523 } + }, + loc: { start: 8514, end: 8523 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'exp', + loc: { start: 8525, end: 8528 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8530, end: 8533 } + }, + loc: { start: 8530, end: 8533 } + }, + loc: { start: 8525, end: 8533 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throwUnless', + loc: { start: 8546, end: 8557 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 5n, + loc: { start: 8558, end: 8559 } + }, + { + kind: 'op_binary', + op: '>=', + left: { + kind: 'var', + name: 'exp', + loc: { start: 8561, end: 8564 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 8568, end: 8569 } + }, + loc: { start: 8561, end: 8569 } + } + ], + loc: { start: 8546, end: 8570 } + }, + loc: { start: 8546, end: 8571 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'result', + loc: { start: 8580, end: 8586 } + }, + type: undefined, + expression: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 8589, end: 8590 } + }, + loc: { start: 8576, end: 8591 } + }, + { + kind: 'statement_repeat', + iterations: { + kind: 'var', + name: 'exp', + loc: { start: 8604, end: 8607 } + }, + statements: [ + { + kind: 'statement_augmentedassign', + op: '*=', + path: { + kind: 'var', + name: 'result', + loc: { start: 8619, end: 8625 } + }, + expression: { + kind: 'var', + name: 'base', + loc: { start: 8629, end: 8633 } + }, + loc: { start: 8619, end: 8634 } + } + ], + loc: { start: 8596, end: 8640 } + }, + { + kind: 'statement_return', + expression: { + kind: 'var', + name: 'result', + loc: { start: 8652, end: 8658 } + }, + loc: { start: 8645, end: 8659 } + } + ] + }, + loc: { start: 8499, end: 8661 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'pow2', loc: { start: 9733, end: 9737 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9749, end: 9752 } + }, + loc: { start: 9749, end: 9752 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'exp', + loc: { start: 9738, end: 9741 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9743, end: 9746 } + }, + loc: { start: 9743, end: 9746 } + }, + loc: { start: 9738, end: 9746 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'POW2' ] + }, + loc: { start: 9725, end: 9761 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sign', + loc: { start: 10233, end: 10237 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10247, end: 10250 } + }, + loc: { start: 10247, end: 10250 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 10238, end: 10239 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10241, end: 10244 } + }, + loc: { start: 10241, end: 10244 } + }, + loc: { start: 10238, end: 10244 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SGN' ] + }, + loc: { start: 10225, end: 10258 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'divc', + loc: { start: 10814, end: 10818 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10836, end: 10839 } + }, + loc: { start: 10836, end: 10839 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 10819, end: 10820 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10822, end: 10825 } + }, + loc: { start: 10822, end: 10825 } + }, + loc: { start: 10819, end: 10825 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 10827, end: 10828 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10830, end: 10833 } + }, + loc: { start: 10830, end: 10833 } + }, + loc: { start: 10827, end: 10833 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DIVC' ] + }, + loc: { start: 10806, end: 10848 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'muldivc', + loc: { start: 11615, end: 11622 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11648, end: 11651 } + }, + loc: { start: 11648, end: 11651 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 11623, end: 11624 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11626, end: 11629 } + }, + loc: { start: 11626, end: 11629 } + }, + loc: { start: 11623, end: 11629 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 11631, end: 11632 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11634, end: 11637 } + }, + loc: { start: 11634, end: 11637 } + }, + loc: { start: 11631, end: 11637 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 11639, end: 11640 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11642, end: 11645 } + }, + loc: { start: 11642, end: 11645 } + }, + loc: { start: 11639, end: 11645 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULDIVC' ] + }, + loc: { start: 11607, end: 11663 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRight', + loc: { start: 12751, end: 12764 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12790, end: 12793 } + }, + loc: { start: 12790, end: 12793 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 12765, end: 12766 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12768, end: 12771 } + }, + loc: { start: 12768, end: 12771 } + }, + loc: { start: 12765, end: 12771 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 12773, end: 12774 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12776, end: 12779 } + }, + loc: { start: 12776, end: 12779 } + }, + loc: { start: 12773, end: 12779 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 12781, end: 12782 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12784, end: 12787 } + }, + loc: { start: 12784, end: 12787 } + }, + loc: { start: 12781, end: 12787 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFT' ] + }, + loc: { start: 12743, end: 12807 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRightRound', + loc: { start: 13862, end: 13880 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13906, end: 13909 } + }, + loc: { start: 13906, end: 13909 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 13881, end: 13882 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13884, end: 13887 } + }, + loc: { start: 13884, end: 13887 } + }, + loc: { start: 13881, end: 13887 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 13889, end: 13890 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13892, end: 13895 } + }, + loc: { start: 13892, end: 13895 } + }, + loc: { start: 13889, end: 13895 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 13897, end: 13898 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13900, end: 13903 } + }, + loc: { start: 13900, end: 13903 } + }, + loc: { start: 13897, end: 13903 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFTR' ] + }, + loc: { start: 13854, end: 13924 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRightCeil', + loc: { start: 14875, end: 14892 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14918, end: 14921 } + }, + loc: { start: 14918, end: 14921 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 14893, end: 14894 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14896, end: 14899 } + }, + loc: { start: 14896, end: 14899 } + }, + loc: { start: 14893, end: 14899 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 14901, end: 14902 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14904, end: 14907 } + }, + loc: { start: 14904, end: 14907 } + }, + loc: { start: 14901, end: 14907 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 14909, end: 14910 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14912, end: 14915 } + }, + loc: { start: 14912, end: 14915 } + }, + loc: { start: 14909, end: 14915 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFTC' ] + }, + loc: { start: 14867, end: 14936 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sqrt', + loc: { start: 15698, end: 15702 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15714, end: 15717 } + }, + loc: { start: 15714, end: 15717 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 15703, end: 15706 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15708, end: 15711 } + }, + loc: { start: 15708, end: 15711 } + }, + loc: { start: 15703, end: 15711 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'num', + loc: { start: 15728, end: 15731 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15735, end: 15736 } + }, + loc: { start: 15728, end: 15736 } + }, + trueStatements: [ + { + kind: 'statement_return', + expression: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15755, end: 15756 } + }, + loc: { start: 15748, end: 15757 } + } + ], + falseStatements: undefined, + loc: { start: 15724, end: 15763 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 's', + loc: { start: 15773, end: 15774 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15776, end: 15779 } + }, + loc: { start: 15776, end: 15779 } + }, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'log2', + loc: { start: 15782, end: 15786 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'num', + loc: { start: 15787, end: 15790 } + } + ], + loc: { start: 15782, end: 15791 } + }, + loc: { start: 15769, end: 15792 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'x', + loc: { start: 15801, end: 15802 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15804, end: 15807 } + }, + loc: { start: 15804, end: 15807 } + }, + expression: { + kind: 'conditional', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 's', + loc: { start: 15811, end: 15812 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15816, end: 15817 } + }, + loc: { start: 15811, end: 15817 } + }, + thenBranch: { + kind: 'op_binary', + op: '+', + left: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'num', + loc: { start: 15821, end: 15824 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15827, end: 15828 } + }, + loc: { start: 15821, end: 15828 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15832, end: 15833 } + }, + loc: { start: 15820, end: 15833 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15836, end: 15837 } + }, + loc: { start: 15820, end: 15837 } + }, + elseBranch: { + kind: 'op_binary', + op: '<<', + left: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15840, end: 15841 } + }, + right: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '+', + left: { + kind: 'var', + name: 's', + loc: { start: 15847, end: 15848 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15851, end: 15852 } + }, + loc: { start: 15847, end: 15852 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15856, end: 15857 } + }, + loc: { start: 15846, end: 15857 } + }, + loc: { start: 15840, end: 15858 } + }, + loc: { start: 15811, end: 15858 } + }, + loc: { start: 15797, end: 15860 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'q', + loc: { start: 15870, end: 15871 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15873, end: 15876 } + }, + loc: { start: 15873, end: 15876 } + }, + expression: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15879, end: 15880 } + }, + loc: { start: 15866, end: 15881 } + }, + { + kind: 'statement_until', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'q', + loc: { start: 15957, end: 15958 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15962, end: 15963 } + }, + loc: { start: 15957, end: 15963 } + }, + statements: [ + { + kind: 'statement_assign', + path: { + kind: 'var', + name: 'q', + loc: { start: 15900, end: 15901 } + }, + expression: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '-', + left: { + kind: 'static_call', + function: { + kind: 'id', + text: 'divc', + loc: { start: 15905, end: 15909 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'num', + loc: { start: 15910, end: 15913 } + }, + { + kind: 'var', + name: 'x', + loc: { start: 15915, end: 15916 } + } + ], + loc: { start: 15905, end: 15917 } + }, + right: { + kind: 'var', + name: 'x', + loc: { start: 15920, end: 15921 } + }, + loc: { start: 15905, end: 15921 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15925, end: 15926 } + }, + loc: { start: 15904, end: 15926 } + }, + loc: { start: 15900, end: 15927 } + }, + { + kind: 'statement_augmentedassign', + op: '+=', + path: { + kind: 'var', + name: 'x', + loc: { start: 15936, end: 15937 } + }, + expression: { + kind: 'var', + name: 'q', + loc: { start: 15941, end: 15942 } + }, + loc: { start: 15936, end: 15943 } + } + ], + loc: { start: 15887, end: 15965 } + }, + { + kind: 'statement_return', + expression: { + kind: 'var', + name: 'x', + loc: { start: 15978, end: 15979 } + }, + loc: { start: 15971, end: 15980 } + } + ] + }, + loc: { start: 15694, end: 15982 } + } + ] + }, + 'log' => { + kind: 'tact', + path: 'std/internal/math.tact', + code: '// Prepare random\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Randomizes the pseudorandom number generator with the specified unsigned 256-bit `Int` `x` by mixing it with the current seed. The new seed is the unsigned 256-bit `Int` value of the SHA-256 hash of concatenated old seed and `x` in their 32-byte strings big-endian representation.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativeRandomize(42); // now, random numbers are less predictable\n' + + "/// let idk: Int = randomInt(); // ???, it's random,\n" + + '/// // but the seed was adjusted deterministically!\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify a negative value of `x`.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomize\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun nativeRandomize(x: Int) { ADDRAND }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Randomizes the random number generator with the logical time of the current transaction. Equivalent to calling `nativeRandomize(curLt())`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativeRandomizeLt(); // now, random numbers are unpredictable for users,\n' + + '/// // but still may be affected by validators or collators\n' + + '/// // as they determine the seed of the current block.\n' + + "/// let idk: Int = randomInt(); // ???, it's random!\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomizelt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomize\n' + + '/// * https://docs.tact-lang.org/ref/core-contextstate#curlt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + 'asm fun nativeRandomizeLt() { LTIME ADDRAND }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Prepares a random number generator by using `nativeRandomizeLt()`. Automatically called by `randomInt()` and `random()` functions.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativePrepareRandom(); // prepare the RNG\n' + + '/// // ... do your random things ...\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativepreparerandom\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomizelt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '/// * https://docs.tact-lang.org/ref/core-random#random\n' + + '///\n' + + '@name(__tact_prepare_random)\n' + + 'native nativePrepareRandom();\n' + + '\n' + + '// Random\n' + + '\n' + + '// Generates a new pseudo-random unsigned 256-bit integer x.\n' + + '// The algorithm is as follows: if r is the old value of the random seed,\n' + + '// considered as a 32-byte array (by constructing the big-endian representation\n' + + '// of an unsigned 256-bit integer), then its sha512(r) is computed;\n' + + "// the first 32 bytes of this hash are stored as the new value r' of the random seed,\n" + + '// and the remaining 32 bytes are returned as the next random value x.\n' + + 'asm fun nativeRandom(): Int { RANDU256 }\n' + + '\n' + + '// Generates a new pseudo-random integer z in the range 0..range−1\n' + + '// (or range..−1, if range < 0).\n' + + '// More precisely, an unsigned random value x is generated as in `nativeRandom`;\n' + + '// then z := x * range / 2^256 is computed.\n' + + 'asm fun nativeRandomInterval(max: Int): Int { RAND }\n' + + '\n' + + '/// Generates and returns a new pseudo-random unsigned 256-bit `Int` value `x`.\n' + + '///\n' + + '/// The algorithm works as follows: first, the `sha512(r)` is computed. There, `r` is an old\n' + + '/// value of the random seed, which is taken as a 32-byte array constructed from the big-endian\n' + + '/// representation of an unsigned 256-bit `Int`. The first 32 bytes of this hash are stored as the new\n' + + "/// value `r'` of the random seed, and the remaining 32 bytes are returned as the next random value `x`.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + "/// let allYourRandomBelongToUs: Int = randomInt(); // ???, it's random :)\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + 'inline fun randomInt(): Int {\n' + + ' nativePrepareRandom();\n' + + ' return nativeRandom();\n' + + '}\n' + + '\n' + + '/// Generates and returns a new pseudo-random unsigned `Int` value `x` in the provided semi-closed\n' + + '/// interval: `min` ≤ `x` < `max`, or `min` ≥ `x` > `max` if both `min` and `max` are negative.\n' + + '///\n' + + '/// Note that the `max` value is never included in the interval.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// random(42, 43); // 42, always\n' + + '/// random(0, 42); // 0-41, but never 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-random#random\n' + + '///\n' + + 'inline fun random(min: Int, max: Int): Int {\n' + + ' nativePrepareRandom();\n' + + ' return min + nativeRandomInterval(max - min);\n' + + '}\n' + + '\n' + + '// Math\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the minimum of two `Int` values `x` and `y`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// min(1, 2); // 1\n' + + '/// min(2, 2); // 2\n' + + '/// min(007, 3); // 3\n' + + '/// min(0x45, 3_0_0); // 69, nice\n' + + '/// // ↑ ↑\n' + + '/// // 69 300\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#min\n' + + '///\n' + + 'asm fun min(x: Int, y: Int): Int { MIN }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the maximum of two `Int` values `x` and `y`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// max(1, 2); // 2\n' + + '/// max(2, 2); // 2\n' + + '/// max(007, 3); // 7\n' + + '/// max(0x45, 3_0_0); // 300\n' + + '/// // ↑ ↑\n' + + '/// // 69 300\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#max\n' + + '///\n' + + 'asm fun max(x: Int, y: Int): Int { MAX }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the absolute value of the `Int` value `x`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// abs(42); // 42\n' + + '/// abs(-42); // 42\n' + + '/// abs(-(-(-42))); // 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#abs\n' + + '///\n' + + 'asm fun abs(x: Int): Int { ABS }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the logarithm of a number `num` > 0 to the base `base` ≥ 1. Results are rounded down.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// log(1000, 10); // 3, as 10^3 is 1000\n' + + '/// // ↑ ↑ ↑ ↑\n' + + '/// // num base base num\n' + + '///\n' + + '/// log(1001, 10); // 3\n' + + '/// log(999, 10); // 2\n' + + '/// try {\n' + + '/// log(-1000, 10); // exit code 5 because of the non-positive num\n' + + '/// }\n' + + '/// log(1024, 2); // 10\n' + + '/// try {\n' + + '/// log(1024, -2); // exit code 5 because the base is less than 1\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `num` value is non-positive\n' + + '/// or the given `base` value is less than 1.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log2\n' + + '///\n' + + '@name(__tact_log)\n' + + 'native log(num: Int, base: Int): Int;\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Similar to `log()`, but sets the `base` to 2.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// log2(1024); // 10, as 2^10 is 1024\n' + + '/// // ↑ ↑ ↑\n' + + '/// // num base₂ num\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `num` value is non-positive.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log2\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log.\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes/#5\n' + + '///\n' + + 'asm fun log2(num: Int): Int { DUP 5 THROWIFNOT UBITSIZE DEC }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the exponentiation involving two numbers: the `base` and the exponent (or _power_) `exp`.\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Example {\n' + + '/// // Persistent state variables\n' + + '/// p23: Int = pow(2, 3); // raises 2 to the 3rd power, which is 8\n' + + '/// one: Int = pow(5, 0); // raises 5 to the power 0, which always produces 1\n' + + '/// // works at compile-time!\n' + + '///\n' + + '/// // Internal message receiver\n' + + '/// receive() {\n' + + '/// pow(self.p23, self.one + 1); // 64, works at run-time too!\n' + + '/// try {\n' + + '/// pow(0, -1); // exit code 5: Integer out of expected range\n' + + '/// }\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `exp` value is negative.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow2\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes/#5\n' + + '///\n' + + 'inline fun pow(base: Int, exp: Int): Int {\n' + + ' throwUnless(5, exp >= 0);\n' + + ' let result = 1;\n' + + ' repeat (exp) {\n' + + ' result *= base;\n' + + ' }\n' + + ' return result;\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Similar to `pow()`, but sets the `base` to 2.\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Example {\n' + + '/// // Persistent state variables\n' + + '/// p23: Int = pow2(3); // raises 2 to the 3rd power, which is 8\n' + + '/// one: Int = pow2(0); // raises 2 to the power 0, which always produces 1\n' + + '/// // works at compile-time!\n' + + '///\n' + + '/// // Internal message receiver, which accepts message ExtMsg\n' + + '/// receive() {\n' + + '/// pow2(self.one + 1); // 4, works at run-time too!\n' + + '/// try {\n' + + '/// pow(-1); // exit code 5: Integer out of expected range\n' + + '/// }\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify a negative value of `exp`.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow2\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun pow2(exp: Int): Int { POW2 }\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Computes and returns the sign of the `Int` value `x`. Produces 1 if the `x` is positive, -1 if the `x` is negative, and 0 if the `x` is 0.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// '... 5983 more characters, + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomize', + loc: { start: 965, end: 980 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { kind: 'id', text: 'x', loc: { start: 981, end: 982 } }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 984, end: 987 } + }, + loc: { start: 984, end: 987 } + }, + loc: { start: 981, end: 987 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ADDRAND' ] + }, + loc: { start: 957, end: 1000 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomizeLt', + loc: { start: 1822, end: 1839 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LTIME ADDRAND' ] + }, + loc: { start: 1814, end: 1859 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 2466, end: 2485 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_prepare_random', + loc: { start: 2436, end: 2457 } + } + }, + loc: { start: 2430, end: 2488 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandom', + loc: { start: 2949, end: 2961 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2965, end: 2968 } + }, + loc: { start: 2965, end: 2968 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RANDU256' ] + }, + loc: { start: 2941, end: 2981 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomInterval', + loc: { start: 3216, end: 3236 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3248, end: 3251 } + }, + loc: { start: 3248, end: 3251 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'max', + loc: { start: 3237, end: 3240 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3242, end: 3245 } + }, + loc: { start: 3242, end: 3245 } + }, + loc: { start: 3237, end: 3245 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RAND' ] + }, + loc: { start: 3208, end: 3260 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'randomInt', + loc: { start: 3953, end: 3962 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3966, end: 3969 } + }, + loc: { start: 3966, end: 3969 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 3976, end: 3995 } + }, + typeArgs: [], + args: [], + loc: { start: 3976, end: 3997 } + }, + loc: { start: 3976, end: 3998 } + }, + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativeRandom', + loc: { start: 4010, end: 4022 } + }, + typeArgs: [], + args: [], + loc: { start: 4010, end: 4024 } + }, + loc: { start: 4003, end: 4025 } + } + ] + }, + loc: { start: 3942, end: 4027 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'random', + loc: { start: 4505, end: 4511 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4533, end: 4536 } + }, + loc: { start: 4533, end: 4536 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'min', + loc: { start: 4512, end: 4515 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4517, end: 4520 } + }, + loc: { start: 4517, end: 4520 } + }, + loc: { start: 4512, end: 4520 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'max', + loc: { start: 4522, end: 4525 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4527, end: 4530 } + }, + loc: { start: 4527, end: 4530 } + }, + loc: { start: 4522, end: 4530 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 4543, end: 4562 } + }, + typeArgs: [], + args: [], + loc: { start: 4543, end: 4564 } + }, + loc: { start: 4543, end: 4565 } + }, + { + kind: 'statement_return', + expression: { + kind: 'op_binary', + op: '+', + left: { + kind: 'var', + name: 'min', + loc: { start: 4577, end: 4580 } + }, + right: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativeRandomInterval', + loc: { start: 4583, end: 4603 } + }, + typeArgs: [], + args: [ + { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'max', + loc: { start: 4604, end: 4607 } + }, + right: { + kind: 'var', + name: 'min', + loc: { start: 4610, end: 4613 } + }, + loc: { start: 4604, end: 4613 } + } + ], + loc: { start: 4583, end: 4614 } + }, + loc: { start: 4577, end: 4614 } + }, + loc: { start: 4570, end: 4615 } + } + ] + }, + loc: { start: 4494, end: 4617 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'min', loc: { start: 5017, end: 5020 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5038, end: 5041 } + }, + loc: { start: 5038, end: 5041 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5021, end: 5022 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5024, end: 5027 } + }, + loc: { start: 5024, end: 5027 } + }, + loc: { start: 5021, end: 5027 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 5029, end: 5030 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5032, end: 5035 } + }, + loc: { start: 5032, end: 5035 } + }, + loc: { start: 5029, end: 5035 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MIN' ] + }, + loc: { start: 5009, end: 5049 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'max', loc: { start: 5435, end: 5438 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5456, end: 5459 } + }, + loc: { start: 5456, end: 5459 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5439, end: 5440 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5442, end: 5445 } + }, + loc: { start: 5442, end: 5445 } + }, + loc: { start: 5439, end: 5445 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 5447, end: 5448 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5450, end: 5453 } + }, + loc: { start: 5450, end: 5453 } + }, + loc: { start: 5447, end: 5453 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MAX' ] + }, + loc: { start: 5427, end: 5467 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'abs', loc: { start: 5773, end: 5776 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5786, end: 5789 } + }, + loc: { start: 5786, end: 5789 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5777, end: 5778 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5780, end: 5783 } + }, + loc: { start: 5780, end: 5783 } + }, + loc: { start: 5777, end: 5783 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ABS' ] + }, + loc: { start: 5765, end: 5797 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'log', loc: { start: 6721, end: 6724 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6747, end: 6750 } + }, + loc: { start: 6747, end: 6750 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 6725, end: 6728 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6730, end: 6733 } + }, + loc: { start: 6730, end: 6733 } + }, + loc: { start: 6725, end: 6733 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'base', + loc: { start: 6735, end: 6739 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6741, end: 6744 } + }, + loc: { start: 6741, end: 6744 } + }, + loc: { start: 6735, end: 6744 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_log', + loc: { start: 6702, end: 6712 } + } + }, + loc: { start: 6696, end: 6751 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'log2', loc: { start: 7341, end: 7345 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7357, end: 7360 } + }, + loc: { start: 7357, end: 7360 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 7346, end: 7349 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7351, end: 7354 } + }, + loc: { start: 7351, end: 7354 } + }, + loc: { start: 7346, end: 7354 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DUP 5 THROWIFNOT UBITSIZE DEC' ] + }, + loc: { start: 7333, end: 7394 } + }, + { + kind: 'function', + inline: true, + name: { kind: 'id', text: 'pow', loc: { start: 8510, end: 8513 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8536, end: 8539 } + }, + loc: { start: 8536, end: 8539 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'base', + loc: { start: 8514, end: 8518 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8520, end: 8523 } + }, + loc: { start: 8520, end: 8523 } + }, + loc: { start: 8514, end: 8523 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'exp', + loc: { start: 8525, end: 8528 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8530, end: 8533 } + }, + loc: { start: 8530, end: 8533 } + }, + loc: { start: 8525, end: 8533 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throwUnless', + loc: { start: 8546, end: 8557 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 5n, + loc: { start: 8558, end: 8559 } + }, + { + kind: 'op_binary', + op: '>=', + left: { + kind: 'var', + name: 'exp', + loc: { start: 8561, end: 8564 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 8568, end: 8569 } + }, + loc: { start: 8561, end: 8569 } + } + ], + loc: { start: 8546, end: 8570 } + }, + loc: { start: 8546, end: 8571 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'result', + loc: { start: 8580, end: 8586 } + }, + type: undefined, + expression: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 8589, end: 8590 } + }, + loc: { start: 8576, end: 8591 } + }, + { + kind: 'statement_repeat', + iterations: { + kind: 'var', + name: 'exp', + loc: { start: 8604, end: 8607 } + }, + statements: [ + { + kind: 'statement_augmentedassign', + op: '*=', + path: { + kind: 'var', + name: 'result', + loc: { start: 8619, end: 8625 } + }, + expression: { + kind: 'var', + name: 'base', + loc: { start: 8629, end: 8633 } + }, + loc: { start: 8619, end: 8634 } + } + ], + loc: { start: 8596, end: 8640 } + }, + { + kind: 'statement_return', + expression: { + kind: 'var', + name: 'result', + loc: { start: 8652, end: 8658 } + }, + loc: { start: 8645, end: 8659 } + } + ] + }, + loc: { start: 8499, end: 8661 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'pow2', loc: { start: 9733, end: 9737 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9749, end: 9752 } + }, + loc: { start: 9749, end: 9752 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'exp', + loc: { start: 9738, end: 9741 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9743, end: 9746 } + }, + loc: { start: 9743, end: 9746 } + }, + loc: { start: 9738, end: 9746 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'POW2' ] + }, + loc: { start: 9725, end: 9761 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sign', + loc: { start: 10233, end: 10237 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10247, end: 10250 } + }, + loc: { start: 10247, end: 10250 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 10238, end: 10239 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10241, end: 10244 } + }, + loc: { start: 10241, end: 10244 } + }, + loc: { start: 10238, end: 10244 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SGN' ] + }, + loc: { start: 10225, end: 10258 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'divc', + loc: { start: 10814, end: 10818 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10836, end: 10839 } + }, + loc: { start: 10836, end: 10839 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 10819, end: 10820 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10822, end: 10825 } + }, + loc: { start: 10822, end: 10825 } + }, + loc: { start: 10819, end: 10825 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 10827, end: 10828 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10830, end: 10833 } + }, + loc: { start: 10830, end: 10833 } + }, + loc: { start: 10827, end: 10833 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DIVC' ] + }, + loc: { start: 10806, end: 10848 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'muldivc', + loc: { start: 11615, end: 11622 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11648, end: 11651 } + }, + loc: { start: 11648, end: 11651 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 11623, end: 11624 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11626, end: 11629 } + }, + loc: { start: 11626, end: 11629 } + }, + loc: { start: 11623, end: 11629 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 11631, end: 11632 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11634, end: 11637 } + }, + loc: { start: 11634, end: 11637 } + }, + loc: { start: 11631, end: 11637 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 11639, end: 11640 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11642, end: 11645 } + }, + loc: { start: 11642, end: 11645 } + }, + loc: { start: 11639, end: 11645 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULDIVC' ] + }, + loc: { start: 11607, end: 11663 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRight', + loc: { start: 12751, end: 12764 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12790, end: 12793 } + }, + loc: { start: 12790, end: 12793 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 12765, end: 12766 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12768, end: 12771 } + }, + loc: { start: 12768, end: 12771 } + }, + loc: { start: 12765, end: 12771 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 12773, end: 12774 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12776, end: 12779 } + }, + loc: { start: 12776, end: 12779 } + }, + loc: { start: 12773, end: 12779 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 12781, end: 12782 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12784, end: 12787 } + }, + loc: { start: 12784, end: 12787 } + }, + loc: { start: 12781, end: 12787 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFT' ] + }, + loc: { start: 12743, end: 12807 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRightRound', + loc: { start: 13862, end: 13880 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13906, end: 13909 } + }, + loc: { start: 13906, end: 13909 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 13881, end: 13882 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13884, end: 13887 } + }, + loc: { start: 13884, end: 13887 } + }, + loc: { start: 13881, end: 13887 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 13889, end: 13890 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13892, end: 13895 } + }, + loc: { start: 13892, end: 13895 } + }, + loc: { start: 13889, end: 13895 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 13897, end: 13898 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13900, end: 13903 } + }, + loc: { start: 13900, end: 13903 } + }, + loc: { start: 13897, end: 13903 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFTR' ] + }, + loc: { start: 13854, end: 13924 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRightCeil', + loc: { start: 14875, end: 14892 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14918, end: 14921 } + }, + loc: { start: 14918, end: 14921 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 14893, end: 14894 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14896, end: 14899 } + }, + loc: { start: 14896, end: 14899 } + }, + loc: { start: 14893, end: 14899 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 14901, end: 14902 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14904, end: 14907 } + }, + loc: { start: 14904, end: 14907 } + }, + loc: { start: 14901, end: 14907 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 14909, end: 14910 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14912, end: 14915 } + }, + loc: { start: 14912, end: 14915 } + }, + loc: { start: 14909, end: 14915 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFTC' ] + }, + loc: { start: 14867, end: 14936 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sqrt', + loc: { start: 15698, end: 15702 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15714, end: 15717 } + }, + loc: { start: 15714, end: 15717 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 15703, end: 15706 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15708, end: 15711 } + }, + loc: { start: 15708, end: 15711 } + }, + loc: { start: 15703, end: 15711 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'num', + loc: { start: 15728, end: 15731 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15735, end: 15736 } + }, + loc: { start: 15728, end: 15736 } + }, + trueStatements: [ + { + kind: 'statement_return', + expression: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15755, end: 15756 } + }, + loc: { start: 15748, end: 15757 } + } + ], + falseStatements: undefined, + loc: { start: 15724, end: 15763 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 's', + loc: { start: 15773, end: 15774 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15776, end: 15779 } + }, + loc: { start: 15776, end: 15779 } + }, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'log2', + loc: { start: 15782, end: 15786 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'num', + loc: { start: 15787, end: 15790 } + } + ], + loc: { start: 15782, end: 15791 } + }, + loc: { start: 15769, end: 15792 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'x', + loc: { start: 15801, end: 15802 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15804, end: 15807 } + }, + loc: { start: 15804, end: 15807 } + }, + expression: { + kind: 'conditional', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 's', + loc: { start: 15811, end: 15812 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15816, end: 15817 } + }, + loc: { start: 15811, end: 15817 } + }, + thenBranch: { + kind: 'op_binary', + op: '+', + left: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'num', + loc: { start: 15821, end: 15824 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15827, end: 15828 } + }, + loc: { start: 15821, end: 15828 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15832, end: 15833 } + }, + loc: { start: 15820, end: 15833 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15836, end: 15837 } + }, + loc: { start: 15820, end: 15837 } + }, + elseBranch: { + kind: 'op_binary', + op: '<<', + left: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15840, end: 15841 } + }, + right: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '+', + left: { + kind: 'var', + name: 's', + loc: { start: 15847, end: 15848 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15851, end: 15852 } + }, + loc: { start: 15847, end: 15852 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15856, end: 15857 } + }, + loc: { start: 15846, end: 15857 } + }, + loc: { start: 15840, end: 15858 } + }, + loc: { start: 15811, end: 15858 } + }, + loc: { start: 15797, end: 15860 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'q', + loc: { start: 15870, end: 15871 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15873, end: 15876 } + }, + loc: { start: 15873, end: 15876 } + }, + expression: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15879, end: 15880 } + }, + loc: { start: 15866, end: 15881 } + }, + { + kind: 'statement_until', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'q', + loc: { start: 15957, end: 15958 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15962, end: 15963 } + }, + loc: { start: 15957, end: 15963 } + }, + statements: [ + { + kind: 'statement_assign', + path: { + kind: 'var', + name: 'q', + loc: { start: 15900, end: 15901 } + }, + expression: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '-', + left: { + kind: 'static_call', + function: { + kind: 'id', + text: 'divc', + loc: { start: 15905, end: 15909 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'num', + loc: { start: 15910, end: 15913 } + }, + { + kind: 'var', + name: 'x', + loc: { start: 15915, end: 15916 } + } + ], + loc: { start: 15905, end: 15917 } + }, + right: { + kind: 'var', + name: 'x', + loc: { start: 15920, end: 15921 } + }, + loc: { start: 15905, end: 15921 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15925, end: 15926 } + }, + loc: { start: 15904, end: 15926 } + }, + loc: { start: 15900, end: 15927 } + }, + { + kind: 'statement_augmentedassign', + op: '+=', + path: { + kind: 'var', + name: 'x', + loc: { start: 15936, end: 15937 } + }, + expression: { + kind: 'var', + name: 'q', + loc: { start: 15941, end: 15942 } + }, + loc: { start: 15936, end: 15943 } + } + ], + loc: { start: 15887, end: 15965 } + }, + { + kind: 'statement_return', + expression: { + kind: 'var', + name: 'x', + loc: { start: 15978, end: 15979 } + }, + loc: { start: 15971, end: 15980 } + } + ] + }, + loc: { start: 15694, end: 15982 } + } + ] + }, + 'log2' => { + kind: 'tact', + path: 'std/internal/math.tact', + code: '// Prepare random\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Randomizes the pseudorandom number generator with the specified unsigned 256-bit `Int` `x` by mixing it with the current seed. The new seed is the unsigned 256-bit `Int` value of the SHA-256 hash of concatenated old seed and `x` in their 32-byte strings big-endian representation.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativeRandomize(42); // now, random numbers are less predictable\n' + + "/// let idk: Int = randomInt(); // ???, it's random,\n" + + '/// // but the seed was adjusted deterministically!\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify a negative value of `x`.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomize\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun nativeRandomize(x: Int) { ADDRAND }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Randomizes the random number generator with the logical time of the current transaction. Equivalent to calling `nativeRandomize(curLt())`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativeRandomizeLt(); // now, random numbers are unpredictable for users,\n' + + '/// // but still may be affected by validators or collators\n' + + '/// // as they determine the seed of the current block.\n' + + "/// let idk: Int = randomInt(); // ???, it's random!\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomizelt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomize\n' + + '/// * https://docs.tact-lang.org/ref/core-contextstate#curlt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + 'asm fun nativeRandomizeLt() { LTIME ADDRAND }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Prepares a random number generator by using `nativeRandomizeLt()`. Automatically called by `randomInt()` and `random()` functions.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativePrepareRandom(); // prepare the RNG\n' + + '/// // ... do your random things ...\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativepreparerandom\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomizelt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '/// * https://docs.tact-lang.org/ref/core-random#random\n' + + '///\n' + + '@name(__tact_prepare_random)\n' + + 'native nativePrepareRandom();\n' + + '\n' + + '// Random\n' + + '\n' + + '// Generates a new pseudo-random unsigned 256-bit integer x.\n' + + '// The algorithm is as follows: if r is the old value of the random seed,\n' + + '// considered as a 32-byte array (by constructing the big-endian representation\n' + + '// of an unsigned 256-bit integer), then its sha512(r) is computed;\n' + + "// the first 32 bytes of this hash are stored as the new value r' of the random seed,\n" + + '// and the remaining 32 bytes are returned as the next random value x.\n' + + 'asm fun nativeRandom(): Int { RANDU256 }\n' + + '\n' + + '// Generates a new pseudo-random integer z in the range 0..range−1\n' + + '// (or range..−1, if range < 0).\n' + + '// More precisely, an unsigned random value x is generated as in `nativeRandom`;\n' + + '// then z := x * range / 2^256 is computed.\n' + + 'asm fun nativeRandomInterval(max: Int): Int { RAND }\n' + + '\n' + + '/// Generates and returns a new pseudo-random unsigned 256-bit `Int` value `x`.\n' + + '///\n' + + '/// The algorithm works as follows: first, the `sha512(r)` is computed. There, `r` is an old\n' + + '/// value of the random seed, which is taken as a 32-byte array constructed from the big-endian\n' + + '/// representation of an unsigned 256-bit `Int`. The first 32 bytes of this hash are stored as the new\n' + + "/// value `r'` of the random seed, and the remaining 32 bytes are returned as the next random value `x`.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + "/// let allYourRandomBelongToUs: Int = randomInt(); // ???, it's random :)\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + 'inline fun randomInt(): Int {\n' + + ' nativePrepareRandom();\n' + + ' return nativeRandom();\n' + + '}\n' + + '\n' + + '/// Generates and returns a new pseudo-random unsigned `Int` value `x` in the provided semi-closed\n' + + '/// interval: `min` ≤ `x` < `max`, or `min` ≥ `x` > `max` if both `min` and `max` are negative.\n' + + '///\n' + + '/// Note that the `max` value is never included in the interval.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// random(42, 43); // 42, always\n' + + '/// random(0, 42); // 0-41, but never 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-random#random\n' + + '///\n' + + 'inline fun random(min: Int, max: Int): Int {\n' + + ' nativePrepareRandom();\n' + + ' return min + nativeRandomInterval(max - min);\n' + + '}\n' + + '\n' + + '// Math\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the minimum of two `Int` values `x` and `y`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// min(1, 2); // 1\n' + + '/// min(2, 2); // 2\n' + + '/// min(007, 3); // 3\n' + + '/// min(0x45, 3_0_0); // 69, nice\n' + + '/// // ↑ ↑\n' + + '/// // 69 300\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#min\n' + + '///\n' + + 'asm fun min(x: Int, y: Int): Int { MIN }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the maximum of two `Int` values `x` and `y`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// max(1, 2); // 2\n' + + '/// max(2, 2); // 2\n' + + '/// max(007, 3); // 7\n' + + '/// max(0x45, 3_0_0); // 300\n' + + '/// // ↑ ↑\n' + + '/// // 69 300\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#max\n' + + '///\n' + + 'asm fun max(x: Int, y: Int): Int { MAX }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the absolute value of the `Int` value `x`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// abs(42); // 42\n' + + '/// abs(-42); // 42\n' + + '/// abs(-(-(-42))); // 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#abs\n' + + '///\n' + + 'asm fun abs(x: Int): Int { ABS }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the logarithm of a number `num` > 0 to the base `base` ≥ 1. Results are rounded down.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// log(1000, 10); // 3, as 10^3 is 1000\n' + + '/// // ↑ ↑ ↑ ↑\n' + + '/// // num base base num\n' + + '///\n' + + '/// log(1001, 10); // 3\n' + + '/// log(999, 10); // 2\n' + + '/// try {\n' + + '/// log(-1000, 10); // exit code 5 because of the non-positive num\n' + + '/// }\n' + + '/// log(1024, 2); // 10\n' + + '/// try {\n' + + '/// log(1024, -2); // exit code 5 because the base is less than 1\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `num` value is non-positive\n' + + '/// or the given `base` value is less than 1.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log2\n' + + '///\n' + + '@name(__tact_log)\n' + + 'native log(num: Int, base: Int): Int;\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Similar to `log()`, but sets the `base` to 2.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// log2(1024); // 10, as 2^10 is 1024\n' + + '/// // ↑ ↑ ↑\n' + + '/// // num base₂ num\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `num` value is non-positive.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log2\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log.\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes/#5\n' + + '///\n' + + 'asm fun log2(num: Int): Int { DUP 5 THROWIFNOT UBITSIZE DEC }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the exponentiation involving two numbers: the `base` and the exponent (or _power_) `exp`.\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Example {\n' + + '/// // Persistent state variables\n' + + '/// p23: Int = pow(2, 3); // raises 2 to the 3rd power, which is 8\n' + + '/// one: Int = pow(5, 0); // raises 5 to the power 0, which always produces 1\n' + + '/// // works at compile-time!\n' + + '///\n' + + '/// // Internal message receiver\n' + + '/// receive() {\n' + + '/// pow(self.p23, self.one + 1); // 64, works at run-time too!\n' + + '/// try {\n' + + '/// pow(0, -1); // exit code 5: Integer out of expected range\n' + + '/// }\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `exp` value is negative.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow2\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes/#5\n' + + '///\n' + + 'inline fun pow(base: Int, exp: Int): Int {\n' + + ' throwUnless(5, exp >= 0);\n' + + ' let result = 1;\n' + + ' repeat (exp) {\n' + + ' result *= base;\n' + + ' }\n' + + ' return result;\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Similar to `pow()`, but sets the `base` to 2.\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Example {\n' + + '/// // Persistent state variables\n' + + '/// p23: Int = pow2(3); // raises 2 to the 3rd power, which is 8\n' + + '/// one: Int = pow2(0); // raises 2 to the power 0, which always produces 1\n' + + '/// // works at compile-time!\n' + + '///\n' + + '/// // Internal message receiver, which accepts message ExtMsg\n' + + '/// receive() {\n' + + '/// pow2(self.one + 1); // 4, works at run-time too!\n' + + '/// try {\n' + + '/// pow(-1); // exit code 5: Integer out of expected range\n' + + '/// }\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify a negative value of `exp`.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow2\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun pow2(exp: Int): Int { POW2 }\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Computes and returns the sign of the `Int` value `x`. Produces 1 if the `x` is positive, -1 if the `x` is negative, and 0 if the `x` is 0.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// '... 5983 more characters, + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomize', + loc: { start: 965, end: 980 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { kind: 'id', text: 'x', loc: { start: 981, end: 982 } }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 984, end: 987 } + }, + loc: { start: 984, end: 987 } + }, + loc: { start: 981, end: 987 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ADDRAND' ] + }, + loc: { start: 957, end: 1000 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomizeLt', + loc: { start: 1822, end: 1839 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LTIME ADDRAND' ] + }, + loc: { start: 1814, end: 1859 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 2466, end: 2485 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_prepare_random', + loc: { start: 2436, end: 2457 } + } + }, + loc: { start: 2430, end: 2488 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandom', + loc: { start: 2949, end: 2961 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2965, end: 2968 } + }, + loc: { start: 2965, end: 2968 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RANDU256' ] + }, + loc: { start: 2941, end: 2981 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomInterval', + loc: { start: 3216, end: 3236 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3248, end: 3251 } + }, + loc: { start: 3248, end: 3251 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'max', + loc: { start: 3237, end: 3240 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3242, end: 3245 } + }, + loc: { start: 3242, end: 3245 } + }, + loc: { start: 3237, end: 3245 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RAND' ] + }, + loc: { start: 3208, end: 3260 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'randomInt', + loc: { start: 3953, end: 3962 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3966, end: 3969 } + }, + loc: { start: 3966, end: 3969 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 3976, end: 3995 } + }, + typeArgs: [], + args: [], + loc: { start: 3976, end: 3997 } + }, + loc: { start: 3976, end: 3998 } + }, + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativeRandom', + loc: { start: 4010, end: 4022 } + }, + typeArgs: [], + args: [], + loc: { start: 4010, end: 4024 } + }, + loc: { start: 4003, end: 4025 } + } + ] + }, + loc: { start: 3942, end: 4027 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'random', + loc: { start: 4505, end: 4511 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4533, end: 4536 } + }, + loc: { start: 4533, end: 4536 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'min', + loc: { start: 4512, end: 4515 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4517, end: 4520 } + }, + loc: { start: 4517, end: 4520 } + }, + loc: { start: 4512, end: 4520 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'max', + loc: { start: 4522, end: 4525 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4527, end: 4530 } + }, + loc: { start: 4527, end: 4530 } + }, + loc: { start: 4522, end: 4530 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 4543, end: 4562 } + }, + typeArgs: [], + args: [], + loc: { start: 4543, end: 4564 } + }, + loc: { start: 4543, end: 4565 } + }, + { + kind: 'statement_return', + expression: { + kind: 'op_binary', + op: '+', + left: { + kind: 'var', + name: 'min', + loc: { start: 4577, end: 4580 } + }, + right: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativeRandomInterval', + loc: { start: 4583, end: 4603 } + }, + typeArgs: [], + args: [ + { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'max', + loc: { start: 4604, end: 4607 } + }, + right: { + kind: 'var', + name: 'min', + loc: { start: 4610, end: 4613 } + }, + loc: { start: 4604, end: 4613 } + } + ], + loc: { start: 4583, end: 4614 } + }, + loc: { start: 4577, end: 4614 } + }, + loc: { start: 4570, end: 4615 } + } + ] + }, + loc: { start: 4494, end: 4617 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'min', loc: { start: 5017, end: 5020 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5038, end: 5041 } + }, + loc: { start: 5038, end: 5041 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5021, end: 5022 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5024, end: 5027 } + }, + loc: { start: 5024, end: 5027 } + }, + loc: { start: 5021, end: 5027 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 5029, end: 5030 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5032, end: 5035 } + }, + loc: { start: 5032, end: 5035 } + }, + loc: { start: 5029, end: 5035 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MIN' ] + }, + loc: { start: 5009, end: 5049 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'max', loc: { start: 5435, end: 5438 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5456, end: 5459 } + }, + loc: { start: 5456, end: 5459 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5439, end: 5440 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5442, end: 5445 } + }, + loc: { start: 5442, end: 5445 } + }, + loc: { start: 5439, end: 5445 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 5447, end: 5448 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5450, end: 5453 } + }, + loc: { start: 5450, end: 5453 } + }, + loc: { start: 5447, end: 5453 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MAX' ] + }, + loc: { start: 5427, end: 5467 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'abs', loc: { start: 5773, end: 5776 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5786, end: 5789 } + }, + loc: { start: 5786, end: 5789 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5777, end: 5778 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5780, end: 5783 } + }, + loc: { start: 5780, end: 5783 } + }, + loc: { start: 5777, end: 5783 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ABS' ] + }, + loc: { start: 5765, end: 5797 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'log', loc: { start: 6721, end: 6724 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6747, end: 6750 } + }, + loc: { start: 6747, end: 6750 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 6725, end: 6728 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6730, end: 6733 } + }, + loc: { start: 6730, end: 6733 } + }, + loc: { start: 6725, end: 6733 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'base', + loc: { start: 6735, end: 6739 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6741, end: 6744 } + }, + loc: { start: 6741, end: 6744 } + }, + loc: { start: 6735, end: 6744 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_log', + loc: { start: 6702, end: 6712 } + } + }, + loc: { start: 6696, end: 6751 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'log2', loc: { start: 7341, end: 7345 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7357, end: 7360 } + }, + loc: { start: 7357, end: 7360 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 7346, end: 7349 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7351, end: 7354 } + }, + loc: { start: 7351, end: 7354 } + }, + loc: { start: 7346, end: 7354 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DUP 5 THROWIFNOT UBITSIZE DEC' ] + }, + loc: { start: 7333, end: 7394 } + }, + { + kind: 'function', + inline: true, + name: { kind: 'id', text: 'pow', loc: { start: 8510, end: 8513 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8536, end: 8539 } + }, + loc: { start: 8536, end: 8539 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'base', + loc: { start: 8514, end: 8518 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8520, end: 8523 } + }, + loc: { start: 8520, end: 8523 } + }, + loc: { start: 8514, end: 8523 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'exp', + loc: { start: 8525, end: 8528 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8530, end: 8533 } + }, + loc: { start: 8530, end: 8533 } + }, + loc: { start: 8525, end: 8533 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throwUnless', + loc: { start: 8546, end: 8557 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 5n, + loc: { start: 8558, end: 8559 } + }, + { + kind: 'op_binary', + op: '>=', + left: { + kind: 'var', + name: 'exp', + loc: { start: 8561, end: 8564 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 8568, end: 8569 } + }, + loc: { start: 8561, end: 8569 } + } + ], + loc: { start: 8546, end: 8570 } + }, + loc: { start: 8546, end: 8571 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'result', + loc: { start: 8580, end: 8586 } + }, + type: undefined, + expression: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 8589, end: 8590 } + }, + loc: { start: 8576, end: 8591 } + }, + { + kind: 'statement_repeat', + iterations: { + kind: 'var', + name: 'exp', + loc: { start: 8604, end: 8607 } + }, + statements: [ + { + kind: 'statement_augmentedassign', + op: '*=', + path: { + kind: 'var', + name: 'result', + loc: { start: 8619, end: 8625 } + }, + expression: { + kind: 'var', + name: 'base', + loc: { start: 8629, end: 8633 } + }, + loc: { start: 8619, end: 8634 } + } + ], + loc: { start: 8596, end: 8640 } + }, + { + kind: 'statement_return', + expression: { + kind: 'var', + name: 'result', + loc: { start: 8652, end: 8658 } + }, + loc: { start: 8645, end: 8659 } + } + ] + }, + loc: { start: 8499, end: 8661 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'pow2', loc: { start: 9733, end: 9737 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9749, end: 9752 } + }, + loc: { start: 9749, end: 9752 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'exp', + loc: { start: 9738, end: 9741 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9743, end: 9746 } + }, + loc: { start: 9743, end: 9746 } + }, + loc: { start: 9738, end: 9746 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'POW2' ] + }, + loc: { start: 9725, end: 9761 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sign', + loc: { start: 10233, end: 10237 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10247, end: 10250 } + }, + loc: { start: 10247, end: 10250 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 10238, end: 10239 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10241, end: 10244 } + }, + loc: { start: 10241, end: 10244 } + }, + loc: { start: 10238, end: 10244 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SGN' ] + }, + loc: { start: 10225, end: 10258 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'divc', + loc: { start: 10814, end: 10818 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10836, end: 10839 } + }, + loc: { start: 10836, end: 10839 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 10819, end: 10820 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10822, end: 10825 } + }, + loc: { start: 10822, end: 10825 } + }, + loc: { start: 10819, end: 10825 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 10827, end: 10828 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10830, end: 10833 } + }, + loc: { start: 10830, end: 10833 } + }, + loc: { start: 10827, end: 10833 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DIVC' ] + }, + loc: { start: 10806, end: 10848 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'muldivc', + loc: { start: 11615, end: 11622 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11648, end: 11651 } + }, + loc: { start: 11648, end: 11651 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 11623, end: 11624 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11626, end: 11629 } + }, + loc: { start: 11626, end: 11629 } + }, + loc: { start: 11623, end: 11629 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 11631, end: 11632 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11634, end: 11637 } + }, + loc: { start: 11634, end: 11637 } + }, + loc: { start: 11631, end: 11637 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 11639, end: 11640 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11642, end: 11645 } + }, + loc: { start: 11642, end: 11645 } + }, + loc: { start: 11639, end: 11645 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULDIVC' ] + }, + loc: { start: 11607, end: 11663 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRight', + loc: { start: 12751, end: 12764 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12790, end: 12793 } + }, + loc: { start: 12790, end: 12793 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 12765, end: 12766 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12768, end: 12771 } + }, + loc: { start: 12768, end: 12771 } + }, + loc: { start: 12765, end: 12771 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 12773, end: 12774 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12776, end: 12779 } + }, + loc: { start: 12776, end: 12779 } + }, + loc: { start: 12773, end: 12779 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 12781, end: 12782 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12784, end: 12787 } + }, + loc: { start: 12784, end: 12787 } + }, + loc: { start: 12781, end: 12787 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFT' ] + }, + loc: { start: 12743, end: 12807 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRightRound', + loc: { start: 13862, end: 13880 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13906, end: 13909 } + }, + loc: { start: 13906, end: 13909 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 13881, end: 13882 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13884, end: 13887 } + }, + loc: { start: 13884, end: 13887 } + }, + loc: { start: 13881, end: 13887 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 13889, end: 13890 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13892, end: 13895 } + }, + loc: { start: 13892, end: 13895 } + }, + loc: { start: 13889, end: 13895 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 13897, end: 13898 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13900, end: 13903 } + }, + loc: { start: 13900, end: 13903 } + }, + loc: { start: 13897, end: 13903 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFTR' ] + }, + loc: { start: 13854, end: 13924 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRightCeil', + loc: { start: 14875, end: 14892 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14918, end: 14921 } + }, + loc: { start: 14918, end: 14921 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 14893, end: 14894 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14896, end: 14899 } + }, + loc: { start: 14896, end: 14899 } + }, + loc: { start: 14893, end: 14899 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 14901, end: 14902 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14904, end: 14907 } + }, + loc: { start: 14904, end: 14907 } + }, + loc: { start: 14901, end: 14907 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 14909, end: 14910 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14912, end: 14915 } + }, + loc: { start: 14912, end: 14915 } + }, + loc: { start: 14909, end: 14915 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFTC' ] + }, + loc: { start: 14867, end: 14936 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sqrt', + loc: { start: 15698, end: 15702 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15714, end: 15717 } + }, + loc: { start: 15714, end: 15717 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 15703, end: 15706 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15708, end: 15711 } + }, + loc: { start: 15708, end: 15711 } + }, + loc: { start: 15703, end: 15711 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'num', + loc: { start: 15728, end: 15731 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15735, end: 15736 } + }, + loc: { start: 15728, end: 15736 } + }, + trueStatements: [ + { + kind: 'statement_return', + expression: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15755, end: 15756 } + }, + loc: { start: 15748, end: 15757 } + } + ], + falseStatements: undefined, + loc: { start: 15724, end: 15763 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 's', + loc: { start: 15773, end: 15774 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15776, end: 15779 } + }, + loc: { start: 15776, end: 15779 } + }, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'log2', + loc: { start: 15782, end: 15786 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'num', + loc: { start: 15787, end: 15790 } + } + ], + loc: { start: 15782, end: 15791 } + }, + loc: { start: 15769, end: 15792 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'x', + loc: { start: 15801, end: 15802 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15804, end: 15807 } + }, + loc: { start: 15804, end: 15807 } + }, + expression: { + kind: 'conditional', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 's', + loc: { start: 15811, end: 15812 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15816, end: 15817 } + }, + loc: { start: 15811, end: 15817 } + }, + thenBranch: { + kind: 'op_binary', + op: '+', + left: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'num', + loc: { start: 15821, end: 15824 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15827, end: 15828 } + }, + loc: { start: 15821, end: 15828 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15832, end: 15833 } + }, + loc: { start: 15820, end: 15833 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15836, end: 15837 } + }, + loc: { start: 15820, end: 15837 } + }, + elseBranch: { + kind: 'op_binary', + op: '<<', + left: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15840, end: 15841 } + }, + right: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '+', + left: { + kind: 'var', + name: 's', + loc: { start: 15847, end: 15848 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15851, end: 15852 } + }, + loc: { start: 15847, end: 15852 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15856, end: 15857 } + }, + loc: { start: 15846, end: 15857 } + }, + loc: { start: 15840, end: 15858 } + }, + loc: { start: 15811, end: 15858 } + }, + loc: { start: 15797, end: 15860 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'q', + loc: { start: 15870, end: 15871 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15873, end: 15876 } + }, + loc: { start: 15873, end: 15876 } + }, + expression: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15879, end: 15880 } + }, + loc: { start: 15866, end: 15881 } + }, + { + kind: 'statement_until', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'q', + loc: { start: 15957, end: 15958 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15962, end: 15963 } + }, + loc: { start: 15957, end: 15963 } + }, + statements: [ + { + kind: 'statement_assign', + path: { + kind: 'var', + name: 'q', + loc: { start: 15900, end: 15901 } + }, + expression: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '-', + left: { + kind: 'static_call', + function: { + kind: 'id', + text: 'divc', + loc: { start: 15905, end: 15909 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'num', + loc: { start: 15910, end: 15913 } + }, + { + kind: 'var', + name: 'x', + loc: { start: 15915, end: 15916 } + } + ], + loc: { start: 15905, end: 15917 } + }, + right: { + kind: 'var', + name: 'x', + loc: { start: 15920, end: 15921 } + }, + loc: { start: 15905, end: 15921 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15925, end: 15926 } + }, + loc: { start: 15904, end: 15926 } + }, + loc: { start: 15900, end: 15927 } + }, + { + kind: 'statement_augmentedassign', + op: '+=', + path: { + kind: 'var', + name: 'x', + loc: { start: 15936, end: 15937 } + }, + expression: { + kind: 'var', + name: 'q', + loc: { start: 15941, end: 15942 } + }, + loc: { start: 15936, end: 15943 } + } + ], + loc: { start: 15887, end: 15965 } + }, + { + kind: 'statement_return', + expression: { + kind: 'var', + name: 'x', + loc: { start: 15978, end: 15979 } + }, + loc: { start: 15971, end: 15980 } + } + ] + }, + loc: { start: 15694, end: 15982 } + } + ] + }, + 'pow' => { + kind: 'tact', + path: 'std/internal/math.tact', + code: '// Prepare random\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Randomizes the pseudorandom number generator with the specified unsigned 256-bit `Int` `x` by mixing it with the current seed. The new seed is the unsigned 256-bit `Int` value of the SHA-256 hash of concatenated old seed and `x` in their 32-byte strings big-endian representation.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativeRandomize(42); // now, random numbers are less predictable\n' + + "/// let idk: Int = randomInt(); // ???, it's random,\n" + + '/// // but the seed was adjusted deterministically!\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify a negative value of `x`.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomize\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun nativeRandomize(x: Int) { ADDRAND }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Randomizes the random number generator with the logical time of the current transaction. Equivalent to calling `nativeRandomize(curLt())`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativeRandomizeLt(); // now, random numbers are unpredictable for users,\n' + + '/// // but still may be affected by validators or collators\n' + + '/// // as they determine the seed of the current block.\n' + + "/// let idk: Int = randomInt(); // ???, it's random!\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomizelt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomize\n' + + '/// * https://docs.tact-lang.org/ref/core-contextstate#curlt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + 'asm fun nativeRandomizeLt() { LTIME ADDRAND }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Prepares a random number generator by using `nativeRandomizeLt()`. Automatically called by `randomInt()` and `random()` functions.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativePrepareRandom(); // prepare the RNG\n' + + '/// // ... do your random things ...\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativepreparerandom\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomizelt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '/// * https://docs.tact-lang.org/ref/core-random#random\n' + + '///\n' + + '@name(__tact_prepare_random)\n' + + 'native nativePrepareRandom();\n' + + '\n' + + '// Random\n' + + '\n' + + '// Generates a new pseudo-random unsigned 256-bit integer x.\n' + + '// The algorithm is as follows: if r is the old value of the random seed,\n' + + '// considered as a 32-byte array (by constructing the big-endian representation\n' + + '// of an unsigned 256-bit integer), then its sha512(r) is computed;\n' + + "// the first 32 bytes of this hash are stored as the new value r' of the random seed,\n" + + '// and the remaining 32 bytes are returned as the next random value x.\n' + + 'asm fun nativeRandom(): Int { RANDU256 }\n' + + '\n' + + '// Generates a new pseudo-random integer z in the range 0..range−1\n' + + '// (or range..−1, if range < 0).\n' + + '// More precisely, an unsigned random value x is generated as in `nativeRandom`;\n' + + '// then z := x * range / 2^256 is computed.\n' + + 'asm fun nativeRandomInterval(max: Int): Int { RAND }\n' + + '\n' + + '/// Generates and returns a new pseudo-random unsigned 256-bit `Int` value `x`.\n' + + '///\n' + + '/// The algorithm works as follows: first, the `sha512(r)` is computed. There, `r` is an old\n' + + '/// value of the random seed, which is taken as a 32-byte array constructed from the big-endian\n' + + '/// representation of an unsigned 256-bit `Int`. The first 32 bytes of this hash are stored as the new\n' + + "/// value `r'` of the random seed, and the remaining 32 bytes are returned as the next random value `x`.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + "/// let allYourRandomBelongToUs: Int = randomInt(); // ???, it's random :)\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + 'inline fun randomInt(): Int {\n' + + ' nativePrepareRandom();\n' + + ' return nativeRandom();\n' + + '}\n' + + '\n' + + '/// Generates and returns a new pseudo-random unsigned `Int` value `x` in the provided semi-closed\n' + + '/// interval: `min` ≤ `x` < `max`, or `min` ≥ `x` > `max` if both `min` and `max` are negative.\n' + + '///\n' + + '/// Note that the `max` value is never included in the interval.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// random(42, 43); // 42, always\n' + + '/// random(0, 42); // 0-41, but never 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-random#random\n' + + '///\n' + + 'inline fun random(min: Int, max: Int): Int {\n' + + ' nativePrepareRandom();\n' + + ' return min + nativeRandomInterval(max - min);\n' + + '}\n' + + '\n' + + '// Math\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the minimum of two `Int` values `x` and `y`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// min(1, 2); // 1\n' + + '/// min(2, 2); // 2\n' + + '/// min(007, 3); // 3\n' + + '/// min(0x45, 3_0_0); // 69, nice\n' + + '/// // ↑ ↑\n' + + '/// // 69 300\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#min\n' + + '///\n' + + 'asm fun min(x: Int, y: Int): Int { MIN }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the maximum of two `Int` values `x` and `y`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// max(1, 2); // 2\n' + + '/// max(2, 2); // 2\n' + + '/// max(007, 3); // 7\n' + + '/// max(0x45, 3_0_0); // 300\n' + + '/// // ↑ ↑\n' + + '/// // 69 300\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#max\n' + + '///\n' + + 'asm fun max(x: Int, y: Int): Int { MAX }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the absolute value of the `Int` value `x`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// abs(42); // 42\n' + + '/// abs(-42); // 42\n' + + '/// abs(-(-(-42))); // 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#abs\n' + + '///\n' + + 'asm fun abs(x: Int): Int { ABS }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the logarithm of a number `num` > 0 to the base `base` ≥ 1. Results are rounded down.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// log(1000, 10); // 3, as 10^3 is 1000\n' + + '/// // ↑ ↑ ↑ ↑\n' + + '/// // num base base num\n' + + '///\n' + + '/// log(1001, 10); // 3\n' + + '/// log(999, 10); // 2\n' + + '/// try {\n' + + '/// log(-1000, 10); // exit code 5 because of the non-positive num\n' + + '/// }\n' + + '/// log(1024, 2); // 10\n' + + '/// try {\n' + + '/// log(1024, -2); // exit code 5 because the base is less than 1\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `num` value is non-positive\n' + + '/// or the given `base` value is less than 1.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log2\n' + + '///\n' + + '@name(__tact_log)\n' + + 'native log(num: Int, base: Int): Int;\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Similar to `log()`, but sets the `base` to 2.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// log2(1024); // 10, as 2^10 is 1024\n' + + '/// // ↑ ↑ ↑\n' + + '/// // num base₂ num\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `num` value is non-positive.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log2\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log.\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes/#5\n' + + '///\n' + + 'asm fun log2(num: Int): Int { DUP 5 THROWIFNOT UBITSIZE DEC }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the exponentiation involving two numbers: the `base` and the exponent (or _power_) `exp`.\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Example {\n' + + '/// // Persistent state variables\n' + + '/// p23: Int = pow(2, 3); // raises 2 to the 3rd power, which is 8\n' + + '/// one: Int = pow(5, 0); // raises 5 to the power 0, which always produces 1\n' + + '/// // works at compile-time!\n' + + '///\n' + + '/// // Internal message receiver\n' + + '/// receive() {\n' + + '/// pow(self.p23, self.one + 1); // 64, works at run-time too!\n' + + '/// try {\n' + + '/// pow(0, -1); // exit code 5: Integer out of expected range\n' + + '/// }\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `exp` value is negative.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow2\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes/#5\n' + + '///\n' + + 'inline fun pow(base: Int, exp: Int): Int {\n' + + ' throwUnless(5, exp >= 0);\n' + + ' let result = 1;\n' + + ' repeat (exp) {\n' + + ' result *= base;\n' + + ' }\n' + + ' return result;\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Similar to `pow()`, but sets the `base` to 2.\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Example {\n' + + '/// // Persistent state variables\n' + + '/// p23: Int = pow2(3); // raises 2 to the 3rd power, which is 8\n' + + '/// one: Int = pow2(0); // raises 2 to the power 0, which always produces 1\n' + + '/// // works at compile-time!\n' + + '///\n' + + '/// // Internal message receiver, which accepts message ExtMsg\n' + + '/// receive() {\n' + + '/// pow2(self.one + 1); // 4, works at run-time too!\n' + + '/// try {\n' + + '/// pow(-1); // exit code 5: Integer out of expected range\n' + + '/// }\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify a negative value of `exp`.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow2\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun pow2(exp: Int): Int { POW2 }\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Computes and returns the sign of the `Int` value `x`. Produces 1 if the `x` is positive, -1 if the `x` is negative, and 0 if the `x` is 0.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// '... 5983 more characters, + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomize', + loc: { start: 965, end: 980 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { kind: 'id', text: 'x', loc: { start: 981, end: 982 } }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 984, end: 987 } + }, + loc: { start: 984, end: 987 } + }, + loc: { start: 981, end: 987 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ADDRAND' ] + }, + loc: { start: 957, end: 1000 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomizeLt', + loc: { start: 1822, end: 1839 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LTIME ADDRAND' ] + }, + loc: { start: 1814, end: 1859 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 2466, end: 2485 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_prepare_random', + loc: { start: 2436, end: 2457 } + } + }, + loc: { start: 2430, end: 2488 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandom', + loc: { start: 2949, end: 2961 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2965, end: 2968 } + }, + loc: { start: 2965, end: 2968 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RANDU256' ] + }, + loc: { start: 2941, end: 2981 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomInterval', + loc: { start: 3216, end: 3236 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3248, end: 3251 } + }, + loc: { start: 3248, end: 3251 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'max', + loc: { start: 3237, end: 3240 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3242, end: 3245 } + }, + loc: { start: 3242, end: 3245 } + }, + loc: { start: 3237, end: 3245 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RAND' ] + }, + loc: { start: 3208, end: 3260 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'randomInt', + loc: { start: 3953, end: 3962 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3966, end: 3969 } + }, + loc: { start: 3966, end: 3969 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 3976, end: 3995 } + }, + typeArgs: [], + args: [], + loc: { start: 3976, end: 3997 } + }, + loc: { start: 3976, end: 3998 } + }, + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativeRandom', + loc: { start: 4010, end: 4022 } + }, + typeArgs: [], + args: [], + loc: { start: 4010, end: 4024 } + }, + loc: { start: 4003, end: 4025 } + } + ] + }, + loc: { start: 3942, end: 4027 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'random', + loc: { start: 4505, end: 4511 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4533, end: 4536 } + }, + loc: { start: 4533, end: 4536 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'min', + loc: { start: 4512, end: 4515 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4517, end: 4520 } + }, + loc: { start: 4517, end: 4520 } + }, + loc: { start: 4512, end: 4520 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'max', + loc: { start: 4522, end: 4525 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4527, end: 4530 } + }, + loc: { start: 4527, end: 4530 } + }, + loc: { start: 4522, end: 4530 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 4543, end: 4562 } + }, + typeArgs: [], + args: [], + loc: { start: 4543, end: 4564 } + }, + loc: { start: 4543, end: 4565 } + }, + { + kind: 'statement_return', + expression: { + kind: 'op_binary', + op: '+', + left: { + kind: 'var', + name: 'min', + loc: { start: 4577, end: 4580 } + }, + right: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativeRandomInterval', + loc: { start: 4583, end: 4603 } + }, + typeArgs: [], + args: [ + { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'max', + loc: { start: 4604, end: 4607 } + }, + right: { + kind: 'var', + name: 'min', + loc: { start: 4610, end: 4613 } + }, + loc: { start: 4604, end: 4613 } + } + ], + loc: { start: 4583, end: 4614 } + }, + loc: { start: 4577, end: 4614 } + }, + loc: { start: 4570, end: 4615 } + } + ] + }, + loc: { start: 4494, end: 4617 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'min', loc: { start: 5017, end: 5020 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5038, end: 5041 } + }, + loc: { start: 5038, end: 5041 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5021, end: 5022 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5024, end: 5027 } + }, + loc: { start: 5024, end: 5027 } + }, + loc: { start: 5021, end: 5027 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 5029, end: 5030 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5032, end: 5035 } + }, + loc: { start: 5032, end: 5035 } + }, + loc: { start: 5029, end: 5035 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MIN' ] + }, + loc: { start: 5009, end: 5049 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'max', loc: { start: 5435, end: 5438 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5456, end: 5459 } + }, + loc: { start: 5456, end: 5459 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5439, end: 5440 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5442, end: 5445 } + }, + loc: { start: 5442, end: 5445 } + }, + loc: { start: 5439, end: 5445 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 5447, end: 5448 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5450, end: 5453 } + }, + loc: { start: 5450, end: 5453 } + }, + loc: { start: 5447, end: 5453 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MAX' ] + }, + loc: { start: 5427, end: 5467 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'abs', loc: { start: 5773, end: 5776 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5786, end: 5789 } + }, + loc: { start: 5786, end: 5789 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5777, end: 5778 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5780, end: 5783 } + }, + loc: { start: 5780, end: 5783 } + }, + loc: { start: 5777, end: 5783 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ABS' ] + }, + loc: { start: 5765, end: 5797 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'log', loc: { start: 6721, end: 6724 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6747, end: 6750 } + }, + loc: { start: 6747, end: 6750 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 6725, end: 6728 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6730, end: 6733 } + }, + loc: { start: 6730, end: 6733 } + }, + loc: { start: 6725, end: 6733 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'base', + loc: { start: 6735, end: 6739 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6741, end: 6744 } + }, + loc: { start: 6741, end: 6744 } + }, + loc: { start: 6735, end: 6744 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_log', + loc: { start: 6702, end: 6712 } + } + }, + loc: { start: 6696, end: 6751 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'log2', loc: { start: 7341, end: 7345 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7357, end: 7360 } + }, + loc: { start: 7357, end: 7360 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 7346, end: 7349 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7351, end: 7354 } + }, + loc: { start: 7351, end: 7354 } + }, + loc: { start: 7346, end: 7354 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DUP 5 THROWIFNOT UBITSIZE DEC' ] + }, + loc: { start: 7333, end: 7394 } + }, + { + kind: 'function', + inline: true, + name: { kind: 'id', text: 'pow', loc: { start: 8510, end: 8513 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8536, end: 8539 } + }, + loc: { start: 8536, end: 8539 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'base', + loc: { start: 8514, end: 8518 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8520, end: 8523 } + }, + loc: { start: 8520, end: 8523 } + }, + loc: { start: 8514, end: 8523 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'exp', + loc: { start: 8525, end: 8528 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8530, end: 8533 } + }, + loc: { start: 8530, end: 8533 } + }, + loc: { start: 8525, end: 8533 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throwUnless', + loc: { start: 8546, end: 8557 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 5n, + loc: { start: 8558, end: 8559 } + }, + { + kind: 'op_binary', + op: '>=', + left: { + kind: 'var', + name: 'exp', + loc: { start: 8561, end: 8564 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 8568, end: 8569 } + }, + loc: { start: 8561, end: 8569 } + } + ], + loc: { start: 8546, end: 8570 } + }, + loc: { start: 8546, end: 8571 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'result', + loc: { start: 8580, end: 8586 } + }, + type: undefined, + expression: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 8589, end: 8590 } + }, + loc: { start: 8576, end: 8591 } + }, + { + kind: 'statement_repeat', + iterations: { + kind: 'var', + name: 'exp', + loc: { start: 8604, end: 8607 } + }, + statements: [ + { + kind: 'statement_augmentedassign', + op: '*=', + path: { + kind: 'var', + name: 'result', + loc: { start: 8619, end: 8625 } + }, + expression: { + kind: 'var', + name: 'base', + loc: { start: 8629, end: 8633 } + }, + loc: { start: 8619, end: 8634 } + } + ], + loc: { start: 8596, end: 8640 } + }, + { + kind: 'statement_return', + expression: { + kind: 'var', + name: 'result', + loc: { start: 8652, end: 8658 } + }, + loc: { start: 8645, end: 8659 } + } + ] + }, + loc: { start: 8499, end: 8661 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'pow2', loc: { start: 9733, end: 9737 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9749, end: 9752 } + }, + loc: { start: 9749, end: 9752 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'exp', + loc: { start: 9738, end: 9741 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9743, end: 9746 } + }, + loc: { start: 9743, end: 9746 } + }, + loc: { start: 9738, end: 9746 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'POW2' ] + }, + loc: { start: 9725, end: 9761 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sign', + loc: { start: 10233, end: 10237 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10247, end: 10250 } + }, + loc: { start: 10247, end: 10250 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 10238, end: 10239 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10241, end: 10244 } + }, + loc: { start: 10241, end: 10244 } + }, + loc: { start: 10238, end: 10244 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SGN' ] + }, + loc: { start: 10225, end: 10258 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'divc', + loc: { start: 10814, end: 10818 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10836, end: 10839 } + }, + loc: { start: 10836, end: 10839 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 10819, end: 10820 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10822, end: 10825 } + }, + loc: { start: 10822, end: 10825 } + }, + loc: { start: 10819, end: 10825 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 10827, end: 10828 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10830, end: 10833 } + }, + loc: { start: 10830, end: 10833 } + }, + loc: { start: 10827, end: 10833 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DIVC' ] + }, + loc: { start: 10806, end: 10848 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'muldivc', + loc: { start: 11615, end: 11622 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11648, end: 11651 } + }, + loc: { start: 11648, end: 11651 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 11623, end: 11624 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11626, end: 11629 } + }, + loc: { start: 11626, end: 11629 } + }, + loc: { start: 11623, end: 11629 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 11631, end: 11632 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11634, end: 11637 } + }, + loc: { start: 11634, end: 11637 } + }, + loc: { start: 11631, end: 11637 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 11639, end: 11640 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11642, end: 11645 } + }, + loc: { start: 11642, end: 11645 } + }, + loc: { start: 11639, end: 11645 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULDIVC' ] + }, + loc: { start: 11607, end: 11663 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRight', + loc: { start: 12751, end: 12764 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12790, end: 12793 } + }, + loc: { start: 12790, end: 12793 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 12765, end: 12766 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12768, end: 12771 } + }, + loc: { start: 12768, end: 12771 } + }, + loc: { start: 12765, end: 12771 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 12773, end: 12774 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12776, end: 12779 } + }, + loc: { start: 12776, end: 12779 } + }, + loc: { start: 12773, end: 12779 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 12781, end: 12782 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12784, end: 12787 } + }, + loc: { start: 12784, end: 12787 } + }, + loc: { start: 12781, end: 12787 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFT' ] + }, + loc: { start: 12743, end: 12807 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRightRound', + loc: { start: 13862, end: 13880 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13906, end: 13909 } + }, + loc: { start: 13906, end: 13909 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 13881, end: 13882 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13884, end: 13887 } + }, + loc: { start: 13884, end: 13887 } + }, + loc: { start: 13881, end: 13887 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 13889, end: 13890 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13892, end: 13895 } + }, + loc: { start: 13892, end: 13895 } + }, + loc: { start: 13889, end: 13895 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 13897, end: 13898 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13900, end: 13903 } + }, + loc: { start: 13900, end: 13903 } + }, + loc: { start: 13897, end: 13903 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFTR' ] + }, + loc: { start: 13854, end: 13924 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRightCeil', + loc: { start: 14875, end: 14892 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14918, end: 14921 } + }, + loc: { start: 14918, end: 14921 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 14893, end: 14894 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14896, end: 14899 } + }, + loc: { start: 14896, end: 14899 } + }, + loc: { start: 14893, end: 14899 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 14901, end: 14902 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14904, end: 14907 } + }, + loc: { start: 14904, end: 14907 } + }, + loc: { start: 14901, end: 14907 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 14909, end: 14910 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14912, end: 14915 } + }, + loc: { start: 14912, end: 14915 } + }, + loc: { start: 14909, end: 14915 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFTC' ] + }, + loc: { start: 14867, end: 14936 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sqrt', + loc: { start: 15698, end: 15702 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15714, end: 15717 } + }, + loc: { start: 15714, end: 15717 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 15703, end: 15706 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15708, end: 15711 } + }, + loc: { start: 15708, end: 15711 } + }, + loc: { start: 15703, end: 15711 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'num', + loc: { start: 15728, end: 15731 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15735, end: 15736 } + }, + loc: { start: 15728, end: 15736 } + }, + trueStatements: [ + { + kind: 'statement_return', + expression: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15755, end: 15756 } + }, + loc: { start: 15748, end: 15757 } + } + ], + falseStatements: undefined, + loc: { start: 15724, end: 15763 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 's', + loc: { start: 15773, end: 15774 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15776, end: 15779 } + }, + loc: { start: 15776, end: 15779 } + }, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'log2', + loc: { start: 15782, end: 15786 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'num', + loc: { start: 15787, end: 15790 } + } + ], + loc: { start: 15782, end: 15791 } + }, + loc: { start: 15769, end: 15792 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'x', + loc: { start: 15801, end: 15802 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15804, end: 15807 } + }, + loc: { start: 15804, end: 15807 } + }, + expression: { + kind: 'conditional', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 's', + loc: { start: 15811, end: 15812 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15816, end: 15817 } + }, + loc: { start: 15811, end: 15817 } + }, + thenBranch: { + kind: 'op_binary', + op: '+', + left: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'num', + loc: { start: 15821, end: 15824 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15827, end: 15828 } + }, + loc: { start: 15821, end: 15828 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15832, end: 15833 } + }, + loc: { start: 15820, end: 15833 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15836, end: 15837 } + }, + loc: { start: 15820, end: 15837 } + }, + elseBranch: { + kind: 'op_binary', + op: '<<', + left: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15840, end: 15841 } + }, + right: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '+', + left: { + kind: 'var', + name: 's', + loc: { start: 15847, end: 15848 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15851, end: 15852 } + }, + loc: { start: 15847, end: 15852 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15856, end: 15857 } + }, + loc: { start: 15846, end: 15857 } + }, + loc: { start: 15840, end: 15858 } + }, + loc: { start: 15811, end: 15858 } + }, + loc: { start: 15797, end: 15860 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'q', + loc: { start: 15870, end: 15871 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15873, end: 15876 } + }, + loc: { start: 15873, end: 15876 } + }, + expression: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15879, end: 15880 } + }, + loc: { start: 15866, end: 15881 } + }, + { + kind: 'statement_until', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'q', + loc: { start: 15957, end: 15958 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15962, end: 15963 } + }, + loc: { start: 15957, end: 15963 } + }, + statements: [ + { + kind: 'statement_assign', + path: { + kind: 'var', + name: 'q', + loc: { start: 15900, end: 15901 } + }, + expression: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '-', + left: { + kind: 'static_call', + function: { + kind: 'id', + text: 'divc', + loc: { start: 15905, end: 15909 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'num', + loc: { start: 15910, end: 15913 } + }, + { + kind: 'var', + name: 'x', + loc: { start: 15915, end: 15916 } + } + ], + loc: { start: 15905, end: 15917 } + }, + right: { + kind: 'var', + name: 'x', + loc: { start: 15920, end: 15921 } + }, + loc: { start: 15905, end: 15921 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15925, end: 15926 } + }, + loc: { start: 15904, end: 15926 } + }, + loc: { start: 15900, end: 15927 } + }, + { + kind: 'statement_augmentedassign', + op: '+=', + path: { + kind: 'var', + name: 'x', + loc: { start: 15936, end: 15937 } + }, + expression: { + kind: 'var', + name: 'q', + loc: { start: 15941, end: 15942 } + }, + loc: { start: 15936, end: 15943 } + } + ], + loc: { start: 15887, end: 15965 } + }, + { + kind: 'statement_return', + expression: { + kind: 'var', + name: 'x', + loc: { start: 15978, end: 15979 } + }, + loc: { start: 15971, end: 15980 } + } + ] + }, + loc: { start: 15694, end: 15982 } + } + ] + }, + 'pow2' => { + kind: 'tact', + path: 'std/internal/math.tact', + code: '// Prepare random\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Randomizes the pseudorandom number generator with the specified unsigned 256-bit `Int` `x` by mixing it with the current seed. The new seed is the unsigned 256-bit `Int` value of the SHA-256 hash of concatenated old seed and `x` in their 32-byte strings big-endian representation.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativeRandomize(42); // now, random numbers are less predictable\n' + + "/// let idk: Int = randomInt(); // ???, it's random,\n" + + '/// // but the seed was adjusted deterministically!\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify a negative value of `x`.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomize\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun nativeRandomize(x: Int) { ADDRAND }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Randomizes the random number generator with the logical time of the current transaction. Equivalent to calling `nativeRandomize(curLt())`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativeRandomizeLt(); // now, random numbers are unpredictable for users,\n' + + '/// // but still may be affected by validators or collators\n' + + '/// // as they determine the seed of the current block.\n' + + "/// let idk: Int = randomInt(); // ???, it's random!\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomizelt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomize\n' + + '/// * https://docs.tact-lang.org/ref/core-contextstate#curlt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + 'asm fun nativeRandomizeLt() { LTIME ADDRAND }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Prepares a random number generator by using `nativeRandomizeLt()`. Automatically called by `randomInt()` and `random()` functions.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativePrepareRandom(); // prepare the RNG\n' + + '/// // ... do your random things ...\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativepreparerandom\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomizelt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '/// * https://docs.tact-lang.org/ref/core-random#random\n' + + '///\n' + + '@name(__tact_prepare_random)\n' + + 'native nativePrepareRandom();\n' + + '\n' + + '// Random\n' + + '\n' + + '// Generates a new pseudo-random unsigned 256-bit integer x.\n' + + '// The algorithm is as follows: if r is the old value of the random seed,\n' + + '// considered as a 32-byte array (by constructing the big-endian representation\n' + + '// of an unsigned 256-bit integer), then its sha512(r) is computed;\n' + + "// the first 32 bytes of this hash are stored as the new value r' of the random seed,\n" + + '// and the remaining 32 bytes are returned as the next random value x.\n' + + 'asm fun nativeRandom(): Int { RANDU256 }\n' + + '\n' + + '// Generates a new pseudo-random integer z in the range 0..range−1\n' + + '// (or range..−1, if range < 0).\n' + + '// More precisely, an unsigned random value x is generated as in `nativeRandom`;\n' + + '// then z := x * range / 2^256 is computed.\n' + + 'asm fun nativeRandomInterval(max: Int): Int { RAND }\n' + + '\n' + + '/// Generates and returns a new pseudo-random unsigned 256-bit `Int` value `x`.\n' + + '///\n' + + '/// The algorithm works as follows: first, the `sha512(r)` is computed. There, `r` is an old\n' + + '/// value of the random seed, which is taken as a 32-byte array constructed from the big-endian\n' + + '/// representation of an unsigned 256-bit `Int`. The first 32 bytes of this hash are stored as the new\n' + + "/// value `r'` of the random seed, and the remaining 32 bytes are returned as the next random value `x`.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + "/// let allYourRandomBelongToUs: Int = randomInt(); // ???, it's random :)\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + 'inline fun randomInt(): Int {\n' + + ' nativePrepareRandom();\n' + + ' return nativeRandom();\n' + + '}\n' + + '\n' + + '/// Generates and returns a new pseudo-random unsigned `Int` value `x` in the provided semi-closed\n' + + '/// interval: `min` ≤ `x` < `max`, or `min` ≥ `x` > `max` if both `min` and `max` are negative.\n' + + '///\n' + + '/// Note that the `max` value is never included in the interval.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// random(42, 43); // 42, always\n' + + '/// random(0, 42); // 0-41, but never 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-random#random\n' + + '///\n' + + 'inline fun random(min: Int, max: Int): Int {\n' + + ' nativePrepareRandom();\n' + + ' return min + nativeRandomInterval(max - min);\n' + + '}\n' + + '\n' + + '// Math\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the minimum of two `Int` values `x` and `y`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// min(1, 2); // 1\n' + + '/// min(2, 2); // 2\n' + + '/// min(007, 3); // 3\n' + + '/// min(0x45, 3_0_0); // 69, nice\n' + + '/// // ↑ ↑\n' + + '/// // 69 300\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#min\n' + + '///\n' + + 'asm fun min(x: Int, y: Int): Int { MIN }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the maximum of two `Int` values `x` and `y`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// max(1, 2); // 2\n' + + '/// max(2, 2); // 2\n' + + '/// max(007, 3); // 7\n' + + '/// max(0x45, 3_0_0); // 300\n' + + '/// // ↑ ↑\n' + + '/// // 69 300\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#max\n' + + '///\n' + + 'asm fun max(x: Int, y: Int): Int { MAX }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the absolute value of the `Int` value `x`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// abs(42); // 42\n' + + '/// abs(-42); // 42\n' + + '/// abs(-(-(-42))); // 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#abs\n' + + '///\n' + + 'asm fun abs(x: Int): Int { ABS }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the logarithm of a number `num` > 0 to the base `base` ≥ 1. Results are rounded down.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// log(1000, 10); // 3, as 10^3 is 1000\n' + + '/// // ↑ ↑ ↑ ↑\n' + + '/// // num base base num\n' + + '///\n' + + '/// log(1001, 10); // 3\n' + + '/// log(999, 10); // 2\n' + + '/// try {\n' + + '/// log(-1000, 10); // exit code 5 because of the non-positive num\n' + + '/// }\n' + + '/// log(1024, 2); // 10\n' + + '/// try {\n' + + '/// log(1024, -2); // exit code 5 because the base is less than 1\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `num` value is non-positive\n' + + '/// or the given `base` value is less than 1.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log2\n' + + '///\n' + + '@name(__tact_log)\n' + + 'native log(num: Int, base: Int): Int;\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Similar to `log()`, but sets the `base` to 2.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// log2(1024); // 10, as 2^10 is 1024\n' + + '/// // ↑ ↑ ↑\n' + + '/// // num base₂ num\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `num` value is non-positive.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log2\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log.\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes/#5\n' + + '///\n' + + 'asm fun log2(num: Int): Int { DUP 5 THROWIFNOT UBITSIZE DEC }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the exponentiation involving two numbers: the `base` and the exponent (or _power_) `exp`.\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Example {\n' + + '/// // Persistent state variables\n' + + '/// p23: Int = pow(2, 3); // raises 2 to the 3rd power, which is 8\n' + + '/// one: Int = pow(5, 0); // raises 5 to the power 0, which always produces 1\n' + + '/// // works at compile-time!\n' + + '///\n' + + '/// // Internal message receiver\n' + + '/// receive() {\n' + + '/// pow(self.p23, self.one + 1); // 64, works at run-time too!\n' + + '/// try {\n' + + '/// pow(0, -1); // exit code 5: Integer out of expected range\n' + + '/// }\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `exp` value is negative.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow2\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes/#5\n' + + '///\n' + + 'inline fun pow(base: Int, exp: Int): Int {\n' + + ' throwUnless(5, exp >= 0);\n' + + ' let result = 1;\n' + + ' repeat (exp) {\n' + + ' result *= base;\n' + + ' }\n' + + ' return result;\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Similar to `pow()`, but sets the `base` to 2.\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Example {\n' + + '/// // Persistent state variables\n' + + '/// p23: Int = pow2(3); // raises 2 to the 3rd power, which is 8\n' + + '/// one: Int = pow2(0); // raises 2 to the power 0, which always produces 1\n' + + '/// // works at compile-time!\n' + + '///\n' + + '/// // Internal message receiver, which accepts message ExtMsg\n' + + '/// receive() {\n' + + '/// pow2(self.one + 1); // 4, works at run-time too!\n' + + '/// try {\n' + + '/// pow(-1); // exit code 5: Integer out of expected range\n' + + '/// }\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify a negative value of `exp`.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow2\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun pow2(exp: Int): Int { POW2 }\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Computes and returns the sign of the `Int` value `x`. Produces 1 if the `x` is positive, -1 if the `x` is negative, and 0 if the `x` is 0.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// '... 5983 more characters, + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomize', + loc: { start: 965, end: 980 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { kind: 'id', text: 'x', loc: { start: 981, end: 982 } }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 984, end: 987 } + }, + loc: { start: 984, end: 987 } + }, + loc: { start: 981, end: 987 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ADDRAND' ] + }, + loc: { start: 957, end: 1000 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomizeLt', + loc: { start: 1822, end: 1839 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LTIME ADDRAND' ] + }, + loc: { start: 1814, end: 1859 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 2466, end: 2485 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_prepare_random', + loc: { start: 2436, end: 2457 } + } + }, + loc: { start: 2430, end: 2488 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandom', + loc: { start: 2949, end: 2961 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2965, end: 2968 } + }, + loc: { start: 2965, end: 2968 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RANDU256' ] + }, + loc: { start: 2941, end: 2981 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomInterval', + loc: { start: 3216, end: 3236 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3248, end: 3251 } + }, + loc: { start: 3248, end: 3251 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'max', + loc: { start: 3237, end: 3240 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3242, end: 3245 } + }, + loc: { start: 3242, end: 3245 } + }, + loc: { start: 3237, end: 3245 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RAND' ] + }, + loc: { start: 3208, end: 3260 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'randomInt', + loc: { start: 3953, end: 3962 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3966, end: 3969 } + }, + loc: { start: 3966, end: 3969 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 3976, end: 3995 } + }, + typeArgs: [], + args: [], + loc: { start: 3976, end: 3997 } + }, + loc: { start: 3976, end: 3998 } + }, + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativeRandom', + loc: { start: 4010, end: 4022 } + }, + typeArgs: [], + args: [], + loc: { start: 4010, end: 4024 } + }, + loc: { start: 4003, end: 4025 } + } + ] + }, + loc: { start: 3942, end: 4027 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'random', + loc: { start: 4505, end: 4511 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4533, end: 4536 } + }, + loc: { start: 4533, end: 4536 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'min', + loc: { start: 4512, end: 4515 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4517, end: 4520 } + }, + loc: { start: 4517, end: 4520 } + }, + loc: { start: 4512, end: 4520 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'max', + loc: { start: 4522, end: 4525 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4527, end: 4530 } + }, + loc: { start: 4527, end: 4530 } + }, + loc: { start: 4522, end: 4530 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 4543, end: 4562 } + }, + typeArgs: [], + args: [], + loc: { start: 4543, end: 4564 } + }, + loc: { start: 4543, end: 4565 } + }, + { + kind: 'statement_return', + expression: { + kind: 'op_binary', + op: '+', + left: { + kind: 'var', + name: 'min', + loc: { start: 4577, end: 4580 } + }, + right: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativeRandomInterval', + loc: { start: 4583, end: 4603 } + }, + typeArgs: [], + args: [ + { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'max', + loc: { start: 4604, end: 4607 } + }, + right: { + kind: 'var', + name: 'min', + loc: { start: 4610, end: 4613 } + }, + loc: { start: 4604, end: 4613 } + } + ], + loc: { start: 4583, end: 4614 } + }, + loc: { start: 4577, end: 4614 } + }, + loc: { start: 4570, end: 4615 } + } + ] + }, + loc: { start: 4494, end: 4617 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'min', loc: { start: 5017, end: 5020 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5038, end: 5041 } + }, + loc: { start: 5038, end: 5041 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5021, end: 5022 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5024, end: 5027 } + }, + loc: { start: 5024, end: 5027 } + }, + loc: { start: 5021, end: 5027 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 5029, end: 5030 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5032, end: 5035 } + }, + loc: { start: 5032, end: 5035 } + }, + loc: { start: 5029, end: 5035 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MIN' ] + }, + loc: { start: 5009, end: 5049 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'max', loc: { start: 5435, end: 5438 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5456, end: 5459 } + }, + loc: { start: 5456, end: 5459 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5439, end: 5440 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5442, end: 5445 } + }, + loc: { start: 5442, end: 5445 } + }, + loc: { start: 5439, end: 5445 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 5447, end: 5448 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5450, end: 5453 } + }, + loc: { start: 5450, end: 5453 } + }, + loc: { start: 5447, end: 5453 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MAX' ] + }, + loc: { start: 5427, end: 5467 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'abs', loc: { start: 5773, end: 5776 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5786, end: 5789 } + }, + loc: { start: 5786, end: 5789 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5777, end: 5778 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5780, end: 5783 } + }, + loc: { start: 5780, end: 5783 } + }, + loc: { start: 5777, end: 5783 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ABS' ] + }, + loc: { start: 5765, end: 5797 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'log', loc: { start: 6721, end: 6724 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6747, end: 6750 } + }, + loc: { start: 6747, end: 6750 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 6725, end: 6728 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6730, end: 6733 } + }, + loc: { start: 6730, end: 6733 } + }, + loc: { start: 6725, end: 6733 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'base', + loc: { start: 6735, end: 6739 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6741, end: 6744 } + }, + loc: { start: 6741, end: 6744 } + }, + loc: { start: 6735, end: 6744 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_log', + loc: { start: 6702, end: 6712 } + } + }, + loc: { start: 6696, end: 6751 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'log2', loc: { start: 7341, end: 7345 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7357, end: 7360 } + }, + loc: { start: 7357, end: 7360 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 7346, end: 7349 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7351, end: 7354 } + }, + loc: { start: 7351, end: 7354 } + }, + loc: { start: 7346, end: 7354 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DUP 5 THROWIFNOT UBITSIZE DEC' ] + }, + loc: { start: 7333, end: 7394 } + }, + { + kind: 'function', + inline: true, + name: { kind: 'id', text: 'pow', loc: { start: 8510, end: 8513 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8536, end: 8539 } + }, + loc: { start: 8536, end: 8539 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'base', + loc: { start: 8514, end: 8518 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8520, end: 8523 } + }, + loc: { start: 8520, end: 8523 } + }, + loc: { start: 8514, end: 8523 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'exp', + loc: { start: 8525, end: 8528 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8530, end: 8533 } + }, + loc: { start: 8530, end: 8533 } + }, + loc: { start: 8525, end: 8533 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throwUnless', + loc: { start: 8546, end: 8557 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 5n, + loc: { start: 8558, end: 8559 } + }, + { + kind: 'op_binary', + op: '>=', + left: { + kind: 'var', + name: 'exp', + loc: { start: 8561, end: 8564 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 8568, end: 8569 } + }, + loc: { start: 8561, end: 8569 } + } + ], + loc: { start: 8546, end: 8570 } + }, + loc: { start: 8546, end: 8571 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'result', + loc: { start: 8580, end: 8586 } + }, + type: undefined, + expression: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 8589, end: 8590 } + }, + loc: { start: 8576, end: 8591 } + }, + { + kind: 'statement_repeat', + iterations: { + kind: 'var', + name: 'exp', + loc: { start: 8604, end: 8607 } + }, + statements: [ + { + kind: 'statement_augmentedassign', + op: '*=', + path: { + kind: 'var', + name: 'result', + loc: { start: 8619, end: 8625 } + }, + expression: { + kind: 'var', + name: 'base', + loc: { start: 8629, end: 8633 } + }, + loc: { start: 8619, end: 8634 } + } + ], + loc: { start: 8596, end: 8640 } + }, + { + kind: 'statement_return', + expression: { + kind: 'var', + name: 'result', + loc: { start: 8652, end: 8658 } + }, + loc: { start: 8645, end: 8659 } + } + ] + }, + loc: { start: 8499, end: 8661 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'pow2', loc: { start: 9733, end: 9737 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9749, end: 9752 } + }, + loc: { start: 9749, end: 9752 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'exp', + loc: { start: 9738, end: 9741 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9743, end: 9746 } + }, + loc: { start: 9743, end: 9746 } + }, + loc: { start: 9738, end: 9746 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'POW2' ] + }, + loc: { start: 9725, end: 9761 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sign', + loc: { start: 10233, end: 10237 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10247, end: 10250 } + }, + loc: { start: 10247, end: 10250 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 10238, end: 10239 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10241, end: 10244 } + }, + loc: { start: 10241, end: 10244 } + }, + loc: { start: 10238, end: 10244 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SGN' ] + }, + loc: { start: 10225, end: 10258 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'divc', + loc: { start: 10814, end: 10818 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10836, end: 10839 } + }, + loc: { start: 10836, end: 10839 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 10819, end: 10820 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10822, end: 10825 } + }, + loc: { start: 10822, end: 10825 } + }, + loc: { start: 10819, end: 10825 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 10827, end: 10828 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10830, end: 10833 } + }, + loc: { start: 10830, end: 10833 } + }, + loc: { start: 10827, end: 10833 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DIVC' ] + }, + loc: { start: 10806, end: 10848 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'muldivc', + loc: { start: 11615, end: 11622 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11648, end: 11651 } + }, + loc: { start: 11648, end: 11651 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 11623, end: 11624 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11626, end: 11629 } + }, + loc: { start: 11626, end: 11629 } + }, + loc: { start: 11623, end: 11629 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 11631, end: 11632 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11634, end: 11637 } + }, + loc: { start: 11634, end: 11637 } + }, + loc: { start: 11631, end: 11637 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 11639, end: 11640 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11642, end: 11645 } + }, + loc: { start: 11642, end: 11645 } + }, + loc: { start: 11639, end: 11645 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULDIVC' ] + }, + loc: { start: 11607, end: 11663 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRight', + loc: { start: 12751, end: 12764 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12790, end: 12793 } + }, + loc: { start: 12790, end: 12793 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 12765, end: 12766 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12768, end: 12771 } + }, + loc: { start: 12768, end: 12771 } + }, + loc: { start: 12765, end: 12771 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 12773, end: 12774 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12776, end: 12779 } + }, + loc: { start: 12776, end: 12779 } + }, + loc: { start: 12773, end: 12779 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 12781, end: 12782 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12784, end: 12787 } + }, + loc: { start: 12784, end: 12787 } + }, + loc: { start: 12781, end: 12787 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFT' ] + }, + loc: { start: 12743, end: 12807 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRightRound', + loc: { start: 13862, end: 13880 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13906, end: 13909 } + }, + loc: { start: 13906, end: 13909 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 13881, end: 13882 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13884, end: 13887 } + }, + loc: { start: 13884, end: 13887 } + }, + loc: { start: 13881, end: 13887 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 13889, end: 13890 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13892, end: 13895 } + }, + loc: { start: 13892, end: 13895 } + }, + loc: { start: 13889, end: 13895 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 13897, end: 13898 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13900, end: 13903 } + }, + loc: { start: 13900, end: 13903 } + }, + loc: { start: 13897, end: 13903 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFTR' ] + }, + loc: { start: 13854, end: 13924 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRightCeil', + loc: { start: 14875, end: 14892 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14918, end: 14921 } + }, + loc: { start: 14918, end: 14921 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 14893, end: 14894 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14896, end: 14899 } + }, + loc: { start: 14896, end: 14899 } + }, + loc: { start: 14893, end: 14899 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 14901, end: 14902 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14904, end: 14907 } + }, + loc: { start: 14904, end: 14907 } + }, + loc: { start: 14901, end: 14907 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 14909, end: 14910 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14912, end: 14915 } + }, + loc: { start: 14912, end: 14915 } + }, + loc: { start: 14909, end: 14915 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFTC' ] + }, + loc: { start: 14867, end: 14936 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sqrt', + loc: { start: 15698, end: 15702 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15714, end: 15717 } + }, + loc: { start: 15714, end: 15717 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 15703, end: 15706 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15708, end: 15711 } + }, + loc: { start: 15708, end: 15711 } + }, + loc: { start: 15703, end: 15711 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'num', + loc: { start: 15728, end: 15731 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15735, end: 15736 } + }, + loc: { start: 15728, end: 15736 } + }, + trueStatements: [ + { + kind: 'statement_return', + expression: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15755, end: 15756 } + }, + loc: { start: 15748, end: 15757 } + } + ], + falseStatements: undefined, + loc: { start: 15724, end: 15763 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 's', + loc: { start: 15773, end: 15774 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15776, end: 15779 } + }, + loc: { start: 15776, end: 15779 } + }, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'log2', + loc: { start: 15782, end: 15786 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'num', + loc: { start: 15787, end: 15790 } + } + ], + loc: { start: 15782, end: 15791 } + }, + loc: { start: 15769, end: 15792 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'x', + loc: { start: 15801, end: 15802 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15804, end: 15807 } + }, + loc: { start: 15804, end: 15807 } + }, + expression: { + kind: 'conditional', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 's', + loc: { start: 15811, end: 15812 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15816, end: 15817 } + }, + loc: { start: 15811, end: 15817 } + }, + thenBranch: { + kind: 'op_binary', + op: '+', + left: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'num', + loc: { start: 15821, end: 15824 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15827, end: 15828 } + }, + loc: { start: 15821, end: 15828 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15832, end: 15833 } + }, + loc: { start: 15820, end: 15833 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15836, end: 15837 } + }, + loc: { start: 15820, end: 15837 } + }, + elseBranch: { + kind: 'op_binary', + op: '<<', + left: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15840, end: 15841 } + }, + right: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '+', + left: { + kind: 'var', + name: 's', + loc: { start: 15847, end: 15848 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15851, end: 15852 } + }, + loc: { start: 15847, end: 15852 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15856, end: 15857 } + }, + loc: { start: 15846, end: 15857 } + }, + loc: { start: 15840, end: 15858 } + }, + loc: { start: 15811, end: 15858 } + }, + loc: { start: 15797, end: 15860 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'q', + loc: { start: 15870, end: 15871 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15873, end: 15876 } + }, + loc: { start: 15873, end: 15876 } + }, + expression: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15879, end: 15880 } + }, + loc: { start: 15866, end: 15881 } + }, + { + kind: 'statement_until', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'q', + loc: { start: 15957, end: 15958 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15962, end: 15963 } + }, + loc: { start: 15957, end: 15963 } + }, + statements: [ + { + kind: 'statement_assign', + path: { + kind: 'var', + name: 'q', + loc: { start: 15900, end: 15901 } + }, + expression: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '-', + left: { + kind: 'static_call', + function: { + kind: 'id', + text: 'divc', + loc: { start: 15905, end: 15909 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'num', + loc: { start: 15910, end: 15913 } + }, + { + kind: 'var', + name: 'x', + loc: { start: 15915, end: 15916 } + } + ], + loc: { start: 15905, end: 15917 } + }, + right: { + kind: 'var', + name: 'x', + loc: { start: 15920, end: 15921 } + }, + loc: { start: 15905, end: 15921 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15925, end: 15926 } + }, + loc: { start: 15904, end: 15926 } + }, + loc: { start: 15900, end: 15927 } + }, + { + kind: 'statement_augmentedassign', + op: '+=', + path: { + kind: 'var', + name: 'x', + loc: { start: 15936, end: 15937 } + }, + expression: { + kind: 'var', + name: 'q', + loc: { start: 15941, end: 15942 } + }, + loc: { start: 15936, end: 15943 } + } + ], + loc: { start: 15887, end: 15965 } + }, + { + kind: 'statement_return', + expression: { + kind: 'var', + name: 'x', + loc: { start: 15978, end: 15979 } + }, + loc: { start: 15971, end: 15980 } + } + ] + }, + loc: { start: 15694, end: 15982 } + } + ] + }, + 'sign' => { + kind: 'tact', + path: 'std/internal/math.tact', + code: '// Prepare random\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Randomizes the pseudorandom number generator with the specified unsigned 256-bit `Int` `x` by mixing it with the current seed. The new seed is the unsigned 256-bit `Int` value of the SHA-256 hash of concatenated old seed and `x` in their 32-byte strings big-endian representation.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativeRandomize(42); // now, random numbers are less predictable\n' + + "/// let idk: Int = randomInt(); // ???, it's random,\n" + + '/// // but the seed was adjusted deterministically!\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify a negative value of `x`.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomize\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun nativeRandomize(x: Int) { ADDRAND }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Randomizes the random number generator with the logical time of the current transaction. Equivalent to calling `nativeRandomize(curLt())`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativeRandomizeLt(); // now, random numbers are unpredictable for users,\n' + + '/// // but still may be affected by validators or collators\n' + + '/// // as they determine the seed of the current block.\n' + + "/// let idk: Int = randomInt(); // ???, it's random!\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomizelt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomize\n' + + '/// * https://docs.tact-lang.org/ref/core-contextstate#curlt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + 'asm fun nativeRandomizeLt() { LTIME ADDRAND }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Prepares a random number generator by using `nativeRandomizeLt()`. Automatically called by `randomInt()` and `random()` functions.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativePrepareRandom(); // prepare the RNG\n' + + '/// // ... do your random things ...\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativepreparerandom\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomizelt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '/// * https://docs.tact-lang.org/ref/core-random#random\n' + + '///\n' + + '@name(__tact_prepare_random)\n' + + 'native nativePrepareRandom();\n' + + '\n' + + '// Random\n' + + '\n' + + '// Generates a new pseudo-random unsigned 256-bit integer x.\n' + + '// The algorithm is as follows: if r is the old value of the random seed,\n' + + '// considered as a 32-byte array (by constructing the big-endian representation\n' + + '// of an unsigned 256-bit integer), then its sha512(r) is computed;\n' + + "// the first 32 bytes of this hash are stored as the new value r' of the random seed,\n" + + '// and the remaining 32 bytes are returned as the next random value x.\n' + + 'asm fun nativeRandom(): Int { RANDU256 }\n' + + '\n' + + '// Generates a new pseudo-random integer z in the range 0..range−1\n' + + '// (or range..−1, if range < 0).\n' + + '// More precisely, an unsigned random value x is generated as in `nativeRandom`;\n' + + '// then z := x * range / 2^256 is computed.\n' + + 'asm fun nativeRandomInterval(max: Int): Int { RAND }\n' + + '\n' + + '/// Generates and returns a new pseudo-random unsigned 256-bit `Int` value `x`.\n' + + '///\n' + + '/// The algorithm works as follows: first, the `sha512(r)` is computed. There, `r` is an old\n' + + '/// value of the random seed, which is taken as a 32-byte array constructed from the big-endian\n' + + '/// representation of an unsigned 256-bit `Int`. The first 32 bytes of this hash are stored as the new\n' + + "/// value `r'` of the random seed, and the remaining 32 bytes are returned as the next random value `x`.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + "/// let allYourRandomBelongToUs: Int = randomInt(); // ???, it's random :)\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + 'inline fun randomInt(): Int {\n' + + ' nativePrepareRandom();\n' + + ' return nativeRandom();\n' + + '}\n' + + '\n' + + '/// Generates and returns a new pseudo-random unsigned `Int` value `x` in the provided semi-closed\n' + + '/// interval: `min` ≤ `x` < `max`, or `min` ≥ `x` > `max` if both `min` and `max` are negative.\n' + + '///\n' + + '/// Note that the `max` value is never included in the interval.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// random(42, 43); // 42, always\n' + + '/// random(0, 42); // 0-41, but never 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-random#random\n' + + '///\n' + + 'inline fun random(min: Int, max: Int): Int {\n' + + ' nativePrepareRandom();\n' + + ' return min + nativeRandomInterval(max - min);\n' + + '}\n' + + '\n' + + '// Math\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the minimum of two `Int` values `x` and `y`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// min(1, 2); // 1\n' + + '/// min(2, 2); // 2\n' + + '/// min(007, 3); // 3\n' + + '/// min(0x45, 3_0_0); // 69, nice\n' + + '/// // ↑ ↑\n' + + '/// // 69 300\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#min\n' + + '///\n' + + 'asm fun min(x: Int, y: Int): Int { MIN }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the maximum of two `Int` values `x` and `y`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// max(1, 2); // 2\n' + + '/// max(2, 2); // 2\n' + + '/// max(007, 3); // 7\n' + + '/// max(0x45, 3_0_0); // 300\n' + + '/// // ↑ ↑\n' + + '/// // 69 300\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#max\n' + + '///\n' + + 'asm fun max(x: Int, y: Int): Int { MAX }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the absolute value of the `Int` value `x`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// abs(42); // 42\n' + + '/// abs(-42); // 42\n' + + '/// abs(-(-(-42))); // 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#abs\n' + + '///\n' + + 'asm fun abs(x: Int): Int { ABS }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the logarithm of a number `num` > 0 to the base `base` ≥ 1. Results are rounded down.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// log(1000, 10); // 3, as 10^3 is 1000\n' + + '/// // ↑ ↑ ↑ ↑\n' + + '/// // num base base num\n' + + '///\n' + + '/// log(1001, 10); // 3\n' + + '/// log(999, 10); // 2\n' + + '/// try {\n' + + '/// log(-1000, 10); // exit code 5 because of the non-positive num\n' + + '/// }\n' + + '/// log(1024, 2); // 10\n' + + '/// try {\n' + + '/// log(1024, -2); // exit code 5 because the base is less than 1\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `num` value is non-positive\n' + + '/// or the given `base` value is less than 1.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log2\n' + + '///\n' + + '@name(__tact_log)\n' + + 'native log(num: Int, base: Int): Int;\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Similar to `log()`, but sets the `base` to 2.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// log2(1024); // 10, as 2^10 is 1024\n' + + '/// // ↑ ↑ ↑\n' + + '/// // num base₂ num\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `num` value is non-positive.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log2\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log.\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes/#5\n' + + '///\n' + + 'asm fun log2(num: Int): Int { DUP 5 THROWIFNOT UBITSIZE DEC }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the exponentiation involving two numbers: the `base` and the exponent (or _power_) `exp`.\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Example {\n' + + '/// // Persistent state variables\n' + + '/// p23: Int = pow(2, 3); // raises 2 to the 3rd power, which is 8\n' + + '/// one: Int = pow(5, 0); // raises 5 to the power 0, which always produces 1\n' + + '/// // works at compile-time!\n' + + '///\n' + + '/// // Internal message receiver\n' + + '/// receive() {\n' + + '/// pow(self.p23, self.one + 1); // 64, works at run-time too!\n' + + '/// try {\n' + + '/// pow(0, -1); // exit code 5: Integer out of expected range\n' + + '/// }\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `exp` value is negative.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow2\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes/#5\n' + + '///\n' + + 'inline fun pow(base: Int, exp: Int): Int {\n' + + ' throwUnless(5, exp >= 0);\n' + + ' let result = 1;\n' + + ' repeat (exp) {\n' + + ' result *= base;\n' + + ' }\n' + + ' return result;\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Similar to `pow()`, but sets the `base` to 2.\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Example {\n' + + '/// // Persistent state variables\n' + + '/// p23: Int = pow2(3); // raises 2 to the 3rd power, which is 8\n' + + '/// one: Int = pow2(0); // raises 2 to the power 0, which always produces 1\n' + + '/// // works at compile-time!\n' + + '///\n' + + '/// // Internal message receiver, which accepts message ExtMsg\n' + + '/// receive() {\n' + + '/// pow2(self.one + 1); // 4, works at run-time too!\n' + + '/// try {\n' + + '/// pow(-1); // exit code 5: Integer out of expected range\n' + + '/// }\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify a negative value of `exp`.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow2\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun pow2(exp: Int): Int { POW2 }\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Computes and returns the sign of the `Int` value `x`. Produces 1 if the `x` is positive, -1 if the `x` is negative, and 0 if the `x` is 0.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// '... 5983 more characters, + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomize', + loc: { start: 965, end: 980 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { kind: 'id', text: 'x', loc: { start: 981, end: 982 } }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 984, end: 987 } + }, + loc: { start: 984, end: 987 } + }, + loc: { start: 981, end: 987 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ADDRAND' ] + }, + loc: { start: 957, end: 1000 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomizeLt', + loc: { start: 1822, end: 1839 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LTIME ADDRAND' ] + }, + loc: { start: 1814, end: 1859 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 2466, end: 2485 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_prepare_random', + loc: { start: 2436, end: 2457 } + } + }, + loc: { start: 2430, end: 2488 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandom', + loc: { start: 2949, end: 2961 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2965, end: 2968 } + }, + loc: { start: 2965, end: 2968 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RANDU256' ] + }, + loc: { start: 2941, end: 2981 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomInterval', + loc: { start: 3216, end: 3236 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3248, end: 3251 } + }, + loc: { start: 3248, end: 3251 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'max', + loc: { start: 3237, end: 3240 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3242, end: 3245 } + }, + loc: { start: 3242, end: 3245 } + }, + loc: { start: 3237, end: 3245 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RAND' ] + }, + loc: { start: 3208, end: 3260 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'randomInt', + loc: { start: 3953, end: 3962 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3966, end: 3969 } + }, + loc: { start: 3966, end: 3969 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 3976, end: 3995 } + }, + typeArgs: [], + args: [], + loc: { start: 3976, end: 3997 } + }, + loc: { start: 3976, end: 3998 } + }, + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativeRandom', + loc: { start: 4010, end: 4022 } + }, + typeArgs: [], + args: [], + loc: { start: 4010, end: 4024 } + }, + loc: { start: 4003, end: 4025 } + } + ] + }, + loc: { start: 3942, end: 4027 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'random', + loc: { start: 4505, end: 4511 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4533, end: 4536 } + }, + loc: { start: 4533, end: 4536 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'min', + loc: { start: 4512, end: 4515 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4517, end: 4520 } + }, + loc: { start: 4517, end: 4520 } + }, + loc: { start: 4512, end: 4520 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'max', + loc: { start: 4522, end: 4525 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4527, end: 4530 } + }, + loc: { start: 4527, end: 4530 } + }, + loc: { start: 4522, end: 4530 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 4543, end: 4562 } + }, + typeArgs: [], + args: [], + loc: { start: 4543, end: 4564 } + }, + loc: { start: 4543, end: 4565 } + }, + { + kind: 'statement_return', + expression: { + kind: 'op_binary', + op: '+', + left: { + kind: 'var', + name: 'min', + loc: { start: 4577, end: 4580 } + }, + right: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativeRandomInterval', + loc: { start: 4583, end: 4603 } + }, + typeArgs: [], + args: [ + { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'max', + loc: { start: 4604, end: 4607 } + }, + right: { + kind: 'var', + name: 'min', + loc: { start: 4610, end: 4613 } + }, + loc: { start: 4604, end: 4613 } + } + ], + loc: { start: 4583, end: 4614 } + }, + loc: { start: 4577, end: 4614 } + }, + loc: { start: 4570, end: 4615 } + } + ] + }, + loc: { start: 4494, end: 4617 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'min', loc: { start: 5017, end: 5020 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5038, end: 5041 } + }, + loc: { start: 5038, end: 5041 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5021, end: 5022 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5024, end: 5027 } + }, + loc: { start: 5024, end: 5027 } + }, + loc: { start: 5021, end: 5027 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 5029, end: 5030 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5032, end: 5035 } + }, + loc: { start: 5032, end: 5035 } + }, + loc: { start: 5029, end: 5035 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MIN' ] + }, + loc: { start: 5009, end: 5049 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'max', loc: { start: 5435, end: 5438 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5456, end: 5459 } + }, + loc: { start: 5456, end: 5459 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5439, end: 5440 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5442, end: 5445 } + }, + loc: { start: 5442, end: 5445 } + }, + loc: { start: 5439, end: 5445 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 5447, end: 5448 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5450, end: 5453 } + }, + loc: { start: 5450, end: 5453 } + }, + loc: { start: 5447, end: 5453 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MAX' ] + }, + loc: { start: 5427, end: 5467 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'abs', loc: { start: 5773, end: 5776 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5786, end: 5789 } + }, + loc: { start: 5786, end: 5789 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5777, end: 5778 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5780, end: 5783 } + }, + loc: { start: 5780, end: 5783 } + }, + loc: { start: 5777, end: 5783 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ABS' ] + }, + loc: { start: 5765, end: 5797 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'log', loc: { start: 6721, end: 6724 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6747, end: 6750 } + }, + loc: { start: 6747, end: 6750 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 6725, end: 6728 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6730, end: 6733 } + }, + loc: { start: 6730, end: 6733 } + }, + loc: { start: 6725, end: 6733 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'base', + loc: { start: 6735, end: 6739 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6741, end: 6744 } + }, + loc: { start: 6741, end: 6744 } + }, + loc: { start: 6735, end: 6744 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_log', + loc: { start: 6702, end: 6712 } + } + }, + loc: { start: 6696, end: 6751 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'log2', loc: { start: 7341, end: 7345 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7357, end: 7360 } + }, + loc: { start: 7357, end: 7360 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 7346, end: 7349 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7351, end: 7354 } + }, + loc: { start: 7351, end: 7354 } + }, + loc: { start: 7346, end: 7354 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DUP 5 THROWIFNOT UBITSIZE DEC' ] + }, + loc: { start: 7333, end: 7394 } + }, + { + kind: 'function', + inline: true, + name: { kind: 'id', text: 'pow', loc: { start: 8510, end: 8513 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8536, end: 8539 } + }, + loc: { start: 8536, end: 8539 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'base', + loc: { start: 8514, end: 8518 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8520, end: 8523 } + }, + loc: { start: 8520, end: 8523 } + }, + loc: { start: 8514, end: 8523 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'exp', + loc: { start: 8525, end: 8528 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8530, end: 8533 } + }, + loc: { start: 8530, end: 8533 } + }, + loc: { start: 8525, end: 8533 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throwUnless', + loc: { start: 8546, end: 8557 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 5n, + loc: { start: 8558, end: 8559 } + }, + { + kind: 'op_binary', + op: '>=', + left: { + kind: 'var', + name: 'exp', + loc: { start: 8561, end: 8564 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 8568, end: 8569 } + }, + loc: { start: 8561, end: 8569 } + } + ], + loc: { start: 8546, end: 8570 } + }, + loc: { start: 8546, end: 8571 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'result', + loc: { start: 8580, end: 8586 } + }, + type: undefined, + expression: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 8589, end: 8590 } + }, + loc: { start: 8576, end: 8591 } + }, + { + kind: 'statement_repeat', + iterations: { + kind: 'var', + name: 'exp', + loc: { start: 8604, end: 8607 } + }, + statements: [ + { + kind: 'statement_augmentedassign', + op: '*=', + path: { + kind: 'var', + name: 'result', + loc: { start: 8619, end: 8625 } + }, + expression: { + kind: 'var', + name: 'base', + loc: { start: 8629, end: 8633 } + }, + loc: { start: 8619, end: 8634 } + } + ], + loc: { start: 8596, end: 8640 } + }, + { + kind: 'statement_return', + expression: { + kind: 'var', + name: 'result', + loc: { start: 8652, end: 8658 } + }, + loc: { start: 8645, end: 8659 } + } + ] + }, + loc: { start: 8499, end: 8661 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'pow2', loc: { start: 9733, end: 9737 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9749, end: 9752 } + }, + loc: { start: 9749, end: 9752 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'exp', + loc: { start: 9738, end: 9741 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9743, end: 9746 } + }, + loc: { start: 9743, end: 9746 } + }, + loc: { start: 9738, end: 9746 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'POW2' ] + }, + loc: { start: 9725, end: 9761 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sign', + loc: { start: 10233, end: 10237 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10247, end: 10250 } + }, + loc: { start: 10247, end: 10250 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 10238, end: 10239 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10241, end: 10244 } + }, + loc: { start: 10241, end: 10244 } + }, + loc: { start: 10238, end: 10244 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SGN' ] + }, + loc: { start: 10225, end: 10258 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'divc', + loc: { start: 10814, end: 10818 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10836, end: 10839 } + }, + loc: { start: 10836, end: 10839 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 10819, end: 10820 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10822, end: 10825 } + }, + loc: { start: 10822, end: 10825 } + }, + loc: { start: 10819, end: 10825 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 10827, end: 10828 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10830, end: 10833 } + }, + loc: { start: 10830, end: 10833 } + }, + loc: { start: 10827, end: 10833 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DIVC' ] + }, + loc: { start: 10806, end: 10848 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'muldivc', + loc: { start: 11615, end: 11622 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11648, end: 11651 } + }, + loc: { start: 11648, end: 11651 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 11623, end: 11624 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11626, end: 11629 } + }, + loc: { start: 11626, end: 11629 } + }, + loc: { start: 11623, end: 11629 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 11631, end: 11632 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11634, end: 11637 } + }, + loc: { start: 11634, end: 11637 } + }, + loc: { start: 11631, end: 11637 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 11639, end: 11640 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11642, end: 11645 } + }, + loc: { start: 11642, end: 11645 } + }, + loc: { start: 11639, end: 11645 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULDIVC' ] + }, + loc: { start: 11607, end: 11663 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRight', + loc: { start: 12751, end: 12764 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12790, end: 12793 } + }, + loc: { start: 12790, end: 12793 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 12765, end: 12766 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12768, end: 12771 } + }, + loc: { start: 12768, end: 12771 } + }, + loc: { start: 12765, end: 12771 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 12773, end: 12774 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12776, end: 12779 } + }, + loc: { start: 12776, end: 12779 } + }, + loc: { start: 12773, end: 12779 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 12781, end: 12782 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12784, end: 12787 } + }, + loc: { start: 12784, end: 12787 } + }, + loc: { start: 12781, end: 12787 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFT' ] + }, + loc: { start: 12743, end: 12807 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRightRound', + loc: { start: 13862, end: 13880 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13906, end: 13909 } + }, + loc: { start: 13906, end: 13909 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 13881, end: 13882 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13884, end: 13887 } + }, + loc: { start: 13884, end: 13887 } + }, + loc: { start: 13881, end: 13887 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 13889, end: 13890 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13892, end: 13895 } + }, + loc: { start: 13892, end: 13895 } + }, + loc: { start: 13889, end: 13895 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 13897, end: 13898 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13900, end: 13903 } + }, + loc: { start: 13900, end: 13903 } + }, + loc: { start: 13897, end: 13903 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFTR' ] + }, + loc: { start: 13854, end: 13924 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRightCeil', + loc: { start: 14875, end: 14892 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14918, end: 14921 } + }, + loc: { start: 14918, end: 14921 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 14893, end: 14894 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14896, end: 14899 } + }, + loc: { start: 14896, end: 14899 } + }, + loc: { start: 14893, end: 14899 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 14901, end: 14902 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14904, end: 14907 } + }, + loc: { start: 14904, end: 14907 } + }, + loc: { start: 14901, end: 14907 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 14909, end: 14910 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14912, end: 14915 } + }, + loc: { start: 14912, end: 14915 } + }, + loc: { start: 14909, end: 14915 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFTC' ] + }, + loc: { start: 14867, end: 14936 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sqrt', + loc: { start: 15698, end: 15702 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15714, end: 15717 } + }, + loc: { start: 15714, end: 15717 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 15703, end: 15706 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15708, end: 15711 } + }, + loc: { start: 15708, end: 15711 } + }, + loc: { start: 15703, end: 15711 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'num', + loc: { start: 15728, end: 15731 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15735, end: 15736 } + }, + loc: { start: 15728, end: 15736 } + }, + trueStatements: [ + { + kind: 'statement_return', + expression: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15755, end: 15756 } + }, + loc: { start: 15748, end: 15757 } + } + ], + falseStatements: undefined, + loc: { start: 15724, end: 15763 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 's', + loc: { start: 15773, end: 15774 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15776, end: 15779 } + }, + loc: { start: 15776, end: 15779 } + }, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'log2', + loc: { start: 15782, end: 15786 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'num', + loc: { start: 15787, end: 15790 } + } + ], + loc: { start: 15782, end: 15791 } + }, + loc: { start: 15769, end: 15792 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'x', + loc: { start: 15801, end: 15802 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15804, end: 15807 } + }, + loc: { start: 15804, end: 15807 } + }, + expression: { + kind: 'conditional', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 's', + loc: { start: 15811, end: 15812 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15816, end: 15817 } + }, + loc: { start: 15811, end: 15817 } + }, + thenBranch: { + kind: 'op_binary', + op: '+', + left: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'num', + loc: { start: 15821, end: 15824 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15827, end: 15828 } + }, + loc: { start: 15821, end: 15828 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15832, end: 15833 } + }, + loc: { start: 15820, end: 15833 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15836, end: 15837 } + }, + loc: { start: 15820, end: 15837 } + }, + elseBranch: { + kind: 'op_binary', + op: '<<', + left: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15840, end: 15841 } + }, + right: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '+', + left: { + kind: 'var', + name: 's', + loc: { start: 15847, end: 15848 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15851, end: 15852 } + }, + loc: { start: 15847, end: 15852 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15856, end: 15857 } + }, + loc: { start: 15846, end: 15857 } + }, + loc: { start: 15840, end: 15858 } + }, + loc: { start: 15811, end: 15858 } + }, + loc: { start: 15797, end: 15860 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'q', + loc: { start: 15870, end: 15871 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15873, end: 15876 } + }, + loc: { start: 15873, end: 15876 } + }, + expression: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15879, end: 15880 } + }, + loc: { start: 15866, end: 15881 } + }, + { + kind: 'statement_until', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'q', + loc: { start: 15957, end: 15958 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15962, end: 15963 } + }, + loc: { start: 15957, end: 15963 } + }, + statements: [ + { + kind: 'statement_assign', + path: { + kind: 'var', + name: 'q', + loc: { start: 15900, end: 15901 } + }, + expression: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '-', + left: { + kind: 'static_call', + function: { + kind: 'id', + text: 'divc', + loc: { start: 15905, end: 15909 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'num', + loc: { start: 15910, end: 15913 } + }, + { + kind: 'var', + name: 'x', + loc: { start: 15915, end: 15916 } + } + ], + loc: { start: 15905, end: 15917 } + }, + right: { + kind: 'var', + name: 'x', + loc: { start: 15920, end: 15921 } + }, + loc: { start: 15905, end: 15921 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15925, end: 15926 } + }, + loc: { start: 15904, end: 15926 } + }, + loc: { start: 15900, end: 15927 } + }, + { + kind: 'statement_augmentedassign', + op: '+=', + path: { + kind: 'var', + name: 'x', + loc: { start: 15936, end: 15937 } + }, + expression: { + kind: 'var', + name: 'q', + loc: { start: 15941, end: 15942 } + }, + loc: { start: 15936, end: 15943 } + } + ], + loc: { start: 15887, end: 15965 } + }, + { + kind: 'statement_return', + expression: { + kind: 'var', + name: 'x', + loc: { start: 15978, end: 15979 } + }, + loc: { start: 15971, end: 15980 } + } + ] + }, + loc: { start: 15694, end: 15982 } + } + ] + }, + 'divc' => { + kind: 'tact', + path: 'std/internal/math.tact', + code: '// Prepare random\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Randomizes the pseudorandom number generator with the specified unsigned 256-bit `Int` `x` by mixing it with the current seed. The new seed is the unsigned 256-bit `Int` value of the SHA-256 hash of concatenated old seed and `x` in their 32-byte strings big-endian representation.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativeRandomize(42); // now, random numbers are less predictable\n' + + "/// let idk: Int = randomInt(); // ???, it's random,\n" + + '/// // but the seed was adjusted deterministically!\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify a negative value of `x`.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomize\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun nativeRandomize(x: Int) { ADDRAND }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Randomizes the random number generator with the logical time of the current transaction. Equivalent to calling `nativeRandomize(curLt())`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativeRandomizeLt(); // now, random numbers are unpredictable for users,\n' + + '/// // but still may be affected by validators or collators\n' + + '/// // as they determine the seed of the current block.\n' + + "/// let idk: Int = randomInt(); // ???, it's random!\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomizelt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomize\n' + + '/// * https://docs.tact-lang.org/ref/core-contextstate#curlt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + 'asm fun nativeRandomizeLt() { LTIME ADDRAND }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Prepares a random number generator by using `nativeRandomizeLt()`. Automatically called by `randomInt()` and `random()` functions.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativePrepareRandom(); // prepare the RNG\n' + + '/// // ... do your random things ...\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativepreparerandom\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomizelt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '/// * https://docs.tact-lang.org/ref/core-random#random\n' + + '///\n' + + '@name(__tact_prepare_random)\n' + + 'native nativePrepareRandom();\n' + + '\n' + + '// Random\n' + + '\n' + + '// Generates a new pseudo-random unsigned 256-bit integer x.\n' + + '// The algorithm is as follows: if r is the old value of the random seed,\n' + + '// considered as a 32-byte array (by constructing the big-endian representation\n' + + '// of an unsigned 256-bit integer), then its sha512(r) is computed;\n' + + "// the first 32 bytes of this hash are stored as the new value r' of the random seed,\n" + + '// and the remaining 32 bytes are returned as the next random value x.\n' + + 'asm fun nativeRandom(): Int { RANDU256 }\n' + + '\n' + + '// Generates a new pseudo-random integer z in the range 0..range−1\n' + + '// (or range..−1, if range < 0).\n' + + '// More precisely, an unsigned random value x is generated as in `nativeRandom`;\n' + + '// then z := x * range / 2^256 is computed.\n' + + 'asm fun nativeRandomInterval(max: Int): Int { RAND }\n' + + '\n' + + '/// Generates and returns a new pseudo-random unsigned 256-bit `Int` value `x`.\n' + + '///\n' + + '/// The algorithm works as follows: first, the `sha512(r)` is computed. There, `r` is an old\n' + + '/// value of the random seed, which is taken as a 32-byte array constructed from the big-endian\n' + + '/// representation of an unsigned 256-bit `Int`. The first 32 bytes of this hash are stored as the new\n' + + "/// value `r'` of the random seed, and the remaining 32 bytes are returned as the next random value `x`.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + "/// let allYourRandomBelongToUs: Int = randomInt(); // ???, it's random :)\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + 'inline fun randomInt(): Int {\n' + + ' nativePrepareRandom();\n' + + ' return nativeRandom();\n' + + '}\n' + + '\n' + + '/// Generates and returns a new pseudo-random unsigned `Int` value `x` in the provided semi-closed\n' + + '/// interval: `min` ≤ `x` < `max`, or `min` ≥ `x` > `max` if both `min` and `max` are negative.\n' + + '///\n' + + '/// Note that the `max` value is never included in the interval.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// random(42, 43); // 42, always\n' + + '/// random(0, 42); // 0-41, but never 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-random#random\n' + + '///\n' + + 'inline fun random(min: Int, max: Int): Int {\n' + + ' nativePrepareRandom();\n' + + ' return min + nativeRandomInterval(max - min);\n' + + '}\n' + + '\n' + + '// Math\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the minimum of two `Int` values `x` and `y`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// min(1, 2); // 1\n' + + '/// min(2, 2); // 2\n' + + '/// min(007, 3); // 3\n' + + '/// min(0x45, 3_0_0); // 69, nice\n' + + '/// // ↑ ↑\n' + + '/// // 69 300\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#min\n' + + '///\n' + + 'asm fun min(x: Int, y: Int): Int { MIN }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the maximum of two `Int` values `x` and `y`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// max(1, 2); // 2\n' + + '/// max(2, 2); // 2\n' + + '/// max(007, 3); // 7\n' + + '/// max(0x45, 3_0_0); // 300\n' + + '/// // ↑ ↑\n' + + '/// // 69 300\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#max\n' + + '///\n' + + 'asm fun max(x: Int, y: Int): Int { MAX }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the absolute value of the `Int` value `x`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// abs(42); // 42\n' + + '/// abs(-42); // 42\n' + + '/// abs(-(-(-42))); // 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#abs\n' + + '///\n' + + 'asm fun abs(x: Int): Int { ABS }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the logarithm of a number `num` > 0 to the base `base` ≥ 1. Results are rounded down.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// log(1000, 10); // 3, as 10^3 is 1000\n' + + '/// // ↑ ↑ ↑ ↑\n' + + '/// // num base base num\n' + + '///\n' + + '/// log(1001, 10); // 3\n' + + '/// log(999, 10); // 2\n' + + '/// try {\n' + + '/// log(-1000, 10); // exit code 5 because of the non-positive num\n' + + '/// }\n' + + '/// log(1024, 2); // 10\n' + + '/// try {\n' + + '/// log(1024, -2); // exit code 5 because the base is less than 1\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `num` value is non-positive\n' + + '/// or the given `base` value is less than 1.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log2\n' + + '///\n' + + '@name(__tact_log)\n' + + 'native log(num: Int, base: Int): Int;\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Similar to `log()`, but sets the `base` to 2.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// log2(1024); // 10, as 2^10 is 1024\n' + + '/// // ↑ ↑ ↑\n' + + '/// // num base₂ num\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `num` value is non-positive.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log2\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log.\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes/#5\n' + + '///\n' + + 'asm fun log2(num: Int): Int { DUP 5 THROWIFNOT UBITSIZE DEC }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the exponentiation involving two numbers: the `base` and the exponent (or _power_) `exp`.\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Example {\n' + + '/// // Persistent state variables\n' + + '/// p23: Int = pow(2, 3); // raises 2 to the 3rd power, which is 8\n' + + '/// one: Int = pow(5, 0); // raises 5 to the power 0, which always produces 1\n' + + '/// // works at compile-time!\n' + + '///\n' + + '/// // Internal message receiver\n' + + '/// receive() {\n' + + '/// pow(self.p23, self.one + 1); // 64, works at run-time too!\n' + + '/// try {\n' + + '/// pow(0, -1); // exit code 5: Integer out of expected range\n' + + '/// }\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `exp` value is negative.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow2\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes/#5\n' + + '///\n' + + 'inline fun pow(base: Int, exp: Int): Int {\n' + + ' throwUnless(5, exp >= 0);\n' + + ' let result = 1;\n' + + ' repeat (exp) {\n' + + ' result *= base;\n' + + ' }\n' + + ' return result;\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Similar to `pow()`, but sets the `base` to 2.\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Example {\n' + + '/// // Persistent state variables\n' + + '/// p23: Int = pow2(3); // raises 2 to the 3rd power, which is 8\n' + + '/// one: Int = pow2(0); // raises 2 to the power 0, which always produces 1\n' + + '/// // works at compile-time!\n' + + '///\n' + + '/// // Internal message receiver, which accepts message ExtMsg\n' + + '/// receive() {\n' + + '/// pow2(self.one + 1); // 4, works at run-time too!\n' + + '/// try {\n' + + '/// pow(-1); // exit code 5: Integer out of expected range\n' + + '/// }\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify a negative value of `exp`.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow2\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun pow2(exp: Int): Int { POW2 }\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Computes and returns the sign of the `Int` value `x`. Produces 1 if the `x` is positive, -1 if the `x` is negative, and 0 if the `x` is 0.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// '... 5983 more characters, + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomize', + loc: { start: 965, end: 980 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { kind: 'id', text: 'x', loc: { start: 981, end: 982 } }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 984, end: 987 } + }, + loc: { start: 984, end: 987 } + }, + loc: { start: 981, end: 987 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ADDRAND' ] + }, + loc: { start: 957, end: 1000 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomizeLt', + loc: { start: 1822, end: 1839 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LTIME ADDRAND' ] + }, + loc: { start: 1814, end: 1859 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 2466, end: 2485 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_prepare_random', + loc: { start: 2436, end: 2457 } + } + }, + loc: { start: 2430, end: 2488 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandom', + loc: { start: 2949, end: 2961 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2965, end: 2968 } + }, + loc: { start: 2965, end: 2968 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RANDU256' ] + }, + loc: { start: 2941, end: 2981 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomInterval', + loc: { start: 3216, end: 3236 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3248, end: 3251 } + }, + loc: { start: 3248, end: 3251 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'max', + loc: { start: 3237, end: 3240 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3242, end: 3245 } + }, + loc: { start: 3242, end: 3245 } + }, + loc: { start: 3237, end: 3245 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RAND' ] + }, + loc: { start: 3208, end: 3260 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'randomInt', + loc: { start: 3953, end: 3962 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3966, end: 3969 } + }, + loc: { start: 3966, end: 3969 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 3976, end: 3995 } + }, + typeArgs: [], + args: [], + loc: { start: 3976, end: 3997 } + }, + loc: { start: 3976, end: 3998 } + }, + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativeRandom', + loc: { start: 4010, end: 4022 } + }, + typeArgs: [], + args: [], + loc: { start: 4010, end: 4024 } + }, + loc: { start: 4003, end: 4025 } + } + ] + }, + loc: { start: 3942, end: 4027 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'random', + loc: { start: 4505, end: 4511 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4533, end: 4536 } + }, + loc: { start: 4533, end: 4536 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'min', + loc: { start: 4512, end: 4515 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4517, end: 4520 } + }, + loc: { start: 4517, end: 4520 } + }, + loc: { start: 4512, end: 4520 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'max', + loc: { start: 4522, end: 4525 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4527, end: 4530 } + }, + loc: { start: 4527, end: 4530 } + }, + loc: { start: 4522, end: 4530 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 4543, end: 4562 } + }, + typeArgs: [], + args: [], + loc: { start: 4543, end: 4564 } + }, + loc: { start: 4543, end: 4565 } + }, + { + kind: 'statement_return', + expression: { + kind: 'op_binary', + op: '+', + left: { + kind: 'var', + name: 'min', + loc: { start: 4577, end: 4580 } + }, + right: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativeRandomInterval', + loc: { start: 4583, end: 4603 } + }, + typeArgs: [], + args: [ + { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'max', + loc: { start: 4604, end: 4607 } + }, + right: { + kind: 'var', + name: 'min', + loc: { start: 4610, end: 4613 } + }, + loc: { start: 4604, end: 4613 } + } + ], + loc: { start: 4583, end: 4614 } + }, + loc: { start: 4577, end: 4614 } + }, + loc: { start: 4570, end: 4615 } + } + ] + }, + loc: { start: 4494, end: 4617 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'min', loc: { start: 5017, end: 5020 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5038, end: 5041 } + }, + loc: { start: 5038, end: 5041 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5021, end: 5022 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5024, end: 5027 } + }, + loc: { start: 5024, end: 5027 } + }, + loc: { start: 5021, end: 5027 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 5029, end: 5030 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5032, end: 5035 } + }, + loc: { start: 5032, end: 5035 } + }, + loc: { start: 5029, end: 5035 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MIN' ] + }, + loc: { start: 5009, end: 5049 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'max', loc: { start: 5435, end: 5438 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5456, end: 5459 } + }, + loc: { start: 5456, end: 5459 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5439, end: 5440 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5442, end: 5445 } + }, + loc: { start: 5442, end: 5445 } + }, + loc: { start: 5439, end: 5445 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 5447, end: 5448 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5450, end: 5453 } + }, + loc: { start: 5450, end: 5453 } + }, + loc: { start: 5447, end: 5453 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MAX' ] + }, + loc: { start: 5427, end: 5467 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'abs', loc: { start: 5773, end: 5776 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5786, end: 5789 } + }, + loc: { start: 5786, end: 5789 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5777, end: 5778 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5780, end: 5783 } + }, + loc: { start: 5780, end: 5783 } + }, + loc: { start: 5777, end: 5783 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ABS' ] + }, + loc: { start: 5765, end: 5797 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'log', loc: { start: 6721, end: 6724 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6747, end: 6750 } + }, + loc: { start: 6747, end: 6750 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 6725, end: 6728 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6730, end: 6733 } + }, + loc: { start: 6730, end: 6733 } + }, + loc: { start: 6725, end: 6733 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'base', + loc: { start: 6735, end: 6739 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6741, end: 6744 } + }, + loc: { start: 6741, end: 6744 } + }, + loc: { start: 6735, end: 6744 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_log', + loc: { start: 6702, end: 6712 } + } + }, + loc: { start: 6696, end: 6751 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'log2', loc: { start: 7341, end: 7345 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7357, end: 7360 } + }, + loc: { start: 7357, end: 7360 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 7346, end: 7349 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7351, end: 7354 } + }, + loc: { start: 7351, end: 7354 } + }, + loc: { start: 7346, end: 7354 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DUP 5 THROWIFNOT UBITSIZE DEC' ] + }, + loc: { start: 7333, end: 7394 } + }, + { + kind: 'function', + inline: true, + name: { kind: 'id', text: 'pow', loc: { start: 8510, end: 8513 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8536, end: 8539 } + }, + loc: { start: 8536, end: 8539 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'base', + loc: { start: 8514, end: 8518 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8520, end: 8523 } + }, + loc: { start: 8520, end: 8523 } + }, + loc: { start: 8514, end: 8523 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'exp', + loc: { start: 8525, end: 8528 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8530, end: 8533 } + }, + loc: { start: 8530, end: 8533 } + }, + loc: { start: 8525, end: 8533 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throwUnless', + loc: { start: 8546, end: 8557 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 5n, + loc: { start: 8558, end: 8559 } + }, + { + kind: 'op_binary', + op: '>=', + left: { + kind: 'var', + name: 'exp', + loc: { start: 8561, end: 8564 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 8568, end: 8569 } + }, + loc: { start: 8561, end: 8569 } + } + ], + loc: { start: 8546, end: 8570 } + }, + loc: { start: 8546, end: 8571 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'result', + loc: { start: 8580, end: 8586 } + }, + type: undefined, + expression: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 8589, end: 8590 } + }, + loc: { start: 8576, end: 8591 } + }, + { + kind: 'statement_repeat', + iterations: { + kind: 'var', + name: 'exp', + loc: { start: 8604, end: 8607 } + }, + statements: [ + { + kind: 'statement_augmentedassign', + op: '*=', + path: { + kind: 'var', + name: 'result', + loc: { start: 8619, end: 8625 } + }, + expression: { + kind: 'var', + name: 'base', + loc: { start: 8629, end: 8633 } + }, + loc: { start: 8619, end: 8634 } + } + ], + loc: { start: 8596, end: 8640 } + }, + { + kind: 'statement_return', + expression: { + kind: 'var', + name: 'result', + loc: { start: 8652, end: 8658 } + }, + loc: { start: 8645, end: 8659 } + } + ] + }, + loc: { start: 8499, end: 8661 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'pow2', loc: { start: 9733, end: 9737 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9749, end: 9752 } + }, + loc: { start: 9749, end: 9752 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'exp', + loc: { start: 9738, end: 9741 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9743, end: 9746 } + }, + loc: { start: 9743, end: 9746 } + }, + loc: { start: 9738, end: 9746 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'POW2' ] + }, + loc: { start: 9725, end: 9761 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sign', + loc: { start: 10233, end: 10237 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10247, end: 10250 } + }, + loc: { start: 10247, end: 10250 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 10238, end: 10239 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10241, end: 10244 } + }, + loc: { start: 10241, end: 10244 } + }, + loc: { start: 10238, end: 10244 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SGN' ] + }, + loc: { start: 10225, end: 10258 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'divc', + loc: { start: 10814, end: 10818 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10836, end: 10839 } + }, + loc: { start: 10836, end: 10839 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 10819, end: 10820 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10822, end: 10825 } + }, + loc: { start: 10822, end: 10825 } + }, + loc: { start: 10819, end: 10825 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 10827, end: 10828 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10830, end: 10833 } + }, + loc: { start: 10830, end: 10833 } + }, + loc: { start: 10827, end: 10833 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DIVC' ] + }, + loc: { start: 10806, end: 10848 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'muldivc', + loc: { start: 11615, end: 11622 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11648, end: 11651 } + }, + loc: { start: 11648, end: 11651 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 11623, end: 11624 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11626, end: 11629 } + }, + loc: { start: 11626, end: 11629 } + }, + loc: { start: 11623, end: 11629 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 11631, end: 11632 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11634, end: 11637 } + }, + loc: { start: 11634, end: 11637 } + }, + loc: { start: 11631, end: 11637 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 11639, end: 11640 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11642, end: 11645 } + }, + loc: { start: 11642, end: 11645 } + }, + loc: { start: 11639, end: 11645 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULDIVC' ] + }, + loc: { start: 11607, end: 11663 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRight', + loc: { start: 12751, end: 12764 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12790, end: 12793 } + }, + loc: { start: 12790, end: 12793 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 12765, end: 12766 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12768, end: 12771 } + }, + loc: { start: 12768, end: 12771 } + }, + loc: { start: 12765, end: 12771 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 12773, end: 12774 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12776, end: 12779 } + }, + loc: { start: 12776, end: 12779 } + }, + loc: { start: 12773, end: 12779 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 12781, end: 12782 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12784, end: 12787 } + }, + loc: { start: 12784, end: 12787 } + }, + loc: { start: 12781, end: 12787 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFT' ] + }, + loc: { start: 12743, end: 12807 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRightRound', + loc: { start: 13862, end: 13880 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13906, end: 13909 } + }, + loc: { start: 13906, end: 13909 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 13881, end: 13882 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13884, end: 13887 } + }, + loc: { start: 13884, end: 13887 } + }, + loc: { start: 13881, end: 13887 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 13889, end: 13890 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13892, end: 13895 } + }, + loc: { start: 13892, end: 13895 } + }, + loc: { start: 13889, end: 13895 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 13897, end: 13898 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13900, end: 13903 } + }, + loc: { start: 13900, end: 13903 } + }, + loc: { start: 13897, end: 13903 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFTR' ] + }, + loc: { start: 13854, end: 13924 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRightCeil', + loc: { start: 14875, end: 14892 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14918, end: 14921 } + }, + loc: { start: 14918, end: 14921 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 14893, end: 14894 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14896, end: 14899 } + }, + loc: { start: 14896, end: 14899 } + }, + loc: { start: 14893, end: 14899 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 14901, end: 14902 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14904, end: 14907 } + }, + loc: { start: 14904, end: 14907 } + }, + loc: { start: 14901, end: 14907 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 14909, end: 14910 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14912, end: 14915 } + }, + loc: { start: 14912, end: 14915 } + }, + loc: { start: 14909, end: 14915 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFTC' ] + }, + loc: { start: 14867, end: 14936 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sqrt', + loc: { start: 15698, end: 15702 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15714, end: 15717 } + }, + loc: { start: 15714, end: 15717 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 15703, end: 15706 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15708, end: 15711 } + }, + loc: { start: 15708, end: 15711 } + }, + loc: { start: 15703, end: 15711 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'num', + loc: { start: 15728, end: 15731 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15735, end: 15736 } + }, + loc: { start: 15728, end: 15736 } + }, + trueStatements: [ + { + kind: 'statement_return', + expression: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15755, end: 15756 } + }, + loc: { start: 15748, end: 15757 } + } + ], + falseStatements: undefined, + loc: { start: 15724, end: 15763 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 's', + loc: { start: 15773, end: 15774 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15776, end: 15779 } + }, + loc: { start: 15776, end: 15779 } + }, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'log2', + loc: { start: 15782, end: 15786 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'num', + loc: { start: 15787, end: 15790 } + } + ], + loc: { start: 15782, end: 15791 } + }, + loc: { start: 15769, end: 15792 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'x', + loc: { start: 15801, end: 15802 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15804, end: 15807 } + }, + loc: { start: 15804, end: 15807 } + }, + expression: { + kind: 'conditional', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 's', + loc: { start: 15811, end: 15812 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15816, end: 15817 } + }, + loc: { start: 15811, end: 15817 } + }, + thenBranch: { + kind: 'op_binary', + op: '+', + left: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'num', + loc: { start: 15821, end: 15824 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15827, end: 15828 } + }, + loc: { start: 15821, end: 15828 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15832, end: 15833 } + }, + loc: { start: 15820, end: 15833 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15836, end: 15837 } + }, + loc: { start: 15820, end: 15837 } + }, + elseBranch: { + kind: 'op_binary', + op: '<<', + left: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15840, end: 15841 } + }, + right: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '+', + left: { + kind: 'var', + name: 's', + loc: { start: 15847, end: 15848 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15851, end: 15852 } + }, + loc: { start: 15847, end: 15852 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15856, end: 15857 } + }, + loc: { start: 15846, end: 15857 } + }, + loc: { start: 15840, end: 15858 } + }, + loc: { start: 15811, end: 15858 } + }, + loc: { start: 15797, end: 15860 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'q', + loc: { start: 15870, end: 15871 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15873, end: 15876 } + }, + loc: { start: 15873, end: 15876 } + }, + expression: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15879, end: 15880 } + }, + loc: { start: 15866, end: 15881 } + }, + { + kind: 'statement_until', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'q', + loc: { start: 15957, end: 15958 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15962, end: 15963 } + }, + loc: { start: 15957, end: 15963 } + }, + statements: [ + { + kind: 'statement_assign', + path: { + kind: 'var', + name: 'q', + loc: { start: 15900, end: 15901 } + }, + expression: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '-', + left: { + kind: 'static_call', + function: { + kind: 'id', + text: 'divc', + loc: { start: 15905, end: 15909 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'num', + loc: { start: 15910, end: 15913 } + }, + { + kind: 'var', + name: 'x', + loc: { start: 15915, end: 15916 } + } + ], + loc: { start: 15905, end: 15917 } + }, + right: { + kind: 'var', + name: 'x', + loc: { start: 15920, end: 15921 } + }, + loc: { start: 15905, end: 15921 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15925, end: 15926 } + }, + loc: { start: 15904, end: 15926 } + }, + loc: { start: 15900, end: 15927 } + }, + { + kind: 'statement_augmentedassign', + op: '+=', + path: { + kind: 'var', + name: 'x', + loc: { start: 15936, end: 15937 } + }, + expression: { + kind: 'var', + name: 'q', + loc: { start: 15941, end: 15942 } + }, + loc: { start: 15936, end: 15943 } + } + ], + loc: { start: 15887, end: 15965 } + }, + { + kind: 'statement_return', + expression: { + kind: 'var', + name: 'x', + loc: { start: 15978, end: 15979 } + }, + loc: { start: 15971, end: 15980 } + } + ] + }, + loc: { start: 15694, end: 15982 } + } + ] + }, + 'muldivc' => { + kind: 'tact', + path: 'std/internal/math.tact', + code: '// Prepare random\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Randomizes the pseudorandom number generator with the specified unsigned 256-bit `Int` `x` by mixing it with the current seed. The new seed is the unsigned 256-bit `Int` value of the SHA-256 hash of concatenated old seed and `x` in their 32-byte strings big-endian representation.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativeRandomize(42); // now, random numbers are less predictable\n' + + "/// let idk: Int = randomInt(); // ???, it's random,\n" + + '/// // but the seed was adjusted deterministically!\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify a negative value of `x`.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomize\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun nativeRandomize(x: Int) { ADDRAND }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Randomizes the random number generator with the logical time of the current transaction. Equivalent to calling `nativeRandomize(curLt())`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativeRandomizeLt(); // now, random numbers are unpredictable for users,\n' + + '/// // but still may be affected by validators or collators\n' + + '/// // as they determine the seed of the current block.\n' + + "/// let idk: Int = randomInt(); // ???, it's random!\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomizelt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomize\n' + + '/// * https://docs.tact-lang.org/ref/core-contextstate#curlt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + 'asm fun nativeRandomizeLt() { LTIME ADDRAND }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Prepares a random number generator by using `nativeRandomizeLt()`. Automatically called by `randomInt()` and `random()` functions.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativePrepareRandom(); // prepare the RNG\n' + + '/// // ... do your random things ...\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativepreparerandom\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomizelt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '/// * https://docs.tact-lang.org/ref/core-random#random\n' + + '///\n' + + '@name(__tact_prepare_random)\n' + + 'native nativePrepareRandom();\n' + + '\n' + + '// Random\n' + + '\n' + + '// Generates a new pseudo-random unsigned 256-bit integer x.\n' + + '// The algorithm is as follows: if r is the old value of the random seed,\n' + + '// considered as a 32-byte array (by constructing the big-endian representation\n' + + '// of an unsigned 256-bit integer), then its sha512(r) is computed;\n' + + "// the first 32 bytes of this hash are stored as the new value r' of the random seed,\n" + + '// and the remaining 32 bytes are returned as the next random value x.\n' + + 'asm fun nativeRandom(): Int { RANDU256 }\n' + + '\n' + + '// Generates a new pseudo-random integer z in the range 0..range−1\n' + + '// (or range..−1, if range < 0).\n' + + '// More precisely, an unsigned random value x is generated as in `nativeRandom`;\n' + + '// then z := x * range / 2^256 is computed.\n' + + 'asm fun nativeRandomInterval(max: Int): Int { RAND }\n' + + '\n' + + '/// Generates and returns a new pseudo-random unsigned 256-bit `Int` value `x`.\n' + + '///\n' + + '/// The algorithm works as follows: first, the `sha512(r)` is computed. There, `r` is an old\n' + + '/// value of the random seed, which is taken as a 32-byte array constructed from the big-endian\n' + + '/// representation of an unsigned 256-bit `Int`. The first 32 bytes of this hash are stored as the new\n' + + "/// value `r'` of the random seed, and the remaining 32 bytes are returned as the next random value `x`.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + "/// let allYourRandomBelongToUs: Int = randomInt(); // ???, it's random :)\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + 'inline fun randomInt(): Int {\n' + + ' nativePrepareRandom();\n' + + ' return nativeRandom();\n' + + '}\n' + + '\n' + + '/// Generates and returns a new pseudo-random unsigned `Int` value `x` in the provided semi-closed\n' + + '/// interval: `min` ≤ `x` < `max`, or `min` ≥ `x` > `max` if both `min` and `max` are negative.\n' + + '///\n' + + '/// Note that the `max` value is never included in the interval.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// random(42, 43); // 42, always\n' + + '/// random(0, 42); // 0-41, but never 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-random#random\n' + + '///\n' + + 'inline fun random(min: Int, max: Int): Int {\n' + + ' nativePrepareRandom();\n' + + ' return min + nativeRandomInterval(max - min);\n' + + '}\n' + + '\n' + + '// Math\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the minimum of two `Int` values `x` and `y`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// min(1, 2); // 1\n' + + '/// min(2, 2); // 2\n' + + '/// min(007, 3); // 3\n' + + '/// min(0x45, 3_0_0); // 69, nice\n' + + '/// // ↑ ↑\n' + + '/// // 69 300\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#min\n' + + '///\n' + + 'asm fun min(x: Int, y: Int): Int { MIN }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the maximum of two `Int` values `x` and `y`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// max(1, 2); // 2\n' + + '/// max(2, 2); // 2\n' + + '/// max(007, 3); // 7\n' + + '/// max(0x45, 3_0_0); // 300\n' + + '/// // ↑ ↑\n' + + '/// // 69 300\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#max\n' + + '///\n' + + 'asm fun max(x: Int, y: Int): Int { MAX }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the absolute value of the `Int` value `x`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// abs(42); // 42\n' + + '/// abs(-42); // 42\n' + + '/// abs(-(-(-42))); // 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#abs\n' + + '///\n' + + 'asm fun abs(x: Int): Int { ABS }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the logarithm of a number `num` > 0 to the base `base` ≥ 1. Results are rounded down.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// log(1000, 10); // 3, as 10^3 is 1000\n' + + '/// // ↑ ↑ ↑ ↑\n' + + '/// // num base base num\n' + + '///\n' + + '/// log(1001, 10); // 3\n' + + '/// log(999, 10); // 2\n' + + '/// try {\n' + + '/// log(-1000, 10); // exit code 5 because of the non-positive num\n' + + '/// }\n' + + '/// log(1024, 2); // 10\n' + + '/// try {\n' + + '/// log(1024, -2); // exit code 5 because the base is less than 1\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `num` value is non-positive\n' + + '/// or the given `base` value is less than 1.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log2\n' + + '///\n' + + '@name(__tact_log)\n' + + 'native log(num: Int, base: Int): Int;\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Similar to `log()`, but sets the `base` to 2.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// log2(1024); // 10, as 2^10 is 1024\n' + + '/// // ↑ ↑ ↑\n' + + '/// // num base₂ num\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `num` value is non-positive.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log2\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log.\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes/#5\n' + + '///\n' + + 'asm fun log2(num: Int): Int { DUP 5 THROWIFNOT UBITSIZE DEC }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the exponentiation involving two numbers: the `base` and the exponent (or _power_) `exp`.\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Example {\n' + + '/// // Persistent state variables\n' + + '/// p23: Int = pow(2, 3); // raises 2 to the 3rd power, which is 8\n' + + '/// one: Int = pow(5, 0); // raises 5 to the power 0, which always produces 1\n' + + '/// // works at compile-time!\n' + + '///\n' + + '/// // Internal message receiver\n' + + '/// receive() {\n' + + '/// pow(self.p23, self.one + 1); // 64, works at run-time too!\n' + + '/// try {\n' + + '/// pow(0, -1); // exit code 5: Integer out of expected range\n' + + '/// }\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `exp` value is negative.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow2\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes/#5\n' + + '///\n' + + 'inline fun pow(base: Int, exp: Int): Int {\n' + + ' throwUnless(5, exp >= 0);\n' + + ' let result = 1;\n' + + ' repeat (exp) {\n' + + ' result *= base;\n' + + ' }\n' + + ' return result;\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Similar to `pow()`, but sets the `base` to 2.\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Example {\n' + + '/// // Persistent state variables\n' + + '/// p23: Int = pow2(3); // raises 2 to the 3rd power, which is 8\n' + + '/// one: Int = pow2(0); // raises 2 to the power 0, which always produces 1\n' + + '/// // works at compile-time!\n' + + '///\n' + + '/// // Internal message receiver, which accepts message ExtMsg\n' + + '/// receive() {\n' + + '/// pow2(self.one + 1); // 4, works at run-time too!\n' + + '/// try {\n' + + '/// pow(-1); // exit code 5: Integer out of expected range\n' + + '/// }\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify a negative value of `exp`.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow2\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun pow2(exp: Int): Int { POW2 }\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Computes and returns the sign of the `Int` value `x`. Produces 1 if the `x` is positive, -1 if the `x` is negative, and 0 if the `x` is 0.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// '... 5983 more characters, + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomize', + loc: { start: 965, end: 980 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { kind: 'id', text: 'x', loc: { start: 981, end: 982 } }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 984, end: 987 } + }, + loc: { start: 984, end: 987 } + }, + loc: { start: 981, end: 987 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ADDRAND' ] + }, + loc: { start: 957, end: 1000 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomizeLt', + loc: { start: 1822, end: 1839 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LTIME ADDRAND' ] + }, + loc: { start: 1814, end: 1859 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 2466, end: 2485 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_prepare_random', + loc: { start: 2436, end: 2457 } + } + }, + loc: { start: 2430, end: 2488 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandom', + loc: { start: 2949, end: 2961 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2965, end: 2968 } + }, + loc: { start: 2965, end: 2968 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RANDU256' ] + }, + loc: { start: 2941, end: 2981 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomInterval', + loc: { start: 3216, end: 3236 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3248, end: 3251 } + }, + loc: { start: 3248, end: 3251 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'max', + loc: { start: 3237, end: 3240 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3242, end: 3245 } + }, + loc: { start: 3242, end: 3245 } + }, + loc: { start: 3237, end: 3245 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RAND' ] + }, + loc: { start: 3208, end: 3260 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'randomInt', + loc: { start: 3953, end: 3962 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3966, end: 3969 } + }, + loc: { start: 3966, end: 3969 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 3976, end: 3995 } + }, + typeArgs: [], + args: [], + loc: { start: 3976, end: 3997 } + }, + loc: { start: 3976, end: 3998 } + }, + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativeRandom', + loc: { start: 4010, end: 4022 } + }, + typeArgs: [], + args: [], + loc: { start: 4010, end: 4024 } + }, + loc: { start: 4003, end: 4025 } + } + ] + }, + loc: { start: 3942, end: 4027 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'random', + loc: { start: 4505, end: 4511 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4533, end: 4536 } + }, + loc: { start: 4533, end: 4536 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'min', + loc: { start: 4512, end: 4515 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4517, end: 4520 } + }, + loc: { start: 4517, end: 4520 } + }, + loc: { start: 4512, end: 4520 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'max', + loc: { start: 4522, end: 4525 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4527, end: 4530 } + }, + loc: { start: 4527, end: 4530 } + }, + loc: { start: 4522, end: 4530 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 4543, end: 4562 } + }, + typeArgs: [], + args: [], + loc: { start: 4543, end: 4564 } + }, + loc: { start: 4543, end: 4565 } + }, + { + kind: 'statement_return', + expression: { + kind: 'op_binary', + op: '+', + left: { + kind: 'var', + name: 'min', + loc: { start: 4577, end: 4580 } + }, + right: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativeRandomInterval', + loc: { start: 4583, end: 4603 } + }, + typeArgs: [], + args: [ + { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'max', + loc: { start: 4604, end: 4607 } + }, + right: { + kind: 'var', + name: 'min', + loc: { start: 4610, end: 4613 } + }, + loc: { start: 4604, end: 4613 } + } + ], + loc: { start: 4583, end: 4614 } + }, + loc: { start: 4577, end: 4614 } + }, + loc: { start: 4570, end: 4615 } + } + ] + }, + loc: { start: 4494, end: 4617 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'min', loc: { start: 5017, end: 5020 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5038, end: 5041 } + }, + loc: { start: 5038, end: 5041 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5021, end: 5022 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5024, end: 5027 } + }, + loc: { start: 5024, end: 5027 } + }, + loc: { start: 5021, end: 5027 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 5029, end: 5030 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5032, end: 5035 } + }, + loc: { start: 5032, end: 5035 } + }, + loc: { start: 5029, end: 5035 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MIN' ] + }, + loc: { start: 5009, end: 5049 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'max', loc: { start: 5435, end: 5438 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5456, end: 5459 } + }, + loc: { start: 5456, end: 5459 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5439, end: 5440 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5442, end: 5445 } + }, + loc: { start: 5442, end: 5445 } + }, + loc: { start: 5439, end: 5445 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 5447, end: 5448 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5450, end: 5453 } + }, + loc: { start: 5450, end: 5453 } + }, + loc: { start: 5447, end: 5453 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MAX' ] + }, + loc: { start: 5427, end: 5467 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'abs', loc: { start: 5773, end: 5776 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5786, end: 5789 } + }, + loc: { start: 5786, end: 5789 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5777, end: 5778 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5780, end: 5783 } + }, + loc: { start: 5780, end: 5783 } + }, + loc: { start: 5777, end: 5783 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ABS' ] + }, + loc: { start: 5765, end: 5797 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'log', loc: { start: 6721, end: 6724 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6747, end: 6750 } + }, + loc: { start: 6747, end: 6750 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 6725, end: 6728 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6730, end: 6733 } + }, + loc: { start: 6730, end: 6733 } + }, + loc: { start: 6725, end: 6733 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'base', + loc: { start: 6735, end: 6739 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6741, end: 6744 } + }, + loc: { start: 6741, end: 6744 } + }, + loc: { start: 6735, end: 6744 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_log', + loc: { start: 6702, end: 6712 } + } + }, + loc: { start: 6696, end: 6751 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'log2', loc: { start: 7341, end: 7345 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7357, end: 7360 } + }, + loc: { start: 7357, end: 7360 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 7346, end: 7349 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7351, end: 7354 } + }, + loc: { start: 7351, end: 7354 } + }, + loc: { start: 7346, end: 7354 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DUP 5 THROWIFNOT UBITSIZE DEC' ] + }, + loc: { start: 7333, end: 7394 } + }, + { + kind: 'function', + inline: true, + name: { kind: 'id', text: 'pow', loc: { start: 8510, end: 8513 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8536, end: 8539 } + }, + loc: { start: 8536, end: 8539 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'base', + loc: { start: 8514, end: 8518 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8520, end: 8523 } + }, + loc: { start: 8520, end: 8523 } + }, + loc: { start: 8514, end: 8523 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'exp', + loc: { start: 8525, end: 8528 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8530, end: 8533 } + }, + loc: { start: 8530, end: 8533 } + }, + loc: { start: 8525, end: 8533 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throwUnless', + loc: { start: 8546, end: 8557 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 5n, + loc: { start: 8558, end: 8559 } + }, + { + kind: 'op_binary', + op: '>=', + left: { + kind: 'var', + name: 'exp', + loc: { start: 8561, end: 8564 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 8568, end: 8569 } + }, + loc: { start: 8561, end: 8569 } + } + ], + loc: { start: 8546, end: 8570 } + }, + loc: { start: 8546, end: 8571 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'result', + loc: { start: 8580, end: 8586 } + }, + type: undefined, + expression: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 8589, end: 8590 } + }, + loc: { start: 8576, end: 8591 } + }, + { + kind: 'statement_repeat', + iterations: { + kind: 'var', + name: 'exp', + loc: { start: 8604, end: 8607 } + }, + statements: [ + { + kind: 'statement_augmentedassign', + op: '*=', + path: { + kind: 'var', + name: 'result', + loc: { start: 8619, end: 8625 } + }, + expression: { + kind: 'var', + name: 'base', + loc: { start: 8629, end: 8633 } + }, + loc: { start: 8619, end: 8634 } + } + ], + loc: { start: 8596, end: 8640 } + }, + { + kind: 'statement_return', + expression: { + kind: 'var', + name: 'result', + loc: { start: 8652, end: 8658 } + }, + loc: { start: 8645, end: 8659 } + } + ] + }, + loc: { start: 8499, end: 8661 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'pow2', loc: { start: 9733, end: 9737 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9749, end: 9752 } + }, + loc: { start: 9749, end: 9752 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'exp', + loc: { start: 9738, end: 9741 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9743, end: 9746 } + }, + loc: { start: 9743, end: 9746 } + }, + loc: { start: 9738, end: 9746 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'POW2' ] + }, + loc: { start: 9725, end: 9761 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sign', + loc: { start: 10233, end: 10237 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10247, end: 10250 } + }, + loc: { start: 10247, end: 10250 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 10238, end: 10239 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10241, end: 10244 } + }, + loc: { start: 10241, end: 10244 } + }, + loc: { start: 10238, end: 10244 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SGN' ] + }, + loc: { start: 10225, end: 10258 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'divc', + loc: { start: 10814, end: 10818 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10836, end: 10839 } + }, + loc: { start: 10836, end: 10839 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 10819, end: 10820 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10822, end: 10825 } + }, + loc: { start: 10822, end: 10825 } + }, + loc: { start: 10819, end: 10825 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 10827, end: 10828 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10830, end: 10833 } + }, + loc: { start: 10830, end: 10833 } + }, + loc: { start: 10827, end: 10833 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DIVC' ] + }, + loc: { start: 10806, end: 10848 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'muldivc', + loc: { start: 11615, end: 11622 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11648, end: 11651 } + }, + loc: { start: 11648, end: 11651 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 11623, end: 11624 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11626, end: 11629 } + }, + loc: { start: 11626, end: 11629 } + }, + loc: { start: 11623, end: 11629 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 11631, end: 11632 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11634, end: 11637 } + }, + loc: { start: 11634, end: 11637 } + }, + loc: { start: 11631, end: 11637 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 11639, end: 11640 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11642, end: 11645 } + }, + loc: { start: 11642, end: 11645 } + }, + loc: { start: 11639, end: 11645 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULDIVC' ] + }, + loc: { start: 11607, end: 11663 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRight', + loc: { start: 12751, end: 12764 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12790, end: 12793 } + }, + loc: { start: 12790, end: 12793 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 12765, end: 12766 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12768, end: 12771 } + }, + loc: { start: 12768, end: 12771 } + }, + loc: { start: 12765, end: 12771 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 12773, end: 12774 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12776, end: 12779 } + }, + loc: { start: 12776, end: 12779 } + }, + loc: { start: 12773, end: 12779 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 12781, end: 12782 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12784, end: 12787 } + }, + loc: { start: 12784, end: 12787 } + }, + loc: { start: 12781, end: 12787 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFT' ] + }, + loc: { start: 12743, end: 12807 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRightRound', + loc: { start: 13862, end: 13880 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13906, end: 13909 } + }, + loc: { start: 13906, end: 13909 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 13881, end: 13882 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13884, end: 13887 } + }, + loc: { start: 13884, end: 13887 } + }, + loc: { start: 13881, end: 13887 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 13889, end: 13890 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13892, end: 13895 } + }, + loc: { start: 13892, end: 13895 } + }, + loc: { start: 13889, end: 13895 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 13897, end: 13898 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13900, end: 13903 } + }, + loc: { start: 13900, end: 13903 } + }, + loc: { start: 13897, end: 13903 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFTR' ] + }, + loc: { start: 13854, end: 13924 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRightCeil', + loc: { start: 14875, end: 14892 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14918, end: 14921 } + }, + loc: { start: 14918, end: 14921 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 14893, end: 14894 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14896, end: 14899 } + }, + loc: { start: 14896, end: 14899 } + }, + loc: { start: 14893, end: 14899 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 14901, end: 14902 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14904, end: 14907 } + }, + loc: { start: 14904, end: 14907 } + }, + loc: { start: 14901, end: 14907 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 14909, end: 14910 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14912, end: 14915 } + }, + loc: { start: 14912, end: 14915 } + }, + loc: { start: 14909, end: 14915 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFTC' ] + }, + loc: { start: 14867, end: 14936 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sqrt', + loc: { start: 15698, end: 15702 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15714, end: 15717 } + }, + loc: { start: 15714, end: 15717 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 15703, end: 15706 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15708, end: 15711 } + }, + loc: { start: 15708, end: 15711 } + }, + loc: { start: 15703, end: 15711 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'num', + loc: { start: 15728, end: 15731 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15735, end: 15736 } + }, + loc: { start: 15728, end: 15736 } + }, + trueStatements: [ + { + kind: 'statement_return', + expression: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15755, end: 15756 } + }, + loc: { start: 15748, end: 15757 } + } + ], + falseStatements: undefined, + loc: { start: 15724, end: 15763 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 's', + loc: { start: 15773, end: 15774 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15776, end: 15779 } + }, + loc: { start: 15776, end: 15779 } + }, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'log2', + loc: { start: 15782, end: 15786 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'num', + loc: { start: 15787, end: 15790 } + } + ], + loc: { start: 15782, end: 15791 } + }, + loc: { start: 15769, end: 15792 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'x', + loc: { start: 15801, end: 15802 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15804, end: 15807 } + }, + loc: { start: 15804, end: 15807 } + }, + expression: { + kind: 'conditional', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 's', + loc: { start: 15811, end: 15812 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15816, end: 15817 } + }, + loc: { start: 15811, end: 15817 } + }, + thenBranch: { + kind: 'op_binary', + op: '+', + left: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'num', + loc: { start: 15821, end: 15824 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15827, end: 15828 } + }, + loc: { start: 15821, end: 15828 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15832, end: 15833 } + }, + loc: { start: 15820, end: 15833 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15836, end: 15837 } + }, + loc: { start: 15820, end: 15837 } + }, + elseBranch: { + kind: 'op_binary', + op: '<<', + left: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15840, end: 15841 } + }, + right: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '+', + left: { + kind: 'var', + name: 's', + loc: { start: 15847, end: 15848 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15851, end: 15852 } + }, + loc: { start: 15847, end: 15852 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15856, end: 15857 } + }, + loc: { start: 15846, end: 15857 } + }, + loc: { start: 15840, end: 15858 } + }, + loc: { start: 15811, end: 15858 } + }, + loc: { start: 15797, end: 15860 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'q', + loc: { start: 15870, end: 15871 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15873, end: 15876 } + }, + loc: { start: 15873, end: 15876 } + }, + expression: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15879, end: 15880 } + }, + loc: { start: 15866, end: 15881 } + }, + { + kind: 'statement_until', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'q', + loc: { start: 15957, end: 15958 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15962, end: 15963 } + }, + loc: { start: 15957, end: 15963 } + }, + statements: [ + { + kind: 'statement_assign', + path: { + kind: 'var', + name: 'q', + loc: { start: 15900, end: 15901 } + }, + expression: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '-', + left: { + kind: 'static_call', + function: { + kind: 'id', + text: 'divc', + loc: { start: 15905, end: 15909 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'num', + loc: { start: 15910, end: 15913 } + }, + { + kind: 'var', + name: 'x', + loc: { start: 15915, end: 15916 } + } + ], + loc: { start: 15905, end: 15917 } + }, + right: { + kind: 'var', + name: 'x', + loc: { start: 15920, end: 15921 } + }, + loc: { start: 15905, end: 15921 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15925, end: 15926 } + }, + loc: { start: 15904, end: 15926 } + }, + loc: { start: 15900, end: 15927 } + }, + { + kind: 'statement_augmentedassign', + op: '+=', + path: { + kind: 'var', + name: 'x', + loc: { start: 15936, end: 15937 } + }, + expression: { + kind: 'var', + name: 'q', + loc: { start: 15941, end: 15942 } + }, + loc: { start: 15936, end: 15943 } + } + ], + loc: { start: 15887, end: 15965 } + }, + { + kind: 'statement_return', + expression: { + kind: 'var', + name: 'x', + loc: { start: 15978, end: 15979 } + }, + loc: { start: 15971, end: 15980 } + } + ] + }, + loc: { start: 15694, end: 15982 } + } + ] + }, + 'mulShiftRight' => { + kind: 'tact', + path: 'std/internal/math.tact', + code: '// Prepare random\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Randomizes the pseudorandom number generator with the specified unsigned 256-bit `Int` `x` by mixing it with the current seed. The new seed is the unsigned 256-bit `Int` value of the SHA-256 hash of concatenated old seed and `x` in their 32-byte strings big-endian representation.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativeRandomize(42); // now, random numbers are less predictable\n' + + "/// let idk: Int = randomInt(); // ???, it's random,\n" + + '/// // but the seed was adjusted deterministically!\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify a negative value of `x`.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomize\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun nativeRandomize(x: Int) { ADDRAND }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Randomizes the random number generator with the logical time of the current transaction. Equivalent to calling `nativeRandomize(curLt())`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativeRandomizeLt(); // now, random numbers are unpredictable for users,\n' + + '/// // but still may be affected by validators or collators\n' + + '/// // as they determine the seed of the current block.\n' + + "/// let idk: Int = randomInt(); // ???, it's random!\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomizelt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomize\n' + + '/// * https://docs.tact-lang.org/ref/core-contextstate#curlt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + 'asm fun nativeRandomizeLt() { LTIME ADDRAND }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Prepares a random number generator by using `nativeRandomizeLt()`. Automatically called by `randomInt()` and `random()` functions.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativePrepareRandom(); // prepare the RNG\n' + + '/// // ... do your random things ...\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativepreparerandom\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomizelt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '/// * https://docs.tact-lang.org/ref/core-random#random\n' + + '///\n' + + '@name(__tact_prepare_random)\n' + + 'native nativePrepareRandom();\n' + + '\n' + + '// Random\n' + + '\n' + + '// Generates a new pseudo-random unsigned 256-bit integer x.\n' + + '// The algorithm is as follows: if r is the old value of the random seed,\n' + + '// considered as a 32-byte array (by constructing the big-endian representation\n' + + '// of an unsigned 256-bit integer), then its sha512(r) is computed;\n' + + "// the first 32 bytes of this hash are stored as the new value r' of the random seed,\n" + + '// and the remaining 32 bytes are returned as the next random value x.\n' + + 'asm fun nativeRandom(): Int { RANDU256 }\n' + + '\n' + + '// Generates a new pseudo-random integer z in the range 0..range−1\n' + + '// (or range..−1, if range < 0).\n' + + '// More precisely, an unsigned random value x is generated as in `nativeRandom`;\n' + + '// then z := x * range / 2^256 is computed.\n' + + 'asm fun nativeRandomInterval(max: Int): Int { RAND }\n' + + '\n' + + '/// Generates and returns a new pseudo-random unsigned 256-bit `Int` value `x`.\n' + + '///\n' + + '/// The algorithm works as follows: first, the `sha512(r)` is computed. There, `r` is an old\n' + + '/// value of the random seed, which is taken as a 32-byte array constructed from the big-endian\n' + + '/// representation of an unsigned 256-bit `Int`. The first 32 bytes of this hash are stored as the new\n' + + "/// value `r'` of the random seed, and the remaining 32 bytes are returned as the next random value `x`.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + "/// let allYourRandomBelongToUs: Int = randomInt(); // ???, it's random :)\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + 'inline fun randomInt(): Int {\n' + + ' nativePrepareRandom();\n' + + ' return nativeRandom();\n' + + '}\n' + + '\n' + + '/// Generates and returns a new pseudo-random unsigned `Int` value `x` in the provided semi-closed\n' + + '/// interval: `min` ≤ `x` < `max`, or `min` ≥ `x` > `max` if both `min` and `max` are negative.\n' + + '///\n' + + '/// Note that the `max` value is never included in the interval.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// random(42, 43); // 42, always\n' + + '/// random(0, 42); // 0-41, but never 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-random#random\n' + + '///\n' + + 'inline fun random(min: Int, max: Int): Int {\n' + + ' nativePrepareRandom();\n' + + ' return min + nativeRandomInterval(max - min);\n' + + '}\n' + + '\n' + + '// Math\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the minimum of two `Int` values `x` and `y`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// min(1, 2); // 1\n' + + '/// min(2, 2); // 2\n' + + '/// min(007, 3); // 3\n' + + '/// min(0x45, 3_0_0); // 69, nice\n' + + '/// // ↑ ↑\n' + + '/// // 69 300\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#min\n' + + '///\n' + + 'asm fun min(x: Int, y: Int): Int { MIN }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the maximum of two `Int` values `x` and `y`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// max(1, 2); // 2\n' + + '/// max(2, 2); // 2\n' + + '/// max(007, 3); // 7\n' + + '/// max(0x45, 3_0_0); // 300\n' + + '/// // ↑ ↑\n' + + '/// // 69 300\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#max\n' + + '///\n' + + 'asm fun max(x: Int, y: Int): Int { MAX }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the absolute value of the `Int` value `x`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// abs(42); // 42\n' + + '/// abs(-42); // 42\n' + + '/// abs(-(-(-42))); // 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#abs\n' + + '///\n' + + 'asm fun abs(x: Int): Int { ABS }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the logarithm of a number `num` > 0 to the base `base` ≥ 1. Results are rounded down.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// log(1000, 10); // 3, as 10^3 is 1000\n' + + '/// // ↑ ↑ ↑ ↑\n' + + '/// // num base base num\n' + + '///\n' + + '/// log(1001, 10); // 3\n' + + '/// log(999, 10); // 2\n' + + '/// try {\n' + + '/// log(-1000, 10); // exit code 5 because of the non-positive num\n' + + '/// }\n' + + '/// log(1024, 2); // 10\n' + + '/// try {\n' + + '/// log(1024, -2); // exit code 5 because the base is less than 1\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `num` value is non-positive\n' + + '/// or the given `base` value is less than 1.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log2\n' + + '///\n' + + '@name(__tact_log)\n' + + 'native log(num: Int, base: Int): Int;\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Similar to `log()`, but sets the `base` to 2.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// log2(1024); // 10, as 2^10 is 1024\n' + + '/// // ↑ ↑ ↑\n' + + '/// // num base₂ num\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `num` value is non-positive.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log2\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log.\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes/#5\n' + + '///\n' + + 'asm fun log2(num: Int): Int { DUP 5 THROWIFNOT UBITSIZE DEC }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the exponentiation involving two numbers: the `base` and the exponent (or _power_) `exp`.\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Example {\n' + + '/// // Persistent state variables\n' + + '/// p23: Int = pow(2, 3); // raises 2 to the 3rd power, which is 8\n' + + '/// one: Int = pow(5, 0); // raises 5 to the power 0, which always produces 1\n' + + '/// // works at compile-time!\n' + + '///\n' + + '/// // Internal message receiver\n' + + '/// receive() {\n' + + '/// pow(self.p23, self.one + 1); // 64, works at run-time too!\n' + + '/// try {\n' + + '/// pow(0, -1); // exit code 5: Integer out of expected range\n' + + '/// }\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `exp` value is negative.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow2\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes/#5\n' + + '///\n' + + 'inline fun pow(base: Int, exp: Int): Int {\n' + + ' throwUnless(5, exp >= 0);\n' + + ' let result = 1;\n' + + ' repeat (exp) {\n' + + ' result *= base;\n' + + ' }\n' + + ' return result;\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Similar to `pow()`, but sets the `base` to 2.\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Example {\n' + + '/// // Persistent state variables\n' + + '/// p23: Int = pow2(3); // raises 2 to the 3rd power, which is 8\n' + + '/// one: Int = pow2(0); // raises 2 to the power 0, which always produces 1\n' + + '/// // works at compile-time!\n' + + '///\n' + + '/// // Internal message receiver, which accepts message ExtMsg\n' + + '/// receive() {\n' + + '/// pow2(self.one + 1); // 4, works at run-time too!\n' + + '/// try {\n' + + '/// pow(-1); // exit code 5: Integer out of expected range\n' + + '/// }\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify a negative value of `exp`.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow2\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun pow2(exp: Int): Int { POW2 }\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Computes and returns the sign of the `Int` value `x`. Produces 1 if the `x` is positive, -1 if the `x` is negative, and 0 if the `x` is 0.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// '... 5983 more characters, + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomize', + loc: { start: 965, end: 980 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { kind: 'id', text: 'x', loc: { start: 981, end: 982 } }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 984, end: 987 } + }, + loc: { start: 984, end: 987 } + }, + loc: { start: 981, end: 987 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ADDRAND' ] + }, + loc: { start: 957, end: 1000 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomizeLt', + loc: { start: 1822, end: 1839 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LTIME ADDRAND' ] + }, + loc: { start: 1814, end: 1859 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 2466, end: 2485 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_prepare_random', + loc: { start: 2436, end: 2457 } + } + }, + loc: { start: 2430, end: 2488 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandom', + loc: { start: 2949, end: 2961 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2965, end: 2968 } + }, + loc: { start: 2965, end: 2968 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RANDU256' ] + }, + loc: { start: 2941, end: 2981 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomInterval', + loc: { start: 3216, end: 3236 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3248, end: 3251 } + }, + loc: { start: 3248, end: 3251 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'max', + loc: { start: 3237, end: 3240 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3242, end: 3245 } + }, + loc: { start: 3242, end: 3245 } + }, + loc: { start: 3237, end: 3245 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RAND' ] + }, + loc: { start: 3208, end: 3260 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'randomInt', + loc: { start: 3953, end: 3962 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3966, end: 3969 } + }, + loc: { start: 3966, end: 3969 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 3976, end: 3995 } + }, + typeArgs: [], + args: [], + loc: { start: 3976, end: 3997 } + }, + loc: { start: 3976, end: 3998 } + }, + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativeRandom', + loc: { start: 4010, end: 4022 } + }, + typeArgs: [], + args: [], + loc: { start: 4010, end: 4024 } + }, + loc: { start: 4003, end: 4025 } + } + ] + }, + loc: { start: 3942, end: 4027 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'random', + loc: { start: 4505, end: 4511 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4533, end: 4536 } + }, + loc: { start: 4533, end: 4536 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'min', + loc: { start: 4512, end: 4515 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4517, end: 4520 } + }, + loc: { start: 4517, end: 4520 } + }, + loc: { start: 4512, end: 4520 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'max', + loc: { start: 4522, end: 4525 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4527, end: 4530 } + }, + loc: { start: 4527, end: 4530 } + }, + loc: { start: 4522, end: 4530 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 4543, end: 4562 } + }, + typeArgs: [], + args: [], + loc: { start: 4543, end: 4564 } + }, + loc: { start: 4543, end: 4565 } + }, + { + kind: 'statement_return', + expression: { + kind: 'op_binary', + op: '+', + left: { + kind: 'var', + name: 'min', + loc: { start: 4577, end: 4580 } + }, + right: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativeRandomInterval', + loc: { start: 4583, end: 4603 } + }, + typeArgs: [], + args: [ + { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'max', + loc: { start: 4604, end: 4607 } + }, + right: { + kind: 'var', + name: 'min', + loc: { start: 4610, end: 4613 } + }, + loc: { start: 4604, end: 4613 } + } + ], + loc: { start: 4583, end: 4614 } + }, + loc: { start: 4577, end: 4614 } + }, + loc: { start: 4570, end: 4615 } + } + ] + }, + loc: { start: 4494, end: 4617 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'min', loc: { start: 5017, end: 5020 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5038, end: 5041 } + }, + loc: { start: 5038, end: 5041 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5021, end: 5022 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5024, end: 5027 } + }, + loc: { start: 5024, end: 5027 } + }, + loc: { start: 5021, end: 5027 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 5029, end: 5030 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5032, end: 5035 } + }, + loc: { start: 5032, end: 5035 } + }, + loc: { start: 5029, end: 5035 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MIN' ] + }, + loc: { start: 5009, end: 5049 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'max', loc: { start: 5435, end: 5438 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5456, end: 5459 } + }, + loc: { start: 5456, end: 5459 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5439, end: 5440 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5442, end: 5445 } + }, + loc: { start: 5442, end: 5445 } + }, + loc: { start: 5439, end: 5445 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 5447, end: 5448 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5450, end: 5453 } + }, + loc: { start: 5450, end: 5453 } + }, + loc: { start: 5447, end: 5453 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MAX' ] + }, + loc: { start: 5427, end: 5467 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'abs', loc: { start: 5773, end: 5776 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5786, end: 5789 } + }, + loc: { start: 5786, end: 5789 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5777, end: 5778 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5780, end: 5783 } + }, + loc: { start: 5780, end: 5783 } + }, + loc: { start: 5777, end: 5783 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ABS' ] + }, + loc: { start: 5765, end: 5797 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'log', loc: { start: 6721, end: 6724 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6747, end: 6750 } + }, + loc: { start: 6747, end: 6750 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 6725, end: 6728 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6730, end: 6733 } + }, + loc: { start: 6730, end: 6733 } + }, + loc: { start: 6725, end: 6733 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'base', + loc: { start: 6735, end: 6739 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6741, end: 6744 } + }, + loc: { start: 6741, end: 6744 } + }, + loc: { start: 6735, end: 6744 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_log', + loc: { start: 6702, end: 6712 } + } + }, + loc: { start: 6696, end: 6751 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'log2', loc: { start: 7341, end: 7345 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7357, end: 7360 } + }, + loc: { start: 7357, end: 7360 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 7346, end: 7349 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7351, end: 7354 } + }, + loc: { start: 7351, end: 7354 } + }, + loc: { start: 7346, end: 7354 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DUP 5 THROWIFNOT UBITSIZE DEC' ] + }, + loc: { start: 7333, end: 7394 } + }, + { + kind: 'function', + inline: true, + name: { kind: 'id', text: 'pow', loc: { start: 8510, end: 8513 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8536, end: 8539 } + }, + loc: { start: 8536, end: 8539 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'base', + loc: { start: 8514, end: 8518 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8520, end: 8523 } + }, + loc: { start: 8520, end: 8523 } + }, + loc: { start: 8514, end: 8523 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'exp', + loc: { start: 8525, end: 8528 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8530, end: 8533 } + }, + loc: { start: 8530, end: 8533 } + }, + loc: { start: 8525, end: 8533 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throwUnless', + loc: { start: 8546, end: 8557 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 5n, + loc: { start: 8558, end: 8559 } + }, + { + kind: 'op_binary', + op: '>=', + left: { + kind: 'var', + name: 'exp', + loc: { start: 8561, end: 8564 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 8568, end: 8569 } + }, + loc: { start: 8561, end: 8569 } + } + ], + loc: { start: 8546, end: 8570 } + }, + loc: { start: 8546, end: 8571 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'result', + loc: { start: 8580, end: 8586 } + }, + type: undefined, + expression: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 8589, end: 8590 } + }, + loc: { start: 8576, end: 8591 } + }, + { + kind: 'statement_repeat', + iterations: { + kind: 'var', + name: 'exp', + loc: { start: 8604, end: 8607 } + }, + statements: [ + { + kind: 'statement_augmentedassign', + op: '*=', + path: { + kind: 'var', + name: 'result', + loc: { start: 8619, end: 8625 } + }, + expression: { + kind: 'var', + name: 'base', + loc: { start: 8629, end: 8633 } + }, + loc: { start: 8619, end: 8634 } + } + ], + loc: { start: 8596, end: 8640 } + }, + { + kind: 'statement_return', + expression: { + kind: 'var', + name: 'result', + loc: { start: 8652, end: 8658 } + }, + loc: { start: 8645, end: 8659 } + } + ] + }, + loc: { start: 8499, end: 8661 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'pow2', loc: { start: 9733, end: 9737 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9749, end: 9752 } + }, + loc: { start: 9749, end: 9752 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'exp', + loc: { start: 9738, end: 9741 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9743, end: 9746 } + }, + loc: { start: 9743, end: 9746 } + }, + loc: { start: 9738, end: 9746 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'POW2' ] + }, + loc: { start: 9725, end: 9761 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sign', + loc: { start: 10233, end: 10237 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10247, end: 10250 } + }, + loc: { start: 10247, end: 10250 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 10238, end: 10239 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10241, end: 10244 } + }, + loc: { start: 10241, end: 10244 } + }, + loc: { start: 10238, end: 10244 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SGN' ] + }, + loc: { start: 10225, end: 10258 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'divc', + loc: { start: 10814, end: 10818 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10836, end: 10839 } + }, + loc: { start: 10836, end: 10839 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 10819, end: 10820 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10822, end: 10825 } + }, + loc: { start: 10822, end: 10825 } + }, + loc: { start: 10819, end: 10825 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 10827, end: 10828 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10830, end: 10833 } + }, + loc: { start: 10830, end: 10833 } + }, + loc: { start: 10827, end: 10833 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DIVC' ] + }, + loc: { start: 10806, end: 10848 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'muldivc', + loc: { start: 11615, end: 11622 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11648, end: 11651 } + }, + loc: { start: 11648, end: 11651 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 11623, end: 11624 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11626, end: 11629 } + }, + loc: { start: 11626, end: 11629 } + }, + loc: { start: 11623, end: 11629 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 11631, end: 11632 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11634, end: 11637 } + }, + loc: { start: 11634, end: 11637 } + }, + loc: { start: 11631, end: 11637 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 11639, end: 11640 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11642, end: 11645 } + }, + loc: { start: 11642, end: 11645 } + }, + loc: { start: 11639, end: 11645 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULDIVC' ] + }, + loc: { start: 11607, end: 11663 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRight', + loc: { start: 12751, end: 12764 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12790, end: 12793 } + }, + loc: { start: 12790, end: 12793 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 12765, end: 12766 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12768, end: 12771 } + }, + loc: { start: 12768, end: 12771 } + }, + loc: { start: 12765, end: 12771 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 12773, end: 12774 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12776, end: 12779 } + }, + loc: { start: 12776, end: 12779 } + }, + loc: { start: 12773, end: 12779 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 12781, end: 12782 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12784, end: 12787 } + }, + loc: { start: 12784, end: 12787 } + }, + loc: { start: 12781, end: 12787 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFT' ] + }, + loc: { start: 12743, end: 12807 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRightRound', + loc: { start: 13862, end: 13880 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13906, end: 13909 } + }, + loc: { start: 13906, end: 13909 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 13881, end: 13882 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13884, end: 13887 } + }, + loc: { start: 13884, end: 13887 } + }, + loc: { start: 13881, end: 13887 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 13889, end: 13890 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13892, end: 13895 } + }, + loc: { start: 13892, end: 13895 } + }, + loc: { start: 13889, end: 13895 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 13897, end: 13898 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13900, end: 13903 } + }, + loc: { start: 13900, end: 13903 } + }, + loc: { start: 13897, end: 13903 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFTR' ] + }, + loc: { start: 13854, end: 13924 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRightCeil', + loc: { start: 14875, end: 14892 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14918, end: 14921 } + }, + loc: { start: 14918, end: 14921 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 14893, end: 14894 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14896, end: 14899 } + }, + loc: { start: 14896, end: 14899 } + }, + loc: { start: 14893, end: 14899 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 14901, end: 14902 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14904, end: 14907 } + }, + loc: { start: 14904, end: 14907 } + }, + loc: { start: 14901, end: 14907 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 14909, end: 14910 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14912, end: 14915 } + }, + loc: { start: 14912, end: 14915 } + }, + loc: { start: 14909, end: 14915 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFTC' ] + }, + loc: { start: 14867, end: 14936 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sqrt', + loc: { start: 15698, end: 15702 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15714, end: 15717 } + }, + loc: { start: 15714, end: 15717 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 15703, end: 15706 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15708, end: 15711 } + }, + loc: { start: 15708, end: 15711 } + }, + loc: { start: 15703, end: 15711 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'num', + loc: { start: 15728, end: 15731 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15735, end: 15736 } + }, + loc: { start: 15728, end: 15736 } + }, + trueStatements: [ + { + kind: 'statement_return', + expression: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15755, end: 15756 } + }, + loc: { start: 15748, end: 15757 } + } + ], + falseStatements: undefined, + loc: { start: 15724, end: 15763 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 's', + loc: { start: 15773, end: 15774 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15776, end: 15779 } + }, + loc: { start: 15776, end: 15779 } + }, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'log2', + loc: { start: 15782, end: 15786 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'num', + loc: { start: 15787, end: 15790 } + } + ], + loc: { start: 15782, end: 15791 } + }, + loc: { start: 15769, end: 15792 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'x', + loc: { start: 15801, end: 15802 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15804, end: 15807 } + }, + loc: { start: 15804, end: 15807 } + }, + expression: { + kind: 'conditional', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 's', + loc: { start: 15811, end: 15812 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15816, end: 15817 } + }, + loc: { start: 15811, end: 15817 } + }, + thenBranch: { + kind: 'op_binary', + op: '+', + left: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'num', + loc: { start: 15821, end: 15824 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15827, end: 15828 } + }, + loc: { start: 15821, end: 15828 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15832, end: 15833 } + }, + loc: { start: 15820, end: 15833 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15836, end: 15837 } + }, + loc: { start: 15820, end: 15837 } + }, + elseBranch: { + kind: 'op_binary', + op: '<<', + left: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15840, end: 15841 } + }, + right: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '+', + left: { + kind: 'var', + name: 's', + loc: { start: 15847, end: 15848 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15851, end: 15852 } + }, + loc: { start: 15847, end: 15852 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15856, end: 15857 } + }, + loc: { start: 15846, end: 15857 } + }, + loc: { start: 15840, end: 15858 } + }, + loc: { start: 15811, end: 15858 } + }, + loc: { start: 15797, end: 15860 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'q', + loc: { start: 15870, end: 15871 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15873, end: 15876 } + }, + loc: { start: 15873, end: 15876 } + }, + expression: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15879, end: 15880 } + }, + loc: { start: 15866, end: 15881 } + }, + { + kind: 'statement_until', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'q', + loc: { start: 15957, end: 15958 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15962, end: 15963 } + }, + loc: { start: 15957, end: 15963 } + }, + statements: [ + { + kind: 'statement_assign', + path: { + kind: 'var', + name: 'q', + loc: { start: 15900, end: 15901 } + }, + expression: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '-', + left: { + kind: 'static_call', + function: { + kind: 'id', + text: 'divc', + loc: { start: 15905, end: 15909 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'num', + loc: { start: 15910, end: 15913 } + }, + { + kind: 'var', + name: 'x', + loc: { start: 15915, end: 15916 } + } + ], + loc: { start: 15905, end: 15917 } + }, + right: { + kind: 'var', + name: 'x', + loc: { start: 15920, end: 15921 } + }, + loc: { start: 15905, end: 15921 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15925, end: 15926 } + }, + loc: { start: 15904, end: 15926 } + }, + loc: { start: 15900, end: 15927 } + }, + { + kind: 'statement_augmentedassign', + op: '+=', + path: { + kind: 'var', + name: 'x', + loc: { start: 15936, end: 15937 } + }, + expression: { + kind: 'var', + name: 'q', + loc: { start: 15941, end: 15942 } + }, + loc: { start: 15936, end: 15943 } + } + ], + loc: { start: 15887, end: 15965 } + }, + { + kind: 'statement_return', + expression: { + kind: 'var', + name: 'x', + loc: { start: 15978, end: 15979 } + }, + loc: { start: 15971, end: 15980 } + } + ] + }, + loc: { start: 15694, end: 15982 } + } + ] + }, + 'mulShiftRightRound' => { + kind: 'tact', + path: 'std/internal/math.tact', + code: '// Prepare random\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Randomizes the pseudorandom number generator with the specified unsigned 256-bit `Int` `x` by mixing it with the current seed. The new seed is the unsigned 256-bit `Int` value of the SHA-256 hash of concatenated old seed and `x` in their 32-byte strings big-endian representation.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativeRandomize(42); // now, random numbers are less predictable\n' + + "/// let idk: Int = randomInt(); // ???, it's random,\n" + + '/// // but the seed was adjusted deterministically!\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify a negative value of `x`.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomize\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun nativeRandomize(x: Int) { ADDRAND }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Randomizes the random number generator with the logical time of the current transaction. Equivalent to calling `nativeRandomize(curLt())`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativeRandomizeLt(); // now, random numbers are unpredictable for users,\n' + + '/// // but still may be affected by validators or collators\n' + + '/// // as they determine the seed of the current block.\n' + + "/// let idk: Int = randomInt(); // ???, it's random!\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomizelt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomize\n' + + '/// * https://docs.tact-lang.org/ref/core-contextstate#curlt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + 'asm fun nativeRandomizeLt() { LTIME ADDRAND }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Prepares a random number generator by using `nativeRandomizeLt()`. Automatically called by `randomInt()` and `random()` functions.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativePrepareRandom(); // prepare the RNG\n' + + '/// // ... do your random things ...\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativepreparerandom\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomizelt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '/// * https://docs.tact-lang.org/ref/core-random#random\n' + + '///\n' + + '@name(__tact_prepare_random)\n' + + 'native nativePrepareRandom();\n' + + '\n' + + '// Random\n' + + '\n' + + '// Generates a new pseudo-random unsigned 256-bit integer x.\n' + + '// The algorithm is as follows: if r is the old value of the random seed,\n' + + '// considered as a 32-byte array (by constructing the big-endian representation\n' + + '// of an unsigned 256-bit integer), then its sha512(r) is computed;\n' + + "// the first 32 bytes of this hash are stored as the new value r' of the random seed,\n" + + '// and the remaining 32 bytes are returned as the next random value x.\n' + + 'asm fun nativeRandom(): Int { RANDU256 }\n' + + '\n' + + '// Generates a new pseudo-random integer z in the range 0..range−1\n' + + '// (or range..−1, if range < 0).\n' + + '// More precisely, an unsigned random value x is generated as in `nativeRandom`;\n' + + '// then z := x * range / 2^256 is computed.\n' + + 'asm fun nativeRandomInterval(max: Int): Int { RAND }\n' + + '\n' + + '/// Generates and returns a new pseudo-random unsigned 256-bit `Int` value `x`.\n' + + '///\n' + + '/// The algorithm works as follows: first, the `sha512(r)` is computed. There, `r` is an old\n' + + '/// value of the random seed, which is taken as a 32-byte array constructed from the big-endian\n' + + '/// representation of an unsigned 256-bit `Int`. The first 32 bytes of this hash are stored as the new\n' + + "/// value `r'` of the random seed, and the remaining 32 bytes are returned as the next random value `x`.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + "/// let allYourRandomBelongToUs: Int = randomInt(); // ???, it's random :)\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + 'inline fun randomInt(): Int {\n' + + ' nativePrepareRandom();\n' + + ' return nativeRandom();\n' + + '}\n' + + '\n' + + '/// Generates and returns a new pseudo-random unsigned `Int` value `x` in the provided semi-closed\n' + + '/// interval: `min` ≤ `x` < `max`, or `min` ≥ `x` > `max` if both `min` and `max` are negative.\n' + + '///\n' + + '/// Note that the `max` value is never included in the interval.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// random(42, 43); // 42, always\n' + + '/// random(0, 42); // 0-41, but never 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-random#random\n' + + '///\n' + + 'inline fun random(min: Int, max: Int): Int {\n' + + ' nativePrepareRandom();\n' + + ' return min + nativeRandomInterval(max - min);\n' + + '}\n' + + '\n' + + '// Math\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the minimum of two `Int` values `x` and `y`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// min(1, 2); // 1\n' + + '/// min(2, 2); // 2\n' + + '/// min(007, 3); // 3\n' + + '/// min(0x45, 3_0_0); // 69, nice\n' + + '/// // ↑ ↑\n' + + '/// // 69 300\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#min\n' + + '///\n' + + 'asm fun min(x: Int, y: Int): Int { MIN }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the maximum of two `Int` values `x` and `y`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// max(1, 2); // 2\n' + + '/// max(2, 2); // 2\n' + + '/// max(007, 3); // 7\n' + + '/// max(0x45, 3_0_0); // 300\n' + + '/// // ↑ ↑\n' + + '/// // 69 300\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#max\n' + + '///\n' + + 'asm fun max(x: Int, y: Int): Int { MAX }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the absolute value of the `Int` value `x`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// abs(42); // 42\n' + + '/// abs(-42); // 42\n' + + '/// abs(-(-(-42))); // 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#abs\n' + + '///\n' + + 'asm fun abs(x: Int): Int { ABS }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the logarithm of a number `num` > 0 to the base `base` ≥ 1. Results are rounded down.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// log(1000, 10); // 3, as 10^3 is 1000\n' + + '/// // ↑ ↑ ↑ ↑\n' + + '/// // num base base num\n' + + '///\n' + + '/// log(1001, 10); // 3\n' + + '/// log(999, 10); // 2\n' + + '/// try {\n' + + '/// log(-1000, 10); // exit code 5 because of the non-positive num\n' + + '/// }\n' + + '/// log(1024, 2); // 10\n' + + '/// try {\n' + + '/// log(1024, -2); // exit code 5 because the base is less than 1\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `num` value is non-positive\n' + + '/// or the given `base` value is less than 1.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log2\n' + + '///\n' + + '@name(__tact_log)\n' + + 'native log(num: Int, base: Int): Int;\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Similar to `log()`, but sets the `base` to 2.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// log2(1024); // 10, as 2^10 is 1024\n' + + '/// // ↑ ↑ ↑\n' + + '/// // num base₂ num\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `num` value is non-positive.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log2\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log.\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes/#5\n' + + '///\n' + + 'asm fun log2(num: Int): Int { DUP 5 THROWIFNOT UBITSIZE DEC }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the exponentiation involving two numbers: the `base` and the exponent (or _power_) `exp`.\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Example {\n' + + '/// // Persistent state variables\n' + + '/// p23: Int = pow(2, 3); // raises 2 to the 3rd power, which is 8\n' + + '/// one: Int = pow(5, 0); // raises 5 to the power 0, which always produces 1\n' + + '/// // works at compile-time!\n' + + '///\n' + + '/// // Internal message receiver\n' + + '/// receive() {\n' + + '/// pow(self.p23, self.one + 1); // 64, works at run-time too!\n' + + '/// try {\n' + + '/// pow(0, -1); // exit code 5: Integer out of expected range\n' + + '/// }\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `exp` value is negative.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow2\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes/#5\n' + + '///\n' + + 'inline fun pow(base: Int, exp: Int): Int {\n' + + ' throwUnless(5, exp >= 0);\n' + + ' let result = 1;\n' + + ' repeat (exp) {\n' + + ' result *= base;\n' + + ' }\n' + + ' return result;\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Similar to `pow()`, but sets the `base` to 2.\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Example {\n' + + '/// // Persistent state variables\n' + + '/// p23: Int = pow2(3); // raises 2 to the 3rd power, which is 8\n' + + '/// one: Int = pow2(0); // raises 2 to the power 0, which always produces 1\n' + + '/// // works at compile-time!\n' + + '///\n' + + '/// // Internal message receiver, which accepts message ExtMsg\n' + + '/// receive() {\n' + + '/// pow2(self.one + 1); // 4, works at run-time too!\n' + + '/// try {\n' + + '/// pow(-1); // exit code 5: Integer out of expected range\n' + + '/// }\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify a negative value of `exp`.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow2\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun pow2(exp: Int): Int { POW2 }\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Computes and returns the sign of the `Int` value `x`. Produces 1 if the `x` is positive, -1 if the `x` is negative, and 0 if the `x` is 0.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// '... 5983 more characters, + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomize', + loc: { start: 965, end: 980 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { kind: 'id', text: 'x', loc: { start: 981, end: 982 } }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 984, end: 987 } + }, + loc: { start: 984, end: 987 } + }, + loc: { start: 981, end: 987 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ADDRAND' ] + }, + loc: { start: 957, end: 1000 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomizeLt', + loc: { start: 1822, end: 1839 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LTIME ADDRAND' ] + }, + loc: { start: 1814, end: 1859 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 2466, end: 2485 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_prepare_random', + loc: { start: 2436, end: 2457 } + } + }, + loc: { start: 2430, end: 2488 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandom', + loc: { start: 2949, end: 2961 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2965, end: 2968 } + }, + loc: { start: 2965, end: 2968 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RANDU256' ] + }, + loc: { start: 2941, end: 2981 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomInterval', + loc: { start: 3216, end: 3236 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3248, end: 3251 } + }, + loc: { start: 3248, end: 3251 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'max', + loc: { start: 3237, end: 3240 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3242, end: 3245 } + }, + loc: { start: 3242, end: 3245 } + }, + loc: { start: 3237, end: 3245 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RAND' ] + }, + loc: { start: 3208, end: 3260 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'randomInt', + loc: { start: 3953, end: 3962 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3966, end: 3969 } + }, + loc: { start: 3966, end: 3969 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 3976, end: 3995 } + }, + typeArgs: [], + args: [], + loc: { start: 3976, end: 3997 } + }, + loc: { start: 3976, end: 3998 } + }, + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativeRandom', + loc: { start: 4010, end: 4022 } + }, + typeArgs: [], + args: [], + loc: { start: 4010, end: 4024 } + }, + loc: { start: 4003, end: 4025 } + } + ] + }, + loc: { start: 3942, end: 4027 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'random', + loc: { start: 4505, end: 4511 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4533, end: 4536 } + }, + loc: { start: 4533, end: 4536 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'min', + loc: { start: 4512, end: 4515 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4517, end: 4520 } + }, + loc: { start: 4517, end: 4520 } + }, + loc: { start: 4512, end: 4520 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'max', + loc: { start: 4522, end: 4525 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4527, end: 4530 } + }, + loc: { start: 4527, end: 4530 } + }, + loc: { start: 4522, end: 4530 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 4543, end: 4562 } + }, + typeArgs: [], + args: [], + loc: { start: 4543, end: 4564 } + }, + loc: { start: 4543, end: 4565 } + }, + { + kind: 'statement_return', + expression: { + kind: 'op_binary', + op: '+', + left: { + kind: 'var', + name: 'min', + loc: { start: 4577, end: 4580 } + }, + right: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativeRandomInterval', + loc: { start: 4583, end: 4603 } + }, + typeArgs: [], + args: [ + { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'max', + loc: { start: 4604, end: 4607 } + }, + right: { + kind: 'var', + name: 'min', + loc: { start: 4610, end: 4613 } + }, + loc: { start: 4604, end: 4613 } + } + ], + loc: { start: 4583, end: 4614 } + }, + loc: { start: 4577, end: 4614 } + }, + loc: { start: 4570, end: 4615 } + } + ] + }, + loc: { start: 4494, end: 4617 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'min', loc: { start: 5017, end: 5020 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5038, end: 5041 } + }, + loc: { start: 5038, end: 5041 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5021, end: 5022 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5024, end: 5027 } + }, + loc: { start: 5024, end: 5027 } + }, + loc: { start: 5021, end: 5027 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 5029, end: 5030 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5032, end: 5035 } + }, + loc: { start: 5032, end: 5035 } + }, + loc: { start: 5029, end: 5035 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MIN' ] + }, + loc: { start: 5009, end: 5049 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'max', loc: { start: 5435, end: 5438 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5456, end: 5459 } + }, + loc: { start: 5456, end: 5459 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5439, end: 5440 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5442, end: 5445 } + }, + loc: { start: 5442, end: 5445 } + }, + loc: { start: 5439, end: 5445 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 5447, end: 5448 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5450, end: 5453 } + }, + loc: { start: 5450, end: 5453 } + }, + loc: { start: 5447, end: 5453 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MAX' ] + }, + loc: { start: 5427, end: 5467 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'abs', loc: { start: 5773, end: 5776 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5786, end: 5789 } + }, + loc: { start: 5786, end: 5789 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5777, end: 5778 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5780, end: 5783 } + }, + loc: { start: 5780, end: 5783 } + }, + loc: { start: 5777, end: 5783 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ABS' ] + }, + loc: { start: 5765, end: 5797 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'log', loc: { start: 6721, end: 6724 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6747, end: 6750 } + }, + loc: { start: 6747, end: 6750 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 6725, end: 6728 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6730, end: 6733 } + }, + loc: { start: 6730, end: 6733 } + }, + loc: { start: 6725, end: 6733 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'base', + loc: { start: 6735, end: 6739 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6741, end: 6744 } + }, + loc: { start: 6741, end: 6744 } + }, + loc: { start: 6735, end: 6744 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_log', + loc: { start: 6702, end: 6712 } + } + }, + loc: { start: 6696, end: 6751 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'log2', loc: { start: 7341, end: 7345 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7357, end: 7360 } + }, + loc: { start: 7357, end: 7360 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 7346, end: 7349 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7351, end: 7354 } + }, + loc: { start: 7351, end: 7354 } + }, + loc: { start: 7346, end: 7354 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DUP 5 THROWIFNOT UBITSIZE DEC' ] + }, + loc: { start: 7333, end: 7394 } + }, + { + kind: 'function', + inline: true, + name: { kind: 'id', text: 'pow', loc: { start: 8510, end: 8513 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8536, end: 8539 } + }, + loc: { start: 8536, end: 8539 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'base', + loc: { start: 8514, end: 8518 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8520, end: 8523 } + }, + loc: { start: 8520, end: 8523 } + }, + loc: { start: 8514, end: 8523 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'exp', + loc: { start: 8525, end: 8528 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8530, end: 8533 } + }, + loc: { start: 8530, end: 8533 } + }, + loc: { start: 8525, end: 8533 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throwUnless', + loc: { start: 8546, end: 8557 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 5n, + loc: { start: 8558, end: 8559 } + }, + { + kind: 'op_binary', + op: '>=', + left: { + kind: 'var', + name: 'exp', + loc: { start: 8561, end: 8564 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 8568, end: 8569 } + }, + loc: { start: 8561, end: 8569 } + } + ], + loc: { start: 8546, end: 8570 } + }, + loc: { start: 8546, end: 8571 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'result', + loc: { start: 8580, end: 8586 } + }, + type: undefined, + expression: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 8589, end: 8590 } + }, + loc: { start: 8576, end: 8591 } + }, + { + kind: 'statement_repeat', + iterations: { + kind: 'var', + name: 'exp', + loc: { start: 8604, end: 8607 } + }, + statements: [ + { + kind: 'statement_augmentedassign', + op: '*=', + path: { + kind: 'var', + name: 'result', + loc: { start: 8619, end: 8625 } + }, + expression: { + kind: 'var', + name: 'base', + loc: { start: 8629, end: 8633 } + }, + loc: { start: 8619, end: 8634 } + } + ], + loc: { start: 8596, end: 8640 } + }, + { + kind: 'statement_return', + expression: { + kind: 'var', + name: 'result', + loc: { start: 8652, end: 8658 } + }, + loc: { start: 8645, end: 8659 } + } + ] + }, + loc: { start: 8499, end: 8661 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'pow2', loc: { start: 9733, end: 9737 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9749, end: 9752 } + }, + loc: { start: 9749, end: 9752 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'exp', + loc: { start: 9738, end: 9741 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9743, end: 9746 } + }, + loc: { start: 9743, end: 9746 } + }, + loc: { start: 9738, end: 9746 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'POW2' ] + }, + loc: { start: 9725, end: 9761 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sign', + loc: { start: 10233, end: 10237 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10247, end: 10250 } + }, + loc: { start: 10247, end: 10250 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 10238, end: 10239 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10241, end: 10244 } + }, + loc: { start: 10241, end: 10244 } + }, + loc: { start: 10238, end: 10244 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SGN' ] + }, + loc: { start: 10225, end: 10258 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'divc', + loc: { start: 10814, end: 10818 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10836, end: 10839 } + }, + loc: { start: 10836, end: 10839 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 10819, end: 10820 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10822, end: 10825 } + }, + loc: { start: 10822, end: 10825 } + }, + loc: { start: 10819, end: 10825 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 10827, end: 10828 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10830, end: 10833 } + }, + loc: { start: 10830, end: 10833 } + }, + loc: { start: 10827, end: 10833 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DIVC' ] + }, + loc: { start: 10806, end: 10848 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'muldivc', + loc: { start: 11615, end: 11622 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11648, end: 11651 } + }, + loc: { start: 11648, end: 11651 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 11623, end: 11624 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11626, end: 11629 } + }, + loc: { start: 11626, end: 11629 } + }, + loc: { start: 11623, end: 11629 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 11631, end: 11632 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11634, end: 11637 } + }, + loc: { start: 11634, end: 11637 } + }, + loc: { start: 11631, end: 11637 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 11639, end: 11640 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11642, end: 11645 } + }, + loc: { start: 11642, end: 11645 } + }, + loc: { start: 11639, end: 11645 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULDIVC' ] + }, + loc: { start: 11607, end: 11663 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRight', + loc: { start: 12751, end: 12764 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12790, end: 12793 } + }, + loc: { start: 12790, end: 12793 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 12765, end: 12766 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12768, end: 12771 } + }, + loc: { start: 12768, end: 12771 } + }, + loc: { start: 12765, end: 12771 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 12773, end: 12774 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12776, end: 12779 } + }, + loc: { start: 12776, end: 12779 } + }, + loc: { start: 12773, end: 12779 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 12781, end: 12782 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12784, end: 12787 } + }, + loc: { start: 12784, end: 12787 } + }, + loc: { start: 12781, end: 12787 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFT' ] + }, + loc: { start: 12743, end: 12807 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRightRound', + loc: { start: 13862, end: 13880 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13906, end: 13909 } + }, + loc: { start: 13906, end: 13909 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 13881, end: 13882 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13884, end: 13887 } + }, + loc: { start: 13884, end: 13887 } + }, + loc: { start: 13881, end: 13887 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 13889, end: 13890 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13892, end: 13895 } + }, + loc: { start: 13892, end: 13895 } + }, + loc: { start: 13889, end: 13895 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 13897, end: 13898 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13900, end: 13903 } + }, + loc: { start: 13900, end: 13903 } + }, + loc: { start: 13897, end: 13903 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFTR' ] + }, + loc: { start: 13854, end: 13924 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRightCeil', + loc: { start: 14875, end: 14892 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14918, end: 14921 } + }, + loc: { start: 14918, end: 14921 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 14893, end: 14894 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14896, end: 14899 } + }, + loc: { start: 14896, end: 14899 } + }, + loc: { start: 14893, end: 14899 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 14901, end: 14902 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14904, end: 14907 } + }, + loc: { start: 14904, end: 14907 } + }, + loc: { start: 14901, end: 14907 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 14909, end: 14910 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14912, end: 14915 } + }, + loc: { start: 14912, end: 14915 } + }, + loc: { start: 14909, end: 14915 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFTC' ] + }, + loc: { start: 14867, end: 14936 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sqrt', + loc: { start: 15698, end: 15702 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15714, end: 15717 } + }, + loc: { start: 15714, end: 15717 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 15703, end: 15706 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15708, end: 15711 } + }, + loc: { start: 15708, end: 15711 } + }, + loc: { start: 15703, end: 15711 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'num', + loc: { start: 15728, end: 15731 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15735, end: 15736 } + }, + loc: { start: 15728, end: 15736 } + }, + trueStatements: [ + { + kind: 'statement_return', + expression: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15755, end: 15756 } + }, + loc: { start: 15748, end: 15757 } + } + ], + falseStatements: undefined, + loc: { start: 15724, end: 15763 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 's', + loc: { start: 15773, end: 15774 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15776, end: 15779 } + }, + loc: { start: 15776, end: 15779 } + }, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'log2', + loc: { start: 15782, end: 15786 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'num', + loc: { start: 15787, end: 15790 } + } + ], + loc: { start: 15782, end: 15791 } + }, + loc: { start: 15769, end: 15792 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'x', + loc: { start: 15801, end: 15802 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15804, end: 15807 } + }, + loc: { start: 15804, end: 15807 } + }, + expression: { + kind: 'conditional', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 's', + loc: { start: 15811, end: 15812 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15816, end: 15817 } + }, + loc: { start: 15811, end: 15817 } + }, + thenBranch: { + kind: 'op_binary', + op: '+', + left: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'num', + loc: { start: 15821, end: 15824 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15827, end: 15828 } + }, + loc: { start: 15821, end: 15828 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15832, end: 15833 } + }, + loc: { start: 15820, end: 15833 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15836, end: 15837 } + }, + loc: { start: 15820, end: 15837 } + }, + elseBranch: { + kind: 'op_binary', + op: '<<', + left: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15840, end: 15841 } + }, + right: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '+', + left: { + kind: 'var', + name: 's', + loc: { start: 15847, end: 15848 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15851, end: 15852 } + }, + loc: { start: 15847, end: 15852 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15856, end: 15857 } + }, + loc: { start: 15846, end: 15857 } + }, + loc: { start: 15840, end: 15858 } + }, + loc: { start: 15811, end: 15858 } + }, + loc: { start: 15797, end: 15860 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'q', + loc: { start: 15870, end: 15871 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15873, end: 15876 } + }, + loc: { start: 15873, end: 15876 } + }, + expression: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15879, end: 15880 } + }, + loc: { start: 15866, end: 15881 } + }, + { + kind: 'statement_until', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'q', + loc: { start: 15957, end: 15958 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15962, end: 15963 } + }, + loc: { start: 15957, end: 15963 } + }, + statements: [ + { + kind: 'statement_assign', + path: { + kind: 'var', + name: 'q', + loc: { start: 15900, end: 15901 } + }, + expression: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '-', + left: { + kind: 'static_call', + function: { + kind: 'id', + text: 'divc', + loc: { start: 15905, end: 15909 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'num', + loc: { start: 15910, end: 15913 } + }, + { + kind: 'var', + name: 'x', + loc: { start: 15915, end: 15916 } + } + ], + loc: { start: 15905, end: 15917 } + }, + right: { + kind: 'var', + name: 'x', + loc: { start: 15920, end: 15921 } + }, + loc: { start: 15905, end: 15921 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15925, end: 15926 } + }, + loc: { start: 15904, end: 15926 } + }, + loc: { start: 15900, end: 15927 } + }, + { + kind: 'statement_augmentedassign', + op: '+=', + path: { + kind: 'var', + name: 'x', + loc: { start: 15936, end: 15937 } + }, + expression: { + kind: 'var', + name: 'q', + loc: { start: 15941, end: 15942 } + }, + loc: { start: 15936, end: 15943 } + } + ], + loc: { start: 15887, end: 15965 } + }, + { + kind: 'statement_return', + expression: { + kind: 'var', + name: 'x', + loc: { start: 15978, end: 15979 } + }, + loc: { start: 15971, end: 15980 } + } + ] + }, + loc: { start: 15694, end: 15982 } + } + ] + }, + 'mulShiftRightCeil' => { + kind: 'tact', + path: 'std/internal/math.tact', + code: '// Prepare random\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Randomizes the pseudorandom number generator with the specified unsigned 256-bit `Int` `x` by mixing it with the current seed. The new seed is the unsigned 256-bit `Int` value of the SHA-256 hash of concatenated old seed and `x` in their 32-byte strings big-endian representation.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativeRandomize(42); // now, random numbers are less predictable\n' + + "/// let idk: Int = randomInt(); // ???, it's random,\n" + + '/// // but the seed was adjusted deterministically!\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify a negative value of `x`.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomize\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun nativeRandomize(x: Int) { ADDRAND }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Randomizes the random number generator with the logical time of the current transaction. Equivalent to calling `nativeRandomize(curLt())`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativeRandomizeLt(); // now, random numbers are unpredictable for users,\n' + + '/// // but still may be affected by validators or collators\n' + + '/// // as they determine the seed of the current block.\n' + + "/// let idk: Int = randomInt(); // ???, it's random!\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomizelt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomize\n' + + '/// * https://docs.tact-lang.org/ref/core-contextstate#curlt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + 'asm fun nativeRandomizeLt() { LTIME ADDRAND }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Prepares a random number generator by using `nativeRandomizeLt()`. Automatically called by `randomInt()` and `random()` functions.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativePrepareRandom(); // prepare the RNG\n' + + '/// // ... do your random things ...\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativepreparerandom\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomizelt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '/// * https://docs.tact-lang.org/ref/core-random#random\n' + + '///\n' + + '@name(__tact_prepare_random)\n' + + 'native nativePrepareRandom();\n' + + '\n' + + '// Random\n' + + '\n' + + '// Generates a new pseudo-random unsigned 256-bit integer x.\n' + + '// The algorithm is as follows: if r is the old value of the random seed,\n' + + '// considered as a 32-byte array (by constructing the big-endian representation\n' + + '// of an unsigned 256-bit integer), then its sha512(r) is computed;\n' + + "// the first 32 bytes of this hash are stored as the new value r' of the random seed,\n" + + '// and the remaining 32 bytes are returned as the next random value x.\n' + + 'asm fun nativeRandom(): Int { RANDU256 }\n' + + '\n' + + '// Generates a new pseudo-random integer z in the range 0..range−1\n' + + '// (or range..−1, if range < 0).\n' + + '// More precisely, an unsigned random value x is generated as in `nativeRandom`;\n' + + '// then z := x * range / 2^256 is computed.\n' + + 'asm fun nativeRandomInterval(max: Int): Int { RAND }\n' + + '\n' + + '/// Generates and returns a new pseudo-random unsigned 256-bit `Int` value `x`.\n' + + '///\n' + + '/// The algorithm works as follows: first, the `sha512(r)` is computed. There, `r` is an old\n' + + '/// value of the random seed, which is taken as a 32-byte array constructed from the big-endian\n' + + '/// representation of an unsigned 256-bit `Int`. The first 32 bytes of this hash are stored as the new\n' + + "/// value `r'` of the random seed, and the remaining 32 bytes are returned as the next random value `x`.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + "/// let allYourRandomBelongToUs: Int = randomInt(); // ???, it's random :)\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + 'inline fun randomInt(): Int {\n' + + ' nativePrepareRandom();\n' + + ' return nativeRandom();\n' + + '}\n' + + '\n' + + '/// Generates and returns a new pseudo-random unsigned `Int` value `x` in the provided semi-closed\n' + + '/// interval: `min` ≤ `x` < `max`, or `min` ≥ `x` > `max` if both `min` and `max` are negative.\n' + + '///\n' + + '/// Note that the `max` value is never included in the interval.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// random(42, 43); // 42, always\n' + + '/// random(0, 42); // 0-41, but never 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-random#random\n' + + '///\n' + + 'inline fun random(min: Int, max: Int): Int {\n' + + ' nativePrepareRandom();\n' + + ' return min + nativeRandomInterval(max - min);\n' + + '}\n' + + '\n' + + '// Math\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the minimum of two `Int` values `x` and `y`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// min(1, 2); // 1\n' + + '/// min(2, 2); // 2\n' + + '/// min(007, 3); // 3\n' + + '/// min(0x45, 3_0_0); // 69, nice\n' + + '/// // ↑ ↑\n' + + '/// // 69 300\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#min\n' + + '///\n' + + 'asm fun min(x: Int, y: Int): Int { MIN }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the maximum of two `Int` values `x` and `y`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// max(1, 2); // 2\n' + + '/// max(2, 2); // 2\n' + + '/// max(007, 3); // 7\n' + + '/// max(0x45, 3_0_0); // 300\n' + + '/// // ↑ ↑\n' + + '/// // 69 300\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#max\n' + + '///\n' + + 'asm fun max(x: Int, y: Int): Int { MAX }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the absolute value of the `Int` value `x`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// abs(42); // 42\n' + + '/// abs(-42); // 42\n' + + '/// abs(-(-(-42))); // 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#abs\n' + + '///\n' + + 'asm fun abs(x: Int): Int { ABS }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the logarithm of a number `num` > 0 to the base `base` ≥ 1. Results are rounded down.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// log(1000, 10); // 3, as 10^3 is 1000\n' + + '/// // ↑ ↑ ↑ ↑\n' + + '/// // num base base num\n' + + '///\n' + + '/// log(1001, 10); // 3\n' + + '/// log(999, 10); // 2\n' + + '/// try {\n' + + '/// log(-1000, 10); // exit code 5 because of the non-positive num\n' + + '/// }\n' + + '/// log(1024, 2); // 10\n' + + '/// try {\n' + + '/// log(1024, -2); // exit code 5 because the base is less than 1\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `num` value is non-positive\n' + + '/// or the given `base` value is less than 1.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log2\n' + + '///\n' + + '@name(__tact_log)\n' + + 'native log(num: Int, base: Int): Int;\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Similar to `log()`, but sets the `base` to 2.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// log2(1024); // 10, as 2^10 is 1024\n' + + '/// // ↑ ↑ ↑\n' + + '/// // num base₂ num\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `num` value is non-positive.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log2\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log.\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes/#5\n' + + '///\n' + + 'asm fun log2(num: Int): Int { DUP 5 THROWIFNOT UBITSIZE DEC }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the exponentiation involving two numbers: the `base` and the exponent (or _power_) `exp`.\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Example {\n' + + '/// // Persistent state variables\n' + + '/// p23: Int = pow(2, 3); // raises 2 to the 3rd power, which is 8\n' + + '/// one: Int = pow(5, 0); // raises 5 to the power 0, which always produces 1\n' + + '/// // works at compile-time!\n' + + '///\n' + + '/// // Internal message receiver\n' + + '/// receive() {\n' + + '/// pow(self.p23, self.one + 1); // 64, works at run-time too!\n' + + '/// try {\n' + + '/// pow(0, -1); // exit code 5: Integer out of expected range\n' + + '/// }\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `exp` value is negative.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow2\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes/#5\n' + + '///\n' + + 'inline fun pow(base: Int, exp: Int): Int {\n' + + ' throwUnless(5, exp >= 0);\n' + + ' let result = 1;\n' + + ' repeat (exp) {\n' + + ' result *= base;\n' + + ' }\n' + + ' return result;\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Similar to `pow()`, but sets the `base` to 2.\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Example {\n' + + '/// // Persistent state variables\n' + + '/// p23: Int = pow2(3); // raises 2 to the 3rd power, which is 8\n' + + '/// one: Int = pow2(0); // raises 2 to the power 0, which always produces 1\n' + + '/// // works at compile-time!\n' + + '///\n' + + '/// // Internal message receiver, which accepts message ExtMsg\n' + + '/// receive() {\n' + + '/// pow2(self.one + 1); // 4, works at run-time too!\n' + + '/// try {\n' + + '/// pow(-1); // exit code 5: Integer out of expected range\n' + + '/// }\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify a negative value of `exp`.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow2\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun pow2(exp: Int): Int { POW2 }\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Computes and returns the sign of the `Int` value `x`. Produces 1 if the `x` is positive, -1 if the `x` is negative, and 0 if the `x` is 0.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// '... 5983 more characters, + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomize', + loc: { start: 965, end: 980 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { kind: 'id', text: 'x', loc: { start: 981, end: 982 } }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 984, end: 987 } + }, + loc: { start: 984, end: 987 } + }, + loc: { start: 981, end: 987 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ADDRAND' ] + }, + loc: { start: 957, end: 1000 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomizeLt', + loc: { start: 1822, end: 1839 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LTIME ADDRAND' ] + }, + loc: { start: 1814, end: 1859 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 2466, end: 2485 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_prepare_random', + loc: { start: 2436, end: 2457 } + } + }, + loc: { start: 2430, end: 2488 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandom', + loc: { start: 2949, end: 2961 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2965, end: 2968 } + }, + loc: { start: 2965, end: 2968 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RANDU256' ] + }, + loc: { start: 2941, end: 2981 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomInterval', + loc: { start: 3216, end: 3236 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3248, end: 3251 } + }, + loc: { start: 3248, end: 3251 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'max', + loc: { start: 3237, end: 3240 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3242, end: 3245 } + }, + loc: { start: 3242, end: 3245 } + }, + loc: { start: 3237, end: 3245 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RAND' ] + }, + loc: { start: 3208, end: 3260 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'randomInt', + loc: { start: 3953, end: 3962 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3966, end: 3969 } + }, + loc: { start: 3966, end: 3969 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 3976, end: 3995 } + }, + typeArgs: [], + args: [], + loc: { start: 3976, end: 3997 } + }, + loc: { start: 3976, end: 3998 } + }, + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativeRandom', + loc: { start: 4010, end: 4022 } + }, + typeArgs: [], + args: [], + loc: { start: 4010, end: 4024 } + }, + loc: { start: 4003, end: 4025 } + } + ] + }, + loc: { start: 3942, end: 4027 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'random', + loc: { start: 4505, end: 4511 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4533, end: 4536 } + }, + loc: { start: 4533, end: 4536 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'min', + loc: { start: 4512, end: 4515 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4517, end: 4520 } + }, + loc: { start: 4517, end: 4520 } + }, + loc: { start: 4512, end: 4520 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'max', + loc: { start: 4522, end: 4525 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4527, end: 4530 } + }, + loc: { start: 4527, end: 4530 } + }, + loc: { start: 4522, end: 4530 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 4543, end: 4562 } + }, + typeArgs: [], + args: [], + loc: { start: 4543, end: 4564 } + }, + loc: { start: 4543, end: 4565 } + }, + { + kind: 'statement_return', + expression: { + kind: 'op_binary', + op: '+', + left: { + kind: 'var', + name: 'min', + loc: { start: 4577, end: 4580 } + }, + right: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativeRandomInterval', + loc: { start: 4583, end: 4603 } + }, + typeArgs: [], + args: [ + { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'max', + loc: { start: 4604, end: 4607 } + }, + right: { + kind: 'var', + name: 'min', + loc: { start: 4610, end: 4613 } + }, + loc: { start: 4604, end: 4613 } + } + ], + loc: { start: 4583, end: 4614 } + }, + loc: { start: 4577, end: 4614 } + }, + loc: { start: 4570, end: 4615 } + } + ] + }, + loc: { start: 4494, end: 4617 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'min', loc: { start: 5017, end: 5020 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5038, end: 5041 } + }, + loc: { start: 5038, end: 5041 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5021, end: 5022 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5024, end: 5027 } + }, + loc: { start: 5024, end: 5027 } + }, + loc: { start: 5021, end: 5027 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 5029, end: 5030 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5032, end: 5035 } + }, + loc: { start: 5032, end: 5035 } + }, + loc: { start: 5029, end: 5035 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MIN' ] + }, + loc: { start: 5009, end: 5049 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'max', loc: { start: 5435, end: 5438 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5456, end: 5459 } + }, + loc: { start: 5456, end: 5459 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5439, end: 5440 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5442, end: 5445 } + }, + loc: { start: 5442, end: 5445 } + }, + loc: { start: 5439, end: 5445 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 5447, end: 5448 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5450, end: 5453 } + }, + loc: { start: 5450, end: 5453 } + }, + loc: { start: 5447, end: 5453 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MAX' ] + }, + loc: { start: 5427, end: 5467 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'abs', loc: { start: 5773, end: 5776 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5786, end: 5789 } + }, + loc: { start: 5786, end: 5789 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5777, end: 5778 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5780, end: 5783 } + }, + loc: { start: 5780, end: 5783 } + }, + loc: { start: 5777, end: 5783 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ABS' ] + }, + loc: { start: 5765, end: 5797 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'log', loc: { start: 6721, end: 6724 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6747, end: 6750 } + }, + loc: { start: 6747, end: 6750 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 6725, end: 6728 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6730, end: 6733 } + }, + loc: { start: 6730, end: 6733 } + }, + loc: { start: 6725, end: 6733 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'base', + loc: { start: 6735, end: 6739 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6741, end: 6744 } + }, + loc: { start: 6741, end: 6744 } + }, + loc: { start: 6735, end: 6744 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_log', + loc: { start: 6702, end: 6712 } + } + }, + loc: { start: 6696, end: 6751 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'log2', loc: { start: 7341, end: 7345 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7357, end: 7360 } + }, + loc: { start: 7357, end: 7360 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 7346, end: 7349 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7351, end: 7354 } + }, + loc: { start: 7351, end: 7354 } + }, + loc: { start: 7346, end: 7354 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DUP 5 THROWIFNOT UBITSIZE DEC' ] + }, + loc: { start: 7333, end: 7394 } + }, + { + kind: 'function', + inline: true, + name: { kind: 'id', text: 'pow', loc: { start: 8510, end: 8513 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8536, end: 8539 } + }, + loc: { start: 8536, end: 8539 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'base', + loc: { start: 8514, end: 8518 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8520, end: 8523 } + }, + loc: { start: 8520, end: 8523 } + }, + loc: { start: 8514, end: 8523 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'exp', + loc: { start: 8525, end: 8528 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8530, end: 8533 } + }, + loc: { start: 8530, end: 8533 } + }, + loc: { start: 8525, end: 8533 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throwUnless', + loc: { start: 8546, end: 8557 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 5n, + loc: { start: 8558, end: 8559 } + }, + { + kind: 'op_binary', + op: '>=', + left: { + kind: 'var', + name: 'exp', + loc: { start: 8561, end: 8564 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 8568, end: 8569 } + }, + loc: { start: 8561, end: 8569 } + } + ], + loc: { start: 8546, end: 8570 } + }, + loc: { start: 8546, end: 8571 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'result', + loc: { start: 8580, end: 8586 } + }, + type: undefined, + expression: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 8589, end: 8590 } + }, + loc: { start: 8576, end: 8591 } + }, + { + kind: 'statement_repeat', + iterations: { + kind: 'var', + name: 'exp', + loc: { start: 8604, end: 8607 } + }, + statements: [ + { + kind: 'statement_augmentedassign', + op: '*=', + path: { + kind: 'var', + name: 'result', + loc: { start: 8619, end: 8625 } + }, + expression: { + kind: 'var', + name: 'base', + loc: { start: 8629, end: 8633 } + }, + loc: { start: 8619, end: 8634 } + } + ], + loc: { start: 8596, end: 8640 } + }, + { + kind: 'statement_return', + expression: { + kind: 'var', + name: 'result', + loc: { start: 8652, end: 8658 } + }, + loc: { start: 8645, end: 8659 } + } + ] + }, + loc: { start: 8499, end: 8661 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'pow2', loc: { start: 9733, end: 9737 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9749, end: 9752 } + }, + loc: { start: 9749, end: 9752 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'exp', + loc: { start: 9738, end: 9741 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9743, end: 9746 } + }, + loc: { start: 9743, end: 9746 } + }, + loc: { start: 9738, end: 9746 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'POW2' ] + }, + loc: { start: 9725, end: 9761 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sign', + loc: { start: 10233, end: 10237 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10247, end: 10250 } + }, + loc: { start: 10247, end: 10250 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 10238, end: 10239 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10241, end: 10244 } + }, + loc: { start: 10241, end: 10244 } + }, + loc: { start: 10238, end: 10244 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SGN' ] + }, + loc: { start: 10225, end: 10258 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'divc', + loc: { start: 10814, end: 10818 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10836, end: 10839 } + }, + loc: { start: 10836, end: 10839 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 10819, end: 10820 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10822, end: 10825 } + }, + loc: { start: 10822, end: 10825 } + }, + loc: { start: 10819, end: 10825 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 10827, end: 10828 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10830, end: 10833 } + }, + loc: { start: 10830, end: 10833 } + }, + loc: { start: 10827, end: 10833 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DIVC' ] + }, + loc: { start: 10806, end: 10848 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'muldivc', + loc: { start: 11615, end: 11622 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11648, end: 11651 } + }, + loc: { start: 11648, end: 11651 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 11623, end: 11624 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11626, end: 11629 } + }, + loc: { start: 11626, end: 11629 } + }, + loc: { start: 11623, end: 11629 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 11631, end: 11632 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11634, end: 11637 } + }, + loc: { start: 11634, end: 11637 } + }, + loc: { start: 11631, end: 11637 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 11639, end: 11640 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11642, end: 11645 } + }, + loc: { start: 11642, end: 11645 } + }, + loc: { start: 11639, end: 11645 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULDIVC' ] + }, + loc: { start: 11607, end: 11663 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRight', + loc: { start: 12751, end: 12764 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12790, end: 12793 } + }, + loc: { start: 12790, end: 12793 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 12765, end: 12766 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12768, end: 12771 } + }, + loc: { start: 12768, end: 12771 } + }, + loc: { start: 12765, end: 12771 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 12773, end: 12774 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12776, end: 12779 } + }, + loc: { start: 12776, end: 12779 } + }, + loc: { start: 12773, end: 12779 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 12781, end: 12782 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12784, end: 12787 } + }, + loc: { start: 12784, end: 12787 } + }, + loc: { start: 12781, end: 12787 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFT' ] + }, + loc: { start: 12743, end: 12807 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRightRound', + loc: { start: 13862, end: 13880 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13906, end: 13909 } + }, + loc: { start: 13906, end: 13909 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 13881, end: 13882 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13884, end: 13887 } + }, + loc: { start: 13884, end: 13887 } + }, + loc: { start: 13881, end: 13887 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 13889, end: 13890 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13892, end: 13895 } + }, + loc: { start: 13892, end: 13895 } + }, + loc: { start: 13889, end: 13895 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 13897, end: 13898 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13900, end: 13903 } + }, + loc: { start: 13900, end: 13903 } + }, + loc: { start: 13897, end: 13903 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFTR' ] + }, + loc: { start: 13854, end: 13924 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRightCeil', + loc: { start: 14875, end: 14892 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14918, end: 14921 } + }, + loc: { start: 14918, end: 14921 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 14893, end: 14894 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14896, end: 14899 } + }, + loc: { start: 14896, end: 14899 } + }, + loc: { start: 14893, end: 14899 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 14901, end: 14902 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14904, end: 14907 } + }, + loc: { start: 14904, end: 14907 } + }, + loc: { start: 14901, end: 14907 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 14909, end: 14910 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14912, end: 14915 } + }, + loc: { start: 14912, end: 14915 } + }, + loc: { start: 14909, end: 14915 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFTC' ] + }, + loc: { start: 14867, end: 14936 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sqrt', + loc: { start: 15698, end: 15702 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15714, end: 15717 } + }, + loc: { start: 15714, end: 15717 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 15703, end: 15706 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15708, end: 15711 } + }, + loc: { start: 15708, end: 15711 } + }, + loc: { start: 15703, end: 15711 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'num', + loc: { start: 15728, end: 15731 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15735, end: 15736 } + }, + loc: { start: 15728, end: 15736 } + }, + trueStatements: [ + { + kind: 'statement_return', + expression: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15755, end: 15756 } + }, + loc: { start: 15748, end: 15757 } + } + ], + falseStatements: undefined, + loc: { start: 15724, end: 15763 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 's', + loc: { start: 15773, end: 15774 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15776, end: 15779 } + }, + loc: { start: 15776, end: 15779 } + }, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'log2', + loc: { start: 15782, end: 15786 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'num', + loc: { start: 15787, end: 15790 } + } + ], + loc: { start: 15782, end: 15791 } + }, + loc: { start: 15769, end: 15792 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'x', + loc: { start: 15801, end: 15802 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15804, end: 15807 } + }, + loc: { start: 15804, end: 15807 } + }, + expression: { + kind: 'conditional', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 's', + loc: { start: 15811, end: 15812 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15816, end: 15817 } + }, + loc: { start: 15811, end: 15817 } + }, + thenBranch: { + kind: 'op_binary', + op: '+', + left: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'num', + loc: { start: 15821, end: 15824 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15827, end: 15828 } + }, + loc: { start: 15821, end: 15828 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15832, end: 15833 } + }, + loc: { start: 15820, end: 15833 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15836, end: 15837 } + }, + loc: { start: 15820, end: 15837 } + }, + elseBranch: { + kind: 'op_binary', + op: '<<', + left: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15840, end: 15841 } + }, + right: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '+', + left: { + kind: 'var', + name: 's', + loc: { start: 15847, end: 15848 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15851, end: 15852 } + }, + loc: { start: 15847, end: 15852 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15856, end: 15857 } + }, + loc: { start: 15846, end: 15857 } + }, + loc: { start: 15840, end: 15858 } + }, + loc: { start: 15811, end: 15858 } + }, + loc: { start: 15797, end: 15860 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'q', + loc: { start: 15870, end: 15871 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15873, end: 15876 } + }, + loc: { start: 15873, end: 15876 } + }, + expression: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15879, end: 15880 } + }, + loc: { start: 15866, end: 15881 } + }, + { + kind: 'statement_until', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'q', + loc: { start: 15957, end: 15958 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15962, end: 15963 } + }, + loc: { start: 15957, end: 15963 } + }, + statements: [ + { + kind: 'statement_assign', + path: { + kind: 'var', + name: 'q', + loc: { start: 15900, end: 15901 } + }, + expression: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '-', + left: { + kind: 'static_call', + function: { + kind: 'id', + text: 'divc', + loc: { start: 15905, end: 15909 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'num', + loc: { start: 15910, end: 15913 } + }, + { + kind: 'var', + name: 'x', + loc: { start: 15915, end: 15916 } + } + ], + loc: { start: 15905, end: 15917 } + }, + right: { + kind: 'var', + name: 'x', + loc: { start: 15920, end: 15921 } + }, + loc: { start: 15905, end: 15921 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15925, end: 15926 } + }, + loc: { start: 15904, end: 15926 } + }, + loc: { start: 15900, end: 15927 } + }, + { + kind: 'statement_augmentedassign', + op: '+=', + path: { + kind: 'var', + name: 'x', + loc: { start: 15936, end: 15937 } + }, + expression: { + kind: 'var', + name: 'q', + loc: { start: 15941, end: 15942 } + }, + loc: { start: 15936, end: 15943 } + } + ], + loc: { start: 15887, end: 15965 } + }, + { + kind: 'statement_return', + expression: { + kind: 'var', + name: 'x', + loc: { start: 15978, end: 15979 } + }, + loc: { start: 15971, end: 15980 } + } + ] + }, + loc: { start: 15694, end: 15982 } + } + ] + }, + 'sqrt' => { + kind: 'tact', + path: 'std/internal/math.tact', + code: '// Prepare random\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Randomizes the pseudorandom number generator with the specified unsigned 256-bit `Int` `x` by mixing it with the current seed. The new seed is the unsigned 256-bit `Int` value of the SHA-256 hash of concatenated old seed and `x` in their 32-byte strings big-endian representation.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativeRandomize(42); // now, random numbers are less predictable\n' + + "/// let idk: Int = randomInt(); // ???, it's random,\n" + + '/// // but the seed was adjusted deterministically!\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify a negative value of `x`.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomize\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun nativeRandomize(x: Int) { ADDRAND }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Randomizes the random number generator with the logical time of the current transaction. Equivalent to calling `nativeRandomize(curLt())`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativeRandomizeLt(); // now, random numbers are unpredictable for users,\n' + + '/// // but still may be affected by validators or collators\n' + + '/// // as they determine the seed of the current block.\n' + + "/// let idk: Int = randomInt(); // ???, it's random!\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomizelt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomize\n' + + '/// * https://docs.tact-lang.org/ref/core-contextstate#curlt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + 'asm fun nativeRandomizeLt() { LTIME ADDRAND }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Prepares a random number generator by using `nativeRandomizeLt()`. Automatically called by `randomInt()` and `random()` functions.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativePrepareRandom(); // prepare the RNG\n' + + '/// // ... do your random things ...\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativepreparerandom\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomizelt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '/// * https://docs.tact-lang.org/ref/core-random#random\n' + + '///\n' + + '@name(__tact_prepare_random)\n' + + 'native nativePrepareRandom();\n' + + '\n' + + '// Random\n' + + '\n' + + '// Generates a new pseudo-random unsigned 256-bit integer x.\n' + + '// The algorithm is as follows: if r is the old value of the random seed,\n' + + '// considered as a 32-byte array (by constructing the big-endian representation\n' + + '// of an unsigned 256-bit integer), then its sha512(r) is computed;\n' + + "// the first 32 bytes of this hash are stored as the new value r' of the random seed,\n" + + '// and the remaining 32 bytes are returned as the next random value x.\n' + + 'asm fun nativeRandom(): Int { RANDU256 }\n' + + '\n' + + '// Generates a new pseudo-random integer z in the range 0..range−1\n' + + '// (or range..−1, if range < 0).\n' + + '// More precisely, an unsigned random value x is generated as in `nativeRandom`;\n' + + '// then z := x * range / 2^256 is computed.\n' + + 'asm fun nativeRandomInterval(max: Int): Int { RAND }\n' + + '\n' + + '/// Generates and returns a new pseudo-random unsigned 256-bit `Int` value `x`.\n' + + '///\n' + + '/// The algorithm works as follows: first, the `sha512(r)` is computed. There, `r` is an old\n' + + '/// value of the random seed, which is taken as a 32-byte array constructed from the big-endian\n' + + '/// representation of an unsigned 256-bit `Int`. The first 32 bytes of this hash are stored as the new\n' + + "/// value `r'` of the random seed, and the remaining 32 bytes are returned as the next random value `x`.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + "/// let allYourRandomBelongToUs: Int = randomInt(); // ???, it's random :)\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + 'inline fun randomInt(): Int {\n' + + ' nativePrepareRandom();\n' + + ' return nativeRandom();\n' + + '}\n' + + '\n' + + '/// Generates and returns a new pseudo-random unsigned `Int` value `x` in the provided semi-closed\n' + + '/// interval: `min` ≤ `x` < `max`, or `min` ≥ `x` > `max` if both `min` and `max` are negative.\n' + + '///\n' + + '/// Note that the `max` value is never included in the interval.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// random(42, 43); // 42, always\n' + + '/// random(0, 42); // 0-41, but never 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-random#random\n' + + '///\n' + + 'inline fun random(min: Int, max: Int): Int {\n' + + ' nativePrepareRandom();\n' + + ' return min + nativeRandomInterval(max - min);\n' + + '}\n' + + '\n' + + '// Math\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the minimum of two `Int` values `x` and `y`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// min(1, 2); // 1\n' + + '/// min(2, 2); // 2\n' + + '/// min(007, 3); // 3\n' + + '/// min(0x45, 3_0_0); // 69, nice\n' + + '/// // ↑ ↑\n' + + '/// // 69 300\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#min\n' + + '///\n' + + 'asm fun min(x: Int, y: Int): Int { MIN }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the maximum of two `Int` values `x` and `y`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// max(1, 2); // 2\n' + + '/// max(2, 2); // 2\n' + + '/// max(007, 3); // 7\n' + + '/// max(0x45, 3_0_0); // 300\n' + + '/// // ↑ ↑\n' + + '/// // 69 300\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#max\n' + + '///\n' + + 'asm fun max(x: Int, y: Int): Int { MAX }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the absolute value of the `Int` value `x`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// abs(42); // 42\n' + + '/// abs(-42); // 42\n' + + '/// abs(-(-(-42))); // 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#abs\n' + + '///\n' + + 'asm fun abs(x: Int): Int { ABS }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the logarithm of a number `num` > 0 to the base `base` ≥ 1. Results are rounded down.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// log(1000, 10); // 3, as 10^3 is 1000\n' + + '/// // ↑ ↑ ↑ ↑\n' + + '/// // num base base num\n' + + '///\n' + + '/// log(1001, 10); // 3\n' + + '/// log(999, 10); // 2\n' + + '/// try {\n' + + '/// log(-1000, 10); // exit code 5 because of the non-positive num\n' + + '/// }\n' + + '/// log(1024, 2); // 10\n' + + '/// try {\n' + + '/// log(1024, -2); // exit code 5 because the base is less than 1\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `num` value is non-positive\n' + + '/// or the given `base` value is less than 1.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log2\n' + + '///\n' + + '@name(__tact_log)\n' + + 'native log(num: Int, base: Int): Int;\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Similar to `log()`, but sets the `base` to 2.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// log2(1024); // 10, as 2^10 is 1024\n' + + '/// // ↑ ↑ ↑\n' + + '/// // num base₂ num\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `num` value is non-positive.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log2\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log.\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes/#5\n' + + '///\n' + + 'asm fun log2(num: Int): Int { DUP 5 THROWIFNOT UBITSIZE DEC }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the exponentiation involving two numbers: the `base` and the exponent (or _power_) `exp`.\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Example {\n' + + '/// // Persistent state variables\n' + + '/// p23: Int = pow(2, 3); // raises 2 to the 3rd power, which is 8\n' + + '/// one: Int = pow(5, 0); // raises 5 to the power 0, which always produces 1\n' + + '/// // works at compile-time!\n' + + '///\n' + + '/// // Internal message receiver\n' + + '/// receive() {\n' + + '/// pow(self.p23, self.one + 1); // 64, works at run-time too!\n' + + '/// try {\n' + + '/// pow(0, -1); // exit code 5: Integer out of expected range\n' + + '/// }\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `exp` value is negative.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow2\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes/#5\n' + + '///\n' + + 'inline fun pow(base: Int, exp: Int): Int {\n' + + ' throwUnless(5, exp >= 0);\n' + + ' let result = 1;\n' + + ' repeat (exp) {\n' + + ' result *= base;\n' + + ' }\n' + + ' return result;\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Similar to `pow()`, but sets the `base` to 2.\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Example {\n' + + '/// // Persistent state variables\n' + + '/// p23: Int = pow2(3); // raises 2 to the 3rd power, which is 8\n' + + '/// one: Int = pow2(0); // raises 2 to the power 0, which always produces 1\n' + + '/// // works at compile-time!\n' + + '///\n' + + '/// // Internal message receiver, which accepts message ExtMsg\n' + + '/// receive() {\n' + + '/// pow2(self.one + 1); // 4, works at run-time too!\n' + + '/// try {\n' + + '/// pow(-1); // exit code 5: Integer out of expected range\n' + + '/// }\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify a negative value of `exp`.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow2\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun pow2(exp: Int): Int { POW2 }\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Computes and returns the sign of the `Int` value `x`. Produces 1 if the `x` is positive, -1 if the `x` is negative, and 0 if the `x` is 0.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// '... 5983 more characters, + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomize', + loc: { start: 965, end: 980 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { kind: 'id', text: 'x', loc: { start: 981, end: 982 } }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 984, end: 987 } + }, + loc: { start: 984, end: 987 } + }, + loc: { start: 981, end: 987 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ADDRAND' ] + }, + loc: { start: 957, end: 1000 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomizeLt', + loc: { start: 1822, end: 1839 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LTIME ADDRAND' ] + }, + loc: { start: 1814, end: 1859 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 2466, end: 2485 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_prepare_random', + loc: { start: 2436, end: 2457 } + } + }, + loc: { start: 2430, end: 2488 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandom', + loc: { start: 2949, end: 2961 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2965, end: 2968 } + }, + loc: { start: 2965, end: 2968 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RANDU256' ] + }, + loc: { start: 2941, end: 2981 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomInterval', + loc: { start: 3216, end: 3236 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3248, end: 3251 } + }, + loc: { start: 3248, end: 3251 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'max', + loc: { start: 3237, end: 3240 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3242, end: 3245 } + }, + loc: { start: 3242, end: 3245 } + }, + loc: { start: 3237, end: 3245 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RAND' ] + }, + loc: { start: 3208, end: 3260 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'randomInt', + loc: { start: 3953, end: 3962 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3966, end: 3969 } + }, + loc: { start: 3966, end: 3969 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 3976, end: 3995 } + }, + typeArgs: [], + args: [], + loc: { start: 3976, end: 3997 } + }, + loc: { start: 3976, end: 3998 } + }, + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativeRandom', + loc: { start: 4010, end: 4022 } + }, + typeArgs: [], + args: [], + loc: { start: 4010, end: 4024 } + }, + loc: { start: 4003, end: 4025 } + } + ] + }, + loc: { start: 3942, end: 4027 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'random', + loc: { start: 4505, end: 4511 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4533, end: 4536 } + }, + loc: { start: 4533, end: 4536 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'min', + loc: { start: 4512, end: 4515 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4517, end: 4520 } + }, + loc: { start: 4517, end: 4520 } + }, + loc: { start: 4512, end: 4520 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'max', + loc: { start: 4522, end: 4525 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4527, end: 4530 } + }, + loc: { start: 4527, end: 4530 } + }, + loc: { start: 4522, end: 4530 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 4543, end: 4562 } + }, + typeArgs: [], + args: [], + loc: { start: 4543, end: 4564 } + }, + loc: { start: 4543, end: 4565 } + }, + { + kind: 'statement_return', + expression: { + kind: 'op_binary', + op: '+', + left: { + kind: 'var', + name: 'min', + loc: { start: 4577, end: 4580 } + }, + right: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativeRandomInterval', + loc: { start: 4583, end: 4603 } + }, + typeArgs: [], + args: [ + { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'max', + loc: { start: 4604, end: 4607 } + }, + right: { + kind: 'var', + name: 'min', + loc: { start: 4610, end: 4613 } + }, + loc: { start: 4604, end: 4613 } + } + ], + loc: { start: 4583, end: 4614 } + }, + loc: { start: 4577, end: 4614 } + }, + loc: { start: 4570, end: 4615 } + } + ] + }, + loc: { start: 4494, end: 4617 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'min', loc: { start: 5017, end: 5020 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5038, end: 5041 } + }, + loc: { start: 5038, end: 5041 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5021, end: 5022 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5024, end: 5027 } + }, + loc: { start: 5024, end: 5027 } + }, + loc: { start: 5021, end: 5027 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 5029, end: 5030 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5032, end: 5035 } + }, + loc: { start: 5032, end: 5035 } + }, + loc: { start: 5029, end: 5035 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MIN' ] + }, + loc: { start: 5009, end: 5049 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'max', loc: { start: 5435, end: 5438 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5456, end: 5459 } + }, + loc: { start: 5456, end: 5459 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5439, end: 5440 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5442, end: 5445 } + }, + loc: { start: 5442, end: 5445 } + }, + loc: { start: 5439, end: 5445 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 5447, end: 5448 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5450, end: 5453 } + }, + loc: { start: 5450, end: 5453 } + }, + loc: { start: 5447, end: 5453 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MAX' ] + }, + loc: { start: 5427, end: 5467 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'abs', loc: { start: 5773, end: 5776 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5786, end: 5789 } + }, + loc: { start: 5786, end: 5789 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5777, end: 5778 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5780, end: 5783 } + }, + loc: { start: 5780, end: 5783 } + }, + loc: { start: 5777, end: 5783 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ABS' ] + }, + loc: { start: 5765, end: 5797 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'log', loc: { start: 6721, end: 6724 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6747, end: 6750 } + }, + loc: { start: 6747, end: 6750 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 6725, end: 6728 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6730, end: 6733 } + }, + loc: { start: 6730, end: 6733 } + }, + loc: { start: 6725, end: 6733 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'base', + loc: { start: 6735, end: 6739 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6741, end: 6744 } + }, + loc: { start: 6741, end: 6744 } + }, + loc: { start: 6735, end: 6744 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_log', + loc: { start: 6702, end: 6712 } + } + }, + loc: { start: 6696, end: 6751 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'log2', loc: { start: 7341, end: 7345 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7357, end: 7360 } + }, + loc: { start: 7357, end: 7360 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 7346, end: 7349 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7351, end: 7354 } + }, + loc: { start: 7351, end: 7354 } + }, + loc: { start: 7346, end: 7354 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DUP 5 THROWIFNOT UBITSIZE DEC' ] + }, + loc: { start: 7333, end: 7394 } + }, + { + kind: 'function', + inline: true, + name: { kind: 'id', text: 'pow', loc: { start: 8510, end: 8513 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8536, end: 8539 } + }, + loc: { start: 8536, end: 8539 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'base', + loc: { start: 8514, end: 8518 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8520, end: 8523 } + }, + loc: { start: 8520, end: 8523 } + }, + loc: { start: 8514, end: 8523 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'exp', + loc: { start: 8525, end: 8528 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8530, end: 8533 } + }, + loc: { start: 8530, end: 8533 } + }, + loc: { start: 8525, end: 8533 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throwUnless', + loc: { start: 8546, end: 8557 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 5n, + loc: { start: 8558, end: 8559 } + }, + { + kind: 'op_binary', + op: '>=', + left: { + kind: 'var', + name: 'exp', + loc: { start: 8561, end: 8564 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 8568, end: 8569 } + }, + loc: { start: 8561, end: 8569 } + } + ], + loc: { start: 8546, end: 8570 } + }, + loc: { start: 8546, end: 8571 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'result', + loc: { start: 8580, end: 8586 } + }, + type: undefined, + expression: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 8589, end: 8590 } + }, + loc: { start: 8576, end: 8591 } + }, + { + kind: 'statement_repeat', + iterations: { + kind: 'var', + name: 'exp', + loc: { start: 8604, end: 8607 } + }, + statements: [ + { + kind: 'statement_augmentedassign', + op: '*=', + path: { + kind: 'var', + name: 'result', + loc: { start: 8619, end: 8625 } + }, + expression: { + kind: 'var', + name: 'base', + loc: { start: 8629, end: 8633 } + }, + loc: { start: 8619, end: 8634 } + } + ], + loc: { start: 8596, end: 8640 } + }, + { + kind: 'statement_return', + expression: { + kind: 'var', + name: 'result', + loc: { start: 8652, end: 8658 } + }, + loc: { start: 8645, end: 8659 } + } + ] + }, + loc: { start: 8499, end: 8661 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'pow2', loc: { start: 9733, end: 9737 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9749, end: 9752 } + }, + loc: { start: 9749, end: 9752 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'exp', + loc: { start: 9738, end: 9741 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9743, end: 9746 } + }, + loc: { start: 9743, end: 9746 } + }, + loc: { start: 9738, end: 9746 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'POW2' ] + }, + loc: { start: 9725, end: 9761 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sign', + loc: { start: 10233, end: 10237 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10247, end: 10250 } + }, + loc: { start: 10247, end: 10250 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 10238, end: 10239 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10241, end: 10244 } + }, + loc: { start: 10241, end: 10244 } + }, + loc: { start: 10238, end: 10244 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SGN' ] + }, + loc: { start: 10225, end: 10258 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'divc', + loc: { start: 10814, end: 10818 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10836, end: 10839 } + }, + loc: { start: 10836, end: 10839 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 10819, end: 10820 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10822, end: 10825 } + }, + loc: { start: 10822, end: 10825 } + }, + loc: { start: 10819, end: 10825 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 10827, end: 10828 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10830, end: 10833 } + }, + loc: { start: 10830, end: 10833 } + }, + loc: { start: 10827, end: 10833 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DIVC' ] + }, + loc: { start: 10806, end: 10848 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'muldivc', + loc: { start: 11615, end: 11622 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11648, end: 11651 } + }, + loc: { start: 11648, end: 11651 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 11623, end: 11624 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11626, end: 11629 } + }, + loc: { start: 11626, end: 11629 } + }, + loc: { start: 11623, end: 11629 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 11631, end: 11632 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11634, end: 11637 } + }, + loc: { start: 11634, end: 11637 } + }, + loc: { start: 11631, end: 11637 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 11639, end: 11640 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11642, end: 11645 } + }, + loc: { start: 11642, end: 11645 } + }, + loc: { start: 11639, end: 11645 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULDIVC' ] + }, + loc: { start: 11607, end: 11663 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRight', + loc: { start: 12751, end: 12764 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12790, end: 12793 } + }, + loc: { start: 12790, end: 12793 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 12765, end: 12766 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12768, end: 12771 } + }, + loc: { start: 12768, end: 12771 } + }, + loc: { start: 12765, end: 12771 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 12773, end: 12774 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12776, end: 12779 } + }, + loc: { start: 12776, end: 12779 } + }, + loc: { start: 12773, end: 12779 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 12781, end: 12782 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12784, end: 12787 } + }, + loc: { start: 12784, end: 12787 } + }, + loc: { start: 12781, end: 12787 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFT' ] + }, + loc: { start: 12743, end: 12807 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRightRound', + loc: { start: 13862, end: 13880 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13906, end: 13909 } + }, + loc: { start: 13906, end: 13909 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 13881, end: 13882 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13884, end: 13887 } + }, + loc: { start: 13884, end: 13887 } + }, + loc: { start: 13881, end: 13887 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 13889, end: 13890 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13892, end: 13895 } + }, + loc: { start: 13892, end: 13895 } + }, + loc: { start: 13889, end: 13895 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 13897, end: 13898 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13900, end: 13903 } + }, + loc: { start: 13900, end: 13903 } + }, + loc: { start: 13897, end: 13903 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFTR' ] + }, + loc: { start: 13854, end: 13924 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRightCeil', + loc: { start: 14875, end: 14892 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14918, end: 14921 } + }, + loc: { start: 14918, end: 14921 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 14893, end: 14894 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14896, end: 14899 } + }, + loc: { start: 14896, end: 14899 } + }, + loc: { start: 14893, end: 14899 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 14901, end: 14902 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14904, end: 14907 } + }, + loc: { start: 14904, end: 14907 } + }, + loc: { start: 14901, end: 14907 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 14909, end: 14910 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14912, end: 14915 } + }, + loc: { start: 14912, end: 14915 } + }, + loc: { start: 14909, end: 14915 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFTC' ] + }, + loc: { start: 14867, end: 14936 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sqrt', + loc: { start: 15698, end: 15702 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15714, end: 15717 } + }, + loc: { start: 15714, end: 15717 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 15703, end: 15706 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15708, end: 15711 } + }, + loc: { start: 15708, end: 15711 } + }, + loc: { start: 15703, end: 15711 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'num', + loc: { start: 15728, end: 15731 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15735, end: 15736 } + }, + loc: { start: 15728, end: 15736 } + }, + trueStatements: [ + { + kind: 'statement_return', + expression: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15755, end: 15756 } + }, + loc: { start: 15748, end: 15757 } + } + ], + falseStatements: undefined, + loc: { start: 15724, end: 15763 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 's', + loc: { start: 15773, end: 15774 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15776, end: 15779 } + }, + loc: { start: 15776, end: 15779 } + }, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'log2', + loc: { start: 15782, end: 15786 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'num', + loc: { start: 15787, end: 15790 } + } + ], + loc: { start: 15782, end: 15791 } + }, + loc: { start: 15769, end: 15792 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'x', + loc: { start: 15801, end: 15802 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15804, end: 15807 } + }, + loc: { start: 15804, end: 15807 } + }, + expression: { + kind: 'conditional', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 's', + loc: { start: 15811, end: 15812 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15816, end: 15817 } + }, + loc: { start: 15811, end: 15817 } + }, + thenBranch: { + kind: 'op_binary', + op: '+', + left: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'num', + loc: { start: 15821, end: 15824 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15827, end: 15828 } + }, + loc: { start: 15821, end: 15828 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15832, end: 15833 } + }, + loc: { start: 15820, end: 15833 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15836, end: 15837 } + }, + loc: { start: 15820, end: 15837 } + }, + elseBranch: { + kind: 'op_binary', + op: '<<', + left: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15840, end: 15841 } + }, + right: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '+', + left: { + kind: 'var', + name: 's', + loc: { start: 15847, end: 15848 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15851, end: 15852 } + }, + loc: { start: 15847, end: 15852 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15856, end: 15857 } + }, + loc: { start: 15846, end: 15857 } + }, + loc: { start: 15840, end: 15858 } + }, + loc: { start: 15811, end: 15858 } + }, + loc: { start: 15797, end: 15860 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'q', + loc: { start: 15870, end: 15871 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15873, end: 15876 } + }, + loc: { start: 15873, end: 15876 } + }, + expression: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15879, end: 15880 } + }, + loc: { start: 15866, end: 15881 } + }, + { + kind: 'statement_until', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'q', + loc: { start: 15957, end: 15958 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15962, end: 15963 } + }, + loc: { start: 15957, end: 15963 } + }, + statements: [ + { + kind: 'statement_assign', + path: { + kind: 'var', + name: 'q', + loc: { start: 15900, end: 15901 } + }, + expression: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '-', + left: { + kind: 'static_call', + function: { + kind: 'id', + text: 'divc', + loc: { start: 15905, end: 15909 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'num', + loc: { start: 15910, end: 15913 } + }, + { + kind: 'var', + name: 'x', + loc: { start: 15915, end: 15916 } + } + ], + loc: { start: 15905, end: 15917 } + }, + right: { + kind: 'var', + name: 'x', + loc: { start: 15920, end: 15921 } + }, + loc: { start: 15905, end: 15921 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15925, end: 15926 } + }, + loc: { start: 15904, end: 15926 } + }, + loc: { start: 15900, end: 15927 } + }, + { + kind: 'statement_augmentedassign', + op: '+=', + path: { + kind: 'var', + name: 'x', + loc: { start: 15936, end: 15937 } + }, + expression: { + kind: 'var', + name: 'q', + loc: { start: 15941, end: 15942 } + }, + loc: { start: 15936, end: 15943 } + } + ], + loc: { start: 15887, end: 15965 } + }, + { + kind: 'statement_return', + expression: { + kind: 'var', + name: 'x', + loc: { start: 15978, end: 15979 } + }, + loc: { start: 15971, end: 15980 } + } + ] + }, + loc: { start: 15694, end: 15982 } + } + ] + }, + 'contractHash' => { + kind: 'tact', + path: 'std/internal/contract.tact', + code: '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Computes and returns an `Int` value of the SHA-256 hash of the `code` and `data` of the given contract. To assemble the `code` and `data` cells together for hashing, the standard `Cell` representation is used.\n' + + '///\n' + + '/// This hash is commonly called account ID. Together with the workchain ID it deterministically forms the address of the contract on TON Blockchain.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let initPkg: StateInit = initOf SomeContract();\n' + + '/// let accountId: Int = contractHash(initPkg.code, initPkg.data);\n' + + '/// let basechainAddr: Address = newAddress(0, accountId);\n' + + '/// let basechainAddr2: Address = contractAddressExt(0, initPkg.code, initPkg.data);\n' + + '///\n' + + '/// basechainAddr == basechainAddr2; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contracthash\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#newaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '///\n' + + 'asm fun contractHash(code: Cell, data: Cell): Int {\n' + + ' // According to the https://docs.tact-lang.org/book/cells#cells-representation,\n' + + ' // the layout for the Builder to hash goes as follows:\n' + + ' // 1) refs_descriptor:bits8 | bits_descriptor:bits8 | data:bitsN\n' + + ' //\n' + + ' // refs_descriptor: ref_count + ((exotic? & 1) * 8) + (mask * 32)\n' + + ' // 2 refs (code + data), non-exotic, zero-mask\n' + + ' //\n' + + ' // bits_descriptor: floor(bit_count / 8) + ceil(bit_count, 8)\n' + + ' // floor (5 bits / 8) + ceil(5 bits / 8) = 0 + 1 = 1\n' + + ' //\n' + + ' // data: [0b00110] + [0b100] = [0b00110100] = 0x34 (data + augmented bits)\n' + + ' // 0b00110 - data (split_depth, special, code, data, Library)\n' + + ' // 0b100 - augmented bits (Leading 1 + zeroes to make section multiple of eight)\n' + + ' //\n' + + ' // That is: (2 << 16) | (1 << 8) | 0x34 = 131380 for all three.\n' + + ' //\n' + + ' // 2) and 3) depth_descriptors: CDEPTH of `code` and CDEPTH of `data`\n' + + ' // 4) and 5) ref hashes: HASHCU of `code` and HASHCU of `data`\n' + + '\n' + + ' // Group 1: Computations and arrangements\n' + + ' s0 PUSH HASHCU // `data` hash\n' + + ' s2 PUSH HASHCU // `code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `code` depth\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + '\n' + + ' // Group 2: Composition of the Builder\n' + + ' NEWC\n' + + ' 24 STU // store refs_descriptor | bits_descriptor | data\n' + + ' 16 STU // store depth_descriptor for `code`\n' + + ' 16 STU // store depth_descriptor for `data`\n' + + ' 256 STU // store `code` hash\n' + + ' 256 STU // store `data` hash\n' + + '\n' + + ' // Group 3: SHA256 hash of the resulting Builder\n' + + ' ONE HASHEXT_SHA256\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + "/// Computes smart contract's `Address` in the `chain` ID using the contract's `code` and the contract's initial state `data`. Use the `initOf` expression to obtain the initial `code` and initial `data` of a given contract.\n" + + '///\n' + + '/// This function lets you specify arbitrary `chain` IDs, including the common -1 (masterchain) and 0 (basechain) ones.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let initPkg: StateInit = initOf SomeContract();\n' + + '/// let hereBeDragons: Address = contractAddressExt(0, initPkg.code, initPkg.data);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '/// * https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'inline fun contractAddressExt(chain: Int, code: Cell, data: Cell): Address {\n' + + ' let hash = contractHash(code, data);\n' + + ' return newAddress(chain, hash);\n' + + '}\n' + + '\n' + + '/// Struct containing the initial state, i.e. initial code and initial data of the given contract upon its deployment.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'struct StateInit {\n' + + ' /// Initial code of the contract (compiled bitcode)\n' + + ' code: Cell;\n' + + '\n' + + ' /// Initial data of the contract (parameters of `init()` function or contract parameters)\n' + + ' data: Cell;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.1.\n' + + '///\n' + + '/// Efficiently compares if the given address matches the basechain address of the contract.\n' + + '/// Returns true if addresses are the same, false otherwise.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let init = initOf SomeContract();\n' + + "/// init.hasSameBasechainAddress(sender()); // returns true if sender matches contract's basechain address\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// This function provides a gas-optimized implementation compared to direct address comparison:\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let init = initOf SomeContract();\n' + + '/// sender() == contractAddress(sender()); // less efficient approach\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// Note that this function works only for basechain addresses!\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddress\n' + + '///\n' + + 'inline extends fun hasSameBasechainAddress(self: StateInit, sender: Address): Bool {\n' + + ' let senderAddress = parseStdAddress(sender.asSlice()).address;\n' + + ' let baseAddress = contractBasechainAddress(self);\n' + + ' return baseAddress.hash!! == senderAddress;\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + "/// Computes smart contract's `Address` in the workchain ID 0 (basechain) using the `StateInit` `s` of the contract. Alias to `contractAddressExt(0, s.code, s.data)`.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let s: StateInit = initOf SomeContract();\n' + + '/// let foundMeSome: Address = contractAddress(s);\n' + + '/// let andSomeMore: Address = contractAddressExt(0, s.code, s.data);\n' + + '///\n' + + '/// foundMeSome == andSomeMore; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '/// * https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'inline fun contractAddress(s: StateInit): Address {\n' + + ' return contractAddressExt(0, s.code, s.data);\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Returns the address of the current smart contract as an `Address`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let meMyselfAndI: Address = myAddress();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#myaddress\n' + + '///\n' + + 'asm fun myAddress(): Address { MYADDR }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` balance of the smart contract as it was at the start of the compute phase of the current transaction.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let iNeedADolla: Int = myBalance();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#mybalance\n' + + '///\n' + + 'asm fun myBalance(): Int { BALANCE FIRST }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` amount of gas consumed by TVM in the current transaction so far. The resulting value includes the cost of calling this function.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let gas: Int = gasConsumed();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#gasconsumed\n' + + '///\n' + + 'asm fun gasConsumed(): Int { GASCONSUMED }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` amount of the accumulated storage fee debt. Storage fees are deducted from the incoming message value before the new contract balance is calculated.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let debt: Int = myStorageDue();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#mystoragedue\n' + + '///\n' + + 'asm fun myStorageDue(): Int { DUEPAYMENT }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Calculates and returns the storage fee in nanoToncoins `Int` for storing a contract with a given number of `cells` and `bits` for a number of `seconds`. Uses the prices of the masterchain if `isMasterchain` is `true`, otherwise the prices of the basechain. The current prices are obtained from the config param 18 of TON Blockchain.\n' + + '///\n' + + '/// Note, that specifying values of `cells` and `bits` higher than their maximum values listed in account state limits (`max_acc_state_cells` and `max_acc_state_bits`) will have the same result as with specifying the exact limits. In addition, make sure you take into account the deduplication of cells with the same hash.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fee: Int = getStorageFee(1_000, 1_000, 1_000, false);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify negative number of `cells`, `bits` or `seconds`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-gas#getstoragefee\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun getStorageFee(cells: Int, bits: Int, seconds: Int, isMasterchain: Bool): Int { GETSTORAGEFEE }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Calculates and returns the compute fee in nanoToncoins `Int` for a transaction that consumed `gasUsed` amount of gas. Uses the prices of the masterchain if `isMasterchain` is `true`, otherwise the prices of the basechain. The current prices are obtained from the config param 20 for the masterchain and config param 21 for the basechain of TON Blockchain.\n' + + '///\n' + + "/// When the `gasUsed` is less than a certain threshold called `flat_gas_limit`, there's a minimum price to pay based on the value of `flat_gas_price`. The less gas is used below this threshold, the higher the minimum price will be. See the example for `getSimpleComputeFee()` to derive that threshold.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fee: Int = getComputeFee(1_000, false);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify negative value of `gasUsed`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-gas#getcomputefee\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun getComputeFee(gasUsed: Int, isMasterchain: Bool): Int { GETGASFEE }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Similar to `getComputeFee()`, but without the `flat_gas_price`, i.e. without a minimum price to pay if the `gasUsed` is less than a certain '... 8611 more characters, + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'contractHash', + loc: { start: 1027, end: 1039 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1065, end: 1068 } + }, + loc: { start: 1065, end: 1068 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 1040, end: 1044 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 1046, end: 1050 } }, + loc: { start: 1046, end: 1050 } + }, + loc: { start: 1040, end: 1050 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'data', + loc: { start: 1052, end: 1056 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 1058, end: 1062 } }, + loc: { start: 1058, end: 1062 } + }, + loc: { start: 1052, end: 1062 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 's0 PUSH HASHCU // `data` hash\n' + + ' s2 PUSH HASHCU // `code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `code` depth\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + '\n' + + ' // Group 2: Composition of the Builder\n' + + ' NEWC\n' + + ' 24 STU // store refs_descriptor | bits_descriptor | data\n' + + ' 16 STU // store depth_descriptor for `code`\n' + + ' 16 STU // store depth_descriptor for `data`\n' + + ' 256 STU // store `code` hash\n' + + ' 256 STU // store `data` hash\n' + + '\n' + + ' // Group 3: SHA256 hash of the resulting Builder\n' + + ' ONE HASHEXT_SHA256' + ] + }, + loc: { start: 1019, end: 2666 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'contractAddressExt', + loc: { start: 3391, end: 3409 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3447, end: 3454 } + }, + typeArgs: [], + loc: { start: 3447, end: 3454 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'chain', + loc: { start: 3410, end: 3415 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3417, end: 3420 } + }, + loc: { start: 3417, end: 3420 } + }, + loc: { start: 3410, end: 3420 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 3422, end: 3426 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3428, end: 3432 } }, + loc: { start: 3428, end: 3432 } + }, + loc: { start: 3422, end: 3432 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'data', + loc: { start: 3434, end: 3438 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3440, end: 3444 } }, + loc: { start: 3440, end: 3444 } + }, + loc: { start: 3434, end: 3444 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'hash', + loc: { start: 3465, end: 3469 } + }, + type: undefined, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractHash', + loc: { start: 3472, end: 3484 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'code', + loc: { start: 3485, end: 3489 } + }, + { + kind: 'var', + name: 'data', + loc: { start: 3491, end: 3495 } + } + ], + loc: { start: 3472, end: 3496 } + }, + loc: { start: 3461, end: 3497 } + }, + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'newAddress', + loc: { start: 3509, end: 3519 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'chain', + loc: { start: 3520, end: 3525 } + }, + { + kind: 'var', + name: 'hash', + loc: { start: 3527, end: 3531 } + } + ], + loc: { start: 3509, end: 3532 } + }, + loc: { start: 3502, end: 3533 } + } + ] + }, + loc: { start: 3380, end: 3535 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 3731, end: 3740 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'code', + loc: { start: 3803, end: 3807 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3809, end: 3813 } }, + loc: { start: 3809, end: 3813 } + }, + initializer: undefined, + loc: { start: 3803, end: 3813 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'data', + loc: { start: 3914, end: 3918 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3920, end: 3924 } }, + loc: { start: 3920, end: 3924 } + }, + initializer: undefined, + loc: { start: 3914, end: 3924 } + } + ], + loc: { start: 3724, end: 3927 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'hasSameBasechainAddress', + loc: { start: 4778, end: 4801 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 4837, end: 4841 } + }, + typeArgs: [], + loc: { start: 4837, end: 4841 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'sender', + loc: { start: 4819, end: 4825 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 4827, end: 4834 } + }, + typeArgs: [], + loc: { start: 4827, end: 4834 } + }, + loc: { start: 4819, end: 4834 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'senderAddress', + loc: { start: 4852, end: 4865 } + }, + type: undefined, + expression: { + kind: 'field_access', + aggregate: { + kind: 'static_call', + function: { + kind: 'id', + text: 'parseStdAddress', + loc: { start: 4868, end: 4883 } + }, + typeArgs: [], + args: [ + { + kind: 'method_call', + self: { + kind: 'var', + name: 'sender', + loc: { start: 4884, end: 4890 } + }, + method: { + kind: 'id', + text: 'asSlice', + loc: { start: 4891, end: 4898 } + }, + typeArgs: [], + args: [], + loc: { start: 4884, end: 4900 } + } + ], + loc: { start: 4868, end: 4901 } + }, + field: { + kind: 'id', + text: 'address', + loc: { start: 4902, end: 4909 } + }, + loc: { start: 4868, end: 4909 } + }, + loc: { start: 4848, end: 4910 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'baseAddress', + loc: { start: 4919, end: 4930 } + }, + type: undefined, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractBasechainAddress', + loc: { start: 4933, end: 4957 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'self', + loc: { start: 4958, end: 4962 } + } + ], + loc: { start: 4933, end: 4963 } + }, + loc: { start: 4915, end: 4964 } + }, + { + kind: 'statement_return', + expression: { + kind: 'op_binary', + op: '==', + left: { + kind: 'op_unary', + op: '!!', + operand: { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'baseAddress', + loc: { start: 4976, end: 4987 } + }, + field: { + kind: 'id', + text: 'hash', + loc: { start: 4988, end: 4992 } + }, + loc: { start: 4976, end: 4992 } + }, + loc: { start: 4976, end: 4994 } + }, + right: { + kind: 'var', + name: 'senderAddress', + loc: { start: 4998, end: 5011 } + }, + loc: { start: 4976, end: 5011 } + }, + loc: { start: 4969, end: 5012 } + } + ] + }, + loc: { start: 4759, end: 5014 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 4808, end: 4817 } + }, + typeArgs: [], + loc: { start: 4808, end: 4817 } + } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'contractAddress', + loc: { start: 5709, end: 5724 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 5740, end: 5747 } + }, + typeArgs: [], + loc: { start: 5740, end: 5747 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 's', + loc: { start: 5725, end: 5726 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 5728, end: 5737 } + }, + typeArgs: [], + loc: { start: 5728, end: 5737 } + }, + loc: { start: 5725, end: 5737 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractAddressExt', + loc: { start: 5761, end: 5779 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 5780, end: 5781 } + }, + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 5783, end: 5784 } + }, + field: { + kind: 'id', + text: 'code', + loc: { start: 5785, end: 5789 } + }, + loc: { start: 5783, end: 5789 } + }, + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 5791, end: 5792 } + }, + field: { + kind: 'id', + text: 'data', + loc: { start: 5793, end: 5797 } + }, + loc: { start: 5791, end: 5797 } + } + ], + loc: { start: 5761, end: 5798 } + }, + loc: { start: 5754, end: 5799 } + } + ] + }, + loc: { start: 5698, end: 5801 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myAddress', + loc: { start: 6082, end: 6091 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 6095, end: 6102 } + }, + typeArgs: [], + loc: { start: 6095, end: 6102 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MYADDR' ] + }, + loc: { start: 6074, end: 6113 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myBalance', + loc: { start: 6454, end: 6463 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6467, end: 6470 } + }, + loc: { start: 6467, end: 6470 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'BALANCE FIRST' ] + }, + loc: { start: 6446, end: 6488 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'gasConsumed', + loc: { start: 6880, end: 6891 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6895, end: 6898 } + }, + loc: { start: 6895, end: 6898 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GASCONSUMED' ] + }, + loc: { start: 6872, end: 6914 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myStorageDue', + loc: { start: 7329, end: 7341 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7345, end: 7348 } + }, + loc: { start: 7345, end: 7348 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DUEPAYMENT' ] + }, + loc: { start: 7321, end: 7363 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getStorageFee', + loc: { start: 8517, end: 8530 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8590, end: 8593 } + }, + loc: { start: 8590, end: 8593 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 8531, end: 8536 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8538, end: 8541 } + }, + loc: { start: 8538, end: 8541 } + }, + loc: { start: 8531, end: 8541 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 8543, end: 8547 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8549, end: 8552 } + }, + loc: { start: 8549, end: 8552 } + }, + loc: { start: 8543, end: 8552 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'seconds', + loc: { start: 8554, end: 8561 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8563, end: 8566 } + }, + loc: { start: 8563, end: 8566 } + }, + loc: { start: 8554, end: 8566 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 8568, end: 8581 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 8583, end: 8587 } + }, + typeArgs: [], + loc: { start: 8583, end: 8587 } + }, + loc: { start: 8568, end: 8587 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETSTORAGEFEE' ] + }, + loc: { start: 8509, end: 8611 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getComputeFee', + loc: { start: 9734, end: 9747 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9784, end: 9787 } + }, + loc: { start: 9784, end: 9787 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'gasUsed', + loc: { start: 9748, end: 9755 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9757, end: 9760 } + }, + loc: { start: 9757, end: 9760 } + }, + loc: { start: 9748, end: 9760 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 9762, end: 9775 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 9777, end: 9781 } + }, + typeArgs: [], + loc: { start: 9777, end: 9781 } + }, + loc: { start: 9762, end: 9781 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETGASFEE' ] + }, + loc: { start: 9726, end: 9801 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSimpleComputeFee', + loc: { start: 10689, end: 10708 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10745, end: 10748 } + }, + loc: { start: 10745, end: 10748 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'gasUsed', + loc: { start: 10709, end: 10716 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10718, end: 10721 } + }, + loc: { start: 10718, end: 10721 } + }, + loc: { start: 10709, end: 10721 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 10723, end: 10736 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 10738, end: 10742 } + }, + typeArgs: [], + loc: { start: 10738, end: 10742 } + }, + loc: { start: 10723, end: 10742 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETGASFEESIMPLE' ] + }, + loc: { start: 10681, end: 10768 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getForwardFee', + loc: { start: 12543, end: 12556 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12602, end: 12605 } + }, + loc: { start: 12602, end: 12605 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 12557, end: 12562 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12564, end: 12567 } + }, + loc: { start: 12564, end: 12567 } + }, + loc: { start: 12557, end: 12567 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 12569, end: 12573 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12575, end: 12578 } + }, + loc: { start: 12575, end: 12578 } + }, + loc: { start: 12569, end: 12578 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 12580, end: 12593 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 12595, end: 12599 } + }, + typeArgs: [], + loc: { start: 12595, end: 12599 } + }, + loc: { start: 12580, end: 12599 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETFORWARDFEE' ] + }, + loc: { start: 12535, end: 12623 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSimpleForwardFee', + loc: { start: 13528, end: 13547 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13593, end: 13596 } + }, + loc: { start: 13593, end: 13596 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 13548, end: 13553 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13555, end: 13558 } + }, + loc: { start: 13555, end: 13558 } + }, + loc: { start: 13548, end: 13558 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 13560, end: 13564 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13566, end: 13569 } + }, + loc: { start: 13566, end: 13569 } + }, + loc: { start: 13560, end: 13569 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 13571, end: 13584 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 13586, end: 13590 } + }, + typeArgs: [], + loc: { start: 13586, end: 13590 } + }, + loc: { start: 13571, end: 13590 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETFORWARDFEESIMPLE' ] + }, + loc: { start: 13520, end: 13620 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getOriginalFwdFee', + loc: { start: 15782, end: 15799 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15835, end: 15838 } + }, + loc: { start: 15835, end: 15838 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'fwdFee', + loc: { start: 15800, end: 15806 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15808, end: 15811 } + }, + loc: { start: 15808, end: 15811 } + }, + loc: { start: 15800, end: 15811 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 15813, end: 15826 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 15828, end: 15832 } + }, + typeArgs: [], + loc: { start: 15828, end: 15832 } + }, + loc: { start: 15813, end: 15832 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETORIGINALFWDFEE' ] + }, + loc: { start: 15774, end: 15860 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'setGasLimit', + loc: { start: 16541, end: 16552 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'limit', + loc: { start: 16553, end: 16558 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 16560, end: 16563 } + }, + loc: { start: 16560, end: 16563 } + }, + loc: { start: 16553, end: 16563 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SETGASLIMIT' ] + }, + loc: { start: 16533, end: 16580 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSeed', + loc: { start: 17350, end: 17357 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 17361, end: 17364 } + }, + loc: { start: 17361, end: 17364 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RANDSEED' ] + }, + loc: { start: 17342, end: 17377 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'setSeed', + loc: { start: 18258, end: 18265 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'seed', + loc: { start: 18266, end: 18270 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 18272, end: 18275 } + }, + loc: { start: 18272, end: 18275 } + }, + loc: { start: 18266, end: 18275 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SETRAND' ] + }, + loc: { start: 18250, end: 18288 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myCode', + loc: { start: 18585, end: 18591 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 18595, end: 18599 } }, + loc: { start: 18595, end: 18599 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MYCODE' ] + }, + loc: { start: 18577, end: 18610 } + } + ] + }, + 'contractAddressExt' => { + kind: 'tact', + path: 'std/internal/contract.tact', + code: '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Computes and returns an `Int` value of the SHA-256 hash of the `code` and `data` of the given contract. To assemble the `code` and `data` cells together for hashing, the standard `Cell` representation is used.\n' + + '///\n' + + '/// This hash is commonly called account ID. Together with the workchain ID it deterministically forms the address of the contract on TON Blockchain.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let initPkg: StateInit = initOf SomeContract();\n' + + '/// let accountId: Int = contractHash(initPkg.code, initPkg.data);\n' + + '/// let basechainAddr: Address = newAddress(0, accountId);\n' + + '/// let basechainAddr2: Address = contractAddressExt(0, initPkg.code, initPkg.data);\n' + + '///\n' + + '/// basechainAddr == basechainAddr2; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contracthash\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#newaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '///\n' + + 'asm fun contractHash(code: Cell, data: Cell): Int {\n' + + ' // According to the https://docs.tact-lang.org/book/cells#cells-representation,\n' + + ' // the layout for the Builder to hash goes as follows:\n' + + ' // 1) refs_descriptor:bits8 | bits_descriptor:bits8 | data:bitsN\n' + + ' //\n' + + ' // refs_descriptor: ref_count + ((exotic? & 1) * 8) + (mask * 32)\n' + + ' // 2 refs (code + data), non-exotic, zero-mask\n' + + ' //\n' + + ' // bits_descriptor: floor(bit_count / 8) + ceil(bit_count, 8)\n' + + ' // floor (5 bits / 8) + ceil(5 bits / 8) = 0 + 1 = 1\n' + + ' //\n' + + ' // data: [0b00110] + [0b100] = [0b00110100] = 0x34 (data + augmented bits)\n' + + ' // 0b00110 - data (split_depth, special, code, data, Library)\n' + + ' // 0b100 - augmented bits (Leading 1 + zeroes to make section multiple of eight)\n' + + ' //\n' + + ' // That is: (2 << 16) | (1 << 8) | 0x34 = 131380 for all three.\n' + + ' //\n' + + ' // 2) and 3) depth_descriptors: CDEPTH of `code` and CDEPTH of `data`\n' + + ' // 4) and 5) ref hashes: HASHCU of `code` and HASHCU of `data`\n' + + '\n' + + ' // Group 1: Computations and arrangements\n' + + ' s0 PUSH HASHCU // `data` hash\n' + + ' s2 PUSH HASHCU // `code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `code` depth\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + '\n' + + ' // Group 2: Composition of the Builder\n' + + ' NEWC\n' + + ' 24 STU // store refs_descriptor | bits_descriptor | data\n' + + ' 16 STU // store depth_descriptor for `code`\n' + + ' 16 STU // store depth_descriptor for `data`\n' + + ' 256 STU // store `code` hash\n' + + ' 256 STU // store `data` hash\n' + + '\n' + + ' // Group 3: SHA256 hash of the resulting Builder\n' + + ' ONE HASHEXT_SHA256\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + "/// Computes smart contract's `Address` in the `chain` ID using the contract's `code` and the contract's initial state `data`. Use the `initOf` expression to obtain the initial `code` and initial `data` of a given contract.\n" + + '///\n' + + '/// This function lets you specify arbitrary `chain` IDs, including the common -1 (masterchain) and 0 (basechain) ones.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let initPkg: StateInit = initOf SomeContract();\n' + + '/// let hereBeDragons: Address = contractAddressExt(0, initPkg.code, initPkg.data);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '/// * https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'inline fun contractAddressExt(chain: Int, code: Cell, data: Cell): Address {\n' + + ' let hash = contractHash(code, data);\n' + + ' return newAddress(chain, hash);\n' + + '}\n' + + '\n' + + '/// Struct containing the initial state, i.e. initial code and initial data of the given contract upon its deployment.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'struct StateInit {\n' + + ' /// Initial code of the contract (compiled bitcode)\n' + + ' code: Cell;\n' + + '\n' + + ' /// Initial data of the contract (parameters of `init()` function or contract parameters)\n' + + ' data: Cell;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.1.\n' + + '///\n' + + '/// Efficiently compares if the given address matches the basechain address of the contract.\n' + + '/// Returns true if addresses are the same, false otherwise.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let init = initOf SomeContract();\n' + + "/// init.hasSameBasechainAddress(sender()); // returns true if sender matches contract's basechain address\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// This function provides a gas-optimized implementation compared to direct address comparison:\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let init = initOf SomeContract();\n' + + '/// sender() == contractAddress(sender()); // less efficient approach\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// Note that this function works only for basechain addresses!\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddress\n' + + '///\n' + + 'inline extends fun hasSameBasechainAddress(self: StateInit, sender: Address): Bool {\n' + + ' let senderAddress = parseStdAddress(sender.asSlice()).address;\n' + + ' let baseAddress = contractBasechainAddress(self);\n' + + ' return baseAddress.hash!! == senderAddress;\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + "/// Computes smart contract's `Address` in the workchain ID 0 (basechain) using the `StateInit` `s` of the contract. Alias to `contractAddressExt(0, s.code, s.data)`.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let s: StateInit = initOf SomeContract();\n' + + '/// let foundMeSome: Address = contractAddress(s);\n' + + '/// let andSomeMore: Address = contractAddressExt(0, s.code, s.data);\n' + + '///\n' + + '/// foundMeSome == andSomeMore; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '/// * https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'inline fun contractAddress(s: StateInit): Address {\n' + + ' return contractAddressExt(0, s.code, s.data);\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Returns the address of the current smart contract as an `Address`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let meMyselfAndI: Address = myAddress();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#myaddress\n' + + '///\n' + + 'asm fun myAddress(): Address { MYADDR }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` balance of the smart contract as it was at the start of the compute phase of the current transaction.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let iNeedADolla: Int = myBalance();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#mybalance\n' + + '///\n' + + 'asm fun myBalance(): Int { BALANCE FIRST }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` amount of gas consumed by TVM in the current transaction so far. The resulting value includes the cost of calling this function.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let gas: Int = gasConsumed();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#gasconsumed\n' + + '///\n' + + 'asm fun gasConsumed(): Int { GASCONSUMED }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` amount of the accumulated storage fee debt. Storage fees are deducted from the incoming message value before the new contract balance is calculated.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let debt: Int = myStorageDue();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#mystoragedue\n' + + '///\n' + + 'asm fun myStorageDue(): Int { DUEPAYMENT }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Calculates and returns the storage fee in nanoToncoins `Int` for storing a contract with a given number of `cells` and `bits` for a number of `seconds`. Uses the prices of the masterchain if `isMasterchain` is `true`, otherwise the prices of the basechain. The current prices are obtained from the config param 18 of TON Blockchain.\n' + + '///\n' + + '/// Note, that specifying values of `cells` and `bits` higher than their maximum values listed in account state limits (`max_acc_state_cells` and `max_acc_state_bits`) will have the same result as with specifying the exact limits. In addition, make sure you take into account the deduplication of cells with the same hash.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fee: Int = getStorageFee(1_000, 1_000, 1_000, false);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify negative number of `cells`, `bits` or `seconds`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-gas#getstoragefee\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun getStorageFee(cells: Int, bits: Int, seconds: Int, isMasterchain: Bool): Int { GETSTORAGEFEE }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Calculates and returns the compute fee in nanoToncoins `Int` for a transaction that consumed `gasUsed` amount of gas. Uses the prices of the masterchain if `isMasterchain` is `true`, otherwise the prices of the basechain. The current prices are obtained from the config param 20 for the masterchain and config param 21 for the basechain of TON Blockchain.\n' + + '///\n' + + "/// When the `gasUsed` is less than a certain threshold called `flat_gas_limit`, there's a minimum price to pay based on the value of `flat_gas_price`. The less gas is used below this threshold, the higher the minimum price will be. See the example for `getSimpleComputeFee()` to derive that threshold.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fee: Int = getComputeFee(1_000, false);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify negative value of `gasUsed`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-gas#getcomputefee\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun getComputeFee(gasUsed: Int, isMasterchain: Bool): Int { GETGASFEE }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Similar to `getComputeFee()`, but without the `flat_gas_price`, i.e. without a minimum price to pay if the `gasUsed` is less than a certain '... 8611 more characters, + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'contractHash', + loc: { start: 1027, end: 1039 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1065, end: 1068 } + }, + loc: { start: 1065, end: 1068 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 1040, end: 1044 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 1046, end: 1050 } }, + loc: { start: 1046, end: 1050 } + }, + loc: { start: 1040, end: 1050 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'data', + loc: { start: 1052, end: 1056 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 1058, end: 1062 } }, + loc: { start: 1058, end: 1062 } + }, + loc: { start: 1052, end: 1062 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 's0 PUSH HASHCU // `data` hash\n' + + ' s2 PUSH HASHCU // `code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `code` depth\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + '\n' + + ' // Group 2: Composition of the Builder\n' + + ' NEWC\n' + + ' 24 STU // store refs_descriptor | bits_descriptor | data\n' + + ' 16 STU // store depth_descriptor for `code`\n' + + ' 16 STU // store depth_descriptor for `data`\n' + + ' 256 STU // store `code` hash\n' + + ' 256 STU // store `data` hash\n' + + '\n' + + ' // Group 3: SHA256 hash of the resulting Builder\n' + + ' ONE HASHEXT_SHA256' + ] + }, + loc: { start: 1019, end: 2666 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'contractAddressExt', + loc: { start: 3391, end: 3409 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3447, end: 3454 } + }, + typeArgs: [], + loc: { start: 3447, end: 3454 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'chain', + loc: { start: 3410, end: 3415 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3417, end: 3420 } + }, + loc: { start: 3417, end: 3420 } + }, + loc: { start: 3410, end: 3420 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 3422, end: 3426 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3428, end: 3432 } }, + loc: { start: 3428, end: 3432 } + }, + loc: { start: 3422, end: 3432 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'data', + loc: { start: 3434, end: 3438 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3440, end: 3444 } }, + loc: { start: 3440, end: 3444 } + }, + loc: { start: 3434, end: 3444 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'hash', + loc: { start: 3465, end: 3469 } + }, + type: undefined, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractHash', + loc: { start: 3472, end: 3484 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'code', + loc: { start: 3485, end: 3489 } + }, + { + kind: 'var', + name: 'data', + loc: { start: 3491, end: 3495 } + } + ], + loc: { start: 3472, end: 3496 } + }, + loc: { start: 3461, end: 3497 } + }, + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'newAddress', + loc: { start: 3509, end: 3519 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'chain', + loc: { start: 3520, end: 3525 } + }, + { + kind: 'var', + name: 'hash', + loc: { start: 3527, end: 3531 } + } + ], + loc: { start: 3509, end: 3532 } + }, + loc: { start: 3502, end: 3533 } + } + ] + }, + loc: { start: 3380, end: 3535 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 3731, end: 3740 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'code', + loc: { start: 3803, end: 3807 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3809, end: 3813 } }, + loc: { start: 3809, end: 3813 } + }, + initializer: undefined, + loc: { start: 3803, end: 3813 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'data', + loc: { start: 3914, end: 3918 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3920, end: 3924 } }, + loc: { start: 3920, end: 3924 } + }, + initializer: undefined, + loc: { start: 3914, end: 3924 } + } + ], + loc: { start: 3724, end: 3927 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'hasSameBasechainAddress', + loc: { start: 4778, end: 4801 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 4837, end: 4841 } + }, + typeArgs: [], + loc: { start: 4837, end: 4841 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'sender', + loc: { start: 4819, end: 4825 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 4827, end: 4834 } + }, + typeArgs: [], + loc: { start: 4827, end: 4834 } + }, + loc: { start: 4819, end: 4834 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'senderAddress', + loc: { start: 4852, end: 4865 } + }, + type: undefined, + expression: { + kind: 'field_access', + aggregate: { + kind: 'static_call', + function: { + kind: 'id', + text: 'parseStdAddress', + loc: { start: 4868, end: 4883 } + }, + typeArgs: [], + args: [ + { + kind: 'method_call', + self: { + kind: 'var', + name: 'sender', + loc: { start: 4884, end: 4890 } + }, + method: { + kind: 'id', + text: 'asSlice', + loc: { start: 4891, end: 4898 } + }, + typeArgs: [], + args: [], + loc: { start: 4884, end: 4900 } + } + ], + loc: { start: 4868, end: 4901 } + }, + field: { + kind: 'id', + text: 'address', + loc: { start: 4902, end: 4909 } + }, + loc: { start: 4868, end: 4909 } + }, + loc: { start: 4848, end: 4910 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'baseAddress', + loc: { start: 4919, end: 4930 } + }, + type: undefined, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractBasechainAddress', + loc: { start: 4933, end: 4957 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'self', + loc: { start: 4958, end: 4962 } + } + ], + loc: { start: 4933, end: 4963 } + }, + loc: { start: 4915, end: 4964 } + }, + { + kind: 'statement_return', + expression: { + kind: 'op_binary', + op: '==', + left: { + kind: 'op_unary', + op: '!!', + operand: { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'baseAddress', + loc: { start: 4976, end: 4987 } + }, + field: { + kind: 'id', + text: 'hash', + loc: { start: 4988, end: 4992 } + }, + loc: { start: 4976, end: 4992 } + }, + loc: { start: 4976, end: 4994 } + }, + right: { + kind: 'var', + name: 'senderAddress', + loc: { start: 4998, end: 5011 } + }, + loc: { start: 4976, end: 5011 } + }, + loc: { start: 4969, end: 5012 } + } + ] + }, + loc: { start: 4759, end: 5014 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 4808, end: 4817 } + }, + typeArgs: [], + loc: { start: 4808, end: 4817 } + } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'contractAddress', + loc: { start: 5709, end: 5724 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 5740, end: 5747 } + }, + typeArgs: [], + loc: { start: 5740, end: 5747 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 's', + loc: { start: 5725, end: 5726 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 5728, end: 5737 } + }, + typeArgs: [], + loc: { start: 5728, end: 5737 } + }, + loc: { start: 5725, end: 5737 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractAddressExt', + loc: { start: 5761, end: 5779 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 5780, end: 5781 } + }, + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 5783, end: 5784 } + }, + field: { + kind: 'id', + text: 'code', + loc: { start: 5785, end: 5789 } + }, + loc: { start: 5783, end: 5789 } + }, + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 5791, end: 5792 } + }, + field: { + kind: 'id', + text: 'data', + loc: { start: 5793, end: 5797 } + }, + loc: { start: 5791, end: 5797 } + } + ], + loc: { start: 5761, end: 5798 } + }, + loc: { start: 5754, end: 5799 } + } + ] + }, + loc: { start: 5698, end: 5801 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myAddress', + loc: { start: 6082, end: 6091 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 6095, end: 6102 } + }, + typeArgs: [], + loc: { start: 6095, end: 6102 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MYADDR' ] + }, + loc: { start: 6074, end: 6113 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myBalance', + loc: { start: 6454, end: 6463 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6467, end: 6470 } + }, + loc: { start: 6467, end: 6470 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'BALANCE FIRST' ] + }, + loc: { start: 6446, end: 6488 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'gasConsumed', + loc: { start: 6880, end: 6891 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6895, end: 6898 } + }, + loc: { start: 6895, end: 6898 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GASCONSUMED' ] + }, + loc: { start: 6872, end: 6914 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myStorageDue', + loc: { start: 7329, end: 7341 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7345, end: 7348 } + }, + loc: { start: 7345, end: 7348 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DUEPAYMENT' ] + }, + loc: { start: 7321, end: 7363 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getStorageFee', + loc: { start: 8517, end: 8530 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8590, end: 8593 } + }, + loc: { start: 8590, end: 8593 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 8531, end: 8536 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8538, end: 8541 } + }, + loc: { start: 8538, end: 8541 } + }, + loc: { start: 8531, end: 8541 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 8543, end: 8547 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8549, end: 8552 } + }, + loc: { start: 8549, end: 8552 } + }, + loc: { start: 8543, end: 8552 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'seconds', + loc: { start: 8554, end: 8561 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8563, end: 8566 } + }, + loc: { start: 8563, end: 8566 } + }, + loc: { start: 8554, end: 8566 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 8568, end: 8581 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 8583, end: 8587 } + }, + typeArgs: [], + loc: { start: 8583, end: 8587 } + }, + loc: { start: 8568, end: 8587 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETSTORAGEFEE' ] + }, + loc: { start: 8509, end: 8611 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getComputeFee', + loc: { start: 9734, end: 9747 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9784, end: 9787 } + }, + loc: { start: 9784, end: 9787 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'gasUsed', + loc: { start: 9748, end: 9755 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9757, end: 9760 } + }, + loc: { start: 9757, end: 9760 } + }, + loc: { start: 9748, end: 9760 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 9762, end: 9775 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 9777, end: 9781 } + }, + typeArgs: [], + loc: { start: 9777, end: 9781 } + }, + loc: { start: 9762, end: 9781 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETGASFEE' ] + }, + loc: { start: 9726, end: 9801 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSimpleComputeFee', + loc: { start: 10689, end: 10708 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10745, end: 10748 } + }, + loc: { start: 10745, end: 10748 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'gasUsed', + loc: { start: 10709, end: 10716 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10718, end: 10721 } + }, + loc: { start: 10718, end: 10721 } + }, + loc: { start: 10709, end: 10721 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 10723, end: 10736 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 10738, end: 10742 } + }, + typeArgs: [], + loc: { start: 10738, end: 10742 } + }, + loc: { start: 10723, end: 10742 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETGASFEESIMPLE' ] + }, + loc: { start: 10681, end: 10768 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getForwardFee', + loc: { start: 12543, end: 12556 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12602, end: 12605 } + }, + loc: { start: 12602, end: 12605 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 12557, end: 12562 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12564, end: 12567 } + }, + loc: { start: 12564, end: 12567 } + }, + loc: { start: 12557, end: 12567 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 12569, end: 12573 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12575, end: 12578 } + }, + loc: { start: 12575, end: 12578 } + }, + loc: { start: 12569, end: 12578 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 12580, end: 12593 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 12595, end: 12599 } + }, + typeArgs: [], + loc: { start: 12595, end: 12599 } + }, + loc: { start: 12580, end: 12599 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETFORWARDFEE' ] + }, + loc: { start: 12535, end: 12623 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSimpleForwardFee', + loc: { start: 13528, end: 13547 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13593, end: 13596 } + }, + loc: { start: 13593, end: 13596 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 13548, end: 13553 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13555, end: 13558 } + }, + loc: { start: 13555, end: 13558 } + }, + loc: { start: 13548, end: 13558 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 13560, end: 13564 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13566, end: 13569 } + }, + loc: { start: 13566, end: 13569 } + }, + loc: { start: 13560, end: 13569 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 13571, end: 13584 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 13586, end: 13590 } + }, + typeArgs: [], + loc: { start: 13586, end: 13590 } + }, + loc: { start: 13571, end: 13590 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETFORWARDFEESIMPLE' ] + }, + loc: { start: 13520, end: 13620 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getOriginalFwdFee', + loc: { start: 15782, end: 15799 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15835, end: 15838 } + }, + loc: { start: 15835, end: 15838 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'fwdFee', + loc: { start: 15800, end: 15806 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15808, end: 15811 } + }, + loc: { start: 15808, end: 15811 } + }, + loc: { start: 15800, end: 15811 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 15813, end: 15826 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 15828, end: 15832 } + }, + typeArgs: [], + loc: { start: 15828, end: 15832 } + }, + loc: { start: 15813, end: 15832 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETORIGINALFWDFEE' ] + }, + loc: { start: 15774, end: 15860 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'setGasLimit', + loc: { start: 16541, end: 16552 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'limit', + loc: { start: 16553, end: 16558 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 16560, end: 16563 } + }, + loc: { start: 16560, end: 16563 } + }, + loc: { start: 16553, end: 16563 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SETGASLIMIT' ] + }, + loc: { start: 16533, end: 16580 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSeed', + loc: { start: 17350, end: 17357 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 17361, end: 17364 } + }, + loc: { start: 17361, end: 17364 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RANDSEED' ] + }, + loc: { start: 17342, end: 17377 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'setSeed', + loc: { start: 18258, end: 18265 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'seed', + loc: { start: 18266, end: 18270 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 18272, end: 18275 } + }, + loc: { start: 18272, end: 18275 } + }, + loc: { start: 18266, end: 18275 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SETRAND' ] + }, + loc: { start: 18250, end: 18288 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myCode', + loc: { start: 18585, end: 18591 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 18595, end: 18599 } }, + loc: { start: 18595, end: 18599 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MYCODE' ] + }, + loc: { start: 18577, end: 18610 } + } + ] + }, + 'contractAddress' => { + kind: 'tact', + path: 'std/internal/contract.tact', + code: '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Computes and returns an `Int` value of the SHA-256 hash of the `code` and `data` of the given contract. To assemble the `code` and `data` cells together for hashing, the standard `Cell` representation is used.\n' + + '///\n' + + '/// This hash is commonly called account ID. Together with the workchain ID it deterministically forms the address of the contract on TON Blockchain.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let initPkg: StateInit = initOf SomeContract();\n' + + '/// let accountId: Int = contractHash(initPkg.code, initPkg.data);\n' + + '/// let basechainAddr: Address = newAddress(0, accountId);\n' + + '/// let basechainAddr2: Address = contractAddressExt(0, initPkg.code, initPkg.data);\n' + + '///\n' + + '/// basechainAddr == basechainAddr2; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contracthash\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#newaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '///\n' + + 'asm fun contractHash(code: Cell, data: Cell): Int {\n' + + ' // According to the https://docs.tact-lang.org/book/cells#cells-representation,\n' + + ' // the layout for the Builder to hash goes as follows:\n' + + ' // 1) refs_descriptor:bits8 | bits_descriptor:bits8 | data:bitsN\n' + + ' //\n' + + ' // refs_descriptor: ref_count + ((exotic? & 1) * 8) + (mask * 32)\n' + + ' // 2 refs (code + data), non-exotic, zero-mask\n' + + ' //\n' + + ' // bits_descriptor: floor(bit_count / 8) + ceil(bit_count, 8)\n' + + ' // floor (5 bits / 8) + ceil(5 bits / 8) = 0 + 1 = 1\n' + + ' //\n' + + ' // data: [0b00110] + [0b100] = [0b00110100] = 0x34 (data + augmented bits)\n' + + ' // 0b00110 - data (split_depth, special, code, data, Library)\n' + + ' // 0b100 - augmented bits (Leading 1 + zeroes to make section multiple of eight)\n' + + ' //\n' + + ' // That is: (2 << 16) | (1 << 8) | 0x34 = 131380 for all three.\n' + + ' //\n' + + ' // 2) and 3) depth_descriptors: CDEPTH of `code` and CDEPTH of `data`\n' + + ' // 4) and 5) ref hashes: HASHCU of `code` and HASHCU of `data`\n' + + '\n' + + ' // Group 1: Computations and arrangements\n' + + ' s0 PUSH HASHCU // `data` hash\n' + + ' s2 PUSH HASHCU // `code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `code` depth\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + '\n' + + ' // Group 2: Composition of the Builder\n' + + ' NEWC\n' + + ' 24 STU // store refs_descriptor | bits_descriptor | data\n' + + ' 16 STU // store depth_descriptor for `code`\n' + + ' 16 STU // store depth_descriptor for `data`\n' + + ' 256 STU // store `code` hash\n' + + ' 256 STU // store `data` hash\n' + + '\n' + + ' // Group 3: SHA256 hash of the resulting Builder\n' + + ' ONE HASHEXT_SHA256\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + "/// Computes smart contract's `Address` in the `chain` ID using the contract's `code` and the contract's initial state `data`. Use the `initOf` expression to obtain the initial `code` and initial `data` of a given contract.\n" + + '///\n' + + '/// This function lets you specify arbitrary `chain` IDs, including the common -1 (masterchain) and 0 (basechain) ones.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let initPkg: StateInit = initOf SomeContract();\n' + + '/// let hereBeDragons: Address = contractAddressExt(0, initPkg.code, initPkg.data);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '/// * https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'inline fun contractAddressExt(chain: Int, code: Cell, data: Cell): Address {\n' + + ' let hash = contractHash(code, data);\n' + + ' return newAddress(chain, hash);\n' + + '}\n' + + '\n' + + '/// Struct containing the initial state, i.e. initial code and initial data of the given contract upon its deployment.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'struct StateInit {\n' + + ' /// Initial code of the contract (compiled bitcode)\n' + + ' code: Cell;\n' + + '\n' + + ' /// Initial data of the contract (parameters of `init()` function or contract parameters)\n' + + ' data: Cell;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.1.\n' + + '///\n' + + '/// Efficiently compares if the given address matches the basechain address of the contract.\n' + + '/// Returns true if addresses are the same, false otherwise.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let init = initOf SomeContract();\n' + + "/// init.hasSameBasechainAddress(sender()); // returns true if sender matches contract's basechain address\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// This function provides a gas-optimized implementation compared to direct address comparison:\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let init = initOf SomeContract();\n' + + '/// sender() == contractAddress(sender()); // less efficient approach\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// Note that this function works only for basechain addresses!\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddress\n' + + '///\n' + + 'inline extends fun hasSameBasechainAddress(self: StateInit, sender: Address): Bool {\n' + + ' let senderAddress = parseStdAddress(sender.asSlice()).address;\n' + + ' let baseAddress = contractBasechainAddress(self);\n' + + ' return baseAddress.hash!! == senderAddress;\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + "/// Computes smart contract's `Address` in the workchain ID 0 (basechain) using the `StateInit` `s` of the contract. Alias to `contractAddressExt(0, s.code, s.data)`.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let s: StateInit = initOf SomeContract();\n' + + '/// let foundMeSome: Address = contractAddress(s);\n' + + '/// let andSomeMore: Address = contractAddressExt(0, s.code, s.data);\n' + + '///\n' + + '/// foundMeSome == andSomeMore; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '/// * https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'inline fun contractAddress(s: StateInit): Address {\n' + + ' return contractAddressExt(0, s.code, s.data);\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Returns the address of the current smart contract as an `Address`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let meMyselfAndI: Address = myAddress();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#myaddress\n' + + '///\n' + + 'asm fun myAddress(): Address { MYADDR }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` balance of the smart contract as it was at the start of the compute phase of the current transaction.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let iNeedADolla: Int = myBalance();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#mybalance\n' + + '///\n' + + 'asm fun myBalance(): Int { BALANCE FIRST }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` amount of gas consumed by TVM in the current transaction so far. The resulting value includes the cost of calling this function.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let gas: Int = gasConsumed();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#gasconsumed\n' + + '///\n' + + 'asm fun gasConsumed(): Int { GASCONSUMED }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` amount of the accumulated storage fee debt. Storage fees are deducted from the incoming message value before the new contract balance is calculated.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let debt: Int = myStorageDue();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#mystoragedue\n' + + '///\n' + + 'asm fun myStorageDue(): Int { DUEPAYMENT }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Calculates and returns the storage fee in nanoToncoins `Int` for storing a contract with a given number of `cells` and `bits` for a number of `seconds`. Uses the prices of the masterchain if `isMasterchain` is `true`, otherwise the prices of the basechain. The current prices are obtained from the config param 18 of TON Blockchain.\n' + + '///\n' + + '/// Note, that specifying values of `cells` and `bits` higher than their maximum values listed in account state limits (`max_acc_state_cells` and `max_acc_state_bits`) will have the same result as with specifying the exact limits. In addition, make sure you take into account the deduplication of cells with the same hash.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fee: Int = getStorageFee(1_000, 1_000, 1_000, false);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify negative number of `cells`, `bits` or `seconds`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-gas#getstoragefee\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun getStorageFee(cells: Int, bits: Int, seconds: Int, isMasterchain: Bool): Int { GETSTORAGEFEE }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Calculates and returns the compute fee in nanoToncoins `Int` for a transaction that consumed `gasUsed` amount of gas. Uses the prices of the masterchain if `isMasterchain` is `true`, otherwise the prices of the basechain. The current prices are obtained from the config param 20 for the masterchain and config param 21 for the basechain of TON Blockchain.\n' + + '///\n' + + "/// When the `gasUsed` is less than a certain threshold called `flat_gas_limit`, there's a minimum price to pay based on the value of `flat_gas_price`. The less gas is used below this threshold, the higher the minimum price will be. See the example for `getSimpleComputeFee()` to derive that threshold.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fee: Int = getComputeFee(1_000, false);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify negative value of `gasUsed`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-gas#getcomputefee\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun getComputeFee(gasUsed: Int, isMasterchain: Bool): Int { GETGASFEE }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Similar to `getComputeFee()`, but without the `flat_gas_price`, i.e. without a minimum price to pay if the `gasUsed` is less than a certain '... 8611 more characters, + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'contractHash', + loc: { start: 1027, end: 1039 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1065, end: 1068 } + }, + loc: { start: 1065, end: 1068 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 1040, end: 1044 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 1046, end: 1050 } }, + loc: { start: 1046, end: 1050 } + }, + loc: { start: 1040, end: 1050 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'data', + loc: { start: 1052, end: 1056 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 1058, end: 1062 } }, + loc: { start: 1058, end: 1062 } + }, + loc: { start: 1052, end: 1062 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 's0 PUSH HASHCU // `data` hash\n' + + ' s2 PUSH HASHCU // `code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `code` depth\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + '\n' + + ' // Group 2: Composition of the Builder\n' + + ' NEWC\n' + + ' 24 STU // store refs_descriptor | bits_descriptor | data\n' + + ' 16 STU // store depth_descriptor for `code`\n' + + ' 16 STU // store depth_descriptor for `data`\n' + + ' 256 STU // store `code` hash\n' + + ' 256 STU // store `data` hash\n' + + '\n' + + ' // Group 3: SHA256 hash of the resulting Builder\n' + + ' ONE HASHEXT_SHA256' + ] + }, + loc: { start: 1019, end: 2666 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'contractAddressExt', + loc: { start: 3391, end: 3409 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3447, end: 3454 } + }, + typeArgs: [], + loc: { start: 3447, end: 3454 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'chain', + loc: { start: 3410, end: 3415 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3417, end: 3420 } + }, + loc: { start: 3417, end: 3420 } + }, + loc: { start: 3410, end: 3420 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 3422, end: 3426 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3428, end: 3432 } }, + loc: { start: 3428, end: 3432 } + }, + loc: { start: 3422, end: 3432 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'data', + loc: { start: 3434, end: 3438 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3440, end: 3444 } }, + loc: { start: 3440, end: 3444 } + }, + loc: { start: 3434, end: 3444 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'hash', + loc: { start: 3465, end: 3469 } + }, + type: undefined, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractHash', + loc: { start: 3472, end: 3484 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'code', + loc: { start: 3485, end: 3489 } + }, + { + kind: 'var', + name: 'data', + loc: { start: 3491, end: 3495 } + } + ], + loc: { start: 3472, end: 3496 } + }, + loc: { start: 3461, end: 3497 } + }, + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'newAddress', + loc: { start: 3509, end: 3519 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'chain', + loc: { start: 3520, end: 3525 } + }, + { + kind: 'var', + name: 'hash', + loc: { start: 3527, end: 3531 } + } + ], + loc: { start: 3509, end: 3532 } + }, + loc: { start: 3502, end: 3533 } + } + ] + }, + loc: { start: 3380, end: 3535 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 3731, end: 3740 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'code', + loc: { start: 3803, end: 3807 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3809, end: 3813 } }, + loc: { start: 3809, end: 3813 } + }, + initializer: undefined, + loc: { start: 3803, end: 3813 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'data', + loc: { start: 3914, end: 3918 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3920, end: 3924 } }, + loc: { start: 3920, end: 3924 } + }, + initializer: undefined, + loc: { start: 3914, end: 3924 } + } + ], + loc: { start: 3724, end: 3927 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'hasSameBasechainAddress', + loc: { start: 4778, end: 4801 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 4837, end: 4841 } + }, + typeArgs: [], + loc: { start: 4837, end: 4841 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'sender', + loc: { start: 4819, end: 4825 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 4827, end: 4834 } + }, + typeArgs: [], + loc: { start: 4827, end: 4834 } + }, + loc: { start: 4819, end: 4834 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'senderAddress', + loc: { start: 4852, end: 4865 } + }, + type: undefined, + expression: { + kind: 'field_access', + aggregate: { + kind: 'static_call', + function: { + kind: 'id', + text: 'parseStdAddress', + loc: { start: 4868, end: 4883 } + }, + typeArgs: [], + args: [ + { + kind: 'method_call', + self: { + kind: 'var', + name: 'sender', + loc: { start: 4884, end: 4890 } + }, + method: { + kind: 'id', + text: 'asSlice', + loc: { start: 4891, end: 4898 } + }, + typeArgs: [], + args: [], + loc: { start: 4884, end: 4900 } + } + ], + loc: { start: 4868, end: 4901 } + }, + field: { + kind: 'id', + text: 'address', + loc: { start: 4902, end: 4909 } + }, + loc: { start: 4868, end: 4909 } + }, + loc: { start: 4848, end: 4910 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'baseAddress', + loc: { start: 4919, end: 4930 } + }, + type: undefined, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractBasechainAddress', + loc: { start: 4933, end: 4957 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'self', + loc: { start: 4958, end: 4962 } + } + ], + loc: { start: 4933, end: 4963 } + }, + loc: { start: 4915, end: 4964 } + }, + { + kind: 'statement_return', + expression: { + kind: 'op_binary', + op: '==', + left: { + kind: 'op_unary', + op: '!!', + operand: { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'baseAddress', + loc: { start: 4976, end: 4987 } + }, + field: { + kind: 'id', + text: 'hash', + loc: { start: 4988, end: 4992 } + }, + loc: { start: 4976, end: 4992 } + }, + loc: { start: 4976, end: 4994 } + }, + right: { + kind: 'var', + name: 'senderAddress', + loc: { start: 4998, end: 5011 } + }, + loc: { start: 4976, end: 5011 } + }, + loc: { start: 4969, end: 5012 } + } + ] + }, + loc: { start: 4759, end: 5014 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 4808, end: 4817 } + }, + typeArgs: [], + loc: { start: 4808, end: 4817 } + } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'contractAddress', + loc: { start: 5709, end: 5724 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 5740, end: 5747 } + }, + typeArgs: [], + loc: { start: 5740, end: 5747 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 's', + loc: { start: 5725, end: 5726 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 5728, end: 5737 } + }, + typeArgs: [], + loc: { start: 5728, end: 5737 } + }, + loc: { start: 5725, end: 5737 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractAddressExt', + loc: { start: 5761, end: 5779 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 5780, end: 5781 } + }, + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 5783, end: 5784 } + }, + field: { + kind: 'id', + text: 'code', + loc: { start: 5785, end: 5789 } + }, + loc: { start: 5783, end: 5789 } + }, + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 5791, end: 5792 } + }, + field: { + kind: 'id', + text: 'data', + loc: { start: 5793, end: 5797 } + }, + loc: { start: 5791, end: 5797 } + } + ], + loc: { start: 5761, end: 5798 } + }, + loc: { start: 5754, end: 5799 } + } + ] + }, + loc: { start: 5698, end: 5801 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myAddress', + loc: { start: 6082, end: 6091 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 6095, end: 6102 } + }, + typeArgs: [], + loc: { start: 6095, end: 6102 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MYADDR' ] + }, + loc: { start: 6074, end: 6113 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myBalance', + loc: { start: 6454, end: 6463 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6467, end: 6470 } + }, + loc: { start: 6467, end: 6470 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'BALANCE FIRST' ] + }, + loc: { start: 6446, end: 6488 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'gasConsumed', + loc: { start: 6880, end: 6891 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6895, end: 6898 } + }, + loc: { start: 6895, end: 6898 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GASCONSUMED' ] + }, + loc: { start: 6872, end: 6914 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myStorageDue', + loc: { start: 7329, end: 7341 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7345, end: 7348 } + }, + loc: { start: 7345, end: 7348 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DUEPAYMENT' ] + }, + loc: { start: 7321, end: 7363 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getStorageFee', + loc: { start: 8517, end: 8530 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8590, end: 8593 } + }, + loc: { start: 8590, end: 8593 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 8531, end: 8536 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8538, end: 8541 } + }, + loc: { start: 8538, end: 8541 } + }, + loc: { start: 8531, end: 8541 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 8543, end: 8547 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8549, end: 8552 } + }, + loc: { start: 8549, end: 8552 } + }, + loc: { start: 8543, end: 8552 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'seconds', + loc: { start: 8554, end: 8561 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8563, end: 8566 } + }, + loc: { start: 8563, end: 8566 } + }, + loc: { start: 8554, end: 8566 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 8568, end: 8581 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 8583, end: 8587 } + }, + typeArgs: [], + loc: { start: 8583, end: 8587 } + }, + loc: { start: 8568, end: 8587 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETSTORAGEFEE' ] + }, + loc: { start: 8509, end: 8611 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getComputeFee', + loc: { start: 9734, end: 9747 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9784, end: 9787 } + }, + loc: { start: 9784, end: 9787 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'gasUsed', + loc: { start: 9748, end: 9755 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9757, end: 9760 } + }, + loc: { start: 9757, end: 9760 } + }, + loc: { start: 9748, end: 9760 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 9762, end: 9775 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 9777, end: 9781 } + }, + typeArgs: [], + loc: { start: 9777, end: 9781 } + }, + loc: { start: 9762, end: 9781 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETGASFEE' ] + }, + loc: { start: 9726, end: 9801 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSimpleComputeFee', + loc: { start: 10689, end: 10708 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10745, end: 10748 } + }, + loc: { start: 10745, end: 10748 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'gasUsed', + loc: { start: 10709, end: 10716 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10718, end: 10721 } + }, + loc: { start: 10718, end: 10721 } + }, + loc: { start: 10709, end: 10721 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 10723, end: 10736 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 10738, end: 10742 } + }, + typeArgs: [], + loc: { start: 10738, end: 10742 } + }, + loc: { start: 10723, end: 10742 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETGASFEESIMPLE' ] + }, + loc: { start: 10681, end: 10768 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getForwardFee', + loc: { start: 12543, end: 12556 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12602, end: 12605 } + }, + loc: { start: 12602, end: 12605 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 12557, end: 12562 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12564, end: 12567 } + }, + loc: { start: 12564, end: 12567 } + }, + loc: { start: 12557, end: 12567 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 12569, end: 12573 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12575, end: 12578 } + }, + loc: { start: 12575, end: 12578 } + }, + loc: { start: 12569, end: 12578 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 12580, end: 12593 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 12595, end: 12599 } + }, + typeArgs: [], + loc: { start: 12595, end: 12599 } + }, + loc: { start: 12580, end: 12599 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETFORWARDFEE' ] + }, + loc: { start: 12535, end: 12623 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSimpleForwardFee', + loc: { start: 13528, end: 13547 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13593, end: 13596 } + }, + loc: { start: 13593, end: 13596 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 13548, end: 13553 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13555, end: 13558 } + }, + loc: { start: 13555, end: 13558 } + }, + loc: { start: 13548, end: 13558 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 13560, end: 13564 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13566, end: 13569 } + }, + loc: { start: 13566, end: 13569 } + }, + loc: { start: 13560, end: 13569 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 13571, end: 13584 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 13586, end: 13590 } + }, + typeArgs: [], + loc: { start: 13586, end: 13590 } + }, + loc: { start: 13571, end: 13590 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETFORWARDFEESIMPLE' ] + }, + loc: { start: 13520, end: 13620 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getOriginalFwdFee', + loc: { start: 15782, end: 15799 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15835, end: 15838 } + }, + loc: { start: 15835, end: 15838 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'fwdFee', + loc: { start: 15800, end: 15806 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15808, end: 15811 } + }, + loc: { start: 15808, end: 15811 } + }, + loc: { start: 15800, end: 15811 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 15813, end: 15826 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 15828, end: 15832 } + }, + typeArgs: [], + loc: { start: 15828, end: 15832 } + }, + loc: { start: 15813, end: 15832 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETORIGINALFWDFEE' ] + }, + loc: { start: 15774, end: 15860 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'setGasLimit', + loc: { start: 16541, end: 16552 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'limit', + loc: { start: 16553, end: 16558 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 16560, end: 16563 } + }, + loc: { start: 16560, end: 16563 } + }, + loc: { start: 16553, end: 16563 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SETGASLIMIT' ] + }, + loc: { start: 16533, end: 16580 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSeed', + loc: { start: 17350, end: 17357 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 17361, end: 17364 } + }, + loc: { start: 17361, end: 17364 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RANDSEED' ] + }, + loc: { start: 17342, end: 17377 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'setSeed', + loc: { start: 18258, end: 18265 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'seed', + loc: { start: 18266, end: 18270 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 18272, end: 18275 } + }, + loc: { start: 18272, end: 18275 } + }, + loc: { start: 18266, end: 18275 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SETRAND' ] + }, + loc: { start: 18250, end: 18288 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myCode', + loc: { start: 18585, end: 18591 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 18595, end: 18599 } }, + loc: { start: 18595, end: 18599 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MYCODE' ] + }, + loc: { start: 18577, end: 18610 } + } + ] + }, + 'myAddress' => { + kind: 'tact', + path: 'std/internal/contract.tact', + code: '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Computes and returns an `Int` value of the SHA-256 hash of the `code` and `data` of the given contract. To assemble the `code` and `data` cells together for hashing, the standard `Cell` representation is used.\n' + + '///\n' + + '/// This hash is commonly called account ID. Together with the workchain ID it deterministically forms the address of the contract on TON Blockchain.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let initPkg: StateInit = initOf SomeContract();\n' + + '/// let accountId: Int = contractHash(initPkg.code, initPkg.data);\n' + + '/// let basechainAddr: Address = newAddress(0, accountId);\n' + + '/// let basechainAddr2: Address = contractAddressExt(0, initPkg.code, initPkg.data);\n' + + '///\n' + + '/// basechainAddr == basechainAddr2; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contracthash\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#newaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '///\n' + + 'asm fun contractHash(code: Cell, data: Cell): Int {\n' + + ' // According to the https://docs.tact-lang.org/book/cells#cells-representation,\n' + + ' // the layout for the Builder to hash goes as follows:\n' + + ' // 1) refs_descriptor:bits8 | bits_descriptor:bits8 | data:bitsN\n' + + ' //\n' + + ' // refs_descriptor: ref_count + ((exotic? & 1) * 8) + (mask * 32)\n' + + ' // 2 refs (code + data), non-exotic, zero-mask\n' + + ' //\n' + + ' // bits_descriptor: floor(bit_count / 8) + ceil(bit_count, 8)\n' + + ' // floor (5 bits / 8) + ceil(5 bits / 8) = 0 + 1 = 1\n' + + ' //\n' + + ' // data: [0b00110] + [0b100] = [0b00110100] = 0x34 (data + augmented bits)\n' + + ' // 0b00110 - data (split_depth, special, code, data, Library)\n' + + ' // 0b100 - augmented bits (Leading 1 + zeroes to make section multiple of eight)\n' + + ' //\n' + + ' // That is: (2 << 16) | (1 << 8) | 0x34 = 131380 for all three.\n' + + ' //\n' + + ' // 2) and 3) depth_descriptors: CDEPTH of `code` and CDEPTH of `data`\n' + + ' // 4) and 5) ref hashes: HASHCU of `code` and HASHCU of `data`\n' + + '\n' + + ' // Group 1: Computations and arrangements\n' + + ' s0 PUSH HASHCU // `data` hash\n' + + ' s2 PUSH HASHCU // `code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `code` depth\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + '\n' + + ' // Group 2: Composition of the Builder\n' + + ' NEWC\n' + + ' 24 STU // store refs_descriptor | bits_descriptor | data\n' + + ' 16 STU // store depth_descriptor for `code`\n' + + ' 16 STU // store depth_descriptor for `data`\n' + + ' 256 STU // store `code` hash\n' + + ' 256 STU // store `data` hash\n' + + '\n' + + ' // Group 3: SHA256 hash of the resulting Builder\n' + + ' ONE HASHEXT_SHA256\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + "/// Computes smart contract's `Address` in the `chain` ID using the contract's `code` and the contract's initial state `data`. Use the `initOf` expression to obtain the initial `code` and initial `data` of a given contract.\n" + + '///\n' + + '/// This function lets you specify arbitrary `chain` IDs, including the common -1 (masterchain) and 0 (basechain) ones.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let initPkg: StateInit = initOf SomeContract();\n' + + '/// let hereBeDragons: Address = contractAddressExt(0, initPkg.code, initPkg.data);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '/// * https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'inline fun contractAddressExt(chain: Int, code: Cell, data: Cell): Address {\n' + + ' let hash = contractHash(code, data);\n' + + ' return newAddress(chain, hash);\n' + + '}\n' + + '\n' + + '/// Struct containing the initial state, i.e. initial code and initial data of the given contract upon its deployment.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'struct StateInit {\n' + + ' /// Initial code of the contract (compiled bitcode)\n' + + ' code: Cell;\n' + + '\n' + + ' /// Initial data of the contract (parameters of `init()` function or contract parameters)\n' + + ' data: Cell;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.1.\n' + + '///\n' + + '/// Efficiently compares if the given address matches the basechain address of the contract.\n' + + '/// Returns true if addresses are the same, false otherwise.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let init = initOf SomeContract();\n' + + "/// init.hasSameBasechainAddress(sender()); // returns true if sender matches contract's basechain address\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// This function provides a gas-optimized implementation compared to direct address comparison:\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let init = initOf SomeContract();\n' + + '/// sender() == contractAddress(sender()); // less efficient approach\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// Note that this function works only for basechain addresses!\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddress\n' + + '///\n' + + 'inline extends fun hasSameBasechainAddress(self: StateInit, sender: Address): Bool {\n' + + ' let senderAddress = parseStdAddress(sender.asSlice()).address;\n' + + ' let baseAddress = contractBasechainAddress(self);\n' + + ' return baseAddress.hash!! == senderAddress;\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + "/// Computes smart contract's `Address` in the workchain ID 0 (basechain) using the `StateInit` `s` of the contract. Alias to `contractAddressExt(0, s.code, s.data)`.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let s: StateInit = initOf SomeContract();\n' + + '/// let foundMeSome: Address = contractAddress(s);\n' + + '/// let andSomeMore: Address = contractAddressExt(0, s.code, s.data);\n' + + '///\n' + + '/// foundMeSome == andSomeMore; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '/// * https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'inline fun contractAddress(s: StateInit): Address {\n' + + ' return contractAddressExt(0, s.code, s.data);\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Returns the address of the current smart contract as an `Address`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let meMyselfAndI: Address = myAddress();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#myaddress\n' + + '///\n' + + 'asm fun myAddress(): Address { MYADDR }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` balance of the smart contract as it was at the start of the compute phase of the current transaction.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let iNeedADolla: Int = myBalance();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#mybalance\n' + + '///\n' + + 'asm fun myBalance(): Int { BALANCE FIRST }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` amount of gas consumed by TVM in the current transaction so far. The resulting value includes the cost of calling this function.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let gas: Int = gasConsumed();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#gasconsumed\n' + + '///\n' + + 'asm fun gasConsumed(): Int { GASCONSUMED }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` amount of the accumulated storage fee debt. Storage fees are deducted from the incoming message value before the new contract balance is calculated.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let debt: Int = myStorageDue();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#mystoragedue\n' + + '///\n' + + 'asm fun myStorageDue(): Int { DUEPAYMENT }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Calculates and returns the storage fee in nanoToncoins `Int` for storing a contract with a given number of `cells` and `bits` for a number of `seconds`. Uses the prices of the masterchain if `isMasterchain` is `true`, otherwise the prices of the basechain. The current prices are obtained from the config param 18 of TON Blockchain.\n' + + '///\n' + + '/// Note, that specifying values of `cells` and `bits` higher than their maximum values listed in account state limits (`max_acc_state_cells` and `max_acc_state_bits`) will have the same result as with specifying the exact limits. In addition, make sure you take into account the deduplication of cells with the same hash.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fee: Int = getStorageFee(1_000, 1_000, 1_000, false);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify negative number of `cells`, `bits` or `seconds`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-gas#getstoragefee\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun getStorageFee(cells: Int, bits: Int, seconds: Int, isMasterchain: Bool): Int { GETSTORAGEFEE }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Calculates and returns the compute fee in nanoToncoins `Int` for a transaction that consumed `gasUsed` amount of gas. Uses the prices of the masterchain if `isMasterchain` is `true`, otherwise the prices of the basechain. The current prices are obtained from the config param 20 for the masterchain and config param 21 for the basechain of TON Blockchain.\n' + + '///\n' + + "/// When the `gasUsed` is less than a certain threshold called `flat_gas_limit`, there's a minimum price to pay based on the value of `flat_gas_price`. The less gas is used below this threshold, the higher the minimum price will be. See the example for `getSimpleComputeFee()` to derive that threshold.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fee: Int = getComputeFee(1_000, false);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify negative value of `gasUsed`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-gas#getcomputefee\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun getComputeFee(gasUsed: Int, isMasterchain: Bool): Int { GETGASFEE }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Similar to `getComputeFee()`, but without the `flat_gas_price`, i.e. without a minimum price to pay if the `gasUsed` is less than a certain '... 8611 more characters, + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'contractHash', + loc: { start: 1027, end: 1039 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1065, end: 1068 } + }, + loc: { start: 1065, end: 1068 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 1040, end: 1044 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 1046, end: 1050 } }, + loc: { start: 1046, end: 1050 } + }, + loc: { start: 1040, end: 1050 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'data', + loc: { start: 1052, end: 1056 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 1058, end: 1062 } }, + loc: { start: 1058, end: 1062 } + }, + loc: { start: 1052, end: 1062 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 's0 PUSH HASHCU // `data` hash\n' + + ' s2 PUSH HASHCU // `code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `code` depth\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + '\n' + + ' // Group 2: Composition of the Builder\n' + + ' NEWC\n' + + ' 24 STU // store refs_descriptor | bits_descriptor | data\n' + + ' 16 STU // store depth_descriptor for `code`\n' + + ' 16 STU // store depth_descriptor for `data`\n' + + ' 256 STU // store `code` hash\n' + + ' 256 STU // store `data` hash\n' + + '\n' + + ' // Group 3: SHA256 hash of the resulting Builder\n' + + ' ONE HASHEXT_SHA256' + ] + }, + loc: { start: 1019, end: 2666 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'contractAddressExt', + loc: { start: 3391, end: 3409 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3447, end: 3454 } + }, + typeArgs: [], + loc: { start: 3447, end: 3454 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'chain', + loc: { start: 3410, end: 3415 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3417, end: 3420 } + }, + loc: { start: 3417, end: 3420 } + }, + loc: { start: 3410, end: 3420 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 3422, end: 3426 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3428, end: 3432 } }, + loc: { start: 3428, end: 3432 } + }, + loc: { start: 3422, end: 3432 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'data', + loc: { start: 3434, end: 3438 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3440, end: 3444 } }, + loc: { start: 3440, end: 3444 } + }, + loc: { start: 3434, end: 3444 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'hash', + loc: { start: 3465, end: 3469 } + }, + type: undefined, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractHash', + loc: { start: 3472, end: 3484 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'code', + loc: { start: 3485, end: 3489 } + }, + { + kind: 'var', + name: 'data', + loc: { start: 3491, end: 3495 } + } + ], + loc: { start: 3472, end: 3496 } + }, + loc: { start: 3461, end: 3497 } + }, + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'newAddress', + loc: { start: 3509, end: 3519 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'chain', + loc: { start: 3520, end: 3525 } + }, + { + kind: 'var', + name: 'hash', + loc: { start: 3527, end: 3531 } + } + ], + loc: { start: 3509, end: 3532 } + }, + loc: { start: 3502, end: 3533 } + } + ] + }, + loc: { start: 3380, end: 3535 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 3731, end: 3740 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'code', + loc: { start: 3803, end: 3807 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3809, end: 3813 } }, + loc: { start: 3809, end: 3813 } + }, + initializer: undefined, + loc: { start: 3803, end: 3813 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'data', + loc: { start: 3914, end: 3918 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3920, end: 3924 } }, + loc: { start: 3920, end: 3924 } + }, + initializer: undefined, + loc: { start: 3914, end: 3924 } + } + ], + loc: { start: 3724, end: 3927 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'hasSameBasechainAddress', + loc: { start: 4778, end: 4801 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 4837, end: 4841 } + }, + typeArgs: [], + loc: { start: 4837, end: 4841 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'sender', + loc: { start: 4819, end: 4825 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 4827, end: 4834 } + }, + typeArgs: [], + loc: { start: 4827, end: 4834 } + }, + loc: { start: 4819, end: 4834 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'senderAddress', + loc: { start: 4852, end: 4865 } + }, + type: undefined, + expression: { + kind: 'field_access', + aggregate: { + kind: 'static_call', + function: { + kind: 'id', + text: 'parseStdAddress', + loc: { start: 4868, end: 4883 } + }, + typeArgs: [], + args: [ + { + kind: 'method_call', + self: { + kind: 'var', + name: 'sender', + loc: { start: 4884, end: 4890 } + }, + method: { + kind: 'id', + text: 'asSlice', + loc: { start: 4891, end: 4898 } + }, + typeArgs: [], + args: [], + loc: { start: 4884, end: 4900 } + } + ], + loc: { start: 4868, end: 4901 } + }, + field: { + kind: 'id', + text: 'address', + loc: { start: 4902, end: 4909 } + }, + loc: { start: 4868, end: 4909 } + }, + loc: { start: 4848, end: 4910 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'baseAddress', + loc: { start: 4919, end: 4930 } + }, + type: undefined, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractBasechainAddress', + loc: { start: 4933, end: 4957 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'self', + loc: { start: 4958, end: 4962 } + } + ], + loc: { start: 4933, end: 4963 } + }, + loc: { start: 4915, end: 4964 } + }, + { + kind: 'statement_return', + expression: { + kind: 'op_binary', + op: '==', + left: { + kind: 'op_unary', + op: '!!', + operand: { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'baseAddress', + loc: { start: 4976, end: 4987 } + }, + field: { + kind: 'id', + text: 'hash', + loc: { start: 4988, end: 4992 } + }, + loc: { start: 4976, end: 4992 } + }, + loc: { start: 4976, end: 4994 } + }, + right: { + kind: 'var', + name: 'senderAddress', + loc: { start: 4998, end: 5011 } + }, + loc: { start: 4976, end: 5011 } + }, + loc: { start: 4969, end: 5012 } + } + ] + }, + loc: { start: 4759, end: 5014 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 4808, end: 4817 } + }, + typeArgs: [], + loc: { start: 4808, end: 4817 } + } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'contractAddress', + loc: { start: 5709, end: 5724 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 5740, end: 5747 } + }, + typeArgs: [], + loc: { start: 5740, end: 5747 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 's', + loc: { start: 5725, end: 5726 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 5728, end: 5737 } + }, + typeArgs: [], + loc: { start: 5728, end: 5737 } + }, + loc: { start: 5725, end: 5737 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractAddressExt', + loc: { start: 5761, end: 5779 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 5780, end: 5781 } + }, + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 5783, end: 5784 } + }, + field: { + kind: 'id', + text: 'code', + loc: { start: 5785, end: 5789 } + }, + loc: { start: 5783, end: 5789 } + }, + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 5791, end: 5792 } + }, + field: { + kind: 'id', + text: 'data', + loc: { start: 5793, end: 5797 } + }, + loc: { start: 5791, end: 5797 } + } + ], + loc: { start: 5761, end: 5798 } + }, + loc: { start: 5754, end: 5799 } + } + ] + }, + loc: { start: 5698, end: 5801 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myAddress', + loc: { start: 6082, end: 6091 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 6095, end: 6102 } + }, + typeArgs: [], + loc: { start: 6095, end: 6102 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MYADDR' ] + }, + loc: { start: 6074, end: 6113 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myBalance', + loc: { start: 6454, end: 6463 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6467, end: 6470 } + }, + loc: { start: 6467, end: 6470 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'BALANCE FIRST' ] + }, + loc: { start: 6446, end: 6488 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'gasConsumed', + loc: { start: 6880, end: 6891 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6895, end: 6898 } + }, + loc: { start: 6895, end: 6898 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GASCONSUMED' ] + }, + loc: { start: 6872, end: 6914 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myStorageDue', + loc: { start: 7329, end: 7341 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7345, end: 7348 } + }, + loc: { start: 7345, end: 7348 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DUEPAYMENT' ] + }, + loc: { start: 7321, end: 7363 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getStorageFee', + loc: { start: 8517, end: 8530 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8590, end: 8593 } + }, + loc: { start: 8590, end: 8593 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 8531, end: 8536 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8538, end: 8541 } + }, + loc: { start: 8538, end: 8541 } + }, + loc: { start: 8531, end: 8541 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 8543, end: 8547 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8549, end: 8552 } + }, + loc: { start: 8549, end: 8552 } + }, + loc: { start: 8543, end: 8552 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'seconds', + loc: { start: 8554, end: 8561 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8563, end: 8566 } + }, + loc: { start: 8563, end: 8566 } + }, + loc: { start: 8554, end: 8566 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 8568, end: 8581 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 8583, end: 8587 } + }, + typeArgs: [], + loc: { start: 8583, end: 8587 } + }, + loc: { start: 8568, end: 8587 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETSTORAGEFEE' ] + }, + loc: { start: 8509, end: 8611 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getComputeFee', + loc: { start: 9734, end: 9747 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9784, end: 9787 } + }, + loc: { start: 9784, end: 9787 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'gasUsed', + loc: { start: 9748, end: 9755 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9757, end: 9760 } + }, + loc: { start: 9757, end: 9760 } + }, + loc: { start: 9748, end: 9760 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 9762, end: 9775 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 9777, end: 9781 } + }, + typeArgs: [], + loc: { start: 9777, end: 9781 } + }, + loc: { start: 9762, end: 9781 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETGASFEE' ] + }, + loc: { start: 9726, end: 9801 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSimpleComputeFee', + loc: { start: 10689, end: 10708 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10745, end: 10748 } + }, + loc: { start: 10745, end: 10748 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'gasUsed', + loc: { start: 10709, end: 10716 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10718, end: 10721 } + }, + loc: { start: 10718, end: 10721 } + }, + loc: { start: 10709, end: 10721 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 10723, end: 10736 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 10738, end: 10742 } + }, + typeArgs: [], + loc: { start: 10738, end: 10742 } + }, + loc: { start: 10723, end: 10742 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETGASFEESIMPLE' ] + }, + loc: { start: 10681, end: 10768 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getForwardFee', + loc: { start: 12543, end: 12556 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12602, end: 12605 } + }, + loc: { start: 12602, end: 12605 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 12557, end: 12562 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12564, end: 12567 } + }, + loc: { start: 12564, end: 12567 } + }, + loc: { start: 12557, end: 12567 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 12569, end: 12573 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12575, end: 12578 } + }, + loc: { start: 12575, end: 12578 } + }, + loc: { start: 12569, end: 12578 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 12580, end: 12593 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 12595, end: 12599 } + }, + typeArgs: [], + loc: { start: 12595, end: 12599 } + }, + loc: { start: 12580, end: 12599 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETFORWARDFEE' ] + }, + loc: { start: 12535, end: 12623 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSimpleForwardFee', + loc: { start: 13528, end: 13547 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13593, end: 13596 } + }, + loc: { start: 13593, end: 13596 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 13548, end: 13553 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13555, end: 13558 } + }, + loc: { start: 13555, end: 13558 } + }, + loc: { start: 13548, end: 13558 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 13560, end: 13564 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13566, end: 13569 } + }, + loc: { start: 13566, end: 13569 } + }, + loc: { start: 13560, end: 13569 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 13571, end: 13584 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 13586, end: 13590 } + }, + typeArgs: [], + loc: { start: 13586, end: 13590 } + }, + loc: { start: 13571, end: 13590 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETFORWARDFEESIMPLE' ] + }, + loc: { start: 13520, end: 13620 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getOriginalFwdFee', + loc: { start: 15782, end: 15799 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15835, end: 15838 } + }, + loc: { start: 15835, end: 15838 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'fwdFee', + loc: { start: 15800, end: 15806 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15808, end: 15811 } + }, + loc: { start: 15808, end: 15811 } + }, + loc: { start: 15800, end: 15811 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 15813, end: 15826 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 15828, end: 15832 } + }, + typeArgs: [], + loc: { start: 15828, end: 15832 } + }, + loc: { start: 15813, end: 15832 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETORIGINALFWDFEE' ] + }, + loc: { start: 15774, end: 15860 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'setGasLimit', + loc: { start: 16541, end: 16552 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'limit', + loc: { start: 16553, end: 16558 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 16560, end: 16563 } + }, + loc: { start: 16560, end: 16563 } + }, + loc: { start: 16553, end: 16563 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SETGASLIMIT' ] + }, + loc: { start: 16533, end: 16580 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSeed', + loc: { start: 17350, end: 17357 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 17361, end: 17364 } + }, + loc: { start: 17361, end: 17364 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RANDSEED' ] + }, + loc: { start: 17342, end: 17377 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'setSeed', + loc: { start: 18258, end: 18265 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'seed', + loc: { start: 18266, end: 18270 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 18272, end: 18275 } + }, + loc: { start: 18272, end: 18275 } + }, + loc: { start: 18266, end: 18275 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SETRAND' ] + }, + loc: { start: 18250, end: 18288 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myCode', + loc: { start: 18585, end: 18591 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 18595, end: 18599 } }, + loc: { start: 18595, end: 18599 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MYCODE' ] + }, + loc: { start: 18577, end: 18610 } + } + ] + }, + 'myBalance' => { + kind: 'tact', + path: 'std/internal/contract.tact', + code: '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Computes and returns an `Int` value of the SHA-256 hash of the `code` and `data` of the given contract. To assemble the `code` and `data` cells together for hashing, the standard `Cell` representation is used.\n' + + '///\n' + + '/// This hash is commonly called account ID. Together with the workchain ID it deterministically forms the address of the contract on TON Blockchain.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let initPkg: StateInit = initOf SomeContract();\n' + + '/// let accountId: Int = contractHash(initPkg.code, initPkg.data);\n' + + '/// let basechainAddr: Address = newAddress(0, accountId);\n' + + '/// let basechainAddr2: Address = contractAddressExt(0, initPkg.code, initPkg.data);\n' + + '///\n' + + '/// basechainAddr == basechainAddr2; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contracthash\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#newaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '///\n' + + 'asm fun contractHash(code: Cell, data: Cell): Int {\n' + + ' // According to the https://docs.tact-lang.org/book/cells#cells-representation,\n' + + ' // the layout for the Builder to hash goes as follows:\n' + + ' // 1) refs_descriptor:bits8 | bits_descriptor:bits8 | data:bitsN\n' + + ' //\n' + + ' // refs_descriptor: ref_count + ((exotic? & 1) * 8) + (mask * 32)\n' + + ' // 2 refs (code + data), non-exotic, zero-mask\n' + + ' //\n' + + ' // bits_descriptor: floor(bit_count / 8) + ceil(bit_count, 8)\n' + + ' // floor (5 bits / 8) + ceil(5 bits / 8) = 0 + 1 = 1\n' + + ' //\n' + + ' // data: [0b00110] + [0b100] = [0b00110100] = 0x34 (data + augmented bits)\n' + + ' // 0b00110 - data (split_depth, special, code, data, Library)\n' + + ' // 0b100 - augmented bits (Leading 1 + zeroes to make section multiple of eight)\n' + + ' //\n' + + ' // That is: (2 << 16) | (1 << 8) | 0x34 = 131380 for all three.\n' + + ' //\n' + + ' // 2) and 3) depth_descriptors: CDEPTH of `code` and CDEPTH of `data`\n' + + ' // 4) and 5) ref hashes: HASHCU of `code` and HASHCU of `data`\n' + + '\n' + + ' // Group 1: Computations and arrangements\n' + + ' s0 PUSH HASHCU // `data` hash\n' + + ' s2 PUSH HASHCU // `code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `code` depth\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + '\n' + + ' // Group 2: Composition of the Builder\n' + + ' NEWC\n' + + ' 24 STU // store refs_descriptor | bits_descriptor | data\n' + + ' 16 STU // store depth_descriptor for `code`\n' + + ' 16 STU // store depth_descriptor for `data`\n' + + ' 256 STU // store `code` hash\n' + + ' 256 STU // store `data` hash\n' + + '\n' + + ' // Group 3: SHA256 hash of the resulting Builder\n' + + ' ONE HASHEXT_SHA256\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + "/// Computes smart contract's `Address` in the `chain` ID using the contract's `code` and the contract's initial state `data`. Use the `initOf` expression to obtain the initial `code` and initial `data` of a given contract.\n" + + '///\n' + + '/// This function lets you specify arbitrary `chain` IDs, including the common -1 (masterchain) and 0 (basechain) ones.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let initPkg: StateInit = initOf SomeContract();\n' + + '/// let hereBeDragons: Address = contractAddressExt(0, initPkg.code, initPkg.data);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '/// * https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'inline fun contractAddressExt(chain: Int, code: Cell, data: Cell): Address {\n' + + ' let hash = contractHash(code, data);\n' + + ' return newAddress(chain, hash);\n' + + '}\n' + + '\n' + + '/// Struct containing the initial state, i.e. initial code and initial data of the given contract upon its deployment.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'struct StateInit {\n' + + ' /// Initial code of the contract (compiled bitcode)\n' + + ' code: Cell;\n' + + '\n' + + ' /// Initial data of the contract (parameters of `init()` function or contract parameters)\n' + + ' data: Cell;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.1.\n' + + '///\n' + + '/// Efficiently compares if the given address matches the basechain address of the contract.\n' + + '/// Returns true if addresses are the same, false otherwise.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let init = initOf SomeContract();\n' + + "/// init.hasSameBasechainAddress(sender()); // returns true if sender matches contract's basechain address\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// This function provides a gas-optimized implementation compared to direct address comparison:\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let init = initOf SomeContract();\n' + + '/// sender() == contractAddress(sender()); // less efficient approach\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// Note that this function works only for basechain addresses!\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddress\n' + + '///\n' + + 'inline extends fun hasSameBasechainAddress(self: StateInit, sender: Address): Bool {\n' + + ' let senderAddress = parseStdAddress(sender.asSlice()).address;\n' + + ' let baseAddress = contractBasechainAddress(self);\n' + + ' return baseAddress.hash!! == senderAddress;\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + "/// Computes smart contract's `Address` in the workchain ID 0 (basechain) using the `StateInit` `s` of the contract. Alias to `contractAddressExt(0, s.code, s.data)`.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let s: StateInit = initOf SomeContract();\n' + + '/// let foundMeSome: Address = contractAddress(s);\n' + + '/// let andSomeMore: Address = contractAddressExt(0, s.code, s.data);\n' + + '///\n' + + '/// foundMeSome == andSomeMore; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '/// * https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'inline fun contractAddress(s: StateInit): Address {\n' + + ' return contractAddressExt(0, s.code, s.data);\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Returns the address of the current smart contract as an `Address`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let meMyselfAndI: Address = myAddress();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#myaddress\n' + + '///\n' + + 'asm fun myAddress(): Address { MYADDR }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` balance of the smart contract as it was at the start of the compute phase of the current transaction.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let iNeedADolla: Int = myBalance();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#mybalance\n' + + '///\n' + + 'asm fun myBalance(): Int { BALANCE FIRST }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` amount of gas consumed by TVM in the current transaction so far. The resulting value includes the cost of calling this function.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let gas: Int = gasConsumed();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#gasconsumed\n' + + '///\n' + + 'asm fun gasConsumed(): Int { GASCONSUMED }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` amount of the accumulated storage fee debt. Storage fees are deducted from the incoming message value before the new contract balance is calculated.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let debt: Int = myStorageDue();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#mystoragedue\n' + + '///\n' + + 'asm fun myStorageDue(): Int { DUEPAYMENT }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Calculates and returns the storage fee in nanoToncoins `Int` for storing a contract with a given number of `cells` and `bits` for a number of `seconds`. Uses the prices of the masterchain if `isMasterchain` is `true`, otherwise the prices of the basechain. The current prices are obtained from the config param 18 of TON Blockchain.\n' + + '///\n' + + '/// Note, that specifying values of `cells` and `bits` higher than their maximum values listed in account state limits (`max_acc_state_cells` and `max_acc_state_bits`) will have the same result as with specifying the exact limits. In addition, make sure you take into account the deduplication of cells with the same hash.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fee: Int = getStorageFee(1_000, 1_000, 1_000, false);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify negative number of `cells`, `bits` or `seconds`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-gas#getstoragefee\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun getStorageFee(cells: Int, bits: Int, seconds: Int, isMasterchain: Bool): Int { GETSTORAGEFEE }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Calculates and returns the compute fee in nanoToncoins `Int` for a transaction that consumed `gasUsed` amount of gas. Uses the prices of the masterchain if `isMasterchain` is `true`, otherwise the prices of the basechain. The current prices are obtained from the config param 20 for the masterchain and config param 21 for the basechain of TON Blockchain.\n' + + '///\n' + + "/// When the `gasUsed` is less than a certain threshold called `flat_gas_limit`, there's a minimum price to pay based on the value of `flat_gas_price`. The less gas is used below this threshold, the higher the minimum price will be. See the example for `getSimpleComputeFee()` to derive that threshold.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fee: Int = getComputeFee(1_000, false);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify negative value of `gasUsed`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-gas#getcomputefee\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun getComputeFee(gasUsed: Int, isMasterchain: Bool): Int { GETGASFEE }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Similar to `getComputeFee()`, but without the `flat_gas_price`, i.e. without a minimum price to pay if the `gasUsed` is less than a certain '... 8611 more characters, + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'contractHash', + loc: { start: 1027, end: 1039 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1065, end: 1068 } + }, + loc: { start: 1065, end: 1068 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 1040, end: 1044 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 1046, end: 1050 } }, + loc: { start: 1046, end: 1050 } + }, + loc: { start: 1040, end: 1050 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'data', + loc: { start: 1052, end: 1056 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 1058, end: 1062 } }, + loc: { start: 1058, end: 1062 } + }, + loc: { start: 1052, end: 1062 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 's0 PUSH HASHCU // `data` hash\n' + + ' s2 PUSH HASHCU // `code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `code` depth\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + '\n' + + ' // Group 2: Composition of the Builder\n' + + ' NEWC\n' + + ' 24 STU // store refs_descriptor | bits_descriptor | data\n' + + ' 16 STU // store depth_descriptor for `code`\n' + + ' 16 STU // store depth_descriptor for `data`\n' + + ' 256 STU // store `code` hash\n' + + ' 256 STU // store `data` hash\n' + + '\n' + + ' // Group 3: SHA256 hash of the resulting Builder\n' + + ' ONE HASHEXT_SHA256' + ] + }, + loc: { start: 1019, end: 2666 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'contractAddressExt', + loc: { start: 3391, end: 3409 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3447, end: 3454 } + }, + typeArgs: [], + loc: { start: 3447, end: 3454 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'chain', + loc: { start: 3410, end: 3415 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3417, end: 3420 } + }, + loc: { start: 3417, end: 3420 } + }, + loc: { start: 3410, end: 3420 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 3422, end: 3426 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3428, end: 3432 } }, + loc: { start: 3428, end: 3432 } + }, + loc: { start: 3422, end: 3432 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'data', + loc: { start: 3434, end: 3438 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3440, end: 3444 } }, + loc: { start: 3440, end: 3444 } + }, + loc: { start: 3434, end: 3444 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'hash', + loc: { start: 3465, end: 3469 } + }, + type: undefined, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractHash', + loc: { start: 3472, end: 3484 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'code', + loc: { start: 3485, end: 3489 } + }, + { + kind: 'var', + name: 'data', + loc: { start: 3491, end: 3495 } + } + ], + loc: { start: 3472, end: 3496 } + }, + loc: { start: 3461, end: 3497 } + }, + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'newAddress', + loc: { start: 3509, end: 3519 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'chain', + loc: { start: 3520, end: 3525 } + }, + { + kind: 'var', + name: 'hash', + loc: { start: 3527, end: 3531 } + } + ], + loc: { start: 3509, end: 3532 } + }, + loc: { start: 3502, end: 3533 } + } + ] + }, + loc: { start: 3380, end: 3535 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 3731, end: 3740 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'code', + loc: { start: 3803, end: 3807 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3809, end: 3813 } }, + loc: { start: 3809, end: 3813 } + }, + initializer: undefined, + loc: { start: 3803, end: 3813 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'data', + loc: { start: 3914, end: 3918 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3920, end: 3924 } }, + loc: { start: 3920, end: 3924 } + }, + initializer: undefined, + loc: { start: 3914, end: 3924 } + } + ], + loc: { start: 3724, end: 3927 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'hasSameBasechainAddress', + loc: { start: 4778, end: 4801 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 4837, end: 4841 } + }, + typeArgs: [], + loc: { start: 4837, end: 4841 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'sender', + loc: { start: 4819, end: 4825 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 4827, end: 4834 } + }, + typeArgs: [], + loc: { start: 4827, end: 4834 } + }, + loc: { start: 4819, end: 4834 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'senderAddress', + loc: { start: 4852, end: 4865 } + }, + type: undefined, + expression: { + kind: 'field_access', + aggregate: { + kind: 'static_call', + function: { + kind: 'id', + text: 'parseStdAddress', + loc: { start: 4868, end: 4883 } + }, + typeArgs: [], + args: [ + { + kind: 'method_call', + self: { + kind: 'var', + name: 'sender', + loc: { start: 4884, end: 4890 } + }, + method: { + kind: 'id', + text: 'asSlice', + loc: { start: 4891, end: 4898 } + }, + typeArgs: [], + args: [], + loc: { start: 4884, end: 4900 } + } + ], + loc: { start: 4868, end: 4901 } + }, + field: { + kind: 'id', + text: 'address', + loc: { start: 4902, end: 4909 } + }, + loc: { start: 4868, end: 4909 } + }, + loc: { start: 4848, end: 4910 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'baseAddress', + loc: { start: 4919, end: 4930 } + }, + type: undefined, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractBasechainAddress', + loc: { start: 4933, end: 4957 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'self', + loc: { start: 4958, end: 4962 } + } + ], + loc: { start: 4933, end: 4963 } + }, + loc: { start: 4915, end: 4964 } + }, + { + kind: 'statement_return', + expression: { + kind: 'op_binary', + op: '==', + left: { + kind: 'op_unary', + op: '!!', + operand: { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'baseAddress', + loc: { start: 4976, end: 4987 } + }, + field: { + kind: 'id', + text: 'hash', + loc: { start: 4988, end: 4992 } + }, + loc: { start: 4976, end: 4992 } + }, + loc: { start: 4976, end: 4994 } + }, + right: { + kind: 'var', + name: 'senderAddress', + loc: { start: 4998, end: 5011 } + }, + loc: { start: 4976, end: 5011 } + }, + loc: { start: 4969, end: 5012 } + } + ] + }, + loc: { start: 4759, end: 5014 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 4808, end: 4817 } + }, + typeArgs: [], + loc: { start: 4808, end: 4817 } + } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'contractAddress', + loc: { start: 5709, end: 5724 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 5740, end: 5747 } + }, + typeArgs: [], + loc: { start: 5740, end: 5747 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 's', + loc: { start: 5725, end: 5726 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 5728, end: 5737 } + }, + typeArgs: [], + loc: { start: 5728, end: 5737 } + }, + loc: { start: 5725, end: 5737 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractAddressExt', + loc: { start: 5761, end: 5779 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 5780, end: 5781 } + }, + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 5783, end: 5784 } + }, + field: { + kind: 'id', + text: 'code', + loc: { start: 5785, end: 5789 } + }, + loc: { start: 5783, end: 5789 } + }, + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 5791, end: 5792 } + }, + field: { + kind: 'id', + text: 'data', + loc: { start: 5793, end: 5797 } + }, + loc: { start: 5791, end: 5797 } + } + ], + loc: { start: 5761, end: 5798 } + }, + loc: { start: 5754, end: 5799 } + } + ] + }, + loc: { start: 5698, end: 5801 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myAddress', + loc: { start: 6082, end: 6091 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 6095, end: 6102 } + }, + typeArgs: [], + loc: { start: 6095, end: 6102 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MYADDR' ] + }, + loc: { start: 6074, end: 6113 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myBalance', + loc: { start: 6454, end: 6463 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6467, end: 6470 } + }, + loc: { start: 6467, end: 6470 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'BALANCE FIRST' ] + }, + loc: { start: 6446, end: 6488 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'gasConsumed', + loc: { start: 6880, end: 6891 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6895, end: 6898 } + }, + loc: { start: 6895, end: 6898 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GASCONSUMED' ] + }, + loc: { start: 6872, end: 6914 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myStorageDue', + loc: { start: 7329, end: 7341 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7345, end: 7348 } + }, + loc: { start: 7345, end: 7348 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DUEPAYMENT' ] + }, + loc: { start: 7321, end: 7363 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getStorageFee', + loc: { start: 8517, end: 8530 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8590, end: 8593 } + }, + loc: { start: 8590, end: 8593 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 8531, end: 8536 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8538, end: 8541 } + }, + loc: { start: 8538, end: 8541 } + }, + loc: { start: 8531, end: 8541 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 8543, end: 8547 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8549, end: 8552 } + }, + loc: { start: 8549, end: 8552 } + }, + loc: { start: 8543, end: 8552 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'seconds', + loc: { start: 8554, end: 8561 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8563, end: 8566 } + }, + loc: { start: 8563, end: 8566 } + }, + loc: { start: 8554, end: 8566 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 8568, end: 8581 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 8583, end: 8587 } + }, + typeArgs: [], + loc: { start: 8583, end: 8587 } + }, + loc: { start: 8568, end: 8587 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETSTORAGEFEE' ] + }, + loc: { start: 8509, end: 8611 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getComputeFee', + loc: { start: 9734, end: 9747 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9784, end: 9787 } + }, + loc: { start: 9784, end: 9787 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'gasUsed', + loc: { start: 9748, end: 9755 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9757, end: 9760 } + }, + loc: { start: 9757, end: 9760 } + }, + loc: { start: 9748, end: 9760 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 9762, end: 9775 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 9777, end: 9781 } + }, + typeArgs: [], + loc: { start: 9777, end: 9781 } + }, + loc: { start: 9762, end: 9781 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETGASFEE' ] + }, + loc: { start: 9726, end: 9801 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSimpleComputeFee', + loc: { start: 10689, end: 10708 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10745, end: 10748 } + }, + loc: { start: 10745, end: 10748 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'gasUsed', + loc: { start: 10709, end: 10716 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10718, end: 10721 } + }, + loc: { start: 10718, end: 10721 } + }, + loc: { start: 10709, end: 10721 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 10723, end: 10736 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 10738, end: 10742 } + }, + typeArgs: [], + loc: { start: 10738, end: 10742 } + }, + loc: { start: 10723, end: 10742 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETGASFEESIMPLE' ] + }, + loc: { start: 10681, end: 10768 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getForwardFee', + loc: { start: 12543, end: 12556 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12602, end: 12605 } + }, + loc: { start: 12602, end: 12605 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 12557, end: 12562 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12564, end: 12567 } + }, + loc: { start: 12564, end: 12567 } + }, + loc: { start: 12557, end: 12567 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 12569, end: 12573 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12575, end: 12578 } + }, + loc: { start: 12575, end: 12578 } + }, + loc: { start: 12569, end: 12578 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 12580, end: 12593 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 12595, end: 12599 } + }, + typeArgs: [], + loc: { start: 12595, end: 12599 } + }, + loc: { start: 12580, end: 12599 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETFORWARDFEE' ] + }, + loc: { start: 12535, end: 12623 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSimpleForwardFee', + loc: { start: 13528, end: 13547 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13593, end: 13596 } + }, + loc: { start: 13593, end: 13596 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 13548, end: 13553 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13555, end: 13558 } + }, + loc: { start: 13555, end: 13558 } + }, + loc: { start: 13548, end: 13558 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 13560, end: 13564 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13566, end: 13569 } + }, + loc: { start: 13566, end: 13569 } + }, + loc: { start: 13560, end: 13569 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 13571, end: 13584 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 13586, end: 13590 } + }, + typeArgs: [], + loc: { start: 13586, end: 13590 } + }, + loc: { start: 13571, end: 13590 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETFORWARDFEESIMPLE' ] + }, + loc: { start: 13520, end: 13620 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getOriginalFwdFee', + loc: { start: 15782, end: 15799 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15835, end: 15838 } + }, + loc: { start: 15835, end: 15838 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'fwdFee', + loc: { start: 15800, end: 15806 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15808, end: 15811 } + }, + loc: { start: 15808, end: 15811 } + }, + loc: { start: 15800, end: 15811 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 15813, end: 15826 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 15828, end: 15832 } + }, + typeArgs: [], + loc: { start: 15828, end: 15832 } + }, + loc: { start: 15813, end: 15832 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETORIGINALFWDFEE' ] + }, + loc: { start: 15774, end: 15860 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'setGasLimit', + loc: { start: 16541, end: 16552 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'limit', + loc: { start: 16553, end: 16558 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 16560, end: 16563 } + }, + loc: { start: 16560, end: 16563 } + }, + loc: { start: 16553, end: 16563 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SETGASLIMIT' ] + }, + loc: { start: 16533, end: 16580 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSeed', + loc: { start: 17350, end: 17357 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 17361, end: 17364 } + }, + loc: { start: 17361, end: 17364 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RANDSEED' ] + }, + loc: { start: 17342, end: 17377 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'setSeed', + loc: { start: 18258, end: 18265 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'seed', + loc: { start: 18266, end: 18270 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 18272, end: 18275 } + }, + loc: { start: 18272, end: 18275 } + }, + loc: { start: 18266, end: 18275 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SETRAND' ] + }, + loc: { start: 18250, end: 18288 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myCode', + loc: { start: 18585, end: 18591 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 18595, end: 18599 } }, + loc: { start: 18595, end: 18599 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MYCODE' ] + }, + loc: { start: 18577, end: 18610 } + } + ] + }, + 'gasConsumed' => { + kind: 'tact', + path: 'std/internal/contract.tact', + code: '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Computes and returns an `Int` value of the SHA-256 hash of the `code` and `data` of the given contract. To assemble the `code` and `data` cells together for hashing, the standard `Cell` representation is used.\n' + + '///\n' + + '/// This hash is commonly called account ID. Together with the workchain ID it deterministically forms the address of the contract on TON Blockchain.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let initPkg: StateInit = initOf SomeContract();\n' + + '/// let accountId: Int = contractHash(initPkg.code, initPkg.data);\n' + + '/// let basechainAddr: Address = newAddress(0, accountId);\n' + + '/// let basechainAddr2: Address = contractAddressExt(0, initPkg.code, initPkg.data);\n' + + '///\n' + + '/// basechainAddr == basechainAddr2; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contracthash\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#newaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '///\n' + + 'asm fun contractHash(code: Cell, data: Cell): Int {\n' + + ' // According to the https://docs.tact-lang.org/book/cells#cells-representation,\n' + + ' // the layout for the Builder to hash goes as follows:\n' + + ' // 1) refs_descriptor:bits8 | bits_descriptor:bits8 | data:bitsN\n' + + ' //\n' + + ' // refs_descriptor: ref_count + ((exotic? & 1) * 8) + (mask * 32)\n' + + ' // 2 refs (code + data), non-exotic, zero-mask\n' + + ' //\n' + + ' // bits_descriptor: floor(bit_count / 8) + ceil(bit_count, 8)\n' + + ' // floor (5 bits / 8) + ceil(5 bits / 8) = 0 + 1 = 1\n' + + ' //\n' + + ' // data: [0b00110] + [0b100] = [0b00110100] = 0x34 (data + augmented bits)\n' + + ' // 0b00110 - data (split_depth, special, code, data, Library)\n' + + ' // 0b100 - augmented bits (Leading 1 + zeroes to make section multiple of eight)\n' + + ' //\n' + + ' // That is: (2 << 16) | (1 << 8) | 0x34 = 131380 for all three.\n' + + ' //\n' + + ' // 2) and 3) depth_descriptors: CDEPTH of `code` and CDEPTH of `data`\n' + + ' // 4) and 5) ref hashes: HASHCU of `code` and HASHCU of `data`\n' + + '\n' + + ' // Group 1: Computations and arrangements\n' + + ' s0 PUSH HASHCU // `data` hash\n' + + ' s2 PUSH HASHCU // `code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `code` depth\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + '\n' + + ' // Group 2: Composition of the Builder\n' + + ' NEWC\n' + + ' 24 STU // store refs_descriptor | bits_descriptor | data\n' + + ' 16 STU // store depth_descriptor for `code`\n' + + ' 16 STU // store depth_descriptor for `data`\n' + + ' 256 STU // store `code` hash\n' + + ' 256 STU // store `data` hash\n' + + '\n' + + ' // Group 3: SHA256 hash of the resulting Builder\n' + + ' ONE HASHEXT_SHA256\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + "/// Computes smart contract's `Address` in the `chain` ID using the contract's `code` and the contract's initial state `data`. Use the `initOf` expression to obtain the initial `code` and initial `data` of a given contract.\n" + + '///\n' + + '/// This function lets you specify arbitrary `chain` IDs, including the common -1 (masterchain) and 0 (basechain) ones.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let initPkg: StateInit = initOf SomeContract();\n' + + '/// let hereBeDragons: Address = contractAddressExt(0, initPkg.code, initPkg.data);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '/// * https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'inline fun contractAddressExt(chain: Int, code: Cell, data: Cell): Address {\n' + + ' let hash = contractHash(code, data);\n' + + ' return newAddress(chain, hash);\n' + + '}\n' + + '\n' + + '/// Struct containing the initial state, i.e. initial code and initial data of the given contract upon its deployment.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'struct StateInit {\n' + + ' /// Initial code of the contract (compiled bitcode)\n' + + ' code: Cell;\n' + + '\n' + + ' /// Initial data of the contract (parameters of `init()` function or contract parameters)\n' + + ' data: Cell;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.1.\n' + + '///\n' + + '/// Efficiently compares if the given address matches the basechain address of the contract.\n' + + '/// Returns true if addresses are the same, false otherwise.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let init = initOf SomeContract();\n' + + "/// init.hasSameBasechainAddress(sender()); // returns true if sender matches contract's basechain address\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// This function provides a gas-optimized implementation compared to direct address comparison:\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let init = initOf SomeContract();\n' + + '/// sender() == contractAddress(sender()); // less efficient approach\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// Note that this function works only for basechain addresses!\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddress\n' + + '///\n' + + 'inline extends fun hasSameBasechainAddress(self: StateInit, sender: Address): Bool {\n' + + ' let senderAddress = parseStdAddress(sender.asSlice()).address;\n' + + ' let baseAddress = contractBasechainAddress(self);\n' + + ' return baseAddress.hash!! == senderAddress;\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + "/// Computes smart contract's `Address` in the workchain ID 0 (basechain) using the `StateInit` `s` of the contract. Alias to `contractAddressExt(0, s.code, s.data)`.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let s: StateInit = initOf SomeContract();\n' + + '/// let foundMeSome: Address = contractAddress(s);\n' + + '/// let andSomeMore: Address = contractAddressExt(0, s.code, s.data);\n' + + '///\n' + + '/// foundMeSome == andSomeMore; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '/// * https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'inline fun contractAddress(s: StateInit): Address {\n' + + ' return contractAddressExt(0, s.code, s.data);\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Returns the address of the current smart contract as an `Address`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let meMyselfAndI: Address = myAddress();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#myaddress\n' + + '///\n' + + 'asm fun myAddress(): Address { MYADDR }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` balance of the smart contract as it was at the start of the compute phase of the current transaction.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let iNeedADolla: Int = myBalance();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#mybalance\n' + + '///\n' + + 'asm fun myBalance(): Int { BALANCE FIRST }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` amount of gas consumed by TVM in the current transaction so far. The resulting value includes the cost of calling this function.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let gas: Int = gasConsumed();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#gasconsumed\n' + + '///\n' + + 'asm fun gasConsumed(): Int { GASCONSUMED }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` amount of the accumulated storage fee debt. Storage fees are deducted from the incoming message value before the new contract balance is calculated.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let debt: Int = myStorageDue();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#mystoragedue\n' + + '///\n' + + 'asm fun myStorageDue(): Int { DUEPAYMENT }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Calculates and returns the storage fee in nanoToncoins `Int` for storing a contract with a given number of `cells` and `bits` for a number of `seconds`. Uses the prices of the masterchain if `isMasterchain` is `true`, otherwise the prices of the basechain. The current prices are obtained from the config param 18 of TON Blockchain.\n' + + '///\n' + + '/// Note, that specifying values of `cells` and `bits` higher than their maximum values listed in account state limits (`max_acc_state_cells` and `max_acc_state_bits`) will have the same result as with specifying the exact limits. In addition, make sure you take into account the deduplication of cells with the same hash.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fee: Int = getStorageFee(1_000, 1_000, 1_000, false);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify negative number of `cells`, `bits` or `seconds`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-gas#getstoragefee\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun getStorageFee(cells: Int, bits: Int, seconds: Int, isMasterchain: Bool): Int { GETSTORAGEFEE }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Calculates and returns the compute fee in nanoToncoins `Int` for a transaction that consumed `gasUsed` amount of gas. Uses the prices of the masterchain if `isMasterchain` is `true`, otherwise the prices of the basechain. The current prices are obtained from the config param 20 for the masterchain and config param 21 for the basechain of TON Blockchain.\n' + + '///\n' + + "/// When the `gasUsed` is less than a certain threshold called `flat_gas_limit`, there's a minimum price to pay based on the value of `flat_gas_price`. The less gas is used below this threshold, the higher the minimum price will be. See the example for `getSimpleComputeFee()` to derive that threshold.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fee: Int = getComputeFee(1_000, false);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify negative value of `gasUsed`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-gas#getcomputefee\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun getComputeFee(gasUsed: Int, isMasterchain: Bool): Int { GETGASFEE }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Similar to `getComputeFee()`, but without the `flat_gas_price`, i.e. without a minimum price to pay if the `gasUsed` is less than a certain '... 8611 more characters, + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'contractHash', + loc: { start: 1027, end: 1039 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1065, end: 1068 } + }, + loc: { start: 1065, end: 1068 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 1040, end: 1044 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 1046, end: 1050 } }, + loc: { start: 1046, end: 1050 } + }, + loc: { start: 1040, end: 1050 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'data', + loc: { start: 1052, end: 1056 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 1058, end: 1062 } }, + loc: { start: 1058, end: 1062 } + }, + loc: { start: 1052, end: 1062 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 's0 PUSH HASHCU // `data` hash\n' + + ' s2 PUSH HASHCU // `code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `code` depth\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + '\n' + + ' // Group 2: Composition of the Builder\n' + + ' NEWC\n' + + ' 24 STU // store refs_descriptor | bits_descriptor | data\n' + + ' 16 STU // store depth_descriptor for `code`\n' + + ' 16 STU // store depth_descriptor for `data`\n' + + ' 256 STU // store `code` hash\n' + + ' 256 STU // store `data` hash\n' + + '\n' + + ' // Group 3: SHA256 hash of the resulting Builder\n' + + ' ONE HASHEXT_SHA256' + ] + }, + loc: { start: 1019, end: 2666 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'contractAddressExt', + loc: { start: 3391, end: 3409 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3447, end: 3454 } + }, + typeArgs: [], + loc: { start: 3447, end: 3454 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'chain', + loc: { start: 3410, end: 3415 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3417, end: 3420 } + }, + loc: { start: 3417, end: 3420 } + }, + loc: { start: 3410, end: 3420 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 3422, end: 3426 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3428, end: 3432 } }, + loc: { start: 3428, end: 3432 } + }, + loc: { start: 3422, end: 3432 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'data', + loc: { start: 3434, end: 3438 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3440, end: 3444 } }, + loc: { start: 3440, end: 3444 } + }, + loc: { start: 3434, end: 3444 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'hash', + loc: { start: 3465, end: 3469 } + }, + type: undefined, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractHash', + loc: { start: 3472, end: 3484 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'code', + loc: { start: 3485, end: 3489 } + }, + { + kind: 'var', + name: 'data', + loc: { start: 3491, end: 3495 } + } + ], + loc: { start: 3472, end: 3496 } + }, + loc: { start: 3461, end: 3497 } + }, + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'newAddress', + loc: { start: 3509, end: 3519 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'chain', + loc: { start: 3520, end: 3525 } + }, + { + kind: 'var', + name: 'hash', + loc: { start: 3527, end: 3531 } + } + ], + loc: { start: 3509, end: 3532 } + }, + loc: { start: 3502, end: 3533 } + } + ] + }, + loc: { start: 3380, end: 3535 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 3731, end: 3740 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'code', + loc: { start: 3803, end: 3807 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3809, end: 3813 } }, + loc: { start: 3809, end: 3813 } + }, + initializer: undefined, + loc: { start: 3803, end: 3813 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'data', + loc: { start: 3914, end: 3918 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3920, end: 3924 } }, + loc: { start: 3920, end: 3924 } + }, + initializer: undefined, + loc: { start: 3914, end: 3924 } + } + ], + loc: { start: 3724, end: 3927 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'hasSameBasechainAddress', + loc: { start: 4778, end: 4801 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 4837, end: 4841 } + }, + typeArgs: [], + loc: { start: 4837, end: 4841 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'sender', + loc: { start: 4819, end: 4825 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 4827, end: 4834 } + }, + typeArgs: [], + loc: { start: 4827, end: 4834 } + }, + loc: { start: 4819, end: 4834 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'senderAddress', + loc: { start: 4852, end: 4865 } + }, + type: undefined, + expression: { + kind: 'field_access', + aggregate: { + kind: 'static_call', + function: { + kind: 'id', + text: 'parseStdAddress', + loc: { start: 4868, end: 4883 } + }, + typeArgs: [], + args: [ + { + kind: 'method_call', + self: { + kind: 'var', + name: 'sender', + loc: { start: 4884, end: 4890 } + }, + method: { + kind: 'id', + text: 'asSlice', + loc: { start: 4891, end: 4898 } + }, + typeArgs: [], + args: [], + loc: { start: 4884, end: 4900 } + } + ], + loc: { start: 4868, end: 4901 } + }, + field: { + kind: 'id', + text: 'address', + loc: { start: 4902, end: 4909 } + }, + loc: { start: 4868, end: 4909 } + }, + loc: { start: 4848, end: 4910 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'baseAddress', + loc: { start: 4919, end: 4930 } + }, + type: undefined, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractBasechainAddress', + loc: { start: 4933, end: 4957 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'self', + loc: { start: 4958, end: 4962 } + } + ], + loc: { start: 4933, end: 4963 } + }, + loc: { start: 4915, end: 4964 } + }, + { + kind: 'statement_return', + expression: { + kind: 'op_binary', + op: '==', + left: { + kind: 'op_unary', + op: '!!', + operand: { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'baseAddress', + loc: { start: 4976, end: 4987 } + }, + field: { + kind: 'id', + text: 'hash', + loc: { start: 4988, end: 4992 } + }, + loc: { start: 4976, end: 4992 } + }, + loc: { start: 4976, end: 4994 } + }, + right: { + kind: 'var', + name: 'senderAddress', + loc: { start: 4998, end: 5011 } + }, + loc: { start: 4976, end: 5011 } + }, + loc: { start: 4969, end: 5012 } + } + ] + }, + loc: { start: 4759, end: 5014 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 4808, end: 4817 } + }, + typeArgs: [], + loc: { start: 4808, end: 4817 } + } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'contractAddress', + loc: { start: 5709, end: 5724 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 5740, end: 5747 } + }, + typeArgs: [], + loc: { start: 5740, end: 5747 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 's', + loc: { start: 5725, end: 5726 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 5728, end: 5737 } + }, + typeArgs: [], + loc: { start: 5728, end: 5737 } + }, + loc: { start: 5725, end: 5737 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractAddressExt', + loc: { start: 5761, end: 5779 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 5780, end: 5781 } + }, + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 5783, end: 5784 } + }, + field: { + kind: 'id', + text: 'code', + loc: { start: 5785, end: 5789 } + }, + loc: { start: 5783, end: 5789 } + }, + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 5791, end: 5792 } + }, + field: { + kind: 'id', + text: 'data', + loc: { start: 5793, end: 5797 } + }, + loc: { start: 5791, end: 5797 } + } + ], + loc: { start: 5761, end: 5798 } + }, + loc: { start: 5754, end: 5799 } + } + ] + }, + loc: { start: 5698, end: 5801 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myAddress', + loc: { start: 6082, end: 6091 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 6095, end: 6102 } + }, + typeArgs: [], + loc: { start: 6095, end: 6102 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MYADDR' ] + }, + loc: { start: 6074, end: 6113 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myBalance', + loc: { start: 6454, end: 6463 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6467, end: 6470 } + }, + loc: { start: 6467, end: 6470 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'BALANCE FIRST' ] + }, + loc: { start: 6446, end: 6488 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'gasConsumed', + loc: { start: 6880, end: 6891 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6895, end: 6898 } + }, + loc: { start: 6895, end: 6898 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GASCONSUMED' ] + }, + loc: { start: 6872, end: 6914 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myStorageDue', + loc: { start: 7329, end: 7341 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7345, end: 7348 } + }, + loc: { start: 7345, end: 7348 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DUEPAYMENT' ] + }, + loc: { start: 7321, end: 7363 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getStorageFee', + loc: { start: 8517, end: 8530 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8590, end: 8593 } + }, + loc: { start: 8590, end: 8593 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 8531, end: 8536 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8538, end: 8541 } + }, + loc: { start: 8538, end: 8541 } + }, + loc: { start: 8531, end: 8541 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 8543, end: 8547 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8549, end: 8552 } + }, + loc: { start: 8549, end: 8552 } + }, + loc: { start: 8543, end: 8552 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'seconds', + loc: { start: 8554, end: 8561 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8563, end: 8566 } + }, + loc: { start: 8563, end: 8566 } + }, + loc: { start: 8554, end: 8566 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 8568, end: 8581 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 8583, end: 8587 } + }, + typeArgs: [], + loc: { start: 8583, end: 8587 } + }, + loc: { start: 8568, end: 8587 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETSTORAGEFEE' ] + }, + loc: { start: 8509, end: 8611 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getComputeFee', + loc: { start: 9734, end: 9747 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9784, end: 9787 } + }, + loc: { start: 9784, end: 9787 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'gasUsed', + loc: { start: 9748, end: 9755 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9757, end: 9760 } + }, + loc: { start: 9757, end: 9760 } + }, + loc: { start: 9748, end: 9760 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 9762, end: 9775 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 9777, end: 9781 } + }, + typeArgs: [], + loc: { start: 9777, end: 9781 } + }, + loc: { start: 9762, end: 9781 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETGASFEE' ] + }, + loc: { start: 9726, end: 9801 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSimpleComputeFee', + loc: { start: 10689, end: 10708 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10745, end: 10748 } + }, + loc: { start: 10745, end: 10748 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'gasUsed', + loc: { start: 10709, end: 10716 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10718, end: 10721 } + }, + loc: { start: 10718, end: 10721 } + }, + loc: { start: 10709, end: 10721 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 10723, end: 10736 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 10738, end: 10742 } + }, + typeArgs: [], + loc: { start: 10738, end: 10742 } + }, + loc: { start: 10723, end: 10742 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETGASFEESIMPLE' ] + }, + loc: { start: 10681, end: 10768 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getForwardFee', + loc: { start: 12543, end: 12556 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12602, end: 12605 } + }, + loc: { start: 12602, end: 12605 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 12557, end: 12562 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12564, end: 12567 } + }, + loc: { start: 12564, end: 12567 } + }, + loc: { start: 12557, end: 12567 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 12569, end: 12573 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12575, end: 12578 } + }, + loc: { start: 12575, end: 12578 } + }, + loc: { start: 12569, end: 12578 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 12580, end: 12593 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 12595, end: 12599 } + }, + typeArgs: [], + loc: { start: 12595, end: 12599 } + }, + loc: { start: 12580, end: 12599 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETFORWARDFEE' ] + }, + loc: { start: 12535, end: 12623 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSimpleForwardFee', + loc: { start: 13528, end: 13547 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13593, end: 13596 } + }, + loc: { start: 13593, end: 13596 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 13548, end: 13553 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13555, end: 13558 } + }, + loc: { start: 13555, end: 13558 } + }, + loc: { start: 13548, end: 13558 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 13560, end: 13564 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13566, end: 13569 } + }, + loc: { start: 13566, end: 13569 } + }, + loc: { start: 13560, end: 13569 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 13571, end: 13584 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 13586, end: 13590 } + }, + typeArgs: [], + loc: { start: 13586, end: 13590 } + }, + loc: { start: 13571, end: 13590 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETFORWARDFEESIMPLE' ] + }, + loc: { start: 13520, end: 13620 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getOriginalFwdFee', + loc: { start: 15782, end: 15799 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15835, end: 15838 } + }, + loc: { start: 15835, end: 15838 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'fwdFee', + loc: { start: 15800, end: 15806 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15808, end: 15811 } + }, + loc: { start: 15808, end: 15811 } + }, + loc: { start: 15800, end: 15811 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 15813, end: 15826 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 15828, end: 15832 } + }, + typeArgs: [], + loc: { start: 15828, end: 15832 } + }, + loc: { start: 15813, end: 15832 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETORIGINALFWDFEE' ] + }, + loc: { start: 15774, end: 15860 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'setGasLimit', + loc: { start: 16541, end: 16552 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'limit', + loc: { start: 16553, end: 16558 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 16560, end: 16563 } + }, + loc: { start: 16560, end: 16563 } + }, + loc: { start: 16553, end: 16563 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SETGASLIMIT' ] + }, + loc: { start: 16533, end: 16580 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSeed', + loc: { start: 17350, end: 17357 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 17361, end: 17364 } + }, + loc: { start: 17361, end: 17364 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RANDSEED' ] + }, + loc: { start: 17342, end: 17377 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'setSeed', + loc: { start: 18258, end: 18265 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'seed', + loc: { start: 18266, end: 18270 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 18272, end: 18275 } + }, + loc: { start: 18272, end: 18275 } + }, + loc: { start: 18266, end: 18275 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SETRAND' ] + }, + loc: { start: 18250, end: 18288 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myCode', + loc: { start: 18585, end: 18591 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 18595, end: 18599 } }, + loc: { start: 18595, end: 18599 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MYCODE' ] + }, + loc: { start: 18577, end: 18610 } + } + ] + }, + 'myStorageDue' => { + kind: 'tact', + path: 'std/internal/contract.tact', + code: '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Computes and returns an `Int` value of the SHA-256 hash of the `code` and `data` of the given contract. To assemble the `code` and `data` cells together for hashing, the standard `Cell` representation is used.\n' + + '///\n' + + '/// This hash is commonly called account ID. Together with the workchain ID it deterministically forms the address of the contract on TON Blockchain.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let initPkg: StateInit = initOf SomeContract();\n' + + '/// let accountId: Int = contractHash(initPkg.code, initPkg.data);\n' + + '/// let basechainAddr: Address = newAddress(0, accountId);\n' + + '/// let basechainAddr2: Address = contractAddressExt(0, initPkg.code, initPkg.data);\n' + + '///\n' + + '/// basechainAddr == basechainAddr2; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contracthash\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#newaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '///\n' + + 'asm fun contractHash(code: Cell, data: Cell): Int {\n' + + ' // According to the https://docs.tact-lang.org/book/cells#cells-representation,\n' + + ' // the layout for the Builder to hash goes as follows:\n' + + ' // 1) refs_descriptor:bits8 | bits_descriptor:bits8 | data:bitsN\n' + + ' //\n' + + ' // refs_descriptor: ref_count + ((exotic? & 1) * 8) + (mask * 32)\n' + + ' // 2 refs (code + data), non-exotic, zero-mask\n' + + ' //\n' + + ' // bits_descriptor: floor(bit_count / 8) + ceil(bit_count, 8)\n' + + ' // floor (5 bits / 8) + ceil(5 bits / 8) = 0 + 1 = 1\n' + + ' //\n' + + ' // data: [0b00110] + [0b100] = [0b00110100] = 0x34 (data + augmented bits)\n' + + ' // 0b00110 - data (split_depth, special, code, data, Library)\n' + + ' // 0b100 - augmented bits (Leading 1 + zeroes to make section multiple of eight)\n' + + ' //\n' + + ' // That is: (2 << 16) | (1 << 8) | 0x34 = 131380 for all three.\n' + + ' //\n' + + ' // 2) and 3) depth_descriptors: CDEPTH of `code` and CDEPTH of `data`\n' + + ' // 4) and 5) ref hashes: HASHCU of `code` and HASHCU of `data`\n' + + '\n' + + ' // Group 1: Computations and arrangements\n' + + ' s0 PUSH HASHCU // `data` hash\n' + + ' s2 PUSH HASHCU // `code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `code` depth\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + '\n' + + ' // Group 2: Composition of the Builder\n' + + ' NEWC\n' + + ' 24 STU // store refs_descriptor | bits_descriptor | data\n' + + ' 16 STU // store depth_descriptor for `code`\n' + + ' 16 STU // store depth_descriptor for `data`\n' + + ' 256 STU // store `code` hash\n' + + ' 256 STU // store `data` hash\n' + + '\n' + + ' // Group 3: SHA256 hash of the resulting Builder\n' + + ' ONE HASHEXT_SHA256\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + "/// Computes smart contract's `Address` in the `chain` ID using the contract's `code` and the contract's initial state `data`. Use the `initOf` expression to obtain the initial `code` and initial `data` of a given contract.\n" + + '///\n' + + '/// This function lets you specify arbitrary `chain` IDs, including the common -1 (masterchain) and 0 (basechain) ones.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let initPkg: StateInit = initOf SomeContract();\n' + + '/// let hereBeDragons: Address = contractAddressExt(0, initPkg.code, initPkg.data);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '/// * https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'inline fun contractAddressExt(chain: Int, code: Cell, data: Cell): Address {\n' + + ' let hash = contractHash(code, data);\n' + + ' return newAddress(chain, hash);\n' + + '}\n' + + '\n' + + '/// Struct containing the initial state, i.e. initial code and initial data of the given contract upon its deployment.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'struct StateInit {\n' + + ' /// Initial code of the contract (compiled bitcode)\n' + + ' code: Cell;\n' + + '\n' + + ' /// Initial data of the contract (parameters of `init()` function or contract parameters)\n' + + ' data: Cell;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.1.\n' + + '///\n' + + '/// Efficiently compares if the given address matches the basechain address of the contract.\n' + + '/// Returns true if addresses are the same, false otherwise.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let init = initOf SomeContract();\n' + + "/// init.hasSameBasechainAddress(sender()); // returns true if sender matches contract's basechain address\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// This function provides a gas-optimized implementation compared to direct address comparison:\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let init = initOf SomeContract();\n' + + '/// sender() == contractAddress(sender()); // less efficient approach\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// Note that this function works only for basechain addresses!\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddress\n' + + '///\n' + + 'inline extends fun hasSameBasechainAddress(self: StateInit, sender: Address): Bool {\n' + + ' let senderAddress = parseStdAddress(sender.asSlice()).address;\n' + + ' let baseAddress = contractBasechainAddress(self);\n' + + ' return baseAddress.hash!! == senderAddress;\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + "/// Computes smart contract's `Address` in the workchain ID 0 (basechain) using the `StateInit` `s` of the contract. Alias to `contractAddressExt(0, s.code, s.data)`.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let s: StateInit = initOf SomeContract();\n' + + '/// let foundMeSome: Address = contractAddress(s);\n' + + '/// let andSomeMore: Address = contractAddressExt(0, s.code, s.data);\n' + + '///\n' + + '/// foundMeSome == andSomeMore; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '/// * https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'inline fun contractAddress(s: StateInit): Address {\n' + + ' return contractAddressExt(0, s.code, s.data);\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Returns the address of the current smart contract as an `Address`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let meMyselfAndI: Address = myAddress();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#myaddress\n' + + '///\n' + + 'asm fun myAddress(): Address { MYADDR }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` balance of the smart contract as it was at the start of the compute phase of the current transaction.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let iNeedADolla: Int = myBalance();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#mybalance\n' + + '///\n' + + 'asm fun myBalance(): Int { BALANCE FIRST }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` amount of gas consumed by TVM in the current transaction so far. The resulting value includes the cost of calling this function.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let gas: Int = gasConsumed();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#gasconsumed\n' + + '///\n' + + 'asm fun gasConsumed(): Int { GASCONSUMED }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` amount of the accumulated storage fee debt. Storage fees are deducted from the incoming message value before the new contract balance is calculated.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let debt: Int = myStorageDue();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#mystoragedue\n' + + '///\n' + + 'asm fun myStorageDue(): Int { DUEPAYMENT }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Calculates and returns the storage fee in nanoToncoins `Int` for storing a contract with a given number of `cells` and `bits` for a number of `seconds`. Uses the prices of the masterchain if `isMasterchain` is `true`, otherwise the prices of the basechain. The current prices are obtained from the config param 18 of TON Blockchain.\n' + + '///\n' + + '/// Note, that specifying values of `cells` and `bits` higher than their maximum values listed in account state limits (`max_acc_state_cells` and `max_acc_state_bits`) will have the same result as with specifying the exact limits. In addition, make sure you take into account the deduplication of cells with the same hash.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fee: Int = getStorageFee(1_000, 1_000, 1_000, false);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify negative number of `cells`, `bits` or `seconds`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-gas#getstoragefee\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun getStorageFee(cells: Int, bits: Int, seconds: Int, isMasterchain: Bool): Int { GETSTORAGEFEE }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Calculates and returns the compute fee in nanoToncoins `Int` for a transaction that consumed `gasUsed` amount of gas. Uses the prices of the masterchain if `isMasterchain` is `true`, otherwise the prices of the basechain. The current prices are obtained from the config param 20 for the masterchain and config param 21 for the basechain of TON Blockchain.\n' + + '///\n' + + "/// When the `gasUsed` is less than a certain threshold called `flat_gas_limit`, there's a minimum price to pay based on the value of `flat_gas_price`. The less gas is used below this threshold, the higher the minimum price will be. See the example for `getSimpleComputeFee()` to derive that threshold.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fee: Int = getComputeFee(1_000, false);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify negative value of `gasUsed`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-gas#getcomputefee\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun getComputeFee(gasUsed: Int, isMasterchain: Bool): Int { GETGASFEE }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Similar to `getComputeFee()`, but without the `flat_gas_price`, i.e. without a minimum price to pay if the `gasUsed` is less than a certain '... 8611 more characters, + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'contractHash', + loc: { start: 1027, end: 1039 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1065, end: 1068 } + }, + loc: { start: 1065, end: 1068 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 1040, end: 1044 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 1046, end: 1050 } }, + loc: { start: 1046, end: 1050 } + }, + loc: { start: 1040, end: 1050 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'data', + loc: { start: 1052, end: 1056 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 1058, end: 1062 } }, + loc: { start: 1058, end: 1062 } + }, + loc: { start: 1052, end: 1062 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 's0 PUSH HASHCU // `data` hash\n' + + ' s2 PUSH HASHCU // `code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `code` depth\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + '\n' + + ' // Group 2: Composition of the Builder\n' + + ' NEWC\n' + + ' 24 STU // store refs_descriptor | bits_descriptor | data\n' + + ' 16 STU // store depth_descriptor for `code`\n' + + ' 16 STU // store depth_descriptor for `data`\n' + + ' 256 STU // store `code` hash\n' + + ' 256 STU // store `data` hash\n' + + '\n' + + ' // Group 3: SHA256 hash of the resulting Builder\n' + + ' ONE HASHEXT_SHA256' + ] + }, + loc: { start: 1019, end: 2666 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'contractAddressExt', + loc: { start: 3391, end: 3409 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3447, end: 3454 } + }, + typeArgs: [], + loc: { start: 3447, end: 3454 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'chain', + loc: { start: 3410, end: 3415 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3417, end: 3420 } + }, + loc: { start: 3417, end: 3420 } + }, + loc: { start: 3410, end: 3420 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 3422, end: 3426 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3428, end: 3432 } }, + loc: { start: 3428, end: 3432 } + }, + loc: { start: 3422, end: 3432 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'data', + loc: { start: 3434, end: 3438 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3440, end: 3444 } }, + loc: { start: 3440, end: 3444 } + }, + loc: { start: 3434, end: 3444 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'hash', + loc: { start: 3465, end: 3469 } + }, + type: undefined, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractHash', + loc: { start: 3472, end: 3484 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'code', + loc: { start: 3485, end: 3489 } + }, + { + kind: 'var', + name: 'data', + loc: { start: 3491, end: 3495 } + } + ], + loc: { start: 3472, end: 3496 } + }, + loc: { start: 3461, end: 3497 } + }, + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'newAddress', + loc: { start: 3509, end: 3519 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'chain', + loc: { start: 3520, end: 3525 } + }, + { + kind: 'var', + name: 'hash', + loc: { start: 3527, end: 3531 } + } + ], + loc: { start: 3509, end: 3532 } + }, + loc: { start: 3502, end: 3533 } + } + ] + }, + loc: { start: 3380, end: 3535 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 3731, end: 3740 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'code', + loc: { start: 3803, end: 3807 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3809, end: 3813 } }, + loc: { start: 3809, end: 3813 } + }, + initializer: undefined, + loc: { start: 3803, end: 3813 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'data', + loc: { start: 3914, end: 3918 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3920, end: 3924 } }, + loc: { start: 3920, end: 3924 } + }, + initializer: undefined, + loc: { start: 3914, end: 3924 } + } + ], + loc: { start: 3724, end: 3927 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'hasSameBasechainAddress', + loc: { start: 4778, end: 4801 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 4837, end: 4841 } + }, + typeArgs: [], + loc: { start: 4837, end: 4841 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'sender', + loc: { start: 4819, end: 4825 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 4827, end: 4834 } + }, + typeArgs: [], + loc: { start: 4827, end: 4834 } + }, + loc: { start: 4819, end: 4834 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'senderAddress', + loc: { start: 4852, end: 4865 } + }, + type: undefined, + expression: { + kind: 'field_access', + aggregate: { + kind: 'static_call', + function: { + kind: 'id', + text: 'parseStdAddress', + loc: { start: 4868, end: 4883 } + }, + typeArgs: [], + args: [ + { + kind: 'method_call', + self: { + kind: 'var', + name: 'sender', + loc: { start: 4884, end: 4890 } + }, + method: { + kind: 'id', + text: 'asSlice', + loc: { start: 4891, end: 4898 } + }, + typeArgs: [], + args: [], + loc: { start: 4884, end: 4900 } + } + ], + loc: { start: 4868, end: 4901 } + }, + field: { + kind: 'id', + text: 'address', + loc: { start: 4902, end: 4909 } + }, + loc: { start: 4868, end: 4909 } + }, + loc: { start: 4848, end: 4910 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'baseAddress', + loc: { start: 4919, end: 4930 } + }, + type: undefined, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractBasechainAddress', + loc: { start: 4933, end: 4957 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'self', + loc: { start: 4958, end: 4962 } + } + ], + loc: { start: 4933, end: 4963 } + }, + loc: { start: 4915, end: 4964 } + }, + { + kind: 'statement_return', + expression: { + kind: 'op_binary', + op: '==', + left: { + kind: 'op_unary', + op: '!!', + operand: { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'baseAddress', + loc: { start: 4976, end: 4987 } + }, + field: { + kind: 'id', + text: 'hash', + loc: { start: 4988, end: 4992 } + }, + loc: { start: 4976, end: 4992 } + }, + loc: { start: 4976, end: 4994 } + }, + right: { + kind: 'var', + name: 'senderAddress', + loc: { start: 4998, end: 5011 } + }, + loc: { start: 4976, end: 5011 } + }, + loc: { start: 4969, end: 5012 } + } + ] + }, + loc: { start: 4759, end: 5014 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 4808, end: 4817 } + }, + typeArgs: [], + loc: { start: 4808, end: 4817 } + } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'contractAddress', + loc: { start: 5709, end: 5724 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 5740, end: 5747 } + }, + typeArgs: [], + loc: { start: 5740, end: 5747 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 's', + loc: { start: 5725, end: 5726 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 5728, end: 5737 } + }, + typeArgs: [], + loc: { start: 5728, end: 5737 } + }, + loc: { start: 5725, end: 5737 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractAddressExt', + loc: { start: 5761, end: 5779 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 5780, end: 5781 } + }, + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 5783, end: 5784 } + }, + field: { + kind: 'id', + text: 'code', + loc: { start: 5785, end: 5789 } + }, + loc: { start: 5783, end: 5789 } + }, + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 5791, end: 5792 } + }, + field: { + kind: 'id', + text: 'data', + loc: { start: 5793, end: 5797 } + }, + loc: { start: 5791, end: 5797 } + } + ], + loc: { start: 5761, end: 5798 } + }, + loc: { start: 5754, end: 5799 } + } + ] + }, + loc: { start: 5698, end: 5801 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myAddress', + loc: { start: 6082, end: 6091 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 6095, end: 6102 } + }, + typeArgs: [], + loc: { start: 6095, end: 6102 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MYADDR' ] + }, + loc: { start: 6074, end: 6113 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myBalance', + loc: { start: 6454, end: 6463 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6467, end: 6470 } + }, + loc: { start: 6467, end: 6470 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'BALANCE FIRST' ] + }, + loc: { start: 6446, end: 6488 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'gasConsumed', + loc: { start: 6880, end: 6891 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6895, end: 6898 } + }, + loc: { start: 6895, end: 6898 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GASCONSUMED' ] + }, + loc: { start: 6872, end: 6914 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myStorageDue', + loc: { start: 7329, end: 7341 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7345, end: 7348 } + }, + loc: { start: 7345, end: 7348 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DUEPAYMENT' ] + }, + loc: { start: 7321, end: 7363 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getStorageFee', + loc: { start: 8517, end: 8530 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8590, end: 8593 } + }, + loc: { start: 8590, end: 8593 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 8531, end: 8536 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8538, end: 8541 } + }, + loc: { start: 8538, end: 8541 } + }, + loc: { start: 8531, end: 8541 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 8543, end: 8547 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8549, end: 8552 } + }, + loc: { start: 8549, end: 8552 } + }, + loc: { start: 8543, end: 8552 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'seconds', + loc: { start: 8554, end: 8561 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8563, end: 8566 } + }, + loc: { start: 8563, end: 8566 } + }, + loc: { start: 8554, end: 8566 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 8568, end: 8581 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 8583, end: 8587 } + }, + typeArgs: [], + loc: { start: 8583, end: 8587 } + }, + loc: { start: 8568, end: 8587 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETSTORAGEFEE' ] + }, + loc: { start: 8509, end: 8611 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getComputeFee', + loc: { start: 9734, end: 9747 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9784, end: 9787 } + }, + loc: { start: 9784, end: 9787 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'gasUsed', + loc: { start: 9748, end: 9755 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9757, end: 9760 } + }, + loc: { start: 9757, end: 9760 } + }, + loc: { start: 9748, end: 9760 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 9762, end: 9775 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 9777, end: 9781 } + }, + typeArgs: [], + loc: { start: 9777, end: 9781 } + }, + loc: { start: 9762, end: 9781 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETGASFEE' ] + }, + loc: { start: 9726, end: 9801 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSimpleComputeFee', + loc: { start: 10689, end: 10708 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10745, end: 10748 } + }, + loc: { start: 10745, end: 10748 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'gasUsed', + loc: { start: 10709, end: 10716 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10718, end: 10721 } + }, + loc: { start: 10718, end: 10721 } + }, + loc: { start: 10709, end: 10721 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 10723, end: 10736 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 10738, end: 10742 } + }, + typeArgs: [], + loc: { start: 10738, end: 10742 } + }, + loc: { start: 10723, end: 10742 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETGASFEESIMPLE' ] + }, + loc: { start: 10681, end: 10768 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getForwardFee', + loc: { start: 12543, end: 12556 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12602, end: 12605 } + }, + loc: { start: 12602, end: 12605 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 12557, end: 12562 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12564, end: 12567 } + }, + loc: { start: 12564, end: 12567 } + }, + loc: { start: 12557, end: 12567 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 12569, end: 12573 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12575, end: 12578 } + }, + loc: { start: 12575, end: 12578 } + }, + loc: { start: 12569, end: 12578 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 12580, end: 12593 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 12595, end: 12599 } + }, + typeArgs: [], + loc: { start: 12595, end: 12599 } + }, + loc: { start: 12580, end: 12599 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETFORWARDFEE' ] + }, + loc: { start: 12535, end: 12623 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSimpleForwardFee', + loc: { start: 13528, end: 13547 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13593, end: 13596 } + }, + loc: { start: 13593, end: 13596 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 13548, end: 13553 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13555, end: 13558 } + }, + loc: { start: 13555, end: 13558 } + }, + loc: { start: 13548, end: 13558 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 13560, end: 13564 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13566, end: 13569 } + }, + loc: { start: 13566, end: 13569 } + }, + loc: { start: 13560, end: 13569 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 13571, end: 13584 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 13586, end: 13590 } + }, + typeArgs: [], + loc: { start: 13586, end: 13590 } + }, + loc: { start: 13571, end: 13590 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETFORWARDFEESIMPLE' ] + }, + loc: { start: 13520, end: 13620 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getOriginalFwdFee', + loc: { start: 15782, end: 15799 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15835, end: 15838 } + }, + loc: { start: 15835, end: 15838 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'fwdFee', + loc: { start: 15800, end: 15806 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15808, end: 15811 } + }, + loc: { start: 15808, end: 15811 } + }, + loc: { start: 15800, end: 15811 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 15813, end: 15826 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 15828, end: 15832 } + }, + typeArgs: [], + loc: { start: 15828, end: 15832 } + }, + loc: { start: 15813, end: 15832 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETORIGINALFWDFEE' ] + }, + loc: { start: 15774, end: 15860 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'setGasLimit', + loc: { start: 16541, end: 16552 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'limit', + loc: { start: 16553, end: 16558 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 16560, end: 16563 } + }, + loc: { start: 16560, end: 16563 } + }, + loc: { start: 16553, end: 16563 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SETGASLIMIT' ] + }, + loc: { start: 16533, end: 16580 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSeed', + loc: { start: 17350, end: 17357 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 17361, end: 17364 } + }, + loc: { start: 17361, end: 17364 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RANDSEED' ] + }, + loc: { start: 17342, end: 17377 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'setSeed', + loc: { start: 18258, end: 18265 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'seed', + loc: { start: 18266, end: 18270 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 18272, end: 18275 } + }, + loc: { start: 18272, end: 18275 } + }, + loc: { start: 18266, end: 18275 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SETRAND' ] + }, + loc: { start: 18250, end: 18288 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myCode', + loc: { start: 18585, end: 18591 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 18595, end: 18599 } }, + loc: { start: 18595, end: 18599 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MYCODE' ] + }, + loc: { start: 18577, end: 18610 } + } + ] + }, + 'getStorageFee' => { + kind: 'tact', + path: 'std/internal/contract.tact', + code: '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Computes and returns an `Int` value of the SHA-256 hash of the `code` and `data` of the given contract. To assemble the `code` and `data` cells together for hashing, the standard `Cell` representation is used.\n' + + '///\n' + + '/// This hash is commonly called account ID. Together with the workchain ID it deterministically forms the address of the contract on TON Blockchain.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let initPkg: StateInit = initOf SomeContract();\n' + + '/// let accountId: Int = contractHash(initPkg.code, initPkg.data);\n' + + '/// let basechainAddr: Address = newAddress(0, accountId);\n' + + '/// let basechainAddr2: Address = contractAddressExt(0, initPkg.code, initPkg.data);\n' + + '///\n' + + '/// basechainAddr == basechainAddr2; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contracthash\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#newaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '///\n' + + 'asm fun contractHash(code: Cell, data: Cell): Int {\n' + + ' // According to the https://docs.tact-lang.org/book/cells#cells-representation,\n' + + ' // the layout for the Builder to hash goes as follows:\n' + + ' // 1) refs_descriptor:bits8 | bits_descriptor:bits8 | data:bitsN\n' + + ' //\n' + + ' // refs_descriptor: ref_count + ((exotic? & 1) * 8) + (mask * 32)\n' + + ' // 2 refs (code + data), non-exotic, zero-mask\n' + + ' //\n' + + ' // bits_descriptor: floor(bit_count / 8) + ceil(bit_count, 8)\n' + + ' // floor (5 bits / 8) + ceil(5 bits / 8) = 0 + 1 = 1\n' + + ' //\n' + + ' // data: [0b00110] + [0b100] = [0b00110100] = 0x34 (data + augmented bits)\n' + + ' // 0b00110 - data (split_depth, special, code, data, Library)\n' + + ' // 0b100 - augmented bits (Leading 1 + zeroes to make section multiple of eight)\n' + + ' //\n' + + ' // That is: (2 << 16) | (1 << 8) | 0x34 = 131380 for all three.\n' + + ' //\n' + + ' // 2) and 3) depth_descriptors: CDEPTH of `code` and CDEPTH of `data`\n' + + ' // 4) and 5) ref hashes: HASHCU of `code` and HASHCU of `data`\n' + + '\n' + + ' // Group 1: Computations and arrangements\n' + + ' s0 PUSH HASHCU // `data` hash\n' + + ' s2 PUSH HASHCU // `code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `code` depth\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + '\n' + + ' // Group 2: Composition of the Builder\n' + + ' NEWC\n' + + ' 24 STU // store refs_descriptor | bits_descriptor | data\n' + + ' 16 STU // store depth_descriptor for `code`\n' + + ' 16 STU // store depth_descriptor for `data`\n' + + ' 256 STU // store `code` hash\n' + + ' 256 STU // store `data` hash\n' + + '\n' + + ' // Group 3: SHA256 hash of the resulting Builder\n' + + ' ONE HASHEXT_SHA256\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + "/// Computes smart contract's `Address` in the `chain` ID using the contract's `code` and the contract's initial state `data`. Use the `initOf` expression to obtain the initial `code` and initial `data` of a given contract.\n" + + '///\n' + + '/// This function lets you specify arbitrary `chain` IDs, including the common -1 (masterchain) and 0 (basechain) ones.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let initPkg: StateInit = initOf SomeContract();\n' + + '/// let hereBeDragons: Address = contractAddressExt(0, initPkg.code, initPkg.data);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '/// * https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'inline fun contractAddressExt(chain: Int, code: Cell, data: Cell): Address {\n' + + ' let hash = contractHash(code, data);\n' + + ' return newAddress(chain, hash);\n' + + '}\n' + + '\n' + + '/// Struct containing the initial state, i.e. initial code and initial data of the given contract upon its deployment.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'struct StateInit {\n' + + ' /// Initial code of the contract (compiled bitcode)\n' + + ' code: Cell;\n' + + '\n' + + ' /// Initial data of the contract (parameters of `init()` function or contract parameters)\n' + + ' data: Cell;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.1.\n' + + '///\n' + + '/// Efficiently compares if the given address matches the basechain address of the contract.\n' + + '/// Returns true if addresses are the same, false otherwise.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let init = initOf SomeContract();\n' + + "/// init.hasSameBasechainAddress(sender()); // returns true if sender matches contract's basechain address\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// This function provides a gas-optimized implementation compared to direct address comparison:\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let init = initOf SomeContract();\n' + + '/// sender() == contractAddress(sender()); // less efficient approach\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// Note that this function works only for basechain addresses!\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddress\n' + + '///\n' + + 'inline extends fun hasSameBasechainAddress(self: StateInit, sender: Address): Bool {\n' + + ' let senderAddress = parseStdAddress(sender.asSlice()).address;\n' + + ' let baseAddress = contractBasechainAddress(self);\n' + + ' return baseAddress.hash!! == senderAddress;\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + "/// Computes smart contract's `Address` in the workchain ID 0 (basechain) using the `StateInit` `s` of the contract. Alias to `contractAddressExt(0, s.code, s.data)`.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let s: StateInit = initOf SomeContract();\n' + + '/// let foundMeSome: Address = contractAddress(s);\n' + + '/// let andSomeMore: Address = contractAddressExt(0, s.code, s.data);\n' + + '///\n' + + '/// foundMeSome == andSomeMore; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '/// * https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'inline fun contractAddress(s: StateInit): Address {\n' + + ' return contractAddressExt(0, s.code, s.data);\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Returns the address of the current smart contract as an `Address`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let meMyselfAndI: Address = myAddress();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#myaddress\n' + + '///\n' + + 'asm fun myAddress(): Address { MYADDR }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` balance of the smart contract as it was at the start of the compute phase of the current transaction.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let iNeedADolla: Int = myBalance();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#mybalance\n' + + '///\n' + + 'asm fun myBalance(): Int { BALANCE FIRST }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` amount of gas consumed by TVM in the current transaction so far. The resulting value includes the cost of calling this function.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let gas: Int = gasConsumed();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#gasconsumed\n' + + '///\n' + + 'asm fun gasConsumed(): Int { GASCONSUMED }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` amount of the accumulated storage fee debt. Storage fees are deducted from the incoming message value before the new contract balance is calculated.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let debt: Int = myStorageDue();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#mystoragedue\n' + + '///\n' + + 'asm fun myStorageDue(): Int { DUEPAYMENT }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Calculates and returns the storage fee in nanoToncoins `Int` for storing a contract with a given number of `cells` and `bits` for a number of `seconds`. Uses the prices of the masterchain if `isMasterchain` is `true`, otherwise the prices of the basechain. The current prices are obtained from the config param 18 of TON Blockchain.\n' + + '///\n' + + '/// Note, that specifying values of `cells` and `bits` higher than their maximum values listed in account state limits (`max_acc_state_cells` and `max_acc_state_bits`) will have the same result as with specifying the exact limits. In addition, make sure you take into account the deduplication of cells with the same hash.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fee: Int = getStorageFee(1_000, 1_000, 1_000, false);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify negative number of `cells`, `bits` or `seconds`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-gas#getstoragefee\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun getStorageFee(cells: Int, bits: Int, seconds: Int, isMasterchain: Bool): Int { GETSTORAGEFEE }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Calculates and returns the compute fee in nanoToncoins `Int` for a transaction that consumed `gasUsed` amount of gas. Uses the prices of the masterchain if `isMasterchain` is `true`, otherwise the prices of the basechain. The current prices are obtained from the config param 20 for the masterchain and config param 21 for the basechain of TON Blockchain.\n' + + '///\n' + + "/// When the `gasUsed` is less than a certain threshold called `flat_gas_limit`, there's a minimum price to pay based on the value of `flat_gas_price`. The less gas is used below this threshold, the higher the minimum price will be. See the example for `getSimpleComputeFee()` to derive that threshold.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fee: Int = getComputeFee(1_000, false);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify negative value of `gasUsed`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-gas#getcomputefee\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun getComputeFee(gasUsed: Int, isMasterchain: Bool): Int { GETGASFEE }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Similar to `getComputeFee()`, but without the `flat_gas_price`, i.e. without a minimum price to pay if the `gasUsed` is less than a certain '... 8611 more characters, + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'contractHash', + loc: { start: 1027, end: 1039 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1065, end: 1068 } + }, + loc: { start: 1065, end: 1068 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 1040, end: 1044 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 1046, end: 1050 } }, + loc: { start: 1046, end: 1050 } + }, + loc: { start: 1040, end: 1050 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'data', + loc: { start: 1052, end: 1056 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 1058, end: 1062 } }, + loc: { start: 1058, end: 1062 } + }, + loc: { start: 1052, end: 1062 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 's0 PUSH HASHCU // `data` hash\n' + + ' s2 PUSH HASHCU // `code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `code` depth\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + '\n' + + ' // Group 2: Composition of the Builder\n' + + ' NEWC\n' + + ' 24 STU // store refs_descriptor | bits_descriptor | data\n' + + ' 16 STU // store depth_descriptor for `code`\n' + + ' 16 STU // store depth_descriptor for `data`\n' + + ' 256 STU // store `code` hash\n' + + ' 256 STU // store `data` hash\n' + + '\n' + + ' // Group 3: SHA256 hash of the resulting Builder\n' + + ' ONE HASHEXT_SHA256' + ] + }, + loc: { start: 1019, end: 2666 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'contractAddressExt', + loc: { start: 3391, end: 3409 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3447, end: 3454 } + }, + typeArgs: [], + loc: { start: 3447, end: 3454 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'chain', + loc: { start: 3410, end: 3415 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3417, end: 3420 } + }, + loc: { start: 3417, end: 3420 } + }, + loc: { start: 3410, end: 3420 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 3422, end: 3426 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3428, end: 3432 } }, + loc: { start: 3428, end: 3432 } + }, + loc: { start: 3422, end: 3432 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'data', + loc: { start: 3434, end: 3438 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3440, end: 3444 } }, + loc: { start: 3440, end: 3444 } + }, + loc: { start: 3434, end: 3444 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'hash', + loc: { start: 3465, end: 3469 } + }, + type: undefined, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractHash', + loc: { start: 3472, end: 3484 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'code', + loc: { start: 3485, end: 3489 } + }, + { + kind: 'var', + name: 'data', + loc: { start: 3491, end: 3495 } + } + ], + loc: { start: 3472, end: 3496 } + }, + loc: { start: 3461, end: 3497 } + }, + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'newAddress', + loc: { start: 3509, end: 3519 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'chain', + loc: { start: 3520, end: 3525 } + }, + { + kind: 'var', + name: 'hash', + loc: { start: 3527, end: 3531 } + } + ], + loc: { start: 3509, end: 3532 } + }, + loc: { start: 3502, end: 3533 } + } + ] + }, + loc: { start: 3380, end: 3535 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 3731, end: 3740 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'code', + loc: { start: 3803, end: 3807 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3809, end: 3813 } }, + loc: { start: 3809, end: 3813 } + }, + initializer: undefined, + loc: { start: 3803, end: 3813 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'data', + loc: { start: 3914, end: 3918 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3920, end: 3924 } }, + loc: { start: 3920, end: 3924 } + }, + initializer: undefined, + loc: { start: 3914, end: 3924 } + } + ], + loc: { start: 3724, end: 3927 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'hasSameBasechainAddress', + loc: { start: 4778, end: 4801 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 4837, end: 4841 } + }, + typeArgs: [], + loc: { start: 4837, end: 4841 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'sender', + loc: { start: 4819, end: 4825 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 4827, end: 4834 } + }, + typeArgs: [], + loc: { start: 4827, end: 4834 } + }, + loc: { start: 4819, end: 4834 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'senderAddress', + loc: { start: 4852, end: 4865 } + }, + type: undefined, + expression: { + kind: 'field_access', + aggregate: { + kind: 'static_call', + function: { + kind: 'id', + text: 'parseStdAddress', + loc: { start: 4868, end: 4883 } + }, + typeArgs: [], + args: [ + { + kind: 'method_call', + self: { + kind: 'var', + name: 'sender', + loc: { start: 4884, end: 4890 } + }, + method: { + kind: 'id', + text: 'asSlice', + loc: { start: 4891, end: 4898 } + }, + typeArgs: [], + args: [], + loc: { start: 4884, end: 4900 } + } + ], + loc: { start: 4868, end: 4901 } + }, + field: { + kind: 'id', + text: 'address', + loc: { start: 4902, end: 4909 } + }, + loc: { start: 4868, end: 4909 } + }, + loc: { start: 4848, end: 4910 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'baseAddress', + loc: { start: 4919, end: 4930 } + }, + type: undefined, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractBasechainAddress', + loc: { start: 4933, end: 4957 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'self', + loc: { start: 4958, end: 4962 } + } + ], + loc: { start: 4933, end: 4963 } + }, + loc: { start: 4915, end: 4964 } + }, + { + kind: 'statement_return', + expression: { + kind: 'op_binary', + op: '==', + left: { + kind: 'op_unary', + op: '!!', + operand: { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'baseAddress', + loc: { start: 4976, end: 4987 } + }, + field: { + kind: 'id', + text: 'hash', + loc: { start: 4988, end: 4992 } + }, + loc: { start: 4976, end: 4992 } + }, + loc: { start: 4976, end: 4994 } + }, + right: { + kind: 'var', + name: 'senderAddress', + loc: { start: 4998, end: 5011 } + }, + loc: { start: 4976, end: 5011 } + }, + loc: { start: 4969, end: 5012 } + } + ] + }, + loc: { start: 4759, end: 5014 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 4808, end: 4817 } + }, + typeArgs: [], + loc: { start: 4808, end: 4817 } + } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'contractAddress', + loc: { start: 5709, end: 5724 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 5740, end: 5747 } + }, + typeArgs: [], + loc: { start: 5740, end: 5747 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 's', + loc: { start: 5725, end: 5726 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 5728, end: 5737 } + }, + typeArgs: [], + loc: { start: 5728, end: 5737 } + }, + loc: { start: 5725, end: 5737 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractAddressExt', + loc: { start: 5761, end: 5779 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 5780, end: 5781 } + }, + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 5783, end: 5784 } + }, + field: { + kind: 'id', + text: 'code', + loc: { start: 5785, end: 5789 } + }, + loc: { start: 5783, end: 5789 } + }, + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 5791, end: 5792 } + }, + field: { + kind: 'id', + text: 'data', + loc: { start: 5793, end: 5797 } + }, + loc: { start: 5791, end: 5797 } + } + ], + loc: { start: 5761, end: 5798 } + }, + loc: { start: 5754, end: 5799 } + } + ] + }, + loc: { start: 5698, end: 5801 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myAddress', + loc: { start: 6082, end: 6091 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 6095, end: 6102 } + }, + typeArgs: [], + loc: { start: 6095, end: 6102 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MYADDR' ] + }, + loc: { start: 6074, end: 6113 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myBalance', + loc: { start: 6454, end: 6463 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6467, end: 6470 } + }, + loc: { start: 6467, end: 6470 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'BALANCE FIRST' ] + }, + loc: { start: 6446, end: 6488 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'gasConsumed', + loc: { start: 6880, end: 6891 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6895, end: 6898 } + }, + loc: { start: 6895, end: 6898 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GASCONSUMED' ] + }, + loc: { start: 6872, end: 6914 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myStorageDue', + loc: { start: 7329, end: 7341 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7345, end: 7348 } + }, + loc: { start: 7345, end: 7348 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DUEPAYMENT' ] + }, + loc: { start: 7321, end: 7363 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getStorageFee', + loc: { start: 8517, end: 8530 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8590, end: 8593 } + }, + loc: { start: 8590, end: 8593 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 8531, end: 8536 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8538, end: 8541 } + }, + loc: { start: 8538, end: 8541 } + }, + loc: { start: 8531, end: 8541 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 8543, end: 8547 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8549, end: 8552 } + }, + loc: { start: 8549, end: 8552 } + }, + loc: { start: 8543, end: 8552 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'seconds', + loc: { start: 8554, end: 8561 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8563, end: 8566 } + }, + loc: { start: 8563, end: 8566 } + }, + loc: { start: 8554, end: 8566 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 8568, end: 8581 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 8583, end: 8587 } + }, + typeArgs: [], + loc: { start: 8583, end: 8587 } + }, + loc: { start: 8568, end: 8587 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETSTORAGEFEE' ] + }, + loc: { start: 8509, end: 8611 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getComputeFee', + loc: { start: 9734, end: 9747 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9784, end: 9787 } + }, + loc: { start: 9784, end: 9787 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'gasUsed', + loc: { start: 9748, end: 9755 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9757, end: 9760 } + }, + loc: { start: 9757, end: 9760 } + }, + loc: { start: 9748, end: 9760 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 9762, end: 9775 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 9777, end: 9781 } + }, + typeArgs: [], + loc: { start: 9777, end: 9781 } + }, + loc: { start: 9762, end: 9781 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETGASFEE' ] + }, + loc: { start: 9726, end: 9801 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSimpleComputeFee', + loc: { start: 10689, end: 10708 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10745, end: 10748 } + }, + loc: { start: 10745, end: 10748 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'gasUsed', + loc: { start: 10709, end: 10716 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10718, end: 10721 } + }, + loc: { start: 10718, end: 10721 } + }, + loc: { start: 10709, end: 10721 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 10723, end: 10736 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 10738, end: 10742 } + }, + typeArgs: [], + loc: { start: 10738, end: 10742 } + }, + loc: { start: 10723, end: 10742 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETGASFEESIMPLE' ] + }, + loc: { start: 10681, end: 10768 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getForwardFee', + loc: { start: 12543, end: 12556 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12602, end: 12605 } + }, + loc: { start: 12602, end: 12605 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 12557, end: 12562 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12564, end: 12567 } + }, + loc: { start: 12564, end: 12567 } + }, + loc: { start: 12557, end: 12567 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 12569, end: 12573 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12575, end: 12578 } + }, + loc: { start: 12575, end: 12578 } + }, + loc: { start: 12569, end: 12578 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 12580, end: 12593 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 12595, end: 12599 } + }, + typeArgs: [], + loc: { start: 12595, end: 12599 } + }, + loc: { start: 12580, end: 12599 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETFORWARDFEE' ] + }, + loc: { start: 12535, end: 12623 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSimpleForwardFee', + loc: { start: 13528, end: 13547 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13593, end: 13596 } + }, + loc: { start: 13593, end: 13596 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 13548, end: 13553 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13555, end: 13558 } + }, + loc: { start: 13555, end: 13558 } + }, + loc: { start: 13548, end: 13558 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 13560, end: 13564 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13566, end: 13569 } + }, + loc: { start: 13566, end: 13569 } + }, + loc: { start: 13560, end: 13569 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 13571, end: 13584 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 13586, end: 13590 } + }, + typeArgs: [], + loc: { start: 13586, end: 13590 } + }, + loc: { start: 13571, end: 13590 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETFORWARDFEESIMPLE' ] + }, + loc: { start: 13520, end: 13620 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getOriginalFwdFee', + loc: { start: 15782, end: 15799 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15835, end: 15838 } + }, + loc: { start: 15835, end: 15838 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'fwdFee', + loc: { start: 15800, end: 15806 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15808, end: 15811 } + }, + loc: { start: 15808, end: 15811 } + }, + loc: { start: 15800, end: 15811 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 15813, end: 15826 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 15828, end: 15832 } + }, + typeArgs: [], + loc: { start: 15828, end: 15832 } + }, + loc: { start: 15813, end: 15832 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETORIGINALFWDFEE' ] + }, + loc: { start: 15774, end: 15860 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'setGasLimit', + loc: { start: 16541, end: 16552 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'limit', + loc: { start: 16553, end: 16558 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 16560, end: 16563 } + }, + loc: { start: 16560, end: 16563 } + }, + loc: { start: 16553, end: 16563 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SETGASLIMIT' ] + }, + loc: { start: 16533, end: 16580 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSeed', + loc: { start: 17350, end: 17357 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 17361, end: 17364 } + }, + loc: { start: 17361, end: 17364 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RANDSEED' ] + }, + loc: { start: 17342, end: 17377 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'setSeed', + loc: { start: 18258, end: 18265 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'seed', + loc: { start: 18266, end: 18270 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 18272, end: 18275 } + }, + loc: { start: 18272, end: 18275 } + }, + loc: { start: 18266, end: 18275 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SETRAND' ] + }, + loc: { start: 18250, end: 18288 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myCode', + loc: { start: 18585, end: 18591 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 18595, end: 18599 } }, + loc: { start: 18595, end: 18599 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MYCODE' ] + }, + loc: { start: 18577, end: 18610 } + } + ] + }, + 'getComputeFee' => { + kind: 'tact', + path: 'std/internal/contract.tact', + code: '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Computes and returns an `Int` value of the SHA-256 hash of the `code` and `data` of the given contract. To assemble the `code` and `data` cells together for hashing, the standard `Cell` representation is used.\n' + + '///\n' + + '/// This hash is commonly called account ID. Together with the workchain ID it deterministically forms the address of the contract on TON Blockchain.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let initPkg: StateInit = initOf SomeContract();\n' + + '/// let accountId: Int = contractHash(initPkg.code, initPkg.data);\n' + + '/// let basechainAddr: Address = newAddress(0, accountId);\n' + + '/// let basechainAddr2: Address = contractAddressExt(0, initPkg.code, initPkg.data);\n' + + '///\n' + + '/// basechainAddr == basechainAddr2; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contracthash\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#newaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '///\n' + + 'asm fun contractHash(code: Cell, data: Cell): Int {\n' + + ' // According to the https://docs.tact-lang.org/book/cells#cells-representation,\n' + + ' // the layout for the Builder to hash goes as follows:\n' + + ' // 1) refs_descriptor:bits8 | bits_descriptor:bits8 | data:bitsN\n' + + ' //\n' + + ' // refs_descriptor: ref_count + ((exotic? & 1) * 8) + (mask * 32)\n' + + ' // 2 refs (code + data), non-exotic, zero-mask\n' + + ' //\n' + + ' // bits_descriptor: floor(bit_count / 8) + ceil(bit_count, 8)\n' + + ' // floor (5 bits / 8) + ceil(5 bits / 8) = 0 + 1 = 1\n' + + ' //\n' + + ' // data: [0b00110] + [0b100] = [0b00110100] = 0x34 (data + augmented bits)\n' + + ' // 0b00110 - data (split_depth, special, code, data, Library)\n' + + ' // 0b100 - augmented bits (Leading 1 + zeroes to make section multiple of eight)\n' + + ' //\n' + + ' // That is: (2 << 16) | (1 << 8) | 0x34 = 131380 for all three.\n' + + ' //\n' + + ' // 2) and 3) depth_descriptors: CDEPTH of `code` and CDEPTH of `data`\n' + + ' // 4) and 5) ref hashes: HASHCU of `code` and HASHCU of `data`\n' + + '\n' + + ' // Group 1: Computations and arrangements\n' + + ' s0 PUSH HASHCU // `data` hash\n' + + ' s2 PUSH HASHCU // `code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `code` depth\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + '\n' + + ' // Group 2: Composition of the Builder\n' + + ' NEWC\n' + + ' 24 STU // store refs_descriptor | bits_descriptor | data\n' + + ' 16 STU // store depth_descriptor for `code`\n' + + ' 16 STU // store depth_descriptor for `data`\n' + + ' 256 STU // store `code` hash\n' + + ' 256 STU // store `data` hash\n' + + '\n' + + ' // Group 3: SHA256 hash of the resulting Builder\n' + + ' ONE HASHEXT_SHA256\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + "/// Computes smart contract's `Address` in the `chain` ID using the contract's `code` and the contract's initial state `data`. Use the `initOf` expression to obtain the initial `code` and initial `data` of a given contract.\n" + + '///\n' + + '/// This function lets you specify arbitrary `chain` IDs, including the common -1 (masterchain) and 0 (basechain) ones.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let initPkg: StateInit = initOf SomeContract();\n' + + '/// let hereBeDragons: Address = contractAddressExt(0, initPkg.code, initPkg.data);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '/// * https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'inline fun contractAddressExt(chain: Int, code: Cell, data: Cell): Address {\n' + + ' let hash = contractHash(code, data);\n' + + ' return newAddress(chain, hash);\n' + + '}\n' + + '\n' + + '/// Struct containing the initial state, i.e. initial code and initial data of the given contract upon its deployment.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'struct StateInit {\n' + + ' /// Initial code of the contract (compiled bitcode)\n' + + ' code: Cell;\n' + + '\n' + + ' /// Initial data of the contract (parameters of `init()` function or contract parameters)\n' + + ' data: Cell;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.1.\n' + + '///\n' + + '/// Efficiently compares if the given address matches the basechain address of the contract.\n' + + '/// Returns true if addresses are the same, false otherwise.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let init = initOf SomeContract();\n' + + "/// init.hasSameBasechainAddress(sender()); // returns true if sender matches contract's basechain address\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// This function provides a gas-optimized implementation compared to direct address comparison:\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let init = initOf SomeContract();\n' + + '/// sender() == contractAddress(sender()); // less efficient approach\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// Note that this function works only for basechain addresses!\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddress\n' + + '///\n' + + 'inline extends fun hasSameBasechainAddress(self: StateInit, sender: Address): Bool {\n' + + ' let senderAddress = parseStdAddress(sender.asSlice()).address;\n' + + ' let baseAddress = contractBasechainAddress(self);\n' + + ' return baseAddress.hash!! == senderAddress;\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + "/// Computes smart contract's `Address` in the workchain ID 0 (basechain) using the `StateInit` `s` of the contract. Alias to `contractAddressExt(0, s.code, s.data)`.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let s: StateInit = initOf SomeContract();\n' + + '/// let foundMeSome: Address = contractAddress(s);\n' + + '/// let andSomeMore: Address = contractAddressExt(0, s.code, s.data);\n' + + '///\n' + + '/// foundMeSome == andSomeMore; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '/// * https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'inline fun contractAddress(s: StateInit): Address {\n' + + ' return contractAddressExt(0, s.code, s.data);\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Returns the address of the current smart contract as an `Address`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let meMyselfAndI: Address = myAddress();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#myaddress\n' + + '///\n' + + 'asm fun myAddress(): Address { MYADDR }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` balance of the smart contract as it was at the start of the compute phase of the current transaction.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let iNeedADolla: Int = myBalance();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#mybalance\n' + + '///\n' + + 'asm fun myBalance(): Int { BALANCE FIRST }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` amount of gas consumed by TVM in the current transaction so far. The resulting value includes the cost of calling this function.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let gas: Int = gasConsumed();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#gasconsumed\n' + + '///\n' + + 'asm fun gasConsumed(): Int { GASCONSUMED }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` amount of the accumulated storage fee debt. Storage fees are deducted from the incoming message value before the new contract balance is calculated.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let debt: Int = myStorageDue();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#mystoragedue\n' + + '///\n' + + 'asm fun myStorageDue(): Int { DUEPAYMENT }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Calculates and returns the storage fee in nanoToncoins `Int` for storing a contract with a given number of `cells` and `bits` for a number of `seconds`. Uses the prices of the masterchain if `isMasterchain` is `true`, otherwise the prices of the basechain. The current prices are obtained from the config param 18 of TON Blockchain.\n' + + '///\n' + + '/// Note, that specifying values of `cells` and `bits` higher than their maximum values listed in account state limits (`max_acc_state_cells` and `max_acc_state_bits`) will have the same result as with specifying the exact limits. In addition, make sure you take into account the deduplication of cells with the same hash.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fee: Int = getStorageFee(1_000, 1_000, 1_000, false);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify negative number of `cells`, `bits` or `seconds`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-gas#getstoragefee\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun getStorageFee(cells: Int, bits: Int, seconds: Int, isMasterchain: Bool): Int { GETSTORAGEFEE }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Calculates and returns the compute fee in nanoToncoins `Int` for a transaction that consumed `gasUsed` amount of gas. Uses the prices of the masterchain if `isMasterchain` is `true`, otherwise the prices of the basechain. The current prices are obtained from the config param 20 for the masterchain and config param 21 for the basechain of TON Blockchain.\n' + + '///\n' + + "/// When the `gasUsed` is less than a certain threshold called `flat_gas_limit`, there's a minimum price to pay based on the value of `flat_gas_price`. The less gas is used below this threshold, the higher the minimum price will be. See the example for `getSimpleComputeFee()` to derive that threshold.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fee: Int = getComputeFee(1_000, false);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify negative value of `gasUsed`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-gas#getcomputefee\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun getComputeFee(gasUsed: Int, isMasterchain: Bool): Int { GETGASFEE }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Similar to `getComputeFee()`, but without the `flat_gas_price`, i.e. without a minimum price to pay if the `gasUsed` is less than a certain '... 8611 more characters, + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'contractHash', + loc: { start: 1027, end: 1039 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1065, end: 1068 } + }, + loc: { start: 1065, end: 1068 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 1040, end: 1044 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 1046, end: 1050 } }, + loc: { start: 1046, end: 1050 } + }, + loc: { start: 1040, end: 1050 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'data', + loc: { start: 1052, end: 1056 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 1058, end: 1062 } }, + loc: { start: 1058, end: 1062 } + }, + loc: { start: 1052, end: 1062 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 's0 PUSH HASHCU // `data` hash\n' + + ' s2 PUSH HASHCU // `code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `code` depth\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + '\n' + + ' // Group 2: Composition of the Builder\n' + + ' NEWC\n' + + ' 24 STU // store refs_descriptor | bits_descriptor | data\n' + + ' 16 STU // store depth_descriptor for `code`\n' + + ' 16 STU // store depth_descriptor for `data`\n' + + ' 256 STU // store `code` hash\n' + + ' 256 STU // store `data` hash\n' + + '\n' + + ' // Group 3: SHA256 hash of the resulting Builder\n' + + ' ONE HASHEXT_SHA256' + ] + }, + loc: { start: 1019, end: 2666 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'contractAddressExt', + loc: { start: 3391, end: 3409 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3447, end: 3454 } + }, + typeArgs: [], + loc: { start: 3447, end: 3454 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'chain', + loc: { start: 3410, end: 3415 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3417, end: 3420 } + }, + loc: { start: 3417, end: 3420 } + }, + loc: { start: 3410, end: 3420 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 3422, end: 3426 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3428, end: 3432 } }, + loc: { start: 3428, end: 3432 } + }, + loc: { start: 3422, end: 3432 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'data', + loc: { start: 3434, end: 3438 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3440, end: 3444 } }, + loc: { start: 3440, end: 3444 } + }, + loc: { start: 3434, end: 3444 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'hash', + loc: { start: 3465, end: 3469 } + }, + type: undefined, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractHash', + loc: { start: 3472, end: 3484 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'code', + loc: { start: 3485, end: 3489 } + }, + { + kind: 'var', + name: 'data', + loc: { start: 3491, end: 3495 } + } + ], + loc: { start: 3472, end: 3496 } + }, + loc: { start: 3461, end: 3497 } + }, + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'newAddress', + loc: { start: 3509, end: 3519 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'chain', + loc: { start: 3520, end: 3525 } + }, + { + kind: 'var', + name: 'hash', + loc: { start: 3527, end: 3531 } + } + ], + loc: { start: 3509, end: 3532 } + }, + loc: { start: 3502, end: 3533 } + } + ] + }, + loc: { start: 3380, end: 3535 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 3731, end: 3740 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'code', + loc: { start: 3803, end: 3807 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3809, end: 3813 } }, + loc: { start: 3809, end: 3813 } + }, + initializer: undefined, + loc: { start: 3803, end: 3813 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'data', + loc: { start: 3914, end: 3918 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3920, end: 3924 } }, + loc: { start: 3920, end: 3924 } + }, + initializer: undefined, + loc: { start: 3914, end: 3924 } + } + ], + loc: { start: 3724, end: 3927 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'hasSameBasechainAddress', + loc: { start: 4778, end: 4801 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 4837, end: 4841 } + }, + typeArgs: [], + loc: { start: 4837, end: 4841 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'sender', + loc: { start: 4819, end: 4825 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 4827, end: 4834 } + }, + typeArgs: [], + loc: { start: 4827, end: 4834 } + }, + loc: { start: 4819, end: 4834 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'senderAddress', + loc: { start: 4852, end: 4865 } + }, + type: undefined, + expression: { + kind: 'field_access', + aggregate: { + kind: 'static_call', + function: { + kind: 'id', + text: 'parseStdAddress', + loc: { start: 4868, end: 4883 } + }, + typeArgs: [], + args: [ + { + kind: 'method_call', + self: { + kind: 'var', + name: 'sender', + loc: { start: 4884, end: 4890 } + }, + method: { + kind: 'id', + text: 'asSlice', + loc: { start: 4891, end: 4898 } + }, + typeArgs: [], + args: [], + loc: { start: 4884, end: 4900 } + } + ], + loc: { start: 4868, end: 4901 } + }, + field: { + kind: 'id', + text: 'address', + loc: { start: 4902, end: 4909 } + }, + loc: { start: 4868, end: 4909 } + }, + loc: { start: 4848, end: 4910 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'baseAddress', + loc: { start: 4919, end: 4930 } + }, + type: undefined, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractBasechainAddress', + loc: { start: 4933, end: 4957 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'self', + loc: { start: 4958, end: 4962 } + } + ], + loc: { start: 4933, end: 4963 } + }, + loc: { start: 4915, end: 4964 } + }, + { + kind: 'statement_return', + expression: { + kind: 'op_binary', + op: '==', + left: { + kind: 'op_unary', + op: '!!', + operand: { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'baseAddress', + loc: { start: 4976, end: 4987 } + }, + field: { + kind: 'id', + text: 'hash', + loc: { start: 4988, end: 4992 } + }, + loc: { start: 4976, end: 4992 } + }, + loc: { start: 4976, end: 4994 } + }, + right: { + kind: 'var', + name: 'senderAddress', + loc: { start: 4998, end: 5011 } + }, + loc: { start: 4976, end: 5011 } + }, + loc: { start: 4969, end: 5012 } + } + ] + }, + loc: { start: 4759, end: 5014 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 4808, end: 4817 } + }, + typeArgs: [], + loc: { start: 4808, end: 4817 } + } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'contractAddress', + loc: { start: 5709, end: 5724 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 5740, end: 5747 } + }, + typeArgs: [], + loc: { start: 5740, end: 5747 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 's', + loc: { start: 5725, end: 5726 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 5728, end: 5737 } + }, + typeArgs: [], + loc: { start: 5728, end: 5737 } + }, + loc: { start: 5725, end: 5737 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractAddressExt', + loc: { start: 5761, end: 5779 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 5780, end: 5781 } + }, + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 5783, end: 5784 } + }, + field: { + kind: 'id', + text: 'code', + loc: { start: 5785, end: 5789 } + }, + loc: { start: 5783, end: 5789 } + }, + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 5791, end: 5792 } + }, + field: { + kind: 'id', + text: 'data', + loc: { start: 5793, end: 5797 } + }, + loc: { start: 5791, end: 5797 } + } + ], + loc: { start: 5761, end: 5798 } + }, + loc: { start: 5754, end: 5799 } + } + ] + }, + loc: { start: 5698, end: 5801 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myAddress', + loc: { start: 6082, end: 6091 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 6095, end: 6102 } + }, + typeArgs: [], + loc: { start: 6095, end: 6102 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MYADDR' ] + }, + loc: { start: 6074, end: 6113 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myBalance', + loc: { start: 6454, end: 6463 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6467, end: 6470 } + }, + loc: { start: 6467, end: 6470 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'BALANCE FIRST' ] + }, + loc: { start: 6446, end: 6488 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'gasConsumed', + loc: { start: 6880, end: 6891 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6895, end: 6898 } + }, + loc: { start: 6895, end: 6898 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GASCONSUMED' ] + }, + loc: { start: 6872, end: 6914 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myStorageDue', + loc: { start: 7329, end: 7341 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7345, end: 7348 } + }, + loc: { start: 7345, end: 7348 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DUEPAYMENT' ] + }, + loc: { start: 7321, end: 7363 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getStorageFee', + loc: { start: 8517, end: 8530 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8590, end: 8593 } + }, + loc: { start: 8590, end: 8593 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 8531, end: 8536 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8538, end: 8541 } + }, + loc: { start: 8538, end: 8541 } + }, + loc: { start: 8531, end: 8541 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 8543, end: 8547 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8549, end: 8552 } + }, + loc: { start: 8549, end: 8552 } + }, + loc: { start: 8543, end: 8552 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'seconds', + loc: { start: 8554, end: 8561 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8563, end: 8566 } + }, + loc: { start: 8563, end: 8566 } + }, + loc: { start: 8554, end: 8566 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 8568, end: 8581 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 8583, end: 8587 } + }, + typeArgs: [], + loc: { start: 8583, end: 8587 } + }, + loc: { start: 8568, end: 8587 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETSTORAGEFEE' ] + }, + loc: { start: 8509, end: 8611 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getComputeFee', + loc: { start: 9734, end: 9747 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9784, end: 9787 } + }, + loc: { start: 9784, end: 9787 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'gasUsed', + loc: { start: 9748, end: 9755 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9757, end: 9760 } + }, + loc: { start: 9757, end: 9760 } + }, + loc: { start: 9748, end: 9760 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 9762, end: 9775 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 9777, end: 9781 } + }, + typeArgs: [], + loc: { start: 9777, end: 9781 } + }, + loc: { start: 9762, end: 9781 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETGASFEE' ] + }, + loc: { start: 9726, end: 9801 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSimpleComputeFee', + loc: { start: 10689, end: 10708 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10745, end: 10748 } + }, + loc: { start: 10745, end: 10748 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'gasUsed', + loc: { start: 10709, end: 10716 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10718, end: 10721 } + }, + loc: { start: 10718, end: 10721 } + }, + loc: { start: 10709, end: 10721 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 10723, end: 10736 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 10738, end: 10742 } + }, + typeArgs: [], + loc: { start: 10738, end: 10742 } + }, + loc: { start: 10723, end: 10742 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETGASFEESIMPLE' ] + }, + loc: { start: 10681, end: 10768 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getForwardFee', + loc: { start: 12543, end: 12556 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12602, end: 12605 } + }, + loc: { start: 12602, end: 12605 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 12557, end: 12562 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12564, end: 12567 } + }, + loc: { start: 12564, end: 12567 } + }, + loc: { start: 12557, end: 12567 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 12569, end: 12573 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12575, end: 12578 } + }, + loc: { start: 12575, end: 12578 } + }, + loc: { start: 12569, end: 12578 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 12580, end: 12593 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 12595, end: 12599 } + }, + typeArgs: [], + loc: { start: 12595, end: 12599 } + }, + loc: { start: 12580, end: 12599 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETFORWARDFEE' ] + }, + loc: { start: 12535, end: 12623 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSimpleForwardFee', + loc: { start: 13528, end: 13547 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13593, end: 13596 } + }, + loc: { start: 13593, end: 13596 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 13548, end: 13553 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13555, end: 13558 } + }, + loc: { start: 13555, end: 13558 } + }, + loc: { start: 13548, end: 13558 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 13560, end: 13564 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13566, end: 13569 } + }, + loc: { start: 13566, end: 13569 } + }, + loc: { start: 13560, end: 13569 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 13571, end: 13584 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 13586, end: 13590 } + }, + typeArgs: [], + loc: { start: 13586, end: 13590 } + }, + loc: { start: 13571, end: 13590 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETFORWARDFEESIMPLE' ] + }, + loc: { start: 13520, end: 13620 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getOriginalFwdFee', + loc: { start: 15782, end: 15799 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15835, end: 15838 } + }, + loc: { start: 15835, end: 15838 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'fwdFee', + loc: { start: 15800, end: 15806 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15808, end: 15811 } + }, + loc: { start: 15808, end: 15811 } + }, + loc: { start: 15800, end: 15811 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 15813, end: 15826 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 15828, end: 15832 } + }, + typeArgs: [], + loc: { start: 15828, end: 15832 } + }, + loc: { start: 15813, end: 15832 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETORIGINALFWDFEE' ] + }, + loc: { start: 15774, end: 15860 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'setGasLimit', + loc: { start: 16541, end: 16552 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'limit', + loc: { start: 16553, end: 16558 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 16560, end: 16563 } + }, + loc: { start: 16560, end: 16563 } + }, + loc: { start: 16553, end: 16563 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SETGASLIMIT' ] + }, + loc: { start: 16533, end: 16580 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSeed', + loc: { start: 17350, end: 17357 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 17361, end: 17364 } + }, + loc: { start: 17361, end: 17364 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RANDSEED' ] + }, + loc: { start: 17342, end: 17377 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'setSeed', + loc: { start: 18258, end: 18265 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'seed', + loc: { start: 18266, end: 18270 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 18272, end: 18275 } + }, + loc: { start: 18272, end: 18275 } + }, + loc: { start: 18266, end: 18275 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SETRAND' ] + }, + loc: { start: 18250, end: 18288 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myCode', + loc: { start: 18585, end: 18591 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 18595, end: 18599 } }, + loc: { start: 18595, end: 18599 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MYCODE' ] + }, + loc: { start: 18577, end: 18610 } + } + ] + }, + 'getSimpleComputeFee' => { + kind: 'tact', + path: 'std/internal/contract.tact', + code: '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Computes and returns an `Int` value of the SHA-256 hash of the `code` and `data` of the given contract. To assemble the `code` and `data` cells together for hashing, the standard `Cell` representation is used.\n' + + '///\n' + + '/// This hash is commonly called account ID. Together with the workchain ID it deterministically forms the address of the contract on TON Blockchain.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let initPkg: StateInit = initOf SomeContract();\n' + + '/// let accountId: Int = contractHash(initPkg.code, initPkg.data);\n' + + '/// let basechainAddr: Address = newAddress(0, accountId);\n' + + '/// let basechainAddr2: Address = contractAddressExt(0, initPkg.code, initPkg.data);\n' + + '///\n' + + '/// basechainAddr == basechainAddr2; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contracthash\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#newaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '///\n' + + 'asm fun contractHash(code: Cell, data: Cell): Int {\n' + + ' // According to the https://docs.tact-lang.org/book/cells#cells-representation,\n' + + ' // the layout for the Builder to hash goes as follows:\n' + + ' // 1) refs_descriptor:bits8 | bits_descriptor:bits8 | data:bitsN\n' + + ' //\n' + + ' // refs_descriptor: ref_count + ((exotic? & 1) * 8) + (mask * 32)\n' + + ' // 2 refs (code + data), non-exotic, zero-mask\n' + + ' //\n' + + ' // bits_descriptor: floor(bit_count / 8) + ceil(bit_count, 8)\n' + + ' // floor (5 bits / 8) + ceil(5 bits / 8) = 0 + 1 = 1\n' + + ' //\n' + + ' // data: [0b00110] + [0b100] = [0b00110100] = 0x34 (data + augmented bits)\n' + + ' // 0b00110 - data (split_depth, special, code, data, Library)\n' + + ' // 0b100 - augmented bits (Leading 1 + zeroes to make section multiple of eight)\n' + + ' //\n' + + ' // That is: (2 << 16) | (1 << 8) | 0x34 = 131380 for all three.\n' + + ' //\n' + + ' // 2) and 3) depth_descriptors: CDEPTH of `code` and CDEPTH of `data`\n' + + ' // 4) and 5) ref hashes: HASHCU of `code` and HASHCU of `data`\n' + + '\n' + + ' // Group 1: Computations and arrangements\n' + + ' s0 PUSH HASHCU // `data` hash\n' + + ' s2 PUSH HASHCU // `code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `code` depth\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + '\n' + + ' // Group 2: Composition of the Builder\n' + + ' NEWC\n' + + ' 24 STU // store refs_descriptor | bits_descriptor | data\n' + + ' 16 STU // store depth_descriptor for `code`\n' + + ' 16 STU // store depth_descriptor for `data`\n' + + ' 256 STU // store `code` hash\n' + + ' 256 STU // store `data` hash\n' + + '\n' + + ' // Group 3: SHA256 hash of the resulting Builder\n' + + ' ONE HASHEXT_SHA256\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + "/// Computes smart contract's `Address` in the `chain` ID using the contract's `code` and the contract's initial state `data`. Use the `initOf` expression to obtain the initial `code` and initial `data` of a given contract.\n" + + '///\n' + + '/// This function lets you specify arbitrary `chain` IDs, including the common -1 (masterchain) and 0 (basechain) ones.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let initPkg: StateInit = initOf SomeContract();\n' + + '/// let hereBeDragons: Address = contractAddressExt(0, initPkg.code, initPkg.data);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '/// * https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'inline fun contractAddressExt(chain: Int, code: Cell, data: Cell): Address {\n' + + ' let hash = contractHash(code, data);\n' + + ' return newAddress(chain, hash);\n' + + '}\n' + + '\n' + + '/// Struct containing the initial state, i.e. initial code and initial data of the given contract upon its deployment.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'struct StateInit {\n' + + ' /// Initial code of the contract (compiled bitcode)\n' + + ' code: Cell;\n' + + '\n' + + ' /// Initial data of the contract (parameters of `init()` function or contract parameters)\n' + + ' data: Cell;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.1.\n' + + '///\n' + + '/// Efficiently compares if the given address matches the basechain address of the contract.\n' + + '/// Returns true if addresses are the same, false otherwise.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let init = initOf SomeContract();\n' + + "/// init.hasSameBasechainAddress(sender()); // returns true if sender matches contract's basechain address\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// This function provides a gas-optimized implementation compared to direct address comparison:\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let init = initOf SomeContract();\n' + + '/// sender() == contractAddress(sender()); // less efficient approach\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// Note that this function works only for basechain addresses!\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddress\n' + + '///\n' + + 'inline extends fun hasSameBasechainAddress(self: StateInit, sender: Address): Bool {\n' + + ' let senderAddress = parseStdAddress(sender.asSlice()).address;\n' + + ' let baseAddress = contractBasechainAddress(self);\n' + + ' return baseAddress.hash!! == senderAddress;\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + "/// Computes smart contract's `Address` in the workchain ID 0 (basechain) using the `StateInit` `s` of the contract. Alias to `contractAddressExt(0, s.code, s.data)`.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let s: StateInit = initOf SomeContract();\n' + + '/// let foundMeSome: Address = contractAddress(s);\n' + + '/// let andSomeMore: Address = contractAddressExt(0, s.code, s.data);\n' + + '///\n' + + '/// foundMeSome == andSomeMore; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '/// * https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'inline fun contractAddress(s: StateInit): Address {\n' + + ' return contractAddressExt(0, s.code, s.data);\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Returns the address of the current smart contract as an `Address`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let meMyselfAndI: Address = myAddress();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#myaddress\n' + + '///\n' + + 'asm fun myAddress(): Address { MYADDR }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` balance of the smart contract as it was at the start of the compute phase of the current transaction.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let iNeedADolla: Int = myBalance();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#mybalance\n' + + '///\n' + + 'asm fun myBalance(): Int { BALANCE FIRST }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` amount of gas consumed by TVM in the current transaction so far. The resulting value includes the cost of calling this function.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let gas: Int = gasConsumed();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#gasconsumed\n' + + '///\n' + + 'asm fun gasConsumed(): Int { GASCONSUMED }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` amount of the accumulated storage fee debt. Storage fees are deducted from the incoming message value before the new contract balance is calculated.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let debt: Int = myStorageDue();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#mystoragedue\n' + + '///\n' + + 'asm fun myStorageDue(): Int { DUEPAYMENT }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Calculates and returns the storage fee in nanoToncoins `Int` for storing a contract with a given number of `cells` and `bits` for a number of `seconds`. Uses the prices of the masterchain if `isMasterchain` is `true`, otherwise the prices of the basechain. The current prices are obtained from the config param 18 of TON Blockchain.\n' + + '///\n' + + '/// Note, that specifying values of `cells` and `bits` higher than their maximum values listed in account state limits (`max_acc_state_cells` and `max_acc_state_bits`) will have the same result as with specifying the exact limits. In addition, make sure you take into account the deduplication of cells with the same hash.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fee: Int = getStorageFee(1_000, 1_000, 1_000, false);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify negative number of `cells`, `bits` or `seconds`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-gas#getstoragefee\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun getStorageFee(cells: Int, bits: Int, seconds: Int, isMasterchain: Bool): Int { GETSTORAGEFEE }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Calculates and returns the compute fee in nanoToncoins `Int` for a transaction that consumed `gasUsed` amount of gas. Uses the prices of the masterchain if `isMasterchain` is `true`, otherwise the prices of the basechain. The current prices are obtained from the config param 20 for the masterchain and config param 21 for the basechain of TON Blockchain.\n' + + '///\n' + + "/// When the `gasUsed` is less than a certain threshold called `flat_gas_limit`, there's a minimum price to pay based on the value of `flat_gas_price`. The less gas is used below this threshold, the higher the minimum price will be. See the example for `getSimpleComputeFee()` to derive that threshold.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fee: Int = getComputeFee(1_000, false);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify negative value of `gasUsed`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-gas#getcomputefee\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun getComputeFee(gasUsed: Int, isMasterchain: Bool): Int { GETGASFEE }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Similar to `getComputeFee()`, but without the `flat_gas_price`, i.e. without a minimum price to pay if the `gasUsed` is less than a certain '... 8611 more characters, + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'contractHash', + loc: { start: 1027, end: 1039 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1065, end: 1068 } + }, + loc: { start: 1065, end: 1068 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 1040, end: 1044 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 1046, end: 1050 } }, + loc: { start: 1046, end: 1050 } + }, + loc: { start: 1040, end: 1050 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'data', + loc: { start: 1052, end: 1056 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 1058, end: 1062 } }, + loc: { start: 1058, end: 1062 } + }, + loc: { start: 1052, end: 1062 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 's0 PUSH HASHCU // `data` hash\n' + + ' s2 PUSH HASHCU // `code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `code` depth\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + '\n' + + ' // Group 2: Composition of the Builder\n' + + ' NEWC\n' + + ' 24 STU // store refs_descriptor | bits_descriptor | data\n' + + ' 16 STU // store depth_descriptor for `code`\n' + + ' 16 STU // store depth_descriptor for `data`\n' + + ' 256 STU // store `code` hash\n' + + ' 256 STU // store `data` hash\n' + + '\n' + + ' // Group 3: SHA256 hash of the resulting Builder\n' + + ' ONE HASHEXT_SHA256' + ] + }, + loc: { start: 1019, end: 2666 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'contractAddressExt', + loc: { start: 3391, end: 3409 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3447, end: 3454 } + }, + typeArgs: [], + loc: { start: 3447, end: 3454 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'chain', + loc: { start: 3410, end: 3415 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3417, end: 3420 } + }, + loc: { start: 3417, end: 3420 } + }, + loc: { start: 3410, end: 3420 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 3422, end: 3426 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3428, end: 3432 } }, + loc: { start: 3428, end: 3432 } + }, + loc: { start: 3422, end: 3432 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'data', + loc: { start: 3434, end: 3438 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3440, end: 3444 } }, + loc: { start: 3440, end: 3444 } + }, + loc: { start: 3434, end: 3444 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'hash', + loc: { start: 3465, end: 3469 } + }, + type: undefined, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractHash', + loc: { start: 3472, end: 3484 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'code', + loc: { start: 3485, end: 3489 } + }, + { + kind: 'var', + name: 'data', + loc: { start: 3491, end: 3495 } + } + ], + loc: { start: 3472, end: 3496 } + }, + loc: { start: 3461, end: 3497 } + }, + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'newAddress', + loc: { start: 3509, end: 3519 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'chain', + loc: { start: 3520, end: 3525 } + }, + { + kind: 'var', + name: 'hash', + loc: { start: 3527, end: 3531 } + } + ], + loc: { start: 3509, end: 3532 } + }, + loc: { start: 3502, end: 3533 } + } + ] + }, + loc: { start: 3380, end: 3535 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 3731, end: 3740 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'code', + loc: { start: 3803, end: 3807 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3809, end: 3813 } }, + loc: { start: 3809, end: 3813 } + }, + initializer: undefined, + loc: { start: 3803, end: 3813 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'data', + loc: { start: 3914, end: 3918 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3920, end: 3924 } }, + loc: { start: 3920, end: 3924 } + }, + initializer: undefined, + loc: { start: 3914, end: 3924 } + } + ], + loc: { start: 3724, end: 3927 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'hasSameBasechainAddress', + loc: { start: 4778, end: 4801 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 4837, end: 4841 } + }, + typeArgs: [], + loc: { start: 4837, end: 4841 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'sender', + loc: { start: 4819, end: 4825 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 4827, end: 4834 } + }, + typeArgs: [], + loc: { start: 4827, end: 4834 } + }, + loc: { start: 4819, end: 4834 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'senderAddress', + loc: { start: 4852, end: 4865 } + }, + type: undefined, + expression: { + kind: 'field_access', + aggregate: { + kind: 'static_call', + function: { + kind: 'id', + text: 'parseStdAddress', + loc: { start: 4868, end: 4883 } + }, + typeArgs: [], + args: [ + { + kind: 'method_call', + self: { + kind: 'var', + name: 'sender', + loc: { start: 4884, end: 4890 } + }, + method: { + kind: 'id', + text: 'asSlice', + loc: { start: 4891, end: 4898 } + }, + typeArgs: [], + args: [], + loc: { start: 4884, end: 4900 } + } + ], + loc: { start: 4868, end: 4901 } + }, + field: { + kind: 'id', + text: 'address', + loc: { start: 4902, end: 4909 } + }, + loc: { start: 4868, end: 4909 } + }, + loc: { start: 4848, end: 4910 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'baseAddress', + loc: { start: 4919, end: 4930 } + }, + type: undefined, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractBasechainAddress', + loc: { start: 4933, end: 4957 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'self', + loc: { start: 4958, end: 4962 } + } + ], + loc: { start: 4933, end: 4963 } + }, + loc: { start: 4915, end: 4964 } + }, + { + kind: 'statement_return', + expression: { + kind: 'op_binary', + op: '==', + left: { + kind: 'op_unary', + op: '!!', + operand: { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'baseAddress', + loc: { start: 4976, end: 4987 } + }, + field: { + kind: 'id', + text: 'hash', + loc: { start: 4988, end: 4992 } + }, + loc: { start: 4976, end: 4992 } + }, + loc: { start: 4976, end: 4994 } + }, + right: { + kind: 'var', + name: 'senderAddress', + loc: { start: 4998, end: 5011 } + }, + loc: { start: 4976, end: 5011 } + }, + loc: { start: 4969, end: 5012 } + } + ] + }, + loc: { start: 4759, end: 5014 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 4808, end: 4817 } + }, + typeArgs: [], + loc: { start: 4808, end: 4817 } + } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'contractAddress', + loc: { start: 5709, end: 5724 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 5740, end: 5747 } + }, + typeArgs: [], + loc: { start: 5740, end: 5747 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 's', + loc: { start: 5725, end: 5726 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 5728, end: 5737 } + }, + typeArgs: [], + loc: { start: 5728, end: 5737 } + }, + loc: { start: 5725, end: 5737 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractAddressExt', + loc: { start: 5761, end: 5779 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 5780, end: 5781 } + }, + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 5783, end: 5784 } + }, + field: { + kind: 'id', + text: 'code', + loc: { start: 5785, end: 5789 } + }, + loc: { start: 5783, end: 5789 } + }, + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 5791, end: 5792 } + }, + field: { + kind: 'id', + text: 'data', + loc: { start: 5793, end: 5797 } + }, + loc: { start: 5791, end: 5797 } + } + ], + loc: { start: 5761, end: 5798 } + }, + loc: { start: 5754, end: 5799 } + } + ] + }, + loc: { start: 5698, end: 5801 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myAddress', + loc: { start: 6082, end: 6091 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 6095, end: 6102 } + }, + typeArgs: [], + loc: { start: 6095, end: 6102 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MYADDR' ] + }, + loc: { start: 6074, end: 6113 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myBalance', + loc: { start: 6454, end: 6463 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6467, end: 6470 } + }, + loc: { start: 6467, end: 6470 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'BALANCE FIRST' ] + }, + loc: { start: 6446, end: 6488 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'gasConsumed', + loc: { start: 6880, end: 6891 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6895, end: 6898 } + }, + loc: { start: 6895, end: 6898 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GASCONSUMED' ] + }, + loc: { start: 6872, end: 6914 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myStorageDue', + loc: { start: 7329, end: 7341 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7345, end: 7348 } + }, + loc: { start: 7345, end: 7348 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DUEPAYMENT' ] + }, + loc: { start: 7321, end: 7363 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getStorageFee', + loc: { start: 8517, end: 8530 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8590, end: 8593 } + }, + loc: { start: 8590, end: 8593 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 8531, end: 8536 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8538, end: 8541 } + }, + loc: { start: 8538, end: 8541 } + }, + loc: { start: 8531, end: 8541 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 8543, end: 8547 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8549, end: 8552 } + }, + loc: { start: 8549, end: 8552 } + }, + loc: { start: 8543, end: 8552 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'seconds', + loc: { start: 8554, end: 8561 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8563, end: 8566 } + }, + loc: { start: 8563, end: 8566 } + }, + loc: { start: 8554, end: 8566 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 8568, end: 8581 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 8583, end: 8587 } + }, + typeArgs: [], + loc: { start: 8583, end: 8587 } + }, + loc: { start: 8568, end: 8587 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETSTORAGEFEE' ] + }, + loc: { start: 8509, end: 8611 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getComputeFee', + loc: { start: 9734, end: 9747 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9784, end: 9787 } + }, + loc: { start: 9784, end: 9787 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'gasUsed', + loc: { start: 9748, end: 9755 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9757, end: 9760 } + }, + loc: { start: 9757, end: 9760 } + }, + loc: { start: 9748, end: 9760 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 9762, end: 9775 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 9777, end: 9781 } + }, + typeArgs: [], + loc: { start: 9777, end: 9781 } + }, + loc: { start: 9762, end: 9781 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETGASFEE' ] + }, + loc: { start: 9726, end: 9801 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSimpleComputeFee', + loc: { start: 10689, end: 10708 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10745, end: 10748 } + }, + loc: { start: 10745, end: 10748 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'gasUsed', + loc: { start: 10709, end: 10716 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10718, end: 10721 } + }, + loc: { start: 10718, end: 10721 } + }, + loc: { start: 10709, end: 10721 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 10723, end: 10736 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 10738, end: 10742 } + }, + typeArgs: [], + loc: { start: 10738, end: 10742 } + }, + loc: { start: 10723, end: 10742 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETGASFEESIMPLE' ] + }, + loc: { start: 10681, end: 10768 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getForwardFee', + loc: { start: 12543, end: 12556 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12602, end: 12605 } + }, + loc: { start: 12602, end: 12605 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 12557, end: 12562 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12564, end: 12567 } + }, + loc: { start: 12564, end: 12567 } + }, + loc: { start: 12557, end: 12567 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 12569, end: 12573 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12575, end: 12578 } + }, + loc: { start: 12575, end: 12578 } + }, + loc: { start: 12569, end: 12578 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 12580, end: 12593 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 12595, end: 12599 } + }, + typeArgs: [], + loc: { start: 12595, end: 12599 } + }, + loc: { start: 12580, end: 12599 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETFORWARDFEE' ] + }, + loc: { start: 12535, end: 12623 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSimpleForwardFee', + loc: { start: 13528, end: 13547 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13593, end: 13596 } + }, + loc: { start: 13593, end: 13596 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 13548, end: 13553 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13555, end: 13558 } + }, + loc: { start: 13555, end: 13558 } + }, + loc: { start: 13548, end: 13558 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 13560, end: 13564 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13566, end: 13569 } + }, + loc: { start: 13566, end: 13569 } + }, + loc: { start: 13560, end: 13569 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 13571, end: 13584 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 13586, end: 13590 } + }, + typeArgs: [], + loc: { start: 13586, end: 13590 } + }, + loc: { start: 13571, end: 13590 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETFORWARDFEESIMPLE' ] + }, + loc: { start: 13520, end: 13620 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getOriginalFwdFee', + loc: { start: 15782, end: 15799 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15835, end: 15838 } + }, + loc: { start: 15835, end: 15838 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'fwdFee', + loc: { start: 15800, end: 15806 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15808, end: 15811 } + }, + loc: { start: 15808, end: 15811 } + }, + loc: { start: 15800, end: 15811 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 15813, end: 15826 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 15828, end: 15832 } + }, + typeArgs: [], + loc: { start: 15828, end: 15832 } + }, + loc: { start: 15813, end: 15832 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETORIGINALFWDFEE' ] + }, + loc: { start: 15774, end: 15860 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'setGasLimit', + loc: { start: 16541, end: 16552 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'limit', + loc: { start: 16553, end: 16558 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 16560, end: 16563 } + }, + loc: { start: 16560, end: 16563 } + }, + loc: { start: 16553, end: 16563 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SETGASLIMIT' ] + }, + loc: { start: 16533, end: 16580 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSeed', + loc: { start: 17350, end: 17357 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 17361, end: 17364 } + }, + loc: { start: 17361, end: 17364 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RANDSEED' ] + }, + loc: { start: 17342, end: 17377 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'setSeed', + loc: { start: 18258, end: 18265 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'seed', + loc: { start: 18266, end: 18270 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 18272, end: 18275 } + }, + loc: { start: 18272, end: 18275 } + }, + loc: { start: 18266, end: 18275 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SETRAND' ] + }, + loc: { start: 18250, end: 18288 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myCode', + loc: { start: 18585, end: 18591 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 18595, end: 18599 } }, + loc: { start: 18595, end: 18599 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MYCODE' ] + }, + loc: { start: 18577, end: 18610 } + } + ] + }, + 'getForwardFee' => { + kind: 'tact', + path: 'std/internal/contract.tact', + code: '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Computes and returns an `Int` value of the SHA-256 hash of the `code` and `data` of the given contract. To assemble the `code` and `data` cells together for hashing, the standard `Cell` representation is used.\n' + + '///\n' + + '/// This hash is commonly called account ID. Together with the workchain ID it deterministically forms the address of the contract on TON Blockchain.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let initPkg: StateInit = initOf SomeContract();\n' + + '/// let accountId: Int = contractHash(initPkg.code, initPkg.data);\n' + + '/// let basechainAddr: Address = newAddress(0, accountId);\n' + + '/// let basechainAddr2: Address = contractAddressExt(0, initPkg.code, initPkg.data);\n' + + '///\n' + + '/// basechainAddr == basechainAddr2; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contracthash\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#newaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '///\n' + + 'asm fun contractHash(code: Cell, data: Cell): Int {\n' + + ' // According to the https://docs.tact-lang.org/book/cells#cells-representation,\n' + + ' // the layout for the Builder to hash goes as follows:\n' + + ' // 1) refs_descriptor:bits8 | bits_descriptor:bits8 | data:bitsN\n' + + ' //\n' + + ' // refs_descriptor: ref_count + ((exotic? & 1) * 8) + (mask * 32)\n' + + ' // 2 refs (code + data), non-exotic, zero-mask\n' + + ' //\n' + + ' // bits_descriptor: floor(bit_count / 8) + ceil(bit_count, 8)\n' + + ' // floor (5 bits / 8) + ceil(5 bits / 8) = 0 + 1 = 1\n' + + ' //\n' + + ' // data: [0b00110] + [0b100] = [0b00110100] = 0x34 (data + augmented bits)\n' + + ' // 0b00110 - data (split_depth, special, code, data, Library)\n' + + ' // 0b100 - augmented bits (Leading 1 + zeroes to make section multiple of eight)\n' + + ' //\n' + + ' // That is: (2 << 16) | (1 << 8) | 0x34 = 131380 for all three.\n' + + ' //\n' + + ' // 2) and 3) depth_descriptors: CDEPTH of `code` and CDEPTH of `data`\n' + + ' // 4) and 5) ref hashes: HASHCU of `code` and HASHCU of `data`\n' + + '\n' + + ' // Group 1: Computations and arrangements\n' + + ' s0 PUSH HASHCU // `data` hash\n' + + ' s2 PUSH HASHCU // `code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `code` depth\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + '\n' + + ' // Group 2: Composition of the Builder\n' + + ' NEWC\n' + + ' 24 STU // store refs_descriptor | bits_descriptor | data\n' + + ' 16 STU // store depth_descriptor for `code`\n' + + ' 16 STU // store depth_descriptor for `data`\n' + + ' 256 STU // store `code` hash\n' + + ' 256 STU // store `data` hash\n' + + '\n' + + ' // Group 3: SHA256 hash of the resulting Builder\n' + + ' ONE HASHEXT_SHA256\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + "/// Computes smart contract's `Address` in the `chain` ID using the contract's `code` and the contract's initial state `data`. Use the `initOf` expression to obtain the initial `code` and initial `data` of a given contract.\n" + + '///\n' + + '/// This function lets you specify arbitrary `chain` IDs, including the common -1 (masterchain) and 0 (basechain) ones.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let initPkg: StateInit = initOf SomeContract();\n' + + '/// let hereBeDragons: Address = contractAddressExt(0, initPkg.code, initPkg.data);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '/// * https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'inline fun contractAddressExt(chain: Int, code: Cell, data: Cell): Address {\n' + + ' let hash = contractHash(code, data);\n' + + ' return newAddress(chain, hash);\n' + + '}\n' + + '\n' + + '/// Struct containing the initial state, i.e. initial code and initial data of the given contract upon its deployment.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'struct StateInit {\n' + + ' /// Initial code of the contract (compiled bitcode)\n' + + ' code: Cell;\n' + + '\n' + + ' /// Initial data of the contract (parameters of `init()` function or contract parameters)\n' + + ' data: Cell;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.1.\n' + + '///\n' + + '/// Efficiently compares if the given address matches the basechain address of the contract.\n' + + '/// Returns true if addresses are the same, false otherwise.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let init = initOf SomeContract();\n' + + "/// init.hasSameBasechainAddress(sender()); // returns true if sender matches contract's basechain address\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// This function provides a gas-optimized implementation compared to direct address comparison:\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let init = initOf SomeContract();\n' + + '/// sender() == contractAddress(sender()); // less efficient approach\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// Note that this function works only for basechain addresses!\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddress\n' + + '///\n' + + 'inline extends fun hasSameBasechainAddress(self: StateInit, sender: Address): Bool {\n' + + ' let senderAddress = parseStdAddress(sender.asSlice()).address;\n' + + ' let baseAddress = contractBasechainAddress(self);\n' + + ' return baseAddress.hash!! == senderAddress;\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + "/// Computes smart contract's `Address` in the workchain ID 0 (basechain) using the `StateInit` `s` of the contract. Alias to `contractAddressExt(0, s.code, s.data)`.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let s: StateInit = initOf SomeContract();\n' + + '/// let foundMeSome: Address = contractAddress(s);\n' + + '/// let andSomeMore: Address = contractAddressExt(0, s.code, s.data);\n' + + '///\n' + + '/// foundMeSome == andSomeMore; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '/// * https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'inline fun contractAddress(s: StateInit): Address {\n' + + ' return contractAddressExt(0, s.code, s.data);\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Returns the address of the current smart contract as an `Address`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let meMyselfAndI: Address = myAddress();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#myaddress\n' + + '///\n' + + 'asm fun myAddress(): Address { MYADDR }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` balance of the smart contract as it was at the start of the compute phase of the current transaction.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let iNeedADolla: Int = myBalance();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#mybalance\n' + + '///\n' + + 'asm fun myBalance(): Int { BALANCE FIRST }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` amount of gas consumed by TVM in the current transaction so far. The resulting value includes the cost of calling this function.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let gas: Int = gasConsumed();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#gasconsumed\n' + + '///\n' + + 'asm fun gasConsumed(): Int { GASCONSUMED }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` amount of the accumulated storage fee debt. Storage fees are deducted from the incoming message value before the new contract balance is calculated.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let debt: Int = myStorageDue();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#mystoragedue\n' + + '///\n' + + 'asm fun myStorageDue(): Int { DUEPAYMENT }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Calculates and returns the storage fee in nanoToncoins `Int` for storing a contract with a given number of `cells` and `bits` for a number of `seconds`. Uses the prices of the masterchain if `isMasterchain` is `true`, otherwise the prices of the basechain. The current prices are obtained from the config param 18 of TON Blockchain.\n' + + '///\n' + + '/// Note, that specifying values of `cells` and `bits` higher than their maximum values listed in account state limits (`max_acc_state_cells` and `max_acc_state_bits`) will have the same result as with specifying the exact limits. In addition, make sure you take into account the deduplication of cells with the same hash.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fee: Int = getStorageFee(1_000, 1_000, 1_000, false);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify negative number of `cells`, `bits` or `seconds`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-gas#getstoragefee\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun getStorageFee(cells: Int, bits: Int, seconds: Int, isMasterchain: Bool): Int { GETSTORAGEFEE }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Calculates and returns the compute fee in nanoToncoins `Int` for a transaction that consumed `gasUsed` amount of gas. Uses the prices of the masterchain if `isMasterchain` is `true`, otherwise the prices of the basechain. The current prices are obtained from the config param 20 for the masterchain and config param 21 for the basechain of TON Blockchain.\n' + + '///\n' + + "/// When the `gasUsed` is less than a certain threshold called `flat_gas_limit`, there's a minimum price to pay based on the value of `flat_gas_price`. The less gas is used below this threshold, the higher the minimum price will be. See the example for `getSimpleComputeFee()` to derive that threshold.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fee: Int = getComputeFee(1_000, false);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify negative value of `gasUsed`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-gas#getcomputefee\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun getComputeFee(gasUsed: Int, isMasterchain: Bool): Int { GETGASFEE }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Similar to `getComputeFee()`, but without the `flat_gas_price`, i.e. without a minimum price to pay if the `gasUsed` is less than a certain '... 8611 more characters, + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'contractHash', + loc: { start: 1027, end: 1039 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1065, end: 1068 } + }, + loc: { start: 1065, end: 1068 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 1040, end: 1044 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 1046, end: 1050 } }, + loc: { start: 1046, end: 1050 } + }, + loc: { start: 1040, end: 1050 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'data', + loc: { start: 1052, end: 1056 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 1058, end: 1062 } }, + loc: { start: 1058, end: 1062 } + }, + loc: { start: 1052, end: 1062 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 's0 PUSH HASHCU // `data` hash\n' + + ' s2 PUSH HASHCU // `code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `code` depth\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + '\n' + + ' // Group 2: Composition of the Builder\n' + + ' NEWC\n' + + ' 24 STU // store refs_descriptor | bits_descriptor | data\n' + + ' 16 STU // store depth_descriptor for `code`\n' + + ' 16 STU // store depth_descriptor for `data`\n' + + ' 256 STU // store `code` hash\n' + + ' 256 STU // store `data` hash\n' + + '\n' + + ' // Group 3: SHA256 hash of the resulting Builder\n' + + ' ONE HASHEXT_SHA256' + ] + }, + loc: { start: 1019, end: 2666 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'contractAddressExt', + loc: { start: 3391, end: 3409 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3447, end: 3454 } + }, + typeArgs: [], + loc: { start: 3447, end: 3454 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'chain', + loc: { start: 3410, end: 3415 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3417, end: 3420 } + }, + loc: { start: 3417, end: 3420 } + }, + loc: { start: 3410, end: 3420 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 3422, end: 3426 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3428, end: 3432 } }, + loc: { start: 3428, end: 3432 } + }, + loc: { start: 3422, end: 3432 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'data', + loc: { start: 3434, end: 3438 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3440, end: 3444 } }, + loc: { start: 3440, end: 3444 } + }, + loc: { start: 3434, end: 3444 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'hash', + loc: { start: 3465, end: 3469 } + }, + type: undefined, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractHash', + loc: { start: 3472, end: 3484 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'code', + loc: { start: 3485, end: 3489 } + }, + { + kind: 'var', + name: 'data', + loc: { start: 3491, end: 3495 } + } + ], + loc: { start: 3472, end: 3496 } + }, + loc: { start: 3461, end: 3497 } + }, + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'newAddress', + loc: { start: 3509, end: 3519 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'chain', + loc: { start: 3520, end: 3525 } + }, + { + kind: 'var', + name: 'hash', + loc: { start: 3527, end: 3531 } + } + ], + loc: { start: 3509, end: 3532 } + }, + loc: { start: 3502, end: 3533 } + } + ] + }, + loc: { start: 3380, end: 3535 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 3731, end: 3740 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'code', + loc: { start: 3803, end: 3807 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3809, end: 3813 } }, + loc: { start: 3809, end: 3813 } + }, + initializer: undefined, + loc: { start: 3803, end: 3813 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'data', + loc: { start: 3914, end: 3918 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3920, end: 3924 } }, + loc: { start: 3920, end: 3924 } + }, + initializer: undefined, + loc: { start: 3914, end: 3924 } + } + ], + loc: { start: 3724, end: 3927 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'hasSameBasechainAddress', + loc: { start: 4778, end: 4801 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 4837, end: 4841 } + }, + typeArgs: [], + loc: { start: 4837, end: 4841 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'sender', + loc: { start: 4819, end: 4825 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 4827, end: 4834 } + }, + typeArgs: [], + loc: { start: 4827, end: 4834 } + }, + loc: { start: 4819, end: 4834 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'senderAddress', + loc: { start: 4852, end: 4865 } + }, + type: undefined, + expression: { + kind: 'field_access', + aggregate: { + kind: 'static_call', + function: { + kind: 'id', + text: 'parseStdAddress', + loc: { start: 4868, end: 4883 } + }, + typeArgs: [], + args: [ + { + kind: 'method_call', + self: { + kind: 'var', + name: 'sender', + loc: { start: 4884, end: 4890 } + }, + method: { + kind: 'id', + text: 'asSlice', + loc: { start: 4891, end: 4898 } + }, + typeArgs: [], + args: [], + loc: { start: 4884, end: 4900 } + } + ], + loc: { start: 4868, end: 4901 } + }, + field: { + kind: 'id', + text: 'address', + loc: { start: 4902, end: 4909 } + }, + loc: { start: 4868, end: 4909 } + }, + loc: { start: 4848, end: 4910 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'baseAddress', + loc: { start: 4919, end: 4930 } + }, + type: undefined, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractBasechainAddress', + loc: { start: 4933, end: 4957 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'self', + loc: { start: 4958, end: 4962 } + } + ], + loc: { start: 4933, end: 4963 } + }, + loc: { start: 4915, end: 4964 } + }, + { + kind: 'statement_return', + expression: { + kind: 'op_binary', + op: '==', + left: { + kind: 'op_unary', + op: '!!', + operand: { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'baseAddress', + loc: { start: 4976, end: 4987 } + }, + field: { + kind: 'id', + text: 'hash', + loc: { start: 4988, end: 4992 } + }, + loc: { start: 4976, end: 4992 } + }, + loc: { start: 4976, end: 4994 } + }, + right: { + kind: 'var', + name: 'senderAddress', + loc: { start: 4998, end: 5011 } + }, + loc: { start: 4976, end: 5011 } + }, + loc: { start: 4969, end: 5012 } + } + ] + }, + loc: { start: 4759, end: 5014 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 4808, end: 4817 } + }, + typeArgs: [], + loc: { start: 4808, end: 4817 } + } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'contractAddress', + loc: { start: 5709, end: 5724 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 5740, end: 5747 } + }, + typeArgs: [], + loc: { start: 5740, end: 5747 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 's', + loc: { start: 5725, end: 5726 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 5728, end: 5737 } + }, + typeArgs: [], + loc: { start: 5728, end: 5737 } + }, + loc: { start: 5725, end: 5737 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractAddressExt', + loc: { start: 5761, end: 5779 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 5780, end: 5781 } + }, + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 5783, end: 5784 } + }, + field: { + kind: 'id', + text: 'code', + loc: { start: 5785, end: 5789 } + }, + loc: { start: 5783, end: 5789 } + }, + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 5791, end: 5792 } + }, + field: { + kind: 'id', + text: 'data', + loc: { start: 5793, end: 5797 } + }, + loc: { start: 5791, end: 5797 } + } + ], + loc: { start: 5761, end: 5798 } + }, + loc: { start: 5754, end: 5799 } + } + ] + }, + loc: { start: 5698, end: 5801 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myAddress', + loc: { start: 6082, end: 6091 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 6095, end: 6102 } + }, + typeArgs: [], + loc: { start: 6095, end: 6102 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MYADDR' ] + }, + loc: { start: 6074, end: 6113 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myBalance', + loc: { start: 6454, end: 6463 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6467, end: 6470 } + }, + loc: { start: 6467, end: 6470 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'BALANCE FIRST' ] + }, + loc: { start: 6446, end: 6488 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'gasConsumed', + loc: { start: 6880, end: 6891 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6895, end: 6898 } + }, + loc: { start: 6895, end: 6898 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GASCONSUMED' ] + }, + loc: { start: 6872, end: 6914 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myStorageDue', + loc: { start: 7329, end: 7341 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7345, end: 7348 } + }, + loc: { start: 7345, end: 7348 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DUEPAYMENT' ] + }, + loc: { start: 7321, end: 7363 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getStorageFee', + loc: { start: 8517, end: 8530 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8590, end: 8593 } + }, + loc: { start: 8590, end: 8593 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 8531, end: 8536 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8538, end: 8541 } + }, + loc: { start: 8538, end: 8541 } + }, + loc: { start: 8531, end: 8541 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 8543, end: 8547 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8549, end: 8552 } + }, + loc: { start: 8549, end: 8552 } + }, + loc: { start: 8543, end: 8552 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'seconds', + loc: { start: 8554, end: 8561 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8563, end: 8566 } + }, + loc: { start: 8563, end: 8566 } + }, + loc: { start: 8554, end: 8566 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 8568, end: 8581 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 8583, end: 8587 } + }, + typeArgs: [], + loc: { start: 8583, end: 8587 } + }, + loc: { start: 8568, end: 8587 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETSTORAGEFEE' ] + }, + loc: { start: 8509, end: 8611 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getComputeFee', + loc: { start: 9734, end: 9747 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9784, end: 9787 } + }, + loc: { start: 9784, end: 9787 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'gasUsed', + loc: { start: 9748, end: 9755 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9757, end: 9760 } + }, + loc: { start: 9757, end: 9760 } + }, + loc: { start: 9748, end: 9760 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 9762, end: 9775 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 9777, end: 9781 } + }, + typeArgs: [], + loc: { start: 9777, end: 9781 } + }, + loc: { start: 9762, end: 9781 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETGASFEE' ] + }, + loc: { start: 9726, end: 9801 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSimpleComputeFee', + loc: { start: 10689, end: 10708 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10745, end: 10748 } + }, + loc: { start: 10745, end: 10748 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'gasUsed', + loc: { start: 10709, end: 10716 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10718, end: 10721 } + }, + loc: { start: 10718, end: 10721 } + }, + loc: { start: 10709, end: 10721 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 10723, end: 10736 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 10738, end: 10742 } + }, + typeArgs: [], + loc: { start: 10738, end: 10742 } + }, + loc: { start: 10723, end: 10742 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETGASFEESIMPLE' ] + }, + loc: { start: 10681, end: 10768 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getForwardFee', + loc: { start: 12543, end: 12556 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12602, end: 12605 } + }, + loc: { start: 12602, end: 12605 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 12557, end: 12562 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12564, end: 12567 } + }, + loc: { start: 12564, end: 12567 } + }, + loc: { start: 12557, end: 12567 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 12569, end: 12573 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12575, end: 12578 } + }, + loc: { start: 12575, end: 12578 } + }, + loc: { start: 12569, end: 12578 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 12580, end: 12593 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 12595, end: 12599 } + }, + typeArgs: [], + loc: { start: 12595, end: 12599 } + }, + loc: { start: 12580, end: 12599 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETFORWARDFEE' ] + }, + loc: { start: 12535, end: 12623 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSimpleForwardFee', + loc: { start: 13528, end: 13547 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13593, end: 13596 } + }, + loc: { start: 13593, end: 13596 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 13548, end: 13553 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13555, end: 13558 } + }, + loc: { start: 13555, end: 13558 } + }, + loc: { start: 13548, end: 13558 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 13560, end: 13564 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13566, end: 13569 } + }, + loc: { start: 13566, end: 13569 } + }, + loc: { start: 13560, end: 13569 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 13571, end: 13584 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 13586, end: 13590 } + }, + typeArgs: [], + loc: { start: 13586, end: 13590 } + }, + loc: { start: 13571, end: 13590 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETFORWARDFEESIMPLE' ] + }, + loc: { start: 13520, end: 13620 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getOriginalFwdFee', + loc: { start: 15782, end: 15799 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15835, end: 15838 } + }, + loc: { start: 15835, end: 15838 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'fwdFee', + loc: { start: 15800, end: 15806 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15808, end: 15811 } + }, + loc: { start: 15808, end: 15811 } + }, + loc: { start: 15800, end: 15811 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 15813, end: 15826 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 15828, end: 15832 } + }, + typeArgs: [], + loc: { start: 15828, end: 15832 } + }, + loc: { start: 15813, end: 15832 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETORIGINALFWDFEE' ] + }, + loc: { start: 15774, end: 15860 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'setGasLimit', + loc: { start: 16541, end: 16552 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'limit', + loc: { start: 16553, end: 16558 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 16560, end: 16563 } + }, + loc: { start: 16560, end: 16563 } + }, + loc: { start: 16553, end: 16563 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SETGASLIMIT' ] + }, + loc: { start: 16533, end: 16580 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSeed', + loc: { start: 17350, end: 17357 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 17361, end: 17364 } + }, + loc: { start: 17361, end: 17364 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RANDSEED' ] + }, + loc: { start: 17342, end: 17377 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'setSeed', + loc: { start: 18258, end: 18265 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'seed', + loc: { start: 18266, end: 18270 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 18272, end: 18275 } + }, + loc: { start: 18272, end: 18275 } + }, + loc: { start: 18266, end: 18275 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SETRAND' ] + }, + loc: { start: 18250, end: 18288 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myCode', + loc: { start: 18585, end: 18591 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 18595, end: 18599 } }, + loc: { start: 18595, end: 18599 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MYCODE' ] + }, + loc: { start: 18577, end: 18610 } + } + ] + }, + 'getSimpleForwardFee' => { + kind: 'tact', + path: 'std/internal/contract.tact', + code: '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Computes and returns an `Int` value of the SHA-256 hash of the `code` and `data` of the given contract. To assemble the `code` and `data` cells together for hashing, the standard `Cell` representation is used.\n' + + '///\n' + + '/// This hash is commonly called account ID. Together with the workchain ID it deterministically forms the address of the contract on TON Blockchain.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let initPkg: StateInit = initOf SomeContract();\n' + + '/// let accountId: Int = contractHash(initPkg.code, initPkg.data);\n' + + '/// let basechainAddr: Address = newAddress(0, accountId);\n' + + '/// let basechainAddr2: Address = contractAddressExt(0, initPkg.code, initPkg.data);\n' + + '///\n' + + '/// basechainAddr == basechainAddr2; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contracthash\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#newaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '///\n' + + 'asm fun contractHash(code: Cell, data: Cell): Int {\n' + + ' // According to the https://docs.tact-lang.org/book/cells#cells-representation,\n' + + ' // the layout for the Builder to hash goes as follows:\n' + + ' // 1) refs_descriptor:bits8 | bits_descriptor:bits8 | data:bitsN\n' + + ' //\n' + + ' // refs_descriptor: ref_count + ((exotic? & 1) * 8) + (mask * 32)\n' + + ' // 2 refs (code + data), non-exotic, zero-mask\n' + + ' //\n' + + ' // bits_descriptor: floor(bit_count / 8) + ceil(bit_count, 8)\n' + + ' // floor (5 bits / 8) + ceil(5 bits / 8) = 0 + 1 = 1\n' + + ' //\n' + + ' // data: [0b00110] + [0b100] = [0b00110100] = 0x34 (data + augmented bits)\n' + + ' // 0b00110 - data (split_depth, special, code, data, Library)\n' + + ' // 0b100 - augmented bits (Leading 1 + zeroes to make section multiple of eight)\n' + + ' //\n' + + ' // That is: (2 << 16) | (1 << 8) | 0x34 = 131380 for all three.\n' + + ' //\n' + + ' // 2) and 3) depth_descriptors: CDEPTH of `code` and CDEPTH of `data`\n' + + ' // 4) and 5) ref hashes: HASHCU of `code` and HASHCU of `data`\n' + + '\n' + + ' // Group 1: Computations and arrangements\n' + + ' s0 PUSH HASHCU // `data` hash\n' + + ' s2 PUSH HASHCU // `code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `code` depth\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + '\n' + + ' // Group 2: Composition of the Builder\n' + + ' NEWC\n' + + ' 24 STU // store refs_descriptor | bits_descriptor | data\n' + + ' 16 STU // store depth_descriptor for `code`\n' + + ' 16 STU // store depth_descriptor for `data`\n' + + ' 256 STU // store `code` hash\n' + + ' 256 STU // store `data` hash\n' + + '\n' + + ' // Group 3: SHA256 hash of the resulting Builder\n' + + ' ONE HASHEXT_SHA256\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + "/// Computes smart contract's `Address` in the `chain` ID using the contract's `code` and the contract's initial state `data`. Use the `initOf` expression to obtain the initial `code` and initial `data` of a given contract.\n" + + '///\n' + + '/// This function lets you specify arbitrary `chain` IDs, including the common -1 (masterchain) and 0 (basechain) ones.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let initPkg: StateInit = initOf SomeContract();\n' + + '/// let hereBeDragons: Address = contractAddressExt(0, initPkg.code, initPkg.data);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '/// * https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'inline fun contractAddressExt(chain: Int, code: Cell, data: Cell): Address {\n' + + ' let hash = contractHash(code, data);\n' + + ' return newAddress(chain, hash);\n' + + '}\n' + + '\n' + + '/// Struct containing the initial state, i.e. initial code and initial data of the given contract upon its deployment.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'struct StateInit {\n' + + ' /// Initial code of the contract (compiled bitcode)\n' + + ' code: Cell;\n' + + '\n' + + ' /// Initial data of the contract (parameters of `init()` function or contract parameters)\n' + + ' data: Cell;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.1.\n' + + '///\n' + + '/// Efficiently compares if the given address matches the basechain address of the contract.\n' + + '/// Returns true if addresses are the same, false otherwise.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let init = initOf SomeContract();\n' + + "/// init.hasSameBasechainAddress(sender()); // returns true if sender matches contract's basechain address\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// This function provides a gas-optimized implementation compared to direct address comparison:\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let init = initOf SomeContract();\n' + + '/// sender() == contractAddress(sender()); // less efficient approach\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// Note that this function works only for basechain addresses!\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddress\n' + + '///\n' + + 'inline extends fun hasSameBasechainAddress(self: StateInit, sender: Address): Bool {\n' + + ' let senderAddress = parseStdAddress(sender.asSlice()).address;\n' + + ' let baseAddress = contractBasechainAddress(self);\n' + + ' return baseAddress.hash!! == senderAddress;\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + "/// Computes smart contract's `Address` in the workchain ID 0 (basechain) using the `StateInit` `s` of the contract. Alias to `contractAddressExt(0, s.code, s.data)`.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let s: StateInit = initOf SomeContract();\n' + + '/// let foundMeSome: Address = contractAddress(s);\n' + + '/// let andSomeMore: Address = contractAddressExt(0, s.code, s.data);\n' + + '///\n' + + '/// foundMeSome == andSomeMore; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '/// * https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'inline fun contractAddress(s: StateInit): Address {\n' + + ' return contractAddressExt(0, s.code, s.data);\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Returns the address of the current smart contract as an `Address`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let meMyselfAndI: Address = myAddress();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#myaddress\n' + + '///\n' + + 'asm fun myAddress(): Address { MYADDR }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` balance of the smart contract as it was at the start of the compute phase of the current transaction.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let iNeedADolla: Int = myBalance();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#mybalance\n' + + '///\n' + + 'asm fun myBalance(): Int { BALANCE FIRST }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` amount of gas consumed by TVM in the current transaction so far. The resulting value includes the cost of calling this function.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let gas: Int = gasConsumed();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#gasconsumed\n' + + '///\n' + + 'asm fun gasConsumed(): Int { GASCONSUMED }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` amount of the accumulated storage fee debt. Storage fees are deducted from the incoming message value before the new contract balance is calculated.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let debt: Int = myStorageDue();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#mystoragedue\n' + + '///\n' + + 'asm fun myStorageDue(): Int { DUEPAYMENT }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Calculates and returns the storage fee in nanoToncoins `Int` for storing a contract with a given number of `cells` and `bits` for a number of `seconds`. Uses the prices of the masterchain if `isMasterchain` is `true`, otherwise the prices of the basechain. The current prices are obtained from the config param 18 of TON Blockchain.\n' + + '///\n' + + '/// Note, that specifying values of `cells` and `bits` higher than their maximum values listed in account state limits (`max_acc_state_cells` and `max_acc_state_bits`) will have the same result as with specifying the exact limits. In addition, make sure you take into account the deduplication of cells with the same hash.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fee: Int = getStorageFee(1_000, 1_000, 1_000, false);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify negative number of `cells`, `bits` or `seconds`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-gas#getstoragefee\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun getStorageFee(cells: Int, bits: Int, seconds: Int, isMasterchain: Bool): Int { GETSTORAGEFEE }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Calculates and returns the compute fee in nanoToncoins `Int` for a transaction that consumed `gasUsed` amount of gas. Uses the prices of the masterchain if `isMasterchain` is `true`, otherwise the prices of the basechain. The current prices are obtained from the config param 20 for the masterchain and config param 21 for the basechain of TON Blockchain.\n' + + '///\n' + + "/// When the `gasUsed` is less than a certain threshold called `flat_gas_limit`, there's a minimum price to pay based on the value of `flat_gas_price`. The less gas is used below this threshold, the higher the minimum price will be. See the example for `getSimpleComputeFee()` to derive that threshold.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fee: Int = getComputeFee(1_000, false);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify negative value of `gasUsed`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-gas#getcomputefee\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun getComputeFee(gasUsed: Int, isMasterchain: Bool): Int { GETGASFEE }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Similar to `getComputeFee()`, but without the `flat_gas_price`, i.e. without a minimum price to pay if the `gasUsed` is less than a certain '... 8611 more characters, + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'contractHash', + loc: { start: 1027, end: 1039 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1065, end: 1068 } + }, + loc: { start: 1065, end: 1068 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 1040, end: 1044 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 1046, end: 1050 } }, + loc: { start: 1046, end: 1050 } + }, + loc: { start: 1040, end: 1050 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'data', + loc: { start: 1052, end: 1056 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 1058, end: 1062 } }, + loc: { start: 1058, end: 1062 } + }, + loc: { start: 1052, end: 1062 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 's0 PUSH HASHCU // `data` hash\n' + + ' s2 PUSH HASHCU // `code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `code` depth\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + '\n' + + ' // Group 2: Composition of the Builder\n' + + ' NEWC\n' + + ' 24 STU // store refs_descriptor | bits_descriptor | data\n' + + ' 16 STU // store depth_descriptor for `code`\n' + + ' 16 STU // store depth_descriptor for `data`\n' + + ' 256 STU // store `code` hash\n' + + ' 256 STU // store `data` hash\n' + + '\n' + + ' // Group 3: SHA256 hash of the resulting Builder\n' + + ' ONE HASHEXT_SHA256' + ] + }, + loc: { start: 1019, end: 2666 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'contractAddressExt', + loc: { start: 3391, end: 3409 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3447, end: 3454 } + }, + typeArgs: [], + loc: { start: 3447, end: 3454 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'chain', + loc: { start: 3410, end: 3415 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3417, end: 3420 } + }, + loc: { start: 3417, end: 3420 } + }, + loc: { start: 3410, end: 3420 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 3422, end: 3426 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3428, end: 3432 } }, + loc: { start: 3428, end: 3432 } + }, + loc: { start: 3422, end: 3432 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'data', + loc: { start: 3434, end: 3438 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3440, end: 3444 } }, + loc: { start: 3440, end: 3444 } + }, + loc: { start: 3434, end: 3444 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'hash', + loc: { start: 3465, end: 3469 } + }, + type: undefined, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractHash', + loc: { start: 3472, end: 3484 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'code', + loc: { start: 3485, end: 3489 } + }, + { + kind: 'var', + name: 'data', + loc: { start: 3491, end: 3495 } + } + ], + loc: { start: 3472, end: 3496 } + }, + loc: { start: 3461, end: 3497 } + }, + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'newAddress', + loc: { start: 3509, end: 3519 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'chain', + loc: { start: 3520, end: 3525 } + }, + { + kind: 'var', + name: 'hash', + loc: { start: 3527, end: 3531 } + } + ], + loc: { start: 3509, end: 3532 } + }, + loc: { start: 3502, end: 3533 } + } + ] + }, + loc: { start: 3380, end: 3535 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 3731, end: 3740 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'code', + loc: { start: 3803, end: 3807 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3809, end: 3813 } }, + loc: { start: 3809, end: 3813 } + }, + initializer: undefined, + loc: { start: 3803, end: 3813 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'data', + loc: { start: 3914, end: 3918 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3920, end: 3924 } }, + loc: { start: 3920, end: 3924 } + }, + initializer: undefined, + loc: { start: 3914, end: 3924 } + } + ], + loc: { start: 3724, end: 3927 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'hasSameBasechainAddress', + loc: { start: 4778, end: 4801 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 4837, end: 4841 } + }, + typeArgs: [], + loc: { start: 4837, end: 4841 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'sender', + loc: { start: 4819, end: 4825 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 4827, end: 4834 } + }, + typeArgs: [], + loc: { start: 4827, end: 4834 } + }, + loc: { start: 4819, end: 4834 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'senderAddress', + loc: { start: 4852, end: 4865 } + }, + type: undefined, + expression: { + kind: 'field_access', + aggregate: { + kind: 'static_call', + function: { + kind: 'id', + text: 'parseStdAddress', + loc: { start: 4868, end: 4883 } + }, + typeArgs: [], + args: [ + { + kind: 'method_call', + self: { + kind: 'var', + name: 'sender', + loc: { start: 4884, end: 4890 } + }, + method: { + kind: 'id', + text: 'asSlice', + loc: { start: 4891, end: 4898 } + }, + typeArgs: [], + args: [], + loc: { start: 4884, end: 4900 } + } + ], + loc: { start: 4868, end: 4901 } + }, + field: { + kind: 'id', + text: 'address', + loc: { start: 4902, end: 4909 } + }, + loc: { start: 4868, end: 4909 } + }, + loc: { start: 4848, end: 4910 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'baseAddress', + loc: { start: 4919, end: 4930 } + }, + type: undefined, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractBasechainAddress', + loc: { start: 4933, end: 4957 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'self', + loc: { start: 4958, end: 4962 } + } + ], + loc: { start: 4933, end: 4963 } + }, + loc: { start: 4915, end: 4964 } + }, + { + kind: 'statement_return', + expression: { + kind: 'op_binary', + op: '==', + left: { + kind: 'op_unary', + op: '!!', + operand: { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'baseAddress', + loc: { start: 4976, end: 4987 } + }, + field: { + kind: 'id', + text: 'hash', + loc: { start: 4988, end: 4992 } + }, + loc: { start: 4976, end: 4992 } + }, + loc: { start: 4976, end: 4994 } + }, + right: { + kind: 'var', + name: 'senderAddress', + loc: { start: 4998, end: 5011 } + }, + loc: { start: 4976, end: 5011 } + }, + loc: { start: 4969, end: 5012 } + } + ] + }, + loc: { start: 4759, end: 5014 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 4808, end: 4817 } + }, + typeArgs: [], + loc: { start: 4808, end: 4817 } + } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'contractAddress', + loc: { start: 5709, end: 5724 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 5740, end: 5747 } + }, + typeArgs: [], + loc: { start: 5740, end: 5747 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 's', + loc: { start: 5725, end: 5726 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 5728, end: 5737 } + }, + typeArgs: [], + loc: { start: 5728, end: 5737 } + }, + loc: { start: 5725, end: 5737 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractAddressExt', + loc: { start: 5761, end: 5779 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 5780, end: 5781 } + }, + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 5783, end: 5784 } + }, + field: { + kind: 'id', + text: 'code', + loc: { start: 5785, end: 5789 } + }, + loc: { start: 5783, end: 5789 } + }, + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 5791, end: 5792 } + }, + field: { + kind: 'id', + text: 'data', + loc: { start: 5793, end: 5797 } + }, + loc: { start: 5791, end: 5797 } + } + ], + loc: { start: 5761, end: 5798 } + }, + loc: { start: 5754, end: 5799 } + } + ] + }, + loc: { start: 5698, end: 5801 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myAddress', + loc: { start: 6082, end: 6091 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 6095, end: 6102 } + }, + typeArgs: [], + loc: { start: 6095, end: 6102 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MYADDR' ] + }, + loc: { start: 6074, end: 6113 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myBalance', + loc: { start: 6454, end: 6463 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6467, end: 6470 } + }, + loc: { start: 6467, end: 6470 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'BALANCE FIRST' ] + }, + loc: { start: 6446, end: 6488 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'gasConsumed', + loc: { start: 6880, end: 6891 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6895, end: 6898 } + }, + loc: { start: 6895, end: 6898 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GASCONSUMED' ] + }, + loc: { start: 6872, end: 6914 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myStorageDue', + loc: { start: 7329, end: 7341 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7345, end: 7348 } + }, + loc: { start: 7345, end: 7348 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DUEPAYMENT' ] + }, + loc: { start: 7321, end: 7363 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getStorageFee', + loc: { start: 8517, end: 8530 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8590, end: 8593 } + }, + loc: { start: 8590, end: 8593 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 8531, end: 8536 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8538, end: 8541 } + }, + loc: { start: 8538, end: 8541 } + }, + loc: { start: 8531, end: 8541 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 8543, end: 8547 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8549, end: 8552 } + }, + loc: { start: 8549, end: 8552 } + }, + loc: { start: 8543, end: 8552 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'seconds', + loc: { start: 8554, end: 8561 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8563, end: 8566 } + }, + loc: { start: 8563, end: 8566 } + }, + loc: { start: 8554, end: 8566 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 8568, end: 8581 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 8583, end: 8587 } + }, + typeArgs: [], + loc: { start: 8583, end: 8587 } + }, + loc: { start: 8568, end: 8587 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETSTORAGEFEE' ] + }, + loc: { start: 8509, end: 8611 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getComputeFee', + loc: { start: 9734, end: 9747 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9784, end: 9787 } + }, + loc: { start: 9784, end: 9787 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'gasUsed', + loc: { start: 9748, end: 9755 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9757, end: 9760 } + }, + loc: { start: 9757, end: 9760 } + }, + loc: { start: 9748, end: 9760 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 9762, end: 9775 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 9777, end: 9781 } + }, + typeArgs: [], + loc: { start: 9777, end: 9781 } + }, + loc: { start: 9762, end: 9781 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETGASFEE' ] + }, + loc: { start: 9726, end: 9801 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSimpleComputeFee', + loc: { start: 10689, end: 10708 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10745, end: 10748 } + }, + loc: { start: 10745, end: 10748 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'gasUsed', + loc: { start: 10709, end: 10716 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10718, end: 10721 } + }, + loc: { start: 10718, end: 10721 } + }, + loc: { start: 10709, end: 10721 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 10723, end: 10736 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 10738, end: 10742 } + }, + typeArgs: [], + loc: { start: 10738, end: 10742 } + }, + loc: { start: 10723, end: 10742 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETGASFEESIMPLE' ] + }, + loc: { start: 10681, end: 10768 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getForwardFee', + loc: { start: 12543, end: 12556 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12602, end: 12605 } + }, + loc: { start: 12602, end: 12605 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 12557, end: 12562 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12564, end: 12567 } + }, + loc: { start: 12564, end: 12567 } + }, + loc: { start: 12557, end: 12567 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 12569, end: 12573 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12575, end: 12578 } + }, + loc: { start: 12575, end: 12578 } + }, + loc: { start: 12569, end: 12578 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 12580, end: 12593 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 12595, end: 12599 } + }, + typeArgs: [], + loc: { start: 12595, end: 12599 } + }, + loc: { start: 12580, end: 12599 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETFORWARDFEE' ] + }, + loc: { start: 12535, end: 12623 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSimpleForwardFee', + loc: { start: 13528, end: 13547 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13593, end: 13596 } + }, + loc: { start: 13593, end: 13596 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 13548, end: 13553 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13555, end: 13558 } + }, + loc: { start: 13555, end: 13558 } + }, + loc: { start: 13548, end: 13558 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 13560, end: 13564 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13566, end: 13569 } + }, + loc: { start: 13566, end: 13569 } + }, + loc: { start: 13560, end: 13569 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 13571, end: 13584 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 13586, end: 13590 } + }, + typeArgs: [], + loc: { start: 13586, end: 13590 } + }, + loc: { start: 13571, end: 13590 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETFORWARDFEESIMPLE' ] + }, + loc: { start: 13520, end: 13620 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getOriginalFwdFee', + loc: { start: 15782, end: 15799 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15835, end: 15838 } + }, + loc: { start: 15835, end: 15838 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'fwdFee', + loc: { start: 15800, end: 15806 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15808, end: 15811 } + }, + loc: { start: 15808, end: 15811 } + }, + loc: { start: 15800, end: 15811 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 15813, end: 15826 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 15828, end: 15832 } + }, + typeArgs: [], + loc: { start: 15828, end: 15832 } + }, + loc: { start: 15813, end: 15832 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETORIGINALFWDFEE' ] + }, + loc: { start: 15774, end: 15860 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'setGasLimit', + loc: { start: 16541, end: 16552 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'limit', + loc: { start: 16553, end: 16558 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 16560, end: 16563 } + }, + loc: { start: 16560, end: 16563 } + }, + loc: { start: 16553, end: 16563 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SETGASLIMIT' ] + }, + loc: { start: 16533, end: 16580 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSeed', + loc: { start: 17350, end: 17357 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 17361, end: 17364 } + }, + loc: { start: 17361, end: 17364 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RANDSEED' ] + }, + loc: { start: 17342, end: 17377 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'setSeed', + loc: { start: 18258, end: 18265 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'seed', + loc: { start: 18266, end: 18270 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 18272, end: 18275 } + }, + loc: { start: 18272, end: 18275 } + }, + loc: { start: 18266, end: 18275 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SETRAND' ] + }, + loc: { start: 18250, end: 18288 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myCode', + loc: { start: 18585, end: 18591 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 18595, end: 18599 } }, + loc: { start: 18595, end: 18599 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MYCODE' ] + }, + loc: { start: 18577, end: 18610 } + } + ] + }, + 'getOriginalFwdFee' => { + kind: 'tact', + path: 'std/internal/contract.tact', + code: '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Computes and returns an `Int` value of the SHA-256 hash of the `code` and `data` of the given contract. To assemble the `code` and `data` cells together for hashing, the standard `Cell` representation is used.\n' + + '///\n' + + '/// This hash is commonly called account ID. Together with the workchain ID it deterministically forms the address of the contract on TON Blockchain.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let initPkg: StateInit = initOf SomeContract();\n' + + '/// let accountId: Int = contractHash(initPkg.code, initPkg.data);\n' + + '/// let basechainAddr: Address = newAddress(0, accountId);\n' + + '/// let basechainAddr2: Address = contractAddressExt(0, initPkg.code, initPkg.data);\n' + + '///\n' + + '/// basechainAddr == basechainAddr2; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contracthash\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#newaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '///\n' + + 'asm fun contractHash(code: Cell, data: Cell): Int {\n' + + ' // According to the https://docs.tact-lang.org/book/cells#cells-representation,\n' + + ' // the layout for the Builder to hash goes as follows:\n' + + ' // 1) refs_descriptor:bits8 | bits_descriptor:bits8 | data:bitsN\n' + + ' //\n' + + ' // refs_descriptor: ref_count + ((exotic? & 1) * 8) + (mask * 32)\n' + + ' // 2 refs (code + data), non-exotic, zero-mask\n' + + ' //\n' + + ' // bits_descriptor: floor(bit_count / 8) + ceil(bit_count, 8)\n' + + ' // floor (5 bits / 8) + ceil(5 bits / 8) = 0 + 1 = 1\n' + + ' //\n' + + ' // data: [0b00110] + [0b100] = [0b00110100] = 0x34 (data + augmented bits)\n' + + ' // 0b00110 - data (split_depth, special, code, data, Library)\n' + + ' // 0b100 - augmented bits (Leading 1 + zeroes to make section multiple of eight)\n' + + ' //\n' + + ' // That is: (2 << 16) | (1 << 8) | 0x34 = 131380 for all three.\n' + + ' //\n' + + ' // 2) and 3) depth_descriptors: CDEPTH of `code` and CDEPTH of `data`\n' + + ' // 4) and 5) ref hashes: HASHCU of `code` and HASHCU of `data`\n' + + '\n' + + ' // Group 1: Computations and arrangements\n' + + ' s0 PUSH HASHCU // `data` hash\n' + + ' s2 PUSH HASHCU // `code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `code` depth\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + '\n' + + ' // Group 2: Composition of the Builder\n' + + ' NEWC\n' + + ' 24 STU // store refs_descriptor | bits_descriptor | data\n' + + ' 16 STU // store depth_descriptor for `code`\n' + + ' 16 STU // store depth_descriptor for `data`\n' + + ' 256 STU // store `code` hash\n' + + ' 256 STU // store `data` hash\n' + + '\n' + + ' // Group 3: SHA256 hash of the resulting Builder\n' + + ' ONE HASHEXT_SHA256\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + "/// Computes smart contract's `Address` in the `chain` ID using the contract's `code` and the contract's initial state `data`. Use the `initOf` expression to obtain the initial `code` and initial `data` of a given contract.\n" + + '///\n' + + '/// This function lets you specify arbitrary `chain` IDs, including the common -1 (masterchain) and 0 (basechain) ones.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let initPkg: StateInit = initOf SomeContract();\n' + + '/// let hereBeDragons: Address = contractAddressExt(0, initPkg.code, initPkg.data);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '/// * https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'inline fun contractAddressExt(chain: Int, code: Cell, data: Cell): Address {\n' + + ' let hash = contractHash(code, data);\n' + + ' return newAddress(chain, hash);\n' + + '}\n' + + '\n' + + '/// Struct containing the initial state, i.e. initial code and initial data of the given contract upon its deployment.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'struct StateInit {\n' + + ' /// Initial code of the contract (compiled bitcode)\n' + + ' code: Cell;\n' + + '\n' + + ' /// Initial data of the contract (parameters of `init()` function or contract parameters)\n' + + ' data: Cell;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.1.\n' + + '///\n' + + '/// Efficiently compares if the given address matches the basechain address of the contract.\n' + + '/// Returns true if addresses are the same, false otherwise.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let init = initOf SomeContract();\n' + + "/// init.hasSameBasechainAddress(sender()); // returns true if sender matches contract's basechain address\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// This function provides a gas-optimized implementation compared to direct address comparison:\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let init = initOf SomeContract();\n' + + '/// sender() == contractAddress(sender()); // less efficient approach\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// Note that this function works only for basechain addresses!\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddress\n' + + '///\n' + + 'inline extends fun hasSameBasechainAddress(self: StateInit, sender: Address): Bool {\n' + + ' let senderAddress = parseStdAddress(sender.asSlice()).address;\n' + + ' let baseAddress = contractBasechainAddress(self);\n' + + ' return baseAddress.hash!! == senderAddress;\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + "/// Computes smart contract's `Address` in the workchain ID 0 (basechain) using the `StateInit` `s` of the contract. Alias to `contractAddressExt(0, s.code, s.data)`.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let s: StateInit = initOf SomeContract();\n' + + '/// let foundMeSome: Address = contractAddress(s);\n' + + '/// let andSomeMore: Address = contractAddressExt(0, s.code, s.data);\n' + + '///\n' + + '/// foundMeSome == andSomeMore; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '/// * https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'inline fun contractAddress(s: StateInit): Address {\n' + + ' return contractAddressExt(0, s.code, s.data);\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Returns the address of the current smart contract as an `Address`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let meMyselfAndI: Address = myAddress();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#myaddress\n' + + '///\n' + + 'asm fun myAddress(): Address { MYADDR }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` balance of the smart contract as it was at the start of the compute phase of the current transaction.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let iNeedADolla: Int = myBalance();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#mybalance\n' + + '///\n' + + 'asm fun myBalance(): Int { BALANCE FIRST }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` amount of gas consumed by TVM in the current transaction so far. The resulting value includes the cost of calling this function.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let gas: Int = gasConsumed();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#gasconsumed\n' + + '///\n' + + 'asm fun gasConsumed(): Int { GASCONSUMED }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` amount of the accumulated storage fee debt. Storage fees are deducted from the incoming message value before the new contract balance is calculated.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let debt: Int = myStorageDue();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#mystoragedue\n' + + '///\n' + + 'asm fun myStorageDue(): Int { DUEPAYMENT }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Calculates and returns the storage fee in nanoToncoins `Int` for storing a contract with a given number of `cells` and `bits` for a number of `seconds`. Uses the prices of the masterchain if `isMasterchain` is `true`, otherwise the prices of the basechain. The current prices are obtained from the config param 18 of TON Blockchain.\n' + + '///\n' + + '/// Note, that specifying values of `cells` and `bits` higher than their maximum values listed in account state limits (`max_acc_state_cells` and `max_acc_state_bits`) will have the same result as with specifying the exact limits. In addition, make sure you take into account the deduplication of cells with the same hash.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fee: Int = getStorageFee(1_000, 1_000, 1_000, false);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify negative number of `cells`, `bits` or `seconds`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-gas#getstoragefee\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun getStorageFee(cells: Int, bits: Int, seconds: Int, isMasterchain: Bool): Int { GETSTORAGEFEE }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Calculates and returns the compute fee in nanoToncoins `Int` for a transaction that consumed `gasUsed` amount of gas. Uses the prices of the masterchain if `isMasterchain` is `true`, otherwise the prices of the basechain. The current prices are obtained from the config param 20 for the masterchain and config param 21 for the basechain of TON Blockchain.\n' + + '///\n' + + "/// When the `gasUsed` is less than a certain threshold called `flat_gas_limit`, there's a minimum price to pay based on the value of `flat_gas_price`. The less gas is used below this threshold, the higher the minimum price will be. See the example for `getSimpleComputeFee()` to derive that threshold.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fee: Int = getComputeFee(1_000, false);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify negative value of `gasUsed`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-gas#getcomputefee\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun getComputeFee(gasUsed: Int, isMasterchain: Bool): Int { GETGASFEE }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Similar to `getComputeFee()`, but without the `flat_gas_price`, i.e. without a minimum price to pay if the `gasUsed` is less than a certain '... 8611 more characters, + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'contractHash', + loc: { start: 1027, end: 1039 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1065, end: 1068 } + }, + loc: { start: 1065, end: 1068 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 1040, end: 1044 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 1046, end: 1050 } }, + loc: { start: 1046, end: 1050 } + }, + loc: { start: 1040, end: 1050 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'data', + loc: { start: 1052, end: 1056 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 1058, end: 1062 } }, + loc: { start: 1058, end: 1062 } + }, + loc: { start: 1052, end: 1062 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 's0 PUSH HASHCU // `data` hash\n' + + ' s2 PUSH HASHCU // `code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `code` depth\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + '\n' + + ' // Group 2: Composition of the Builder\n' + + ' NEWC\n' + + ' 24 STU // store refs_descriptor | bits_descriptor | data\n' + + ' 16 STU // store depth_descriptor for `code`\n' + + ' 16 STU // store depth_descriptor for `data`\n' + + ' 256 STU // store `code` hash\n' + + ' 256 STU // store `data` hash\n' + + '\n' + + ' // Group 3: SHA256 hash of the resulting Builder\n' + + ' ONE HASHEXT_SHA256' + ] + }, + loc: { start: 1019, end: 2666 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'contractAddressExt', + loc: { start: 3391, end: 3409 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3447, end: 3454 } + }, + typeArgs: [], + loc: { start: 3447, end: 3454 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'chain', + loc: { start: 3410, end: 3415 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3417, end: 3420 } + }, + loc: { start: 3417, end: 3420 } + }, + loc: { start: 3410, end: 3420 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 3422, end: 3426 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3428, end: 3432 } }, + loc: { start: 3428, end: 3432 } + }, + loc: { start: 3422, end: 3432 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'data', + loc: { start: 3434, end: 3438 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3440, end: 3444 } }, + loc: { start: 3440, end: 3444 } + }, + loc: { start: 3434, end: 3444 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'hash', + loc: { start: 3465, end: 3469 } + }, + type: undefined, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractHash', + loc: { start: 3472, end: 3484 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'code', + loc: { start: 3485, end: 3489 } + }, + { + kind: 'var', + name: 'data', + loc: { start: 3491, end: 3495 } + } + ], + loc: { start: 3472, end: 3496 } + }, + loc: { start: 3461, end: 3497 } + }, + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'newAddress', + loc: { start: 3509, end: 3519 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'chain', + loc: { start: 3520, end: 3525 } + }, + { + kind: 'var', + name: 'hash', + loc: { start: 3527, end: 3531 } + } + ], + loc: { start: 3509, end: 3532 } + }, + loc: { start: 3502, end: 3533 } + } + ] + }, + loc: { start: 3380, end: 3535 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 3731, end: 3740 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'code', + loc: { start: 3803, end: 3807 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3809, end: 3813 } }, + loc: { start: 3809, end: 3813 } + }, + initializer: undefined, + loc: { start: 3803, end: 3813 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'data', + loc: { start: 3914, end: 3918 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3920, end: 3924 } }, + loc: { start: 3920, end: 3924 } + }, + initializer: undefined, + loc: { start: 3914, end: 3924 } + } + ], + loc: { start: 3724, end: 3927 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'hasSameBasechainAddress', + loc: { start: 4778, end: 4801 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 4837, end: 4841 } + }, + typeArgs: [], + loc: { start: 4837, end: 4841 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'sender', + loc: { start: 4819, end: 4825 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 4827, end: 4834 } + }, + typeArgs: [], + loc: { start: 4827, end: 4834 } + }, + loc: { start: 4819, end: 4834 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'senderAddress', + loc: { start: 4852, end: 4865 } + }, + type: undefined, + expression: { + kind: 'field_access', + aggregate: { + kind: 'static_call', + function: { + kind: 'id', + text: 'parseStdAddress', + loc: { start: 4868, end: 4883 } + }, + typeArgs: [], + args: [ + { + kind: 'method_call', + self: { + kind: 'var', + name: 'sender', + loc: { start: 4884, end: 4890 } + }, + method: { + kind: 'id', + text: 'asSlice', + loc: { start: 4891, end: 4898 } + }, + typeArgs: [], + args: [], + loc: { start: 4884, end: 4900 } + } + ], + loc: { start: 4868, end: 4901 } + }, + field: { + kind: 'id', + text: 'address', + loc: { start: 4902, end: 4909 } + }, + loc: { start: 4868, end: 4909 } + }, + loc: { start: 4848, end: 4910 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'baseAddress', + loc: { start: 4919, end: 4930 } + }, + type: undefined, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractBasechainAddress', + loc: { start: 4933, end: 4957 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'self', + loc: { start: 4958, end: 4962 } + } + ], + loc: { start: 4933, end: 4963 } + }, + loc: { start: 4915, end: 4964 } + }, + { + kind: 'statement_return', + expression: { + kind: 'op_binary', + op: '==', + left: { + kind: 'op_unary', + op: '!!', + operand: { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'baseAddress', + loc: { start: 4976, end: 4987 } + }, + field: { + kind: 'id', + text: 'hash', + loc: { start: 4988, end: 4992 } + }, + loc: { start: 4976, end: 4992 } + }, + loc: { start: 4976, end: 4994 } + }, + right: { + kind: 'var', + name: 'senderAddress', + loc: { start: 4998, end: 5011 } + }, + loc: { start: 4976, end: 5011 } + }, + loc: { start: 4969, end: 5012 } + } + ] + }, + loc: { start: 4759, end: 5014 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 4808, end: 4817 } + }, + typeArgs: [], + loc: { start: 4808, end: 4817 } + } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'contractAddress', + loc: { start: 5709, end: 5724 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 5740, end: 5747 } + }, + typeArgs: [], + loc: { start: 5740, end: 5747 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 's', + loc: { start: 5725, end: 5726 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 5728, end: 5737 } + }, + typeArgs: [], + loc: { start: 5728, end: 5737 } + }, + loc: { start: 5725, end: 5737 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractAddressExt', + loc: { start: 5761, end: 5779 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 5780, end: 5781 } + }, + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 5783, end: 5784 } + }, + field: { + kind: 'id', + text: 'code', + loc: { start: 5785, end: 5789 } + }, + loc: { start: 5783, end: 5789 } + }, + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 5791, end: 5792 } + }, + field: { + kind: 'id', + text: 'data', + loc: { start: 5793, end: 5797 } + }, + loc: { start: 5791, end: 5797 } + } + ], + loc: { start: 5761, end: 5798 } + }, + loc: { start: 5754, end: 5799 } + } + ] + }, + loc: { start: 5698, end: 5801 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myAddress', + loc: { start: 6082, end: 6091 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 6095, end: 6102 } + }, + typeArgs: [], + loc: { start: 6095, end: 6102 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MYADDR' ] + }, + loc: { start: 6074, end: 6113 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myBalance', + loc: { start: 6454, end: 6463 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6467, end: 6470 } + }, + loc: { start: 6467, end: 6470 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'BALANCE FIRST' ] + }, + loc: { start: 6446, end: 6488 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'gasConsumed', + loc: { start: 6880, end: 6891 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6895, end: 6898 } + }, + loc: { start: 6895, end: 6898 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GASCONSUMED' ] + }, + loc: { start: 6872, end: 6914 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myStorageDue', + loc: { start: 7329, end: 7341 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7345, end: 7348 } + }, + loc: { start: 7345, end: 7348 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DUEPAYMENT' ] + }, + loc: { start: 7321, end: 7363 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getStorageFee', + loc: { start: 8517, end: 8530 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8590, end: 8593 } + }, + loc: { start: 8590, end: 8593 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 8531, end: 8536 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8538, end: 8541 } + }, + loc: { start: 8538, end: 8541 } + }, + loc: { start: 8531, end: 8541 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 8543, end: 8547 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8549, end: 8552 } + }, + loc: { start: 8549, end: 8552 } + }, + loc: { start: 8543, end: 8552 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'seconds', + loc: { start: 8554, end: 8561 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8563, end: 8566 } + }, + loc: { start: 8563, end: 8566 } + }, + loc: { start: 8554, end: 8566 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 8568, end: 8581 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 8583, end: 8587 } + }, + typeArgs: [], + loc: { start: 8583, end: 8587 } + }, + loc: { start: 8568, end: 8587 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETSTORAGEFEE' ] + }, + loc: { start: 8509, end: 8611 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getComputeFee', + loc: { start: 9734, end: 9747 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9784, end: 9787 } + }, + loc: { start: 9784, end: 9787 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'gasUsed', + loc: { start: 9748, end: 9755 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9757, end: 9760 } + }, + loc: { start: 9757, end: 9760 } + }, + loc: { start: 9748, end: 9760 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 9762, end: 9775 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 9777, end: 9781 } + }, + typeArgs: [], + loc: { start: 9777, end: 9781 } + }, + loc: { start: 9762, end: 9781 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETGASFEE' ] + }, + loc: { start: 9726, end: 9801 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSimpleComputeFee', + loc: { start: 10689, end: 10708 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10745, end: 10748 } + }, + loc: { start: 10745, end: 10748 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'gasUsed', + loc: { start: 10709, end: 10716 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10718, end: 10721 } + }, + loc: { start: 10718, end: 10721 } + }, + loc: { start: 10709, end: 10721 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 10723, end: 10736 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 10738, end: 10742 } + }, + typeArgs: [], + loc: { start: 10738, end: 10742 } + }, + loc: { start: 10723, end: 10742 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETGASFEESIMPLE' ] + }, + loc: { start: 10681, end: 10768 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getForwardFee', + loc: { start: 12543, end: 12556 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12602, end: 12605 } + }, + loc: { start: 12602, end: 12605 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 12557, end: 12562 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12564, end: 12567 } + }, + loc: { start: 12564, end: 12567 } + }, + loc: { start: 12557, end: 12567 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 12569, end: 12573 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12575, end: 12578 } + }, + loc: { start: 12575, end: 12578 } + }, + loc: { start: 12569, end: 12578 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 12580, end: 12593 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 12595, end: 12599 } + }, + typeArgs: [], + loc: { start: 12595, end: 12599 } + }, + loc: { start: 12580, end: 12599 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETFORWARDFEE' ] + }, + loc: { start: 12535, end: 12623 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSimpleForwardFee', + loc: { start: 13528, end: 13547 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13593, end: 13596 } + }, + loc: { start: 13593, end: 13596 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 13548, end: 13553 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13555, end: 13558 } + }, + loc: { start: 13555, end: 13558 } + }, + loc: { start: 13548, end: 13558 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 13560, end: 13564 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13566, end: 13569 } + }, + loc: { start: 13566, end: 13569 } + }, + loc: { start: 13560, end: 13569 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 13571, end: 13584 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 13586, end: 13590 } + }, + typeArgs: [], + loc: { start: 13586, end: 13590 } + }, + loc: { start: 13571, end: 13590 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETFORWARDFEESIMPLE' ] + }, + loc: { start: 13520, end: 13620 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getOriginalFwdFee', + loc: { start: 15782, end: 15799 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15835, end: 15838 } + }, + loc: { start: 15835, end: 15838 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'fwdFee', + loc: { start: 15800, end: 15806 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15808, end: 15811 } + }, + loc: { start: 15808, end: 15811 } + }, + loc: { start: 15800, end: 15811 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 15813, end: 15826 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 15828, end: 15832 } + }, + typeArgs: [], + loc: { start: 15828, end: 15832 } + }, + loc: { start: 15813, end: 15832 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETORIGINALFWDFEE' ] + }, + loc: { start: 15774, end: 15860 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'setGasLimit', + loc: { start: 16541, end: 16552 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'limit', + loc: { start: 16553, end: 16558 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 16560, end: 16563 } + }, + loc: { start: 16560, end: 16563 } + }, + loc: { start: 16553, end: 16563 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SETGASLIMIT' ] + }, + loc: { start: 16533, end: 16580 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSeed', + loc: { start: 17350, end: 17357 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 17361, end: 17364 } + }, + loc: { start: 17361, end: 17364 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RANDSEED' ] + }, + loc: { start: 17342, end: 17377 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'setSeed', + loc: { start: 18258, end: 18265 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'seed', + loc: { start: 18266, end: 18270 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 18272, end: 18275 } + }, + loc: { start: 18272, end: 18275 } + }, + loc: { start: 18266, end: 18275 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SETRAND' ] + }, + loc: { start: 18250, end: 18288 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myCode', + loc: { start: 18585, end: 18591 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 18595, end: 18599 } }, + loc: { start: 18595, end: 18599 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MYCODE' ] + }, + loc: { start: 18577, end: 18610 } + } + ] + }, + 'setGasLimit' => { + kind: 'tact', + path: 'std/internal/contract.tact', + code: '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Computes and returns an `Int` value of the SHA-256 hash of the `code` and `data` of the given contract. To assemble the `code` and `data` cells together for hashing, the standard `Cell` representation is used.\n' + + '///\n' + + '/// This hash is commonly called account ID. Together with the workchain ID it deterministically forms the address of the contract on TON Blockchain.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let initPkg: StateInit = initOf SomeContract();\n' + + '/// let accountId: Int = contractHash(initPkg.code, initPkg.data);\n' + + '/// let basechainAddr: Address = newAddress(0, accountId);\n' + + '/// let basechainAddr2: Address = contractAddressExt(0, initPkg.code, initPkg.data);\n' + + '///\n' + + '/// basechainAddr == basechainAddr2; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contracthash\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#newaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '///\n' + + 'asm fun contractHash(code: Cell, data: Cell): Int {\n' + + ' // According to the https://docs.tact-lang.org/book/cells#cells-representation,\n' + + ' // the layout for the Builder to hash goes as follows:\n' + + ' // 1) refs_descriptor:bits8 | bits_descriptor:bits8 | data:bitsN\n' + + ' //\n' + + ' // refs_descriptor: ref_count + ((exotic? & 1) * 8) + (mask * 32)\n' + + ' // 2 refs (code + data), non-exotic, zero-mask\n' + + ' //\n' + + ' // bits_descriptor: floor(bit_count / 8) + ceil(bit_count, 8)\n' + + ' // floor (5 bits / 8) + ceil(5 bits / 8) = 0 + 1 = 1\n' + + ' //\n' + + ' // data: [0b00110] + [0b100] = [0b00110100] = 0x34 (data + augmented bits)\n' + + ' // 0b00110 - data (split_depth, special, code, data, Library)\n' + + ' // 0b100 - augmented bits (Leading 1 + zeroes to make section multiple of eight)\n' + + ' //\n' + + ' // That is: (2 << 16) | (1 << 8) | 0x34 = 131380 for all three.\n' + + ' //\n' + + ' // 2) and 3) depth_descriptors: CDEPTH of `code` and CDEPTH of `data`\n' + + ' // 4) and 5) ref hashes: HASHCU of `code` and HASHCU of `data`\n' + + '\n' + + ' // Group 1: Computations and arrangements\n' + + ' s0 PUSH HASHCU // `data` hash\n' + + ' s2 PUSH HASHCU // `code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `code` depth\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + '\n' + + ' // Group 2: Composition of the Builder\n' + + ' NEWC\n' + + ' 24 STU // store refs_descriptor | bits_descriptor | data\n' + + ' 16 STU // store depth_descriptor for `code`\n' + + ' 16 STU // store depth_descriptor for `data`\n' + + ' 256 STU // store `code` hash\n' + + ' 256 STU // store `data` hash\n' + + '\n' + + ' // Group 3: SHA256 hash of the resulting Builder\n' + + ' ONE HASHEXT_SHA256\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + "/// Computes smart contract's `Address` in the `chain` ID using the contract's `code` and the contract's initial state `data`. Use the `initOf` expression to obtain the initial `code` and initial `data` of a given contract.\n" + + '///\n' + + '/// This function lets you specify arbitrary `chain` IDs, including the common -1 (masterchain) and 0 (basechain) ones.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let initPkg: StateInit = initOf SomeContract();\n' + + '/// let hereBeDragons: Address = contractAddressExt(0, initPkg.code, initPkg.data);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '/// * https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'inline fun contractAddressExt(chain: Int, code: Cell, data: Cell): Address {\n' + + ' let hash = contractHash(code, data);\n' + + ' return newAddress(chain, hash);\n' + + '}\n' + + '\n' + + '/// Struct containing the initial state, i.e. initial code and initial data of the given contract upon its deployment.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'struct StateInit {\n' + + ' /// Initial code of the contract (compiled bitcode)\n' + + ' code: Cell;\n' + + '\n' + + ' /// Initial data of the contract (parameters of `init()` function or contract parameters)\n' + + ' data: Cell;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.1.\n' + + '///\n' + + '/// Efficiently compares if the given address matches the basechain address of the contract.\n' + + '/// Returns true if addresses are the same, false otherwise.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let init = initOf SomeContract();\n' + + "/// init.hasSameBasechainAddress(sender()); // returns true if sender matches contract's basechain address\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// This function provides a gas-optimized implementation compared to direct address comparison:\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let init = initOf SomeContract();\n' + + '/// sender() == contractAddress(sender()); // less efficient approach\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// Note that this function works only for basechain addresses!\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddress\n' + + '///\n' + + 'inline extends fun hasSameBasechainAddress(self: StateInit, sender: Address): Bool {\n' + + ' let senderAddress = parseStdAddress(sender.asSlice()).address;\n' + + ' let baseAddress = contractBasechainAddress(self);\n' + + ' return baseAddress.hash!! == senderAddress;\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + "/// Computes smart contract's `Address` in the workchain ID 0 (basechain) using the `StateInit` `s` of the contract. Alias to `contractAddressExt(0, s.code, s.data)`.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let s: StateInit = initOf SomeContract();\n' + + '/// let foundMeSome: Address = contractAddress(s);\n' + + '/// let andSomeMore: Address = contractAddressExt(0, s.code, s.data);\n' + + '///\n' + + '/// foundMeSome == andSomeMore; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '/// * https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'inline fun contractAddress(s: StateInit): Address {\n' + + ' return contractAddressExt(0, s.code, s.data);\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Returns the address of the current smart contract as an `Address`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let meMyselfAndI: Address = myAddress();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#myaddress\n' + + '///\n' + + 'asm fun myAddress(): Address { MYADDR }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` balance of the smart contract as it was at the start of the compute phase of the current transaction.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let iNeedADolla: Int = myBalance();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#mybalance\n' + + '///\n' + + 'asm fun myBalance(): Int { BALANCE FIRST }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` amount of gas consumed by TVM in the current transaction so far. The resulting value includes the cost of calling this function.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let gas: Int = gasConsumed();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#gasconsumed\n' + + '///\n' + + 'asm fun gasConsumed(): Int { GASCONSUMED }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` amount of the accumulated storage fee debt. Storage fees are deducted from the incoming message value before the new contract balance is calculated.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let debt: Int = myStorageDue();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#mystoragedue\n' + + '///\n' + + 'asm fun myStorageDue(): Int { DUEPAYMENT }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Calculates and returns the storage fee in nanoToncoins `Int` for storing a contract with a given number of `cells` and `bits` for a number of `seconds`. Uses the prices of the masterchain if `isMasterchain` is `true`, otherwise the prices of the basechain. The current prices are obtained from the config param 18 of TON Blockchain.\n' + + '///\n' + + '/// Note, that specifying values of `cells` and `bits` higher than their maximum values listed in account state limits (`max_acc_state_cells` and `max_acc_state_bits`) will have the same result as with specifying the exact limits. In addition, make sure you take into account the deduplication of cells with the same hash.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fee: Int = getStorageFee(1_000, 1_000, 1_000, false);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify negative number of `cells`, `bits` or `seconds`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-gas#getstoragefee\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun getStorageFee(cells: Int, bits: Int, seconds: Int, isMasterchain: Bool): Int { GETSTORAGEFEE }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Calculates and returns the compute fee in nanoToncoins `Int` for a transaction that consumed `gasUsed` amount of gas. Uses the prices of the masterchain if `isMasterchain` is `true`, otherwise the prices of the basechain. The current prices are obtained from the config param 20 for the masterchain and config param 21 for the basechain of TON Blockchain.\n' + + '///\n' + + "/// When the `gasUsed` is less than a certain threshold called `flat_gas_limit`, there's a minimum price to pay based on the value of `flat_gas_price`. The less gas is used below this threshold, the higher the minimum price will be. See the example for `getSimpleComputeFee()` to derive that threshold.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fee: Int = getComputeFee(1_000, false);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify negative value of `gasUsed`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-gas#getcomputefee\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun getComputeFee(gasUsed: Int, isMasterchain: Bool): Int { GETGASFEE }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Similar to `getComputeFee()`, but without the `flat_gas_price`, i.e. without a minimum price to pay if the `gasUsed` is less than a certain '... 8611 more characters, + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'contractHash', + loc: { start: 1027, end: 1039 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1065, end: 1068 } + }, + loc: { start: 1065, end: 1068 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 1040, end: 1044 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 1046, end: 1050 } }, + loc: { start: 1046, end: 1050 } + }, + loc: { start: 1040, end: 1050 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'data', + loc: { start: 1052, end: 1056 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 1058, end: 1062 } }, + loc: { start: 1058, end: 1062 } + }, + loc: { start: 1052, end: 1062 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 's0 PUSH HASHCU // `data` hash\n' + + ' s2 PUSH HASHCU // `code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `code` depth\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + '\n' + + ' // Group 2: Composition of the Builder\n' + + ' NEWC\n' + + ' 24 STU // store refs_descriptor | bits_descriptor | data\n' + + ' 16 STU // store depth_descriptor for `code`\n' + + ' 16 STU // store depth_descriptor for `data`\n' + + ' 256 STU // store `code` hash\n' + + ' 256 STU // store `data` hash\n' + + '\n' + + ' // Group 3: SHA256 hash of the resulting Builder\n' + + ' ONE HASHEXT_SHA256' + ] + }, + loc: { start: 1019, end: 2666 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'contractAddressExt', + loc: { start: 3391, end: 3409 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3447, end: 3454 } + }, + typeArgs: [], + loc: { start: 3447, end: 3454 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'chain', + loc: { start: 3410, end: 3415 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3417, end: 3420 } + }, + loc: { start: 3417, end: 3420 } + }, + loc: { start: 3410, end: 3420 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 3422, end: 3426 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3428, end: 3432 } }, + loc: { start: 3428, end: 3432 } + }, + loc: { start: 3422, end: 3432 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'data', + loc: { start: 3434, end: 3438 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3440, end: 3444 } }, + loc: { start: 3440, end: 3444 } + }, + loc: { start: 3434, end: 3444 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'hash', + loc: { start: 3465, end: 3469 } + }, + type: undefined, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractHash', + loc: { start: 3472, end: 3484 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'code', + loc: { start: 3485, end: 3489 } + }, + { + kind: 'var', + name: 'data', + loc: { start: 3491, end: 3495 } + } + ], + loc: { start: 3472, end: 3496 } + }, + loc: { start: 3461, end: 3497 } + }, + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'newAddress', + loc: { start: 3509, end: 3519 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'chain', + loc: { start: 3520, end: 3525 } + }, + { + kind: 'var', + name: 'hash', + loc: { start: 3527, end: 3531 } + } + ], + loc: { start: 3509, end: 3532 } + }, + loc: { start: 3502, end: 3533 } + } + ] + }, + loc: { start: 3380, end: 3535 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 3731, end: 3740 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'code', + loc: { start: 3803, end: 3807 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3809, end: 3813 } }, + loc: { start: 3809, end: 3813 } + }, + initializer: undefined, + loc: { start: 3803, end: 3813 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'data', + loc: { start: 3914, end: 3918 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3920, end: 3924 } }, + loc: { start: 3920, end: 3924 } + }, + initializer: undefined, + loc: { start: 3914, end: 3924 } + } + ], + loc: { start: 3724, end: 3927 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'hasSameBasechainAddress', + loc: { start: 4778, end: 4801 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 4837, end: 4841 } + }, + typeArgs: [], + loc: { start: 4837, end: 4841 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'sender', + loc: { start: 4819, end: 4825 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 4827, end: 4834 } + }, + typeArgs: [], + loc: { start: 4827, end: 4834 } + }, + loc: { start: 4819, end: 4834 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'senderAddress', + loc: { start: 4852, end: 4865 } + }, + type: undefined, + expression: { + kind: 'field_access', + aggregate: { + kind: 'static_call', + function: { + kind: 'id', + text: 'parseStdAddress', + loc: { start: 4868, end: 4883 } + }, + typeArgs: [], + args: [ + { + kind: 'method_call', + self: { + kind: 'var', + name: 'sender', + loc: { start: 4884, end: 4890 } + }, + method: { + kind: 'id', + text: 'asSlice', + loc: { start: 4891, end: 4898 } + }, + typeArgs: [], + args: [], + loc: { start: 4884, end: 4900 } + } + ], + loc: { start: 4868, end: 4901 } + }, + field: { + kind: 'id', + text: 'address', + loc: { start: 4902, end: 4909 } + }, + loc: { start: 4868, end: 4909 } + }, + loc: { start: 4848, end: 4910 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'baseAddress', + loc: { start: 4919, end: 4930 } + }, + type: undefined, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractBasechainAddress', + loc: { start: 4933, end: 4957 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'self', + loc: { start: 4958, end: 4962 } + } + ], + loc: { start: 4933, end: 4963 } + }, + loc: { start: 4915, end: 4964 } + }, + { + kind: 'statement_return', + expression: { + kind: 'op_binary', + op: '==', + left: { + kind: 'op_unary', + op: '!!', + operand: { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'baseAddress', + loc: { start: 4976, end: 4987 } + }, + field: { + kind: 'id', + text: 'hash', + loc: { start: 4988, end: 4992 } + }, + loc: { start: 4976, end: 4992 } + }, + loc: { start: 4976, end: 4994 } + }, + right: { + kind: 'var', + name: 'senderAddress', + loc: { start: 4998, end: 5011 } + }, + loc: { start: 4976, end: 5011 } + }, + loc: { start: 4969, end: 5012 } + } + ] + }, + loc: { start: 4759, end: 5014 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 4808, end: 4817 } + }, + typeArgs: [], + loc: { start: 4808, end: 4817 } + } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'contractAddress', + loc: { start: 5709, end: 5724 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 5740, end: 5747 } + }, + typeArgs: [], + loc: { start: 5740, end: 5747 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 's', + loc: { start: 5725, end: 5726 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 5728, end: 5737 } + }, + typeArgs: [], + loc: { start: 5728, end: 5737 } + }, + loc: { start: 5725, end: 5737 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractAddressExt', + loc: { start: 5761, end: 5779 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 5780, end: 5781 } + }, + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 5783, end: 5784 } + }, + field: { + kind: 'id', + text: 'code', + loc: { start: 5785, end: 5789 } + }, + loc: { start: 5783, end: 5789 } + }, + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 5791, end: 5792 } + }, + field: { + kind: 'id', + text: 'data', + loc: { start: 5793, end: 5797 } + }, + loc: { start: 5791, end: 5797 } + } + ], + loc: { start: 5761, end: 5798 } + }, + loc: { start: 5754, end: 5799 } + } + ] + }, + loc: { start: 5698, end: 5801 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myAddress', + loc: { start: 6082, end: 6091 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 6095, end: 6102 } + }, + typeArgs: [], + loc: { start: 6095, end: 6102 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MYADDR' ] + }, + loc: { start: 6074, end: 6113 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myBalance', + loc: { start: 6454, end: 6463 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6467, end: 6470 } + }, + loc: { start: 6467, end: 6470 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'BALANCE FIRST' ] + }, + loc: { start: 6446, end: 6488 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'gasConsumed', + loc: { start: 6880, end: 6891 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6895, end: 6898 } + }, + loc: { start: 6895, end: 6898 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GASCONSUMED' ] + }, + loc: { start: 6872, end: 6914 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myStorageDue', + loc: { start: 7329, end: 7341 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7345, end: 7348 } + }, + loc: { start: 7345, end: 7348 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DUEPAYMENT' ] + }, + loc: { start: 7321, end: 7363 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getStorageFee', + loc: { start: 8517, end: 8530 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8590, end: 8593 } + }, + loc: { start: 8590, end: 8593 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 8531, end: 8536 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8538, end: 8541 } + }, + loc: { start: 8538, end: 8541 } + }, + loc: { start: 8531, end: 8541 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 8543, end: 8547 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8549, end: 8552 } + }, + loc: { start: 8549, end: 8552 } + }, + loc: { start: 8543, end: 8552 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'seconds', + loc: { start: 8554, end: 8561 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8563, end: 8566 } + }, + loc: { start: 8563, end: 8566 } + }, + loc: { start: 8554, end: 8566 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 8568, end: 8581 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 8583, end: 8587 } + }, + typeArgs: [], + loc: { start: 8583, end: 8587 } + }, + loc: { start: 8568, end: 8587 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETSTORAGEFEE' ] + }, + loc: { start: 8509, end: 8611 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getComputeFee', + loc: { start: 9734, end: 9747 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9784, end: 9787 } + }, + loc: { start: 9784, end: 9787 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'gasUsed', + loc: { start: 9748, end: 9755 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9757, end: 9760 } + }, + loc: { start: 9757, end: 9760 } + }, + loc: { start: 9748, end: 9760 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 9762, end: 9775 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 9777, end: 9781 } + }, + typeArgs: [], + loc: { start: 9777, end: 9781 } + }, + loc: { start: 9762, end: 9781 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETGASFEE' ] + }, + loc: { start: 9726, end: 9801 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSimpleComputeFee', + loc: { start: 10689, end: 10708 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10745, end: 10748 } + }, + loc: { start: 10745, end: 10748 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'gasUsed', + loc: { start: 10709, end: 10716 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10718, end: 10721 } + }, + loc: { start: 10718, end: 10721 } + }, + loc: { start: 10709, end: 10721 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 10723, end: 10736 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 10738, end: 10742 } + }, + typeArgs: [], + loc: { start: 10738, end: 10742 } + }, + loc: { start: 10723, end: 10742 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETGASFEESIMPLE' ] + }, + loc: { start: 10681, end: 10768 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getForwardFee', + loc: { start: 12543, end: 12556 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12602, end: 12605 } + }, + loc: { start: 12602, end: 12605 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 12557, end: 12562 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12564, end: 12567 } + }, + loc: { start: 12564, end: 12567 } + }, + loc: { start: 12557, end: 12567 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 12569, end: 12573 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12575, end: 12578 } + }, + loc: { start: 12575, end: 12578 } + }, + loc: { start: 12569, end: 12578 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 12580, end: 12593 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 12595, end: 12599 } + }, + typeArgs: [], + loc: { start: 12595, end: 12599 } + }, + loc: { start: 12580, end: 12599 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETFORWARDFEE' ] + }, + loc: { start: 12535, end: 12623 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSimpleForwardFee', + loc: { start: 13528, end: 13547 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13593, end: 13596 } + }, + loc: { start: 13593, end: 13596 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 13548, end: 13553 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13555, end: 13558 } + }, + loc: { start: 13555, end: 13558 } + }, + loc: { start: 13548, end: 13558 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 13560, end: 13564 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13566, end: 13569 } + }, + loc: { start: 13566, end: 13569 } + }, + loc: { start: 13560, end: 13569 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 13571, end: 13584 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 13586, end: 13590 } + }, + typeArgs: [], + loc: { start: 13586, end: 13590 } + }, + loc: { start: 13571, end: 13590 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETFORWARDFEESIMPLE' ] + }, + loc: { start: 13520, end: 13620 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getOriginalFwdFee', + loc: { start: 15782, end: 15799 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15835, end: 15838 } + }, + loc: { start: 15835, end: 15838 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'fwdFee', + loc: { start: 15800, end: 15806 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15808, end: 15811 } + }, + loc: { start: 15808, end: 15811 } + }, + loc: { start: 15800, end: 15811 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 15813, end: 15826 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 15828, end: 15832 } + }, + typeArgs: [], + loc: { start: 15828, end: 15832 } + }, + loc: { start: 15813, end: 15832 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETORIGINALFWDFEE' ] + }, + loc: { start: 15774, end: 15860 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'setGasLimit', + loc: { start: 16541, end: 16552 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'limit', + loc: { start: 16553, end: 16558 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 16560, end: 16563 } + }, + loc: { start: 16560, end: 16563 } + }, + loc: { start: 16553, end: 16563 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SETGASLIMIT' ] + }, + loc: { start: 16533, end: 16580 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSeed', + loc: { start: 17350, end: 17357 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 17361, end: 17364 } + }, + loc: { start: 17361, end: 17364 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RANDSEED' ] + }, + loc: { start: 17342, end: 17377 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'setSeed', + loc: { start: 18258, end: 18265 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'seed', + loc: { start: 18266, end: 18270 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 18272, end: 18275 } + }, + loc: { start: 18272, end: 18275 } + }, + loc: { start: 18266, end: 18275 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SETRAND' ] + }, + loc: { start: 18250, end: 18288 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myCode', + loc: { start: 18585, end: 18591 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 18595, end: 18599 } }, + loc: { start: 18595, end: 18599 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MYCODE' ] + }, + loc: { start: 18577, end: 18610 } + } + ] + }, + 'getSeed' => { + kind: 'tact', + path: 'std/internal/contract.tact', + code: '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Computes and returns an `Int` value of the SHA-256 hash of the `code` and `data` of the given contract. To assemble the `code` and `data` cells together for hashing, the standard `Cell` representation is used.\n' + + '///\n' + + '/// This hash is commonly called account ID. Together with the workchain ID it deterministically forms the address of the contract on TON Blockchain.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let initPkg: StateInit = initOf SomeContract();\n' + + '/// let accountId: Int = contractHash(initPkg.code, initPkg.data);\n' + + '/// let basechainAddr: Address = newAddress(0, accountId);\n' + + '/// let basechainAddr2: Address = contractAddressExt(0, initPkg.code, initPkg.data);\n' + + '///\n' + + '/// basechainAddr == basechainAddr2; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contracthash\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#newaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '///\n' + + 'asm fun contractHash(code: Cell, data: Cell): Int {\n' + + ' // According to the https://docs.tact-lang.org/book/cells#cells-representation,\n' + + ' // the layout for the Builder to hash goes as follows:\n' + + ' // 1) refs_descriptor:bits8 | bits_descriptor:bits8 | data:bitsN\n' + + ' //\n' + + ' // refs_descriptor: ref_count + ((exotic? & 1) * 8) + (mask * 32)\n' + + ' // 2 refs (code + data), non-exotic, zero-mask\n' + + ' //\n' + + ' // bits_descriptor: floor(bit_count / 8) + ceil(bit_count, 8)\n' + + ' // floor (5 bits / 8) + ceil(5 bits / 8) = 0 + 1 = 1\n' + + ' //\n' + + ' // data: [0b00110] + [0b100] = [0b00110100] = 0x34 (data + augmented bits)\n' + + ' // 0b00110 - data (split_depth, special, code, data, Library)\n' + + ' // 0b100 - augmented bits (Leading 1 + zeroes to make section multiple of eight)\n' + + ' //\n' + + ' // That is: (2 << 16) | (1 << 8) | 0x34 = 131380 for all three.\n' + + ' //\n' + + ' // 2) and 3) depth_descriptors: CDEPTH of `code` and CDEPTH of `data`\n' + + ' // 4) and 5) ref hashes: HASHCU of `code` and HASHCU of `data`\n' + + '\n' + + ' // Group 1: Computations and arrangements\n' + + ' s0 PUSH HASHCU // `data` hash\n' + + ' s2 PUSH HASHCU // `code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `code` depth\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + '\n' + + ' // Group 2: Composition of the Builder\n' + + ' NEWC\n' + + ' 24 STU // store refs_descriptor | bits_descriptor | data\n' + + ' 16 STU // store depth_descriptor for `code`\n' + + ' 16 STU // store depth_descriptor for `data`\n' + + ' 256 STU // store `code` hash\n' + + ' 256 STU // store `data` hash\n' + + '\n' + + ' // Group 3: SHA256 hash of the resulting Builder\n' + + ' ONE HASHEXT_SHA256\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + "/// Computes smart contract's `Address` in the `chain` ID using the contract's `code` and the contract's initial state `data`. Use the `initOf` expression to obtain the initial `code` and initial `data` of a given contract.\n" + + '///\n' + + '/// This function lets you specify arbitrary `chain` IDs, including the common -1 (masterchain) and 0 (basechain) ones.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let initPkg: StateInit = initOf SomeContract();\n' + + '/// let hereBeDragons: Address = contractAddressExt(0, initPkg.code, initPkg.data);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '/// * https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'inline fun contractAddressExt(chain: Int, code: Cell, data: Cell): Address {\n' + + ' let hash = contractHash(code, data);\n' + + ' return newAddress(chain, hash);\n' + + '}\n' + + '\n' + + '/// Struct containing the initial state, i.e. initial code and initial data of the given contract upon its deployment.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'struct StateInit {\n' + + ' /// Initial code of the contract (compiled bitcode)\n' + + ' code: Cell;\n' + + '\n' + + ' /// Initial data of the contract (parameters of `init()` function or contract parameters)\n' + + ' data: Cell;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.1.\n' + + '///\n' + + '/// Efficiently compares if the given address matches the basechain address of the contract.\n' + + '/// Returns true if addresses are the same, false otherwise.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let init = initOf SomeContract();\n' + + "/// init.hasSameBasechainAddress(sender()); // returns true if sender matches contract's basechain address\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// This function provides a gas-optimized implementation compared to direct address comparison:\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let init = initOf SomeContract();\n' + + '/// sender() == contractAddress(sender()); // less efficient approach\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// Note that this function works only for basechain addresses!\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddress\n' + + '///\n' + + 'inline extends fun hasSameBasechainAddress(self: StateInit, sender: Address): Bool {\n' + + ' let senderAddress = parseStdAddress(sender.asSlice()).address;\n' + + ' let baseAddress = contractBasechainAddress(self);\n' + + ' return baseAddress.hash!! == senderAddress;\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + "/// Computes smart contract's `Address` in the workchain ID 0 (basechain) using the `StateInit` `s` of the contract. Alias to `contractAddressExt(0, s.code, s.data)`.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let s: StateInit = initOf SomeContract();\n' + + '/// let foundMeSome: Address = contractAddress(s);\n' + + '/// let andSomeMore: Address = contractAddressExt(0, s.code, s.data);\n' + + '///\n' + + '/// foundMeSome == andSomeMore; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '/// * https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'inline fun contractAddress(s: StateInit): Address {\n' + + ' return contractAddressExt(0, s.code, s.data);\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Returns the address of the current smart contract as an `Address`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let meMyselfAndI: Address = myAddress();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#myaddress\n' + + '///\n' + + 'asm fun myAddress(): Address { MYADDR }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` balance of the smart contract as it was at the start of the compute phase of the current transaction.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let iNeedADolla: Int = myBalance();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#mybalance\n' + + '///\n' + + 'asm fun myBalance(): Int { BALANCE FIRST }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` amount of gas consumed by TVM in the current transaction so far. The resulting value includes the cost of calling this function.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let gas: Int = gasConsumed();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#gasconsumed\n' + + '///\n' + + 'asm fun gasConsumed(): Int { GASCONSUMED }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` amount of the accumulated storage fee debt. Storage fees are deducted from the incoming message value before the new contract balance is calculated.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let debt: Int = myStorageDue();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#mystoragedue\n' + + '///\n' + + 'asm fun myStorageDue(): Int { DUEPAYMENT }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Calculates and returns the storage fee in nanoToncoins `Int` for storing a contract with a given number of `cells` and `bits` for a number of `seconds`. Uses the prices of the masterchain if `isMasterchain` is `true`, otherwise the prices of the basechain. The current prices are obtained from the config param 18 of TON Blockchain.\n' + + '///\n' + + '/// Note, that specifying values of `cells` and `bits` higher than their maximum values listed in account state limits (`max_acc_state_cells` and `max_acc_state_bits`) will have the same result as with specifying the exact limits. In addition, make sure you take into account the deduplication of cells with the same hash.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fee: Int = getStorageFee(1_000, 1_000, 1_000, false);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify negative number of `cells`, `bits` or `seconds`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-gas#getstoragefee\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun getStorageFee(cells: Int, bits: Int, seconds: Int, isMasterchain: Bool): Int { GETSTORAGEFEE }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Calculates and returns the compute fee in nanoToncoins `Int` for a transaction that consumed `gasUsed` amount of gas. Uses the prices of the masterchain if `isMasterchain` is `true`, otherwise the prices of the basechain. The current prices are obtained from the config param 20 for the masterchain and config param 21 for the basechain of TON Blockchain.\n' + + '///\n' + + "/// When the `gasUsed` is less than a certain threshold called `flat_gas_limit`, there's a minimum price to pay based on the value of `flat_gas_price`. The less gas is used below this threshold, the higher the minimum price will be. See the example for `getSimpleComputeFee()` to derive that threshold.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fee: Int = getComputeFee(1_000, false);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify negative value of `gasUsed`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-gas#getcomputefee\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun getComputeFee(gasUsed: Int, isMasterchain: Bool): Int { GETGASFEE }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Similar to `getComputeFee()`, but without the `flat_gas_price`, i.e. without a minimum price to pay if the `gasUsed` is less than a certain '... 8611 more characters, + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'contractHash', + loc: { start: 1027, end: 1039 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1065, end: 1068 } + }, + loc: { start: 1065, end: 1068 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 1040, end: 1044 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 1046, end: 1050 } }, + loc: { start: 1046, end: 1050 } + }, + loc: { start: 1040, end: 1050 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'data', + loc: { start: 1052, end: 1056 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 1058, end: 1062 } }, + loc: { start: 1058, end: 1062 } + }, + loc: { start: 1052, end: 1062 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 's0 PUSH HASHCU // `data` hash\n' + + ' s2 PUSH HASHCU // `code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `code` depth\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + '\n' + + ' // Group 2: Composition of the Builder\n' + + ' NEWC\n' + + ' 24 STU // store refs_descriptor | bits_descriptor | data\n' + + ' 16 STU // store depth_descriptor for `code`\n' + + ' 16 STU // store depth_descriptor for `data`\n' + + ' 256 STU // store `code` hash\n' + + ' 256 STU // store `data` hash\n' + + '\n' + + ' // Group 3: SHA256 hash of the resulting Builder\n' + + ' ONE HASHEXT_SHA256' + ] + }, + loc: { start: 1019, end: 2666 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'contractAddressExt', + loc: { start: 3391, end: 3409 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3447, end: 3454 } + }, + typeArgs: [], + loc: { start: 3447, end: 3454 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'chain', + loc: { start: 3410, end: 3415 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3417, end: 3420 } + }, + loc: { start: 3417, end: 3420 } + }, + loc: { start: 3410, end: 3420 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 3422, end: 3426 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3428, end: 3432 } }, + loc: { start: 3428, end: 3432 } + }, + loc: { start: 3422, end: 3432 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'data', + loc: { start: 3434, end: 3438 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3440, end: 3444 } }, + loc: { start: 3440, end: 3444 } + }, + loc: { start: 3434, end: 3444 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'hash', + loc: { start: 3465, end: 3469 } + }, + type: undefined, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractHash', + loc: { start: 3472, end: 3484 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'code', + loc: { start: 3485, end: 3489 } + }, + { + kind: 'var', + name: 'data', + loc: { start: 3491, end: 3495 } + } + ], + loc: { start: 3472, end: 3496 } + }, + loc: { start: 3461, end: 3497 } + }, + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'newAddress', + loc: { start: 3509, end: 3519 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'chain', + loc: { start: 3520, end: 3525 } + }, + { + kind: 'var', + name: 'hash', + loc: { start: 3527, end: 3531 } + } + ], + loc: { start: 3509, end: 3532 } + }, + loc: { start: 3502, end: 3533 } + } + ] + }, + loc: { start: 3380, end: 3535 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 3731, end: 3740 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'code', + loc: { start: 3803, end: 3807 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3809, end: 3813 } }, + loc: { start: 3809, end: 3813 } + }, + initializer: undefined, + loc: { start: 3803, end: 3813 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'data', + loc: { start: 3914, end: 3918 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3920, end: 3924 } }, + loc: { start: 3920, end: 3924 } + }, + initializer: undefined, + loc: { start: 3914, end: 3924 } + } + ], + loc: { start: 3724, end: 3927 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'hasSameBasechainAddress', + loc: { start: 4778, end: 4801 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 4837, end: 4841 } + }, + typeArgs: [], + loc: { start: 4837, end: 4841 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'sender', + loc: { start: 4819, end: 4825 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 4827, end: 4834 } + }, + typeArgs: [], + loc: { start: 4827, end: 4834 } + }, + loc: { start: 4819, end: 4834 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'senderAddress', + loc: { start: 4852, end: 4865 } + }, + type: undefined, + expression: { + kind: 'field_access', + aggregate: { + kind: 'static_call', + function: { + kind: 'id', + text: 'parseStdAddress', + loc: { start: 4868, end: 4883 } + }, + typeArgs: [], + args: [ + { + kind: 'method_call', + self: { + kind: 'var', + name: 'sender', + loc: { start: 4884, end: 4890 } + }, + method: { + kind: 'id', + text: 'asSlice', + loc: { start: 4891, end: 4898 } + }, + typeArgs: [], + args: [], + loc: { start: 4884, end: 4900 } + } + ], + loc: { start: 4868, end: 4901 } + }, + field: { + kind: 'id', + text: 'address', + loc: { start: 4902, end: 4909 } + }, + loc: { start: 4868, end: 4909 } + }, + loc: { start: 4848, end: 4910 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'baseAddress', + loc: { start: 4919, end: 4930 } + }, + type: undefined, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractBasechainAddress', + loc: { start: 4933, end: 4957 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'self', + loc: { start: 4958, end: 4962 } + } + ], + loc: { start: 4933, end: 4963 } + }, + loc: { start: 4915, end: 4964 } + }, + { + kind: 'statement_return', + expression: { + kind: 'op_binary', + op: '==', + left: { + kind: 'op_unary', + op: '!!', + operand: { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'baseAddress', + loc: { start: 4976, end: 4987 } + }, + field: { + kind: 'id', + text: 'hash', + loc: { start: 4988, end: 4992 } + }, + loc: { start: 4976, end: 4992 } + }, + loc: { start: 4976, end: 4994 } + }, + right: { + kind: 'var', + name: 'senderAddress', + loc: { start: 4998, end: 5011 } + }, + loc: { start: 4976, end: 5011 } + }, + loc: { start: 4969, end: 5012 } + } + ] + }, + loc: { start: 4759, end: 5014 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 4808, end: 4817 } + }, + typeArgs: [], + loc: { start: 4808, end: 4817 } + } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'contractAddress', + loc: { start: 5709, end: 5724 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 5740, end: 5747 } + }, + typeArgs: [], + loc: { start: 5740, end: 5747 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 's', + loc: { start: 5725, end: 5726 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 5728, end: 5737 } + }, + typeArgs: [], + loc: { start: 5728, end: 5737 } + }, + loc: { start: 5725, end: 5737 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractAddressExt', + loc: { start: 5761, end: 5779 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 5780, end: 5781 } + }, + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 5783, end: 5784 } + }, + field: { + kind: 'id', + text: 'code', + loc: { start: 5785, end: 5789 } + }, + loc: { start: 5783, end: 5789 } + }, + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 5791, end: 5792 } + }, + field: { + kind: 'id', + text: 'data', + loc: { start: 5793, end: 5797 } + }, + loc: { start: 5791, end: 5797 } + } + ], + loc: { start: 5761, end: 5798 } + }, + loc: { start: 5754, end: 5799 } + } + ] + }, + loc: { start: 5698, end: 5801 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myAddress', + loc: { start: 6082, end: 6091 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 6095, end: 6102 } + }, + typeArgs: [], + loc: { start: 6095, end: 6102 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MYADDR' ] + }, + loc: { start: 6074, end: 6113 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myBalance', + loc: { start: 6454, end: 6463 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6467, end: 6470 } + }, + loc: { start: 6467, end: 6470 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'BALANCE FIRST' ] + }, + loc: { start: 6446, end: 6488 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'gasConsumed', + loc: { start: 6880, end: 6891 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6895, end: 6898 } + }, + loc: { start: 6895, end: 6898 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GASCONSUMED' ] + }, + loc: { start: 6872, end: 6914 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myStorageDue', + loc: { start: 7329, end: 7341 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7345, end: 7348 } + }, + loc: { start: 7345, end: 7348 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DUEPAYMENT' ] + }, + loc: { start: 7321, end: 7363 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getStorageFee', + loc: { start: 8517, end: 8530 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8590, end: 8593 } + }, + loc: { start: 8590, end: 8593 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 8531, end: 8536 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8538, end: 8541 } + }, + loc: { start: 8538, end: 8541 } + }, + loc: { start: 8531, end: 8541 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 8543, end: 8547 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8549, end: 8552 } + }, + loc: { start: 8549, end: 8552 } + }, + loc: { start: 8543, end: 8552 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'seconds', + loc: { start: 8554, end: 8561 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8563, end: 8566 } + }, + loc: { start: 8563, end: 8566 } + }, + loc: { start: 8554, end: 8566 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 8568, end: 8581 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 8583, end: 8587 } + }, + typeArgs: [], + loc: { start: 8583, end: 8587 } + }, + loc: { start: 8568, end: 8587 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETSTORAGEFEE' ] + }, + loc: { start: 8509, end: 8611 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getComputeFee', + loc: { start: 9734, end: 9747 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9784, end: 9787 } + }, + loc: { start: 9784, end: 9787 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'gasUsed', + loc: { start: 9748, end: 9755 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9757, end: 9760 } + }, + loc: { start: 9757, end: 9760 } + }, + loc: { start: 9748, end: 9760 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 9762, end: 9775 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 9777, end: 9781 } + }, + typeArgs: [], + loc: { start: 9777, end: 9781 } + }, + loc: { start: 9762, end: 9781 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETGASFEE' ] + }, + loc: { start: 9726, end: 9801 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSimpleComputeFee', + loc: { start: 10689, end: 10708 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10745, end: 10748 } + }, + loc: { start: 10745, end: 10748 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'gasUsed', + loc: { start: 10709, end: 10716 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10718, end: 10721 } + }, + loc: { start: 10718, end: 10721 } + }, + loc: { start: 10709, end: 10721 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 10723, end: 10736 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 10738, end: 10742 } + }, + typeArgs: [], + loc: { start: 10738, end: 10742 } + }, + loc: { start: 10723, end: 10742 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETGASFEESIMPLE' ] + }, + loc: { start: 10681, end: 10768 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getForwardFee', + loc: { start: 12543, end: 12556 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12602, end: 12605 } + }, + loc: { start: 12602, end: 12605 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 12557, end: 12562 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12564, end: 12567 } + }, + loc: { start: 12564, end: 12567 } + }, + loc: { start: 12557, end: 12567 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 12569, end: 12573 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12575, end: 12578 } + }, + loc: { start: 12575, end: 12578 } + }, + loc: { start: 12569, end: 12578 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 12580, end: 12593 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 12595, end: 12599 } + }, + typeArgs: [], + loc: { start: 12595, end: 12599 } + }, + loc: { start: 12580, end: 12599 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETFORWARDFEE' ] + }, + loc: { start: 12535, end: 12623 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSimpleForwardFee', + loc: { start: 13528, end: 13547 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13593, end: 13596 } + }, + loc: { start: 13593, end: 13596 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 13548, end: 13553 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13555, end: 13558 } + }, + loc: { start: 13555, end: 13558 } + }, + loc: { start: 13548, end: 13558 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 13560, end: 13564 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13566, end: 13569 } + }, + loc: { start: 13566, end: 13569 } + }, + loc: { start: 13560, end: 13569 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 13571, end: 13584 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 13586, end: 13590 } + }, + typeArgs: [], + loc: { start: 13586, end: 13590 } + }, + loc: { start: 13571, end: 13590 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETFORWARDFEESIMPLE' ] + }, + loc: { start: 13520, end: 13620 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getOriginalFwdFee', + loc: { start: 15782, end: 15799 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15835, end: 15838 } + }, + loc: { start: 15835, end: 15838 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'fwdFee', + loc: { start: 15800, end: 15806 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15808, end: 15811 } + }, + loc: { start: 15808, end: 15811 } + }, + loc: { start: 15800, end: 15811 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 15813, end: 15826 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 15828, end: 15832 } + }, + typeArgs: [], + loc: { start: 15828, end: 15832 } + }, + loc: { start: 15813, end: 15832 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETORIGINALFWDFEE' ] + }, + loc: { start: 15774, end: 15860 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'setGasLimit', + loc: { start: 16541, end: 16552 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'limit', + loc: { start: 16553, end: 16558 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 16560, end: 16563 } + }, + loc: { start: 16560, end: 16563 } + }, + loc: { start: 16553, end: 16563 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SETGASLIMIT' ] + }, + loc: { start: 16533, end: 16580 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSeed', + loc: { start: 17350, end: 17357 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 17361, end: 17364 } + }, + loc: { start: 17361, end: 17364 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RANDSEED' ] + }, + loc: { start: 17342, end: 17377 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'setSeed', + loc: { start: 18258, end: 18265 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'seed', + loc: { start: 18266, end: 18270 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 18272, end: 18275 } + }, + loc: { start: 18272, end: 18275 } + }, + loc: { start: 18266, end: 18275 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SETRAND' ] + }, + loc: { start: 18250, end: 18288 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myCode', + loc: { start: 18585, end: 18591 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 18595, end: 18599 } }, + loc: { start: 18595, end: 18599 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MYCODE' ] + }, + loc: { start: 18577, end: 18610 } + } + ] + }, + 'setSeed' => { + kind: 'tact', + path: 'std/internal/contract.tact', + code: '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Computes and returns an `Int` value of the SHA-256 hash of the `code` and `data` of the given contract. To assemble the `code` and `data` cells together for hashing, the standard `Cell` representation is used.\n' + + '///\n' + + '/// This hash is commonly called account ID. Together with the workchain ID it deterministically forms the address of the contract on TON Blockchain.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let initPkg: StateInit = initOf SomeContract();\n' + + '/// let accountId: Int = contractHash(initPkg.code, initPkg.data);\n' + + '/// let basechainAddr: Address = newAddress(0, accountId);\n' + + '/// let basechainAddr2: Address = contractAddressExt(0, initPkg.code, initPkg.data);\n' + + '///\n' + + '/// basechainAddr == basechainAddr2; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contracthash\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#newaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '///\n' + + 'asm fun contractHash(code: Cell, data: Cell): Int {\n' + + ' // According to the https://docs.tact-lang.org/book/cells#cells-representation,\n' + + ' // the layout for the Builder to hash goes as follows:\n' + + ' // 1) refs_descriptor:bits8 | bits_descriptor:bits8 | data:bitsN\n' + + ' //\n' + + ' // refs_descriptor: ref_count + ((exotic? & 1) * 8) + (mask * 32)\n' + + ' // 2 refs (code + data), non-exotic, zero-mask\n' + + ' //\n' + + ' // bits_descriptor: floor(bit_count / 8) + ceil(bit_count, 8)\n' + + ' // floor (5 bits / 8) + ceil(5 bits / 8) = 0 + 1 = 1\n' + + ' //\n' + + ' // data: [0b00110] + [0b100] = [0b00110100] = 0x34 (data + augmented bits)\n' + + ' // 0b00110 - data (split_depth, special, code, data, Library)\n' + + ' // 0b100 - augmented bits (Leading 1 + zeroes to make section multiple of eight)\n' + + ' //\n' + + ' // That is: (2 << 16) | (1 << 8) | 0x34 = 131380 for all three.\n' + + ' //\n' + + ' // 2) and 3) depth_descriptors: CDEPTH of `code` and CDEPTH of `data`\n' + + ' // 4) and 5) ref hashes: HASHCU of `code` and HASHCU of `data`\n' + + '\n' + + ' // Group 1: Computations and arrangements\n' + + ' s0 PUSH HASHCU // `data` hash\n' + + ' s2 PUSH HASHCU // `code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `code` depth\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + '\n' + + ' // Group 2: Composition of the Builder\n' + + ' NEWC\n' + + ' 24 STU // store refs_descriptor | bits_descriptor | data\n' + + ' 16 STU // store depth_descriptor for `code`\n' + + ' 16 STU // store depth_descriptor for `data`\n' + + ' 256 STU // store `code` hash\n' + + ' 256 STU // store `data` hash\n' + + '\n' + + ' // Group 3: SHA256 hash of the resulting Builder\n' + + ' ONE HASHEXT_SHA256\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + "/// Computes smart contract's `Address` in the `chain` ID using the contract's `code` and the contract's initial state `data`. Use the `initOf` expression to obtain the initial `code` and initial `data` of a given contract.\n" + + '///\n' + + '/// This function lets you specify arbitrary `chain` IDs, including the common -1 (masterchain) and 0 (basechain) ones.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let initPkg: StateInit = initOf SomeContract();\n' + + '/// let hereBeDragons: Address = contractAddressExt(0, initPkg.code, initPkg.data);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '/// * https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'inline fun contractAddressExt(chain: Int, code: Cell, data: Cell): Address {\n' + + ' let hash = contractHash(code, data);\n' + + ' return newAddress(chain, hash);\n' + + '}\n' + + '\n' + + '/// Struct containing the initial state, i.e. initial code and initial data of the given contract upon its deployment.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'struct StateInit {\n' + + ' /// Initial code of the contract (compiled bitcode)\n' + + ' code: Cell;\n' + + '\n' + + ' /// Initial data of the contract (parameters of `init()` function or contract parameters)\n' + + ' data: Cell;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.1.\n' + + '///\n' + + '/// Efficiently compares if the given address matches the basechain address of the contract.\n' + + '/// Returns true if addresses are the same, false otherwise.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let init = initOf SomeContract();\n' + + "/// init.hasSameBasechainAddress(sender()); // returns true if sender matches contract's basechain address\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// This function provides a gas-optimized implementation compared to direct address comparison:\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let init = initOf SomeContract();\n' + + '/// sender() == contractAddress(sender()); // less efficient approach\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// Note that this function works only for basechain addresses!\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddress\n' + + '///\n' + + 'inline extends fun hasSameBasechainAddress(self: StateInit, sender: Address): Bool {\n' + + ' let senderAddress = parseStdAddress(sender.asSlice()).address;\n' + + ' let baseAddress = contractBasechainAddress(self);\n' + + ' return baseAddress.hash!! == senderAddress;\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + "/// Computes smart contract's `Address` in the workchain ID 0 (basechain) using the `StateInit` `s` of the contract. Alias to `contractAddressExt(0, s.code, s.data)`.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let s: StateInit = initOf SomeContract();\n' + + '/// let foundMeSome: Address = contractAddress(s);\n' + + '/// let andSomeMore: Address = contractAddressExt(0, s.code, s.data);\n' + + '///\n' + + '/// foundMeSome == andSomeMore; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '/// * https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'inline fun contractAddress(s: StateInit): Address {\n' + + ' return contractAddressExt(0, s.code, s.data);\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Returns the address of the current smart contract as an `Address`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let meMyselfAndI: Address = myAddress();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#myaddress\n' + + '///\n' + + 'asm fun myAddress(): Address { MYADDR }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` balance of the smart contract as it was at the start of the compute phase of the current transaction.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let iNeedADolla: Int = myBalance();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#mybalance\n' + + '///\n' + + 'asm fun myBalance(): Int { BALANCE FIRST }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` amount of gas consumed by TVM in the current transaction so far. The resulting value includes the cost of calling this function.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let gas: Int = gasConsumed();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#gasconsumed\n' + + '///\n' + + 'asm fun gasConsumed(): Int { GASCONSUMED }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` amount of the accumulated storage fee debt. Storage fees are deducted from the incoming message value before the new contract balance is calculated.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let debt: Int = myStorageDue();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#mystoragedue\n' + + '///\n' + + 'asm fun myStorageDue(): Int { DUEPAYMENT }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Calculates and returns the storage fee in nanoToncoins `Int` for storing a contract with a given number of `cells` and `bits` for a number of `seconds`. Uses the prices of the masterchain if `isMasterchain` is `true`, otherwise the prices of the basechain. The current prices are obtained from the config param 18 of TON Blockchain.\n' + + '///\n' + + '/// Note, that specifying values of `cells` and `bits` higher than their maximum values listed in account state limits (`max_acc_state_cells` and `max_acc_state_bits`) will have the same result as with specifying the exact limits. In addition, make sure you take into account the deduplication of cells with the same hash.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fee: Int = getStorageFee(1_000, 1_000, 1_000, false);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify negative number of `cells`, `bits` or `seconds`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-gas#getstoragefee\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun getStorageFee(cells: Int, bits: Int, seconds: Int, isMasterchain: Bool): Int { GETSTORAGEFEE }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Calculates and returns the compute fee in nanoToncoins `Int` for a transaction that consumed `gasUsed` amount of gas. Uses the prices of the masterchain if `isMasterchain` is `true`, otherwise the prices of the basechain. The current prices are obtained from the config param 20 for the masterchain and config param 21 for the basechain of TON Blockchain.\n' + + '///\n' + + "/// When the `gasUsed` is less than a certain threshold called `flat_gas_limit`, there's a minimum price to pay based on the value of `flat_gas_price`. The less gas is used below this threshold, the higher the minimum price will be. See the example for `getSimpleComputeFee()` to derive that threshold.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fee: Int = getComputeFee(1_000, false);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify negative value of `gasUsed`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-gas#getcomputefee\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun getComputeFee(gasUsed: Int, isMasterchain: Bool): Int { GETGASFEE }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Similar to `getComputeFee()`, but without the `flat_gas_price`, i.e. without a minimum price to pay if the `gasUsed` is less than a certain '... 8611 more characters, + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'contractHash', + loc: { start: 1027, end: 1039 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1065, end: 1068 } + }, + loc: { start: 1065, end: 1068 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 1040, end: 1044 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 1046, end: 1050 } }, + loc: { start: 1046, end: 1050 } + }, + loc: { start: 1040, end: 1050 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'data', + loc: { start: 1052, end: 1056 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 1058, end: 1062 } }, + loc: { start: 1058, end: 1062 } + }, + loc: { start: 1052, end: 1062 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 's0 PUSH HASHCU // `data` hash\n' + + ' s2 PUSH HASHCU // `code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `code` depth\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + '\n' + + ' // Group 2: Composition of the Builder\n' + + ' NEWC\n' + + ' 24 STU // store refs_descriptor | bits_descriptor | data\n' + + ' 16 STU // store depth_descriptor for `code`\n' + + ' 16 STU // store depth_descriptor for `data`\n' + + ' 256 STU // store `code` hash\n' + + ' 256 STU // store `data` hash\n' + + '\n' + + ' // Group 3: SHA256 hash of the resulting Builder\n' + + ' ONE HASHEXT_SHA256' + ] + }, + loc: { start: 1019, end: 2666 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'contractAddressExt', + loc: { start: 3391, end: 3409 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3447, end: 3454 } + }, + typeArgs: [], + loc: { start: 3447, end: 3454 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'chain', + loc: { start: 3410, end: 3415 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3417, end: 3420 } + }, + loc: { start: 3417, end: 3420 } + }, + loc: { start: 3410, end: 3420 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 3422, end: 3426 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3428, end: 3432 } }, + loc: { start: 3428, end: 3432 } + }, + loc: { start: 3422, end: 3432 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'data', + loc: { start: 3434, end: 3438 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3440, end: 3444 } }, + loc: { start: 3440, end: 3444 } + }, + loc: { start: 3434, end: 3444 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'hash', + loc: { start: 3465, end: 3469 } + }, + type: undefined, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractHash', + loc: { start: 3472, end: 3484 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'code', + loc: { start: 3485, end: 3489 } + }, + { + kind: 'var', + name: 'data', + loc: { start: 3491, end: 3495 } + } + ], + loc: { start: 3472, end: 3496 } + }, + loc: { start: 3461, end: 3497 } + }, + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'newAddress', + loc: { start: 3509, end: 3519 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'chain', + loc: { start: 3520, end: 3525 } + }, + { + kind: 'var', + name: 'hash', + loc: { start: 3527, end: 3531 } + } + ], + loc: { start: 3509, end: 3532 } + }, + loc: { start: 3502, end: 3533 } + } + ] + }, + loc: { start: 3380, end: 3535 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 3731, end: 3740 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'code', + loc: { start: 3803, end: 3807 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3809, end: 3813 } }, + loc: { start: 3809, end: 3813 } + }, + initializer: undefined, + loc: { start: 3803, end: 3813 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'data', + loc: { start: 3914, end: 3918 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3920, end: 3924 } }, + loc: { start: 3920, end: 3924 } + }, + initializer: undefined, + loc: { start: 3914, end: 3924 } + } + ], + loc: { start: 3724, end: 3927 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'hasSameBasechainAddress', + loc: { start: 4778, end: 4801 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 4837, end: 4841 } + }, + typeArgs: [], + loc: { start: 4837, end: 4841 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'sender', + loc: { start: 4819, end: 4825 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 4827, end: 4834 } + }, + typeArgs: [], + loc: { start: 4827, end: 4834 } + }, + loc: { start: 4819, end: 4834 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'senderAddress', + loc: { start: 4852, end: 4865 } + }, + type: undefined, + expression: { + kind: 'field_access', + aggregate: { + kind: 'static_call', + function: { + kind: 'id', + text: 'parseStdAddress', + loc: { start: 4868, end: 4883 } + }, + typeArgs: [], + args: [ + { + kind: 'method_call', + self: { + kind: 'var', + name: 'sender', + loc: { start: 4884, end: 4890 } + }, + method: { + kind: 'id', + text: 'asSlice', + loc: { start: 4891, end: 4898 } + }, + typeArgs: [], + args: [], + loc: { start: 4884, end: 4900 } + } + ], + loc: { start: 4868, end: 4901 } + }, + field: { + kind: 'id', + text: 'address', + loc: { start: 4902, end: 4909 } + }, + loc: { start: 4868, end: 4909 } + }, + loc: { start: 4848, end: 4910 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'baseAddress', + loc: { start: 4919, end: 4930 } + }, + type: undefined, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractBasechainAddress', + loc: { start: 4933, end: 4957 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'self', + loc: { start: 4958, end: 4962 } + } + ], + loc: { start: 4933, end: 4963 } + }, + loc: { start: 4915, end: 4964 } + }, + { + kind: 'statement_return', + expression: { + kind: 'op_binary', + op: '==', + left: { + kind: 'op_unary', + op: '!!', + operand: { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'baseAddress', + loc: { start: 4976, end: 4987 } + }, + field: { + kind: 'id', + text: 'hash', + loc: { start: 4988, end: 4992 } + }, + loc: { start: 4976, end: 4992 } + }, + loc: { start: 4976, end: 4994 } + }, + right: { + kind: 'var', + name: 'senderAddress', + loc: { start: 4998, end: 5011 } + }, + loc: { start: 4976, end: 5011 } + }, + loc: { start: 4969, end: 5012 } + } + ] + }, + loc: { start: 4759, end: 5014 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 4808, end: 4817 } + }, + typeArgs: [], + loc: { start: 4808, end: 4817 } + } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'contractAddress', + loc: { start: 5709, end: 5724 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 5740, end: 5747 } + }, + typeArgs: [], + loc: { start: 5740, end: 5747 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 's', + loc: { start: 5725, end: 5726 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 5728, end: 5737 } + }, + typeArgs: [], + loc: { start: 5728, end: 5737 } + }, + loc: { start: 5725, end: 5737 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractAddressExt', + loc: { start: 5761, end: 5779 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 5780, end: 5781 } + }, + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 5783, end: 5784 } + }, + field: { + kind: 'id', + text: 'code', + loc: { start: 5785, end: 5789 } + }, + loc: { start: 5783, end: 5789 } + }, + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 5791, end: 5792 } + }, + field: { + kind: 'id', + text: 'data', + loc: { start: 5793, end: 5797 } + }, + loc: { start: 5791, end: 5797 } + } + ], + loc: { start: 5761, end: 5798 } + }, + loc: { start: 5754, end: 5799 } + } + ] + }, + loc: { start: 5698, end: 5801 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myAddress', + loc: { start: 6082, end: 6091 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 6095, end: 6102 } + }, + typeArgs: [], + loc: { start: 6095, end: 6102 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MYADDR' ] + }, + loc: { start: 6074, end: 6113 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myBalance', + loc: { start: 6454, end: 6463 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6467, end: 6470 } + }, + loc: { start: 6467, end: 6470 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'BALANCE FIRST' ] + }, + loc: { start: 6446, end: 6488 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'gasConsumed', + loc: { start: 6880, end: 6891 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6895, end: 6898 } + }, + loc: { start: 6895, end: 6898 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GASCONSUMED' ] + }, + loc: { start: 6872, end: 6914 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myStorageDue', + loc: { start: 7329, end: 7341 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7345, end: 7348 } + }, + loc: { start: 7345, end: 7348 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DUEPAYMENT' ] + }, + loc: { start: 7321, end: 7363 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getStorageFee', + loc: { start: 8517, end: 8530 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8590, end: 8593 } + }, + loc: { start: 8590, end: 8593 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 8531, end: 8536 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8538, end: 8541 } + }, + loc: { start: 8538, end: 8541 } + }, + loc: { start: 8531, end: 8541 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 8543, end: 8547 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8549, end: 8552 } + }, + loc: { start: 8549, end: 8552 } + }, + loc: { start: 8543, end: 8552 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'seconds', + loc: { start: 8554, end: 8561 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8563, end: 8566 } + }, + loc: { start: 8563, end: 8566 } + }, + loc: { start: 8554, end: 8566 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 8568, end: 8581 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 8583, end: 8587 } + }, + typeArgs: [], + loc: { start: 8583, end: 8587 } + }, + loc: { start: 8568, end: 8587 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETSTORAGEFEE' ] + }, + loc: { start: 8509, end: 8611 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getComputeFee', + loc: { start: 9734, end: 9747 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9784, end: 9787 } + }, + loc: { start: 9784, end: 9787 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'gasUsed', + loc: { start: 9748, end: 9755 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9757, end: 9760 } + }, + loc: { start: 9757, end: 9760 } + }, + loc: { start: 9748, end: 9760 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 9762, end: 9775 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 9777, end: 9781 } + }, + typeArgs: [], + loc: { start: 9777, end: 9781 } + }, + loc: { start: 9762, end: 9781 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETGASFEE' ] + }, + loc: { start: 9726, end: 9801 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSimpleComputeFee', + loc: { start: 10689, end: 10708 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10745, end: 10748 } + }, + loc: { start: 10745, end: 10748 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'gasUsed', + loc: { start: 10709, end: 10716 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10718, end: 10721 } + }, + loc: { start: 10718, end: 10721 } + }, + loc: { start: 10709, end: 10721 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 10723, end: 10736 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 10738, end: 10742 } + }, + typeArgs: [], + loc: { start: 10738, end: 10742 } + }, + loc: { start: 10723, end: 10742 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETGASFEESIMPLE' ] + }, + loc: { start: 10681, end: 10768 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getForwardFee', + loc: { start: 12543, end: 12556 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12602, end: 12605 } + }, + loc: { start: 12602, end: 12605 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 12557, end: 12562 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12564, end: 12567 } + }, + loc: { start: 12564, end: 12567 } + }, + loc: { start: 12557, end: 12567 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 12569, end: 12573 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12575, end: 12578 } + }, + loc: { start: 12575, end: 12578 } + }, + loc: { start: 12569, end: 12578 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 12580, end: 12593 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 12595, end: 12599 } + }, + typeArgs: [], + loc: { start: 12595, end: 12599 } + }, + loc: { start: 12580, end: 12599 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETFORWARDFEE' ] + }, + loc: { start: 12535, end: 12623 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSimpleForwardFee', + loc: { start: 13528, end: 13547 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13593, end: 13596 } + }, + loc: { start: 13593, end: 13596 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 13548, end: 13553 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13555, end: 13558 } + }, + loc: { start: 13555, end: 13558 } + }, + loc: { start: 13548, end: 13558 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 13560, end: 13564 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13566, end: 13569 } + }, + loc: { start: 13566, end: 13569 } + }, + loc: { start: 13560, end: 13569 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 13571, end: 13584 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 13586, end: 13590 } + }, + typeArgs: [], + loc: { start: 13586, end: 13590 } + }, + loc: { start: 13571, end: 13590 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETFORWARDFEESIMPLE' ] + }, + loc: { start: 13520, end: 13620 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getOriginalFwdFee', + loc: { start: 15782, end: 15799 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15835, end: 15838 } + }, + loc: { start: 15835, end: 15838 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'fwdFee', + loc: { start: 15800, end: 15806 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15808, end: 15811 } + }, + loc: { start: 15808, end: 15811 } + }, + loc: { start: 15800, end: 15811 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 15813, end: 15826 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 15828, end: 15832 } + }, + typeArgs: [], + loc: { start: 15828, end: 15832 } + }, + loc: { start: 15813, end: 15832 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETORIGINALFWDFEE' ] + }, + loc: { start: 15774, end: 15860 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'setGasLimit', + loc: { start: 16541, end: 16552 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'limit', + loc: { start: 16553, end: 16558 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 16560, end: 16563 } + }, + loc: { start: 16560, end: 16563 } + }, + loc: { start: 16553, end: 16563 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SETGASLIMIT' ] + }, + loc: { start: 16533, end: 16580 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSeed', + loc: { start: 17350, end: 17357 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 17361, end: 17364 } + }, + loc: { start: 17361, end: 17364 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RANDSEED' ] + }, + loc: { start: 17342, end: 17377 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'setSeed', + loc: { start: 18258, end: 18265 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'seed', + loc: { start: 18266, end: 18270 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 18272, end: 18275 } + }, + loc: { start: 18272, end: 18275 } + }, + loc: { start: 18266, end: 18275 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SETRAND' ] + }, + loc: { start: 18250, end: 18288 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myCode', + loc: { start: 18585, end: 18591 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 18595, end: 18599 } }, + loc: { start: 18595, end: 18599 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MYCODE' ] + }, + loc: { start: 18577, end: 18610 } + } + ] + }, + 'myCode' => { + kind: 'tact', + path: 'std/internal/contract.tact', + code: '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Computes and returns an `Int` value of the SHA-256 hash of the `code` and `data` of the given contract. To assemble the `code` and `data` cells together for hashing, the standard `Cell` representation is used.\n' + + '///\n' + + '/// This hash is commonly called account ID. Together with the workchain ID it deterministically forms the address of the contract on TON Blockchain.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let initPkg: StateInit = initOf SomeContract();\n' + + '/// let accountId: Int = contractHash(initPkg.code, initPkg.data);\n' + + '/// let basechainAddr: Address = newAddress(0, accountId);\n' + + '/// let basechainAddr2: Address = contractAddressExt(0, initPkg.code, initPkg.data);\n' + + '///\n' + + '/// basechainAddr == basechainAddr2; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contracthash\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#newaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '///\n' + + 'asm fun contractHash(code: Cell, data: Cell): Int {\n' + + ' // According to the https://docs.tact-lang.org/book/cells#cells-representation,\n' + + ' // the layout for the Builder to hash goes as follows:\n' + + ' // 1) refs_descriptor:bits8 | bits_descriptor:bits8 | data:bitsN\n' + + ' //\n' + + ' // refs_descriptor: ref_count + ((exotic? & 1) * 8) + (mask * 32)\n' + + ' // 2 refs (code + data), non-exotic, zero-mask\n' + + ' //\n' + + ' // bits_descriptor: floor(bit_count / 8) + ceil(bit_count, 8)\n' + + ' // floor (5 bits / 8) + ceil(5 bits / 8) = 0 + 1 = 1\n' + + ' //\n' + + ' // data: [0b00110] + [0b100] = [0b00110100] = 0x34 (data + augmented bits)\n' + + ' // 0b00110 - data (split_depth, special, code, data, Library)\n' + + ' // 0b100 - augmented bits (Leading 1 + zeroes to make section multiple of eight)\n' + + ' //\n' + + ' // That is: (2 << 16) | (1 << 8) | 0x34 = 131380 for all three.\n' + + ' //\n' + + ' // 2) and 3) depth_descriptors: CDEPTH of `code` and CDEPTH of `data`\n' + + ' // 4) and 5) ref hashes: HASHCU of `code` and HASHCU of `data`\n' + + '\n' + + ' // Group 1: Computations and arrangements\n' + + ' s0 PUSH HASHCU // `data` hash\n' + + ' s2 PUSH HASHCU // `code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `code` depth\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + '\n' + + ' // Group 2: Composition of the Builder\n' + + ' NEWC\n' + + ' 24 STU // store refs_descriptor | bits_descriptor | data\n' + + ' 16 STU // store depth_descriptor for `code`\n' + + ' 16 STU // store depth_descriptor for `data`\n' + + ' 256 STU // store `code` hash\n' + + ' 256 STU // store `data` hash\n' + + '\n' + + ' // Group 3: SHA256 hash of the resulting Builder\n' + + ' ONE HASHEXT_SHA256\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + "/// Computes smart contract's `Address` in the `chain` ID using the contract's `code` and the contract's initial state `data`. Use the `initOf` expression to obtain the initial `code` and initial `data` of a given contract.\n" + + '///\n' + + '/// This function lets you specify arbitrary `chain` IDs, including the common -1 (masterchain) and 0 (basechain) ones.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let initPkg: StateInit = initOf SomeContract();\n' + + '/// let hereBeDragons: Address = contractAddressExt(0, initPkg.code, initPkg.data);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '/// * https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'inline fun contractAddressExt(chain: Int, code: Cell, data: Cell): Address {\n' + + ' let hash = contractHash(code, data);\n' + + ' return newAddress(chain, hash);\n' + + '}\n' + + '\n' + + '/// Struct containing the initial state, i.e. initial code and initial data of the given contract upon its deployment.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'struct StateInit {\n' + + ' /// Initial code of the contract (compiled bitcode)\n' + + ' code: Cell;\n' + + '\n' + + ' /// Initial data of the contract (parameters of `init()` function or contract parameters)\n' + + ' data: Cell;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.1.\n' + + '///\n' + + '/// Efficiently compares if the given address matches the basechain address of the contract.\n' + + '/// Returns true if addresses are the same, false otherwise.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let init = initOf SomeContract();\n' + + "/// init.hasSameBasechainAddress(sender()); // returns true if sender matches contract's basechain address\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// This function provides a gas-optimized implementation compared to direct address comparison:\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let init = initOf SomeContract();\n' + + '/// sender() == contractAddress(sender()); // less efficient approach\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// Note that this function works only for basechain addresses!\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddress\n' + + '///\n' + + 'inline extends fun hasSameBasechainAddress(self: StateInit, sender: Address): Bool {\n' + + ' let senderAddress = parseStdAddress(sender.asSlice()).address;\n' + + ' let baseAddress = contractBasechainAddress(self);\n' + + ' return baseAddress.hash!! == senderAddress;\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + "/// Computes smart contract's `Address` in the workchain ID 0 (basechain) using the `StateInit` `s` of the contract. Alias to `contractAddressExt(0, s.code, s.data)`.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let s: StateInit = initOf SomeContract();\n' + + '/// let foundMeSome: Address = contractAddress(s);\n' + + '/// let andSomeMore: Address = contractAddressExt(0, s.code, s.data);\n' + + '///\n' + + '/// foundMeSome == andSomeMore; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '/// * https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'inline fun contractAddress(s: StateInit): Address {\n' + + ' return contractAddressExt(0, s.code, s.data);\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Returns the address of the current smart contract as an `Address`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let meMyselfAndI: Address = myAddress();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#myaddress\n' + + '///\n' + + 'asm fun myAddress(): Address { MYADDR }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` balance of the smart contract as it was at the start of the compute phase of the current transaction.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let iNeedADolla: Int = myBalance();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#mybalance\n' + + '///\n' + + 'asm fun myBalance(): Int { BALANCE FIRST }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` amount of gas consumed by TVM in the current transaction so far. The resulting value includes the cost of calling this function.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let gas: Int = gasConsumed();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#gasconsumed\n' + + '///\n' + + 'asm fun gasConsumed(): Int { GASCONSUMED }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` amount of the accumulated storage fee debt. Storage fees are deducted from the incoming message value before the new contract balance is calculated.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let debt: Int = myStorageDue();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#mystoragedue\n' + + '///\n' + + 'asm fun myStorageDue(): Int { DUEPAYMENT }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Calculates and returns the storage fee in nanoToncoins `Int` for storing a contract with a given number of `cells` and `bits` for a number of `seconds`. Uses the prices of the masterchain if `isMasterchain` is `true`, otherwise the prices of the basechain. The current prices are obtained from the config param 18 of TON Blockchain.\n' + + '///\n' + + '/// Note, that specifying values of `cells` and `bits` higher than their maximum values listed in account state limits (`max_acc_state_cells` and `max_acc_state_bits`) will have the same result as with specifying the exact limits. In addition, make sure you take into account the deduplication of cells with the same hash.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fee: Int = getStorageFee(1_000, 1_000, 1_000, false);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify negative number of `cells`, `bits` or `seconds`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-gas#getstoragefee\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun getStorageFee(cells: Int, bits: Int, seconds: Int, isMasterchain: Bool): Int { GETSTORAGEFEE }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Calculates and returns the compute fee in nanoToncoins `Int` for a transaction that consumed `gasUsed` amount of gas. Uses the prices of the masterchain if `isMasterchain` is `true`, otherwise the prices of the basechain. The current prices are obtained from the config param 20 for the masterchain and config param 21 for the basechain of TON Blockchain.\n' + + '///\n' + + "/// When the `gasUsed` is less than a certain threshold called `flat_gas_limit`, there's a minimum price to pay based on the value of `flat_gas_price`. The less gas is used below this threshold, the higher the minimum price will be. See the example for `getSimpleComputeFee()` to derive that threshold.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fee: Int = getComputeFee(1_000, false);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify negative value of `gasUsed`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-gas#getcomputefee\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun getComputeFee(gasUsed: Int, isMasterchain: Bool): Int { GETGASFEE }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Similar to `getComputeFee()`, but without the `flat_gas_price`, i.e. without a minimum price to pay if the `gasUsed` is less than a certain '... 8611 more characters, + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'contractHash', + loc: { start: 1027, end: 1039 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1065, end: 1068 } + }, + loc: { start: 1065, end: 1068 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 1040, end: 1044 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 1046, end: 1050 } }, + loc: { start: 1046, end: 1050 } + }, + loc: { start: 1040, end: 1050 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'data', + loc: { start: 1052, end: 1056 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 1058, end: 1062 } }, + loc: { start: 1058, end: 1062 } + }, + loc: { start: 1052, end: 1062 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 's0 PUSH HASHCU // `data` hash\n' + + ' s2 PUSH HASHCU // `code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `code` depth\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + '\n' + + ' // Group 2: Composition of the Builder\n' + + ' NEWC\n' + + ' 24 STU // store refs_descriptor | bits_descriptor | data\n' + + ' 16 STU // store depth_descriptor for `code`\n' + + ' 16 STU // store depth_descriptor for `data`\n' + + ' 256 STU // store `code` hash\n' + + ' 256 STU // store `data` hash\n' + + '\n' + + ' // Group 3: SHA256 hash of the resulting Builder\n' + + ' ONE HASHEXT_SHA256' + ] + }, + loc: { start: 1019, end: 2666 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'contractAddressExt', + loc: { start: 3391, end: 3409 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3447, end: 3454 } + }, + typeArgs: [], + loc: { start: 3447, end: 3454 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'chain', + loc: { start: 3410, end: 3415 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3417, end: 3420 } + }, + loc: { start: 3417, end: 3420 } + }, + loc: { start: 3410, end: 3420 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 3422, end: 3426 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3428, end: 3432 } }, + loc: { start: 3428, end: 3432 } + }, + loc: { start: 3422, end: 3432 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'data', + loc: { start: 3434, end: 3438 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3440, end: 3444 } }, + loc: { start: 3440, end: 3444 } + }, + loc: { start: 3434, end: 3444 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'hash', + loc: { start: 3465, end: 3469 } + }, + type: undefined, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractHash', + loc: { start: 3472, end: 3484 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'code', + loc: { start: 3485, end: 3489 } + }, + { + kind: 'var', + name: 'data', + loc: { start: 3491, end: 3495 } + } + ], + loc: { start: 3472, end: 3496 } + }, + loc: { start: 3461, end: 3497 } + }, + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'newAddress', + loc: { start: 3509, end: 3519 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'chain', + loc: { start: 3520, end: 3525 } + }, + { + kind: 'var', + name: 'hash', + loc: { start: 3527, end: 3531 } + } + ], + loc: { start: 3509, end: 3532 } + }, + loc: { start: 3502, end: 3533 } + } + ] + }, + loc: { start: 3380, end: 3535 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 3731, end: 3740 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'code', + loc: { start: 3803, end: 3807 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3809, end: 3813 } }, + loc: { start: 3809, end: 3813 } + }, + initializer: undefined, + loc: { start: 3803, end: 3813 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'data', + loc: { start: 3914, end: 3918 } + }, + type: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 3920, end: 3924 } }, + loc: { start: 3920, end: 3924 } + }, + initializer: undefined, + loc: { start: 3914, end: 3924 } + } + ], + loc: { start: 3724, end: 3927 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'hasSameBasechainAddress', + loc: { start: 4778, end: 4801 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 4837, end: 4841 } + }, + typeArgs: [], + loc: { start: 4837, end: 4841 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'sender', + loc: { start: 4819, end: 4825 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 4827, end: 4834 } + }, + typeArgs: [], + loc: { start: 4827, end: 4834 } + }, + loc: { start: 4819, end: 4834 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'senderAddress', + loc: { start: 4852, end: 4865 } + }, + type: undefined, + expression: { + kind: 'field_access', + aggregate: { + kind: 'static_call', + function: { + kind: 'id', + text: 'parseStdAddress', + loc: { start: 4868, end: 4883 } + }, + typeArgs: [], + args: [ + { + kind: 'method_call', + self: { + kind: 'var', + name: 'sender', + loc: { start: 4884, end: 4890 } + }, + method: { + kind: 'id', + text: 'asSlice', + loc: { start: 4891, end: 4898 } + }, + typeArgs: [], + args: [], + loc: { start: 4884, end: 4900 } + } + ], + loc: { start: 4868, end: 4901 } + }, + field: { + kind: 'id', + text: 'address', + loc: { start: 4902, end: 4909 } + }, + loc: { start: 4868, end: 4909 } + }, + loc: { start: 4848, end: 4910 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'baseAddress', + loc: { start: 4919, end: 4930 } + }, + type: undefined, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractBasechainAddress', + loc: { start: 4933, end: 4957 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'self', + loc: { start: 4958, end: 4962 } + } + ], + loc: { start: 4933, end: 4963 } + }, + loc: { start: 4915, end: 4964 } + }, + { + kind: 'statement_return', + expression: { + kind: 'op_binary', + op: '==', + left: { + kind: 'op_unary', + op: '!!', + operand: { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'baseAddress', + loc: { start: 4976, end: 4987 } + }, + field: { + kind: 'id', + text: 'hash', + loc: { start: 4988, end: 4992 } + }, + loc: { start: 4976, end: 4992 } + }, + loc: { start: 4976, end: 4994 } + }, + right: { + kind: 'var', + name: 'senderAddress', + loc: { start: 4998, end: 5011 } + }, + loc: { start: 4976, end: 5011 } + }, + loc: { start: 4969, end: 5012 } + } + ] + }, + loc: { start: 4759, end: 5014 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 4808, end: 4817 } + }, + typeArgs: [], + loc: { start: 4808, end: 4817 } + } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'contractAddress', + loc: { start: 5709, end: 5724 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 5740, end: 5747 } + }, + typeArgs: [], + loc: { start: 5740, end: 5747 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 's', + loc: { start: 5725, end: 5726 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 5728, end: 5737 } + }, + typeArgs: [], + loc: { start: 5728, end: 5737 } + }, + loc: { start: 5725, end: 5737 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractAddressExt', + loc: { start: 5761, end: 5779 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 5780, end: 5781 } + }, + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 5783, end: 5784 } + }, + field: { + kind: 'id', + text: 'code', + loc: { start: 5785, end: 5789 } + }, + loc: { start: 5783, end: 5789 } + }, + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 5791, end: 5792 } + }, + field: { + kind: 'id', + text: 'data', + loc: { start: 5793, end: 5797 } + }, + loc: { start: 5791, end: 5797 } + } + ], + loc: { start: 5761, end: 5798 } + }, + loc: { start: 5754, end: 5799 } + } + ] + }, + loc: { start: 5698, end: 5801 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myAddress', + loc: { start: 6082, end: 6091 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 6095, end: 6102 } + }, + typeArgs: [], + loc: { start: 6095, end: 6102 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MYADDR' ] + }, + loc: { start: 6074, end: 6113 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myBalance', + loc: { start: 6454, end: 6463 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6467, end: 6470 } + }, + loc: { start: 6467, end: 6470 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'BALANCE FIRST' ] + }, + loc: { start: 6446, end: 6488 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'gasConsumed', + loc: { start: 6880, end: 6891 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6895, end: 6898 } + }, + loc: { start: 6895, end: 6898 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GASCONSUMED' ] + }, + loc: { start: 6872, end: 6914 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myStorageDue', + loc: { start: 7329, end: 7341 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7345, end: 7348 } + }, + loc: { start: 7345, end: 7348 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DUEPAYMENT' ] + }, + loc: { start: 7321, end: 7363 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getStorageFee', + loc: { start: 8517, end: 8530 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8590, end: 8593 } + }, + loc: { start: 8590, end: 8593 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 8531, end: 8536 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8538, end: 8541 } + }, + loc: { start: 8538, end: 8541 } + }, + loc: { start: 8531, end: 8541 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 8543, end: 8547 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8549, end: 8552 } + }, + loc: { start: 8549, end: 8552 } + }, + loc: { start: 8543, end: 8552 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'seconds', + loc: { start: 8554, end: 8561 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8563, end: 8566 } + }, + loc: { start: 8563, end: 8566 } + }, + loc: { start: 8554, end: 8566 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 8568, end: 8581 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 8583, end: 8587 } + }, + typeArgs: [], + loc: { start: 8583, end: 8587 } + }, + loc: { start: 8568, end: 8587 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETSTORAGEFEE' ] + }, + loc: { start: 8509, end: 8611 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getComputeFee', + loc: { start: 9734, end: 9747 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9784, end: 9787 } + }, + loc: { start: 9784, end: 9787 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'gasUsed', + loc: { start: 9748, end: 9755 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9757, end: 9760 } + }, + loc: { start: 9757, end: 9760 } + }, + loc: { start: 9748, end: 9760 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 9762, end: 9775 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 9777, end: 9781 } + }, + typeArgs: [], + loc: { start: 9777, end: 9781 } + }, + loc: { start: 9762, end: 9781 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETGASFEE' ] + }, + loc: { start: 9726, end: 9801 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSimpleComputeFee', + loc: { start: 10689, end: 10708 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10745, end: 10748 } + }, + loc: { start: 10745, end: 10748 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'gasUsed', + loc: { start: 10709, end: 10716 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10718, end: 10721 } + }, + loc: { start: 10718, end: 10721 } + }, + loc: { start: 10709, end: 10721 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 10723, end: 10736 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 10738, end: 10742 } + }, + typeArgs: [], + loc: { start: 10738, end: 10742 } + }, + loc: { start: 10723, end: 10742 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETGASFEESIMPLE' ] + }, + loc: { start: 10681, end: 10768 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getForwardFee', + loc: { start: 12543, end: 12556 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12602, end: 12605 } + }, + loc: { start: 12602, end: 12605 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 12557, end: 12562 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12564, end: 12567 } + }, + loc: { start: 12564, end: 12567 } + }, + loc: { start: 12557, end: 12567 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 12569, end: 12573 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12575, end: 12578 } + }, + loc: { start: 12575, end: 12578 } + }, + loc: { start: 12569, end: 12578 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 12580, end: 12593 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 12595, end: 12599 } + }, + typeArgs: [], + loc: { start: 12595, end: 12599 } + }, + loc: { start: 12580, end: 12599 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETFORWARDFEE' ] + }, + loc: { start: 12535, end: 12623 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSimpleForwardFee', + loc: { start: 13528, end: 13547 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13593, end: 13596 } + }, + loc: { start: 13593, end: 13596 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 13548, end: 13553 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13555, end: 13558 } + }, + loc: { start: 13555, end: 13558 } + }, + loc: { start: 13548, end: 13558 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 13560, end: 13564 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13566, end: 13569 } + }, + loc: { start: 13566, end: 13569 } + }, + loc: { start: 13560, end: 13569 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 13571, end: 13584 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 13586, end: 13590 } + }, + typeArgs: [], + loc: { start: 13586, end: 13590 } + }, + loc: { start: 13571, end: 13590 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETFORWARDFEESIMPLE' ] + }, + loc: { start: 13520, end: 13620 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getOriginalFwdFee', + loc: { start: 15782, end: 15799 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15835, end: 15838 } + }, + loc: { start: 15835, end: 15838 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'fwdFee', + loc: { start: 15800, end: 15806 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15808, end: 15811 } + }, + loc: { start: 15808, end: 15811 } + }, + loc: { start: 15800, end: 15811 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 15813, end: 15826 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 15828, end: 15832 } + }, + typeArgs: [], + loc: { start: 15828, end: 15832 } + }, + loc: { start: 15813, end: 15832 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETORIGINALFWDFEE' ] + }, + loc: { start: 15774, end: 15860 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'setGasLimit', + loc: { start: 16541, end: 16552 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'limit', + loc: { start: 16553, end: 16558 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 16560, end: 16563 } + }, + loc: { start: 16560, end: 16563 } + }, + loc: { start: 16553, end: 16563 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SETGASLIMIT' ] + }, + loc: { start: 16533, end: 16580 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSeed', + loc: { start: 17350, end: 17357 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 17361, end: 17364 } + }, + loc: { start: 17361, end: 17364 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RANDSEED' ] + }, + loc: { start: 17342, end: 17377 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'setSeed', + loc: { start: 18258, end: 18265 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'seed', + loc: { start: 18266, end: 18270 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 18272, end: 18275 } + }, + loc: { start: 18272, end: 18275 } + }, + loc: { start: 18266, end: 18275 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SETRAND' ] + }, + loc: { start: 18250, end: 18288 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myCode', + loc: { start: 18585, end: 18591 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 18595, end: 18599 } }, + loc: { start: 18595, end: 18599 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MYCODE' ] + }, + loc: { start: 18577, end: 18610 } + } + ] + }, + 'throw' => { + kind: 'tact', + path: 'std/internal/debug.tact', + code: '// these are builtin functions, these get special treatment from FunC\n' + + '// hence, no asm here\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Unconditionally throws an exception with an error `code`.\n' + + '///\n' + + '/// Execution of the current context stops, statements after `throw` are not executed, and control is passed to the first `try...catch` block on the call stack. If there is no `try` or `try...catch` block among the calling functions, TVM will terminate the transaction.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun thisWillTerminateAbruptly() {\n' + + '/// throw(1042); // throwing with exit code 1042\n' + + '/// }\n' + + '///\n' + + '/// fun butThisWont() {\n' + + '/// try {\n' + + '/// throw(1042); // throwing with exit code 1042\n' + + '/// }\n' + + '///\n' + + '/// // ... follow-up logic ...\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify the `code` outside of 0-65535 range.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#throw\n' + + '/// * https://docs.tact-lang.org/book/statements#try-catch\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + '@name(throw)\n' + + 'native throw(code: Int);\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + "/// Similar to `throw()`, but throws an error `code` only if `condition` holds, i.e. `condition` is equal to `true`. Doesn't throw otherwise.\n" + + '///\n' + + '/// ```tact\n' + + '/// contract Ownership {\n' + + '/// owner: Address;\n' + + '///\n' + + '/// init() {\n' + + '/// self.owner = myAddress();\n' + + '/// }\n' + + '///\n' + + '/// receive() {\n' + + '/// // Check the sender is the owner of the contract,\n' + + "/// // and throw exit code 1024 if it's not\n" + + '/// throwIf(1024, sender() != self.owner);\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify the `code` outside of 0-65535 range.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#throwif\n' + + '/// * https://docs.tact-lang.org/book/statements#try-catch\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + '@name(throw_if)\n' + + 'native throwIf(code: Int, condition: Bool);\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + "/// Similar to `throw()`, but throws an error `code` only if `condition` does **not** hold, i.e. `condition` is equal to `true`. Doesn't throw otherwise.\n" + + '///\n' + + '/// This function is also similar to `require()`, but uses the specified `code` directly instead of generating one based on the given error message `String`.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Ownership {\n' + + '/// owner: Address;\n' + + '///\n' + + '/// init() {\n' + + '/// self.owner = myAddress();\n' + + '/// }\n' + + '///\n' + + '/// receive() {\n' + + '/// // Check the sender is the owner of the contract,\n' + + "/// // and throw exit code 1024 if it's not\n" + + '/// throwUnless(1024, sender() == self.owner);\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify the `code` outside of 0-65535 range.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#throwunless\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#require\n' + + '/// * https://docs.tact-lang.org/book/statements#try-catch\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + '@name(throw_unless)\n' + + 'native throwUnless(code: Int, condition: Bool);\n' + + '\n' + + '/// Global function. **Deprecated** since Tact 1.6.0.\n' + + '///\n' + + '/// Use `throw()` instead.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#throw\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#nativethrow\n' + + '///\n' + + '@name(throw)\n' + + 'native nativeThrow(code: Int);\n' + + '\n' + + '/// Global function. **Deprecated** since Tact 1.6.0.\n' + + '///\n' + + '/// Use `throwIf()` instead.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#throwif\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#nativethrowif\n' + + '///\n' + + '@name(throw_if)\n' + + 'native nativeThrowIf(code: Int, condition: Bool);\n' + + '\n' + + '/// Global function. **Deprecated** since Tact 1.6.0.\n' + + '///\n' + + '/// Use `throwUnless()` instead.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#throwunless\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#nativethrowunless\n' + + '///\n' + + '@name(throw_unless)\n' + + 'native nativeThrowUnless(code: Int, condition: Bool);\n', + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'throw', + loc: { start: 1107, end: 1112 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 1113, end: 1117 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1119, end: 1122 } + }, + loc: { start: 1119, end: 1122 } + }, + loc: { start: 1113, end: 1122 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'throw', + loc: { start: 1093, end: 1098 } + } + }, + loc: { start: 1087, end: 1124 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'throwIf', + loc: { start: 2051, end: 2058 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 2059, end: 2063 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2065, end: 2068 } + }, + loc: { start: 2065, end: 2068 } + }, + loc: { start: 2059, end: 2068 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'condition', + loc: { start: 2070, end: 2079 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 2081, end: 2085 } + }, + typeArgs: [], + loc: { start: 2081, end: 2085 } + }, + loc: { start: 2070, end: 2085 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'throw_if', + loc: { start: 2034, end: 2042 } + } + }, + loc: { start: 2028, end: 2087 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'throwUnless', + loc: { start: 3256, end: 3267 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 3268, end: 3272 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3274, end: 3277 } + }, + loc: { start: 3274, end: 3277 } + }, + loc: { start: 3268, end: 3277 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'condition', + loc: { start: 3279, end: 3288 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 3290, end: 3294 } + }, + typeArgs: [], + loc: { start: 3290, end: 3294 } + }, + loc: { start: 3279, end: 3294 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'throw_unless', + loc: { start: 3235, end: 3247 } + } + }, + loc: { start: 3229, end: 3296 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeThrow', + loc: { start: 3534, end: 3545 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 3546, end: 3550 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3552, end: 3555 } + }, + loc: { start: 3552, end: 3555 } + }, + loc: { start: 3546, end: 3555 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'throw', + loc: { start: 3520, end: 3525 } + } + }, + loc: { start: 3514, end: 3557 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeThrowIf', + loc: { start: 3804, end: 3817 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 3818, end: 3822 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3824, end: 3827 } + }, + loc: { start: 3824, end: 3827 } + }, + loc: { start: 3818, end: 3827 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'condition', + loc: { start: 3829, end: 3838 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 3840, end: 3844 } + }, + typeArgs: [], + loc: { start: 3840, end: 3844 } + }, + loc: { start: 3829, end: 3844 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'throw_if', + loc: { start: 3787, end: 3795 } + } + }, + loc: { start: 3781, end: 3846 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeThrowUnless', + loc: { start: 4109, end: 4126 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 4127, end: 4131 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4133, end: 4136 } + }, + loc: { start: 4133, end: 4136 } + }, + loc: { start: 4127, end: 4136 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'condition', + loc: { start: 4138, end: 4147 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 4149, end: 4153 } + }, + typeArgs: [], + loc: { start: 4149, end: 4153 } + }, + loc: { start: 4138, end: 4153 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'throw_unless', + loc: { start: 4088, end: 4100 } + } + }, + loc: { start: 4082, end: 4155 } + } + ] + }, + 'throwIf' => { + kind: 'tact', + path: 'std/internal/debug.tact', + code: '// these are builtin functions, these get special treatment from FunC\n' + + '// hence, no asm here\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Unconditionally throws an exception with an error `code`.\n' + + '///\n' + + '/// Execution of the current context stops, statements after `throw` are not executed, and control is passed to the first `try...catch` block on the call stack. If there is no `try` or `try...catch` block among the calling functions, TVM will terminate the transaction.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun thisWillTerminateAbruptly() {\n' + + '/// throw(1042); // throwing with exit code 1042\n' + + '/// }\n' + + '///\n' + + '/// fun butThisWont() {\n' + + '/// try {\n' + + '/// throw(1042); // throwing with exit code 1042\n' + + '/// }\n' + + '///\n' + + '/// // ... follow-up logic ...\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify the `code` outside of 0-65535 range.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#throw\n' + + '/// * https://docs.tact-lang.org/book/statements#try-catch\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + '@name(throw)\n' + + 'native throw(code: Int);\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + "/// Similar to `throw()`, but throws an error `code` only if `condition` holds, i.e. `condition` is equal to `true`. Doesn't throw otherwise.\n" + + '///\n' + + '/// ```tact\n' + + '/// contract Ownership {\n' + + '/// owner: Address;\n' + + '///\n' + + '/// init() {\n' + + '/// self.owner = myAddress();\n' + + '/// }\n' + + '///\n' + + '/// receive() {\n' + + '/// // Check the sender is the owner of the contract,\n' + + "/// // and throw exit code 1024 if it's not\n" + + '/// throwIf(1024, sender() != self.owner);\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify the `code` outside of 0-65535 range.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#throwif\n' + + '/// * https://docs.tact-lang.org/book/statements#try-catch\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + '@name(throw_if)\n' + + 'native throwIf(code: Int, condition: Bool);\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + "/// Similar to `throw()`, but throws an error `code` only if `condition` does **not** hold, i.e. `condition` is equal to `true`. Doesn't throw otherwise.\n" + + '///\n' + + '/// This function is also similar to `require()`, but uses the specified `code` directly instead of generating one based on the given error message `String`.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Ownership {\n' + + '/// owner: Address;\n' + + '///\n' + + '/// init() {\n' + + '/// self.owner = myAddress();\n' + + '/// }\n' + + '///\n' + + '/// receive() {\n' + + '/// // Check the sender is the owner of the contract,\n' + + "/// // and throw exit code 1024 if it's not\n" + + '/// throwUnless(1024, sender() == self.owner);\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify the `code` outside of 0-65535 range.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#throwunless\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#require\n' + + '/// * https://docs.tact-lang.org/book/statements#try-catch\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + '@name(throw_unless)\n' + + 'native throwUnless(code: Int, condition: Bool);\n' + + '\n' + + '/// Global function. **Deprecated** since Tact 1.6.0.\n' + + '///\n' + + '/// Use `throw()` instead.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#throw\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#nativethrow\n' + + '///\n' + + '@name(throw)\n' + + 'native nativeThrow(code: Int);\n' + + '\n' + + '/// Global function. **Deprecated** since Tact 1.6.0.\n' + + '///\n' + + '/// Use `throwIf()` instead.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#throwif\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#nativethrowif\n' + + '///\n' + + '@name(throw_if)\n' + + 'native nativeThrowIf(code: Int, condition: Bool);\n' + + '\n' + + '/// Global function. **Deprecated** since Tact 1.6.0.\n' + + '///\n' + + '/// Use `throwUnless()` instead.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#throwunless\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#nativethrowunless\n' + + '///\n' + + '@name(throw_unless)\n' + + 'native nativeThrowUnless(code: Int, condition: Bool);\n', + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'throw', + loc: { start: 1107, end: 1112 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 1113, end: 1117 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1119, end: 1122 } + }, + loc: { start: 1119, end: 1122 } + }, + loc: { start: 1113, end: 1122 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'throw', + loc: { start: 1093, end: 1098 } + } + }, + loc: { start: 1087, end: 1124 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'throwIf', + loc: { start: 2051, end: 2058 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 2059, end: 2063 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2065, end: 2068 } + }, + loc: { start: 2065, end: 2068 } + }, + loc: { start: 2059, end: 2068 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'condition', + loc: { start: 2070, end: 2079 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 2081, end: 2085 } + }, + typeArgs: [], + loc: { start: 2081, end: 2085 } + }, + loc: { start: 2070, end: 2085 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'throw_if', + loc: { start: 2034, end: 2042 } + } + }, + loc: { start: 2028, end: 2087 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'throwUnless', + loc: { start: 3256, end: 3267 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 3268, end: 3272 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3274, end: 3277 } + }, + loc: { start: 3274, end: 3277 } + }, + loc: { start: 3268, end: 3277 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'condition', + loc: { start: 3279, end: 3288 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 3290, end: 3294 } + }, + typeArgs: [], + loc: { start: 3290, end: 3294 } + }, + loc: { start: 3279, end: 3294 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'throw_unless', + loc: { start: 3235, end: 3247 } + } + }, + loc: { start: 3229, end: 3296 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeThrow', + loc: { start: 3534, end: 3545 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 3546, end: 3550 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3552, end: 3555 } + }, + loc: { start: 3552, end: 3555 } + }, + loc: { start: 3546, end: 3555 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'throw', + loc: { start: 3520, end: 3525 } + } + }, + loc: { start: 3514, end: 3557 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeThrowIf', + loc: { start: 3804, end: 3817 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 3818, end: 3822 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3824, end: 3827 } + }, + loc: { start: 3824, end: 3827 } + }, + loc: { start: 3818, end: 3827 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'condition', + loc: { start: 3829, end: 3838 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 3840, end: 3844 } + }, + typeArgs: [], + loc: { start: 3840, end: 3844 } + }, + loc: { start: 3829, end: 3844 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'throw_if', + loc: { start: 3787, end: 3795 } + } + }, + loc: { start: 3781, end: 3846 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeThrowUnless', + loc: { start: 4109, end: 4126 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 4127, end: 4131 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4133, end: 4136 } + }, + loc: { start: 4133, end: 4136 } + }, + loc: { start: 4127, end: 4136 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'condition', + loc: { start: 4138, end: 4147 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 4149, end: 4153 } + }, + typeArgs: [], + loc: { start: 4149, end: 4153 } + }, + loc: { start: 4138, end: 4153 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'throw_unless', + loc: { start: 4088, end: 4100 } + } + }, + loc: { start: 4082, end: 4155 } + } + ] + }, + 'throwUnless' => { + kind: 'tact', + path: 'std/internal/debug.tact', + code: '// these are builtin functions, these get special treatment from FunC\n' + + '// hence, no asm here\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Unconditionally throws an exception with an error `code`.\n' + + '///\n' + + '/// Execution of the current context stops, statements after `throw` are not executed, and control is passed to the first `try...catch` block on the call stack. If there is no `try` or `try...catch` block among the calling functions, TVM will terminate the transaction.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun thisWillTerminateAbruptly() {\n' + + '/// throw(1042); // throwing with exit code 1042\n' + + '/// }\n' + + '///\n' + + '/// fun butThisWont() {\n' + + '/// try {\n' + + '/// throw(1042); // throwing with exit code 1042\n' + + '/// }\n' + + '///\n' + + '/// // ... follow-up logic ...\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify the `code` outside of 0-65535 range.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#throw\n' + + '/// * https://docs.tact-lang.org/book/statements#try-catch\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + '@name(throw)\n' + + 'native throw(code: Int);\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + "/// Similar to `throw()`, but throws an error `code` only if `condition` holds, i.e. `condition` is equal to `true`. Doesn't throw otherwise.\n" + + '///\n' + + '/// ```tact\n' + + '/// contract Ownership {\n' + + '/// owner: Address;\n' + + '///\n' + + '/// init() {\n' + + '/// self.owner = myAddress();\n' + + '/// }\n' + + '///\n' + + '/// receive() {\n' + + '/// // Check the sender is the owner of the contract,\n' + + "/// // and throw exit code 1024 if it's not\n" + + '/// throwIf(1024, sender() != self.owner);\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify the `code` outside of 0-65535 range.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#throwif\n' + + '/// * https://docs.tact-lang.org/book/statements#try-catch\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + '@name(throw_if)\n' + + 'native throwIf(code: Int, condition: Bool);\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + "/// Similar to `throw()`, but throws an error `code` only if `condition` does **not** hold, i.e. `condition` is equal to `true`. Doesn't throw otherwise.\n" + + '///\n' + + '/// This function is also similar to `require()`, but uses the specified `code` directly instead of generating one based on the given error message `String`.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Ownership {\n' + + '/// owner: Address;\n' + + '///\n' + + '/// init() {\n' + + '/// self.owner = myAddress();\n' + + '/// }\n' + + '///\n' + + '/// receive() {\n' + + '/// // Check the sender is the owner of the contract,\n' + + "/// // and throw exit code 1024 if it's not\n" + + '/// throwUnless(1024, sender() == self.owner);\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify the `code` outside of 0-65535 range.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#throwunless\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#require\n' + + '/// * https://docs.tact-lang.org/book/statements#try-catch\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + '@name(throw_unless)\n' + + 'native throwUnless(code: Int, condition: Bool);\n' + + '\n' + + '/// Global function. **Deprecated** since Tact 1.6.0.\n' + + '///\n' + + '/// Use `throw()` instead.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#throw\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#nativethrow\n' + + '///\n' + + '@name(throw)\n' + + 'native nativeThrow(code: Int);\n' + + '\n' + + '/// Global function. **Deprecated** since Tact 1.6.0.\n' + + '///\n' + + '/// Use `throwIf()` instead.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#throwif\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#nativethrowif\n' + + '///\n' + + '@name(throw_if)\n' + + 'native nativeThrowIf(code: Int, condition: Bool);\n' + + '\n' + + '/// Global function. **Deprecated** since Tact 1.6.0.\n' + + '///\n' + + '/// Use `throwUnless()` instead.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#throwunless\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#nativethrowunless\n' + + '///\n' + + '@name(throw_unless)\n' + + 'native nativeThrowUnless(code: Int, condition: Bool);\n', + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'throw', + loc: { start: 1107, end: 1112 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 1113, end: 1117 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1119, end: 1122 } + }, + loc: { start: 1119, end: 1122 } + }, + loc: { start: 1113, end: 1122 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'throw', + loc: { start: 1093, end: 1098 } + } + }, + loc: { start: 1087, end: 1124 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'throwIf', + loc: { start: 2051, end: 2058 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 2059, end: 2063 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2065, end: 2068 } + }, + loc: { start: 2065, end: 2068 } + }, + loc: { start: 2059, end: 2068 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'condition', + loc: { start: 2070, end: 2079 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 2081, end: 2085 } + }, + typeArgs: [], + loc: { start: 2081, end: 2085 } + }, + loc: { start: 2070, end: 2085 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'throw_if', + loc: { start: 2034, end: 2042 } + } + }, + loc: { start: 2028, end: 2087 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'throwUnless', + loc: { start: 3256, end: 3267 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 3268, end: 3272 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3274, end: 3277 } + }, + loc: { start: 3274, end: 3277 } + }, + loc: { start: 3268, end: 3277 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'condition', + loc: { start: 3279, end: 3288 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 3290, end: 3294 } + }, + typeArgs: [], + loc: { start: 3290, end: 3294 } + }, + loc: { start: 3279, end: 3294 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'throw_unless', + loc: { start: 3235, end: 3247 } + } + }, + loc: { start: 3229, end: 3296 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeThrow', + loc: { start: 3534, end: 3545 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 3546, end: 3550 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3552, end: 3555 } + }, + loc: { start: 3552, end: 3555 } + }, + loc: { start: 3546, end: 3555 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'throw', + loc: { start: 3520, end: 3525 } + } + }, + loc: { start: 3514, end: 3557 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeThrowIf', + loc: { start: 3804, end: 3817 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 3818, end: 3822 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3824, end: 3827 } + }, + loc: { start: 3824, end: 3827 } + }, + loc: { start: 3818, end: 3827 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'condition', + loc: { start: 3829, end: 3838 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 3840, end: 3844 } + }, + typeArgs: [], + loc: { start: 3840, end: 3844 } + }, + loc: { start: 3829, end: 3844 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'throw_if', + loc: { start: 3787, end: 3795 } + } + }, + loc: { start: 3781, end: 3846 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeThrowUnless', + loc: { start: 4109, end: 4126 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 4127, end: 4131 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4133, end: 4136 } + }, + loc: { start: 4133, end: 4136 } + }, + loc: { start: 4127, end: 4136 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'condition', + loc: { start: 4138, end: 4147 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 4149, end: 4153 } + }, + typeArgs: [], + loc: { start: 4149, end: 4153 } + }, + loc: { start: 4138, end: 4153 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'throw_unless', + loc: { start: 4088, end: 4100 } + } + }, + loc: { start: 4082, end: 4155 } + } + ] + }, + 'nativeThrow' => { + kind: 'tact', + path: 'std/internal/debug.tact', + code: '// these are builtin functions, these get special treatment from FunC\n' + + '// hence, no asm here\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Unconditionally throws an exception with an error `code`.\n' + + '///\n' + + '/// Execution of the current context stops, statements after `throw` are not executed, and control is passed to the first `try...catch` block on the call stack. If there is no `try` or `try...catch` block among the calling functions, TVM will terminate the transaction.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun thisWillTerminateAbruptly() {\n' + + '/// throw(1042); // throwing with exit code 1042\n' + + '/// }\n' + + '///\n' + + '/// fun butThisWont() {\n' + + '/// try {\n' + + '/// throw(1042); // throwing with exit code 1042\n' + + '/// }\n' + + '///\n' + + '/// // ... follow-up logic ...\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify the `code` outside of 0-65535 range.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#throw\n' + + '/// * https://docs.tact-lang.org/book/statements#try-catch\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + '@name(throw)\n' + + 'native throw(code: Int);\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + "/// Similar to `throw()`, but throws an error `code` only if `condition` holds, i.e. `condition` is equal to `true`. Doesn't throw otherwise.\n" + + '///\n' + + '/// ```tact\n' + + '/// contract Ownership {\n' + + '/// owner: Address;\n' + + '///\n' + + '/// init() {\n' + + '/// self.owner = myAddress();\n' + + '/// }\n' + + '///\n' + + '/// receive() {\n' + + '/// // Check the sender is the owner of the contract,\n' + + "/// // and throw exit code 1024 if it's not\n" + + '/// throwIf(1024, sender() != self.owner);\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify the `code` outside of 0-65535 range.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#throwif\n' + + '/// * https://docs.tact-lang.org/book/statements#try-catch\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + '@name(throw_if)\n' + + 'native throwIf(code: Int, condition: Bool);\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + "/// Similar to `throw()`, but throws an error `code` only if `condition` does **not** hold, i.e. `condition` is equal to `true`. Doesn't throw otherwise.\n" + + '///\n' + + '/// This function is also similar to `require()`, but uses the specified `code` directly instead of generating one based on the given error message `String`.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Ownership {\n' + + '/// owner: Address;\n' + + '///\n' + + '/// init() {\n' + + '/// self.owner = myAddress();\n' + + '/// }\n' + + '///\n' + + '/// receive() {\n' + + '/// // Check the sender is the owner of the contract,\n' + + "/// // and throw exit code 1024 if it's not\n" + + '/// throwUnless(1024, sender() == self.owner);\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify the `code` outside of 0-65535 range.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#throwunless\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#require\n' + + '/// * https://docs.tact-lang.org/book/statements#try-catch\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + '@name(throw_unless)\n' + + 'native throwUnless(code: Int, condition: Bool);\n' + + '\n' + + '/// Global function. **Deprecated** since Tact 1.6.0.\n' + + '///\n' + + '/// Use `throw()` instead.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#throw\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#nativethrow\n' + + '///\n' + + '@name(throw)\n' + + 'native nativeThrow(code: Int);\n' + + '\n' + + '/// Global function. **Deprecated** since Tact 1.6.0.\n' + + '///\n' + + '/// Use `throwIf()` instead.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#throwif\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#nativethrowif\n' + + '///\n' + + '@name(throw_if)\n' + + 'native nativeThrowIf(code: Int, condition: Bool);\n' + + '\n' + + '/// Global function. **Deprecated** since Tact 1.6.0.\n' + + '///\n' + + '/// Use `throwUnless()` instead.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#throwunless\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#nativethrowunless\n' + + '///\n' + + '@name(throw_unless)\n' + + 'native nativeThrowUnless(code: Int, condition: Bool);\n', + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'throw', + loc: { start: 1107, end: 1112 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 1113, end: 1117 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1119, end: 1122 } + }, + loc: { start: 1119, end: 1122 } + }, + loc: { start: 1113, end: 1122 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'throw', + loc: { start: 1093, end: 1098 } + } + }, + loc: { start: 1087, end: 1124 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'throwIf', + loc: { start: 2051, end: 2058 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 2059, end: 2063 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2065, end: 2068 } + }, + loc: { start: 2065, end: 2068 } + }, + loc: { start: 2059, end: 2068 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'condition', + loc: { start: 2070, end: 2079 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 2081, end: 2085 } + }, + typeArgs: [], + loc: { start: 2081, end: 2085 } + }, + loc: { start: 2070, end: 2085 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'throw_if', + loc: { start: 2034, end: 2042 } + } + }, + loc: { start: 2028, end: 2087 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'throwUnless', + loc: { start: 3256, end: 3267 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 3268, end: 3272 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3274, end: 3277 } + }, + loc: { start: 3274, end: 3277 } + }, + loc: { start: 3268, end: 3277 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'condition', + loc: { start: 3279, end: 3288 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 3290, end: 3294 } + }, + typeArgs: [], + loc: { start: 3290, end: 3294 } + }, + loc: { start: 3279, end: 3294 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'throw_unless', + loc: { start: 3235, end: 3247 } + } + }, + loc: { start: 3229, end: 3296 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeThrow', + loc: { start: 3534, end: 3545 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 3546, end: 3550 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3552, end: 3555 } + }, + loc: { start: 3552, end: 3555 } + }, + loc: { start: 3546, end: 3555 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'throw', + loc: { start: 3520, end: 3525 } + } + }, + loc: { start: 3514, end: 3557 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeThrowIf', + loc: { start: 3804, end: 3817 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 3818, end: 3822 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3824, end: 3827 } + }, + loc: { start: 3824, end: 3827 } + }, + loc: { start: 3818, end: 3827 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'condition', + loc: { start: 3829, end: 3838 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 3840, end: 3844 } + }, + typeArgs: [], + loc: { start: 3840, end: 3844 } + }, + loc: { start: 3829, end: 3844 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'throw_if', + loc: { start: 3787, end: 3795 } + } + }, + loc: { start: 3781, end: 3846 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeThrowUnless', + loc: { start: 4109, end: 4126 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 4127, end: 4131 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4133, end: 4136 } + }, + loc: { start: 4133, end: 4136 } + }, + loc: { start: 4127, end: 4136 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'condition', + loc: { start: 4138, end: 4147 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 4149, end: 4153 } + }, + typeArgs: [], + loc: { start: 4149, end: 4153 } + }, + loc: { start: 4138, end: 4153 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'throw_unless', + loc: { start: 4088, end: 4100 } + } + }, + loc: { start: 4082, end: 4155 } + } + ] + }, + 'nativeThrowIf' => { + kind: 'tact', + path: 'std/internal/debug.tact', + code: '// these are builtin functions, these get special treatment from FunC\n' + + '// hence, no asm here\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Unconditionally throws an exception with an error `code`.\n' + + '///\n' + + '/// Execution of the current context stops, statements after `throw` are not executed, and control is passed to the first `try...catch` block on the call stack. If there is no `try` or `try...catch` block among the calling functions, TVM will terminate the transaction.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun thisWillTerminateAbruptly() {\n' + + '/// throw(1042); // throwing with exit code 1042\n' + + '/// }\n' + + '///\n' + + '/// fun butThisWont() {\n' + + '/// try {\n' + + '/// throw(1042); // throwing with exit code 1042\n' + + '/// }\n' + + '///\n' + + '/// // ... follow-up logic ...\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify the `code` outside of 0-65535 range.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#throw\n' + + '/// * https://docs.tact-lang.org/book/statements#try-catch\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + '@name(throw)\n' + + 'native throw(code: Int);\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + "/// Similar to `throw()`, but throws an error `code` only if `condition` holds, i.e. `condition` is equal to `true`. Doesn't throw otherwise.\n" + + '///\n' + + '/// ```tact\n' + + '/// contract Ownership {\n' + + '/// owner: Address;\n' + + '///\n' + + '/// init() {\n' + + '/// self.owner = myAddress();\n' + + '/// }\n' + + '///\n' + + '/// receive() {\n' + + '/// // Check the sender is the owner of the contract,\n' + + "/// // and throw exit code 1024 if it's not\n" + + '/// throwIf(1024, sender() != self.owner);\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify the `code` outside of 0-65535 range.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#throwif\n' + + '/// * https://docs.tact-lang.org/book/statements#try-catch\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + '@name(throw_if)\n' + + 'native throwIf(code: Int, condition: Bool);\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + "/// Similar to `throw()`, but throws an error `code` only if `condition` does **not** hold, i.e. `condition` is equal to `true`. Doesn't throw otherwise.\n" + + '///\n' + + '/// This function is also similar to `require()`, but uses the specified `code` directly instead of generating one based on the given error message `String`.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Ownership {\n' + + '/// owner: Address;\n' + + '///\n' + + '/// init() {\n' + + '/// self.owner = myAddress();\n' + + '/// }\n' + + '///\n' + + '/// receive() {\n' + + '/// // Check the sender is the owner of the contract,\n' + + "/// // and throw exit code 1024 if it's not\n" + + '/// throwUnless(1024, sender() == self.owner);\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify the `code` outside of 0-65535 range.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#throwunless\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#require\n' + + '/// * https://docs.tact-lang.org/book/statements#try-catch\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + '@name(throw_unless)\n' + + 'native throwUnless(code: Int, condition: Bool);\n' + + '\n' + + '/// Global function. **Deprecated** since Tact 1.6.0.\n' + + '///\n' + + '/// Use `throw()` instead.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#throw\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#nativethrow\n' + + '///\n' + + '@name(throw)\n' + + 'native nativeThrow(code: Int);\n' + + '\n' + + '/// Global function. **Deprecated** since Tact 1.6.0.\n' + + '///\n' + + '/// Use `throwIf()` instead.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#throwif\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#nativethrowif\n' + + '///\n' + + '@name(throw_if)\n' + + 'native nativeThrowIf(code: Int, condition: Bool);\n' + + '\n' + + '/// Global function. **Deprecated** since Tact 1.6.0.\n' + + '///\n' + + '/// Use `throwUnless()` instead.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#throwunless\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#nativethrowunless\n' + + '///\n' + + '@name(throw_unless)\n' + + 'native nativeThrowUnless(code: Int, condition: Bool);\n', + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'throw', + loc: { start: 1107, end: 1112 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 1113, end: 1117 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1119, end: 1122 } + }, + loc: { start: 1119, end: 1122 } + }, + loc: { start: 1113, end: 1122 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'throw', + loc: { start: 1093, end: 1098 } + } + }, + loc: { start: 1087, end: 1124 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'throwIf', + loc: { start: 2051, end: 2058 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 2059, end: 2063 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2065, end: 2068 } + }, + loc: { start: 2065, end: 2068 } + }, + loc: { start: 2059, end: 2068 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'condition', + loc: { start: 2070, end: 2079 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 2081, end: 2085 } + }, + typeArgs: [], + loc: { start: 2081, end: 2085 } + }, + loc: { start: 2070, end: 2085 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'throw_if', + loc: { start: 2034, end: 2042 } + } + }, + loc: { start: 2028, end: 2087 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'throwUnless', + loc: { start: 3256, end: 3267 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 3268, end: 3272 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3274, end: 3277 } + }, + loc: { start: 3274, end: 3277 } + }, + loc: { start: 3268, end: 3277 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'condition', + loc: { start: 3279, end: 3288 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 3290, end: 3294 } + }, + typeArgs: [], + loc: { start: 3290, end: 3294 } + }, + loc: { start: 3279, end: 3294 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'throw_unless', + loc: { start: 3235, end: 3247 } + } + }, + loc: { start: 3229, end: 3296 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeThrow', + loc: { start: 3534, end: 3545 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 3546, end: 3550 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3552, end: 3555 } + }, + loc: { start: 3552, end: 3555 } + }, + loc: { start: 3546, end: 3555 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'throw', + loc: { start: 3520, end: 3525 } + } + }, + loc: { start: 3514, end: 3557 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeThrowIf', + loc: { start: 3804, end: 3817 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 3818, end: 3822 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3824, end: 3827 } + }, + loc: { start: 3824, end: 3827 } + }, + loc: { start: 3818, end: 3827 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'condition', + loc: { start: 3829, end: 3838 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 3840, end: 3844 } + }, + typeArgs: [], + loc: { start: 3840, end: 3844 } + }, + loc: { start: 3829, end: 3844 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'throw_if', + loc: { start: 3787, end: 3795 } + } + }, + loc: { start: 3781, end: 3846 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeThrowUnless', + loc: { start: 4109, end: 4126 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 4127, end: 4131 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4133, end: 4136 } + }, + loc: { start: 4133, end: 4136 } + }, + loc: { start: 4127, end: 4136 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'condition', + loc: { start: 4138, end: 4147 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 4149, end: 4153 } + }, + typeArgs: [], + loc: { start: 4149, end: 4153 } + }, + loc: { start: 4138, end: 4153 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'throw_unless', + loc: { start: 4088, end: 4100 } + } + }, + loc: { start: 4082, end: 4155 } + } + ] + }, + 'nativeThrowUnless' => { + kind: 'tact', + path: 'std/internal/debug.tact', + code: '// these are builtin functions, these get special treatment from FunC\n' + + '// hence, no asm here\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Unconditionally throws an exception with an error `code`.\n' + + '///\n' + + '/// Execution of the current context stops, statements after `throw` are not executed, and control is passed to the first `try...catch` block on the call stack. If there is no `try` or `try...catch` block among the calling functions, TVM will terminate the transaction.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun thisWillTerminateAbruptly() {\n' + + '/// throw(1042); // throwing with exit code 1042\n' + + '/// }\n' + + '///\n' + + '/// fun butThisWont() {\n' + + '/// try {\n' + + '/// throw(1042); // throwing with exit code 1042\n' + + '/// }\n' + + '///\n' + + '/// // ... follow-up logic ...\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify the `code` outside of 0-65535 range.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#throw\n' + + '/// * https://docs.tact-lang.org/book/statements#try-catch\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + '@name(throw)\n' + + 'native throw(code: Int);\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + "/// Similar to `throw()`, but throws an error `code` only if `condition` holds, i.e. `condition` is equal to `true`. Doesn't throw otherwise.\n" + + '///\n' + + '/// ```tact\n' + + '/// contract Ownership {\n' + + '/// owner: Address;\n' + + '///\n' + + '/// init() {\n' + + '/// self.owner = myAddress();\n' + + '/// }\n' + + '///\n' + + '/// receive() {\n' + + '/// // Check the sender is the owner of the contract,\n' + + "/// // and throw exit code 1024 if it's not\n" + + '/// throwIf(1024, sender() != self.owner);\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify the `code` outside of 0-65535 range.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#throwif\n' + + '/// * https://docs.tact-lang.org/book/statements#try-catch\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + '@name(throw_if)\n' + + 'native throwIf(code: Int, condition: Bool);\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + "/// Similar to `throw()`, but throws an error `code` only if `condition` does **not** hold, i.e. `condition` is equal to `true`. Doesn't throw otherwise.\n" + + '///\n' + + '/// This function is also similar to `require()`, but uses the specified `code` directly instead of generating one based on the given error message `String`.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Ownership {\n' + + '/// owner: Address;\n' + + '///\n' + + '/// init() {\n' + + '/// self.owner = myAddress();\n' + + '/// }\n' + + '///\n' + + '/// receive() {\n' + + '/// // Check the sender is the owner of the contract,\n' + + "/// // and throw exit code 1024 if it's not\n" + + '/// throwUnless(1024, sender() == self.owner);\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify the `code` outside of 0-65535 range.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#throwunless\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#require\n' + + '/// * https://docs.tact-lang.org/book/statements#try-catch\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + '@name(throw_unless)\n' + + 'native throwUnless(code: Int, condition: Bool);\n' + + '\n' + + '/// Global function. **Deprecated** since Tact 1.6.0.\n' + + '///\n' + + '/// Use `throw()` instead.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#throw\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#nativethrow\n' + + '///\n' + + '@name(throw)\n' + + 'native nativeThrow(code: Int);\n' + + '\n' + + '/// Global function. **Deprecated** since Tact 1.6.0.\n' + + '///\n' + + '/// Use `throwIf()` instead.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#throwif\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#nativethrowif\n' + + '///\n' + + '@name(throw_if)\n' + + 'native nativeThrowIf(code: Int, condition: Bool);\n' + + '\n' + + '/// Global function. **Deprecated** since Tact 1.6.0.\n' + + '///\n' + + '/// Use `throwUnless()` instead.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#throwunless\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#nativethrowunless\n' + + '///\n' + + '@name(throw_unless)\n' + + 'native nativeThrowUnless(code: Int, condition: Bool);\n', + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'throw', + loc: { start: 1107, end: 1112 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 1113, end: 1117 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1119, end: 1122 } + }, + loc: { start: 1119, end: 1122 } + }, + loc: { start: 1113, end: 1122 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'throw', + loc: { start: 1093, end: 1098 } + } + }, + loc: { start: 1087, end: 1124 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'throwIf', + loc: { start: 2051, end: 2058 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 2059, end: 2063 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2065, end: 2068 } + }, + loc: { start: 2065, end: 2068 } + }, + loc: { start: 2059, end: 2068 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'condition', + loc: { start: 2070, end: 2079 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 2081, end: 2085 } + }, + typeArgs: [], + loc: { start: 2081, end: 2085 } + }, + loc: { start: 2070, end: 2085 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'throw_if', + loc: { start: 2034, end: 2042 } + } + }, + loc: { start: 2028, end: 2087 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'throwUnless', + loc: { start: 3256, end: 3267 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 3268, end: 3272 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3274, end: 3277 } + }, + loc: { start: 3274, end: 3277 } + }, + loc: { start: 3268, end: 3277 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'condition', + loc: { start: 3279, end: 3288 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 3290, end: 3294 } + }, + typeArgs: [], + loc: { start: 3290, end: 3294 } + }, + loc: { start: 3279, end: 3294 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'throw_unless', + loc: { start: 3235, end: 3247 } + } + }, + loc: { start: 3229, end: 3296 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeThrow', + loc: { start: 3534, end: 3545 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 3546, end: 3550 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3552, end: 3555 } + }, + loc: { start: 3552, end: 3555 } + }, + loc: { start: 3546, end: 3555 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'throw', + loc: { start: 3520, end: 3525 } + } + }, + loc: { start: 3514, end: 3557 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeThrowIf', + loc: { start: 3804, end: 3817 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 3818, end: 3822 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3824, end: 3827 } + }, + loc: { start: 3824, end: 3827 } + }, + loc: { start: 3818, end: 3827 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'condition', + loc: { start: 3829, end: 3838 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 3840, end: 3844 } + }, + typeArgs: [], + loc: { start: 3840, end: 3844 } + }, + loc: { start: 3829, end: 3844 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'throw_if', + loc: { start: 3787, end: 3795 } + } + }, + loc: { start: 3781, end: 3846 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeThrowUnless', + loc: { start: 4109, end: 4126 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 4127, end: 4131 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4133, end: 4136 } + }, + loc: { start: 4133, end: 4136 } + }, + loc: { start: 4127, end: 4136 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'condition', + loc: { start: 4138, end: 4147 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 4149, end: 4153 } + }, + typeArgs: [], + loc: { start: 4149, end: 4153 } + }, + loc: { start: 4138, end: 4153 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'throw_unless', + loc: { start: 4088, end: 4100 } + } + }, + loc: { start: 4082, end: 4155 } + } + ] + }, + 'context' => { + kind: 'tact', + path: 'std/internal/context.tact', + code: '/// Represents the context of the current message.\n' + + 'struct Context {\n' + + ' /// Indicates whether the received message can\n' + + ' /// [bounce back](https://docs.ton.org/v3/documentation/smart-contracts/message-management/non-bounceable-messages).\n' + + ' bounceable: Bool;\n' + + '\n' + + ' /// Internal address of the sender on the TON Blockchain.\n' + + ' sender: Address;\n' + + '\n' + + ' /// Amount of [nanoToncoin](https://docs.tact-lang.org/book/integers#nanotoncoin) in the received message.\n' + + ' value: Int;\n' + + '\n' + + ' /// The remainder of the received message as a `Slice`. It follows the [internal message layout]\n' + + ' /// of TON, starting from the destination `Address` (`MsgAddressInt` in [TL-B notation]).\n' + + ' ///\n' + + ' /// [internal message layout]: https://docs.ton.org/develop/smart-contracts/messages#message-layout\n' + + ' /// [TL-B notation]: https://docs.ton.org/develop/data-formats/tl-b-language\n' + + ' raw: Slice;\n' + + '}\n' + + '\n' + + '/// Returns `Context` struct, which consists of:\n' + + '///\n' + + '/// * `bounceable` — Indicates whether the received message can [bounce back].\n' + + '/// * `sender` — Internal address of the sender on the TON blockchain.\n' + + '/// * `value` — Amount of [nanoToncoin] in the received message.\n' + + '/// * `raw` — The remainder of the received message as a `Slice`. It follows the [internal message layout] of TON, starting from the destination `Address` (`MsgAddressInt` in [TL-B notation]).\n' + + '///\n' + + '/// ```tact\n' + + '/// fun test() {\n' + + '/// let ctx: Context = context();\n' + + '/// require(ctx.value != 68 + 1, "Invalid amount of nanoToncoins, bye!");\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// Note: If you only need to know who sent the message, use the `sender()` function,\n' + + '/// as it is less gas-consuming.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#context\n' + + '///\n' + + '/// [bounce back]: https://docs.ton.org/v3/documentation/smart-contracts/message-management/non-bounceable-messages\n' + + '/// [nanoToncoin]: https://docs.tact-lang.org/book/integers#nanotoncoin\n' + + '/// [internal message layout]: https://docs.ton.org/develop/smart-contracts/messages#message-layout\n' + + '/// [TL-B notation]: https://docs.ton.org/develop/data-formats/tl-b-language\n' + + '///\n' + + '@name(__tact_context_get)\n' + + 'native context(): Context;\n' + + '\n' + + '/// Returns the `Address` of the sender of the current message.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract MeSee {\n' + + '/// receive() {\n' + + '/// let whoSentMeMessage: Address = sender();\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// Note: Behavior is undefined for [getter functions], because they cannot have a sender\n' + + '/// nor can they send messages.\n' + + '///\n' + + '/// Tip: To reduce gas usage, prefer using this function over calling `context().sender`\n' + + '/// when you only need to know the sender of the message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#sender\n' + + '///\n' + + '/// [getter functions]: https://docs.tact-lang.org/book/contracts#getter-functions\n' + + '///\n' + + '@name(__tact_context_get_sender)\n' + + 'native sender(): Address;\n' + + '\n' + + '/// Extension function for the `Context` structure.\n' + + '///\n' + + '/// Reads forward fee and returns it as `Int` amount of nanoToncoins.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fwdFee: Int = context().readForwardFee();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-contextstate#contextreadforwardfee\n' + + '/// * https://docs.tact-lang.org/ref/core-gas#getoriginalfwdfee\n' + + '///\n' + + 'asm extends fun readForwardFee(self: Context): Int {\n' + + ' // Only the self.raw (Context.raw) is important,\n' + + ' // so all the other fields and loaded values will be dropped by `BLKDROP2`\n' + + ' //\n' + + ' // Context.raw starts at the dest:MsgAddressInt, following this TL-B scheme:\n' + + ' // int_msg_info$0\n' + + ' // ihr_disabled:Bool\n' + + ' // bounce:Bool\n' + + ' // bounced:Bool\n' + + ' // src:MsgAddress\n' + + ' // dest:MsgAddressInt ← here is the start\n' + + ' // value:CurrencyCollection\n' + + ' // ihr_fee:Grams\n' + + ' // fwd_fee:Grams\n' + + ' // created_lt:uint64\n' + + ' // created_at:uint32\n' + + ' // = CommonMsgInfoRelaxed;\n' + + '\n' + + ' LDMSGADDR // load dest:MsgAddressInt\n' + + ' LDGRAMS // load value:CurrencyCollection\n' + + ' ONE\n' + + ' SDSKIPFIRST // skip extra currency collection\n' + + ' LDGRAMS // load ihr_fee\n' + + " LDGRAMS // load fwd_fee, we'll be using this!\n" + + ' DROP // drop remaining Slice (with created_lt and created_at)\n' + + '\n' + + ' // There are 7 entries on the stack — first 3 fields of Context plus 4 loaded ones.\n' + + " // The topmost is fwd_fee, which is the only one we're after, so let's drop 6 entries below:\n" + + ' 6 1 BLKDROP2 // drop the loaded values as well as the first 3 fields of Context\n' + + '\n' + + ' ZERO // not masterchain\n' + + ' GETORIGINALFWDFEE // floor(fwd_fee * 2^16 / (2^16 - first_frac)), where\n' + + ' // first_frac is a value listed in config param 25\n' + + ' // of the blockchain: https://tonviewer.com/config#25\n' + + ' // this instruction effectively multiplies the fwd_fee by 1.5,\n' + + ' // at least for the current value of first_frac, which is 21845\n' + + '}\n', + imports: [], + items: [ + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'Context', + loc: { start: 58, end: 65 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounceable', + loc: { start: 244, end: 254 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 256, end: 260 } + }, + typeArgs: [], + loc: { start: 256, end: 260 } + }, + initializer: undefined, + loc: { start: 244, end: 260 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'sender', + loc: { start: 329, end: 335 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 337, end: 344 } + }, + typeArgs: [], + loc: { start: 337, end: 344 } + }, + initializer: undefined, + loc: { start: 329, end: 344 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 462, end: 467 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 469, end: 472 } + }, + loc: { start: 469, end: 472 } + }, + initializer: undefined, + loc: { start: 462, end: 472 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'raw', + loc: { start: 867, end: 870 } + }, + type: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 872, end: 877 } }, + loc: { start: 872, end: 877 } + }, + initializer: undefined, + loc: { start: 867, end: 877 } + } + ], + loc: { start: 51, end: 880 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'context', + loc: { start: 2105, end: 2112 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Context', + loc: { start: 2116, end: 2123 } + }, + typeArgs: [], + loc: { start: 2116, end: 2123 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_context_get', + loc: { start: 2078, end: 2096 } + } + }, + loc: { start: 2072, end: 2124 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sender', + loc: { start: 2802, end: 2808 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 2812, end: 2819 } + }, + typeArgs: [], + loc: { start: 2812, end: 2819 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_context_get_sender', + loc: { start: 2768, end: 2793 } + } + }, + loc: { start: 2762, end: 2820 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'readForwardFee', + loc: { start: 3226, end: 3240 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3257, end: 3260 } + }, + loc: { start: 3257, end: 3260 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'LDMSGADDR // load dest:MsgAddressInt\n' + + ' LDGRAMS // load value:CurrencyCollection\n' + + ' ONE\n' + + ' SDSKIPFIRST // skip extra currency collection\n' + + ' LDGRAMS // load ihr_fee\n' + + " LDGRAMS // load fwd_fee, we'll be using this!\n" + + ' DROP // drop remaining Slice (with created_lt and created_at)\n' + + '\n' + + ' // There are 7 entries on the stack — first 3 fields of Context plus 4 loaded ones.\n' + + " // The topmost is fwd_fee, which is the only one we're after, so let's drop 6 entries below:\n" + + ' 6 1 BLKDROP2 // drop the loaded values as well as the first 3 fields of Context\n' + + '\n' + + ' ZERO // not masterchain\n' + + ' GETORIGINALFWDFEE // floor(fwd_fee * 2^16 / (2^16 - first_frac)), where\n' + + ' // first_frac is a value listed in config param 25\n' + + ' // of the blockchain: https://tonviewer.com/config#25\n' + + ' // this instruction effectively multiplies the fwd_fee by 1.5,\n' + + ' // at least for the current value of first_frac, which is 21845' + ] + }, + loc: { start: 3210, end: 4831 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Context', + loc: { start: 3247, end: 3254 } + }, + typeArgs: [], + loc: { start: 3247, end: 3254 } + } + } + ] + }, + 'sender' => { + kind: 'tact', + path: 'std/internal/context.tact', + code: '/// Represents the context of the current message.\n' + + 'struct Context {\n' + + ' /// Indicates whether the received message can\n' + + ' /// [bounce back](https://docs.ton.org/v3/documentation/smart-contracts/message-management/non-bounceable-messages).\n' + + ' bounceable: Bool;\n' + + '\n' + + ' /// Internal address of the sender on the TON Blockchain.\n' + + ' sender: Address;\n' + + '\n' + + ' /// Amount of [nanoToncoin](https://docs.tact-lang.org/book/integers#nanotoncoin) in the received message.\n' + + ' value: Int;\n' + + '\n' + + ' /// The remainder of the received message as a `Slice`. It follows the [internal message layout]\n' + + ' /// of TON, starting from the destination `Address` (`MsgAddressInt` in [TL-B notation]).\n' + + ' ///\n' + + ' /// [internal message layout]: https://docs.ton.org/develop/smart-contracts/messages#message-layout\n' + + ' /// [TL-B notation]: https://docs.ton.org/develop/data-formats/tl-b-language\n' + + ' raw: Slice;\n' + + '}\n' + + '\n' + + '/// Returns `Context` struct, which consists of:\n' + + '///\n' + + '/// * `bounceable` — Indicates whether the received message can [bounce back].\n' + + '/// * `sender` — Internal address of the sender on the TON blockchain.\n' + + '/// * `value` — Amount of [nanoToncoin] in the received message.\n' + + '/// * `raw` — The remainder of the received message as a `Slice`. It follows the [internal message layout] of TON, starting from the destination `Address` (`MsgAddressInt` in [TL-B notation]).\n' + + '///\n' + + '/// ```tact\n' + + '/// fun test() {\n' + + '/// let ctx: Context = context();\n' + + '/// require(ctx.value != 68 + 1, "Invalid amount of nanoToncoins, bye!");\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// Note: If you only need to know who sent the message, use the `sender()` function,\n' + + '/// as it is less gas-consuming.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#context\n' + + '///\n' + + '/// [bounce back]: https://docs.ton.org/v3/documentation/smart-contracts/message-management/non-bounceable-messages\n' + + '/// [nanoToncoin]: https://docs.tact-lang.org/book/integers#nanotoncoin\n' + + '/// [internal message layout]: https://docs.ton.org/develop/smart-contracts/messages#message-layout\n' + + '/// [TL-B notation]: https://docs.ton.org/develop/data-formats/tl-b-language\n' + + '///\n' + + '@name(__tact_context_get)\n' + + 'native context(): Context;\n' + + '\n' + + '/// Returns the `Address` of the sender of the current message.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract MeSee {\n' + + '/// receive() {\n' + + '/// let whoSentMeMessage: Address = sender();\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// Note: Behavior is undefined for [getter functions], because they cannot have a sender\n' + + '/// nor can they send messages.\n' + + '///\n' + + '/// Tip: To reduce gas usage, prefer using this function over calling `context().sender`\n' + + '/// when you only need to know the sender of the message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#sender\n' + + '///\n' + + '/// [getter functions]: https://docs.tact-lang.org/book/contracts#getter-functions\n' + + '///\n' + + '@name(__tact_context_get_sender)\n' + + 'native sender(): Address;\n' + + '\n' + + '/// Extension function for the `Context` structure.\n' + + '///\n' + + '/// Reads forward fee and returns it as `Int` amount of nanoToncoins.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fwdFee: Int = context().readForwardFee();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-contextstate#contextreadforwardfee\n' + + '/// * https://docs.tact-lang.org/ref/core-gas#getoriginalfwdfee\n' + + '///\n' + + 'asm extends fun readForwardFee(self: Context): Int {\n' + + ' // Only the self.raw (Context.raw) is important,\n' + + ' // so all the other fields and loaded values will be dropped by `BLKDROP2`\n' + + ' //\n' + + ' // Context.raw starts at the dest:MsgAddressInt, following this TL-B scheme:\n' + + ' // int_msg_info$0\n' + + ' // ihr_disabled:Bool\n' + + ' // bounce:Bool\n' + + ' // bounced:Bool\n' + + ' // src:MsgAddress\n' + + ' // dest:MsgAddressInt ← here is the start\n' + + ' // value:CurrencyCollection\n' + + ' // ihr_fee:Grams\n' + + ' // fwd_fee:Grams\n' + + ' // created_lt:uint64\n' + + ' // created_at:uint32\n' + + ' // = CommonMsgInfoRelaxed;\n' + + '\n' + + ' LDMSGADDR // load dest:MsgAddressInt\n' + + ' LDGRAMS // load value:CurrencyCollection\n' + + ' ONE\n' + + ' SDSKIPFIRST // skip extra currency collection\n' + + ' LDGRAMS // load ihr_fee\n' + + " LDGRAMS // load fwd_fee, we'll be using this!\n" + + ' DROP // drop remaining Slice (with created_lt and created_at)\n' + + '\n' + + ' // There are 7 entries on the stack — first 3 fields of Context plus 4 loaded ones.\n' + + " // The topmost is fwd_fee, which is the only one we're after, so let's drop 6 entries below:\n" + + ' 6 1 BLKDROP2 // drop the loaded values as well as the first 3 fields of Context\n' + + '\n' + + ' ZERO // not masterchain\n' + + ' GETORIGINALFWDFEE // floor(fwd_fee * 2^16 / (2^16 - first_frac)), where\n' + + ' // first_frac is a value listed in config param 25\n' + + ' // of the blockchain: https://tonviewer.com/config#25\n' + + ' // this instruction effectively multiplies the fwd_fee by 1.5,\n' + + ' // at least for the current value of first_frac, which is 21845\n' + + '}\n', + imports: [], + items: [ + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'Context', + loc: { start: 58, end: 65 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounceable', + loc: { start: 244, end: 254 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 256, end: 260 } + }, + typeArgs: [], + loc: { start: 256, end: 260 } + }, + initializer: undefined, + loc: { start: 244, end: 260 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'sender', + loc: { start: 329, end: 335 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 337, end: 344 } + }, + typeArgs: [], + loc: { start: 337, end: 344 } + }, + initializer: undefined, + loc: { start: 329, end: 344 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 462, end: 467 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 469, end: 472 } + }, + loc: { start: 469, end: 472 } + }, + initializer: undefined, + loc: { start: 462, end: 472 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'raw', + loc: { start: 867, end: 870 } + }, + type: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 872, end: 877 } }, + loc: { start: 872, end: 877 } + }, + initializer: undefined, + loc: { start: 867, end: 877 } + } + ], + loc: { start: 51, end: 880 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'context', + loc: { start: 2105, end: 2112 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Context', + loc: { start: 2116, end: 2123 } + }, + typeArgs: [], + loc: { start: 2116, end: 2123 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_context_get', + loc: { start: 2078, end: 2096 } + } + }, + loc: { start: 2072, end: 2124 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sender', + loc: { start: 2802, end: 2808 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 2812, end: 2819 } + }, + typeArgs: [], + loc: { start: 2812, end: 2819 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_context_get_sender', + loc: { start: 2768, end: 2793 } + } + }, + loc: { start: 2762, end: 2820 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'readForwardFee', + loc: { start: 3226, end: 3240 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3257, end: 3260 } + }, + loc: { start: 3257, end: 3260 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'LDMSGADDR // load dest:MsgAddressInt\n' + + ' LDGRAMS // load value:CurrencyCollection\n' + + ' ONE\n' + + ' SDSKIPFIRST // skip extra currency collection\n' + + ' LDGRAMS // load ihr_fee\n' + + " LDGRAMS // load fwd_fee, we'll be using this!\n" + + ' DROP // drop remaining Slice (with created_lt and created_at)\n' + + '\n' + + ' // There are 7 entries on the stack — first 3 fields of Context plus 4 loaded ones.\n' + + " // The topmost is fwd_fee, which is the only one we're after, so let's drop 6 entries below:\n" + + ' 6 1 BLKDROP2 // drop the loaded values as well as the first 3 fields of Context\n' + + '\n' + + ' ZERO // not masterchain\n' + + ' GETORIGINALFWDFEE // floor(fwd_fee * 2^16 / (2^16 - first_frac)), where\n' + + ' // first_frac is a value listed in config param 25\n' + + ' // of the blockchain: https://tonviewer.com/config#25\n' + + ' // this instruction effectively multiplies the fwd_fee by 1.5,\n' + + ' // at least for the current value of first_frac, which is 21845' + ] + }, + loc: { start: 3210, end: 4831 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Context', + loc: { start: 3247, end: 3254 } + }, + typeArgs: [], + loc: { start: 3247, end: 3254 } + } + } + ] + }, + 'nativeReserve' => { + kind: 'tact', + path: 'std/internal/reserve.tact', + code: '/// Executes the native `RAWRESERVE` instruction with the specified amount and mode.\n' + + '/// The `RAWRESERVE` instruction creates an output action to reserve a specific amount of\n' + + '/// [nanoToncoin] from the remaining balance of the account.\n' + + '///\n' + + '/// The `RAWRESERVE` instruction takes two arguments:\n' + + '/// * `amount`: The number of [nanoToncoin] to reserve.\n' + + '/// * `mode`: Determines the reservation behavior.\n' + + '///\n' + + '/// The `RAWRESERVE` instruction is roughly equivalent to creating an outbound message\n' + + '/// carrying the specified `amount` of [nanoToncoin] (or `b - amount` [nanoToncoin],\n' + + '/// where `b` is the remaining balance) to oneself.\n' + + '/// This ensures that subsequent output actions cannot spend more money than the remainder.\n' + + '///\n' + + '/// It is possible to use raw `Int` values and manually provide them for the `mode`,\n' + + "/// but for your convenience, there's a set of constants you may use to construct the\n" + + '/// compound `mode` with ease.\n' + + '///\n' + + '/// NOTE: Currently, `amount` must be a non-negative integer, and `mode` must be in the\n' + + '/// range `0..31`, inclusive.\n' + + '///\n' + + '/// Additionally, attempts to queue more than 255 reservations in one transaction throw an\n' + + '/// exception with [exit code 33]: `Action list is too long`.\n' + + '///\n' + + '/// NOTE: This function is gas-expensive and uses 500 gas units or more.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve\n' + + '///\n' + + '/// [exit code 33]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '/// [nanoToncoin]: https://docs.tact-lang.org/book/integers#nanotoncoin\n' + + 'asm fun nativeReserve(amount: Int, mode: Int) { RAWRESERVE }\n' + + '\n' + + '/// Reserves exactly the specified `amount` of\n' + + '/// [nanoToncoin](https://docs.tact-lang.org/book/integers#nanotoncoin).\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve-base-modes\n' + + '///\n' + + 'const ReserveExact: Int = 0;\n' + + '\n' + + '/// Reserves all but the specified `amount` of\n' + + '/// [nanoToncoin](https://docs.tact-lang.org/book/integers#nanotoncoin).\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve-base-modes\n' + + '///\n' + + 'const ReserveAllExcept: Int = 1;\n' + + '\n' + + '/// Reserves at most the specified `amount` of\n' + + '/// [nanoToncoin](https://docs.tact-lang.org/book/integers#nanotoncoin).\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve-base-modes\n' + + '///\n' + + 'const ReserveAtMost: Int = 2;\n' + + '\n' + + '/// Increases the `amount` by the original balance of the current account\n' + + '/// (before the compute phase), including all extra currencies.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve-optional-flags\n' + + '///\n' + + 'const ReserveAddOriginalBalance: Int = 4;\n' + + '\n' + + '/// Negates the `amount` value before performing the reservation.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve-optional-flags\n' + + '///\n' + + 'const ReserveInvertSign: Int = 8;\n' + + '\n' + + '/// Bounces the transaction if the reservation fails.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve-optional-flags\n' + + '///\n' + + 'const ReserveBounceIfActionFail: Int = 16;\n', + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeReserve', + loc: { start: 1509, end: 1522 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'amount', + loc: { start: 1523, end: 1529 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1531, end: 1534 } + }, + loc: { start: 1531, end: 1534 } + }, + loc: { start: 1523, end: 1534 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 1536, end: 1540 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1542, end: 1545 } + }, + loc: { start: 1542, end: 1545 } + }, + loc: { start: 1536, end: 1545 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RAWRESERVE' ] + }, + loc: { start: 1501, end: 1561 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'ReserveExact', + loc: { start: 1780, end: 1792 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1794, end: 1797 } + }, + loc: { start: 1794, end: 1797 } + }, + initializer: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 1800, end: 1801 } + } + }, + loc: { start: 1774, end: 1802 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'ReserveAllExcept', + loc: { start: 2021, end: 2037 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2039, end: 2042 } + }, + loc: { start: 2039, end: 2042 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 2045, end: 2046 } + } + }, + loc: { start: 2015, end: 2047 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'ReserveAtMost', + loc: { start: 2266, end: 2279 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2281, end: 2284 } + }, + loc: { start: 2281, end: 2284 } + }, + initializer: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 2287, end: 2288 } + } + }, + loc: { start: 2260, end: 2289 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'ReserveAddOriginalBalance', + loc: { start: 2530, end: 2555 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2557, end: 2560 } + }, + loc: { start: 2557, end: 2560 } + }, + initializer: { + kind: 'number', + base: '10', + value: 4n, + loc: { start: 2563, end: 2564 } + } + }, + loc: { start: 2524, end: 2565 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'ReserveInvertSign', + loc: { start: 2734, end: 2751 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2753, end: 2756 } + }, + loc: { start: 2753, end: 2756 } + }, + initializer: { + kind: 'number', + base: '10', + value: 8n, + loc: { start: 2759, end: 2760 } + } + }, + loc: { start: 2728, end: 2761 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'ReserveBounceIfActionFail', + loc: { start: 2918, end: 2943 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2945, end: 2948 } + }, + loc: { start: 2945, end: 2948 } + }, + initializer: { + kind: 'number', + base: '10', + value: 16n, + loc: { start: 2951, end: 2953 } + } + }, + loc: { start: 2912, end: 2954 } + } + ] + }, + 'message' => { + kind: 'tact', + path: 'std/internal/send.tact', + code: '/// Ordinary message (default).\n' + + '///\n' + + '/// This constant is available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendDefaultMode: Int = 0;\n' + + '\n' + + '/// Carry all the remaining value of the inbound message in addition\n' + + '/// to the value initially indicated in the new message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendRemainingValue: Int = 64;\n' + + '\n' + + '/// Carry **all the remaining balance** of the current smart contract instead\n' + + '/// of the value originally indicated in the message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendRemainingBalance: Int = 128;\n' + + '\n' + + "/// Doesn't send the message, only estimates the forward fees\n" + + '/// if the message-sending function computes those.\n' + + '///\n' + + '/// This constant is available since Tact 1.5.0.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '/// * https://docs.tact-lang.org/book/send#message-sending-functions\n' + + '///\n' + + 'const SendOnlyEstimateFee: Int = 1024;\n' + + '\n' + + '/// **Deprecated** since Tact 1.6.5.\n' + + '///\n' + + '/// Pay forward fees separately from the message value.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendPayGasSeparately: Int = 1;\n' + + '\n' + + '/// Pay forward fees separately from the message value.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendPayFwdFeesSeparately: Int = 1;\n' + + '\n' + + '/// Ignore any errors arising while processing this message during the action phase.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendIgnoreErrors: Int = 2;\n' + + '\n' + + '/// Bounce transaction in case of any errors during action phase.\n' + + '/// Has no effect if flag +2, `SendIgnoreErrors` is used.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendBounceIfActionFail: Int = 16;\n' + + '\n' + + '/// Current account (contract) will be destroyed if its resulting balance is zero.\n' + + '/// This flag is often used with mode 128, `SendRemainingBalance`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendDestroyIfZero: Int = 32;\n' + + '\n' + + '/// Struct for specifying the message parameters of the `send()` function.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#send\n' + + '///\n' + + 'struct SendParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// Optional initial code of the contract (compiled bitcode).\n' + + ' code: Cell? = null;\n' + + '\n' + + ' /// Optional initial data of the contract (arguments of `init()` function or values of contract parameters).\n' + + ' data: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// Recipient internal `Address` on TON Blockchain.\n' + + ' to: Address;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '}\n' + + '\n' + + '/// Struct for specifying the message parameters of the `message()` function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#message\n' + + '///\n' + + 'struct MessageParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// Recipient internal `Address` on TON Blockchain.\n' + + ' to: Address;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Queues the message to be sent using the `MessageParameters` struct. Allows for cheaper non-deployment, regular messages compared to the `send()` function.\n' + + '///\n' + + '/// The `MessageParameters` struct is similar to `SendParameters` struct, but without the `code` and `data` fields.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// message(MessageParameters{\n' + + '/// to: sender(), // back to the sender,\n' + + '/// value: ton("1"), // with 1 Toncoin (1_000_000_000 nanoToncoin),\n' + + '/// // and no message body\n' + + '/// });\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 33: [Action list is too long] — Thrown when attempting to queue more than 255 messages.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-send#message\n' + + '/// * https://docs.tact-lang.org/book/message-mode\n' + + '///\n' + + '/// [Action list is too long]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '///\n' + + 'asm fun message(params: MessageParameters) {\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 106 PUSHINT // 1 + 4 + 4 + 64 + 32 + 1\n' + + ' STZEROES\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + ' STDICT\n' + + ' ENDC\n' + + ' SWAP\n' + + ' SENDRAWMSG\n' + + '}\n' + + '\n' + + '/// Global function. Queues the message to be sent using a `SendParameters` Struct.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// send(SendParameters{\n' + + '/// to: sender(), // back to the sender,\n' + + '/// value: ton("1"), // with 1 Toncoin (1_000_000_000 nanoToncoin),\n' + + '/// // and no message body\n' + + '/// });\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 33: [Action list is too long] — Thrown when attempting to queue more than 255 messages.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#send\n' + + '///\n' + + '/// [Action list is too long]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '///\n' + + 'asm fun send(params: SendParameters) {\n' + + ' // Instructions are grouped, and the stack states they produce as a group are shown right after.\n' + + ' // In the end, our message Cell should have the following TL-B structure:\n' + + ' // message$_ {X:Type}\n' + + ' // info:CommonMsgInfoRelaxed\n' + + ' // init:(Maybe (Either StateInit ^StateInit))\n' + + ' // body:(Either X ^X)\n' + + ' // = MessageRelaxed X;\n' + + '\n' + + ' // → Stack state\n' + + ' // s0: `params.bounce`\n' + + ' // s1: `params.to`\n' + + ' // s2: `params.value`\n' + + ' // s3: `params.data`\n' + + ' // s4: `params.code`\n' + + ' // s5: `params.body`\n' + + ' // s6: `params.mode`\n' + + ' // For brevity, the "params" prefix will be omitted from now on.\n' + + '\n' + + ' // Group 1: Storing the `bounce`, `to` and `value` into a Builder\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + '\n' + + ' // Group 2: Placing the Builder after code and data, then checking those for nullability\n' + + ' s2 XCHG0\n' + + ' DUP2\n' + + ' ISNULL\n' + + ' SWAP\n' + + ' ISNULL\n' + + ' AND\n' + + ' // → Stack state\n' + + ' // s0: -1 (true) if `data` and `code` are both null, 0 (false) otherwise\n' + + ' // s1: `code`\n' + + ' // s2: `data`\n' + + ' // s3: Builder\n' + + ' // s4: `body`\n' + + ' // s5: `mode`\n' + + '\n' + + ' // Group 3: Left branch of the IFELSE, executed if s0 is -1 (true)\n' + + ' <{\n' + + ' DROP2 // drop `data` and `code`, since either of those is null\n' + + ' b{0} STSLICECONST\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: Right branch of the IFELSE, executed if s0 is 0 (false)\n' + + ' <{\n' + + ' // _ split_depth:(Maybe (## 5))\n' + + ' // special:(Maybe TickTock)\n' + + ' // code:(Maybe ^Cell)\n' + + ' // data:(Maybe ^Cell)\n' + + ' // library:(Maybe ^Cell)\n' + + ' // = StateInit;\n' + + ' ROT // place message Builder on top\n' + + ' b{10} STSLICECONST // store Maybe = true, Either = false\n' + + ' // Start composing inlined StateInit\n' + + ' b{00} STSLICECONST // store split_depth and special first\n' + + ' STDICT // store code\n' + + ' STDICT // store data\n' + + ' b{0} STSLICECONST // store library\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: IFELSE that does the branching shown above\n' + + ' IFELSE\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: null or StateInit\n' + + ' // s2: `body`\n' + + ' // s3: `mode`\n' + + '\n' + + ' // Group 4: Finalizing the message\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: `mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG // https://github.com/tact-lang/tact/issues/1558\n' + + '}\n' + + '\n' + + '/// Struct for specifying the deployment message parameters of the `deploy()` function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#deploy\n' + + '///\n' + + 'struct DeployParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '\n' + + ' //'... 12658 more characters, + imports: [], + items: [ + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendDefaultMode', + loc: { start: 164, end: 179 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 181, end: 184 } + }, + loc: { start: 181, end: 184 } + }, + initializer: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 187, end: 188 } + } + }, + loc: { start: 158, end: 189 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendRemainingValue', + loc: { start: 396, end: 414 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 416, end: 419 } + }, + loc: { start: 416, end: 419 } + }, + initializer: { + kind: 'number', + base: '10', + value: 64n, + loc: { start: 422, end: 424 } + } + }, + loc: { start: 390, end: 425 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendRemainingBalance', + loc: { start: 638, end: 658 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 660, end: 663 } + }, + loc: { start: 660, end: 663 } + }, + initializer: { + kind: 'number', + base: '10', + value: 128n, + loc: { start: 666, end: 669 } + } + }, + loc: { start: 632, end: 670 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendOnlyEstimateFee', + loc: { start: 993, end: 1012 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1014, end: 1017 } + }, + loc: { start: 1014, end: 1017 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1024n, + loc: { start: 1020, end: 1024 } + } + }, + loc: { start: 987, end: 1025 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendPayGasSeparately', + loc: { start: 1207, end: 1227 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1229, end: 1232 } + }, + loc: { start: 1229, end: 1232 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1235, end: 1236 } + } + }, + loc: { start: 1201, end: 1237 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendPayFwdFeesSeparately', + loc: { start: 1378, end: 1402 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1404, end: 1407 } + }, + loc: { start: 1404, end: 1407 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1410, end: 1411 } + } + }, + loc: { start: 1372, end: 1412 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendIgnoreErrors', + loc: { start: 1582, end: 1598 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1600, end: 1603 } + }, + loc: { start: 1600, end: 1603 } + }, + initializer: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 1606, end: 1607 } + } + }, + loc: { start: 1576, end: 1608 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendBounceIfActionFail', + loc: { start: 1817, end: 1839 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1841, end: 1844 } + }, + loc: { start: 1841, end: 1844 } + }, + initializer: { + kind: 'number', + base: '10', + value: 16n, + loc: { start: 1847, end: 1849 } + } + }, + loc: { start: 1811, end: 1850 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendDestroyIfZero', + loc: { start: 2085, end: 2102 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2104, end: 2107 } + }, + loc: { start: 2104, end: 2107 } + }, + initializer: { + kind: 'number', + base: '10', + value: 32n, + loc: { start: 2110, end: 2112 } + } + }, + loc: { start: 2079, end: 2113 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'SendParameters', + loc: { start: 2260, end: 2274 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 2416, end: 2420 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2422, end: 2425 } + }, + loc: { start: 2422, end: 2425 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 2428, end: 2443 } + }, + loc: { start: 2416, end: 2443 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 2493, end: 2497 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2503, end: 2504 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2499, end: 2503 } + }, + loc: { start: 2499, end: 2503 } + } + ], + loc: { start: 2503, end: 2504 } + }, + initializer: { kind: 'null', loc: { start: 2507, end: 2511 } }, + loc: { start: 2493, end: 2511 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'code', + loc: { start: 2584, end: 2588 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2594, end: 2595 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2590, end: 2594 } + }, + loc: { start: 2590, end: 2594 } + } + ], + loc: { start: 2594, end: 2595 } + }, + initializer: { kind: 'null', loc: { start: 2598, end: 2602 } }, + loc: { start: 2584, end: 2602 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'data', + loc: { start: 2722, end: 2726 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2732, end: 2733 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2728, end: 2732 } + }, + loc: { start: 2728, end: 2732 } + } + ], + loc: { start: 2732, end: 2733 } + }, + initializer: { kind: 'null', loc: { start: 2736, end: 2740 } }, + loc: { start: 2722, end: 2740 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 2936, end: 2941 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2943, end: 2946 } + }, + loc: { start: 2943, end: 2946 } + }, + initializer: undefined, + loc: { start: 2936, end: 2946 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'to', + loc: { start: 3009, end: 3011 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3013, end: 3020 } + }, + typeArgs: [], + loc: { start: 3013, end: 3020 } + }, + initializer: undefined, + loc: { start: 3009, end: 3020 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 3186, end: 3192 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 3194, end: 3198 } + }, + typeArgs: [], + loc: { start: 3194, end: 3198 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 3201, end: 3205 } + }, + loc: { start: 3186, end: 3205 } + } + ], + loc: { start: 2253, end: 3208 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'MessageParameters', + loc: { start: 3389, end: 3406 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 3548, end: 3552 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3554, end: 3557 } + }, + loc: { start: 3554, end: 3557 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 3560, end: 3575 } + }, + loc: { start: 3548, end: 3575 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 3625, end: 3629 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 3635, end: 3636 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 3631, end: 3635 } + }, + loc: { start: 3631, end: 3635 } + } + ], + loc: { start: 3635, end: 3636 } + }, + initializer: { kind: 'null', loc: { start: 3639, end: 3643 } }, + loc: { start: 3625, end: 3643 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 3839, end: 3844 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3846, end: 3849 } + }, + loc: { start: 3846, end: 3849 } + }, + initializer: undefined, + loc: { start: 3839, end: 3849 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'to', + loc: { start: 3912, end: 3914 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3916, end: 3923 } + }, + typeArgs: [], + loc: { start: 3916, end: 3923 } + }, + initializer: undefined, + loc: { start: 3912, end: 3923 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 4089, end: 4095 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 4097, end: 4101 } + }, + typeArgs: [], + loc: { start: 4097, end: 4101 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 4104, end: 4108 } + }, + loc: { start: 4089, end: 4108 } + } + ], + loc: { start: 3382, end: 4111 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'message', + loc: { start: 5056, end: 5063 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 5064, end: 5070 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'MessageParameters', + loc: { start: 5072, end: 5089 } + }, + typeArgs: [], + loc: { start: 5072, end: 5089 } + }, + loc: { start: 5064, end: 5089 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 106 PUSHINT // 1 + 4 + 4 + 64 + 32 + 1\n' + + ' STZEROES\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + ' STDICT\n' + + ' ENDC\n' + + ' SWAP\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 5048, end: 5588 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'send', loc: { start: 6219, end: 6223 } }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 6224, end: 6230 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'SendParameters', + loc: { start: 6232, end: 6246 } + }, + typeArgs: [], + loc: { start: 6232, end: 6246 } + }, + loc: { start: 6224, end: 6246 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + '\n' + + ' // Group 2: Placing the Builder after code and data, then checking those for nullability\n' + + ' s2 XCHG0\n' + + ' DUP2\n' + + ' ISNULL\n' + + ' SWAP\n' + + ' ISNULL\n' + + ' AND\n' + + ' // → Stack state\n' + + ' // s0: -1 (true) if `data` and `code` are both null, 0 (false) otherwise\n' + + ' // s1: `code`\n' + + ' // s2: `data`\n' + + ' // s3: Builder\n' + + ' // s4: `body`\n' + + ' // s5: `mode`\n' + + '\n' + + ' // Group 3: Left branch of the IFELSE, executed if s0 is -1 (true)\n' + + ' <{\n' + + ' DROP2 // drop `data` and `code`, since either of those is null\n' + + ' b{0} STSLICECONST\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: Right branch of the IFELSE, executed if s0 is 0 (false)\n' + + ' <{\n' + + ' // _ split_depth:(Maybe (## 5))\n' + + ' // special:(Maybe TickTock)\n' + + ' // code:(Maybe ^Cell)\n' + + ' // data:(Maybe ^Cell)\n' + + ' // library:(Maybe ^Cell)\n' + + ' // = StateInit;\n' + + ' ROT // place message Builder on top\n' + + ' b{10} STSLICECONST // store Maybe = true, Either = false\n' + + ' // Start composing inlined StateInit\n' + + ' b{00} STSLICECONST // store split_depth and special first\n' + + ' STDICT // store code\n' + + ' STDICT // store data\n' + + ' b{0} STSLICECONST // store library\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: IFELSE that does the branching shown above\n' + + ' IFELSE\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: null or StateInit\n' + + ' // s2: `body`\n' + + ' // s3: `mode`\n' + + '\n' + + ' // Group 4: Finalizing the message\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: `mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG // https://github.com/tact-lang/tact/issues/1558' + ] + }, + loc: { start: 6211, end: 9157 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'DeployParameters', + loc: { start: 9347, end: 9363 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 9505, end: 9509 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9511, end: 9514 } + }, + loc: { start: 9511, end: 9514 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 9517, end: 9532 } + }, + loc: { start: 9505, end: 9532 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 9582, end: 9586 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 9592, end: 9593 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 9588, end: 9592 } + }, + loc: { start: 9588, end: 9592 } + } + ], + loc: { start: 9592, end: 9593 } + }, + initializer: { kind: 'null', loc: { start: 9596, end: 9600 } }, + loc: { start: 9582, end: 9600 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 9796, end: 9801 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9803, end: 9806 } + }, + loc: { start: 9803, end: 9806 } + }, + initializer: undefined, + loc: { start: 9796, end: 9806 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 9972, end: 9978 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 9980, end: 9984 } + }, + typeArgs: [], + loc: { start: 9980, end: 9984 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 9987, end: 9991 } + }, + loc: { start: 9972, end: 9991 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'init', + loc: { start: 10135, end: 10139 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 10141, end: 10150 } + }, + typeArgs: [], + loc: { start: 10141, end: 10150 } + }, + initializer: undefined, + loc: { start: 10135, end: 10150 } + } + ], + loc: { start: 9340, end: 10153 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'deploy', + loc: { start: 11796, end: 11802 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 11803, end: 11809 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'DeployParameters', + loc: { start: 11811, end: 11827 } + }, + typeArgs: [], + loc: { start: 11811, end: 11827 } + }, + loc: { start: 11803, end: 11827 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '4 1 BLKPUSH // pushes 2 copies of `init.code` and `init.data`\n' + + ' HASHCU // `init.data` hash\n' + + ' SWAP\n' + + ' HASHCU // `init.code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `init.data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `init.code` depth\n' + + '\n' + + ' // Group 2: Calculating destination address\n' + + ' // For almost identical logic and instructions,\n' + + ' // see comments inside `contractHash()` function in contract.tact\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + ' NEWC\n' + + ' 24 STU\n' + + ' 16 STU\n' + + ' 16 STU\n' + + ' 256 STU\n' + + ' 256 STU\n' + + ' ONE HASHEXT_SHA256 // obtains hash part (account id) of the address\n' + + ' // → Stack state\n' + + ' // s0: destAddr(hash part)\n' + + ' // s1: `init.data`\n' + + ' // s2: `init.code`\n' + + ' // s3 and below: `bounce`, `value`, `body`, `mode`\n' + + '\n' + + ' // Group 3: Building a message (CommonMsgInfoRelaxed)\n' + + ' s3 XCHG0 // swaps `bounce` with destAddr(hash part)\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' s1 s2 XCHG // swap `init.data` with `init.code`, placing code on s1\n' + + ' STREF // store `init.code`\n' + + ' STREF // store `init.data`\n' + + ' // Inline StateInit:\n' + + ' b{00010000000000} STSLICECONST\n' + + ' // 0 + 00 + 10 + 0 + 00000000\n' + + ' // 1) 0 - bounced = false\n' + + ' // 2) 00 - src = addr_none\n' + + ' // 3) 10 - tag of addr_std (part of dest)\n' + + ' // 4) 0 - Maybe Anycast = false\n' + + ' // 5) 00000000 - workchain_id (part of dest)\n' + + ' //\n' + + ' 256 STU // store destAddr(hash part)\n' + + ' SWAP // Builder on top, `value` below\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + '\n' + + ' // Group 4: Continue building a message (CommonMsgInfoRelaxed into MessageRelaxed)\n' + + ' // Remaining bits of MessageRelaxed:\n' + + ' b{1000110} STSLICECONST\n' + + ' // 10 + 0 + 0 + 1 + 1 + 0\n' + + ' // 10 - Maybe (Either StateInit ^StateInit) = true false\n' + + ' // 0 - split_depth:(Maybe (## 5)) = false\n' + + ' // 0 = special:(Maybe TickTock) = false\n' + + ' // 1 = code:(Maybe ^Cell) = true\n' + + ' // 1 = data:(Maybe ^Cell) = true\n' + + ' // 0 = library:(Maybe ^Cell) = false\n' + + ' //\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC // finalize the message\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: params.`mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 11788, end: 14770 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'cashback', + loc: { start: 15971, end: 15979 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'to', + loc: { start: 15980, end: 15982 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 15984, end: 15991 } + }, + typeArgs: [], + loc: { start: 15984, end: 15991 } + }, + loc: { start: 15980, end: 15991 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '16 PUSHINT // 0x10, i.e. 0x18 but with bounce = false\n' + + ' NEWC\n' + + ' 6 STU // .storeUint(0x10, 6)\n' + + ' STSLICE // .storeAddress(to)\n' + + ' 0 PUSHINT // 0\n' + + ' 111 STUR // .storeUint(0, 111)\n' + + ' // 4 zeros for coins and 107 zeros for lt, fees, etc.\n' + + ' ENDC\n' + + ' 66 PUSHINT // SendRemainingValue | SendIgnoreErrors\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 15963, end: 16385 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeSendMessage', + loc: { start: 16936, end: 16953 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 16954, end: 16957 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 16959, end: 16963 } + }, + loc: { start: 16959, end: 16963 } + }, + loc: { start: 16954, end: 16963 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 16965, end: 16969 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 16971, end: 16974 } + }, + loc: { start: 16971, end: 16974 } + }, + loc: { start: 16965, end: 16974 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDRAWMSG' ] + }, + loc: { start: 16928, end: 16990 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sendRawMessage', + loc: { start: 17751, end: 17765 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 17766, end: 17769 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 17771, end: 17775 } + }, + loc: { start: 17771, end: 17775 } + }, + loc: { start: 17766, end: 17775 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 17777, end: 17781 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 17783, end: 17786 } + }, + loc: { start: 17783, end: 17786 } + }, + loc: { start: 17777, end: 17786 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDRAWMSG' ] + }, + loc: { start: 17743, end: 17802 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeSendMessageReturnForwardFee', + loc: { start: 19063, end: 19096 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 19120, end: 19123 } + }, + loc: { start: 19120, end: 19123 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 19097, end: 19100 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 19102, end: 19106 } + }, + loc: { start: 19102, end: 19106 } + }, + loc: { start: 19097, end: 19106 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 19108, end: 19112 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 19114, end: 19117 } + }, + loc: { start: 19114, end: 19117 } + }, + loc: { start: 19108, end: 19117 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDMSG' ] + }, + loc: { start: 19055, end: 19135 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sendMessageReturnForwardFee', + loc: { start: 20186, end: 20213 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 20237, end: 20240 } + }, + loc: { start: 20237, end: 20240 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 20214, end: 20217 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 20219, end: 20223 } + }, + loc: { start: 20219, end: 20223 } + }, + loc: { start: 20214, end: 20223 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 20225, end: 20229 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 20231, end: 20234 } + }, + loc: { start: 20231, end: 20234 } + }, + loc: { start: 20225, end: 20234 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDMSG' ] + }, + loc: { start: 20178, end: 20252 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'emit', + loc: { start: 21033, end: 21037 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'body', + loc: { start: 21038, end: 21042 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 21044, end: 21048 } + }, + loc: { start: 21044, end: 21048 } + }, + loc: { start: 21038, end: 21048 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'c', + loc: { start: 21233, end: 21234 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 21236, end: 21240 } + }, + loc: { start: 21236, end: 21240 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'static_call', + function: { + kind: 'id', + text: 'beginCell', + loc: { start: 21243, end: 21252 } + }, + typeArgs: [], + args: [], + loc: { start: 21243, end: 21254 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 21264, end: 21273 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 15211807202738752817960438464513n, + loc: { start: 21274, end: 21306 } + }, + { + kind: 'number', + base: '10', + value: 104n, + loc: { start: 21308, end: 21311 } + } + ], + loc: { start: 21243, end: 21312 } + }, + method: { + kind: 'id', + text: 'storeRef', + loc: { start: 21322, end: 21330 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'body', + loc: { start: 21331, end: 21335 } + } + ], + loc: { start: 21243, end: 21336 } + }, + method: { + kind: 'id', + text: 'endCell', + loc: { start: 21346, end: 21353 } + }, + typeArgs: [], + args: [], + loc: { start: 21243, end: 21355 } + }, + loc: { start: 21229, end: 21356 } + }, + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'sendRawMessage', + loc: { start: 21361, end: 21375 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'c', + loc: { start: 21376, end: 21377 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 21379, end: 21380 } + } + ], + loc: { start: 21361, end: 21381 } + }, + loc: { start: 21361, end: 21382 } + } + ] + }, + loc: { start: 21022, end: 21384 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'acceptMessage', + loc: { start: 22124, end: 22137 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ACCEPT' ] + }, + loc: { start: 22116, end: 22150 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'commit', + loc: { start: 22638, end: 22644 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'COMMIT' ] + }, + loc: { start: 22630, end: 22657 } + } + ] + }, + 'send' => { + kind: 'tact', + path: 'std/internal/send.tact', + code: '/// Ordinary message (default).\n' + + '///\n' + + '/// This constant is available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendDefaultMode: Int = 0;\n' + + '\n' + + '/// Carry all the remaining value of the inbound message in addition\n' + + '/// to the value initially indicated in the new message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendRemainingValue: Int = 64;\n' + + '\n' + + '/// Carry **all the remaining balance** of the current smart contract instead\n' + + '/// of the value originally indicated in the message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendRemainingBalance: Int = 128;\n' + + '\n' + + "/// Doesn't send the message, only estimates the forward fees\n" + + '/// if the message-sending function computes those.\n' + + '///\n' + + '/// This constant is available since Tact 1.5.0.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '/// * https://docs.tact-lang.org/book/send#message-sending-functions\n' + + '///\n' + + 'const SendOnlyEstimateFee: Int = 1024;\n' + + '\n' + + '/// **Deprecated** since Tact 1.6.5.\n' + + '///\n' + + '/// Pay forward fees separately from the message value.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendPayGasSeparately: Int = 1;\n' + + '\n' + + '/// Pay forward fees separately from the message value.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendPayFwdFeesSeparately: Int = 1;\n' + + '\n' + + '/// Ignore any errors arising while processing this message during the action phase.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendIgnoreErrors: Int = 2;\n' + + '\n' + + '/// Bounce transaction in case of any errors during action phase.\n' + + '/// Has no effect if flag +2, `SendIgnoreErrors` is used.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendBounceIfActionFail: Int = 16;\n' + + '\n' + + '/// Current account (contract) will be destroyed if its resulting balance is zero.\n' + + '/// This flag is often used with mode 128, `SendRemainingBalance`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendDestroyIfZero: Int = 32;\n' + + '\n' + + '/// Struct for specifying the message parameters of the `send()` function.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#send\n' + + '///\n' + + 'struct SendParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// Optional initial code of the contract (compiled bitcode).\n' + + ' code: Cell? = null;\n' + + '\n' + + ' /// Optional initial data of the contract (arguments of `init()` function or values of contract parameters).\n' + + ' data: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// Recipient internal `Address` on TON Blockchain.\n' + + ' to: Address;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '}\n' + + '\n' + + '/// Struct for specifying the message parameters of the `message()` function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#message\n' + + '///\n' + + 'struct MessageParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// Recipient internal `Address` on TON Blockchain.\n' + + ' to: Address;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Queues the message to be sent using the `MessageParameters` struct. Allows for cheaper non-deployment, regular messages compared to the `send()` function.\n' + + '///\n' + + '/// The `MessageParameters` struct is similar to `SendParameters` struct, but without the `code` and `data` fields.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// message(MessageParameters{\n' + + '/// to: sender(), // back to the sender,\n' + + '/// value: ton("1"), // with 1 Toncoin (1_000_000_000 nanoToncoin),\n' + + '/// // and no message body\n' + + '/// });\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 33: [Action list is too long] — Thrown when attempting to queue more than 255 messages.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-send#message\n' + + '/// * https://docs.tact-lang.org/book/message-mode\n' + + '///\n' + + '/// [Action list is too long]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '///\n' + + 'asm fun message(params: MessageParameters) {\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 106 PUSHINT // 1 + 4 + 4 + 64 + 32 + 1\n' + + ' STZEROES\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + ' STDICT\n' + + ' ENDC\n' + + ' SWAP\n' + + ' SENDRAWMSG\n' + + '}\n' + + '\n' + + '/// Global function. Queues the message to be sent using a `SendParameters` Struct.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// send(SendParameters{\n' + + '/// to: sender(), // back to the sender,\n' + + '/// value: ton("1"), // with 1 Toncoin (1_000_000_000 nanoToncoin),\n' + + '/// // and no message body\n' + + '/// });\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 33: [Action list is too long] — Thrown when attempting to queue more than 255 messages.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#send\n' + + '///\n' + + '/// [Action list is too long]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '///\n' + + 'asm fun send(params: SendParameters) {\n' + + ' // Instructions are grouped, and the stack states they produce as a group are shown right after.\n' + + ' // In the end, our message Cell should have the following TL-B structure:\n' + + ' // message$_ {X:Type}\n' + + ' // info:CommonMsgInfoRelaxed\n' + + ' // init:(Maybe (Either StateInit ^StateInit))\n' + + ' // body:(Either X ^X)\n' + + ' // = MessageRelaxed X;\n' + + '\n' + + ' // → Stack state\n' + + ' // s0: `params.bounce`\n' + + ' // s1: `params.to`\n' + + ' // s2: `params.value`\n' + + ' // s3: `params.data`\n' + + ' // s4: `params.code`\n' + + ' // s5: `params.body`\n' + + ' // s6: `params.mode`\n' + + ' // For brevity, the "params" prefix will be omitted from now on.\n' + + '\n' + + ' // Group 1: Storing the `bounce`, `to` and `value` into a Builder\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + '\n' + + ' // Group 2: Placing the Builder after code and data, then checking those for nullability\n' + + ' s2 XCHG0\n' + + ' DUP2\n' + + ' ISNULL\n' + + ' SWAP\n' + + ' ISNULL\n' + + ' AND\n' + + ' // → Stack state\n' + + ' // s0: -1 (true) if `data` and `code` are both null, 0 (false) otherwise\n' + + ' // s1: `code`\n' + + ' // s2: `data`\n' + + ' // s3: Builder\n' + + ' // s4: `body`\n' + + ' // s5: `mode`\n' + + '\n' + + ' // Group 3: Left branch of the IFELSE, executed if s0 is -1 (true)\n' + + ' <{\n' + + ' DROP2 // drop `data` and `code`, since either of those is null\n' + + ' b{0} STSLICECONST\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: Right branch of the IFELSE, executed if s0 is 0 (false)\n' + + ' <{\n' + + ' // _ split_depth:(Maybe (## 5))\n' + + ' // special:(Maybe TickTock)\n' + + ' // code:(Maybe ^Cell)\n' + + ' // data:(Maybe ^Cell)\n' + + ' // library:(Maybe ^Cell)\n' + + ' // = StateInit;\n' + + ' ROT // place message Builder on top\n' + + ' b{10} STSLICECONST // store Maybe = true, Either = false\n' + + ' // Start composing inlined StateInit\n' + + ' b{00} STSLICECONST // store split_depth and special first\n' + + ' STDICT // store code\n' + + ' STDICT // store data\n' + + ' b{0} STSLICECONST // store library\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: IFELSE that does the branching shown above\n' + + ' IFELSE\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: null or StateInit\n' + + ' // s2: `body`\n' + + ' // s3: `mode`\n' + + '\n' + + ' // Group 4: Finalizing the message\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: `mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG // https://github.com/tact-lang/tact/issues/1558\n' + + '}\n' + + '\n' + + '/// Struct for specifying the deployment message parameters of the `deploy()` function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#deploy\n' + + '///\n' + + 'struct DeployParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '\n' + + ' //'... 12658 more characters, + imports: [], + items: [ + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendDefaultMode', + loc: { start: 164, end: 179 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 181, end: 184 } + }, + loc: { start: 181, end: 184 } + }, + initializer: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 187, end: 188 } + } + }, + loc: { start: 158, end: 189 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendRemainingValue', + loc: { start: 396, end: 414 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 416, end: 419 } + }, + loc: { start: 416, end: 419 } + }, + initializer: { + kind: 'number', + base: '10', + value: 64n, + loc: { start: 422, end: 424 } + } + }, + loc: { start: 390, end: 425 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendRemainingBalance', + loc: { start: 638, end: 658 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 660, end: 663 } + }, + loc: { start: 660, end: 663 } + }, + initializer: { + kind: 'number', + base: '10', + value: 128n, + loc: { start: 666, end: 669 } + } + }, + loc: { start: 632, end: 670 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendOnlyEstimateFee', + loc: { start: 993, end: 1012 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1014, end: 1017 } + }, + loc: { start: 1014, end: 1017 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1024n, + loc: { start: 1020, end: 1024 } + } + }, + loc: { start: 987, end: 1025 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendPayGasSeparately', + loc: { start: 1207, end: 1227 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1229, end: 1232 } + }, + loc: { start: 1229, end: 1232 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1235, end: 1236 } + } + }, + loc: { start: 1201, end: 1237 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendPayFwdFeesSeparately', + loc: { start: 1378, end: 1402 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1404, end: 1407 } + }, + loc: { start: 1404, end: 1407 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1410, end: 1411 } + } + }, + loc: { start: 1372, end: 1412 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendIgnoreErrors', + loc: { start: 1582, end: 1598 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1600, end: 1603 } + }, + loc: { start: 1600, end: 1603 } + }, + initializer: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 1606, end: 1607 } + } + }, + loc: { start: 1576, end: 1608 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendBounceIfActionFail', + loc: { start: 1817, end: 1839 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1841, end: 1844 } + }, + loc: { start: 1841, end: 1844 } + }, + initializer: { + kind: 'number', + base: '10', + value: 16n, + loc: { start: 1847, end: 1849 } + } + }, + loc: { start: 1811, end: 1850 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendDestroyIfZero', + loc: { start: 2085, end: 2102 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2104, end: 2107 } + }, + loc: { start: 2104, end: 2107 } + }, + initializer: { + kind: 'number', + base: '10', + value: 32n, + loc: { start: 2110, end: 2112 } + } + }, + loc: { start: 2079, end: 2113 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'SendParameters', + loc: { start: 2260, end: 2274 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 2416, end: 2420 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2422, end: 2425 } + }, + loc: { start: 2422, end: 2425 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 2428, end: 2443 } + }, + loc: { start: 2416, end: 2443 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 2493, end: 2497 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2503, end: 2504 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2499, end: 2503 } + }, + loc: { start: 2499, end: 2503 } + } + ], + loc: { start: 2503, end: 2504 } + }, + initializer: { kind: 'null', loc: { start: 2507, end: 2511 } }, + loc: { start: 2493, end: 2511 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'code', + loc: { start: 2584, end: 2588 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2594, end: 2595 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2590, end: 2594 } + }, + loc: { start: 2590, end: 2594 } + } + ], + loc: { start: 2594, end: 2595 } + }, + initializer: { kind: 'null', loc: { start: 2598, end: 2602 } }, + loc: { start: 2584, end: 2602 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'data', + loc: { start: 2722, end: 2726 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2732, end: 2733 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2728, end: 2732 } + }, + loc: { start: 2728, end: 2732 } + } + ], + loc: { start: 2732, end: 2733 } + }, + initializer: { kind: 'null', loc: { start: 2736, end: 2740 } }, + loc: { start: 2722, end: 2740 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 2936, end: 2941 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2943, end: 2946 } + }, + loc: { start: 2943, end: 2946 } + }, + initializer: undefined, + loc: { start: 2936, end: 2946 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'to', + loc: { start: 3009, end: 3011 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3013, end: 3020 } + }, + typeArgs: [], + loc: { start: 3013, end: 3020 } + }, + initializer: undefined, + loc: { start: 3009, end: 3020 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 3186, end: 3192 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 3194, end: 3198 } + }, + typeArgs: [], + loc: { start: 3194, end: 3198 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 3201, end: 3205 } + }, + loc: { start: 3186, end: 3205 } + } + ], + loc: { start: 2253, end: 3208 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'MessageParameters', + loc: { start: 3389, end: 3406 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 3548, end: 3552 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3554, end: 3557 } + }, + loc: { start: 3554, end: 3557 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 3560, end: 3575 } + }, + loc: { start: 3548, end: 3575 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 3625, end: 3629 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 3635, end: 3636 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 3631, end: 3635 } + }, + loc: { start: 3631, end: 3635 } + } + ], + loc: { start: 3635, end: 3636 } + }, + initializer: { kind: 'null', loc: { start: 3639, end: 3643 } }, + loc: { start: 3625, end: 3643 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 3839, end: 3844 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3846, end: 3849 } + }, + loc: { start: 3846, end: 3849 } + }, + initializer: undefined, + loc: { start: 3839, end: 3849 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'to', + loc: { start: 3912, end: 3914 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3916, end: 3923 } + }, + typeArgs: [], + loc: { start: 3916, end: 3923 } + }, + initializer: undefined, + loc: { start: 3912, end: 3923 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 4089, end: 4095 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 4097, end: 4101 } + }, + typeArgs: [], + loc: { start: 4097, end: 4101 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 4104, end: 4108 } + }, + loc: { start: 4089, end: 4108 } + } + ], + loc: { start: 3382, end: 4111 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'message', + loc: { start: 5056, end: 5063 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 5064, end: 5070 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'MessageParameters', + loc: { start: 5072, end: 5089 } + }, + typeArgs: [], + loc: { start: 5072, end: 5089 } + }, + loc: { start: 5064, end: 5089 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 106 PUSHINT // 1 + 4 + 4 + 64 + 32 + 1\n' + + ' STZEROES\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + ' STDICT\n' + + ' ENDC\n' + + ' SWAP\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 5048, end: 5588 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'send', loc: { start: 6219, end: 6223 } }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 6224, end: 6230 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'SendParameters', + loc: { start: 6232, end: 6246 } + }, + typeArgs: [], + loc: { start: 6232, end: 6246 } + }, + loc: { start: 6224, end: 6246 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + '\n' + + ' // Group 2: Placing the Builder after code and data, then checking those for nullability\n' + + ' s2 XCHG0\n' + + ' DUP2\n' + + ' ISNULL\n' + + ' SWAP\n' + + ' ISNULL\n' + + ' AND\n' + + ' // → Stack state\n' + + ' // s0: -1 (true) if `data` and `code` are both null, 0 (false) otherwise\n' + + ' // s1: `code`\n' + + ' // s2: `data`\n' + + ' // s3: Builder\n' + + ' // s4: `body`\n' + + ' // s5: `mode`\n' + + '\n' + + ' // Group 3: Left branch of the IFELSE, executed if s0 is -1 (true)\n' + + ' <{\n' + + ' DROP2 // drop `data` and `code`, since either of those is null\n' + + ' b{0} STSLICECONST\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: Right branch of the IFELSE, executed if s0 is 0 (false)\n' + + ' <{\n' + + ' // _ split_depth:(Maybe (## 5))\n' + + ' // special:(Maybe TickTock)\n' + + ' // code:(Maybe ^Cell)\n' + + ' // data:(Maybe ^Cell)\n' + + ' // library:(Maybe ^Cell)\n' + + ' // = StateInit;\n' + + ' ROT // place message Builder on top\n' + + ' b{10} STSLICECONST // store Maybe = true, Either = false\n' + + ' // Start composing inlined StateInit\n' + + ' b{00} STSLICECONST // store split_depth and special first\n' + + ' STDICT // store code\n' + + ' STDICT // store data\n' + + ' b{0} STSLICECONST // store library\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: IFELSE that does the branching shown above\n' + + ' IFELSE\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: null or StateInit\n' + + ' // s2: `body`\n' + + ' // s3: `mode`\n' + + '\n' + + ' // Group 4: Finalizing the message\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: `mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG // https://github.com/tact-lang/tact/issues/1558' + ] + }, + loc: { start: 6211, end: 9157 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'DeployParameters', + loc: { start: 9347, end: 9363 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 9505, end: 9509 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9511, end: 9514 } + }, + loc: { start: 9511, end: 9514 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 9517, end: 9532 } + }, + loc: { start: 9505, end: 9532 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 9582, end: 9586 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 9592, end: 9593 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 9588, end: 9592 } + }, + loc: { start: 9588, end: 9592 } + } + ], + loc: { start: 9592, end: 9593 } + }, + initializer: { kind: 'null', loc: { start: 9596, end: 9600 } }, + loc: { start: 9582, end: 9600 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 9796, end: 9801 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9803, end: 9806 } + }, + loc: { start: 9803, end: 9806 } + }, + initializer: undefined, + loc: { start: 9796, end: 9806 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 9972, end: 9978 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 9980, end: 9984 } + }, + typeArgs: [], + loc: { start: 9980, end: 9984 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 9987, end: 9991 } + }, + loc: { start: 9972, end: 9991 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'init', + loc: { start: 10135, end: 10139 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 10141, end: 10150 } + }, + typeArgs: [], + loc: { start: 10141, end: 10150 } + }, + initializer: undefined, + loc: { start: 10135, end: 10150 } + } + ], + loc: { start: 9340, end: 10153 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'deploy', + loc: { start: 11796, end: 11802 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 11803, end: 11809 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'DeployParameters', + loc: { start: 11811, end: 11827 } + }, + typeArgs: [], + loc: { start: 11811, end: 11827 } + }, + loc: { start: 11803, end: 11827 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '4 1 BLKPUSH // pushes 2 copies of `init.code` and `init.data`\n' + + ' HASHCU // `init.data` hash\n' + + ' SWAP\n' + + ' HASHCU // `init.code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `init.data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `init.code` depth\n' + + '\n' + + ' // Group 2: Calculating destination address\n' + + ' // For almost identical logic and instructions,\n' + + ' // see comments inside `contractHash()` function in contract.tact\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + ' NEWC\n' + + ' 24 STU\n' + + ' 16 STU\n' + + ' 16 STU\n' + + ' 256 STU\n' + + ' 256 STU\n' + + ' ONE HASHEXT_SHA256 // obtains hash part (account id) of the address\n' + + ' // → Stack state\n' + + ' // s0: destAddr(hash part)\n' + + ' // s1: `init.data`\n' + + ' // s2: `init.code`\n' + + ' // s3 and below: `bounce`, `value`, `body`, `mode`\n' + + '\n' + + ' // Group 3: Building a message (CommonMsgInfoRelaxed)\n' + + ' s3 XCHG0 // swaps `bounce` with destAddr(hash part)\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' s1 s2 XCHG // swap `init.data` with `init.code`, placing code on s1\n' + + ' STREF // store `init.code`\n' + + ' STREF // store `init.data`\n' + + ' // Inline StateInit:\n' + + ' b{00010000000000} STSLICECONST\n' + + ' // 0 + 00 + 10 + 0 + 00000000\n' + + ' // 1) 0 - bounced = false\n' + + ' // 2) 00 - src = addr_none\n' + + ' // 3) 10 - tag of addr_std (part of dest)\n' + + ' // 4) 0 - Maybe Anycast = false\n' + + ' // 5) 00000000 - workchain_id (part of dest)\n' + + ' //\n' + + ' 256 STU // store destAddr(hash part)\n' + + ' SWAP // Builder on top, `value` below\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + '\n' + + ' // Group 4: Continue building a message (CommonMsgInfoRelaxed into MessageRelaxed)\n' + + ' // Remaining bits of MessageRelaxed:\n' + + ' b{1000110} STSLICECONST\n' + + ' // 10 + 0 + 0 + 1 + 1 + 0\n' + + ' // 10 - Maybe (Either StateInit ^StateInit) = true false\n' + + ' // 0 - split_depth:(Maybe (## 5)) = false\n' + + ' // 0 = special:(Maybe TickTock) = false\n' + + ' // 1 = code:(Maybe ^Cell) = true\n' + + ' // 1 = data:(Maybe ^Cell) = true\n' + + ' // 0 = library:(Maybe ^Cell) = false\n' + + ' //\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC // finalize the message\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: params.`mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 11788, end: 14770 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'cashback', + loc: { start: 15971, end: 15979 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'to', + loc: { start: 15980, end: 15982 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 15984, end: 15991 } + }, + typeArgs: [], + loc: { start: 15984, end: 15991 } + }, + loc: { start: 15980, end: 15991 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '16 PUSHINT // 0x10, i.e. 0x18 but with bounce = false\n' + + ' NEWC\n' + + ' 6 STU // .storeUint(0x10, 6)\n' + + ' STSLICE // .storeAddress(to)\n' + + ' 0 PUSHINT // 0\n' + + ' 111 STUR // .storeUint(0, 111)\n' + + ' // 4 zeros for coins and 107 zeros for lt, fees, etc.\n' + + ' ENDC\n' + + ' 66 PUSHINT // SendRemainingValue | SendIgnoreErrors\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 15963, end: 16385 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeSendMessage', + loc: { start: 16936, end: 16953 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 16954, end: 16957 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 16959, end: 16963 } + }, + loc: { start: 16959, end: 16963 } + }, + loc: { start: 16954, end: 16963 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 16965, end: 16969 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 16971, end: 16974 } + }, + loc: { start: 16971, end: 16974 } + }, + loc: { start: 16965, end: 16974 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDRAWMSG' ] + }, + loc: { start: 16928, end: 16990 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sendRawMessage', + loc: { start: 17751, end: 17765 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 17766, end: 17769 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 17771, end: 17775 } + }, + loc: { start: 17771, end: 17775 } + }, + loc: { start: 17766, end: 17775 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 17777, end: 17781 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 17783, end: 17786 } + }, + loc: { start: 17783, end: 17786 } + }, + loc: { start: 17777, end: 17786 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDRAWMSG' ] + }, + loc: { start: 17743, end: 17802 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeSendMessageReturnForwardFee', + loc: { start: 19063, end: 19096 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 19120, end: 19123 } + }, + loc: { start: 19120, end: 19123 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 19097, end: 19100 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 19102, end: 19106 } + }, + loc: { start: 19102, end: 19106 } + }, + loc: { start: 19097, end: 19106 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 19108, end: 19112 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 19114, end: 19117 } + }, + loc: { start: 19114, end: 19117 } + }, + loc: { start: 19108, end: 19117 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDMSG' ] + }, + loc: { start: 19055, end: 19135 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sendMessageReturnForwardFee', + loc: { start: 20186, end: 20213 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 20237, end: 20240 } + }, + loc: { start: 20237, end: 20240 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 20214, end: 20217 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 20219, end: 20223 } + }, + loc: { start: 20219, end: 20223 } + }, + loc: { start: 20214, end: 20223 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 20225, end: 20229 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 20231, end: 20234 } + }, + loc: { start: 20231, end: 20234 } + }, + loc: { start: 20225, end: 20234 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDMSG' ] + }, + loc: { start: 20178, end: 20252 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'emit', + loc: { start: 21033, end: 21037 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'body', + loc: { start: 21038, end: 21042 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 21044, end: 21048 } + }, + loc: { start: 21044, end: 21048 } + }, + loc: { start: 21038, end: 21048 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'c', + loc: { start: 21233, end: 21234 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 21236, end: 21240 } + }, + loc: { start: 21236, end: 21240 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'static_call', + function: { + kind: 'id', + text: 'beginCell', + loc: { start: 21243, end: 21252 } + }, + typeArgs: [], + args: [], + loc: { start: 21243, end: 21254 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 21264, end: 21273 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 15211807202738752817960438464513n, + loc: { start: 21274, end: 21306 } + }, + { + kind: 'number', + base: '10', + value: 104n, + loc: { start: 21308, end: 21311 } + } + ], + loc: { start: 21243, end: 21312 } + }, + method: { + kind: 'id', + text: 'storeRef', + loc: { start: 21322, end: 21330 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'body', + loc: { start: 21331, end: 21335 } + } + ], + loc: { start: 21243, end: 21336 } + }, + method: { + kind: 'id', + text: 'endCell', + loc: { start: 21346, end: 21353 } + }, + typeArgs: [], + args: [], + loc: { start: 21243, end: 21355 } + }, + loc: { start: 21229, end: 21356 } + }, + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'sendRawMessage', + loc: { start: 21361, end: 21375 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'c', + loc: { start: 21376, end: 21377 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 21379, end: 21380 } + } + ], + loc: { start: 21361, end: 21381 } + }, + loc: { start: 21361, end: 21382 } + } + ] + }, + loc: { start: 21022, end: 21384 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'acceptMessage', + loc: { start: 22124, end: 22137 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ACCEPT' ] + }, + loc: { start: 22116, end: 22150 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'commit', + loc: { start: 22638, end: 22644 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'COMMIT' ] + }, + loc: { start: 22630, end: 22657 } + } + ] + }, + 'deploy' => { + kind: 'tact', + path: 'std/internal/send.tact', + code: '/// Ordinary message (default).\n' + + '///\n' + + '/// This constant is available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendDefaultMode: Int = 0;\n' + + '\n' + + '/// Carry all the remaining value of the inbound message in addition\n' + + '/// to the value initially indicated in the new message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendRemainingValue: Int = 64;\n' + + '\n' + + '/// Carry **all the remaining balance** of the current smart contract instead\n' + + '/// of the value originally indicated in the message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendRemainingBalance: Int = 128;\n' + + '\n' + + "/// Doesn't send the message, only estimates the forward fees\n" + + '/// if the message-sending function computes those.\n' + + '///\n' + + '/// This constant is available since Tact 1.5.0.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '/// * https://docs.tact-lang.org/book/send#message-sending-functions\n' + + '///\n' + + 'const SendOnlyEstimateFee: Int = 1024;\n' + + '\n' + + '/// **Deprecated** since Tact 1.6.5.\n' + + '///\n' + + '/// Pay forward fees separately from the message value.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendPayGasSeparately: Int = 1;\n' + + '\n' + + '/// Pay forward fees separately from the message value.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendPayFwdFeesSeparately: Int = 1;\n' + + '\n' + + '/// Ignore any errors arising while processing this message during the action phase.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendIgnoreErrors: Int = 2;\n' + + '\n' + + '/// Bounce transaction in case of any errors during action phase.\n' + + '/// Has no effect if flag +2, `SendIgnoreErrors` is used.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendBounceIfActionFail: Int = 16;\n' + + '\n' + + '/// Current account (contract) will be destroyed if its resulting balance is zero.\n' + + '/// This flag is often used with mode 128, `SendRemainingBalance`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendDestroyIfZero: Int = 32;\n' + + '\n' + + '/// Struct for specifying the message parameters of the `send()` function.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#send\n' + + '///\n' + + 'struct SendParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// Optional initial code of the contract (compiled bitcode).\n' + + ' code: Cell? = null;\n' + + '\n' + + ' /// Optional initial data of the contract (arguments of `init()` function or values of contract parameters).\n' + + ' data: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// Recipient internal `Address` on TON Blockchain.\n' + + ' to: Address;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '}\n' + + '\n' + + '/// Struct for specifying the message parameters of the `message()` function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#message\n' + + '///\n' + + 'struct MessageParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// Recipient internal `Address` on TON Blockchain.\n' + + ' to: Address;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Queues the message to be sent using the `MessageParameters` struct. Allows for cheaper non-deployment, regular messages compared to the `send()` function.\n' + + '///\n' + + '/// The `MessageParameters` struct is similar to `SendParameters` struct, but without the `code` and `data` fields.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// message(MessageParameters{\n' + + '/// to: sender(), // back to the sender,\n' + + '/// value: ton("1"), // with 1 Toncoin (1_000_000_000 nanoToncoin),\n' + + '/// // and no message body\n' + + '/// });\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 33: [Action list is too long] — Thrown when attempting to queue more than 255 messages.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-send#message\n' + + '/// * https://docs.tact-lang.org/book/message-mode\n' + + '///\n' + + '/// [Action list is too long]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '///\n' + + 'asm fun message(params: MessageParameters) {\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 106 PUSHINT // 1 + 4 + 4 + 64 + 32 + 1\n' + + ' STZEROES\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + ' STDICT\n' + + ' ENDC\n' + + ' SWAP\n' + + ' SENDRAWMSG\n' + + '}\n' + + '\n' + + '/// Global function. Queues the message to be sent using a `SendParameters` Struct.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// send(SendParameters{\n' + + '/// to: sender(), // back to the sender,\n' + + '/// value: ton("1"), // with 1 Toncoin (1_000_000_000 nanoToncoin),\n' + + '/// // and no message body\n' + + '/// });\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 33: [Action list is too long] — Thrown when attempting to queue more than 255 messages.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#send\n' + + '///\n' + + '/// [Action list is too long]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '///\n' + + 'asm fun send(params: SendParameters) {\n' + + ' // Instructions are grouped, and the stack states they produce as a group are shown right after.\n' + + ' // In the end, our message Cell should have the following TL-B structure:\n' + + ' // message$_ {X:Type}\n' + + ' // info:CommonMsgInfoRelaxed\n' + + ' // init:(Maybe (Either StateInit ^StateInit))\n' + + ' // body:(Either X ^X)\n' + + ' // = MessageRelaxed X;\n' + + '\n' + + ' // → Stack state\n' + + ' // s0: `params.bounce`\n' + + ' // s1: `params.to`\n' + + ' // s2: `params.value`\n' + + ' // s3: `params.data`\n' + + ' // s4: `params.code`\n' + + ' // s5: `params.body`\n' + + ' // s6: `params.mode`\n' + + ' // For brevity, the "params" prefix will be omitted from now on.\n' + + '\n' + + ' // Group 1: Storing the `bounce`, `to` and `value` into a Builder\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + '\n' + + ' // Group 2: Placing the Builder after code and data, then checking those for nullability\n' + + ' s2 XCHG0\n' + + ' DUP2\n' + + ' ISNULL\n' + + ' SWAP\n' + + ' ISNULL\n' + + ' AND\n' + + ' // → Stack state\n' + + ' // s0: -1 (true) if `data` and `code` are both null, 0 (false) otherwise\n' + + ' // s1: `code`\n' + + ' // s2: `data`\n' + + ' // s3: Builder\n' + + ' // s4: `body`\n' + + ' // s5: `mode`\n' + + '\n' + + ' // Group 3: Left branch of the IFELSE, executed if s0 is -1 (true)\n' + + ' <{\n' + + ' DROP2 // drop `data` and `code`, since either of those is null\n' + + ' b{0} STSLICECONST\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: Right branch of the IFELSE, executed if s0 is 0 (false)\n' + + ' <{\n' + + ' // _ split_depth:(Maybe (## 5))\n' + + ' // special:(Maybe TickTock)\n' + + ' // code:(Maybe ^Cell)\n' + + ' // data:(Maybe ^Cell)\n' + + ' // library:(Maybe ^Cell)\n' + + ' // = StateInit;\n' + + ' ROT // place message Builder on top\n' + + ' b{10} STSLICECONST // store Maybe = true, Either = false\n' + + ' // Start composing inlined StateInit\n' + + ' b{00} STSLICECONST // store split_depth and special first\n' + + ' STDICT // store code\n' + + ' STDICT // store data\n' + + ' b{0} STSLICECONST // store library\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: IFELSE that does the branching shown above\n' + + ' IFELSE\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: null or StateInit\n' + + ' // s2: `body`\n' + + ' // s3: `mode`\n' + + '\n' + + ' // Group 4: Finalizing the message\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: `mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG // https://github.com/tact-lang/tact/issues/1558\n' + + '}\n' + + '\n' + + '/// Struct for specifying the deployment message parameters of the `deploy()` function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#deploy\n' + + '///\n' + + 'struct DeployParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '\n' + + ' //'... 12658 more characters, + imports: [], + items: [ + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendDefaultMode', + loc: { start: 164, end: 179 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 181, end: 184 } + }, + loc: { start: 181, end: 184 } + }, + initializer: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 187, end: 188 } + } + }, + loc: { start: 158, end: 189 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendRemainingValue', + loc: { start: 396, end: 414 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 416, end: 419 } + }, + loc: { start: 416, end: 419 } + }, + initializer: { + kind: 'number', + base: '10', + value: 64n, + loc: { start: 422, end: 424 } + } + }, + loc: { start: 390, end: 425 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendRemainingBalance', + loc: { start: 638, end: 658 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 660, end: 663 } + }, + loc: { start: 660, end: 663 } + }, + initializer: { + kind: 'number', + base: '10', + value: 128n, + loc: { start: 666, end: 669 } + } + }, + loc: { start: 632, end: 670 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendOnlyEstimateFee', + loc: { start: 993, end: 1012 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1014, end: 1017 } + }, + loc: { start: 1014, end: 1017 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1024n, + loc: { start: 1020, end: 1024 } + } + }, + loc: { start: 987, end: 1025 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendPayGasSeparately', + loc: { start: 1207, end: 1227 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1229, end: 1232 } + }, + loc: { start: 1229, end: 1232 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1235, end: 1236 } + } + }, + loc: { start: 1201, end: 1237 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendPayFwdFeesSeparately', + loc: { start: 1378, end: 1402 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1404, end: 1407 } + }, + loc: { start: 1404, end: 1407 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1410, end: 1411 } + } + }, + loc: { start: 1372, end: 1412 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendIgnoreErrors', + loc: { start: 1582, end: 1598 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1600, end: 1603 } + }, + loc: { start: 1600, end: 1603 } + }, + initializer: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 1606, end: 1607 } + } + }, + loc: { start: 1576, end: 1608 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendBounceIfActionFail', + loc: { start: 1817, end: 1839 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1841, end: 1844 } + }, + loc: { start: 1841, end: 1844 } + }, + initializer: { + kind: 'number', + base: '10', + value: 16n, + loc: { start: 1847, end: 1849 } + } + }, + loc: { start: 1811, end: 1850 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendDestroyIfZero', + loc: { start: 2085, end: 2102 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2104, end: 2107 } + }, + loc: { start: 2104, end: 2107 } + }, + initializer: { + kind: 'number', + base: '10', + value: 32n, + loc: { start: 2110, end: 2112 } + } + }, + loc: { start: 2079, end: 2113 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'SendParameters', + loc: { start: 2260, end: 2274 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 2416, end: 2420 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2422, end: 2425 } + }, + loc: { start: 2422, end: 2425 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 2428, end: 2443 } + }, + loc: { start: 2416, end: 2443 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 2493, end: 2497 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2503, end: 2504 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2499, end: 2503 } + }, + loc: { start: 2499, end: 2503 } + } + ], + loc: { start: 2503, end: 2504 } + }, + initializer: { kind: 'null', loc: { start: 2507, end: 2511 } }, + loc: { start: 2493, end: 2511 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'code', + loc: { start: 2584, end: 2588 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2594, end: 2595 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2590, end: 2594 } + }, + loc: { start: 2590, end: 2594 } + } + ], + loc: { start: 2594, end: 2595 } + }, + initializer: { kind: 'null', loc: { start: 2598, end: 2602 } }, + loc: { start: 2584, end: 2602 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'data', + loc: { start: 2722, end: 2726 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2732, end: 2733 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2728, end: 2732 } + }, + loc: { start: 2728, end: 2732 } + } + ], + loc: { start: 2732, end: 2733 } + }, + initializer: { kind: 'null', loc: { start: 2736, end: 2740 } }, + loc: { start: 2722, end: 2740 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 2936, end: 2941 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2943, end: 2946 } + }, + loc: { start: 2943, end: 2946 } + }, + initializer: undefined, + loc: { start: 2936, end: 2946 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'to', + loc: { start: 3009, end: 3011 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3013, end: 3020 } + }, + typeArgs: [], + loc: { start: 3013, end: 3020 } + }, + initializer: undefined, + loc: { start: 3009, end: 3020 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 3186, end: 3192 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 3194, end: 3198 } + }, + typeArgs: [], + loc: { start: 3194, end: 3198 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 3201, end: 3205 } + }, + loc: { start: 3186, end: 3205 } + } + ], + loc: { start: 2253, end: 3208 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'MessageParameters', + loc: { start: 3389, end: 3406 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 3548, end: 3552 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3554, end: 3557 } + }, + loc: { start: 3554, end: 3557 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 3560, end: 3575 } + }, + loc: { start: 3548, end: 3575 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 3625, end: 3629 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 3635, end: 3636 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 3631, end: 3635 } + }, + loc: { start: 3631, end: 3635 } + } + ], + loc: { start: 3635, end: 3636 } + }, + initializer: { kind: 'null', loc: { start: 3639, end: 3643 } }, + loc: { start: 3625, end: 3643 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 3839, end: 3844 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3846, end: 3849 } + }, + loc: { start: 3846, end: 3849 } + }, + initializer: undefined, + loc: { start: 3839, end: 3849 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'to', + loc: { start: 3912, end: 3914 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3916, end: 3923 } + }, + typeArgs: [], + loc: { start: 3916, end: 3923 } + }, + initializer: undefined, + loc: { start: 3912, end: 3923 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 4089, end: 4095 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 4097, end: 4101 } + }, + typeArgs: [], + loc: { start: 4097, end: 4101 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 4104, end: 4108 } + }, + loc: { start: 4089, end: 4108 } + } + ], + loc: { start: 3382, end: 4111 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'message', + loc: { start: 5056, end: 5063 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 5064, end: 5070 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'MessageParameters', + loc: { start: 5072, end: 5089 } + }, + typeArgs: [], + loc: { start: 5072, end: 5089 } + }, + loc: { start: 5064, end: 5089 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 106 PUSHINT // 1 + 4 + 4 + 64 + 32 + 1\n' + + ' STZEROES\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + ' STDICT\n' + + ' ENDC\n' + + ' SWAP\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 5048, end: 5588 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'send', loc: { start: 6219, end: 6223 } }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 6224, end: 6230 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'SendParameters', + loc: { start: 6232, end: 6246 } + }, + typeArgs: [], + loc: { start: 6232, end: 6246 } + }, + loc: { start: 6224, end: 6246 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + '\n' + + ' // Group 2: Placing the Builder after code and data, then checking those for nullability\n' + + ' s2 XCHG0\n' + + ' DUP2\n' + + ' ISNULL\n' + + ' SWAP\n' + + ' ISNULL\n' + + ' AND\n' + + ' // → Stack state\n' + + ' // s0: -1 (true) if `data` and `code` are both null, 0 (false) otherwise\n' + + ' // s1: `code`\n' + + ' // s2: `data`\n' + + ' // s3: Builder\n' + + ' // s4: `body`\n' + + ' // s5: `mode`\n' + + '\n' + + ' // Group 3: Left branch of the IFELSE, executed if s0 is -1 (true)\n' + + ' <{\n' + + ' DROP2 // drop `data` and `code`, since either of those is null\n' + + ' b{0} STSLICECONST\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: Right branch of the IFELSE, executed if s0 is 0 (false)\n' + + ' <{\n' + + ' // _ split_depth:(Maybe (## 5))\n' + + ' // special:(Maybe TickTock)\n' + + ' // code:(Maybe ^Cell)\n' + + ' // data:(Maybe ^Cell)\n' + + ' // library:(Maybe ^Cell)\n' + + ' // = StateInit;\n' + + ' ROT // place message Builder on top\n' + + ' b{10} STSLICECONST // store Maybe = true, Either = false\n' + + ' // Start composing inlined StateInit\n' + + ' b{00} STSLICECONST // store split_depth and special first\n' + + ' STDICT // store code\n' + + ' STDICT // store data\n' + + ' b{0} STSLICECONST // store library\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: IFELSE that does the branching shown above\n' + + ' IFELSE\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: null or StateInit\n' + + ' // s2: `body`\n' + + ' // s3: `mode`\n' + + '\n' + + ' // Group 4: Finalizing the message\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: `mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG // https://github.com/tact-lang/tact/issues/1558' + ] + }, + loc: { start: 6211, end: 9157 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'DeployParameters', + loc: { start: 9347, end: 9363 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 9505, end: 9509 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9511, end: 9514 } + }, + loc: { start: 9511, end: 9514 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 9517, end: 9532 } + }, + loc: { start: 9505, end: 9532 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 9582, end: 9586 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 9592, end: 9593 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 9588, end: 9592 } + }, + loc: { start: 9588, end: 9592 } + } + ], + loc: { start: 9592, end: 9593 } + }, + initializer: { kind: 'null', loc: { start: 9596, end: 9600 } }, + loc: { start: 9582, end: 9600 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 9796, end: 9801 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9803, end: 9806 } + }, + loc: { start: 9803, end: 9806 } + }, + initializer: undefined, + loc: { start: 9796, end: 9806 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 9972, end: 9978 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 9980, end: 9984 } + }, + typeArgs: [], + loc: { start: 9980, end: 9984 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 9987, end: 9991 } + }, + loc: { start: 9972, end: 9991 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'init', + loc: { start: 10135, end: 10139 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 10141, end: 10150 } + }, + typeArgs: [], + loc: { start: 10141, end: 10150 } + }, + initializer: undefined, + loc: { start: 10135, end: 10150 } + } + ], + loc: { start: 9340, end: 10153 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'deploy', + loc: { start: 11796, end: 11802 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 11803, end: 11809 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'DeployParameters', + loc: { start: 11811, end: 11827 } + }, + typeArgs: [], + loc: { start: 11811, end: 11827 } + }, + loc: { start: 11803, end: 11827 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '4 1 BLKPUSH // pushes 2 copies of `init.code` and `init.data`\n' + + ' HASHCU // `init.data` hash\n' + + ' SWAP\n' + + ' HASHCU // `init.code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `init.data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `init.code` depth\n' + + '\n' + + ' // Group 2: Calculating destination address\n' + + ' // For almost identical logic and instructions,\n' + + ' // see comments inside `contractHash()` function in contract.tact\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + ' NEWC\n' + + ' 24 STU\n' + + ' 16 STU\n' + + ' 16 STU\n' + + ' 256 STU\n' + + ' 256 STU\n' + + ' ONE HASHEXT_SHA256 // obtains hash part (account id) of the address\n' + + ' // → Stack state\n' + + ' // s0: destAddr(hash part)\n' + + ' // s1: `init.data`\n' + + ' // s2: `init.code`\n' + + ' // s3 and below: `bounce`, `value`, `body`, `mode`\n' + + '\n' + + ' // Group 3: Building a message (CommonMsgInfoRelaxed)\n' + + ' s3 XCHG0 // swaps `bounce` with destAddr(hash part)\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' s1 s2 XCHG // swap `init.data` with `init.code`, placing code on s1\n' + + ' STREF // store `init.code`\n' + + ' STREF // store `init.data`\n' + + ' // Inline StateInit:\n' + + ' b{00010000000000} STSLICECONST\n' + + ' // 0 + 00 + 10 + 0 + 00000000\n' + + ' // 1) 0 - bounced = false\n' + + ' // 2) 00 - src = addr_none\n' + + ' // 3) 10 - tag of addr_std (part of dest)\n' + + ' // 4) 0 - Maybe Anycast = false\n' + + ' // 5) 00000000 - workchain_id (part of dest)\n' + + ' //\n' + + ' 256 STU // store destAddr(hash part)\n' + + ' SWAP // Builder on top, `value` below\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + '\n' + + ' // Group 4: Continue building a message (CommonMsgInfoRelaxed into MessageRelaxed)\n' + + ' // Remaining bits of MessageRelaxed:\n' + + ' b{1000110} STSLICECONST\n' + + ' // 10 + 0 + 0 + 1 + 1 + 0\n' + + ' // 10 - Maybe (Either StateInit ^StateInit) = true false\n' + + ' // 0 - split_depth:(Maybe (## 5)) = false\n' + + ' // 0 = special:(Maybe TickTock) = false\n' + + ' // 1 = code:(Maybe ^Cell) = true\n' + + ' // 1 = data:(Maybe ^Cell) = true\n' + + ' // 0 = library:(Maybe ^Cell) = false\n' + + ' //\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC // finalize the message\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: params.`mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 11788, end: 14770 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'cashback', + loc: { start: 15971, end: 15979 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'to', + loc: { start: 15980, end: 15982 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 15984, end: 15991 } + }, + typeArgs: [], + loc: { start: 15984, end: 15991 } + }, + loc: { start: 15980, end: 15991 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '16 PUSHINT // 0x10, i.e. 0x18 but with bounce = false\n' + + ' NEWC\n' + + ' 6 STU // .storeUint(0x10, 6)\n' + + ' STSLICE // .storeAddress(to)\n' + + ' 0 PUSHINT // 0\n' + + ' 111 STUR // .storeUint(0, 111)\n' + + ' // 4 zeros for coins and 107 zeros for lt, fees, etc.\n' + + ' ENDC\n' + + ' 66 PUSHINT // SendRemainingValue | SendIgnoreErrors\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 15963, end: 16385 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeSendMessage', + loc: { start: 16936, end: 16953 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 16954, end: 16957 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 16959, end: 16963 } + }, + loc: { start: 16959, end: 16963 } + }, + loc: { start: 16954, end: 16963 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 16965, end: 16969 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 16971, end: 16974 } + }, + loc: { start: 16971, end: 16974 } + }, + loc: { start: 16965, end: 16974 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDRAWMSG' ] + }, + loc: { start: 16928, end: 16990 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sendRawMessage', + loc: { start: 17751, end: 17765 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 17766, end: 17769 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 17771, end: 17775 } + }, + loc: { start: 17771, end: 17775 } + }, + loc: { start: 17766, end: 17775 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 17777, end: 17781 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 17783, end: 17786 } + }, + loc: { start: 17783, end: 17786 } + }, + loc: { start: 17777, end: 17786 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDRAWMSG' ] + }, + loc: { start: 17743, end: 17802 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeSendMessageReturnForwardFee', + loc: { start: 19063, end: 19096 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 19120, end: 19123 } + }, + loc: { start: 19120, end: 19123 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 19097, end: 19100 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 19102, end: 19106 } + }, + loc: { start: 19102, end: 19106 } + }, + loc: { start: 19097, end: 19106 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 19108, end: 19112 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 19114, end: 19117 } + }, + loc: { start: 19114, end: 19117 } + }, + loc: { start: 19108, end: 19117 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDMSG' ] + }, + loc: { start: 19055, end: 19135 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sendMessageReturnForwardFee', + loc: { start: 20186, end: 20213 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 20237, end: 20240 } + }, + loc: { start: 20237, end: 20240 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 20214, end: 20217 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 20219, end: 20223 } + }, + loc: { start: 20219, end: 20223 } + }, + loc: { start: 20214, end: 20223 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 20225, end: 20229 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 20231, end: 20234 } + }, + loc: { start: 20231, end: 20234 } + }, + loc: { start: 20225, end: 20234 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDMSG' ] + }, + loc: { start: 20178, end: 20252 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'emit', + loc: { start: 21033, end: 21037 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'body', + loc: { start: 21038, end: 21042 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 21044, end: 21048 } + }, + loc: { start: 21044, end: 21048 } + }, + loc: { start: 21038, end: 21048 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'c', + loc: { start: 21233, end: 21234 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 21236, end: 21240 } + }, + loc: { start: 21236, end: 21240 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'static_call', + function: { + kind: 'id', + text: 'beginCell', + loc: { start: 21243, end: 21252 } + }, + typeArgs: [], + args: [], + loc: { start: 21243, end: 21254 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 21264, end: 21273 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 15211807202738752817960438464513n, + loc: { start: 21274, end: 21306 } + }, + { + kind: 'number', + base: '10', + value: 104n, + loc: { start: 21308, end: 21311 } + } + ], + loc: { start: 21243, end: 21312 } + }, + method: { + kind: 'id', + text: 'storeRef', + loc: { start: 21322, end: 21330 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'body', + loc: { start: 21331, end: 21335 } + } + ], + loc: { start: 21243, end: 21336 } + }, + method: { + kind: 'id', + text: 'endCell', + loc: { start: 21346, end: 21353 } + }, + typeArgs: [], + args: [], + loc: { start: 21243, end: 21355 } + }, + loc: { start: 21229, end: 21356 } + }, + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'sendRawMessage', + loc: { start: 21361, end: 21375 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'c', + loc: { start: 21376, end: 21377 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 21379, end: 21380 } + } + ], + loc: { start: 21361, end: 21381 } + }, + loc: { start: 21361, end: 21382 } + } + ] + }, + loc: { start: 21022, end: 21384 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'acceptMessage', + loc: { start: 22124, end: 22137 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ACCEPT' ] + }, + loc: { start: 22116, end: 22150 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'commit', + loc: { start: 22638, end: 22644 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'COMMIT' ] + }, + loc: { start: 22630, end: 22657 } + } + ] + }, + 'cashback' => { + kind: 'tact', + path: 'std/internal/send.tact', + code: '/// Ordinary message (default).\n' + + '///\n' + + '/// This constant is available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendDefaultMode: Int = 0;\n' + + '\n' + + '/// Carry all the remaining value of the inbound message in addition\n' + + '/// to the value initially indicated in the new message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendRemainingValue: Int = 64;\n' + + '\n' + + '/// Carry **all the remaining balance** of the current smart contract instead\n' + + '/// of the value originally indicated in the message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendRemainingBalance: Int = 128;\n' + + '\n' + + "/// Doesn't send the message, only estimates the forward fees\n" + + '/// if the message-sending function computes those.\n' + + '///\n' + + '/// This constant is available since Tact 1.5.0.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '/// * https://docs.tact-lang.org/book/send#message-sending-functions\n' + + '///\n' + + 'const SendOnlyEstimateFee: Int = 1024;\n' + + '\n' + + '/// **Deprecated** since Tact 1.6.5.\n' + + '///\n' + + '/// Pay forward fees separately from the message value.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendPayGasSeparately: Int = 1;\n' + + '\n' + + '/// Pay forward fees separately from the message value.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendPayFwdFeesSeparately: Int = 1;\n' + + '\n' + + '/// Ignore any errors arising while processing this message during the action phase.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendIgnoreErrors: Int = 2;\n' + + '\n' + + '/// Bounce transaction in case of any errors during action phase.\n' + + '/// Has no effect if flag +2, `SendIgnoreErrors` is used.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendBounceIfActionFail: Int = 16;\n' + + '\n' + + '/// Current account (contract) will be destroyed if its resulting balance is zero.\n' + + '/// This flag is often used with mode 128, `SendRemainingBalance`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendDestroyIfZero: Int = 32;\n' + + '\n' + + '/// Struct for specifying the message parameters of the `send()` function.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#send\n' + + '///\n' + + 'struct SendParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// Optional initial code of the contract (compiled bitcode).\n' + + ' code: Cell? = null;\n' + + '\n' + + ' /// Optional initial data of the contract (arguments of `init()` function or values of contract parameters).\n' + + ' data: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// Recipient internal `Address` on TON Blockchain.\n' + + ' to: Address;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '}\n' + + '\n' + + '/// Struct for specifying the message parameters of the `message()` function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#message\n' + + '///\n' + + 'struct MessageParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// Recipient internal `Address` on TON Blockchain.\n' + + ' to: Address;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Queues the message to be sent using the `MessageParameters` struct. Allows for cheaper non-deployment, regular messages compared to the `send()` function.\n' + + '///\n' + + '/// The `MessageParameters` struct is similar to `SendParameters` struct, but without the `code` and `data` fields.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// message(MessageParameters{\n' + + '/// to: sender(), // back to the sender,\n' + + '/// value: ton("1"), // with 1 Toncoin (1_000_000_000 nanoToncoin),\n' + + '/// // and no message body\n' + + '/// });\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 33: [Action list is too long] — Thrown when attempting to queue more than 255 messages.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-send#message\n' + + '/// * https://docs.tact-lang.org/book/message-mode\n' + + '///\n' + + '/// [Action list is too long]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '///\n' + + 'asm fun message(params: MessageParameters) {\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 106 PUSHINT // 1 + 4 + 4 + 64 + 32 + 1\n' + + ' STZEROES\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + ' STDICT\n' + + ' ENDC\n' + + ' SWAP\n' + + ' SENDRAWMSG\n' + + '}\n' + + '\n' + + '/// Global function. Queues the message to be sent using a `SendParameters` Struct.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// send(SendParameters{\n' + + '/// to: sender(), // back to the sender,\n' + + '/// value: ton("1"), // with 1 Toncoin (1_000_000_000 nanoToncoin),\n' + + '/// // and no message body\n' + + '/// });\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 33: [Action list is too long] — Thrown when attempting to queue more than 255 messages.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#send\n' + + '///\n' + + '/// [Action list is too long]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '///\n' + + 'asm fun send(params: SendParameters) {\n' + + ' // Instructions are grouped, and the stack states they produce as a group are shown right after.\n' + + ' // In the end, our message Cell should have the following TL-B structure:\n' + + ' // message$_ {X:Type}\n' + + ' // info:CommonMsgInfoRelaxed\n' + + ' // init:(Maybe (Either StateInit ^StateInit))\n' + + ' // body:(Either X ^X)\n' + + ' // = MessageRelaxed X;\n' + + '\n' + + ' // → Stack state\n' + + ' // s0: `params.bounce`\n' + + ' // s1: `params.to`\n' + + ' // s2: `params.value`\n' + + ' // s3: `params.data`\n' + + ' // s4: `params.code`\n' + + ' // s5: `params.body`\n' + + ' // s6: `params.mode`\n' + + ' // For brevity, the "params" prefix will be omitted from now on.\n' + + '\n' + + ' // Group 1: Storing the `bounce`, `to` and `value` into a Builder\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + '\n' + + ' // Group 2: Placing the Builder after code and data, then checking those for nullability\n' + + ' s2 XCHG0\n' + + ' DUP2\n' + + ' ISNULL\n' + + ' SWAP\n' + + ' ISNULL\n' + + ' AND\n' + + ' // → Stack state\n' + + ' // s0: -1 (true) if `data` and `code` are both null, 0 (false) otherwise\n' + + ' // s1: `code`\n' + + ' // s2: `data`\n' + + ' // s3: Builder\n' + + ' // s4: `body`\n' + + ' // s5: `mode`\n' + + '\n' + + ' // Group 3: Left branch of the IFELSE, executed if s0 is -1 (true)\n' + + ' <{\n' + + ' DROP2 // drop `data` and `code`, since either of those is null\n' + + ' b{0} STSLICECONST\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: Right branch of the IFELSE, executed if s0 is 0 (false)\n' + + ' <{\n' + + ' // _ split_depth:(Maybe (## 5))\n' + + ' // special:(Maybe TickTock)\n' + + ' // code:(Maybe ^Cell)\n' + + ' // data:(Maybe ^Cell)\n' + + ' // library:(Maybe ^Cell)\n' + + ' // = StateInit;\n' + + ' ROT // place message Builder on top\n' + + ' b{10} STSLICECONST // store Maybe = true, Either = false\n' + + ' // Start composing inlined StateInit\n' + + ' b{00} STSLICECONST // store split_depth and special first\n' + + ' STDICT // store code\n' + + ' STDICT // store data\n' + + ' b{0} STSLICECONST // store library\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: IFELSE that does the branching shown above\n' + + ' IFELSE\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: null or StateInit\n' + + ' // s2: `body`\n' + + ' // s3: `mode`\n' + + '\n' + + ' // Group 4: Finalizing the message\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: `mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG // https://github.com/tact-lang/tact/issues/1558\n' + + '}\n' + + '\n' + + '/// Struct for specifying the deployment message parameters of the `deploy()` function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#deploy\n' + + '///\n' + + 'struct DeployParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '\n' + + ' //'... 12658 more characters, + imports: [], + items: [ + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendDefaultMode', + loc: { start: 164, end: 179 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 181, end: 184 } + }, + loc: { start: 181, end: 184 } + }, + initializer: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 187, end: 188 } + } + }, + loc: { start: 158, end: 189 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendRemainingValue', + loc: { start: 396, end: 414 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 416, end: 419 } + }, + loc: { start: 416, end: 419 } + }, + initializer: { + kind: 'number', + base: '10', + value: 64n, + loc: { start: 422, end: 424 } + } + }, + loc: { start: 390, end: 425 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendRemainingBalance', + loc: { start: 638, end: 658 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 660, end: 663 } + }, + loc: { start: 660, end: 663 } + }, + initializer: { + kind: 'number', + base: '10', + value: 128n, + loc: { start: 666, end: 669 } + } + }, + loc: { start: 632, end: 670 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendOnlyEstimateFee', + loc: { start: 993, end: 1012 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1014, end: 1017 } + }, + loc: { start: 1014, end: 1017 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1024n, + loc: { start: 1020, end: 1024 } + } + }, + loc: { start: 987, end: 1025 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendPayGasSeparately', + loc: { start: 1207, end: 1227 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1229, end: 1232 } + }, + loc: { start: 1229, end: 1232 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1235, end: 1236 } + } + }, + loc: { start: 1201, end: 1237 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendPayFwdFeesSeparately', + loc: { start: 1378, end: 1402 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1404, end: 1407 } + }, + loc: { start: 1404, end: 1407 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1410, end: 1411 } + } + }, + loc: { start: 1372, end: 1412 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendIgnoreErrors', + loc: { start: 1582, end: 1598 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1600, end: 1603 } + }, + loc: { start: 1600, end: 1603 } + }, + initializer: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 1606, end: 1607 } + } + }, + loc: { start: 1576, end: 1608 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendBounceIfActionFail', + loc: { start: 1817, end: 1839 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1841, end: 1844 } + }, + loc: { start: 1841, end: 1844 } + }, + initializer: { + kind: 'number', + base: '10', + value: 16n, + loc: { start: 1847, end: 1849 } + } + }, + loc: { start: 1811, end: 1850 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendDestroyIfZero', + loc: { start: 2085, end: 2102 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2104, end: 2107 } + }, + loc: { start: 2104, end: 2107 } + }, + initializer: { + kind: 'number', + base: '10', + value: 32n, + loc: { start: 2110, end: 2112 } + } + }, + loc: { start: 2079, end: 2113 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'SendParameters', + loc: { start: 2260, end: 2274 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 2416, end: 2420 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2422, end: 2425 } + }, + loc: { start: 2422, end: 2425 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 2428, end: 2443 } + }, + loc: { start: 2416, end: 2443 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 2493, end: 2497 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2503, end: 2504 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2499, end: 2503 } + }, + loc: { start: 2499, end: 2503 } + } + ], + loc: { start: 2503, end: 2504 } + }, + initializer: { kind: 'null', loc: { start: 2507, end: 2511 } }, + loc: { start: 2493, end: 2511 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'code', + loc: { start: 2584, end: 2588 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2594, end: 2595 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2590, end: 2594 } + }, + loc: { start: 2590, end: 2594 } + } + ], + loc: { start: 2594, end: 2595 } + }, + initializer: { kind: 'null', loc: { start: 2598, end: 2602 } }, + loc: { start: 2584, end: 2602 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'data', + loc: { start: 2722, end: 2726 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2732, end: 2733 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2728, end: 2732 } + }, + loc: { start: 2728, end: 2732 } + } + ], + loc: { start: 2732, end: 2733 } + }, + initializer: { kind: 'null', loc: { start: 2736, end: 2740 } }, + loc: { start: 2722, end: 2740 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 2936, end: 2941 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2943, end: 2946 } + }, + loc: { start: 2943, end: 2946 } + }, + initializer: undefined, + loc: { start: 2936, end: 2946 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'to', + loc: { start: 3009, end: 3011 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3013, end: 3020 } + }, + typeArgs: [], + loc: { start: 3013, end: 3020 } + }, + initializer: undefined, + loc: { start: 3009, end: 3020 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 3186, end: 3192 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 3194, end: 3198 } + }, + typeArgs: [], + loc: { start: 3194, end: 3198 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 3201, end: 3205 } + }, + loc: { start: 3186, end: 3205 } + } + ], + loc: { start: 2253, end: 3208 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'MessageParameters', + loc: { start: 3389, end: 3406 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 3548, end: 3552 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3554, end: 3557 } + }, + loc: { start: 3554, end: 3557 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 3560, end: 3575 } + }, + loc: { start: 3548, end: 3575 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 3625, end: 3629 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 3635, end: 3636 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 3631, end: 3635 } + }, + loc: { start: 3631, end: 3635 } + } + ], + loc: { start: 3635, end: 3636 } + }, + initializer: { kind: 'null', loc: { start: 3639, end: 3643 } }, + loc: { start: 3625, end: 3643 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 3839, end: 3844 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3846, end: 3849 } + }, + loc: { start: 3846, end: 3849 } + }, + initializer: undefined, + loc: { start: 3839, end: 3849 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'to', + loc: { start: 3912, end: 3914 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3916, end: 3923 } + }, + typeArgs: [], + loc: { start: 3916, end: 3923 } + }, + initializer: undefined, + loc: { start: 3912, end: 3923 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 4089, end: 4095 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 4097, end: 4101 } + }, + typeArgs: [], + loc: { start: 4097, end: 4101 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 4104, end: 4108 } + }, + loc: { start: 4089, end: 4108 } + } + ], + loc: { start: 3382, end: 4111 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'message', + loc: { start: 5056, end: 5063 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 5064, end: 5070 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'MessageParameters', + loc: { start: 5072, end: 5089 } + }, + typeArgs: [], + loc: { start: 5072, end: 5089 } + }, + loc: { start: 5064, end: 5089 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 106 PUSHINT // 1 + 4 + 4 + 64 + 32 + 1\n' + + ' STZEROES\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + ' STDICT\n' + + ' ENDC\n' + + ' SWAP\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 5048, end: 5588 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'send', loc: { start: 6219, end: 6223 } }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 6224, end: 6230 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'SendParameters', + loc: { start: 6232, end: 6246 } + }, + typeArgs: [], + loc: { start: 6232, end: 6246 } + }, + loc: { start: 6224, end: 6246 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + '\n' + + ' // Group 2: Placing the Builder after code and data, then checking those for nullability\n' + + ' s2 XCHG0\n' + + ' DUP2\n' + + ' ISNULL\n' + + ' SWAP\n' + + ' ISNULL\n' + + ' AND\n' + + ' // → Stack state\n' + + ' // s0: -1 (true) if `data` and `code` are both null, 0 (false) otherwise\n' + + ' // s1: `code`\n' + + ' // s2: `data`\n' + + ' // s3: Builder\n' + + ' // s4: `body`\n' + + ' // s5: `mode`\n' + + '\n' + + ' // Group 3: Left branch of the IFELSE, executed if s0 is -1 (true)\n' + + ' <{\n' + + ' DROP2 // drop `data` and `code`, since either of those is null\n' + + ' b{0} STSLICECONST\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: Right branch of the IFELSE, executed if s0 is 0 (false)\n' + + ' <{\n' + + ' // _ split_depth:(Maybe (## 5))\n' + + ' // special:(Maybe TickTock)\n' + + ' // code:(Maybe ^Cell)\n' + + ' // data:(Maybe ^Cell)\n' + + ' // library:(Maybe ^Cell)\n' + + ' // = StateInit;\n' + + ' ROT // place message Builder on top\n' + + ' b{10} STSLICECONST // store Maybe = true, Either = false\n' + + ' // Start composing inlined StateInit\n' + + ' b{00} STSLICECONST // store split_depth and special first\n' + + ' STDICT // store code\n' + + ' STDICT // store data\n' + + ' b{0} STSLICECONST // store library\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: IFELSE that does the branching shown above\n' + + ' IFELSE\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: null or StateInit\n' + + ' // s2: `body`\n' + + ' // s3: `mode`\n' + + '\n' + + ' // Group 4: Finalizing the message\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: `mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG // https://github.com/tact-lang/tact/issues/1558' + ] + }, + loc: { start: 6211, end: 9157 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'DeployParameters', + loc: { start: 9347, end: 9363 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 9505, end: 9509 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9511, end: 9514 } + }, + loc: { start: 9511, end: 9514 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 9517, end: 9532 } + }, + loc: { start: 9505, end: 9532 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 9582, end: 9586 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 9592, end: 9593 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 9588, end: 9592 } + }, + loc: { start: 9588, end: 9592 } + } + ], + loc: { start: 9592, end: 9593 } + }, + initializer: { kind: 'null', loc: { start: 9596, end: 9600 } }, + loc: { start: 9582, end: 9600 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 9796, end: 9801 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9803, end: 9806 } + }, + loc: { start: 9803, end: 9806 } + }, + initializer: undefined, + loc: { start: 9796, end: 9806 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 9972, end: 9978 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 9980, end: 9984 } + }, + typeArgs: [], + loc: { start: 9980, end: 9984 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 9987, end: 9991 } + }, + loc: { start: 9972, end: 9991 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'init', + loc: { start: 10135, end: 10139 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 10141, end: 10150 } + }, + typeArgs: [], + loc: { start: 10141, end: 10150 } + }, + initializer: undefined, + loc: { start: 10135, end: 10150 } + } + ], + loc: { start: 9340, end: 10153 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'deploy', + loc: { start: 11796, end: 11802 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 11803, end: 11809 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'DeployParameters', + loc: { start: 11811, end: 11827 } + }, + typeArgs: [], + loc: { start: 11811, end: 11827 } + }, + loc: { start: 11803, end: 11827 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '4 1 BLKPUSH // pushes 2 copies of `init.code` and `init.data`\n' + + ' HASHCU // `init.data` hash\n' + + ' SWAP\n' + + ' HASHCU // `init.code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `init.data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `init.code` depth\n' + + '\n' + + ' // Group 2: Calculating destination address\n' + + ' // For almost identical logic and instructions,\n' + + ' // see comments inside `contractHash()` function in contract.tact\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + ' NEWC\n' + + ' 24 STU\n' + + ' 16 STU\n' + + ' 16 STU\n' + + ' 256 STU\n' + + ' 256 STU\n' + + ' ONE HASHEXT_SHA256 // obtains hash part (account id) of the address\n' + + ' // → Stack state\n' + + ' // s0: destAddr(hash part)\n' + + ' // s1: `init.data`\n' + + ' // s2: `init.code`\n' + + ' // s3 and below: `bounce`, `value`, `body`, `mode`\n' + + '\n' + + ' // Group 3: Building a message (CommonMsgInfoRelaxed)\n' + + ' s3 XCHG0 // swaps `bounce` with destAddr(hash part)\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' s1 s2 XCHG // swap `init.data` with `init.code`, placing code on s1\n' + + ' STREF // store `init.code`\n' + + ' STREF // store `init.data`\n' + + ' // Inline StateInit:\n' + + ' b{00010000000000} STSLICECONST\n' + + ' // 0 + 00 + 10 + 0 + 00000000\n' + + ' // 1) 0 - bounced = false\n' + + ' // 2) 00 - src = addr_none\n' + + ' // 3) 10 - tag of addr_std (part of dest)\n' + + ' // 4) 0 - Maybe Anycast = false\n' + + ' // 5) 00000000 - workchain_id (part of dest)\n' + + ' //\n' + + ' 256 STU // store destAddr(hash part)\n' + + ' SWAP // Builder on top, `value` below\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + '\n' + + ' // Group 4: Continue building a message (CommonMsgInfoRelaxed into MessageRelaxed)\n' + + ' // Remaining bits of MessageRelaxed:\n' + + ' b{1000110} STSLICECONST\n' + + ' // 10 + 0 + 0 + 1 + 1 + 0\n' + + ' // 10 - Maybe (Either StateInit ^StateInit) = true false\n' + + ' // 0 - split_depth:(Maybe (## 5)) = false\n' + + ' // 0 = special:(Maybe TickTock) = false\n' + + ' // 1 = code:(Maybe ^Cell) = true\n' + + ' // 1 = data:(Maybe ^Cell) = true\n' + + ' // 0 = library:(Maybe ^Cell) = false\n' + + ' //\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC // finalize the message\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: params.`mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 11788, end: 14770 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'cashback', + loc: { start: 15971, end: 15979 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'to', + loc: { start: 15980, end: 15982 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 15984, end: 15991 } + }, + typeArgs: [], + loc: { start: 15984, end: 15991 } + }, + loc: { start: 15980, end: 15991 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '16 PUSHINT // 0x10, i.e. 0x18 but with bounce = false\n' + + ' NEWC\n' + + ' 6 STU // .storeUint(0x10, 6)\n' + + ' STSLICE // .storeAddress(to)\n' + + ' 0 PUSHINT // 0\n' + + ' 111 STUR // .storeUint(0, 111)\n' + + ' // 4 zeros for coins and 107 zeros for lt, fees, etc.\n' + + ' ENDC\n' + + ' 66 PUSHINT // SendRemainingValue | SendIgnoreErrors\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 15963, end: 16385 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeSendMessage', + loc: { start: 16936, end: 16953 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 16954, end: 16957 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 16959, end: 16963 } + }, + loc: { start: 16959, end: 16963 } + }, + loc: { start: 16954, end: 16963 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 16965, end: 16969 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 16971, end: 16974 } + }, + loc: { start: 16971, end: 16974 } + }, + loc: { start: 16965, end: 16974 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDRAWMSG' ] + }, + loc: { start: 16928, end: 16990 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sendRawMessage', + loc: { start: 17751, end: 17765 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 17766, end: 17769 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 17771, end: 17775 } + }, + loc: { start: 17771, end: 17775 } + }, + loc: { start: 17766, end: 17775 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 17777, end: 17781 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 17783, end: 17786 } + }, + loc: { start: 17783, end: 17786 } + }, + loc: { start: 17777, end: 17786 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDRAWMSG' ] + }, + loc: { start: 17743, end: 17802 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeSendMessageReturnForwardFee', + loc: { start: 19063, end: 19096 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 19120, end: 19123 } + }, + loc: { start: 19120, end: 19123 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 19097, end: 19100 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 19102, end: 19106 } + }, + loc: { start: 19102, end: 19106 } + }, + loc: { start: 19097, end: 19106 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 19108, end: 19112 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 19114, end: 19117 } + }, + loc: { start: 19114, end: 19117 } + }, + loc: { start: 19108, end: 19117 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDMSG' ] + }, + loc: { start: 19055, end: 19135 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sendMessageReturnForwardFee', + loc: { start: 20186, end: 20213 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 20237, end: 20240 } + }, + loc: { start: 20237, end: 20240 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 20214, end: 20217 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 20219, end: 20223 } + }, + loc: { start: 20219, end: 20223 } + }, + loc: { start: 20214, end: 20223 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 20225, end: 20229 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 20231, end: 20234 } + }, + loc: { start: 20231, end: 20234 } + }, + loc: { start: 20225, end: 20234 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDMSG' ] + }, + loc: { start: 20178, end: 20252 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'emit', + loc: { start: 21033, end: 21037 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'body', + loc: { start: 21038, end: 21042 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 21044, end: 21048 } + }, + loc: { start: 21044, end: 21048 } + }, + loc: { start: 21038, end: 21048 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'c', + loc: { start: 21233, end: 21234 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 21236, end: 21240 } + }, + loc: { start: 21236, end: 21240 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'static_call', + function: { + kind: 'id', + text: 'beginCell', + loc: { start: 21243, end: 21252 } + }, + typeArgs: [], + args: [], + loc: { start: 21243, end: 21254 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 21264, end: 21273 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 15211807202738752817960438464513n, + loc: { start: 21274, end: 21306 } + }, + { + kind: 'number', + base: '10', + value: 104n, + loc: { start: 21308, end: 21311 } + } + ], + loc: { start: 21243, end: 21312 } + }, + method: { + kind: 'id', + text: 'storeRef', + loc: { start: 21322, end: 21330 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'body', + loc: { start: 21331, end: 21335 } + } + ], + loc: { start: 21243, end: 21336 } + }, + method: { + kind: 'id', + text: 'endCell', + loc: { start: 21346, end: 21353 } + }, + typeArgs: [], + args: [], + loc: { start: 21243, end: 21355 } + }, + loc: { start: 21229, end: 21356 } + }, + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'sendRawMessage', + loc: { start: 21361, end: 21375 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'c', + loc: { start: 21376, end: 21377 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 21379, end: 21380 } + } + ], + loc: { start: 21361, end: 21381 } + }, + loc: { start: 21361, end: 21382 } + } + ] + }, + loc: { start: 21022, end: 21384 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'acceptMessage', + loc: { start: 22124, end: 22137 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ACCEPT' ] + }, + loc: { start: 22116, end: 22150 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'commit', + loc: { start: 22638, end: 22644 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'COMMIT' ] + }, + loc: { start: 22630, end: 22657 } + } + ] + }, + 'nativeSendMessage' => { + kind: 'tact', + path: 'std/internal/send.tact', + code: '/// Ordinary message (default).\n' + + '///\n' + + '/// This constant is available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendDefaultMode: Int = 0;\n' + + '\n' + + '/// Carry all the remaining value of the inbound message in addition\n' + + '/// to the value initially indicated in the new message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendRemainingValue: Int = 64;\n' + + '\n' + + '/// Carry **all the remaining balance** of the current smart contract instead\n' + + '/// of the value originally indicated in the message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendRemainingBalance: Int = 128;\n' + + '\n' + + "/// Doesn't send the message, only estimates the forward fees\n" + + '/// if the message-sending function computes those.\n' + + '///\n' + + '/// This constant is available since Tact 1.5.0.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '/// * https://docs.tact-lang.org/book/send#message-sending-functions\n' + + '///\n' + + 'const SendOnlyEstimateFee: Int = 1024;\n' + + '\n' + + '/// **Deprecated** since Tact 1.6.5.\n' + + '///\n' + + '/// Pay forward fees separately from the message value.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendPayGasSeparately: Int = 1;\n' + + '\n' + + '/// Pay forward fees separately from the message value.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendPayFwdFeesSeparately: Int = 1;\n' + + '\n' + + '/// Ignore any errors arising while processing this message during the action phase.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendIgnoreErrors: Int = 2;\n' + + '\n' + + '/// Bounce transaction in case of any errors during action phase.\n' + + '/// Has no effect if flag +2, `SendIgnoreErrors` is used.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendBounceIfActionFail: Int = 16;\n' + + '\n' + + '/// Current account (contract) will be destroyed if its resulting balance is zero.\n' + + '/// This flag is often used with mode 128, `SendRemainingBalance`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendDestroyIfZero: Int = 32;\n' + + '\n' + + '/// Struct for specifying the message parameters of the `send()` function.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#send\n' + + '///\n' + + 'struct SendParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// Optional initial code of the contract (compiled bitcode).\n' + + ' code: Cell? = null;\n' + + '\n' + + ' /// Optional initial data of the contract (arguments of `init()` function or values of contract parameters).\n' + + ' data: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// Recipient internal `Address` on TON Blockchain.\n' + + ' to: Address;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '}\n' + + '\n' + + '/// Struct for specifying the message parameters of the `message()` function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#message\n' + + '///\n' + + 'struct MessageParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// Recipient internal `Address` on TON Blockchain.\n' + + ' to: Address;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Queues the message to be sent using the `MessageParameters` struct. Allows for cheaper non-deployment, regular messages compared to the `send()` function.\n' + + '///\n' + + '/// The `MessageParameters` struct is similar to `SendParameters` struct, but without the `code` and `data` fields.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// message(MessageParameters{\n' + + '/// to: sender(), // back to the sender,\n' + + '/// value: ton("1"), // with 1 Toncoin (1_000_000_000 nanoToncoin),\n' + + '/// // and no message body\n' + + '/// });\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 33: [Action list is too long] — Thrown when attempting to queue more than 255 messages.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-send#message\n' + + '/// * https://docs.tact-lang.org/book/message-mode\n' + + '///\n' + + '/// [Action list is too long]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '///\n' + + 'asm fun message(params: MessageParameters) {\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 106 PUSHINT // 1 + 4 + 4 + 64 + 32 + 1\n' + + ' STZEROES\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + ' STDICT\n' + + ' ENDC\n' + + ' SWAP\n' + + ' SENDRAWMSG\n' + + '}\n' + + '\n' + + '/// Global function. Queues the message to be sent using a `SendParameters` Struct.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// send(SendParameters{\n' + + '/// to: sender(), // back to the sender,\n' + + '/// value: ton("1"), // with 1 Toncoin (1_000_000_000 nanoToncoin),\n' + + '/// // and no message body\n' + + '/// });\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 33: [Action list is too long] — Thrown when attempting to queue more than 255 messages.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#send\n' + + '///\n' + + '/// [Action list is too long]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '///\n' + + 'asm fun send(params: SendParameters) {\n' + + ' // Instructions are grouped, and the stack states they produce as a group are shown right after.\n' + + ' // In the end, our message Cell should have the following TL-B structure:\n' + + ' // message$_ {X:Type}\n' + + ' // info:CommonMsgInfoRelaxed\n' + + ' // init:(Maybe (Either StateInit ^StateInit))\n' + + ' // body:(Either X ^X)\n' + + ' // = MessageRelaxed X;\n' + + '\n' + + ' // → Stack state\n' + + ' // s0: `params.bounce`\n' + + ' // s1: `params.to`\n' + + ' // s2: `params.value`\n' + + ' // s3: `params.data`\n' + + ' // s4: `params.code`\n' + + ' // s5: `params.body`\n' + + ' // s6: `params.mode`\n' + + ' // For brevity, the "params" prefix will be omitted from now on.\n' + + '\n' + + ' // Group 1: Storing the `bounce`, `to` and `value` into a Builder\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + '\n' + + ' // Group 2: Placing the Builder after code and data, then checking those for nullability\n' + + ' s2 XCHG0\n' + + ' DUP2\n' + + ' ISNULL\n' + + ' SWAP\n' + + ' ISNULL\n' + + ' AND\n' + + ' // → Stack state\n' + + ' // s0: -1 (true) if `data` and `code` are both null, 0 (false) otherwise\n' + + ' // s1: `code`\n' + + ' // s2: `data`\n' + + ' // s3: Builder\n' + + ' // s4: `body`\n' + + ' // s5: `mode`\n' + + '\n' + + ' // Group 3: Left branch of the IFELSE, executed if s0 is -1 (true)\n' + + ' <{\n' + + ' DROP2 // drop `data` and `code`, since either of those is null\n' + + ' b{0} STSLICECONST\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: Right branch of the IFELSE, executed if s0 is 0 (false)\n' + + ' <{\n' + + ' // _ split_depth:(Maybe (## 5))\n' + + ' // special:(Maybe TickTock)\n' + + ' // code:(Maybe ^Cell)\n' + + ' // data:(Maybe ^Cell)\n' + + ' // library:(Maybe ^Cell)\n' + + ' // = StateInit;\n' + + ' ROT // place message Builder on top\n' + + ' b{10} STSLICECONST // store Maybe = true, Either = false\n' + + ' // Start composing inlined StateInit\n' + + ' b{00} STSLICECONST // store split_depth and special first\n' + + ' STDICT // store code\n' + + ' STDICT // store data\n' + + ' b{0} STSLICECONST // store library\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: IFELSE that does the branching shown above\n' + + ' IFELSE\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: null or StateInit\n' + + ' // s2: `body`\n' + + ' // s3: `mode`\n' + + '\n' + + ' // Group 4: Finalizing the message\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: `mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG // https://github.com/tact-lang/tact/issues/1558\n' + + '}\n' + + '\n' + + '/// Struct for specifying the deployment message parameters of the `deploy()` function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#deploy\n' + + '///\n' + + 'struct DeployParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '\n' + + ' //'... 12658 more characters, + imports: [], + items: [ + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendDefaultMode', + loc: { start: 164, end: 179 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 181, end: 184 } + }, + loc: { start: 181, end: 184 } + }, + initializer: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 187, end: 188 } + } + }, + loc: { start: 158, end: 189 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendRemainingValue', + loc: { start: 396, end: 414 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 416, end: 419 } + }, + loc: { start: 416, end: 419 } + }, + initializer: { + kind: 'number', + base: '10', + value: 64n, + loc: { start: 422, end: 424 } + } + }, + loc: { start: 390, end: 425 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendRemainingBalance', + loc: { start: 638, end: 658 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 660, end: 663 } + }, + loc: { start: 660, end: 663 } + }, + initializer: { + kind: 'number', + base: '10', + value: 128n, + loc: { start: 666, end: 669 } + } + }, + loc: { start: 632, end: 670 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendOnlyEstimateFee', + loc: { start: 993, end: 1012 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1014, end: 1017 } + }, + loc: { start: 1014, end: 1017 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1024n, + loc: { start: 1020, end: 1024 } + } + }, + loc: { start: 987, end: 1025 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendPayGasSeparately', + loc: { start: 1207, end: 1227 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1229, end: 1232 } + }, + loc: { start: 1229, end: 1232 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1235, end: 1236 } + } + }, + loc: { start: 1201, end: 1237 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendPayFwdFeesSeparately', + loc: { start: 1378, end: 1402 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1404, end: 1407 } + }, + loc: { start: 1404, end: 1407 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1410, end: 1411 } + } + }, + loc: { start: 1372, end: 1412 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendIgnoreErrors', + loc: { start: 1582, end: 1598 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1600, end: 1603 } + }, + loc: { start: 1600, end: 1603 } + }, + initializer: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 1606, end: 1607 } + } + }, + loc: { start: 1576, end: 1608 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendBounceIfActionFail', + loc: { start: 1817, end: 1839 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1841, end: 1844 } + }, + loc: { start: 1841, end: 1844 } + }, + initializer: { + kind: 'number', + base: '10', + value: 16n, + loc: { start: 1847, end: 1849 } + } + }, + loc: { start: 1811, end: 1850 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendDestroyIfZero', + loc: { start: 2085, end: 2102 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2104, end: 2107 } + }, + loc: { start: 2104, end: 2107 } + }, + initializer: { + kind: 'number', + base: '10', + value: 32n, + loc: { start: 2110, end: 2112 } + } + }, + loc: { start: 2079, end: 2113 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'SendParameters', + loc: { start: 2260, end: 2274 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 2416, end: 2420 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2422, end: 2425 } + }, + loc: { start: 2422, end: 2425 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 2428, end: 2443 } + }, + loc: { start: 2416, end: 2443 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 2493, end: 2497 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2503, end: 2504 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2499, end: 2503 } + }, + loc: { start: 2499, end: 2503 } + } + ], + loc: { start: 2503, end: 2504 } + }, + initializer: { kind: 'null', loc: { start: 2507, end: 2511 } }, + loc: { start: 2493, end: 2511 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'code', + loc: { start: 2584, end: 2588 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2594, end: 2595 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2590, end: 2594 } + }, + loc: { start: 2590, end: 2594 } + } + ], + loc: { start: 2594, end: 2595 } + }, + initializer: { kind: 'null', loc: { start: 2598, end: 2602 } }, + loc: { start: 2584, end: 2602 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'data', + loc: { start: 2722, end: 2726 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2732, end: 2733 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2728, end: 2732 } + }, + loc: { start: 2728, end: 2732 } + } + ], + loc: { start: 2732, end: 2733 } + }, + initializer: { kind: 'null', loc: { start: 2736, end: 2740 } }, + loc: { start: 2722, end: 2740 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 2936, end: 2941 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2943, end: 2946 } + }, + loc: { start: 2943, end: 2946 } + }, + initializer: undefined, + loc: { start: 2936, end: 2946 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'to', + loc: { start: 3009, end: 3011 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3013, end: 3020 } + }, + typeArgs: [], + loc: { start: 3013, end: 3020 } + }, + initializer: undefined, + loc: { start: 3009, end: 3020 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 3186, end: 3192 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 3194, end: 3198 } + }, + typeArgs: [], + loc: { start: 3194, end: 3198 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 3201, end: 3205 } + }, + loc: { start: 3186, end: 3205 } + } + ], + loc: { start: 2253, end: 3208 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'MessageParameters', + loc: { start: 3389, end: 3406 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 3548, end: 3552 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3554, end: 3557 } + }, + loc: { start: 3554, end: 3557 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 3560, end: 3575 } + }, + loc: { start: 3548, end: 3575 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 3625, end: 3629 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 3635, end: 3636 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 3631, end: 3635 } + }, + loc: { start: 3631, end: 3635 } + } + ], + loc: { start: 3635, end: 3636 } + }, + initializer: { kind: 'null', loc: { start: 3639, end: 3643 } }, + loc: { start: 3625, end: 3643 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 3839, end: 3844 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3846, end: 3849 } + }, + loc: { start: 3846, end: 3849 } + }, + initializer: undefined, + loc: { start: 3839, end: 3849 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'to', + loc: { start: 3912, end: 3914 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3916, end: 3923 } + }, + typeArgs: [], + loc: { start: 3916, end: 3923 } + }, + initializer: undefined, + loc: { start: 3912, end: 3923 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 4089, end: 4095 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 4097, end: 4101 } + }, + typeArgs: [], + loc: { start: 4097, end: 4101 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 4104, end: 4108 } + }, + loc: { start: 4089, end: 4108 } + } + ], + loc: { start: 3382, end: 4111 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'message', + loc: { start: 5056, end: 5063 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 5064, end: 5070 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'MessageParameters', + loc: { start: 5072, end: 5089 } + }, + typeArgs: [], + loc: { start: 5072, end: 5089 } + }, + loc: { start: 5064, end: 5089 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 106 PUSHINT // 1 + 4 + 4 + 64 + 32 + 1\n' + + ' STZEROES\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + ' STDICT\n' + + ' ENDC\n' + + ' SWAP\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 5048, end: 5588 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'send', loc: { start: 6219, end: 6223 } }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 6224, end: 6230 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'SendParameters', + loc: { start: 6232, end: 6246 } + }, + typeArgs: [], + loc: { start: 6232, end: 6246 } + }, + loc: { start: 6224, end: 6246 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + '\n' + + ' // Group 2: Placing the Builder after code and data, then checking those for nullability\n' + + ' s2 XCHG0\n' + + ' DUP2\n' + + ' ISNULL\n' + + ' SWAP\n' + + ' ISNULL\n' + + ' AND\n' + + ' // → Stack state\n' + + ' // s0: -1 (true) if `data` and `code` are both null, 0 (false) otherwise\n' + + ' // s1: `code`\n' + + ' // s2: `data`\n' + + ' // s3: Builder\n' + + ' // s4: `body`\n' + + ' // s5: `mode`\n' + + '\n' + + ' // Group 3: Left branch of the IFELSE, executed if s0 is -1 (true)\n' + + ' <{\n' + + ' DROP2 // drop `data` and `code`, since either of those is null\n' + + ' b{0} STSLICECONST\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: Right branch of the IFELSE, executed if s0 is 0 (false)\n' + + ' <{\n' + + ' // _ split_depth:(Maybe (## 5))\n' + + ' // special:(Maybe TickTock)\n' + + ' // code:(Maybe ^Cell)\n' + + ' // data:(Maybe ^Cell)\n' + + ' // library:(Maybe ^Cell)\n' + + ' // = StateInit;\n' + + ' ROT // place message Builder on top\n' + + ' b{10} STSLICECONST // store Maybe = true, Either = false\n' + + ' // Start composing inlined StateInit\n' + + ' b{00} STSLICECONST // store split_depth and special first\n' + + ' STDICT // store code\n' + + ' STDICT // store data\n' + + ' b{0} STSLICECONST // store library\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: IFELSE that does the branching shown above\n' + + ' IFELSE\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: null or StateInit\n' + + ' // s2: `body`\n' + + ' // s3: `mode`\n' + + '\n' + + ' // Group 4: Finalizing the message\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: `mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG // https://github.com/tact-lang/tact/issues/1558' + ] + }, + loc: { start: 6211, end: 9157 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'DeployParameters', + loc: { start: 9347, end: 9363 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 9505, end: 9509 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9511, end: 9514 } + }, + loc: { start: 9511, end: 9514 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 9517, end: 9532 } + }, + loc: { start: 9505, end: 9532 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 9582, end: 9586 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 9592, end: 9593 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 9588, end: 9592 } + }, + loc: { start: 9588, end: 9592 } + } + ], + loc: { start: 9592, end: 9593 } + }, + initializer: { kind: 'null', loc: { start: 9596, end: 9600 } }, + loc: { start: 9582, end: 9600 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 9796, end: 9801 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9803, end: 9806 } + }, + loc: { start: 9803, end: 9806 } + }, + initializer: undefined, + loc: { start: 9796, end: 9806 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 9972, end: 9978 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 9980, end: 9984 } + }, + typeArgs: [], + loc: { start: 9980, end: 9984 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 9987, end: 9991 } + }, + loc: { start: 9972, end: 9991 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'init', + loc: { start: 10135, end: 10139 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 10141, end: 10150 } + }, + typeArgs: [], + loc: { start: 10141, end: 10150 } + }, + initializer: undefined, + loc: { start: 10135, end: 10150 } + } + ], + loc: { start: 9340, end: 10153 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'deploy', + loc: { start: 11796, end: 11802 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 11803, end: 11809 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'DeployParameters', + loc: { start: 11811, end: 11827 } + }, + typeArgs: [], + loc: { start: 11811, end: 11827 } + }, + loc: { start: 11803, end: 11827 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '4 1 BLKPUSH // pushes 2 copies of `init.code` and `init.data`\n' + + ' HASHCU // `init.data` hash\n' + + ' SWAP\n' + + ' HASHCU // `init.code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `init.data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `init.code` depth\n' + + '\n' + + ' // Group 2: Calculating destination address\n' + + ' // For almost identical logic and instructions,\n' + + ' // see comments inside `contractHash()` function in contract.tact\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + ' NEWC\n' + + ' 24 STU\n' + + ' 16 STU\n' + + ' 16 STU\n' + + ' 256 STU\n' + + ' 256 STU\n' + + ' ONE HASHEXT_SHA256 // obtains hash part (account id) of the address\n' + + ' // → Stack state\n' + + ' // s0: destAddr(hash part)\n' + + ' // s1: `init.data`\n' + + ' // s2: `init.code`\n' + + ' // s3 and below: `bounce`, `value`, `body`, `mode`\n' + + '\n' + + ' // Group 3: Building a message (CommonMsgInfoRelaxed)\n' + + ' s3 XCHG0 // swaps `bounce` with destAddr(hash part)\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' s1 s2 XCHG // swap `init.data` with `init.code`, placing code on s1\n' + + ' STREF // store `init.code`\n' + + ' STREF // store `init.data`\n' + + ' // Inline StateInit:\n' + + ' b{00010000000000} STSLICECONST\n' + + ' // 0 + 00 + 10 + 0 + 00000000\n' + + ' // 1) 0 - bounced = false\n' + + ' // 2) 00 - src = addr_none\n' + + ' // 3) 10 - tag of addr_std (part of dest)\n' + + ' // 4) 0 - Maybe Anycast = false\n' + + ' // 5) 00000000 - workchain_id (part of dest)\n' + + ' //\n' + + ' 256 STU // store destAddr(hash part)\n' + + ' SWAP // Builder on top, `value` below\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + '\n' + + ' // Group 4: Continue building a message (CommonMsgInfoRelaxed into MessageRelaxed)\n' + + ' // Remaining bits of MessageRelaxed:\n' + + ' b{1000110} STSLICECONST\n' + + ' // 10 + 0 + 0 + 1 + 1 + 0\n' + + ' // 10 - Maybe (Either StateInit ^StateInit) = true false\n' + + ' // 0 - split_depth:(Maybe (## 5)) = false\n' + + ' // 0 = special:(Maybe TickTock) = false\n' + + ' // 1 = code:(Maybe ^Cell) = true\n' + + ' // 1 = data:(Maybe ^Cell) = true\n' + + ' // 0 = library:(Maybe ^Cell) = false\n' + + ' //\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC // finalize the message\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: params.`mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 11788, end: 14770 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'cashback', + loc: { start: 15971, end: 15979 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'to', + loc: { start: 15980, end: 15982 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 15984, end: 15991 } + }, + typeArgs: [], + loc: { start: 15984, end: 15991 } + }, + loc: { start: 15980, end: 15991 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '16 PUSHINT // 0x10, i.e. 0x18 but with bounce = false\n' + + ' NEWC\n' + + ' 6 STU // .storeUint(0x10, 6)\n' + + ' STSLICE // .storeAddress(to)\n' + + ' 0 PUSHINT // 0\n' + + ' 111 STUR // .storeUint(0, 111)\n' + + ' // 4 zeros for coins and 107 zeros for lt, fees, etc.\n' + + ' ENDC\n' + + ' 66 PUSHINT // SendRemainingValue | SendIgnoreErrors\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 15963, end: 16385 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeSendMessage', + loc: { start: 16936, end: 16953 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 16954, end: 16957 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 16959, end: 16963 } + }, + loc: { start: 16959, end: 16963 } + }, + loc: { start: 16954, end: 16963 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 16965, end: 16969 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 16971, end: 16974 } + }, + loc: { start: 16971, end: 16974 } + }, + loc: { start: 16965, end: 16974 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDRAWMSG' ] + }, + loc: { start: 16928, end: 16990 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sendRawMessage', + loc: { start: 17751, end: 17765 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 17766, end: 17769 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 17771, end: 17775 } + }, + loc: { start: 17771, end: 17775 } + }, + loc: { start: 17766, end: 17775 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 17777, end: 17781 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 17783, end: 17786 } + }, + loc: { start: 17783, end: 17786 } + }, + loc: { start: 17777, end: 17786 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDRAWMSG' ] + }, + loc: { start: 17743, end: 17802 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeSendMessageReturnForwardFee', + loc: { start: 19063, end: 19096 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 19120, end: 19123 } + }, + loc: { start: 19120, end: 19123 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 19097, end: 19100 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 19102, end: 19106 } + }, + loc: { start: 19102, end: 19106 } + }, + loc: { start: 19097, end: 19106 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 19108, end: 19112 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 19114, end: 19117 } + }, + loc: { start: 19114, end: 19117 } + }, + loc: { start: 19108, end: 19117 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDMSG' ] + }, + loc: { start: 19055, end: 19135 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sendMessageReturnForwardFee', + loc: { start: 20186, end: 20213 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 20237, end: 20240 } + }, + loc: { start: 20237, end: 20240 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 20214, end: 20217 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 20219, end: 20223 } + }, + loc: { start: 20219, end: 20223 } + }, + loc: { start: 20214, end: 20223 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 20225, end: 20229 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 20231, end: 20234 } + }, + loc: { start: 20231, end: 20234 } + }, + loc: { start: 20225, end: 20234 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDMSG' ] + }, + loc: { start: 20178, end: 20252 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'emit', + loc: { start: 21033, end: 21037 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'body', + loc: { start: 21038, end: 21042 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 21044, end: 21048 } + }, + loc: { start: 21044, end: 21048 } + }, + loc: { start: 21038, end: 21048 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'c', + loc: { start: 21233, end: 21234 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 21236, end: 21240 } + }, + loc: { start: 21236, end: 21240 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'static_call', + function: { + kind: 'id', + text: 'beginCell', + loc: { start: 21243, end: 21252 } + }, + typeArgs: [], + args: [], + loc: { start: 21243, end: 21254 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 21264, end: 21273 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 15211807202738752817960438464513n, + loc: { start: 21274, end: 21306 } + }, + { + kind: 'number', + base: '10', + value: 104n, + loc: { start: 21308, end: 21311 } + } + ], + loc: { start: 21243, end: 21312 } + }, + method: { + kind: 'id', + text: 'storeRef', + loc: { start: 21322, end: 21330 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'body', + loc: { start: 21331, end: 21335 } + } + ], + loc: { start: 21243, end: 21336 } + }, + method: { + kind: 'id', + text: 'endCell', + loc: { start: 21346, end: 21353 } + }, + typeArgs: [], + args: [], + loc: { start: 21243, end: 21355 } + }, + loc: { start: 21229, end: 21356 } + }, + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'sendRawMessage', + loc: { start: 21361, end: 21375 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'c', + loc: { start: 21376, end: 21377 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 21379, end: 21380 } + } + ], + loc: { start: 21361, end: 21381 } + }, + loc: { start: 21361, end: 21382 } + } + ] + }, + loc: { start: 21022, end: 21384 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'acceptMessage', + loc: { start: 22124, end: 22137 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ACCEPT' ] + }, + loc: { start: 22116, end: 22150 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'commit', + loc: { start: 22638, end: 22644 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'COMMIT' ] + }, + loc: { start: 22630, end: 22657 } + } + ] + }, + 'sendRawMessage' => { + kind: 'tact', + path: 'std/internal/send.tact', + code: '/// Ordinary message (default).\n' + + '///\n' + + '/// This constant is available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendDefaultMode: Int = 0;\n' + + '\n' + + '/// Carry all the remaining value of the inbound message in addition\n' + + '/// to the value initially indicated in the new message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendRemainingValue: Int = 64;\n' + + '\n' + + '/// Carry **all the remaining balance** of the current smart contract instead\n' + + '/// of the value originally indicated in the message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendRemainingBalance: Int = 128;\n' + + '\n' + + "/// Doesn't send the message, only estimates the forward fees\n" + + '/// if the message-sending function computes those.\n' + + '///\n' + + '/// This constant is available since Tact 1.5.0.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '/// * https://docs.tact-lang.org/book/send#message-sending-functions\n' + + '///\n' + + 'const SendOnlyEstimateFee: Int = 1024;\n' + + '\n' + + '/// **Deprecated** since Tact 1.6.5.\n' + + '///\n' + + '/// Pay forward fees separately from the message value.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendPayGasSeparately: Int = 1;\n' + + '\n' + + '/// Pay forward fees separately from the message value.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendPayFwdFeesSeparately: Int = 1;\n' + + '\n' + + '/// Ignore any errors arising while processing this message during the action phase.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendIgnoreErrors: Int = 2;\n' + + '\n' + + '/// Bounce transaction in case of any errors during action phase.\n' + + '/// Has no effect if flag +2, `SendIgnoreErrors` is used.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendBounceIfActionFail: Int = 16;\n' + + '\n' + + '/// Current account (contract) will be destroyed if its resulting balance is zero.\n' + + '/// This flag is often used with mode 128, `SendRemainingBalance`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendDestroyIfZero: Int = 32;\n' + + '\n' + + '/// Struct for specifying the message parameters of the `send()` function.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#send\n' + + '///\n' + + 'struct SendParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// Optional initial code of the contract (compiled bitcode).\n' + + ' code: Cell? = null;\n' + + '\n' + + ' /// Optional initial data of the contract (arguments of `init()` function or values of contract parameters).\n' + + ' data: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// Recipient internal `Address` on TON Blockchain.\n' + + ' to: Address;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '}\n' + + '\n' + + '/// Struct for specifying the message parameters of the `message()` function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#message\n' + + '///\n' + + 'struct MessageParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// Recipient internal `Address` on TON Blockchain.\n' + + ' to: Address;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Queues the message to be sent using the `MessageParameters` struct. Allows for cheaper non-deployment, regular messages compared to the `send()` function.\n' + + '///\n' + + '/// The `MessageParameters` struct is similar to `SendParameters` struct, but without the `code` and `data` fields.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// message(MessageParameters{\n' + + '/// to: sender(), // back to the sender,\n' + + '/// value: ton("1"), // with 1 Toncoin (1_000_000_000 nanoToncoin),\n' + + '/// // and no message body\n' + + '/// });\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 33: [Action list is too long] — Thrown when attempting to queue more than 255 messages.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-send#message\n' + + '/// * https://docs.tact-lang.org/book/message-mode\n' + + '///\n' + + '/// [Action list is too long]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '///\n' + + 'asm fun message(params: MessageParameters) {\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 106 PUSHINT // 1 + 4 + 4 + 64 + 32 + 1\n' + + ' STZEROES\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + ' STDICT\n' + + ' ENDC\n' + + ' SWAP\n' + + ' SENDRAWMSG\n' + + '}\n' + + '\n' + + '/// Global function. Queues the message to be sent using a `SendParameters` Struct.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// send(SendParameters{\n' + + '/// to: sender(), // back to the sender,\n' + + '/// value: ton("1"), // with 1 Toncoin (1_000_000_000 nanoToncoin),\n' + + '/// // and no message body\n' + + '/// });\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 33: [Action list is too long] — Thrown when attempting to queue more than 255 messages.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#send\n' + + '///\n' + + '/// [Action list is too long]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '///\n' + + 'asm fun send(params: SendParameters) {\n' + + ' // Instructions are grouped, and the stack states they produce as a group are shown right after.\n' + + ' // In the end, our message Cell should have the following TL-B structure:\n' + + ' // message$_ {X:Type}\n' + + ' // info:CommonMsgInfoRelaxed\n' + + ' // init:(Maybe (Either StateInit ^StateInit))\n' + + ' // body:(Either X ^X)\n' + + ' // = MessageRelaxed X;\n' + + '\n' + + ' // → Stack state\n' + + ' // s0: `params.bounce`\n' + + ' // s1: `params.to`\n' + + ' // s2: `params.value`\n' + + ' // s3: `params.data`\n' + + ' // s4: `params.code`\n' + + ' // s5: `params.body`\n' + + ' // s6: `params.mode`\n' + + ' // For brevity, the "params" prefix will be omitted from now on.\n' + + '\n' + + ' // Group 1: Storing the `bounce`, `to` and `value` into a Builder\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + '\n' + + ' // Group 2: Placing the Builder after code and data, then checking those for nullability\n' + + ' s2 XCHG0\n' + + ' DUP2\n' + + ' ISNULL\n' + + ' SWAP\n' + + ' ISNULL\n' + + ' AND\n' + + ' // → Stack state\n' + + ' // s0: -1 (true) if `data` and `code` are both null, 0 (false) otherwise\n' + + ' // s1: `code`\n' + + ' // s2: `data`\n' + + ' // s3: Builder\n' + + ' // s4: `body`\n' + + ' // s5: `mode`\n' + + '\n' + + ' // Group 3: Left branch of the IFELSE, executed if s0 is -1 (true)\n' + + ' <{\n' + + ' DROP2 // drop `data` and `code`, since either of those is null\n' + + ' b{0} STSLICECONST\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: Right branch of the IFELSE, executed if s0 is 0 (false)\n' + + ' <{\n' + + ' // _ split_depth:(Maybe (## 5))\n' + + ' // special:(Maybe TickTock)\n' + + ' // code:(Maybe ^Cell)\n' + + ' // data:(Maybe ^Cell)\n' + + ' // library:(Maybe ^Cell)\n' + + ' // = StateInit;\n' + + ' ROT // place message Builder on top\n' + + ' b{10} STSLICECONST // store Maybe = true, Either = false\n' + + ' // Start composing inlined StateInit\n' + + ' b{00} STSLICECONST // store split_depth and special first\n' + + ' STDICT // store code\n' + + ' STDICT // store data\n' + + ' b{0} STSLICECONST // store library\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: IFELSE that does the branching shown above\n' + + ' IFELSE\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: null or StateInit\n' + + ' // s2: `body`\n' + + ' // s3: `mode`\n' + + '\n' + + ' // Group 4: Finalizing the message\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: `mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG // https://github.com/tact-lang/tact/issues/1558\n' + + '}\n' + + '\n' + + '/// Struct for specifying the deployment message parameters of the `deploy()` function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#deploy\n' + + '///\n' + + 'struct DeployParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '\n' + + ' //'... 12658 more characters, + imports: [], + items: [ + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendDefaultMode', + loc: { start: 164, end: 179 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 181, end: 184 } + }, + loc: { start: 181, end: 184 } + }, + initializer: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 187, end: 188 } + } + }, + loc: { start: 158, end: 189 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendRemainingValue', + loc: { start: 396, end: 414 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 416, end: 419 } + }, + loc: { start: 416, end: 419 } + }, + initializer: { + kind: 'number', + base: '10', + value: 64n, + loc: { start: 422, end: 424 } + } + }, + loc: { start: 390, end: 425 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendRemainingBalance', + loc: { start: 638, end: 658 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 660, end: 663 } + }, + loc: { start: 660, end: 663 } + }, + initializer: { + kind: 'number', + base: '10', + value: 128n, + loc: { start: 666, end: 669 } + } + }, + loc: { start: 632, end: 670 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendOnlyEstimateFee', + loc: { start: 993, end: 1012 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1014, end: 1017 } + }, + loc: { start: 1014, end: 1017 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1024n, + loc: { start: 1020, end: 1024 } + } + }, + loc: { start: 987, end: 1025 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendPayGasSeparately', + loc: { start: 1207, end: 1227 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1229, end: 1232 } + }, + loc: { start: 1229, end: 1232 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1235, end: 1236 } + } + }, + loc: { start: 1201, end: 1237 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendPayFwdFeesSeparately', + loc: { start: 1378, end: 1402 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1404, end: 1407 } + }, + loc: { start: 1404, end: 1407 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1410, end: 1411 } + } + }, + loc: { start: 1372, end: 1412 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendIgnoreErrors', + loc: { start: 1582, end: 1598 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1600, end: 1603 } + }, + loc: { start: 1600, end: 1603 } + }, + initializer: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 1606, end: 1607 } + } + }, + loc: { start: 1576, end: 1608 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendBounceIfActionFail', + loc: { start: 1817, end: 1839 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1841, end: 1844 } + }, + loc: { start: 1841, end: 1844 } + }, + initializer: { + kind: 'number', + base: '10', + value: 16n, + loc: { start: 1847, end: 1849 } + } + }, + loc: { start: 1811, end: 1850 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendDestroyIfZero', + loc: { start: 2085, end: 2102 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2104, end: 2107 } + }, + loc: { start: 2104, end: 2107 } + }, + initializer: { + kind: 'number', + base: '10', + value: 32n, + loc: { start: 2110, end: 2112 } + } + }, + loc: { start: 2079, end: 2113 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'SendParameters', + loc: { start: 2260, end: 2274 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 2416, end: 2420 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2422, end: 2425 } + }, + loc: { start: 2422, end: 2425 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 2428, end: 2443 } + }, + loc: { start: 2416, end: 2443 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 2493, end: 2497 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2503, end: 2504 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2499, end: 2503 } + }, + loc: { start: 2499, end: 2503 } + } + ], + loc: { start: 2503, end: 2504 } + }, + initializer: { kind: 'null', loc: { start: 2507, end: 2511 } }, + loc: { start: 2493, end: 2511 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'code', + loc: { start: 2584, end: 2588 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2594, end: 2595 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2590, end: 2594 } + }, + loc: { start: 2590, end: 2594 } + } + ], + loc: { start: 2594, end: 2595 } + }, + initializer: { kind: 'null', loc: { start: 2598, end: 2602 } }, + loc: { start: 2584, end: 2602 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'data', + loc: { start: 2722, end: 2726 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2732, end: 2733 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2728, end: 2732 } + }, + loc: { start: 2728, end: 2732 } + } + ], + loc: { start: 2732, end: 2733 } + }, + initializer: { kind: 'null', loc: { start: 2736, end: 2740 } }, + loc: { start: 2722, end: 2740 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 2936, end: 2941 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2943, end: 2946 } + }, + loc: { start: 2943, end: 2946 } + }, + initializer: undefined, + loc: { start: 2936, end: 2946 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'to', + loc: { start: 3009, end: 3011 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3013, end: 3020 } + }, + typeArgs: [], + loc: { start: 3013, end: 3020 } + }, + initializer: undefined, + loc: { start: 3009, end: 3020 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 3186, end: 3192 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 3194, end: 3198 } + }, + typeArgs: [], + loc: { start: 3194, end: 3198 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 3201, end: 3205 } + }, + loc: { start: 3186, end: 3205 } + } + ], + loc: { start: 2253, end: 3208 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'MessageParameters', + loc: { start: 3389, end: 3406 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 3548, end: 3552 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3554, end: 3557 } + }, + loc: { start: 3554, end: 3557 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 3560, end: 3575 } + }, + loc: { start: 3548, end: 3575 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 3625, end: 3629 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 3635, end: 3636 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 3631, end: 3635 } + }, + loc: { start: 3631, end: 3635 } + } + ], + loc: { start: 3635, end: 3636 } + }, + initializer: { kind: 'null', loc: { start: 3639, end: 3643 } }, + loc: { start: 3625, end: 3643 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 3839, end: 3844 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3846, end: 3849 } + }, + loc: { start: 3846, end: 3849 } + }, + initializer: undefined, + loc: { start: 3839, end: 3849 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'to', + loc: { start: 3912, end: 3914 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3916, end: 3923 } + }, + typeArgs: [], + loc: { start: 3916, end: 3923 } + }, + initializer: undefined, + loc: { start: 3912, end: 3923 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 4089, end: 4095 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 4097, end: 4101 } + }, + typeArgs: [], + loc: { start: 4097, end: 4101 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 4104, end: 4108 } + }, + loc: { start: 4089, end: 4108 } + } + ], + loc: { start: 3382, end: 4111 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'message', + loc: { start: 5056, end: 5063 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 5064, end: 5070 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'MessageParameters', + loc: { start: 5072, end: 5089 } + }, + typeArgs: [], + loc: { start: 5072, end: 5089 } + }, + loc: { start: 5064, end: 5089 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 106 PUSHINT // 1 + 4 + 4 + 64 + 32 + 1\n' + + ' STZEROES\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + ' STDICT\n' + + ' ENDC\n' + + ' SWAP\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 5048, end: 5588 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'send', loc: { start: 6219, end: 6223 } }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 6224, end: 6230 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'SendParameters', + loc: { start: 6232, end: 6246 } + }, + typeArgs: [], + loc: { start: 6232, end: 6246 } + }, + loc: { start: 6224, end: 6246 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + '\n' + + ' // Group 2: Placing the Builder after code and data, then checking those for nullability\n' + + ' s2 XCHG0\n' + + ' DUP2\n' + + ' ISNULL\n' + + ' SWAP\n' + + ' ISNULL\n' + + ' AND\n' + + ' // → Stack state\n' + + ' // s0: -1 (true) if `data` and `code` are both null, 0 (false) otherwise\n' + + ' // s1: `code`\n' + + ' // s2: `data`\n' + + ' // s3: Builder\n' + + ' // s4: `body`\n' + + ' // s5: `mode`\n' + + '\n' + + ' // Group 3: Left branch of the IFELSE, executed if s0 is -1 (true)\n' + + ' <{\n' + + ' DROP2 // drop `data` and `code`, since either of those is null\n' + + ' b{0} STSLICECONST\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: Right branch of the IFELSE, executed if s0 is 0 (false)\n' + + ' <{\n' + + ' // _ split_depth:(Maybe (## 5))\n' + + ' // special:(Maybe TickTock)\n' + + ' // code:(Maybe ^Cell)\n' + + ' // data:(Maybe ^Cell)\n' + + ' // library:(Maybe ^Cell)\n' + + ' // = StateInit;\n' + + ' ROT // place message Builder on top\n' + + ' b{10} STSLICECONST // store Maybe = true, Either = false\n' + + ' // Start composing inlined StateInit\n' + + ' b{00} STSLICECONST // store split_depth and special first\n' + + ' STDICT // store code\n' + + ' STDICT // store data\n' + + ' b{0} STSLICECONST // store library\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: IFELSE that does the branching shown above\n' + + ' IFELSE\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: null or StateInit\n' + + ' // s2: `body`\n' + + ' // s3: `mode`\n' + + '\n' + + ' // Group 4: Finalizing the message\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: `mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG // https://github.com/tact-lang/tact/issues/1558' + ] + }, + loc: { start: 6211, end: 9157 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'DeployParameters', + loc: { start: 9347, end: 9363 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 9505, end: 9509 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9511, end: 9514 } + }, + loc: { start: 9511, end: 9514 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 9517, end: 9532 } + }, + loc: { start: 9505, end: 9532 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 9582, end: 9586 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 9592, end: 9593 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 9588, end: 9592 } + }, + loc: { start: 9588, end: 9592 } + } + ], + loc: { start: 9592, end: 9593 } + }, + initializer: { kind: 'null', loc: { start: 9596, end: 9600 } }, + loc: { start: 9582, end: 9600 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 9796, end: 9801 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9803, end: 9806 } + }, + loc: { start: 9803, end: 9806 } + }, + initializer: undefined, + loc: { start: 9796, end: 9806 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 9972, end: 9978 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 9980, end: 9984 } + }, + typeArgs: [], + loc: { start: 9980, end: 9984 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 9987, end: 9991 } + }, + loc: { start: 9972, end: 9991 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'init', + loc: { start: 10135, end: 10139 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 10141, end: 10150 } + }, + typeArgs: [], + loc: { start: 10141, end: 10150 } + }, + initializer: undefined, + loc: { start: 10135, end: 10150 } + } + ], + loc: { start: 9340, end: 10153 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'deploy', + loc: { start: 11796, end: 11802 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 11803, end: 11809 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'DeployParameters', + loc: { start: 11811, end: 11827 } + }, + typeArgs: [], + loc: { start: 11811, end: 11827 } + }, + loc: { start: 11803, end: 11827 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '4 1 BLKPUSH // pushes 2 copies of `init.code` and `init.data`\n' + + ' HASHCU // `init.data` hash\n' + + ' SWAP\n' + + ' HASHCU // `init.code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `init.data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `init.code` depth\n' + + '\n' + + ' // Group 2: Calculating destination address\n' + + ' // For almost identical logic and instructions,\n' + + ' // see comments inside `contractHash()` function in contract.tact\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + ' NEWC\n' + + ' 24 STU\n' + + ' 16 STU\n' + + ' 16 STU\n' + + ' 256 STU\n' + + ' 256 STU\n' + + ' ONE HASHEXT_SHA256 // obtains hash part (account id) of the address\n' + + ' // → Stack state\n' + + ' // s0: destAddr(hash part)\n' + + ' // s1: `init.data`\n' + + ' // s2: `init.code`\n' + + ' // s3 and below: `bounce`, `value`, `body`, `mode`\n' + + '\n' + + ' // Group 3: Building a message (CommonMsgInfoRelaxed)\n' + + ' s3 XCHG0 // swaps `bounce` with destAddr(hash part)\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' s1 s2 XCHG // swap `init.data` with `init.code`, placing code on s1\n' + + ' STREF // store `init.code`\n' + + ' STREF // store `init.data`\n' + + ' // Inline StateInit:\n' + + ' b{00010000000000} STSLICECONST\n' + + ' // 0 + 00 + 10 + 0 + 00000000\n' + + ' // 1) 0 - bounced = false\n' + + ' // 2) 00 - src = addr_none\n' + + ' // 3) 10 - tag of addr_std (part of dest)\n' + + ' // 4) 0 - Maybe Anycast = false\n' + + ' // 5) 00000000 - workchain_id (part of dest)\n' + + ' //\n' + + ' 256 STU // store destAddr(hash part)\n' + + ' SWAP // Builder on top, `value` below\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + '\n' + + ' // Group 4: Continue building a message (CommonMsgInfoRelaxed into MessageRelaxed)\n' + + ' // Remaining bits of MessageRelaxed:\n' + + ' b{1000110} STSLICECONST\n' + + ' // 10 + 0 + 0 + 1 + 1 + 0\n' + + ' // 10 - Maybe (Either StateInit ^StateInit) = true false\n' + + ' // 0 - split_depth:(Maybe (## 5)) = false\n' + + ' // 0 = special:(Maybe TickTock) = false\n' + + ' // 1 = code:(Maybe ^Cell) = true\n' + + ' // 1 = data:(Maybe ^Cell) = true\n' + + ' // 0 = library:(Maybe ^Cell) = false\n' + + ' //\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC // finalize the message\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: params.`mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 11788, end: 14770 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'cashback', + loc: { start: 15971, end: 15979 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'to', + loc: { start: 15980, end: 15982 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 15984, end: 15991 } + }, + typeArgs: [], + loc: { start: 15984, end: 15991 } + }, + loc: { start: 15980, end: 15991 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '16 PUSHINT // 0x10, i.e. 0x18 but with bounce = false\n' + + ' NEWC\n' + + ' 6 STU // .storeUint(0x10, 6)\n' + + ' STSLICE // .storeAddress(to)\n' + + ' 0 PUSHINT // 0\n' + + ' 111 STUR // .storeUint(0, 111)\n' + + ' // 4 zeros for coins and 107 zeros for lt, fees, etc.\n' + + ' ENDC\n' + + ' 66 PUSHINT // SendRemainingValue | SendIgnoreErrors\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 15963, end: 16385 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeSendMessage', + loc: { start: 16936, end: 16953 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 16954, end: 16957 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 16959, end: 16963 } + }, + loc: { start: 16959, end: 16963 } + }, + loc: { start: 16954, end: 16963 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 16965, end: 16969 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 16971, end: 16974 } + }, + loc: { start: 16971, end: 16974 } + }, + loc: { start: 16965, end: 16974 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDRAWMSG' ] + }, + loc: { start: 16928, end: 16990 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sendRawMessage', + loc: { start: 17751, end: 17765 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 17766, end: 17769 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 17771, end: 17775 } + }, + loc: { start: 17771, end: 17775 } + }, + loc: { start: 17766, end: 17775 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 17777, end: 17781 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 17783, end: 17786 } + }, + loc: { start: 17783, end: 17786 } + }, + loc: { start: 17777, end: 17786 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDRAWMSG' ] + }, + loc: { start: 17743, end: 17802 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeSendMessageReturnForwardFee', + loc: { start: 19063, end: 19096 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 19120, end: 19123 } + }, + loc: { start: 19120, end: 19123 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 19097, end: 19100 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 19102, end: 19106 } + }, + loc: { start: 19102, end: 19106 } + }, + loc: { start: 19097, end: 19106 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 19108, end: 19112 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 19114, end: 19117 } + }, + loc: { start: 19114, end: 19117 } + }, + loc: { start: 19108, end: 19117 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDMSG' ] + }, + loc: { start: 19055, end: 19135 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sendMessageReturnForwardFee', + loc: { start: 20186, end: 20213 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 20237, end: 20240 } + }, + loc: { start: 20237, end: 20240 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 20214, end: 20217 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 20219, end: 20223 } + }, + loc: { start: 20219, end: 20223 } + }, + loc: { start: 20214, end: 20223 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 20225, end: 20229 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 20231, end: 20234 } + }, + loc: { start: 20231, end: 20234 } + }, + loc: { start: 20225, end: 20234 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDMSG' ] + }, + loc: { start: 20178, end: 20252 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'emit', + loc: { start: 21033, end: 21037 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'body', + loc: { start: 21038, end: 21042 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 21044, end: 21048 } + }, + loc: { start: 21044, end: 21048 } + }, + loc: { start: 21038, end: 21048 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'c', + loc: { start: 21233, end: 21234 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 21236, end: 21240 } + }, + loc: { start: 21236, end: 21240 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'static_call', + function: { + kind: 'id', + text: 'beginCell', + loc: { start: 21243, end: 21252 } + }, + typeArgs: [], + args: [], + loc: { start: 21243, end: 21254 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 21264, end: 21273 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 15211807202738752817960438464513n, + loc: { start: 21274, end: 21306 } + }, + { + kind: 'number', + base: '10', + value: 104n, + loc: { start: 21308, end: 21311 } + } + ], + loc: { start: 21243, end: 21312 } + }, + method: { + kind: 'id', + text: 'storeRef', + loc: { start: 21322, end: 21330 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'body', + loc: { start: 21331, end: 21335 } + } + ], + loc: { start: 21243, end: 21336 } + }, + method: { + kind: 'id', + text: 'endCell', + loc: { start: 21346, end: 21353 } + }, + typeArgs: [], + args: [], + loc: { start: 21243, end: 21355 } + }, + loc: { start: 21229, end: 21356 } + }, + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'sendRawMessage', + loc: { start: 21361, end: 21375 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'c', + loc: { start: 21376, end: 21377 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 21379, end: 21380 } + } + ], + loc: { start: 21361, end: 21381 } + }, + loc: { start: 21361, end: 21382 } + } + ] + }, + loc: { start: 21022, end: 21384 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'acceptMessage', + loc: { start: 22124, end: 22137 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ACCEPT' ] + }, + loc: { start: 22116, end: 22150 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'commit', + loc: { start: 22638, end: 22644 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'COMMIT' ] + }, + loc: { start: 22630, end: 22657 } + } + ] + }, + 'nativeSendMessageReturnForwardFee' => { + kind: 'tact', + path: 'std/internal/send.tact', + code: '/// Ordinary message (default).\n' + + '///\n' + + '/// This constant is available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendDefaultMode: Int = 0;\n' + + '\n' + + '/// Carry all the remaining value of the inbound message in addition\n' + + '/// to the value initially indicated in the new message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendRemainingValue: Int = 64;\n' + + '\n' + + '/// Carry **all the remaining balance** of the current smart contract instead\n' + + '/// of the value originally indicated in the message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendRemainingBalance: Int = 128;\n' + + '\n' + + "/// Doesn't send the message, only estimates the forward fees\n" + + '/// if the message-sending function computes those.\n' + + '///\n' + + '/// This constant is available since Tact 1.5.0.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '/// * https://docs.tact-lang.org/book/send#message-sending-functions\n' + + '///\n' + + 'const SendOnlyEstimateFee: Int = 1024;\n' + + '\n' + + '/// **Deprecated** since Tact 1.6.5.\n' + + '///\n' + + '/// Pay forward fees separately from the message value.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendPayGasSeparately: Int = 1;\n' + + '\n' + + '/// Pay forward fees separately from the message value.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendPayFwdFeesSeparately: Int = 1;\n' + + '\n' + + '/// Ignore any errors arising while processing this message during the action phase.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendIgnoreErrors: Int = 2;\n' + + '\n' + + '/// Bounce transaction in case of any errors during action phase.\n' + + '/// Has no effect if flag +2, `SendIgnoreErrors` is used.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendBounceIfActionFail: Int = 16;\n' + + '\n' + + '/// Current account (contract) will be destroyed if its resulting balance is zero.\n' + + '/// This flag is often used with mode 128, `SendRemainingBalance`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendDestroyIfZero: Int = 32;\n' + + '\n' + + '/// Struct for specifying the message parameters of the `send()` function.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#send\n' + + '///\n' + + 'struct SendParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// Optional initial code of the contract (compiled bitcode).\n' + + ' code: Cell? = null;\n' + + '\n' + + ' /// Optional initial data of the contract (arguments of `init()` function or values of contract parameters).\n' + + ' data: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// Recipient internal `Address` on TON Blockchain.\n' + + ' to: Address;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '}\n' + + '\n' + + '/// Struct for specifying the message parameters of the `message()` function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#message\n' + + '///\n' + + 'struct MessageParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// Recipient internal `Address` on TON Blockchain.\n' + + ' to: Address;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Queues the message to be sent using the `MessageParameters` struct. Allows for cheaper non-deployment, regular messages compared to the `send()` function.\n' + + '///\n' + + '/// The `MessageParameters` struct is similar to `SendParameters` struct, but without the `code` and `data` fields.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// message(MessageParameters{\n' + + '/// to: sender(), // back to the sender,\n' + + '/// value: ton("1"), // with 1 Toncoin (1_000_000_000 nanoToncoin),\n' + + '/// // and no message body\n' + + '/// });\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 33: [Action list is too long] — Thrown when attempting to queue more than 255 messages.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-send#message\n' + + '/// * https://docs.tact-lang.org/book/message-mode\n' + + '///\n' + + '/// [Action list is too long]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '///\n' + + 'asm fun message(params: MessageParameters) {\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 106 PUSHINT // 1 + 4 + 4 + 64 + 32 + 1\n' + + ' STZEROES\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + ' STDICT\n' + + ' ENDC\n' + + ' SWAP\n' + + ' SENDRAWMSG\n' + + '}\n' + + '\n' + + '/// Global function. Queues the message to be sent using a `SendParameters` Struct.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// send(SendParameters{\n' + + '/// to: sender(), // back to the sender,\n' + + '/// value: ton("1"), // with 1 Toncoin (1_000_000_000 nanoToncoin),\n' + + '/// // and no message body\n' + + '/// });\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 33: [Action list is too long] — Thrown when attempting to queue more than 255 messages.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#send\n' + + '///\n' + + '/// [Action list is too long]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '///\n' + + 'asm fun send(params: SendParameters) {\n' + + ' // Instructions are grouped, and the stack states they produce as a group are shown right after.\n' + + ' // In the end, our message Cell should have the following TL-B structure:\n' + + ' // message$_ {X:Type}\n' + + ' // info:CommonMsgInfoRelaxed\n' + + ' // init:(Maybe (Either StateInit ^StateInit))\n' + + ' // body:(Either X ^X)\n' + + ' // = MessageRelaxed X;\n' + + '\n' + + ' // → Stack state\n' + + ' // s0: `params.bounce`\n' + + ' // s1: `params.to`\n' + + ' // s2: `params.value`\n' + + ' // s3: `params.data`\n' + + ' // s4: `params.code`\n' + + ' // s5: `params.body`\n' + + ' // s6: `params.mode`\n' + + ' // For brevity, the "params" prefix will be omitted from now on.\n' + + '\n' + + ' // Group 1: Storing the `bounce`, `to` and `value` into a Builder\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + '\n' + + ' // Group 2: Placing the Builder after code and data, then checking those for nullability\n' + + ' s2 XCHG0\n' + + ' DUP2\n' + + ' ISNULL\n' + + ' SWAP\n' + + ' ISNULL\n' + + ' AND\n' + + ' // → Stack state\n' + + ' // s0: -1 (true) if `data` and `code` are both null, 0 (false) otherwise\n' + + ' // s1: `code`\n' + + ' // s2: `data`\n' + + ' // s3: Builder\n' + + ' // s4: `body`\n' + + ' // s5: `mode`\n' + + '\n' + + ' // Group 3: Left branch of the IFELSE, executed if s0 is -1 (true)\n' + + ' <{\n' + + ' DROP2 // drop `data` and `code`, since either of those is null\n' + + ' b{0} STSLICECONST\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: Right branch of the IFELSE, executed if s0 is 0 (false)\n' + + ' <{\n' + + ' // _ split_depth:(Maybe (## 5))\n' + + ' // special:(Maybe TickTock)\n' + + ' // code:(Maybe ^Cell)\n' + + ' // data:(Maybe ^Cell)\n' + + ' // library:(Maybe ^Cell)\n' + + ' // = StateInit;\n' + + ' ROT // place message Builder on top\n' + + ' b{10} STSLICECONST // store Maybe = true, Either = false\n' + + ' // Start composing inlined StateInit\n' + + ' b{00} STSLICECONST // store split_depth and special first\n' + + ' STDICT // store code\n' + + ' STDICT // store data\n' + + ' b{0} STSLICECONST // store library\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: IFELSE that does the branching shown above\n' + + ' IFELSE\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: null or StateInit\n' + + ' // s2: `body`\n' + + ' // s3: `mode`\n' + + '\n' + + ' // Group 4: Finalizing the message\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: `mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG // https://github.com/tact-lang/tact/issues/1558\n' + + '}\n' + + '\n' + + '/// Struct for specifying the deployment message parameters of the `deploy()` function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#deploy\n' + + '///\n' + + 'struct DeployParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '\n' + + ' //'... 12658 more characters, + imports: [], + items: [ + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendDefaultMode', + loc: { start: 164, end: 179 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 181, end: 184 } + }, + loc: { start: 181, end: 184 } + }, + initializer: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 187, end: 188 } + } + }, + loc: { start: 158, end: 189 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendRemainingValue', + loc: { start: 396, end: 414 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 416, end: 419 } + }, + loc: { start: 416, end: 419 } + }, + initializer: { + kind: 'number', + base: '10', + value: 64n, + loc: { start: 422, end: 424 } + } + }, + loc: { start: 390, end: 425 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendRemainingBalance', + loc: { start: 638, end: 658 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 660, end: 663 } + }, + loc: { start: 660, end: 663 } + }, + initializer: { + kind: 'number', + base: '10', + value: 128n, + loc: { start: 666, end: 669 } + } + }, + loc: { start: 632, end: 670 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendOnlyEstimateFee', + loc: { start: 993, end: 1012 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1014, end: 1017 } + }, + loc: { start: 1014, end: 1017 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1024n, + loc: { start: 1020, end: 1024 } + } + }, + loc: { start: 987, end: 1025 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendPayGasSeparately', + loc: { start: 1207, end: 1227 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1229, end: 1232 } + }, + loc: { start: 1229, end: 1232 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1235, end: 1236 } + } + }, + loc: { start: 1201, end: 1237 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendPayFwdFeesSeparately', + loc: { start: 1378, end: 1402 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1404, end: 1407 } + }, + loc: { start: 1404, end: 1407 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1410, end: 1411 } + } + }, + loc: { start: 1372, end: 1412 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendIgnoreErrors', + loc: { start: 1582, end: 1598 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1600, end: 1603 } + }, + loc: { start: 1600, end: 1603 } + }, + initializer: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 1606, end: 1607 } + } + }, + loc: { start: 1576, end: 1608 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendBounceIfActionFail', + loc: { start: 1817, end: 1839 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1841, end: 1844 } + }, + loc: { start: 1841, end: 1844 } + }, + initializer: { + kind: 'number', + base: '10', + value: 16n, + loc: { start: 1847, end: 1849 } + } + }, + loc: { start: 1811, end: 1850 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendDestroyIfZero', + loc: { start: 2085, end: 2102 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2104, end: 2107 } + }, + loc: { start: 2104, end: 2107 } + }, + initializer: { + kind: 'number', + base: '10', + value: 32n, + loc: { start: 2110, end: 2112 } + } + }, + loc: { start: 2079, end: 2113 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'SendParameters', + loc: { start: 2260, end: 2274 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 2416, end: 2420 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2422, end: 2425 } + }, + loc: { start: 2422, end: 2425 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 2428, end: 2443 } + }, + loc: { start: 2416, end: 2443 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 2493, end: 2497 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2503, end: 2504 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2499, end: 2503 } + }, + loc: { start: 2499, end: 2503 } + } + ], + loc: { start: 2503, end: 2504 } + }, + initializer: { kind: 'null', loc: { start: 2507, end: 2511 } }, + loc: { start: 2493, end: 2511 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'code', + loc: { start: 2584, end: 2588 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2594, end: 2595 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2590, end: 2594 } + }, + loc: { start: 2590, end: 2594 } + } + ], + loc: { start: 2594, end: 2595 } + }, + initializer: { kind: 'null', loc: { start: 2598, end: 2602 } }, + loc: { start: 2584, end: 2602 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'data', + loc: { start: 2722, end: 2726 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2732, end: 2733 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2728, end: 2732 } + }, + loc: { start: 2728, end: 2732 } + } + ], + loc: { start: 2732, end: 2733 } + }, + initializer: { kind: 'null', loc: { start: 2736, end: 2740 } }, + loc: { start: 2722, end: 2740 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 2936, end: 2941 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2943, end: 2946 } + }, + loc: { start: 2943, end: 2946 } + }, + initializer: undefined, + loc: { start: 2936, end: 2946 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'to', + loc: { start: 3009, end: 3011 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3013, end: 3020 } + }, + typeArgs: [], + loc: { start: 3013, end: 3020 } + }, + initializer: undefined, + loc: { start: 3009, end: 3020 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 3186, end: 3192 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 3194, end: 3198 } + }, + typeArgs: [], + loc: { start: 3194, end: 3198 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 3201, end: 3205 } + }, + loc: { start: 3186, end: 3205 } + } + ], + loc: { start: 2253, end: 3208 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'MessageParameters', + loc: { start: 3389, end: 3406 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 3548, end: 3552 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3554, end: 3557 } + }, + loc: { start: 3554, end: 3557 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 3560, end: 3575 } + }, + loc: { start: 3548, end: 3575 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 3625, end: 3629 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 3635, end: 3636 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 3631, end: 3635 } + }, + loc: { start: 3631, end: 3635 } + } + ], + loc: { start: 3635, end: 3636 } + }, + initializer: { kind: 'null', loc: { start: 3639, end: 3643 } }, + loc: { start: 3625, end: 3643 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 3839, end: 3844 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3846, end: 3849 } + }, + loc: { start: 3846, end: 3849 } + }, + initializer: undefined, + loc: { start: 3839, end: 3849 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'to', + loc: { start: 3912, end: 3914 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3916, end: 3923 } + }, + typeArgs: [], + loc: { start: 3916, end: 3923 } + }, + initializer: undefined, + loc: { start: 3912, end: 3923 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 4089, end: 4095 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 4097, end: 4101 } + }, + typeArgs: [], + loc: { start: 4097, end: 4101 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 4104, end: 4108 } + }, + loc: { start: 4089, end: 4108 } + } + ], + loc: { start: 3382, end: 4111 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'message', + loc: { start: 5056, end: 5063 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 5064, end: 5070 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'MessageParameters', + loc: { start: 5072, end: 5089 } + }, + typeArgs: [], + loc: { start: 5072, end: 5089 } + }, + loc: { start: 5064, end: 5089 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 106 PUSHINT // 1 + 4 + 4 + 64 + 32 + 1\n' + + ' STZEROES\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + ' STDICT\n' + + ' ENDC\n' + + ' SWAP\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 5048, end: 5588 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'send', loc: { start: 6219, end: 6223 } }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 6224, end: 6230 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'SendParameters', + loc: { start: 6232, end: 6246 } + }, + typeArgs: [], + loc: { start: 6232, end: 6246 } + }, + loc: { start: 6224, end: 6246 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + '\n' + + ' // Group 2: Placing the Builder after code and data, then checking those for nullability\n' + + ' s2 XCHG0\n' + + ' DUP2\n' + + ' ISNULL\n' + + ' SWAP\n' + + ' ISNULL\n' + + ' AND\n' + + ' // → Stack state\n' + + ' // s0: -1 (true) if `data` and `code` are both null, 0 (false) otherwise\n' + + ' // s1: `code`\n' + + ' // s2: `data`\n' + + ' // s3: Builder\n' + + ' // s4: `body`\n' + + ' // s5: `mode`\n' + + '\n' + + ' // Group 3: Left branch of the IFELSE, executed if s0 is -1 (true)\n' + + ' <{\n' + + ' DROP2 // drop `data` and `code`, since either of those is null\n' + + ' b{0} STSLICECONST\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: Right branch of the IFELSE, executed if s0 is 0 (false)\n' + + ' <{\n' + + ' // _ split_depth:(Maybe (## 5))\n' + + ' // special:(Maybe TickTock)\n' + + ' // code:(Maybe ^Cell)\n' + + ' // data:(Maybe ^Cell)\n' + + ' // library:(Maybe ^Cell)\n' + + ' // = StateInit;\n' + + ' ROT // place message Builder on top\n' + + ' b{10} STSLICECONST // store Maybe = true, Either = false\n' + + ' // Start composing inlined StateInit\n' + + ' b{00} STSLICECONST // store split_depth and special first\n' + + ' STDICT // store code\n' + + ' STDICT // store data\n' + + ' b{0} STSLICECONST // store library\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: IFELSE that does the branching shown above\n' + + ' IFELSE\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: null or StateInit\n' + + ' // s2: `body`\n' + + ' // s3: `mode`\n' + + '\n' + + ' // Group 4: Finalizing the message\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: `mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG // https://github.com/tact-lang/tact/issues/1558' + ] + }, + loc: { start: 6211, end: 9157 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'DeployParameters', + loc: { start: 9347, end: 9363 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 9505, end: 9509 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9511, end: 9514 } + }, + loc: { start: 9511, end: 9514 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 9517, end: 9532 } + }, + loc: { start: 9505, end: 9532 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 9582, end: 9586 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 9592, end: 9593 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 9588, end: 9592 } + }, + loc: { start: 9588, end: 9592 } + } + ], + loc: { start: 9592, end: 9593 } + }, + initializer: { kind: 'null', loc: { start: 9596, end: 9600 } }, + loc: { start: 9582, end: 9600 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 9796, end: 9801 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9803, end: 9806 } + }, + loc: { start: 9803, end: 9806 } + }, + initializer: undefined, + loc: { start: 9796, end: 9806 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 9972, end: 9978 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 9980, end: 9984 } + }, + typeArgs: [], + loc: { start: 9980, end: 9984 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 9987, end: 9991 } + }, + loc: { start: 9972, end: 9991 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'init', + loc: { start: 10135, end: 10139 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 10141, end: 10150 } + }, + typeArgs: [], + loc: { start: 10141, end: 10150 } + }, + initializer: undefined, + loc: { start: 10135, end: 10150 } + } + ], + loc: { start: 9340, end: 10153 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'deploy', + loc: { start: 11796, end: 11802 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 11803, end: 11809 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'DeployParameters', + loc: { start: 11811, end: 11827 } + }, + typeArgs: [], + loc: { start: 11811, end: 11827 } + }, + loc: { start: 11803, end: 11827 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '4 1 BLKPUSH // pushes 2 copies of `init.code` and `init.data`\n' + + ' HASHCU // `init.data` hash\n' + + ' SWAP\n' + + ' HASHCU // `init.code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `init.data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `init.code` depth\n' + + '\n' + + ' // Group 2: Calculating destination address\n' + + ' // For almost identical logic and instructions,\n' + + ' // see comments inside `contractHash()` function in contract.tact\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + ' NEWC\n' + + ' 24 STU\n' + + ' 16 STU\n' + + ' 16 STU\n' + + ' 256 STU\n' + + ' 256 STU\n' + + ' ONE HASHEXT_SHA256 // obtains hash part (account id) of the address\n' + + ' // → Stack state\n' + + ' // s0: destAddr(hash part)\n' + + ' // s1: `init.data`\n' + + ' // s2: `init.code`\n' + + ' // s3 and below: `bounce`, `value`, `body`, `mode`\n' + + '\n' + + ' // Group 3: Building a message (CommonMsgInfoRelaxed)\n' + + ' s3 XCHG0 // swaps `bounce` with destAddr(hash part)\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' s1 s2 XCHG // swap `init.data` with `init.code`, placing code on s1\n' + + ' STREF // store `init.code`\n' + + ' STREF // store `init.data`\n' + + ' // Inline StateInit:\n' + + ' b{00010000000000} STSLICECONST\n' + + ' // 0 + 00 + 10 + 0 + 00000000\n' + + ' // 1) 0 - bounced = false\n' + + ' // 2) 00 - src = addr_none\n' + + ' // 3) 10 - tag of addr_std (part of dest)\n' + + ' // 4) 0 - Maybe Anycast = false\n' + + ' // 5) 00000000 - workchain_id (part of dest)\n' + + ' //\n' + + ' 256 STU // store destAddr(hash part)\n' + + ' SWAP // Builder on top, `value` below\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + '\n' + + ' // Group 4: Continue building a message (CommonMsgInfoRelaxed into MessageRelaxed)\n' + + ' // Remaining bits of MessageRelaxed:\n' + + ' b{1000110} STSLICECONST\n' + + ' // 10 + 0 + 0 + 1 + 1 + 0\n' + + ' // 10 - Maybe (Either StateInit ^StateInit) = true false\n' + + ' // 0 - split_depth:(Maybe (## 5)) = false\n' + + ' // 0 = special:(Maybe TickTock) = false\n' + + ' // 1 = code:(Maybe ^Cell) = true\n' + + ' // 1 = data:(Maybe ^Cell) = true\n' + + ' // 0 = library:(Maybe ^Cell) = false\n' + + ' //\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC // finalize the message\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: params.`mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 11788, end: 14770 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'cashback', + loc: { start: 15971, end: 15979 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'to', + loc: { start: 15980, end: 15982 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 15984, end: 15991 } + }, + typeArgs: [], + loc: { start: 15984, end: 15991 } + }, + loc: { start: 15980, end: 15991 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '16 PUSHINT // 0x10, i.e. 0x18 but with bounce = false\n' + + ' NEWC\n' + + ' 6 STU // .storeUint(0x10, 6)\n' + + ' STSLICE // .storeAddress(to)\n' + + ' 0 PUSHINT // 0\n' + + ' 111 STUR // .storeUint(0, 111)\n' + + ' // 4 zeros for coins and 107 zeros for lt, fees, etc.\n' + + ' ENDC\n' + + ' 66 PUSHINT // SendRemainingValue | SendIgnoreErrors\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 15963, end: 16385 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeSendMessage', + loc: { start: 16936, end: 16953 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 16954, end: 16957 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 16959, end: 16963 } + }, + loc: { start: 16959, end: 16963 } + }, + loc: { start: 16954, end: 16963 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 16965, end: 16969 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 16971, end: 16974 } + }, + loc: { start: 16971, end: 16974 } + }, + loc: { start: 16965, end: 16974 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDRAWMSG' ] + }, + loc: { start: 16928, end: 16990 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sendRawMessage', + loc: { start: 17751, end: 17765 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 17766, end: 17769 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 17771, end: 17775 } + }, + loc: { start: 17771, end: 17775 } + }, + loc: { start: 17766, end: 17775 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 17777, end: 17781 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 17783, end: 17786 } + }, + loc: { start: 17783, end: 17786 } + }, + loc: { start: 17777, end: 17786 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDRAWMSG' ] + }, + loc: { start: 17743, end: 17802 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeSendMessageReturnForwardFee', + loc: { start: 19063, end: 19096 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 19120, end: 19123 } + }, + loc: { start: 19120, end: 19123 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 19097, end: 19100 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 19102, end: 19106 } + }, + loc: { start: 19102, end: 19106 } + }, + loc: { start: 19097, end: 19106 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 19108, end: 19112 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 19114, end: 19117 } + }, + loc: { start: 19114, end: 19117 } + }, + loc: { start: 19108, end: 19117 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDMSG' ] + }, + loc: { start: 19055, end: 19135 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sendMessageReturnForwardFee', + loc: { start: 20186, end: 20213 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 20237, end: 20240 } + }, + loc: { start: 20237, end: 20240 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 20214, end: 20217 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 20219, end: 20223 } + }, + loc: { start: 20219, end: 20223 } + }, + loc: { start: 20214, end: 20223 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 20225, end: 20229 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 20231, end: 20234 } + }, + loc: { start: 20231, end: 20234 } + }, + loc: { start: 20225, end: 20234 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDMSG' ] + }, + loc: { start: 20178, end: 20252 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'emit', + loc: { start: 21033, end: 21037 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'body', + loc: { start: 21038, end: 21042 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 21044, end: 21048 } + }, + loc: { start: 21044, end: 21048 } + }, + loc: { start: 21038, end: 21048 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'c', + loc: { start: 21233, end: 21234 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 21236, end: 21240 } + }, + loc: { start: 21236, end: 21240 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'static_call', + function: { + kind: 'id', + text: 'beginCell', + loc: { start: 21243, end: 21252 } + }, + typeArgs: [], + args: [], + loc: { start: 21243, end: 21254 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 21264, end: 21273 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 15211807202738752817960438464513n, + loc: { start: 21274, end: 21306 } + }, + { + kind: 'number', + base: '10', + value: 104n, + loc: { start: 21308, end: 21311 } + } + ], + loc: { start: 21243, end: 21312 } + }, + method: { + kind: 'id', + text: 'storeRef', + loc: { start: 21322, end: 21330 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'body', + loc: { start: 21331, end: 21335 } + } + ], + loc: { start: 21243, end: 21336 } + }, + method: { + kind: 'id', + text: 'endCell', + loc: { start: 21346, end: 21353 } + }, + typeArgs: [], + args: [], + loc: { start: 21243, end: 21355 } + }, + loc: { start: 21229, end: 21356 } + }, + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'sendRawMessage', + loc: { start: 21361, end: 21375 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'c', + loc: { start: 21376, end: 21377 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 21379, end: 21380 } + } + ], + loc: { start: 21361, end: 21381 } + }, + loc: { start: 21361, end: 21382 } + } + ] + }, + loc: { start: 21022, end: 21384 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'acceptMessage', + loc: { start: 22124, end: 22137 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ACCEPT' ] + }, + loc: { start: 22116, end: 22150 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'commit', + loc: { start: 22638, end: 22644 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'COMMIT' ] + }, + loc: { start: 22630, end: 22657 } + } + ] + }, + 'sendMessageReturnForwardFee' => { + kind: 'tact', + path: 'std/internal/send.tact', + code: '/// Ordinary message (default).\n' + + '///\n' + + '/// This constant is available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendDefaultMode: Int = 0;\n' + + '\n' + + '/// Carry all the remaining value of the inbound message in addition\n' + + '/// to the value initially indicated in the new message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendRemainingValue: Int = 64;\n' + + '\n' + + '/// Carry **all the remaining balance** of the current smart contract instead\n' + + '/// of the value originally indicated in the message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendRemainingBalance: Int = 128;\n' + + '\n' + + "/// Doesn't send the message, only estimates the forward fees\n" + + '/// if the message-sending function computes those.\n' + + '///\n' + + '/// This constant is available since Tact 1.5.0.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '/// * https://docs.tact-lang.org/book/send#message-sending-functions\n' + + '///\n' + + 'const SendOnlyEstimateFee: Int = 1024;\n' + + '\n' + + '/// **Deprecated** since Tact 1.6.5.\n' + + '///\n' + + '/// Pay forward fees separately from the message value.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendPayGasSeparately: Int = 1;\n' + + '\n' + + '/// Pay forward fees separately from the message value.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendPayFwdFeesSeparately: Int = 1;\n' + + '\n' + + '/// Ignore any errors arising while processing this message during the action phase.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendIgnoreErrors: Int = 2;\n' + + '\n' + + '/// Bounce transaction in case of any errors during action phase.\n' + + '/// Has no effect if flag +2, `SendIgnoreErrors` is used.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendBounceIfActionFail: Int = 16;\n' + + '\n' + + '/// Current account (contract) will be destroyed if its resulting balance is zero.\n' + + '/// This flag is often used with mode 128, `SendRemainingBalance`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendDestroyIfZero: Int = 32;\n' + + '\n' + + '/// Struct for specifying the message parameters of the `send()` function.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#send\n' + + '///\n' + + 'struct SendParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// Optional initial code of the contract (compiled bitcode).\n' + + ' code: Cell? = null;\n' + + '\n' + + ' /// Optional initial data of the contract (arguments of `init()` function or values of contract parameters).\n' + + ' data: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// Recipient internal `Address` on TON Blockchain.\n' + + ' to: Address;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '}\n' + + '\n' + + '/// Struct for specifying the message parameters of the `message()` function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#message\n' + + '///\n' + + 'struct MessageParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// Recipient internal `Address` on TON Blockchain.\n' + + ' to: Address;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Queues the message to be sent using the `MessageParameters` struct. Allows for cheaper non-deployment, regular messages compared to the `send()` function.\n' + + '///\n' + + '/// The `MessageParameters` struct is similar to `SendParameters` struct, but without the `code` and `data` fields.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// message(MessageParameters{\n' + + '/// to: sender(), // back to the sender,\n' + + '/// value: ton("1"), // with 1 Toncoin (1_000_000_000 nanoToncoin),\n' + + '/// // and no message body\n' + + '/// });\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 33: [Action list is too long] — Thrown when attempting to queue more than 255 messages.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-send#message\n' + + '/// * https://docs.tact-lang.org/book/message-mode\n' + + '///\n' + + '/// [Action list is too long]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '///\n' + + 'asm fun message(params: MessageParameters) {\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 106 PUSHINT // 1 + 4 + 4 + 64 + 32 + 1\n' + + ' STZEROES\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + ' STDICT\n' + + ' ENDC\n' + + ' SWAP\n' + + ' SENDRAWMSG\n' + + '}\n' + + '\n' + + '/// Global function. Queues the message to be sent using a `SendParameters` Struct.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// send(SendParameters{\n' + + '/// to: sender(), // back to the sender,\n' + + '/// value: ton("1"), // with 1 Toncoin (1_000_000_000 nanoToncoin),\n' + + '/// // and no message body\n' + + '/// });\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 33: [Action list is too long] — Thrown when attempting to queue more than 255 messages.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#send\n' + + '///\n' + + '/// [Action list is too long]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '///\n' + + 'asm fun send(params: SendParameters) {\n' + + ' // Instructions are grouped, and the stack states they produce as a group are shown right after.\n' + + ' // In the end, our message Cell should have the following TL-B structure:\n' + + ' // message$_ {X:Type}\n' + + ' // info:CommonMsgInfoRelaxed\n' + + ' // init:(Maybe (Either StateInit ^StateInit))\n' + + ' // body:(Either X ^X)\n' + + ' // = MessageRelaxed X;\n' + + '\n' + + ' // → Stack state\n' + + ' // s0: `params.bounce`\n' + + ' // s1: `params.to`\n' + + ' // s2: `params.value`\n' + + ' // s3: `params.data`\n' + + ' // s4: `params.code`\n' + + ' // s5: `params.body`\n' + + ' // s6: `params.mode`\n' + + ' // For brevity, the "params" prefix will be omitted from now on.\n' + + '\n' + + ' // Group 1: Storing the `bounce`, `to` and `value` into a Builder\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + '\n' + + ' // Group 2: Placing the Builder after code and data, then checking those for nullability\n' + + ' s2 XCHG0\n' + + ' DUP2\n' + + ' ISNULL\n' + + ' SWAP\n' + + ' ISNULL\n' + + ' AND\n' + + ' // → Stack state\n' + + ' // s0: -1 (true) if `data` and `code` are both null, 0 (false) otherwise\n' + + ' // s1: `code`\n' + + ' // s2: `data`\n' + + ' // s3: Builder\n' + + ' // s4: `body`\n' + + ' // s5: `mode`\n' + + '\n' + + ' // Group 3: Left branch of the IFELSE, executed if s0 is -1 (true)\n' + + ' <{\n' + + ' DROP2 // drop `data` and `code`, since either of those is null\n' + + ' b{0} STSLICECONST\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: Right branch of the IFELSE, executed if s0 is 0 (false)\n' + + ' <{\n' + + ' // _ split_depth:(Maybe (## 5))\n' + + ' // special:(Maybe TickTock)\n' + + ' // code:(Maybe ^Cell)\n' + + ' // data:(Maybe ^Cell)\n' + + ' // library:(Maybe ^Cell)\n' + + ' // = StateInit;\n' + + ' ROT // place message Builder on top\n' + + ' b{10} STSLICECONST // store Maybe = true, Either = false\n' + + ' // Start composing inlined StateInit\n' + + ' b{00} STSLICECONST // store split_depth and special first\n' + + ' STDICT // store code\n' + + ' STDICT // store data\n' + + ' b{0} STSLICECONST // store library\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: IFELSE that does the branching shown above\n' + + ' IFELSE\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: null or StateInit\n' + + ' // s2: `body`\n' + + ' // s3: `mode`\n' + + '\n' + + ' // Group 4: Finalizing the message\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: `mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG // https://github.com/tact-lang/tact/issues/1558\n' + + '}\n' + + '\n' + + '/// Struct for specifying the deployment message parameters of the `deploy()` function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#deploy\n' + + '///\n' + + 'struct DeployParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '\n' + + ' //'... 12658 more characters, + imports: [], + items: [ + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendDefaultMode', + loc: { start: 164, end: 179 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 181, end: 184 } + }, + loc: { start: 181, end: 184 } + }, + initializer: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 187, end: 188 } + } + }, + loc: { start: 158, end: 189 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendRemainingValue', + loc: { start: 396, end: 414 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 416, end: 419 } + }, + loc: { start: 416, end: 419 } + }, + initializer: { + kind: 'number', + base: '10', + value: 64n, + loc: { start: 422, end: 424 } + } + }, + loc: { start: 390, end: 425 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendRemainingBalance', + loc: { start: 638, end: 658 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 660, end: 663 } + }, + loc: { start: 660, end: 663 } + }, + initializer: { + kind: 'number', + base: '10', + value: 128n, + loc: { start: 666, end: 669 } + } + }, + loc: { start: 632, end: 670 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendOnlyEstimateFee', + loc: { start: 993, end: 1012 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1014, end: 1017 } + }, + loc: { start: 1014, end: 1017 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1024n, + loc: { start: 1020, end: 1024 } + } + }, + loc: { start: 987, end: 1025 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendPayGasSeparately', + loc: { start: 1207, end: 1227 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1229, end: 1232 } + }, + loc: { start: 1229, end: 1232 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1235, end: 1236 } + } + }, + loc: { start: 1201, end: 1237 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendPayFwdFeesSeparately', + loc: { start: 1378, end: 1402 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1404, end: 1407 } + }, + loc: { start: 1404, end: 1407 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1410, end: 1411 } + } + }, + loc: { start: 1372, end: 1412 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendIgnoreErrors', + loc: { start: 1582, end: 1598 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1600, end: 1603 } + }, + loc: { start: 1600, end: 1603 } + }, + initializer: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 1606, end: 1607 } + } + }, + loc: { start: 1576, end: 1608 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendBounceIfActionFail', + loc: { start: 1817, end: 1839 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1841, end: 1844 } + }, + loc: { start: 1841, end: 1844 } + }, + initializer: { + kind: 'number', + base: '10', + value: 16n, + loc: { start: 1847, end: 1849 } + } + }, + loc: { start: 1811, end: 1850 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendDestroyIfZero', + loc: { start: 2085, end: 2102 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2104, end: 2107 } + }, + loc: { start: 2104, end: 2107 } + }, + initializer: { + kind: 'number', + base: '10', + value: 32n, + loc: { start: 2110, end: 2112 } + } + }, + loc: { start: 2079, end: 2113 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'SendParameters', + loc: { start: 2260, end: 2274 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 2416, end: 2420 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2422, end: 2425 } + }, + loc: { start: 2422, end: 2425 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 2428, end: 2443 } + }, + loc: { start: 2416, end: 2443 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 2493, end: 2497 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2503, end: 2504 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2499, end: 2503 } + }, + loc: { start: 2499, end: 2503 } + } + ], + loc: { start: 2503, end: 2504 } + }, + initializer: { kind: 'null', loc: { start: 2507, end: 2511 } }, + loc: { start: 2493, end: 2511 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'code', + loc: { start: 2584, end: 2588 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2594, end: 2595 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2590, end: 2594 } + }, + loc: { start: 2590, end: 2594 } + } + ], + loc: { start: 2594, end: 2595 } + }, + initializer: { kind: 'null', loc: { start: 2598, end: 2602 } }, + loc: { start: 2584, end: 2602 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'data', + loc: { start: 2722, end: 2726 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2732, end: 2733 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2728, end: 2732 } + }, + loc: { start: 2728, end: 2732 } + } + ], + loc: { start: 2732, end: 2733 } + }, + initializer: { kind: 'null', loc: { start: 2736, end: 2740 } }, + loc: { start: 2722, end: 2740 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 2936, end: 2941 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2943, end: 2946 } + }, + loc: { start: 2943, end: 2946 } + }, + initializer: undefined, + loc: { start: 2936, end: 2946 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'to', + loc: { start: 3009, end: 3011 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3013, end: 3020 } + }, + typeArgs: [], + loc: { start: 3013, end: 3020 } + }, + initializer: undefined, + loc: { start: 3009, end: 3020 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 3186, end: 3192 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 3194, end: 3198 } + }, + typeArgs: [], + loc: { start: 3194, end: 3198 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 3201, end: 3205 } + }, + loc: { start: 3186, end: 3205 } + } + ], + loc: { start: 2253, end: 3208 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'MessageParameters', + loc: { start: 3389, end: 3406 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 3548, end: 3552 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3554, end: 3557 } + }, + loc: { start: 3554, end: 3557 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 3560, end: 3575 } + }, + loc: { start: 3548, end: 3575 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 3625, end: 3629 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 3635, end: 3636 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 3631, end: 3635 } + }, + loc: { start: 3631, end: 3635 } + } + ], + loc: { start: 3635, end: 3636 } + }, + initializer: { kind: 'null', loc: { start: 3639, end: 3643 } }, + loc: { start: 3625, end: 3643 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 3839, end: 3844 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3846, end: 3849 } + }, + loc: { start: 3846, end: 3849 } + }, + initializer: undefined, + loc: { start: 3839, end: 3849 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'to', + loc: { start: 3912, end: 3914 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3916, end: 3923 } + }, + typeArgs: [], + loc: { start: 3916, end: 3923 } + }, + initializer: undefined, + loc: { start: 3912, end: 3923 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 4089, end: 4095 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 4097, end: 4101 } + }, + typeArgs: [], + loc: { start: 4097, end: 4101 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 4104, end: 4108 } + }, + loc: { start: 4089, end: 4108 } + } + ], + loc: { start: 3382, end: 4111 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'message', + loc: { start: 5056, end: 5063 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 5064, end: 5070 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'MessageParameters', + loc: { start: 5072, end: 5089 } + }, + typeArgs: [], + loc: { start: 5072, end: 5089 } + }, + loc: { start: 5064, end: 5089 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 106 PUSHINT // 1 + 4 + 4 + 64 + 32 + 1\n' + + ' STZEROES\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + ' STDICT\n' + + ' ENDC\n' + + ' SWAP\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 5048, end: 5588 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'send', loc: { start: 6219, end: 6223 } }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 6224, end: 6230 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'SendParameters', + loc: { start: 6232, end: 6246 } + }, + typeArgs: [], + loc: { start: 6232, end: 6246 } + }, + loc: { start: 6224, end: 6246 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + '\n' + + ' // Group 2: Placing the Builder after code and data, then checking those for nullability\n' + + ' s2 XCHG0\n' + + ' DUP2\n' + + ' ISNULL\n' + + ' SWAP\n' + + ' ISNULL\n' + + ' AND\n' + + ' // → Stack state\n' + + ' // s0: -1 (true) if `data` and `code` are both null, 0 (false) otherwise\n' + + ' // s1: `code`\n' + + ' // s2: `data`\n' + + ' // s3: Builder\n' + + ' // s4: `body`\n' + + ' // s5: `mode`\n' + + '\n' + + ' // Group 3: Left branch of the IFELSE, executed if s0 is -1 (true)\n' + + ' <{\n' + + ' DROP2 // drop `data` and `code`, since either of those is null\n' + + ' b{0} STSLICECONST\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: Right branch of the IFELSE, executed if s0 is 0 (false)\n' + + ' <{\n' + + ' // _ split_depth:(Maybe (## 5))\n' + + ' // special:(Maybe TickTock)\n' + + ' // code:(Maybe ^Cell)\n' + + ' // data:(Maybe ^Cell)\n' + + ' // library:(Maybe ^Cell)\n' + + ' // = StateInit;\n' + + ' ROT // place message Builder on top\n' + + ' b{10} STSLICECONST // store Maybe = true, Either = false\n' + + ' // Start composing inlined StateInit\n' + + ' b{00} STSLICECONST // store split_depth and special first\n' + + ' STDICT // store code\n' + + ' STDICT // store data\n' + + ' b{0} STSLICECONST // store library\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: IFELSE that does the branching shown above\n' + + ' IFELSE\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: null or StateInit\n' + + ' // s2: `body`\n' + + ' // s3: `mode`\n' + + '\n' + + ' // Group 4: Finalizing the message\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: `mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG // https://github.com/tact-lang/tact/issues/1558' + ] + }, + loc: { start: 6211, end: 9157 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'DeployParameters', + loc: { start: 9347, end: 9363 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 9505, end: 9509 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9511, end: 9514 } + }, + loc: { start: 9511, end: 9514 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 9517, end: 9532 } + }, + loc: { start: 9505, end: 9532 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 9582, end: 9586 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 9592, end: 9593 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 9588, end: 9592 } + }, + loc: { start: 9588, end: 9592 } + } + ], + loc: { start: 9592, end: 9593 } + }, + initializer: { kind: 'null', loc: { start: 9596, end: 9600 } }, + loc: { start: 9582, end: 9600 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 9796, end: 9801 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9803, end: 9806 } + }, + loc: { start: 9803, end: 9806 } + }, + initializer: undefined, + loc: { start: 9796, end: 9806 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 9972, end: 9978 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 9980, end: 9984 } + }, + typeArgs: [], + loc: { start: 9980, end: 9984 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 9987, end: 9991 } + }, + loc: { start: 9972, end: 9991 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'init', + loc: { start: 10135, end: 10139 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 10141, end: 10150 } + }, + typeArgs: [], + loc: { start: 10141, end: 10150 } + }, + initializer: undefined, + loc: { start: 10135, end: 10150 } + } + ], + loc: { start: 9340, end: 10153 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'deploy', + loc: { start: 11796, end: 11802 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 11803, end: 11809 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'DeployParameters', + loc: { start: 11811, end: 11827 } + }, + typeArgs: [], + loc: { start: 11811, end: 11827 } + }, + loc: { start: 11803, end: 11827 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '4 1 BLKPUSH // pushes 2 copies of `init.code` and `init.data`\n' + + ' HASHCU // `init.data` hash\n' + + ' SWAP\n' + + ' HASHCU // `init.code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `init.data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `init.code` depth\n' + + '\n' + + ' // Group 2: Calculating destination address\n' + + ' // For almost identical logic and instructions,\n' + + ' // see comments inside `contractHash()` function in contract.tact\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + ' NEWC\n' + + ' 24 STU\n' + + ' 16 STU\n' + + ' 16 STU\n' + + ' 256 STU\n' + + ' 256 STU\n' + + ' ONE HASHEXT_SHA256 // obtains hash part (account id) of the address\n' + + ' // → Stack state\n' + + ' // s0: destAddr(hash part)\n' + + ' // s1: `init.data`\n' + + ' // s2: `init.code`\n' + + ' // s3 and below: `bounce`, `value`, `body`, `mode`\n' + + '\n' + + ' // Group 3: Building a message (CommonMsgInfoRelaxed)\n' + + ' s3 XCHG0 // swaps `bounce` with destAddr(hash part)\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' s1 s2 XCHG // swap `init.data` with `init.code`, placing code on s1\n' + + ' STREF // store `init.code`\n' + + ' STREF // store `init.data`\n' + + ' // Inline StateInit:\n' + + ' b{00010000000000} STSLICECONST\n' + + ' // 0 + 00 + 10 + 0 + 00000000\n' + + ' // 1) 0 - bounced = false\n' + + ' // 2) 00 - src = addr_none\n' + + ' // 3) 10 - tag of addr_std (part of dest)\n' + + ' // 4) 0 - Maybe Anycast = false\n' + + ' // 5) 00000000 - workchain_id (part of dest)\n' + + ' //\n' + + ' 256 STU // store destAddr(hash part)\n' + + ' SWAP // Builder on top, `value` below\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + '\n' + + ' // Group 4: Continue building a message (CommonMsgInfoRelaxed into MessageRelaxed)\n' + + ' // Remaining bits of MessageRelaxed:\n' + + ' b{1000110} STSLICECONST\n' + + ' // 10 + 0 + 0 + 1 + 1 + 0\n' + + ' // 10 - Maybe (Either StateInit ^StateInit) = true false\n' + + ' // 0 - split_depth:(Maybe (## 5)) = false\n' + + ' // 0 = special:(Maybe TickTock) = false\n' + + ' // 1 = code:(Maybe ^Cell) = true\n' + + ' // 1 = data:(Maybe ^Cell) = true\n' + + ' // 0 = library:(Maybe ^Cell) = false\n' + + ' //\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC // finalize the message\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: params.`mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 11788, end: 14770 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'cashback', + loc: { start: 15971, end: 15979 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'to', + loc: { start: 15980, end: 15982 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 15984, end: 15991 } + }, + typeArgs: [], + loc: { start: 15984, end: 15991 } + }, + loc: { start: 15980, end: 15991 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '16 PUSHINT // 0x10, i.e. 0x18 but with bounce = false\n' + + ' NEWC\n' + + ' 6 STU // .storeUint(0x10, 6)\n' + + ' STSLICE // .storeAddress(to)\n' + + ' 0 PUSHINT // 0\n' + + ' 111 STUR // .storeUint(0, 111)\n' + + ' // 4 zeros for coins and 107 zeros for lt, fees, etc.\n' + + ' ENDC\n' + + ' 66 PUSHINT // SendRemainingValue | SendIgnoreErrors\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 15963, end: 16385 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeSendMessage', + loc: { start: 16936, end: 16953 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 16954, end: 16957 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 16959, end: 16963 } + }, + loc: { start: 16959, end: 16963 } + }, + loc: { start: 16954, end: 16963 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 16965, end: 16969 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 16971, end: 16974 } + }, + loc: { start: 16971, end: 16974 } + }, + loc: { start: 16965, end: 16974 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDRAWMSG' ] + }, + loc: { start: 16928, end: 16990 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sendRawMessage', + loc: { start: 17751, end: 17765 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 17766, end: 17769 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 17771, end: 17775 } + }, + loc: { start: 17771, end: 17775 } + }, + loc: { start: 17766, end: 17775 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 17777, end: 17781 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 17783, end: 17786 } + }, + loc: { start: 17783, end: 17786 } + }, + loc: { start: 17777, end: 17786 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDRAWMSG' ] + }, + loc: { start: 17743, end: 17802 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeSendMessageReturnForwardFee', + loc: { start: 19063, end: 19096 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 19120, end: 19123 } + }, + loc: { start: 19120, end: 19123 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 19097, end: 19100 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 19102, end: 19106 } + }, + loc: { start: 19102, end: 19106 } + }, + loc: { start: 19097, end: 19106 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 19108, end: 19112 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 19114, end: 19117 } + }, + loc: { start: 19114, end: 19117 } + }, + loc: { start: 19108, end: 19117 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDMSG' ] + }, + loc: { start: 19055, end: 19135 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sendMessageReturnForwardFee', + loc: { start: 20186, end: 20213 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 20237, end: 20240 } + }, + loc: { start: 20237, end: 20240 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 20214, end: 20217 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 20219, end: 20223 } + }, + loc: { start: 20219, end: 20223 } + }, + loc: { start: 20214, end: 20223 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 20225, end: 20229 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 20231, end: 20234 } + }, + loc: { start: 20231, end: 20234 } + }, + loc: { start: 20225, end: 20234 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDMSG' ] + }, + loc: { start: 20178, end: 20252 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'emit', + loc: { start: 21033, end: 21037 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'body', + loc: { start: 21038, end: 21042 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 21044, end: 21048 } + }, + loc: { start: 21044, end: 21048 } + }, + loc: { start: 21038, end: 21048 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'c', + loc: { start: 21233, end: 21234 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 21236, end: 21240 } + }, + loc: { start: 21236, end: 21240 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'static_call', + function: { + kind: 'id', + text: 'beginCell', + loc: { start: 21243, end: 21252 } + }, + typeArgs: [], + args: [], + loc: { start: 21243, end: 21254 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 21264, end: 21273 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 15211807202738752817960438464513n, + loc: { start: 21274, end: 21306 } + }, + { + kind: 'number', + base: '10', + value: 104n, + loc: { start: 21308, end: 21311 } + } + ], + loc: { start: 21243, end: 21312 } + }, + method: { + kind: 'id', + text: 'storeRef', + loc: { start: 21322, end: 21330 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'body', + loc: { start: 21331, end: 21335 } + } + ], + loc: { start: 21243, end: 21336 } + }, + method: { + kind: 'id', + text: 'endCell', + loc: { start: 21346, end: 21353 } + }, + typeArgs: [], + args: [], + loc: { start: 21243, end: 21355 } + }, + loc: { start: 21229, end: 21356 } + }, + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'sendRawMessage', + loc: { start: 21361, end: 21375 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'c', + loc: { start: 21376, end: 21377 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 21379, end: 21380 } + } + ], + loc: { start: 21361, end: 21381 } + }, + loc: { start: 21361, end: 21382 } + } + ] + }, + loc: { start: 21022, end: 21384 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'acceptMessage', + loc: { start: 22124, end: 22137 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ACCEPT' ] + }, + loc: { start: 22116, end: 22150 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'commit', + loc: { start: 22638, end: 22644 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'COMMIT' ] + }, + loc: { start: 22630, end: 22657 } + } + ] + }, + 'emit' => { + kind: 'tact', + path: 'std/internal/send.tact', + code: '/// Ordinary message (default).\n' + + '///\n' + + '/// This constant is available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendDefaultMode: Int = 0;\n' + + '\n' + + '/// Carry all the remaining value of the inbound message in addition\n' + + '/// to the value initially indicated in the new message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendRemainingValue: Int = 64;\n' + + '\n' + + '/// Carry **all the remaining balance** of the current smart contract instead\n' + + '/// of the value originally indicated in the message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendRemainingBalance: Int = 128;\n' + + '\n' + + "/// Doesn't send the message, only estimates the forward fees\n" + + '/// if the message-sending function computes those.\n' + + '///\n' + + '/// This constant is available since Tact 1.5.0.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '/// * https://docs.tact-lang.org/book/send#message-sending-functions\n' + + '///\n' + + 'const SendOnlyEstimateFee: Int = 1024;\n' + + '\n' + + '/// **Deprecated** since Tact 1.6.5.\n' + + '///\n' + + '/// Pay forward fees separately from the message value.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendPayGasSeparately: Int = 1;\n' + + '\n' + + '/// Pay forward fees separately from the message value.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendPayFwdFeesSeparately: Int = 1;\n' + + '\n' + + '/// Ignore any errors arising while processing this message during the action phase.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendIgnoreErrors: Int = 2;\n' + + '\n' + + '/// Bounce transaction in case of any errors during action phase.\n' + + '/// Has no effect if flag +2, `SendIgnoreErrors` is used.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendBounceIfActionFail: Int = 16;\n' + + '\n' + + '/// Current account (contract) will be destroyed if its resulting balance is zero.\n' + + '/// This flag is often used with mode 128, `SendRemainingBalance`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendDestroyIfZero: Int = 32;\n' + + '\n' + + '/// Struct for specifying the message parameters of the `send()` function.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#send\n' + + '///\n' + + 'struct SendParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// Optional initial code of the contract (compiled bitcode).\n' + + ' code: Cell? = null;\n' + + '\n' + + ' /// Optional initial data of the contract (arguments of `init()` function or values of contract parameters).\n' + + ' data: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// Recipient internal `Address` on TON Blockchain.\n' + + ' to: Address;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '}\n' + + '\n' + + '/// Struct for specifying the message parameters of the `message()` function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#message\n' + + '///\n' + + 'struct MessageParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// Recipient internal `Address` on TON Blockchain.\n' + + ' to: Address;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Queues the message to be sent using the `MessageParameters` struct. Allows for cheaper non-deployment, regular messages compared to the `send()` function.\n' + + '///\n' + + '/// The `MessageParameters` struct is similar to `SendParameters` struct, but without the `code` and `data` fields.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// message(MessageParameters{\n' + + '/// to: sender(), // back to the sender,\n' + + '/// value: ton("1"), // with 1 Toncoin (1_000_000_000 nanoToncoin),\n' + + '/// // and no message body\n' + + '/// });\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 33: [Action list is too long] — Thrown when attempting to queue more than 255 messages.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-send#message\n' + + '/// * https://docs.tact-lang.org/book/message-mode\n' + + '///\n' + + '/// [Action list is too long]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '///\n' + + 'asm fun message(params: MessageParameters) {\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 106 PUSHINT // 1 + 4 + 4 + 64 + 32 + 1\n' + + ' STZEROES\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + ' STDICT\n' + + ' ENDC\n' + + ' SWAP\n' + + ' SENDRAWMSG\n' + + '}\n' + + '\n' + + '/// Global function. Queues the message to be sent using a `SendParameters` Struct.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// send(SendParameters{\n' + + '/// to: sender(), // back to the sender,\n' + + '/// value: ton("1"), // with 1 Toncoin (1_000_000_000 nanoToncoin),\n' + + '/// // and no message body\n' + + '/// });\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 33: [Action list is too long] — Thrown when attempting to queue more than 255 messages.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#send\n' + + '///\n' + + '/// [Action list is too long]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '///\n' + + 'asm fun send(params: SendParameters) {\n' + + ' // Instructions are grouped, and the stack states they produce as a group are shown right after.\n' + + ' // In the end, our message Cell should have the following TL-B structure:\n' + + ' // message$_ {X:Type}\n' + + ' // info:CommonMsgInfoRelaxed\n' + + ' // init:(Maybe (Either StateInit ^StateInit))\n' + + ' // body:(Either X ^X)\n' + + ' // = MessageRelaxed X;\n' + + '\n' + + ' // → Stack state\n' + + ' // s0: `params.bounce`\n' + + ' // s1: `params.to`\n' + + ' // s2: `params.value`\n' + + ' // s3: `params.data`\n' + + ' // s4: `params.code`\n' + + ' // s5: `params.body`\n' + + ' // s6: `params.mode`\n' + + ' // For brevity, the "params" prefix will be omitted from now on.\n' + + '\n' + + ' // Group 1: Storing the `bounce`, `to` and `value` into a Builder\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + '\n' + + ' // Group 2: Placing the Builder after code and data, then checking those for nullability\n' + + ' s2 XCHG0\n' + + ' DUP2\n' + + ' ISNULL\n' + + ' SWAP\n' + + ' ISNULL\n' + + ' AND\n' + + ' // → Stack state\n' + + ' // s0: -1 (true) if `data` and `code` are both null, 0 (false) otherwise\n' + + ' // s1: `code`\n' + + ' // s2: `data`\n' + + ' // s3: Builder\n' + + ' // s4: `body`\n' + + ' // s5: `mode`\n' + + '\n' + + ' // Group 3: Left branch of the IFELSE, executed if s0 is -1 (true)\n' + + ' <{\n' + + ' DROP2 // drop `data` and `code`, since either of those is null\n' + + ' b{0} STSLICECONST\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: Right branch of the IFELSE, executed if s0 is 0 (false)\n' + + ' <{\n' + + ' // _ split_depth:(Maybe (## 5))\n' + + ' // special:(Maybe TickTock)\n' + + ' // code:(Maybe ^Cell)\n' + + ' // data:(Maybe ^Cell)\n' + + ' // library:(Maybe ^Cell)\n' + + ' // = StateInit;\n' + + ' ROT // place message Builder on top\n' + + ' b{10} STSLICECONST // store Maybe = true, Either = false\n' + + ' // Start composing inlined StateInit\n' + + ' b{00} STSLICECONST // store split_depth and special first\n' + + ' STDICT // store code\n' + + ' STDICT // store data\n' + + ' b{0} STSLICECONST // store library\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: IFELSE that does the branching shown above\n' + + ' IFELSE\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: null or StateInit\n' + + ' // s2: `body`\n' + + ' // s3: `mode`\n' + + '\n' + + ' // Group 4: Finalizing the message\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: `mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG // https://github.com/tact-lang/tact/issues/1558\n' + + '}\n' + + '\n' + + '/// Struct for specifying the deployment message parameters of the `deploy()` function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#deploy\n' + + '///\n' + + 'struct DeployParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '\n' + + ' //'... 12658 more characters, + imports: [], + items: [ + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendDefaultMode', + loc: { start: 164, end: 179 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 181, end: 184 } + }, + loc: { start: 181, end: 184 } + }, + initializer: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 187, end: 188 } + } + }, + loc: { start: 158, end: 189 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendRemainingValue', + loc: { start: 396, end: 414 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 416, end: 419 } + }, + loc: { start: 416, end: 419 } + }, + initializer: { + kind: 'number', + base: '10', + value: 64n, + loc: { start: 422, end: 424 } + } + }, + loc: { start: 390, end: 425 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendRemainingBalance', + loc: { start: 638, end: 658 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 660, end: 663 } + }, + loc: { start: 660, end: 663 } + }, + initializer: { + kind: 'number', + base: '10', + value: 128n, + loc: { start: 666, end: 669 } + } + }, + loc: { start: 632, end: 670 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendOnlyEstimateFee', + loc: { start: 993, end: 1012 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1014, end: 1017 } + }, + loc: { start: 1014, end: 1017 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1024n, + loc: { start: 1020, end: 1024 } + } + }, + loc: { start: 987, end: 1025 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendPayGasSeparately', + loc: { start: 1207, end: 1227 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1229, end: 1232 } + }, + loc: { start: 1229, end: 1232 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1235, end: 1236 } + } + }, + loc: { start: 1201, end: 1237 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendPayFwdFeesSeparately', + loc: { start: 1378, end: 1402 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1404, end: 1407 } + }, + loc: { start: 1404, end: 1407 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1410, end: 1411 } + } + }, + loc: { start: 1372, end: 1412 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendIgnoreErrors', + loc: { start: 1582, end: 1598 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1600, end: 1603 } + }, + loc: { start: 1600, end: 1603 } + }, + initializer: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 1606, end: 1607 } + } + }, + loc: { start: 1576, end: 1608 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendBounceIfActionFail', + loc: { start: 1817, end: 1839 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1841, end: 1844 } + }, + loc: { start: 1841, end: 1844 } + }, + initializer: { + kind: 'number', + base: '10', + value: 16n, + loc: { start: 1847, end: 1849 } + } + }, + loc: { start: 1811, end: 1850 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendDestroyIfZero', + loc: { start: 2085, end: 2102 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2104, end: 2107 } + }, + loc: { start: 2104, end: 2107 } + }, + initializer: { + kind: 'number', + base: '10', + value: 32n, + loc: { start: 2110, end: 2112 } + } + }, + loc: { start: 2079, end: 2113 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'SendParameters', + loc: { start: 2260, end: 2274 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 2416, end: 2420 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2422, end: 2425 } + }, + loc: { start: 2422, end: 2425 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 2428, end: 2443 } + }, + loc: { start: 2416, end: 2443 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 2493, end: 2497 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2503, end: 2504 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2499, end: 2503 } + }, + loc: { start: 2499, end: 2503 } + } + ], + loc: { start: 2503, end: 2504 } + }, + initializer: { kind: 'null', loc: { start: 2507, end: 2511 } }, + loc: { start: 2493, end: 2511 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'code', + loc: { start: 2584, end: 2588 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2594, end: 2595 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2590, end: 2594 } + }, + loc: { start: 2590, end: 2594 } + } + ], + loc: { start: 2594, end: 2595 } + }, + initializer: { kind: 'null', loc: { start: 2598, end: 2602 } }, + loc: { start: 2584, end: 2602 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'data', + loc: { start: 2722, end: 2726 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2732, end: 2733 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2728, end: 2732 } + }, + loc: { start: 2728, end: 2732 } + } + ], + loc: { start: 2732, end: 2733 } + }, + initializer: { kind: 'null', loc: { start: 2736, end: 2740 } }, + loc: { start: 2722, end: 2740 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 2936, end: 2941 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2943, end: 2946 } + }, + loc: { start: 2943, end: 2946 } + }, + initializer: undefined, + loc: { start: 2936, end: 2946 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'to', + loc: { start: 3009, end: 3011 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3013, end: 3020 } + }, + typeArgs: [], + loc: { start: 3013, end: 3020 } + }, + initializer: undefined, + loc: { start: 3009, end: 3020 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 3186, end: 3192 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 3194, end: 3198 } + }, + typeArgs: [], + loc: { start: 3194, end: 3198 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 3201, end: 3205 } + }, + loc: { start: 3186, end: 3205 } + } + ], + loc: { start: 2253, end: 3208 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'MessageParameters', + loc: { start: 3389, end: 3406 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 3548, end: 3552 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3554, end: 3557 } + }, + loc: { start: 3554, end: 3557 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 3560, end: 3575 } + }, + loc: { start: 3548, end: 3575 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 3625, end: 3629 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 3635, end: 3636 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 3631, end: 3635 } + }, + loc: { start: 3631, end: 3635 } + } + ], + loc: { start: 3635, end: 3636 } + }, + initializer: { kind: 'null', loc: { start: 3639, end: 3643 } }, + loc: { start: 3625, end: 3643 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 3839, end: 3844 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3846, end: 3849 } + }, + loc: { start: 3846, end: 3849 } + }, + initializer: undefined, + loc: { start: 3839, end: 3849 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'to', + loc: { start: 3912, end: 3914 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3916, end: 3923 } + }, + typeArgs: [], + loc: { start: 3916, end: 3923 } + }, + initializer: undefined, + loc: { start: 3912, end: 3923 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 4089, end: 4095 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 4097, end: 4101 } + }, + typeArgs: [], + loc: { start: 4097, end: 4101 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 4104, end: 4108 } + }, + loc: { start: 4089, end: 4108 } + } + ], + loc: { start: 3382, end: 4111 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'message', + loc: { start: 5056, end: 5063 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 5064, end: 5070 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'MessageParameters', + loc: { start: 5072, end: 5089 } + }, + typeArgs: [], + loc: { start: 5072, end: 5089 } + }, + loc: { start: 5064, end: 5089 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 106 PUSHINT // 1 + 4 + 4 + 64 + 32 + 1\n' + + ' STZEROES\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + ' STDICT\n' + + ' ENDC\n' + + ' SWAP\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 5048, end: 5588 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'send', loc: { start: 6219, end: 6223 } }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 6224, end: 6230 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'SendParameters', + loc: { start: 6232, end: 6246 } + }, + typeArgs: [], + loc: { start: 6232, end: 6246 } + }, + loc: { start: 6224, end: 6246 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + '\n' + + ' // Group 2: Placing the Builder after code and data, then checking those for nullability\n' + + ' s2 XCHG0\n' + + ' DUP2\n' + + ' ISNULL\n' + + ' SWAP\n' + + ' ISNULL\n' + + ' AND\n' + + ' // → Stack state\n' + + ' // s0: -1 (true) if `data` and `code` are both null, 0 (false) otherwise\n' + + ' // s1: `code`\n' + + ' // s2: `data`\n' + + ' // s3: Builder\n' + + ' // s4: `body`\n' + + ' // s5: `mode`\n' + + '\n' + + ' // Group 3: Left branch of the IFELSE, executed if s0 is -1 (true)\n' + + ' <{\n' + + ' DROP2 // drop `data` and `code`, since either of those is null\n' + + ' b{0} STSLICECONST\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: Right branch of the IFELSE, executed if s0 is 0 (false)\n' + + ' <{\n' + + ' // _ split_depth:(Maybe (## 5))\n' + + ' // special:(Maybe TickTock)\n' + + ' // code:(Maybe ^Cell)\n' + + ' // data:(Maybe ^Cell)\n' + + ' // library:(Maybe ^Cell)\n' + + ' // = StateInit;\n' + + ' ROT // place message Builder on top\n' + + ' b{10} STSLICECONST // store Maybe = true, Either = false\n' + + ' // Start composing inlined StateInit\n' + + ' b{00} STSLICECONST // store split_depth and special first\n' + + ' STDICT // store code\n' + + ' STDICT // store data\n' + + ' b{0} STSLICECONST // store library\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: IFELSE that does the branching shown above\n' + + ' IFELSE\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: null or StateInit\n' + + ' // s2: `body`\n' + + ' // s3: `mode`\n' + + '\n' + + ' // Group 4: Finalizing the message\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: `mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG // https://github.com/tact-lang/tact/issues/1558' + ] + }, + loc: { start: 6211, end: 9157 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'DeployParameters', + loc: { start: 9347, end: 9363 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 9505, end: 9509 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9511, end: 9514 } + }, + loc: { start: 9511, end: 9514 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 9517, end: 9532 } + }, + loc: { start: 9505, end: 9532 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 9582, end: 9586 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 9592, end: 9593 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 9588, end: 9592 } + }, + loc: { start: 9588, end: 9592 } + } + ], + loc: { start: 9592, end: 9593 } + }, + initializer: { kind: 'null', loc: { start: 9596, end: 9600 } }, + loc: { start: 9582, end: 9600 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 9796, end: 9801 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9803, end: 9806 } + }, + loc: { start: 9803, end: 9806 } + }, + initializer: undefined, + loc: { start: 9796, end: 9806 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 9972, end: 9978 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 9980, end: 9984 } + }, + typeArgs: [], + loc: { start: 9980, end: 9984 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 9987, end: 9991 } + }, + loc: { start: 9972, end: 9991 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'init', + loc: { start: 10135, end: 10139 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 10141, end: 10150 } + }, + typeArgs: [], + loc: { start: 10141, end: 10150 } + }, + initializer: undefined, + loc: { start: 10135, end: 10150 } + } + ], + loc: { start: 9340, end: 10153 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'deploy', + loc: { start: 11796, end: 11802 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 11803, end: 11809 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'DeployParameters', + loc: { start: 11811, end: 11827 } + }, + typeArgs: [], + loc: { start: 11811, end: 11827 } + }, + loc: { start: 11803, end: 11827 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '4 1 BLKPUSH // pushes 2 copies of `init.code` and `init.data`\n' + + ' HASHCU // `init.data` hash\n' + + ' SWAP\n' + + ' HASHCU // `init.code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `init.data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `init.code` depth\n' + + '\n' + + ' // Group 2: Calculating destination address\n' + + ' // For almost identical logic and instructions,\n' + + ' // see comments inside `contractHash()` function in contract.tact\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + ' NEWC\n' + + ' 24 STU\n' + + ' 16 STU\n' + + ' 16 STU\n' + + ' 256 STU\n' + + ' 256 STU\n' + + ' ONE HASHEXT_SHA256 // obtains hash part (account id) of the address\n' + + ' // → Stack state\n' + + ' // s0: destAddr(hash part)\n' + + ' // s1: `init.data`\n' + + ' // s2: `init.code`\n' + + ' // s3 and below: `bounce`, `value`, `body`, `mode`\n' + + '\n' + + ' // Group 3: Building a message (CommonMsgInfoRelaxed)\n' + + ' s3 XCHG0 // swaps `bounce` with destAddr(hash part)\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' s1 s2 XCHG // swap `init.data` with `init.code`, placing code on s1\n' + + ' STREF // store `init.code`\n' + + ' STREF // store `init.data`\n' + + ' // Inline StateInit:\n' + + ' b{00010000000000} STSLICECONST\n' + + ' // 0 + 00 + 10 + 0 + 00000000\n' + + ' // 1) 0 - bounced = false\n' + + ' // 2) 00 - src = addr_none\n' + + ' // 3) 10 - tag of addr_std (part of dest)\n' + + ' // 4) 0 - Maybe Anycast = false\n' + + ' // 5) 00000000 - workchain_id (part of dest)\n' + + ' //\n' + + ' 256 STU // store destAddr(hash part)\n' + + ' SWAP // Builder on top, `value` below\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + '\n' + + ' // Group 4: Continue building a message (CommonMsgInfoRelaxed into MessageRelaxed)\n' + + ' // Remaining bits of MessageRelaxed:\n' + + ' b{1000110} STSLICECONST\n' + + ' // 10 + 0 + 0 + 1 + 1 + 0\n' + + ' // 10 - Maybe (Either StateInit ^StateInit) = true false\n' + + ' // 0 - split_depth:(Maybe (## 5)) = false\n' + + ' // 0 = special:(Maybe TickTock) = false\n' + + ' // 1 = code:(Maybe ^Cell) = true\n' + + ' // 1 = data:(Maybe ^Cell) = true\n' + + ' // 0 = library:(Maybe ^Cell) = false\n' + + ' //\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC // finalize the message\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: params.`mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 11788, end: 14770 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'cashback', + loc: { start: 15971, end: 15979 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'to', + loc: { start: 15980, end: 15982 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 15984, end: 15991 } + }, + typeArgs: [], + loc: { start: 15984, end: 15991 } + }, + loc: { start: 15980, end: 15991 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '16 PUSHINT // 0x10, i.e. 0x18 but with bounce = false\n' + + ' NEWC\n' + + ' 6 STU // .storeUint(0x10, 6)\n' + + ' STSLICE // .storeAddress(to)\n' + + ' 0 PUSHINT // 0\n' + + ' 111 STUR // .storeUint(0, 111)\n' + + ' // 4 zeros for coins and 107 zeros for lt, fees, etc.\n' + + ' ENDC\n' + + ' 66 PUSHINT // SendRemainingValue | SendIgnoreErrors\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 15963, end: 16385 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeSendMessage', + loc: { start: 16936, end: 16953 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 16954, end: 16957 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 16959, end: 16963 } + }, + loc: { start: 16959, end: 16963 } + }, + loc: { start: 16954, end: 16963 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 16965, end: 16969 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 16971, end: 16974 } + }, + loc: { start: 16971, end: 16974 } + }, + loc: { start: 16965, end: 16974 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDRAWMSG' ] + }, + loc: { start: 16928, end: 16990 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sendRawMessage', + loc: { start: 17751, end: 17765 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 17766, end: 17769 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 17771, end: 17775 } + }, + loc: { start: 17771, end: 17775 } + }, + loc: { start: 17766, end: 17775 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 17777, end: 17781 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 17783, end: 17786 } + }, + loc: { start: 17783, end: 17786 } + }, + loc: { start: 17777, end: 17786 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDRAWMSG' ] + }, + loc: { start: 17743, end: 17802 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeSendMessageReturnForwardFee', + loc: { start: 19063, end: 19096 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 19120, end: 19123 } + }, + loc: { start: 19120, end: 19123 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 19097, end: 19100 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 19102, end: 19106 } + }, + loc: { start: 19102, end: 19106 } + }, + loc: { start: 19097, end: 19106 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 19108, end: 19112 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 19114, end: 19117 } + }, + loc: { start: 19114, end: 19117 } + }, + loc: { start: 19108, end: 19117 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDMSG' ] + }, + loc: { start: 19055, end: 19135 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sendMessageReturnForwardFee', + loc: { start: 20186, end: 20213 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 20237, end: 20240 } + }, + loc: { start: 20237, end: 20240 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 20214, end: 20217 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 20219, end: 20223 } + }, + loc: { start: 20219, end: 20223 } + }, + loc: { start: 20214, end: 20223 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 20225, end: 20229 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 20231, end: 20234 } + }, + loc: { start: 20231, end: 20234 } + }, + loc: { start: 20225, end: 20234 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDMSG' ] + }, + loc: { start: 20178, end: 20252 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'emit', + loc: { start: 21033, end: 21037 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'body', + loc: { start: 21038, end: 21042 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 21044, end: 21048 } + }, + loc: { start: 21044, end: 21048 } + }, + loc: { start: 21038, end: 21048 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'c', + loc: { start: 21233, end: 21234 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 21236, end: 21240 } + }, + loc: { start: 21236, end: 21240 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'static_call', + function: { + kind: 'id', + text: 'beginCell', + loc: { start: 21243, end: 21252 } + }, + typeArgs: [], + args: [], + loc: { start: 21243, end: 21254 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 21264, end: 21273 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 15211807202738752817960438464513n, + loc: { start: 21274, end: 21306 } + }, + { + kind: 'number', + base: '10', + value: 104n, + loc: { start: 21308, end: 21311 } + } + ], + loc: { start: 21243, end: 21312 } + }, + method: { + kind: 'id', + text: 'storeRef', + loc: { start: 21322, end: 21330 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'body', + loc: { start: 21331, end: 21335 } + } + ], + loc: { start: 21243, end: 21336 } + }, + method: { + kind: 'id', + text: 'endCell', + loc: { start: 21346, end: 21353 } + }, + typeArgs: [], + args: [], + loc: { start: 21243, end: 21355 } + }, + loc: { start: 21229, end: 21356 } + }, + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'sendRawMessage', + loc: { start: 21361, end: 21375 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'c', + loc: { start: 21376, end: 21377 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 21379, end: 21380 } + } + ], + loc: { start: 21361, end: 21381 } + }, + loc: { start: 21361, end: 21382 } + } + ] + }, + loc: { start: 21022, end: 21384 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'acceptMessage', + loc: { start: 22124, end: 22137 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ACCEPT' ] + }, + loc: { start: 22116, end: 22150 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'commit', + loc: { start: 22638, end: 22644 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'COMMIT' ] + }, + loc: { start: 22630, end: 22657 } + } + ] + }, + 'acceptMessage' => { + kind: 'tact', + path: 'std/internal/send.tact', + code: '/// Ordinary message (default).\n' + + '///\n' + + '/// This constant is available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendDefaultMode: Int = 0;\n' + + '\n' + + '/// Carry all the remaining value of the inbound message in addition\n' + + '/// to the value initially indicated in the new message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendRemainingValue: Int = 64;\n' + + '\n' + + '/// Carry **all the remaining balance** of the current smart contract instead\n' + + '/// of the value originally indicated in the message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendRemainingBalance: Int = 128;\n' + + '\n' + + "/// Doesn't send the message, only estimates the forward fees\n" + + '/// if the message-sending function computes those.\n' + + '///\n' + + '/// This constant is available since Tact 1.5.0.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '/// * https://docs.tact-lang.org/book/send#message-sending-functions\n' + + '///\n' + + 'const SendOnlyEstimateFee: Int = 1024;\n' + + '\n' + + '/// **Deprecated** since Tact 1.6.5.\n' + + '///\n' + + '/// Pay forward fees separately from the message value.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendPayGasSeparately: Int = 1;\n' + + '\n' + + '/// Pay forward fees separately from the message value.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendPayFwdFeesSeparately: Int = 1;\n' + + '\n' + + '/// Ignore any errors arising while processing this message during the action phase.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendIgnoreErrors: Int = 2;\n' + + '\n' + + '/// Bounce transaction in case of any errors during action phase.\n' + + '/// Has no effect if flag +2, `SendIgnoreErrors` is used.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendBounceIfActionFail: Int = 16;\n' + + '\n' + + '/// Current account (contract) will be destroyed if its resulting balance is zero.\n' + + '/// This flag is often used with mode 128, `SendRemainingBalance`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendDestroyIfZero: Int = 32;\n' + + '\n' + + '/// Struct for specifying the message parameters of the `send()` function.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#send\n' + + '///\n' + + 'struct SendParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// Optional initial code of the contract (compiled bitcode).\n' + + ' code: Cell? = null;\n' + + '\n' + + ' /// Optional initial data of the contract (arguments of `init()` function or values of contract parameters).\n' + + ' data: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// Recipient internal `Address` on TON Blockchain.\n' + + ' to: Address;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '}\n' + + '\n' + + '/// Struct for specifying the message parameters of the `message()` function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#message\n' + + '///\n' + + 'struct MessageParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// Recipient internal `Address` on TON Blockchain.\n' + + ' to: Address;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Queues the message to be sent using the `MessageParameters` struct. Allows for cheaper non-deployment, regular messages compared to the `send()` function.\n' + + '///\n' + + '/// The `MessageParameters` struct is similar to `SendParameters` struct, but without the `code` and `data` fields.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// message(MessageParameters{\n' + + '/// to: sender(), // back to the sender,\n' + + '/// value: ton("1"), // with 1 Toncoin (1_000_000_000 nanoToncoin),\n' + + '/// // and no message body\n' + + '/// });\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 33: [Action list is too long] — Thrown when attempting to queue more than 255 messages.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-send#message\n' + + '/// * https://docs.tact-lang.org/book/message-mode\n' + + '///\n' + + '/// [Action list is too long]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '///\n' + + 'asm fun message(params: MessageParameters) {\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 106 PUSHINT // 1 + 4 + 4 + 64 + 32 + 1\n' + + ' STZEROES\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + ' STDICT\n' + + ' ENDC\n' + + ' SWAP\n' + + ' SENDRAWMSG\n' + + '}\n' + + '\n' + + '/// Global function. Queues the message to be sent using a `SendParameters` Struct.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// send(SendParameters{\n' + + '/// to: sender(), // back to the sender,\n' + + '/// value: ton("1"), // with 1 Toncoin (1_000_000_000 nanoToncoin),\n' + + '/// // and no message body\n' + + '/// });\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 33: [Action list is too long] — Thrown when attempting to queue more than 255 messages.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#send\n' + + '///\n' + + '/// [Action list is too long]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '///\n' + + 'asm fun send(params: SendParameters) {\n' + + ' // Instructions are grouped, and the stack states they produce as a group are shown right after.\n' + + ' // In the end, our message Cell should have the following TL-B structure:\n' + + ' // message$_ {X:Type}\n' + + ' // info:CommonMsgInfoRelaxed\n' + + ' // init:(Maybe (Either StateInit ^StateInit))\n' + + ' // body:(Either X ^X)\n' + + ' // = MessageRelaxed X;\n' + + '\n' + + ' // → Stack state\n' + + ' // s0: `params.bounce`\n' + + ' // s1: `params.to`\n' + + ' // s2: `params.value`\n' + + ' // s3: `params.data`\n' + + ' // s4: `params.code`\n' + + ' // s5: `params.body`\n' + + ' // s6: `params.mode`\n' + + ' // For brevity, the "params" prefix will be omitted from now on.\n' + + '\n' + + ' // Group 1: Storing the `bounce`, `to` and `value` into a Builder\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + '\n' + + ' // Group 2: Placing the Builder after code and data, then checking those for nullability\n' + + ' s2 XCHG0\n' + + ' DUP2\n' + + ' ISNULL\n' + + ' SWAP\n' + + ' ISNULL\n' + + ' AND\n' + + ' // → Stack state\n' + + ' // s0: -1 (true) if `data` and `code` are both null, 0 (false) otherwise\n' + + ' // s1: `code`\n' + + ' // s2: `data`\n' + + ' // s3: Builder\n' + + ' // s4: `body`\n' + + ' // s5: `mode`\n' + + '\n' + + ' // Group 3: Left branch of the IFELSE, executed if s0 is -1 (true)\n' + + ' <{\n' + + ' DROP2 // drop `data` and `code`, since either of those is null\n' + + ' b{0} STSLICECONST\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: Right branch of the IFELSE, executed if s0 is 0 (false)\n' + + ' <{\n' + + ' // _ split_depth:(Maybe (## 5))\n' + + ' // special:(Maybe TickTock)\n' + + ' // code:(Maybe ^Cell)\n' + + ' // data:(Maybe ^Cell)\n' + + ' // library:(Maybe ^Cell)\n' + + ' // = StateInit;\n' + + ' ROT // place message Builder on top\n' + + ' b{10} STSLICECONST // store Maybe = true, Either = false\n' + + ' // Start composing inlined StateInit\n' + + ' b{00} STSLICECONST // store split_depth and special first\n' + + ' STDICT // store code\n' + + ' STDICT // store data\n' + + ' b{0} STSLICECONST // store library\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: IFELSE that does the branching shown above\n' + + ' IFELSE\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: null or StateInit\n' + + ' // s2: `body`\n' + + ' // s3: `mode`\n' + + '\n' + + ' // Group 4: Finalizing the message\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: `mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG // https://github.com/tact-lang/tact/issues/1558\n' + + '}\n' + + '\n' + + '/// Struct for specifying the deployment message parameters of the `deploy()` function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#deploy\n' + + '///\n' + + 'struct DeployParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '\n' + + ' //'... 12658 more characters, + imports: [], + items: [ + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendDefaultMode', + loc: { start: 164, end: 179 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 181, end: 184 } + }, + loc: { start: 181, end: 184 } + }, + initializer: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 187, end: 188 } + } + }, + loc: { start: 158, end: 189 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendRemainingValue', + loc: { start: 396, end: 414 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 416, end: 419 } + }, + loc: { start: 416, end: 419 } + }, + initializer: { + kind: 'number', + base: '10', + value: 64n, + loc: { start: 422, end: 424 } + } + }, + loc: { start: 390, end: 425 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendRemainingBalance', + loc: { start: 638, end: 658 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 660, end: 663 } + }, + loc: { start: 660, end: 663 } + }, + initializer: { + kind: 'number', + base: '10', + value: 128n, + loc: { start: 666, end: 669 } + } + }, + loc: { start: 632, end: 670 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendOnlyEstimateFee', + loc: { start: 993, end: 1012 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1014, end: 1017 } + }, + loc: { start: 1014, end: 1017 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1024n, + loc: { start: 1020, end: 1024 } + } + }, + loc: { start: 987, end: 1025 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendPayGasSeparately', + loc: { start: 1207, end: 1227 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1229, end: 1232 } + }, + loc: { start: 1229, end: 1232 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1235, end: 1236 } + } + }, + loc: { start: 1201, end: 1237 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendPayFwdFeesSeparately', + loc: { start: 1378, end: 1402 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1404, end: 1407 } + }, + loc: { start: 1404, end: 1407 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1410, end: 1411 } + } + }, + loc: { start: 1372, end: 1412 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendIgnoreErrors', + loc: { start: 1582, end: 1598 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1600, end: 1603 } + }, + loc: { start: 1600, end: 1603 } + }, + initializer: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 1606, end: 1607 } + } + }, + loc: { start: 1576, end: 1608 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendBounceIfActionFail', + loc: { start: 1817, end: 1839 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1841, end: 1844 } + }, + loc: { start: 1841, end: 1844 } + }, + initializer: { + kind: 'number', + base: '10', + value: 16n, + loc: { start: 1847, end: 1849 } + } + }, + loc: { start: 1811, end: 1850 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendDestroyIfZero', + loc: { start: 2085, end: 2102 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2104, end: 2107 } + }, + loc: { start: 2104, end: 2107 } + }, + initializer: { + kind: 'number', + base: '10', + value: 32n, + loc: { start: 2110, end: 2112 } + } + }, + loc: { start: 2079, end: 2113 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'SendParameters', + loc: { start: 2260, end: 2274 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 2416, end: 2420 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2422, end: 2425 } + }, + loc: { start: 2422, end: 2425 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 2428, end: 2443 } + }, + loc: { start: 2416, end: 2443 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 2493, end: 2497 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2503, end: 2504 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2499, end: 2503 } + }, + loc: { start: 2499, end: 2503 } + } + ], + loc: { start: 2503, end: 2504 } + }, + initializer: { kind: 'null', loc: { start: 2507, end: 2511 } }, + loc: { start: 2493, end: 2511 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'code', + loc: { start: 2584, end: 2588 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2594, end: 2595 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2590, end: 2594 } + }, + loc: { start: 2590, end: 2594 } + } + ], + loc: { start: 2594, end: 2595 } + }, + initializer: { kind: 'null', loc: { start: 2598, end: 2602 } }, + loc: { start: 2584, end: 2602 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'data', + loc: { start: 2722, end: 2726 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2732, end: 2733 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2728, end: 2732 } + }, + loc: { start: 2728, end: 2732 } + } + ], + loc: { start: 2732, end: 2733 } + }, + initializer: { kind: 'null', loc: { start: 2736, end: 2740 } }, + loc: { start: 2722, end: 2740 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 2936, end: 2941 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2943, end: 2946 } + }, + loc: { start: 2943, end: 2946 } + }, + initializer: undefined, + loc: { start: 2936, end: 2946 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'to', + loc: { start: 3009, end: 3011 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3013, end: 3020 } + }, + typeArgs: [], + loc: { start: 3013, end: 3020 } + }, + initializer: undefined, + loc: { start: 3009, end: 3020 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 3186, end: 3192 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 3194, end: 3198 } + }, + typeArgs: [], + loc: { start: 3194, end: 3198 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 3201, end: 3205 } + }, + loc: { start: 3186, end: 3205 } + } + ], + loc: { start: 2253, end: 3208 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'MessageParameters', + loc: { start: 3389, end: 3406 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 3548, end: 3552 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3554, end: 3557 } + }, + loc: { start: 3554, end: 3557 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 3560, end: 3575 } + }, + loc: { start: 3548, end: 3575 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 3625, end: 3629 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 3635, end: 3636 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 3631, end: 3635 } + }, + loc: { start: 3631, end: 3635 } + } + ], + loc: { start: 3635, end: 3636 } + }, + initializer: { kind: 'null', loc: { start: 3639, end: 3643 } }, + loc: { start: 3625, end: 3643 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 3839, end: 3844 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3846, end: 3849 } + }, + loc: { start: 3846, end: 3849 } + }, + initializer: undefined, + loc: { start: 3839, end: 3849 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'to', + loc: { start: 3912, end: 3914 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3916, end: 3923 } + }, + typeArgs: [], + loc: { start: 3916, end: 3923 } + }, + initializer: undefined, + loc: { start: 3912, end: 3923 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 4089, end: 4095 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 4097, end: 4101 } + }, + typeArgs: [], + loc: { start: 4097, end: 4101 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 4104, end: 4108 } + }, + loc: { start: 4089, end: 4108 } + } + ], + loc: { start: 3382, end: 4111 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'message', + loc: { start: 5056, end: 5063 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 5064, end: 5070 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'MessageParameters', + loc: { start: 5072, end: 5089 } + }, + typeArgs: [], + loc: { start: 5072, end: 5089 } + }, + loc: { start: 5064, end: 5089 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 106 PUSHINT // 1 + 4 + 4 + 64 + 32 + 1\n' + + ' STZEROES\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + ' STDICT\n' + + ' ENDC\n' + + ' SWAP\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 5048, end: 5588 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'send', loc: { start: 6219, end: 6223 } }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 6224, end: 6230 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'SendParameters', + loc: { start: 6232, end: 6246 } + }, + typeArgs: [], + loc: { start: 6232, end: 6246 } + }, + loc: { start: 6224, end: 6246 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + '\n' + + ' // Group 2: Placing the Builder after code and data, then checking those for nullability\n' + + ' s2 XCHG0\n' + + ' DUP2\n' + + ' ISNULL\n' + + ' SWAP\n' + + ' ISNULL\n' + + ' AND\n' + + ' // → Stack state\n' + + ' // s0: -1 (true) if `data` and `code` are both null, 0 (false) otherwise\n' + + ' // s1: `code`\n' + + ' // s2: `data`\n' + + ' // s3: Builder\n' + + ' // s4: `body`\n' + + ' // s5: `mode`\n' + + '\n' + + ' // Group 3: Left branch of the IFELSE, executed if s0 is -1 (true)\n' + + ' <{\n' + + ' DROP2 // drop `data` and `code`, since either of those is null\n' + + ' b{0} STSLICECONST\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: Right branch of the IFELSE, executed if s0 is 0 (false)\n' + + ' <{\n' + + ' // _ split_depth:(Maybe (## 5))\n' + + ' // special:(Maybe TickTock)\n' + + ' // code:(Maybe ^Cell)\n' + + ' // data:(Maybe ^Cell)\n' + + ' // library:(Maybe ^Cell)\n' + + ' // = StateInit;\n' + + ' ROT // place message Builder on top\n' + + ' b{10} STSLICECONST // store Maybe = true, Either = false\n' + + ' // Start composing inlined StateInit\n' + + ' b{00} STSLICECONST // store split_depth and special first\n' + + ' STDICT // store code\n' + + ' STDICT // store data\n' + + ' b{0} STSLICECONST // store library\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: IFELSE that does the branching shown above\n' + + ' IFELSE\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: null or StateInit\n' + + ' // s2: `body`\n' + + ' // s3: `mode`\n' + + '\n' + + ' // Group 4: Finalizing the message\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: `mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG // https://github.com/tact-lang/tact/issues/1558' + ] + }, + loc: { start: 6211, end: 9157 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'DeployParameters', + loc: { start: 9347, end: 9363 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 9505, end: 9509 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9511, end: 9514 } + }, + loc: { start: 9511, end: 9514 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 9517, end: 9532 } + }, + loc: { start: 9505, end: 9532 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 9582, end: 9586 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 9592, end: 9593 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 9588, end: 9592 } + }, + loc: { start: 9588, end: 9592 } + } + ], + loc: { start: 9592, end: 9593 } + }, + initializer: { kind: 'null', loc: { start: 9596, end: 9600 } }, + loc: { start: 9582, end: 9600 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 9796, end: 9801 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9803, end: 9806 } + }, + loc: { start: 9803, end: 9806 } + }, + initializer: undefined, + loc: { start: 9796, end: 9806 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 9972, end: 9978 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 9980, end: 9984 } + }, + typeArgs: [], + loc: { start: 9980, end: 9984 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 9987, end: 9991 } + }, + loc: { start: 9972, end: 9991 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'init', + loc: { start: 10135, end: 10139 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 10141, end: 10150 } + }, + typeArgs: [], + loc: { start: 10141, end: 10150 } + }, + initializer: undefined, + loc: { start: 10135, end: 10150 } + } + ], + loc: { start: 9340, end: 10153 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'deploy', + loc: { start: 11796, end: 11802 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 11803, end: 11809 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'DeployParameters', + loc: { start: 11811, end: 11827 } + }, + typeArgs: [], + loc: { start: 11811, end: 11827 } + }, + loc: { start: 11803, end: 11827 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '4 1 BLKPUSH // pushes 2 copies of `init.code` and `init.data`\n' + + ' HASHCU // `init.data` hash\n' + + ' SWAP\n' + + ' HASHCU // `init.code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `init.data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `init.code` depth\n' + + '\n' + + ' // Group 2: Calculating destination address\n' + + ' // For almost identical logic and instructions,\n' + + ' // see comments inside `contractHash()` function in contract.tact\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + ' NEWC\n' + + ' 24 STU\n' + + ' 16 STU\n' + + ' 16 STU\n' + + ' 256 STU\n' + + ' 256 STU\n' + + ' ONE HASHEXT_SHA256 // obtains hash part (account id) of the address\n' + + ' // → Stack state\n' + + ' // s0: destAddr(hash part)\n' + + ' // s1: `init.data`\n' + + ' // s2: `init.code`\n' + + ' // s3 and below: `bounce`, `value`, `body`, `mode`\n' + + '\n' + + ' // Group 3: Building a message (CommonMsgInfoRelaxed)\n' + + ' s3 XCHG0 // swaps `bounce` with destAddr(hash part)\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' s1 s2 XCHG // swap `init.data` with `init.code`, placing code on s1\n' + + ' STREF // store `init.code`\n' + + ' STREF // store `init.data`\n' + + ' // Inline StateInit:\n' + + ' b{00010000000000} STSLICECONST\n' + + ' // 0 + 00 + 10 + 0 + 00000000\n' + + ' // 1) 0 - bounced = false\n' + + ' // 2) 00 - src = addr_none\n' + + ' // 3) 10 - tag of addr_std (part of dest)\n' + + ' // 4) 0 - Maybe Anycast = false\n' + + ' // 5) 00000000 - workchain_id (part of dest)\n' + + ' //\n' + + ' 256 STU // store destAddr(hash part)\n' + + ' SWAP // Builder on top, `value` below\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + '\n' + + ' // Group 4: Continue building a message (CommonMsgInfoRelaxed into MessageRelaxed)\n' + + ' // Remaining bits of MessageRelaxed:\n' + + ' b{1000110} STSLICECONST\n' + + ' // 10 + 0 + 0 + 1 + 1 + 0\n' + + ' // 10 - Maybe (Either StateInit ^StateInit) = true false\n' + + ' // 0 - split_depth:(Maybe (## 5)) = false\n' + + ' // 0 = special:(Maybe TickTock) = false\n' + + ' // 1 = code:(Maybe ^Cell) = true\n' + + ' // 1 = data:(Maybe ^Cell) = true\n' + + ' // 0 = library:(Maybe ^Cell) = false\n' + + ' //\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC // finalize the message\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: params.`mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 11788, end: 14770 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'cashback', + loc: { start: 15971, end: 15979 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'to', + loc: { start: 15980, end: 15982 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 15984, end: 15991 } + }, + typeArgs: [], + loc: { start: 15984, end: 15991 } + }, + loc: { start: 15980, end: 15991 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '16 PUSHINT // 0x10, i.e. 0x18 but with bounce = false\n' + + ' NEWC\n' + + ' 6 STU // .storeUint(0x10, 6)\n' + + ' STSLICE // .storeAddress(to)\n' + + ' 0 PUSHINT // 0\n' + + ' 111 STUR // .storeUint(0, 111)\n' + + ' // 4 zeros for coins and 107 zeros for lt, fees, etc.\n' + + ' ENDC\n' + + ' 66 PUSHINT // SendRemainingValue | SendIgnoreErrors\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 15963, end: 16385 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeSendMessage', + loc: { start: 16936, end: 16953 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 16954, end: 16957 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 16959, end: 16963 } + }, + loc: { start: 16959, end: 16963 } + }, + loc: { start: 16954, end: 16963 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 16965, end: 16969 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 16971, end: 16974 } + }, + loc: { start: 16971, end: 16974 } + }, + loc: { start: 16965, end: 16974 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDRAWMSG' ] + }, + loc: { start: 16928, end: 16990 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sendRawMessage', + loc: { start: 17751, end: 17765 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 17766, end: 17769 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 17771, end: 17775 } + }, + loc: { start: 17771, end: 17775 } + }, + loc: { start: 17766, end: 17775 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 17777, end: 17781 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 17783, end: 17786 } + }, + loc: { start: 17783, end: 17786 } + }, + loc: { start: 17777, end: 17786 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDRAWMSG' ] + }, + loc: { start: 17743, end: 17802 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeSendMessageReturnForwardFee', + loc: { start: 19063, end: 19096 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 19120, end: 19123 } + }, + loc: { start: 19120, end: 19123 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 19097, end: 19100 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 19102, end: 19106 } + }, + loc: { start: 19102, end: 19106 } + }, + loc: { start: 19097, end: 19106 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 19108, end: 19112 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 19114, end: 19117 } + }, + loc: { start: 19114, end: 19117 } + }, + loc: { start: 19108, end: 19117 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDMSG' ] + }, + loc: { start: 19055, end: 19135 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sendMessageReturnForwardFee', + loc: { start: 20186, end: 20213 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 20237, end: 20240 } + }, + loc: { start: 20237, end: 20240 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 20214, end: 20217 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 20219, end: 20223 } + }, + loc: { start: 20219, end: 20223 } + }, + loc: { start: 20214, end: 20223 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 20225, end: 20229 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 20231, end: 20234 } + }, + loc: { start: 20231, end: 20234 } + }, + loc: { start: 20225, end: 20234 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDMSG' ] + }, + loc: { start: 20178, end: 20252 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'emit', + loc: { start: 21033, end: 21037 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'body', + loc: { start: 21038, end: 21042 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 21044, end: 21048 } + }, + loc: { start: 21044, end: 21048 } + }, + loc: { start: 21038, end: 21048 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'c', + loc: { start: 21233, end: 21234 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 21236, end: 21240 } + }, + loc: { start: 21236, end: 21240 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'static_call', + function: { + kind: 'id', + text: 'beginCell', + loc: { start: 21243, end: 21252 } + }, + typeArgs: [], + args: [], + loc: { start: 21243, end: 21254 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 21264, end: 21273 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 15211807202738752817960438464513n, + loc: { start: 21274, end: 21306 } + }, + { + kind: 'number', + base: '10', + value: 104n, + loc: { start: 21308, end: 21311 } + } + ], + loc: { start: 21243, end: 21312 } + }, + method: { + kind: 'id', + text: 'storeRef', + loc: { start: 21322, end: 21330 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'body', + loc: { start: 21331, end: 21335 } + } + ], + loc: { start: 21243, end: 21336 } + }, + method: { + kind: 'id', + text: 'endCell', + loc: { start: 21346, end: 21353 } + }, + typeArgs: [], + args: [], + loc: { start: 21243, end: 21355 } + }, + loc: { start: 21229, end: 21356 } + }, + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'sendRawMessage', + loc: { start: 21361, end: 21375 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'c', + loc: { start: 21376, end: 21377 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 21379, end: 21380 } + } + ], + loc: { start: 21361, end: 21381 } + }, + loc: { start: 21361, end: 21382 } + } + ] + }, + loc: { start: 21022, end: 21384 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'acceptMessage', + loc: { start: 22124, end: 22137 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ACCEPT' ] + }, + loc: { start: 22116, end: 22150 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'commit', + loc: { start: 22638, end: 22644 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'COMMIT' ] + }, + loc: { start: 22630, end: 22657 } + } + ] + }, + 'commit' => { + kind: 'tact', + path: 'std/internal/send.tact', + code: '/// Ordinary message (default).\n' + + '///\n' + + '/// This constant is available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendDefaultMode: Int = 0;\n' + + '\n' + + '/// Carry all the remaining value of the inbound message in addition\n' + + '/// to the value initially indicated in the new message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendRemainingValue: Int = 64;\n' + + '\n' + + '/// Carry **all the remaining balance** of the current smart contract instead\n' + + '/// of the value originally indicated in the message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendRemainingBalance: Int = 128;\n' + + '\n' + + "/// Doesn't send the message, only estimates the forward fees\n" + + '/// if the message-sending function computes those.\n' + + '///\n' + + '/// This constant is available since Tact 1.5.0.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '/// * https://docs.tact-lang.org/book/send#message-sending-functions\n' + + '///\n' + + 'const SendOnlyEstimateFee: Int = 1024;\n' + + '\n' + + '/// **Deprecated** since Tact 1.6.5.\n' + + '///\n' + + '/// Pay forward fees separately from the message value.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendPayGasSeparately: Int = 1;\n' + + '\n' + + '/// Pay forward fees separately from the message value.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendPayFwdFeesSeparately: Int = 1;\n' + + '\n' + + '/// Ignore any errors arising while processing this message during the action phase.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendIgnoreErrors: Int = 2;\n' + + '\n' + + '/// Bounce transaction in case of any errors during action phase.\n' + + '/// Has no effect if flag +2, `SendIgnoreErrors` is used.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendBounceIfActionFail: Int = 16;\n' + + '\n' + + '/// Current account (contract) will be destroyed if its resulting balance is zero.\n' + + '/// This flag is often used with mode 128, `SendRemainingBalance`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendDestroyIfZero: Int = 32;\n' + + '\n' + + '/// Struct for specifying the message parameters of the `send()` function.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#send\n' + + '///\n' + + 'struct SendParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// Optional initial code of the contract (compiled bitcode).\n' + + ' code: Cell? = null;\n' + + '\n' + + ' /// Optional initial data of the contract (arguments of `init()` function or values of contract parameters).\n' + + ' data: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// Recipient internal `Address` on TON Blockchain.\n' + + ' to: Address;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '}\n' + + '\n' + + '/// Struct for specifying the message parameters of the `message()` function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#message\n' + + '///\n' + + 'struct MessageParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// Recipient internal `Address` on TON Blockchain.\n' + + ' to: Address;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Queues the message to be sent using the `MessageParameters` struct. Allows for cheaper non-deployment, regular messages compared to the `send()` function.\n' + + '///\n' + + '/// The `MessageParameters` struct is similar to `SendParameters` struct, but without the `code` and `data` fields.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// message(MessageParameters{\n' + + '/// to: sender(), // back to the sender,\n' + + '/// value: ton("1"), // with 1 Toncoin (1_000_000_000 nanoToncoin),\n' + + '/// // and no message body\n' + + '/// });\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 33: [Action list is too long] — Thrown when attempting to queue more than 255 messages.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-send#message\n' + + '/// * https://docs.tact-lang.org/book/message-mode\n' + + '///\n' + + '/// [Action list is too long]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '///\n' + + 'asm fun message(params: MessageParameters) {\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 106 PUSHINT // 1 + 4 + 4 + 64 + 32 + 1\n' + + ' STZEROES\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + ' STDICT\n' + + ' ENDC\n' + + ' SWAP\n' + + ' SENDRAWMSG\n' + + '}\n' + + '\n' + + '/// Global function. Queues the message to be sent using a `SendParameters` Struct.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// send(SendParameters{\n' + + '/// to: sender(), // back to the sender,\n' + + '/// value: ton("1"), // with 1 Toncoin (1_000_000_000 nanoToncoin),\n' + + '/// // and no message body\n' + + '/// });\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 33: [Action list is too long] — Thrown when attempting to queue more than 255 messages.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#send\n' + + '///\n' + + '/// [Action list is too long]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '///\n' + + 'asm fun send(params: SendParameters) {\n' + + ' // Instructions are grouped, and the stack states they produce as a group are shown right after.\n' + + ' // In the end, our message Cell should have the following TL-B structure:\n' + + ' // message$_ {X:Type}\n' + + ' // info:CommonMsgInfoRelaxed\n' + + ' // init:(Maybe (Either StateInit ^StateInit))\n' + + ' // body:(Either X ^X)\n' + + ' // = MessageRelaxed X;\n' + + '\n' + + ' // → Stack state\n' + + ' // s0: `params.bounce`\n' + + ' // s1: `params.to`\n' + + ' // s2: `params.value`\n' + + ' // s3: `params.data`\n' + + ' // s4: `params.code`\n' + + ' // s5: `params.body`\n' + + ' // s6: `params.mode`\n' + + ' // For brevity, the "params" prefix will be omitted from now on.\n' + + '\n' + + ' // Group 1: Storing the `bounce`, `to` and `value` into a Builder\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + '\n' + + ' // Group 2: Placing the Builder after code and data, then checking those for nullability\n' + + ' s2 XCHG0\n' + + ' DUP2\n' + + ' ISNULL\n' + + ' SWAP\n' + + ' ISNULL\n' + + ' AND\n' + + ' // → Stack state\n' + + ' // s0: -1 (true) if `data` and `code` are both null, 0 (false) otherwise\n' + + ' // s1: `code`\n' + + ' // s2: `data`\n' + + ' // s3: Builder\n' + + ' // s4: `body`\n' + + ' // s5: `mode`\n' + + '\n' + + ' // Group 3: Left branch of the IFELSE, executed if s0 is -1 (true)\n' + + ' <{\n' + + ' DROP2 // drop `data` and `code`, since either of those is null\n' + + ' b{0} STSLICECONST\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: Right branch of the IFELSE, executed if s0 is 0 (false)\n' + + ' <{\n' + + ' // _ split_depth:(Maybe (## 5))\n' + + ' // special:(Maybe TickTock)\n' + + ' // code:(Maybe ^Cell)\n' + + ' // data:(Maybe ^Cell)\n' + + ' // library:(Maybe ^Cell)\n' + + ' // = StateInit;\n' + + ' ROT // place message Builder on top\n' + + ' b{10} STSLICECONST // store Maybe = true, Either = false\n' + + ' // Start composing inlined StateInit\n' + + ' b{00} STSLICECONST // store split_depth and special first\n' + + ' STDICT // store code\n' + + ' STDICT // store data\n' + + ' b{0} STSLICECONST // store library\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: IFELSE that does the branching shown above\n' + + ' IFELSE\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: null or StateInit\n' + + ' // s2: `body`\n' + + ' // s3: `mode`\n' + + '\n' + + ' // Group 4: Finalizing the message\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: `mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG // https://github.com/tact-lang/tact/issues/1558\n' + + '}\n' + + '\n' + + '/// Struct for specifying the deployment message parameters of the `deploy()` function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#deploy\n' + + '///\n' + + 'struct DeployParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '\n' + + ' //'... 12658 more characters, + imports: [], + items: [ + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendDefaultMode', + loc: { start: 164, end: 179 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 181, end: 184 } + }, + loc: { start: 181, end: 184 } + }, + initializer: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 187, end: 188 } + } + }, + loc: { start: 158, end: 189 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendRemainingValue', + loc: { start: 396, end: 414 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 416, end: 419 } + }, + loc: { start: 416, end: 419 } + }, + initializer: { + kind: 'number', + base: '10', + value: 64n, + loc: { start: 422, end: 424 } + } + }, + loc: { start: 390, end: 425 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendRemainingBalance', + loc: { start: 638, end: 658 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 660, end: 663 } + }, + loc: { start: 660, end: 663 } + }, + initializer: { + kind: 'number', + base: '10', + value: 128n, + loc: { start: 666, end: 669 } + } + }, + loc: { start: 632, end: 670 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendOnlyEstimateFee', + loc: { start: 993, end: 1012 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1014, end: 1017 } + }, + loc: { start: 1014, end: 1017 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1024n, + loc: { start: 1020, end: 1024 } + } + }, + loc: { start: 987, end: 1025 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendPayGasSeparately', + loc: { start: 1207, end: 1227 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1229, end: 1232 } + }, + loc: { start: 1229, end: 1232 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1235, end: 1236 } + } + }, + loc: { start: 1201, end: 1237 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendPayFwdFeesSeparately', + loc: { start: 1378, end: 1402 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1404, end: 1407 } + }, + loc: { start: 1404, end: 1407 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1410, end: 1411 } + } + }, + loc: { start: 1372, end: 1412 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendIgnoreErrors', + loc: { start: 1582, end: 1598 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1600, end: 1603 } + }, + loc: { start: 1600, end: 1603 } + }, + initializer: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 1606, end: 1607 } + } + }, + loc: { start: 1576, end: 1608 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendBounceIfActionFail', + loc: { start: 1817, end: 1839 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1841, end: 1844 } + }, + loc: { start: 1841, end: 1844 } + }, + initializer: { + kind: 'number', + base: '10', + value: 16n, + loc: { start: 1847, end: 1849 } + } + }, + loc: { start: 1811, end: 1850 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendDestroyIfZero', + loc: { start: 2085, end: 2102 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2104, end: 2107 } + }, + loc: { start: 2104, end: 2107 } + }, + initializer: { + kind: 'number', + base: '10', + value: 32n, + loc: { start: 2110, end: 2112 } + } + }, + loc: { start: 2079, end: 2113 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'SendParameters', + loc: { start: 2260, end: 2274 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 2416, end: 2420 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2422, end: 2425 } + }, + loc: { start: 2422, end: 2425 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 2428, end: 2443 } + }, + loc: { start: 2416, end: 2443 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 2493, end: 2497 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2503, end: 2504 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2499, end: 2503 } + }, + loc: { start: 2499, end: 2503 } + } + ], + loc: { start: 2503, end: 2504 } + }, + initializer: { kind: 'null', loc: { start: 2507, end: 2511 } }, + loc: { start: 2493, end: 2511 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'code', + loc: { start: 2584, end: 2588 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2594, end: 2595 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2590, end: 2594 } + }, + loc: { start: 2590, end: 2594 } + } + ], + loc: { start: 2594, end: 2595 } + }, + initializer: { kind: 'null', loc: { start: 2598, end: 2602 } }, + loc: { start: 2584, end: 2602 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'data', + loc: { start: 2722, end: 2726 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2732, end: 2733 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2728, end: 2732 } + }, + loc: { start: 2728, end: 2732 } + } + ], + loc: { start: 2732, end: 2733 } + }, + initializer: { kind: 'null', loc: { start: 2736, end: 2740 } }, + loc: { start: 2722, end: 2740 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 2936, end: 2941 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2943, end: 2946 } + }, + loc: { start: 2943, end: 2946 } + }, + initializer: undefined, + loc: { start: 2936, end: 2946 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'to', + loc: { start: 3009, end: 3011 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3013, end: 3020 } + }, + typeArgs: [], + loc: { start: 3013, end: 3020 } + }, + initializer: undefined, + loc: { start: 3009, end: 3020 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 3186, end: 3192 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 3194, end: 3198 } + }, + typeArgs: [], + loc: { start: 3194, end: 3198 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 3201, end: 3205 } + }, + loc: { start: 3186, end: 3205 } + } + ], + loc: { start: 2253, end: 3208 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'MessageParameters', + loc: { start: 3389, end: 3406 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 3548, end: 3552 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3554, end: 3557 } + }, + loc: { start: 3554, end: 3557 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 3560, end: 3575 } + }, + loc: { start: 3548, end: 3575 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 3625, end: 3629 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 3635, end: 3636 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 3631, end: 3635 } + }, + loc: { start: 3631, end: 3635 } + } + ], + loc: { start: 3635, end: 3636 } + }, + initializer: { kind: 'null', loc: { start: 3639, end: 3643 } }, + loc: { start: 3625, end: 3643 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 3839, end: 3844 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3846, end: 3849 } + }, + loc: { start: 3846, end: 3849 } + }, + initializer: undefined, + loc: { start: 3839, end: 3849 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'to', + loc: { start: 3912, end: 3914 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3916, end: 3923 } + }, + typeArgs: [], + loc: { start: 3916, end: 3923 } + }, + initializer: undefined, + loc: { start: 3912, end: 3923 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 4089, end: 4095 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 4097, end: 4101 } + }, + typeArgs: [], + loc: { start: 4097, end: 4101 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 4104, end: 4108 } + }, + loc: { start: 4089, end: 4108 } + } + ], + loc: { start: 3382, end: 4111 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'message', + loc: { start: 5056, end: 5063 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 5064, end: 5070 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'MessageParameters', + loc: { start: 5072, end: 5089 } + }, + typeArgs: [], + loc: { start: 5072, end: 5089 } + }, + loc: { start: 5064, end: 5089 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 106 PUSHINT // 1 + 4 + 4 + 64 + 32 + 1\n' + + ' STZEROES\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + ' STDICT\n' + + ' ENDC\n' + + ' SWAP\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 5048, end: 5588 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'send', loc: { start: 6219, end: 6223 } }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 6224, end: 6230 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'SendParameters', + loc: { start: 6232, end: 6246 } + }, + typeArgs: [], + loc: { start: 6232, end: 6246 } + }, + loc: { start: 6224, end: 6246 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + '\n' + + ' // Group 2: Placing the Builder after code and data, then checking those for nullability\n' + + ' s2 XCHG0\n' + + ' DUP2\n' + + ' ISNULL\n' + + ' SWAP\n' + + ' ISNULL\n' + + ' AND\n' + + ' // → Stack state\n' + + ' // s0: -1 (true) if `data` and `code` are both null, 0 (false) otherwise\n' + + ' // s1: `code`\n' + + ' // s2: `data`\n' + + ' // s3: Builder\n' + + ' // s4: `body`\n' + + ' // s5: `mode`\n' + + '\n' + + ' // Group 3: Left branch of the IFELSE, executed if s0 is -1 (true)\n' + + ' <{\n' + + ' DROP2 // drop `data` and `code`, since either of those is null\n' + + ' b{0} STSLICECONST\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: Right branch of the IFELSE, executed if s0 is 0 (false)\n' + + ' <{\n' + + ' // _ split_depth:(Maybe (## 5))\n' + + ' // special:(Maybe TickTock)\n' + + ' // code:(Maybe ^Cell)\n' + + ' // data:(Maybe ^Cell)\n' + + ' // library:(Maybe ^Cell)\n' + + ' // = StateInit;\n' + + ' ROT // place message Builder on top\n' + + ' b{10} STSLICECONST // store Maybe = true, Either = false\n' + + ' // Start composing inlined StateInit\n' + + ' b{00} STSLICECONST // store split_depth and special first\n' + + ' STDICT // store code\n' + + ' STDICT // store data\n' + + ' b{0} STSLICECONST // store library\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: IFELSE that does the branching shown above\n' + + ' IFELSE\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: null or StateInit\n' + + ' // s2: `body`\n' + + ' // s3: `mode`\n' + + '\n' + + ' // Group 4: Finalizing the message\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: `mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG // https://github.com/tact-lang/tact/issues/1558' + ] + }, + loc: { start: 6211, end: 9157 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'DeployParameters', + loc: { start: 9347, end: 9363 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 9505, end: 9509 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9511, end: 9514 } + }, + loc: { start: 9511, end: 9514 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 9517, end: 9532 } + }, + loc: { start: 9505, end: 9532 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 9582, end: 9586 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 9592, end: 9593 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 9588, end: 9592 } + }, + loc: { start: 9588, end: 9592 } + } + ], + loc: { start: 9592, end: 9593 } + }, + initializer: { kind: 'null', loc: { start: 9596, end: 9600 } }, + loc: { start: 9582, end: 9600 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 9796, end: 9801 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9803, end: 9806 } + }, + loc: { start: 9803, end: 9806 } + }, + initializer: undefined, + loc: { start: 9796, end: 9806 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 9972, end: 9978 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 9980, end: 9984 } + }, + typeArgs: [], + loc: { start: 9980, end: 9984 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 9987, end: 9991 } + }, + loc: { start: 9972, end: 9991 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'init', + loc: { start: 10135, end: 10139 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 10141, end: 10150 } + }, + typeArgs: [], + loc: { start: 10141, end: 10150 } + }, + initializer: undefined, + loc: { start: 10135, end: 10150 } + } + ], + loc: { start: 9340, end: 10153 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'deploy', + loc: { start: 11796, end: 11802 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 11803, end: 11809 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'DeployParameters', + loc: { start: 11811, end: 11827 } + }, + typeArgs: [], + loc: { start: 11811, end: 11827 } + }, + loc: { start: 11803, end: 11827 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '4 1 BLKPUSH // pushes 2 copies of `init.code` and `init.data`\n' + + ' HASHCU // `init.data` hash\n' + + ' SWAP\n' + + ' HASHCU // `init.code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `init.data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `init.code` depth\n' + + '\n' + + ' // Group 2: Calculating destination address\n' + + ' // For almost identical logic and instructions,\n' + + ' // see comments inside `contractHash()` function in contract.tact\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + ' NEWC\n' + + ' 24 STU\n' + + ' 16 STU\n' + + ' 16 STU\n' + + ' 256 STU\n' + + ' 256 STU\n' + + ' ONE HASHEXT_SHA256 // obtains hash part (account id) of the address\n' + + ' // → Stack state\n' + + ' // s0: destAddr(hash part)\n' + + ' // s1: `init.data`\n' + + ' // s2: `init.code`\n' + + ' // s3 and below: `bounce`, `value`, `body`, `mode`\n' + + '\n' + + ' // Group 3: Building a message (CommonMsgInfoRelaxed)\n' + + ' s3 XCHG0 // swaps `bounce` with destAddr(hash part)\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' s1 s2 XCHG // swap `init.data` with `init.code`, placing code on s1\n' + + ' STREF // store `init.code`\n' + + ' STREF // store `init.data`\n' + + ' // Inline StateInit:\n' + + ' b{00010000000000} STSLICECONST\n' + + ' // 0 + 00 + 10 + 0 + 00000000\n' + + ' // 1) 0 - bounced = false\n' + + ' // 2) 00 - src = addr_none\n' + + ' // 3) 10 - tag of addr_std (part of dest)\n' + + ' // 4) 0 - Maybe Anycast = false\n' + + ' // 5) 00000000 - workchain_id (part of dest)\n' + + ' //\n' + + ' 256 STU // store destAddr(hash part)\n' + + ' SWAP // Builder on top, `value` below\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + '\n' + + ' // Group 4: Continue building a message (CommonMsgInfoRelaxed into MessageRelaxed)\n' + + ' // Remaining bits of MessageRelaxed:\n' + + ' b{1000110} STSLICECONST\n' + + ' // 10 + 0 + 0 + 1 + 1 + 0\n' + + ' // 10 - Maybe (Either StateInit ^StateInit) = true false\n' + + ' // 0 - split_depth:(Maybe (## 5)) = false\n' + + ' // 0 = special:(Maybe TickTock) = false\n' + + ' // 1 = code:(Maybe ^Cell) = true\n' + + ' // 1 = data:(Maybe ^Cell) = true\n' + + ' // 0 = library:(Maybe ^Cell) = false\n' + + ' //\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC // finalize the message\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: params.`mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 11788, end: 14770 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'cashback', + loc: { start: 15971, end: 15979 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'to', + loc: { start: 15980, end: 15982 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 15984, end: 15991 } + }, + typeArgs: [], + loc: { start: 15984, end: 15991 } + }, + loc: { start: 15980, end: 15991 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '16 PUSHINT // 0x10, i.e. 0x18 but with bounce = false\n' + + ' NEWC\n' + + ' 6 STU // .storeUint(0x10, 6)\n' + + ' STSLICE // .storeAddress(to)\n' + + ' 0 PUSHINT // 0\n' + + ' 111 STUR // .storeUint(0, 111)\n' + + ' // 4 zeros for coins and 107 zeros for lt, fees, etc.\n' + + ' ENDC\n' + + ' 66 PUSHINT // SendRemainingValue | SendIgnoreErrors\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 15963, end: 16385 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeSendMessage', + loc: { start: 16936, end: 16953 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 16954, end: 16957 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 16959, end: 16963 } + }, + loc: { start: 16959, end: 16963 } + }, + loc: { start: 16954, end: 16963 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 16965, end: 16969 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 16971, end: 16974 } + }, + loc: { start: 16971, end: 16974 } + }, + loc: { start: 16965, end: 16974 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDRAWMSG' ] + }, + loc: { start: 16928, end: 16990 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sendRawMessage', + loc: { start: 17751, end: 17765 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 17766, end: 17769 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 17771, end: 17775 } + }, + loc: { start: 17771, end: 17775 } + }, + loc: { start: 17766, end: 17775 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 17777, end: 17781 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 17783, end: 17786 } + }, + loc: { start: 17783, end: 17786 } + }, + loc: { start: 17777, end: 17786 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDRAWMSG' ] + }, + loc: { start: 17743, end: 17802 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeSendMessageReturnForwardFee', + loc: { start: 19063, end: 19096 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 19120, end: 19123 } + }, + loc: { start: 19120, end: 19123 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 19097, end: 19100 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 19102, end: 19106 } + }, + loc: { start: 19102, end: 19106 } + }, + loc: { start: 19097, end: 19106 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 19108, end: 19112 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 19114, end: 19117 } + }, + loc: { start: 19114, end: 19117 } + }, + loc: { start: 19108, end: 19117 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDMSG' ] + }, + loc: { start: 19055, end: 19135 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sendMessageReturnForwardFee', + loc: { start: 20186, end: 20213 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 20237, end: 20240 } + }, + loc: { start: 20237, end: 20240 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 20214, end: 20217 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 20219, end: 20223 } + }, + loc: { start: 20219, end: 20223 } + }, + loc: { start: 20214, end: 20223 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 20225, end: 20229 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 20231, end: 20234 } + }, + loc: { start: 20231, end: 20234 } + }, + loc: { start: 20225, end: 20234 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDMSG' ] + }, + loc: { start: 20178, end: 20252 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'emit', + loc: { start: 21033, end: 21037 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'body', + loc: { start: 21038, end: 21042 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 21044, end: 21048 } + }, + loc: { start: 21044, end: 21048 } + }, + loc: { start: 21038, end: 21048 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'c', + loc: { start: 21233, end: 21234 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 21236, end: 21240 } + }, + loc: { start: 21236, end: 21240 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'static_call', + function: { + kind: 'id', + text: 'beginCell', + loc: { start: 21243, end: 21252 } + }, + typeArgs: [], + args: [], + loc: { start: 21243, end: 21254 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 21264, end: 21273 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 15211807202738752817960438464513n, + loc: { start: 21274, end: 21306 } + }, + { + kind: 'number', + base: '10', + value: 104n, + loc: { start: 21308, end: 21311 } + } + ], + loc: { start: 21243, end: 21312 } + }, + method: { + kind: 'id', + text: 'storeRef', + loc: { start: 21322, end: 21330 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'body', + loc: { start: 21331, end: 21335 } + } + ], + loc: { start: 21243, end: 21336 } + }, + method: { + kind: 'id', + text: 'endCell', + loc: { start: 21346, end: 21353 } + }, + typeArgs: [], + args: [], + loc: { start: 21243, end: 21355 } + }, + loc: { start: 21229, end: 21356 } + }, + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'sendRawMessage', + loc: { start: 21361, end: 21375 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'c', + loc: { start: 21376, end: 21377 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 21379, end: 21380 } + } + ], + loc: { start: 21361, end: 21381 } + }, + loc: { start: 21361, end: 21382 } + } + ] + }, + loc: { start: 21022, end: 21384 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'acceptMessage', + loc: { start: 22124, end: 22137 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ACCEPT' ] + }, + loc: { start: 22116, end: 22150 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'commit', + loc: { start: 22638, end: 22644 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'COMMIT' ] + }, + loc: { start: 22630, end: 22657 } + } + ] + }, + 'getConfigParam' => { + kind: 'tact', + path: 'std/internal/config.tact', + code: '/// Loads a [configuration parameter] of TON Blockchain by its `id` number.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#getconfigparam\n' + + '///\n' + + '/// [configuration parameter]: https://docs.ton.org/develop/howto/blockchain-configs\n' + + '///\n' + + 'asm fun getConfigParam(id: Int): Cell? { CONFIGOPTPARAM }\n', + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getConfigParam', + loc: { start: 254, end: 268 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 283, end: 284 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { kind: 'SFDefault', loc: { start: 279, end: 283 } }, + loc: { start: 279, end: 283 } + } + ], + loc: { start: 283, end: 284 } + }, + params: [ + { + kind: 'typed_parameter', + name: { kind: 'id', text: 'id', loc: { start: 269, end: 271 } }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 273, end: 276 } + }, + loc: { start: 273, end: 276 } + }, + loc: { start: 269, end: 276 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'CONFIGOPTPARAM' ] + }, + loc: { start: 246, end: 303 } + } + ] + }, + 'newAddress' => { + kind: 'tact', + path: 'std/internal/address.tact', + code: '/// Extension function for the `Slice` type. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Casts the `Slice` to an `Address` in a given `chain` ID and returns it. The inverse of `Address.asSlice()` and a safe but more gas-expensive version of `Slice.asAddressUnsafe()`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + "/// let a: Address = myAddress(); // let's assume we're in a basechain\n" + + '/// let a2: Address = a.asSlice().asAddress(0); // so the chain ID is 0\n' + + '///\n' + + '/// a == a2; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 136: [Invalid standard address] — Thrown when the given `Slice` contains an invalid\n' + + '/// tag prefix (not `0b100`) or an invalid account ID length (not 256 bits).\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#sliceasaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#sliceasaddressunsafe\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#addressasslice\n' + + '///\n' + + '/// [Invalid standard address]: https://docs.tact-lang.org/book/exit-codes#136\n' + + '///\n' + + 'extends fun asAddress(self: Slice, chain: Int): Address {\n' + + ' // 11 bits for the prefix,\n' + + ' // 256 bits for the address itself\n' + + ' throwUnless(TactExitCodeInvalidStandardAddress, self.bits() == 267);\n' + + '\n' + + ' if (chain == -1) {\n' + + ' // 1279 = 0b100_1111_1111,\n' + + ' // i.e. internal address prefix and chain ID -1\n' + + ' throwUnless(TactExitCodeInvalidStandardAddress, self.preloadUint(11) == 1279);\n' + + ' } else {\n' + + ' // Only check the correct internal address prefix,\n' + + ' // but do not verify the chain ID\n' + + ' throwUnless(TactExitCodeInvalidStandardAddress, self.preloadUint(3) == 4);\n' + + ' }\n' + + '\n' + + ' // Proceed with the cast\n' + + ' return self.asAddressUnsafe();\n' + + '}\n' + + '\n' + + '/// Extension function for the `Slice` type. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Unsafely casts the `Slice` to an `Address` and returns it. The inverse of `Address.asSlice()`.\n' + + '///\n' + + '/// This function does **not** perform any checks on the contents of the `Slice`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let a: Address = myAddress();\n' + + '/// let a2: Address = a.asSlice().asAddressUnsafe();\n' + + '///\n' + + '/// a == a2; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// Use it only if you want to optimize the code for gas and can guarantee in advance that the `Slice` contains the data of an `Address`.\n' + + '///\n' + + '/// Otherwise, use a safer but more gas-expensive `Slice.asAddress()` function.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#sliceasaddressunsafe\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#sliceasaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#addressasslice\n' + + '///\n' + + 'asm extends fun asAddressUnsafe(self: Slice): Address {}\n' + + '\n' + + '/// Extension function for the `Address` type.\n' + + '///\n' + + '/// Casts `self` back to the underlying `Slice` and returns it. The inverse of `Slice.asAddressUnsafe()`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let a: Address = myAddress();\n' + + '/// let fizz: Slice = beginCell().storeAddress(a).asSlice();\n' + + '/// let buzz: Slice = a.asSlice(); // cheap, unlike the previous statement\n' + + '///\n' + + '/// fizz == buzz; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#addressasslice\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#sliceasaddressunsafe\n' + + '///\n' + + 'asm extends fun asSlice(self: Address): Slice {}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Creates a new `Address` based on the `chain` ID and the SHA-256 encoded `hash` value (account ID).\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// Attempts to specify an uncommon `chain` ID (not -1 or 0) that can be detected in compile-time will result in a compilation error.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let oldTonFoundationAddr: Address =\n' + + '/// newAddress(0, 0x83dfd552e63729b472fcbcc8c45ebcc6691702558b68ec7527e1ba403a0f31a8);\n' + + '/// // ↑ ↑\n' + + "/// // | sha-256 hash of contract's init package (StateInit)\n" + + '/// // chain id: 0 is a workchain, -1 is a masterchain\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-addresses#newaddress\n' + + '///\n' + + 'inline fun newAddress(chain: Int, hash: Int): Address {\n' + + ' return beginCell()\n' + + ' .storeUint(0b10_0, 3)\n' + + ' .storeInt(chain, 8)\n' + + ' .storeUint(hash, 256)\n' + + ' .endCell()\n' + + ' .asSlice()\n' + + ' .asAddressUnsafe();\n' + + '}\n' + + '\n' + + '/// Struct representing the standard address on TON Blockchain with signed 8-bit `workchain` ID and an unsigned 256-bit `address` in the specified `workchain`. Available since Tact 1.5.0.\n' + + '///\n' + + '/// At the moment, only `workchain` IDs used on TON are 0 of the basechain and -1 of the masterchain.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#parsestdaddress\n' + + '/// * https://github.com/ton-blockchain/ton/blob/master/crypto/block/block.tlb#L105-L106\n' + + '///\n' + + 'struct StdAddress {\n' + + ' workchain: Int as int8;\n' + + ' address: Int as uint256;\n' + + '}\n' + + '\n' + + '/// Struct representing the address of variable length with signed 32-bit `workchain` ID and a `Slice` containing unsigned `address` in the specified `workchain`. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Variable-length addresses are intended for future extensions, and while validators must be ready to accept them in inbound messages, the standard (non-variable) addresses are used whenever possible.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#parsevaraddress\n' + + '/// * https://github.com/ton-blockchain/ton/blob/master/crypto/block/block.tlb#L107-L108\n' + + '///\n' + + 'struct VarAddress {\n' + + ' workchain: Int as int32;\n' + + ' address: Slice;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Converts a `slice` containing an address into the `StdAddress` Struct and returns it.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let addr = address("EQDtFpEwcFAEcRe5mLVh2N6C0x-_hJEM7W61_JLnSF74p4q2");\n' + + '/// let parsedAddr = parseStdAddress(addr.asSlice());\n' + + '///\n' + + '/// parsedAddr.workchain; // 0\n' + + '/// parsedAddr.address; // 107...287\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-addresses#parsestdaddress\n' + + '///\n' + + 'asm fun parseStdAddress(slice: Slice): StdAddress { REWRITESTDADDR }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Converts a `slice` containing an address of variable length into the `VarAddress` Struct and returns it.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let varAddrSlice = beginCell()\n' + + '/// .storeUint(6, 3) // to recognize the following as a VarAddress\n' + + '/// .storeUint(123, 9) // make address occupy 123 bits\n' + + '/// .storeUint(234, 32) // specify workchain ID of 234\n' + + '/// .storeUint(345, 123) // specify address of 345\n' + + '/// .asSlice();\n' + + '/// let parsedVarAddr = parseVarAddress(varAddrSlice);\n' + + '///\n' + + '/// parsedVarAddr.workchain; // 234\n' + + '/// parsedVarAddr.address; // CS{Cell{002...2b3} bits: 44..167; refs: 0..0}\n' + + '/// parsedVarAddr.address.loadUint(123); // 345\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-addresses#parsevaraddress\n' + + '///\n' + + 'asm fun parseVarAddress(slice: Slice): VarAddress { REWRITEVARADDR }\n' + + '\n' + + '/// Extension mutation function for the `Slice` type.\n' + + '///\n' + + '/// Loads and returns an `Address` from the `Slice`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let s: Slice = beginCell().storeAddress(myAddress()).asSlice();\n' + + '/// let fizz: Address = s.loadAddress();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + "/// * 8: [Cell overflow] — Thrown when attempting to load an `Address` when `Slice` doesn't contain it.\n" + + '/// * 9: [Cell underflow] — Thrown when attempting to load more data than `Slice` contains.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#sliceloadaddress\n' + + '///\n' + + '/// [Cell overflow]: https://docs.tact-lang.org/book/exit-codes#8\n' + + '/// [Cell underflow]: https://docs.tact-lang.org/book/exit-codes#9\n' + + '///\n' + + 'asm(-> 1 0) extends mutates fun loadAddress(self: Slice): Address { LDMSGADDR }\n' + + '\n' + + '/// Extension mutation function for the `Slice` type. Available since Tact 1.6.2.\n' + + '///\n' + + '/// Skips an `Address` from the `Slice`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let s1: Slice = beginCell()\n' + + '/// .storeAddress(myAddress())\n' + + '/// .storeUint(42, 32)\n' + + '/// .asSlice();\n' + + '///\n' + + '/// s1.skipAddress();\n' + + '/// let fizz: Int = s1.loadUint(32); // 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + "/// * 8: [Cell overflow] — Thrown when attempting to skip an `Address` when `Slice` doesn't contain it.\n" + + '/// * 9: [Cell underflow] — Thrown when attempting to skip more data than `Slice` contains.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#sliceskipaddress\n' + + '///\n' + + '/// [Cell overflow]: https://docs.tact-lang.org/book/exit-codes#8\n' + + '/// [Cell underflow]: https://docs.tact-lang.org/book/exit-codes#9\n' + + '///\n' + + 'asm extends mutates fun skipAddress(self: Slice) { LDMSGADDR NIP }\n' + + '\n' + + '/// Extension function for the `Builder` type.\n' + + '///\n' + + '/// Stores the `address` in the copy of the `Builder`. Returns that copy.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b.storeAddress(myAddress());\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 8: [Cell overflow] — Thrown when attempting to store an `address` into the `Builder` when it cannot fit it.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#builderstoreaddress\n' + + '///\n' + + '/// [Cell overflow]: https://docs.tact-lang.org/book/exit-codes#8\n' + + '///\n' + + 'asm extends fun storeAddress(self: Builder, address: Address): Builder { STSLICER }\n' + + '\n' + + '/// Struct representing a basechain address. Available since Tact 1.6.0.\n' + + '///\n' + + '/// A basechain address (workchain 0) can be either empty (null hash) or contain a 256-bit hash value.\n' + + '///\n' + + 'struct BasechainAddress {\n' + + ' hash: Int?;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Creates and returns an empty basechain address with a null hash.\n' + + '///\n' + + '/// When serialized, an empty basechain address is represented as `addr_none`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let emptyAddr: BasechainAddress = emptyBasechainAddress();\n' + + '/// emptyAddr.hash == null; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + 'inline fun emptyBasechainAddress(): BasechainAddress {\n' + + ' return BasechainAddress { hash: null };\n' + + '}\n' + + '\n' + + '/// Global f'... 4363 more characters, + imports: [], + items: [ + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'asAddress', + loc: { start: 998, end: 1007 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 1034, end: 1041 } + }, + typeArgs: [], + loc: { start: 1034, end: 1041 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'chain', + loc: { start: 1021, end: 1026 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1028, end: 1031 } + }, + loc: { start: 1028, end: 1031 } + }, + loc: { start: 1021, end: 1031 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throwUnless', + loc: { start: 1118, end: 1129 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'TactExitCodeInvalidStandardAddress', + loc: { start: 1130, end: 1164 } + }, + { + kind: 'op_binary', + op: '==', + left: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 1166, end: 1170 } + }, + method: { + kind: 'id', + text: 'bits', + loc: { start: 1171, end: 1175 } + }, + typeArgs: [], + args: [], + loc: { start: 1166, end: 1177 } + }, + right: { + kind: 'number', + base: '10', + value: 267n, + loc: { start: 1181, end: 1184 } + }, + loc: { start: 1166, end: 1184 } + } + ], + loc: { start: 1118, end: 1185 } + }, + loc: { start: 1118, end: 1186 } + }, + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'chain', + loc: { start: 1196, end: 1201 } + }, + right: { + kind: 'op_unary', + op: '-', + operand: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1206, end: 1207 } + }, + loc: { start: 1205, end: 1207 } + }, + loc: { start: 1196, end: 1207 } + }, + trueStatements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throwUnless', + loc: { start: 1310, end: 1321 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'TactExitCodeInvalidStandardAddress', + loc: { start: 1322, end: 1356 } + }, + { + kind: 'op_binary', + op: '==', + left: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 1358, end: 1362 } + }, + method: { + kind: 'id', + text: 'preloadUint', + loc: { start: 1363, end: 1374 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 11n, + loc: { start: 1375, end: 1377 } + } + ], + loc: { start: 1358, end: 1378 } + }, + right: { + kind: 'number', + base: '10', + value: 1279n, + loc: { start: 1382, end: 1386 } + }, + loc: { start: 1358, end: 1386 } + } + ], + loc: { start: 1310, end: 1387 } + }, + loc: { start: 1310, end: 1388 } + } + ], + falseStatements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throwUnless', + loc: { start: 1511, end: 1522 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'TactExitCodeInvalidStandardAddress', + loc: { start: 1523, end: 1557 } + }, + { + kind: 'op_binary', + op: '==', + left: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 1559, end: 1563 } + }, + method: { + kind: 'id', + text: 'preloadUint', + loc: { start: 1564, end: 1575 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 3n, + loc: { start: 1576, end: 1577 } + } + ], + loc: { start: 1559, end: 1578 } + }, + right: { + kind: 'number', + base: '10', + value: 4n, + loc: { start: 1582, end: 1583 } + }, + loc: { start: 1559, end: 1583 } + } + ], + loc: { start: 1511, end: 1584 } + }, + loc: { start: 1511, end: 1585 } + } + ], + loc: { start: 1192, end: 1591 } + }, + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 1633, end: 1637 } + }, + method: { + kind: 'id', + text: 'asAddressUnsafe', + loc: { start: 1638, end: 1653 } + }, + typeArgs: [], + args: [], + loc: { start: 1633, end: 1655 } + }, + loc: { start: 1626, end: 1656 } + } + ] + }, + loc: { start: 986, end: 1658 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 1014, end: 1019 } }, + loc: { start: 1014, end: 1019 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'asAddressUnsafe', + loc: { start: 2554, end: 2569 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 2584, end: 2591 } + }, + typeArgs: [], + loc: { start: 2584, end: 2591 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ '' ] + }, + loc: { start: 2538, end: 2594 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 2576, end: 2581 } }, + loc: { start: 2576, end: 2581 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'asSlice', + loc: { start: 3188, end: 3195 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 3212, end: 3217 } }, + loc: { start: 3212, end: 3217 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ '' ] + }, + loc: { start: 3172, end: 3220 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3202, end: 3209 } + }, + typeArgs: [], + loc: { start: 3202, end: 3209 } + } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'newAddress', + loc: { start: 4029, end: 4039 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 4064, end: 4071 } + }, + typeArgs: [], + loc: { start: 4064, end: 4071 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'chain', + loc: { start: 4040, end: 4045 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4047, end: 4050 } + }, + loc: { start: 4047, end: 4050 } + }, + loc: { start: 4040, end: 4050 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'hash', + loc: { start: 4052, end: 4056 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4058, end: 4061 } + }, + loc: { start: 4058, end: 4061 } + }, + loc: { start: 4052, end: 4061 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'static_call', + function: { + kind: 'id', + text: 'beginCell', + loc: { start: 4085, end: 4094 } + }, + typeArgs: [], + args: [], + loc: { start: 4085, end: 4096 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 4106, end: 4115 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '2', + value: 4n, + loc: { start: 4116, end: 4122 } + }, + { + kind: 'number', + base: '10', + value: 3n, + loc: { start: 4124, end: 4125 } + } + ], + loc: { start: 4085, end: 4126 } + }, + method: { + kind: 'id', + text: 'storeInt', + loc: { start: 4136, end: 4144 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'chain', + loc: { start: 4145, end: 4150 } + }, + { + kind: 'number', + base: '10', + value: 8n, + loc: { start: 4152, end: 4153 } + } + ], + loc: { start: 4085, end: 4154 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 4164, end: 4173 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'hash', + loc: { start: 4174, end: 4178 } + }, + { + kind: 'number', + base: '10', + value: 256n, + loc: { start: 4180, end: 4183 } + } + ], + loc: { start: 4085, end: 4184 } + }, + method: { + kind: 'id', + text: 'endCell', + loc: { start: 4194, end: 4201 } + }, + typeArgs: [], + args: [], + loc: { start: 4085, end: 4203 } + }, + method: { + kind: 'id', + text: 'asSlice', + loc: { start: 4213, end: 4220 } + }, + typeArgs: [], + args: [], + loc: { start: 4085, end: 4222 } + }, + method: { + kind: 'id', + text: 'asAddressUnsafe', + loc: { start: 4232, end: 4247 } + }, + typeArgs: [], + args: [], + loc: { start: 4085, end: 4249 } + }, + loc: { start: 4078, end: 4250 } + } + ] + }, + loc: { start: 4018, end: 4252 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'StdAddress', + loc: { start: 4729, end: 4739 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'workchain', + loc: { start: 4746, end: 4755 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 8, + loc: { start: 4757, end: 4768 } + }, + loc: { start: 4757, end: 4760 } + }, + initializer: undefined, + loc: { start: 4746, end: 4768 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'address', + loc: { start: 4774, end: 4781 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'unsigned', + width: 256, + loc: { start: 4783, end: 4797 } + }, + loc: { start: 4783, end: 4786 } + }, + initializer: undefined, + loc: { start: 4774, end: 4797 } + } + ], + loc: { start: 4722, end: 4800 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'VarAddress', + loc: { start: 5381, end: 5391 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'workchain', + loc: { start: 5398, end: 5407 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 32, + loc: { start: 5409, end: 5421 } + }, + loc: { start: 5409, end: 5412 } + }, + initializer: undefined, + loc: { start: 5398, end: 5421 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'address', + loc: { start: 5427, end: 5434 } + }, + type: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 5436, end: 5441 } }, + loc: { start: 5436, end: 5441 } + }, + initializer: undefined, + loc: { start: 5427, end: 5441 } + } + ], + loc: { start: 5374, end: 5444 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'parseStdAddress', + loc: { start: 5946, end: 5961 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StdAddress', + loc: { start: 5977, end: 5987 } + }, + typeArgs: [], + loc: { start: 5977, end: 5987 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'slice', + loc: { start: 5962, end: 5967 } + }, + type: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 5969, end: 5974 } }, + loc: { start: 5969, end: 5974 } + }, + loc: { start: 5962, end: 5974 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'REWRITESTDADDR' ] + }, + loc: { start: 5938, end: 6006 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'parseVarAddress', + loc: { start: 6898, end: 6913 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'VarAddress', + loc: { start: 6929, end: 6939 } + }, + typeArgs: [], + loc: { start: 6929, end: 6939 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'slice', + loc: { start: 6914, end: 6919 } + }, + type: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 6921, end: 6926 } }, + loc: { start: 6921, end: 6926 } + }, + loc: { start: 6914, end: 6926 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'REWRITEVARADDR' ] + }, + loc: { start: 6890, end: 6958 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadAddress', + loc: { start: 7707, end: 7718 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 7733, end: 7740 } + }, + typeArgs: [], + loc: { start: 7733, end: 7740 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { + args: [], + ret: [ + { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 7682, end: 7683 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 7684, end: 7685 } + } + ] + }, + instructions: [ 'LDMSGADDR' ] + }, + loc: { start: 7675, end: 7754 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 7725, end: 7730 } }, + loc: { start: 7725, end: 7730 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'skipAddress', + loc: { start: 8601, end: 8612 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LDMSGADDR NIP' ] + }, + loc: { start: 8577, end: 8643 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 8619, end: 8624 } }, + loc: { start: 8619, end: 8624 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeAddress', + loc: { start: 9222, end: 9234 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 9269, end: 9276 } }, + loc: { start: 9269, end: 9276 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'address', + loc: { start: 9250, end: 9257 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 9259, end: 9266 } + }, + typeArgs: [], + loc: { start: 9259, end: 9266 } + }, + loc: { start: 9250, end: 9266 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'STSLICER' ] + }, + loc: { start: 9206, end: 9289 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 9241, end: 9248 } }, + loc: { start: 9241, end: 9248 } + } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 9482, end: 9498 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'hash', + loc: { start: 9505, end: 9509 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 9514, end: 9515 } + }, + typeArgs: [ + { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9511, end: 9514 } + }, + loc: { start: 9511, end: 9514 } + } + ], + loc: { start: 9514, end: 9515 } + }, + initializer: undefined, + loc: { start: 9505, end: 9515 } + } + ], + loc: { start: 9475, end: 9518 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'emptyBasechainAddress', + loc: { start: 9897, end: 9918 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 9922, end: 9938 } + }, + typeArgs: [], + loc: { start: 9922, end: 9938 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'struct_instance', + type: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 9952, end: 9968 } + }, + typeArgs: [], + args: [ + { + kind: 'struct_field_initializer', + field: { + kind: 'id', + text: 'hash', + loc: { start: 9971, end: 9975 } + }, + initializer: { kind: 'null', loc: { start: 9977, end: 9981 } }, + loc: { start: 9971, end: 9981 } + } + ], + loc: { start: 9952, end: 9983 } + }, + loc: { start: 9945, end: 9984 } + } + ] + }, + loc: { start: 9886, end: 9986 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'newBasechainAddress', + loc: { start: 10311, end: 10330 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 10343, end: 10359 } + }, + typeArgs: [], + loc: { start: 10343, end: 10359 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'hash', + loc: { start: 10331, end: 10335 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10337, end: 10340 } + }, + loc: { start: 10337, end: 10340 } + }, + loc: { start: 10331, end: 10340 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'struct_instance', + type: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 10373, end: 10389 } + }, + typeArgs: [], + args: [ + { + kind: 'struct_field_initializer', + field: { + kind: 'id', + text: 'hash', + loc: { start: 10392, end: 10396 } + }, + initializer: { + kind: 'var', + name: 'hash', + loc: { start: 10392, end: 10396 } + }, + loc: { start: 10392, end: 10396 } + } + ], + loc: { start: 10373, end: 10398 } + }, + loc: { start: 10366, end: 10399 } + } + ] + }, + loc: { start: 10300, end: 10401 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'contractBasechainAddress', + loc: { start: 10865, end: 10889 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 10905, end: 10921 } + }, + typeArgs: [], + loc: { start: 10905, end: 10921 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 's', + loc: { start: 10890, end: 10891 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 10893, end: 10902 } + }, + typeArgs: [], + loc: { start: 10893, end: 10902 } + }, + loc: { start: 10890, end: 10902 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'hash', + loc: { start: 10932, end: 10936 } + }, + type: undefined, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractHash', + loc: { start: 10939, end: 10951 } + }, + typeArgs: [], + args: [ + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 10952, end: 10953 } + }, + field: { + kind: 'id', + text: 'code', + loc: { start: 10954, end: 10958 } + }, + loc: { start: 10952, end: 10958 } + }, + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 10960, end: 10961 } + }, + field: { + kind: 'id', + text: 'data', + loc: { start: 10962, end: 10966 } + }, + loc: { start: 10960, end: 10966 } + } + ], + loc: { start: 10939, end: 10967 } + }, + loc: { start: 10928, end: 10968 } + }, + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'newBasechainAddress', + loc: { start: 10980, end: 10999 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'hash', + loc: { start: 11000, end: 11004 } + } + ], + loc: { start: 10980, end: 11005 } + }, + loc: { start: 10973, end: 11006 } + } + ] + }, + loc: { start: 10854, end: 11008 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeBasechainAddress', + loc: { start: 11633, end: 11654 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 11698, end: 11705 } + }, + loc: { start: 11698, end: 11705 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'address', + loc: { start: 11670, end: 11677 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 11679, end: 11695 } + }, + typeArgs: [], + loc: { start: 11679, end: 11695 } + }, + loc: { start: 11670, end: 11695 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'address', + loc: { start: 11716, end: 11723 } + }, + field: { + kind: 'id', + text: 'hash', + loc: { start: 11724, end: 11728 } + }, + loc: { start: 11716, end: 11728 } + }, + right: { + kind: 'null', + loc: { start: 11732, end: 11736 } + }, + loc: { start: 11716, end: 11736 } + }, + trueStatements: [ + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 11755, end: 11759 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 11760, end: 11769 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 11770, end: 11771 } + }, + { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 11773, end: 11774 } + } + ], + loc: { start: 11755, end: 11775 } + }, + loc: { start: 11748, end: 11776 } + } + ], + falseStatements: undefined, + loc: { start: 11712, end: 11790 } + }, + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 11803, end: 11807 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 11817, end: 11826 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '2', + value: 1024n, + loc: { start: 11827, end: 11842 } + }, + { + kind: 'op_binary', + op: '+', + left: { + kind: 'number', + base: '10', + value: 3n, + loc: { start: 11844, end: 11845 } + }, + right: { + kind: 'number', + base: '10', + value: 8n, + loc: { start: 11848, end: 11849 } + }, + loc: { start: 11844, end: 11849 } + } + ], + loc: { start: 11803, end: 11850 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 11860, end: 11869 } + }, + typeArgs: [], + args: [ + { + kind: 'op_unary', + op: '!!', + operand: { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'address', + loc: { start: 11870, end: 11877 } + }, + field: { + kind: 'id', + text: 'hash', + loc: { start: 11878, end: 11882 } + }, + loc: { start: 11870, end: 11882 } + }, + loc: { start: 11870, end: 11884 } + }, + { + kind: 'number', + base: '10', + value: 256n, + loc: { start: 11886, end: 11889 } + } + ], + loc: { start: 11803, end: 11890 } + }, + loc: { start: 11796, end: 11891 } + } + ] + }, + loc: { start: 11621, end: 11893 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 11661, end: 11668 } }, + loc: { start: 11661, end: 11668 } + } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'forceBasechain', + loc: { start: 12980, end: 12994 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'address', + loc: { start: 12995, end: 13002 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 13004, end: 13011 } + }, + typeArgs: [], + loc: { start: 13004, end: 13011 } + }, + loc: { start: 12995, end: 13011 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'REWRITESTDADDR DROP 138 THROWIF' ] + }, + loc: { start: 12972, end: 13048 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'forceWorkchain', + loc: { start: 14243, end: 14257 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'address', + loc: { start: 14258, end: 14265 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 14267, end: 14274 } + }, + typeArgs: [], + loc: { start: 14267, end: 14274 } + }, + loc: { start: 14258, end: 14274 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'workchain', + loc: { start: 14276, end: 14285 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14287, end: 14290 } + }, + loc: { start: 14287, end: 14290 } + }, + loc: { start: 14276, end: 14290 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'errorCode', + loc: { start: 14292, end: 14301 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14303, end: 14306 } + }, + loc: { start: 14303, end: 14306 } + }, + loc: { start: 14292, end: 14306 } + } + ], + body: { + kind: 'asm_body', + shuffle: { + args: [ + { + kind: 'id', + text: 'errorCode', + loc: { start: 14210, end: 14219 } + }, + { + kind: 'id', + text: 'workchain', + loc: { start: 14220, end: 14229 } + }, + { + kind: 'id', + text: 'address', + loc: { start: 14230, end: 14237 } + } + ], + ret: [] + }, + instructions: [ 'REWRITESTDADDR\n DROP\n CMP\n THROWANYIF' ] + }, + loc: { start: 14206, end: 14362 } + } + ] + }, + 'parseStdAddress' => { + kind: 'tact', + path: 'std/internal/address.tact', + code: '/// Extension function for the `Slice` type. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Casts the `Slice` to an `Address` in a given `chain` ID and returns it. The inverse of `Address.asSlice()` and a safe but more gas-expensive version of `Slice.asAddressUnsafe()`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + "/// let a: Address = myAddress(); // let's assume we're in a basechain\n" + + '/// let a2: Address = a.asSlice().asAddress(0); // so the chain ID is 0\n' + + '///\n' + + '/// a == a2; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 136: [Invalid standard address] — Thrown when the given `Slice` contains an invalid\n' + + '/// tag prefix (not `0b100`) or an invalid account ID length (not 256 bits).\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#sliceasaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#sliceasaddressunsafe\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#addressasslice\n' + + '///\n' + + '/// [Invalid standard address]: https://docs.tact-lang.org/book/exit-codes#136\n' + + '///\n' + + 'extends fun asAddress(self: Slice, chain: Int): Address {\n' + + ' // 11 bits for the prefix,\n' + + ' // 256 bits for the address itself\n' + + ' throwUnless(TactExitCodeInvalidStandardAddress, self.bits() == 267);\n' + + '\n' + + ' if (chain == -1) {\n' + + ' // 1279 = 0b100_1111_1111,\n' + + ' // i.e. internal address prefix and chain ID -1\n' + + ' throwUnless(TactExitCodeInvalidStandardAddress, self.preloadUint(11) == 1279);\n' + + ' } else {\n' + + ' // Only check the correct internal address prefix,\n' + + ' // but do not verify the chain ID\n' + + ' throwUnless(TactExitCodeInvalidStandardAddress, self.preloadUint(3) == 4);\n' + + ' }\n' + + '\n' + + ' // Proceed with the cast\n' + + ' return self.asAddressUnsafe();\n' + + '}\n' + + '\n' + + '/// Extension function for the `Slice` type. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Unsafely casts the `Slice` to an `Address` and returns it. The inverse of `Address.asSlice()`.\n' + + '///\n' + + '/// This function does **not** perform any checks on the contents of the `Slice`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let a: Address = myAddress();\n' + + '/// let a2: Address = a.asSlice().asAddressUnsafe();\n' + + '///\n' + + '/// a == a2; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// Use it only if you want to optimize the code for gas and can guarantee in advance that the `Slice` contains the data of an `Address`.\n' + + '///\n' + + '/// Otherwise, use a safer but more gas-expensive `Slice.asAddress()` function.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#sliceasaddressunsafe\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#sliceasaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#addressasslice\n' + + '///\n' + + 'asm extends fun asAddressUnsafe(self: Slice): Address {}\n' + + '\n' + + '/// Extension function for the `Address` type.\n' + + '///\n' + + '/// Casts `self` back to the underlying `Slice` and returns it. The inverse of `Slice.asAddressUnsafe()`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let a: Address = myAddress();\n' + + '/// let fizz: Slice = beginCell().storeAddress(a).asSlice();\n' + + '/// let buzz: Slice = a.asSlice(); // cheap, unlike the previous statement\n' + + '///\n' + + '/// fizz == buzz; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#addressasslice\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#sliceasaddressunsafe\n' + + '///\n' + + 'asm extends fun asSlice(self: Address): Slice {}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Creates a new `Address` based on the `chain` ID and the SHA-256 encoded `hash` value (account ID).\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// Attempts to specify an uncommon `chain` ID (not -1 or 0) that can be detected in compile-time will result in a compilation error.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let oldTonFoundationAddr: Address =\n' + + '/// newAddress(0, 0x83dfd552e63729b472fcbcc8c45ebcc6691702558b68ec7527e1ba403a0f31a8);\n' + + '/// // ↑ ↑\n' + + "/// // | sha-256 hash of contract's init package (StateInit)\n" + + '/// // chain id: 0 is a workchain, -1 is a masterchain\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-addresses#newaddress\n' + + '///\n' + + 'inline fun newAddress(chain: Int, hash: Int): Address {\n' + + ' return beginCell()\n' + + ' .storeUint(0b10_0, 3)\n' + + ' .storeInt(chain, 8)\n' + + ' .storeUint(hash, 256)\n' + + ' .endCell()\n' + + ' .asSlice()\n' + + ' .asAddressUnsafe();\n' + + '}\n' + + '\n' + + '/// Struct representing the standard address on TON Blockchain with signed 8-bit `workchain` ID and an unsigned 256-bit `address` in the specified `workchain`. Available since Tact 1.5.0.\n' + + '///\n' + + '/// At the moment, only `workchain` IDs used on TON are 0 of the basechain and -1 of the masterchain.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#parsestdaddress\n' + + '/// * https://github.com/ton-blockchain/ton/blob/master/crypto/block/block.tlb#L105-L106\n' + + '///\n' + + 'struct StdAddress {\n' + + ' workchain: Int as int8;\n' + + ' address: Int as uint256;\n' + + '}\n' + + '\n' + + '/// Struct representing the address of variable length with signed 32-bit `workchain` ID and a `Slice` containing unsigned `address` in the specified `workchain`. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Variable-length addresses are intended for future extensions, and while validators must be ready to accept them in inbound messages, the standard (non-variable) addresses are used whenever possible.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#parsevaraddress\n' + + '/// * https://github.com/ton-blockchain/ton/blob/master/crypto/block/block.tlb#L107-L108\n' + + '///\n' + + 'struct VarAddress {\n' + + ' workchain: Int as int32;\n' + + ' address: Slice;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Converts a `slice` containing an address into the `StdAddress` Struct and returns it.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let addr = address("EQDtFpEwcFAEcRe5mLVh2N6C0x-_hJEM7W61_JLnSF74p4q2");\n' + + '/// let parsedAddr = parseStdAddress(addr.asSlice());\n' + + '///\n' + + '/// parsedAddr.workchain; // 0\n' + + '/// parsedAddr.address; // 107...287\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-addresses#parsestdaddress\n' + + '///\n' + + 'asm fun parseStdAddress(slice: Slice): StdAddress { REWRITESTDADDR }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Converts a `slice` containing an address of variable length into the `VarAddress` Struct and returns it.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let varAddrSlice = beginCell()\n' + + '/// .storeUint(6, 3) // to recognize the following as a VarAddress\n' + + '/// .storeUint(123, 9) // make address occupy 123 bits\n' + + '/// .storeUint(234, 32) // specify workchain ID of 234\n' + + '/// .storeUint(345, 123) // specify address of 345\n' + + '/// .asSlice();\n' + + '/// let parsedVarAddr = parseVarAddress(varAddrSlice);\n' + + '///\n' + + '/// parsedVarAddr.workchain; // 234\n' + + '/// parsedVarAddr.address; // CS{Cell{002...2b3} bits: 44..167; refs: 0..0}\n' + + '/// parsedVarAddr.address.loadUint(123); // 345\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-addresses#parsevaraddress\n' + + '///\n' + + 'asm fun parseVarAddress(slice: Slice): VarAddress { REWRITEVARADDR }\n' + + '\n' + + '/// Extension mutation function for the `Slice` type.\n' + + '///\n' + + '/// Loads and returns an `Address` from the `Slice`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let s: Slice = beginCell().storeAddress(myAddress()).asSlice();\n' + + '/// let fizz: Address = s.loadAddress();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + "/// * 8: [Cell overflow] — Thrown when attempting to load an `Address` when `Slice` doesn't contain it.\n" + + '/// * 9: [Cell underflow] — Thrown when attempting to load more data than `Slice` contains.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#sliceloadaddress\n' + + '///\n' + + '/// [Cell overflow]: https://docs.tact-lang.org/book/exit-codes#8\n' + + '/// [Cell underflow]: https://docs.tact-lang.org/book/exit-codes#9\n' + + '///\n' + + 'asm(-> 1 0) extends mutates fun loadAddress(self: Slice): Address { LDMSGADDR }\n' + + '\n' + + '/// Extension mutation function for the `Slice` type. Available since Tact 1.6.2.\n' + + '///\n' + + '/// Skips an `Address` from the `Slice`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let s1: Slice = beginCell()\n' + + '/// .storeAddress(myAddress())\n' + + '/// .storeUint(42, 32)\n' + + '/// .asSlice();\n' + + '///\n' + + '/// s1.skipAddress();\n' + + '/// let fizz: Int = s1.loadUint(32); // 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + "/// * 8: [Cell overflow] — Thrown when attempting to skip an `Address` when `Slice` doesn't contain it.\n" + + '/// * 9: [Cell underflow] — Thrown when attempting to skip more data than `Slice` contains.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#sliceskipaddress\n' + + '///\n' + + '/// [Cell overflow]: https://docs.tact-lang.org/book/exit-codes#8\n' + + '/// [Cell underflow]: https://docs.tact-lang.org/book/exit-codes#9\n' + + '///\n' + + 'asm extends mutates fun skipAddress(self: Slice) { LDMSGADDR NIP }\n' + + '\n' + + '/// Extension function for the `Builder` type.\n' + + '///\n' + + '/// Stores the `address` in the copy of the `Builder`. Returns that copy.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b.storeAddress(myAddress());\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 8: [Cell overflow] — Thrown when attempting to store an `address` into the `Builder` when it cannot fit it.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#builderstoreaddress\n' + + '///\n' + + '/// [Cell overflow]: https://docs.tact-lang.org/book/exit-codes#8\n' + + '///\n' + + 'asm extends fun storeAddress(self: Builder, address: Address): Builder { STSLICER }\n' + + '\n' + + '/// Struct representing a basechain address. Available since Tact 1.6.0.\n' + + '///\n' + + '/// A basechain address (workchain 0) can be either empty (null hash) or contain a 256-bit hash value.\n' + + '///\n' + + 'struct BasechainAddress {\n' + + ' hash: Int?;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Creates and returns an empty basechain address with a null hash.\n' + + '///\n' + + '/// When serialized, an empty basechain address is represented as `addr_none`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let emptyAddr: BasechainAddress = emptyBasechainAddress();\n' + + '/// emptyAddr.hash == null; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + 'inline fun emptyBasechainAddress(): BasechainAddress {\n' + + ' return BasechainAddress { hash: null };\n' + + '}\n' + + '\n' + + '/// Global f'... 4363 more characters, + imports: [], + items: [ + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'asAddress', + loc: { start: 998, end: 1007 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 1034, end: 1041 } + }, + typeArgs: [], + loc: { start: 1034, end: 1041 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'chain', + loc: { start: 1021, end: 1026 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1028, end: 1031 } + }, + loc: { start: 1028, end: 1031 } + }, + loc: { start: 1021, end: 1031 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throwUnless', + loc: { start: 1118, end: 1129 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'TactExitCodeInvalidStandardAddress', + loc: { start: 1130, end: 1164 } + }, + { + kind: 'op_binary', + op: '==', + left: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 1166, end: 1170 } + }, + method: { + kind: 'id', + text: 'bits', + loc: { start: 1171, end: 1175 } + }, + typeArgs: [], + args: [], + loc: { start: 1166, end: 1177 } + }, + right: { + kind: 'number', + base: '10', + value: 267n, + loc: { start: 1181, end: 1184 } + }, + loc: { start: 1166, end: 1184 } + } + ], + loc: { start: 1118, end: 1185 } + }, + loc: { start: 1118, end: 1186 } + }, + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'chain', + loc: { start: 1196, end: 1201 } + }, + right: { + kind: 'op_unary', + op: '-', + operand: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1206, end: 1207 } + }, + loc: { start: 1205, end: 1207 } + }, + loc: { start: 1196, end: 1207 } + }, + trueStatements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throwUnless', + loc: { start: 1310, end: 1321 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'TactExitCodeInvalidStandardAddress', + loc: { start: 1322, end: 1356 } + }, + { + kind: 'op_binary', + op: '==', + left: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 1358, end: 1362 } + }, + method: { + kind: 'id', + text: 'preloadUint', + loc: { start: 1363, end: 1374 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 11n, + loc: { start: 1375, end: 1377 } + } + ], + loc: { start: 1358, end: 1378 } + }, + right: { + kind: 'number', + base: '10', + value: 1279n, + loc: { start: 1382, end: 1386 } + }, + loc: { start: 1358, end: 1386 } + } + ], + loc: { start: 1310, end: 1387 } + }, + loc: { start: 1310, end: 1388 } + } + ], + falseStatements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throwUnless', + loc: { start: 1511, end: 1522 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'TactExitCodeInvalidStandardAddress', + loc: { start: 1523, end: 1557 } + }, + { + kind: 'op_binary', + op: '==', + left: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 1559, end: 1563 } + }, + method: { + kind: 'id', + text: 'preloadUint', + loc: { start: 1564, end: 1575 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 3n, + loc: { start: 1576, end: 1577 } + } + ], + loc: { start: 1559, end: 1578 } + }, + right: { + kind: 'number', + base: '10', + value: 4n, + loc: { start: 1582, end: 1583 } + }, + loc: { start: 1559, end: 1583 } + } + ], + loc: { start: 1511, end: 1584 } + }, + loc: { start: 1511, end: 1585 } + } + ], + loc: { start: 1192, end: 1591 } + }, + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 1633, end: 1637 } + }, + method: { + kind: 'id', + text: 'asAddressUnsafe', + loc: { start: 1638, end: 1653 } + }, + typeArgs: [], + args: [], + loc: { start: 1633, end: 1655 } + }, + loc: { start: 1626, end: 1656 } + } + ] + }, + loc: { start: 986, end: 1658 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 1014, end: 1019 } }, + loc: { start: 1014, end: 1019 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'asAddressUnsafe', + loc: { start: 2554, end: 2569 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 2584, end: 2591 } + }, + typeArgs: [], + loc: { start: 2584, end: 2591 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ '' ] + }, + loc: { start: 2538, end: 2594 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 2576, end: 2581 } }, + loc: { start: 2576, end: 2581 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'asSlice', + loc: { start: 3188, end: 3195 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 3212, end: 3217 } }, + loc: { start: 3212, end: 3217 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ '' ] + }, + loc: { start: 3172, end: 3220 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3202, end: 3209 } + }, + typeArgs: [], + loc: { start: 3202, end: 3209 } + } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'newAddress', + loc: { start: 4029, end: 4039 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 4064, end: 4071 } + }, + typeArgs: [], + loc: { start: 4064, end: 4071 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'chain', + loc: { start: 4040, end: 4045 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4047, end: 4050 } + }, + loc: { start: 4047, end: 4050 } + }, + loc: { start: 4040, end: 4050 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'hash', + loc: { start: 4052, end: 4056 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4058, end: 4061 } + }, + loc: { start: 4058, end: 4061 } + }, + loc: { start: 4052, end: 4061 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'static_call', + function: { + kind: 'id', + text: 'beginCell', + loc: { start: 4085, end: 4094 } + }, + typeArgs: [], + args: [], + loc: { start: 4085, end: 4096 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 4106, end: 4115 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '2', + value: 4n, + loc: { start: 4116, end: 4122 } + }, + { + kind: 'number', + base: '10', + value: 3n, + loc: { start: 4124, end: 4125 } + } + ], + loc: { start: 4085, end: 4126 } + }, + method: { + kind: 'id', + text: 'storeInt', + loc: { start: 4136, end: 4144 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'chain', + loc: { start: 4145, end: 4150 } + }, + { + kind: 'number', + base: '10', + value: 8n, + loc: { start: 4152, end: 4153 } + } + ], + loc: { start: 4085, end: 4154 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 4164, end: 4173 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'hash', + loc: { start: 4174, end: 4178 } + }, + { + kind: 'number', + base: '10', + value: 256n, + loc: { start: 4180, end: 4183 } + } + ], + loc: { start: 4085, end: 4184 } + }, + method: { + kind: 'id', + text: 'endCell', + loc: { start: 4194, end: 4201 } + }, + typeArgs: [], + args: [], + loc: { start: 4085, end: 4203 } + }, + method: { + kind: 'id', + text: 'asSlice', + loc: { start: 4213, end: 4220 } + }, + typeArgs: [], + args: [], + loc: { start: 4085, end: 4222 } + }, + method: { + kind: 'id', + text: 'asAddressUnsafe', + loc: { start: 4232, end: 4247 } + }, + typeArgs: [], + args: [], + loc: { start: 4085, end: 4249 } + }, + loc: { start: 4078, end: 4250 } + } + ] + }, + loc: { start: 4018, end: 4252 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'StdAddress', + loc: { start: 4729, end: 4739 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'workchain', + loc: { start: 4746, end: 4755 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 8, + loc: { start: 4757, end: 4768 } + }, + loc: { start: 4757, end: 4760 } + }, + initializer: undefined, + loc: { start: 4746, end: 4768 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'address', + loc: { start: 4774, end: 4781 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'unsigned', + width: 256, + loc: { start: 4783, end: 4797 } + }, + loc: { start: 4783, end: 4786 } + }, + initializer: undefined, + loc: { start: 4774, end: 4797 } + } + ], + loc: { start: 4722, end: 4800 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'VarAddress', + loc: { start: 5381, end: 5391 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'workchain', + loc: { start: 5398, end: 5407 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 32, + loc: { start: 5409, end: 5421 } + }, + loc: { start: 5409, end: 5412 } + }, + initializer: undefined, + loc: { start: 5398, end: 5421 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'address', + loc: { start: 5427, end: 5434 } + }, + type: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 5436, end: 5441 } }, + loc: { start: 5436, end: 5441 } + }, + initializer: undefined, + loc: { start: 5427, end: 5441 } + } + ], + loc: { start: 5374, end: 5444 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'parseStdAddress', + loc: { start: 5946, end: 5961 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StdAddress', + loc: { start: 5977, end: 5987 } + }, + typeArgs: [], + loc: { start: 5977, end: 5987 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'slice', + loc: { start: 5962, end: 5967 } + }, + type: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 5969, end: 5974 } }, + loc: { start: 5969, end: 5974 } + }, + loc: { start: 5962, end: 5974 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'REWRITESTDADDR' ] + }, + loc: { start: 5938, end: 6006 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'parseVarAddress', + loc: { start: 6898, end: 6913 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'VarAddress', + loc: { start: 6929, end: 6939 } + }, + typeArgs: [], + loc: { start: 6929, end: 6939 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'slice', + loc: { start: 6914, end: 6919 } + }, + type: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 6921, end: 6926 } }, + loc: { start: 6921, end: 6926 } + }, + loc: { start: 6914, end: 6926 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'REWRITEVARADDR' ] + }, + loc: { start: 6890, end: 6958 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadAddress', + loc: { start: 7707, end: 7718 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 7733, end: 7740 } + }, + typeArgs: [], + loc: { start: 7733, end: 7740 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { + args: [], + ret: [ + { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 7682, end: 7683 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 7684, end: 7685 } + } + ] + }, + instructions: [ 'LDMSGADDR' ] + }, + loc: { start: 7675, end: 7754 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 7725, end: 7730 } }, + loc: { start: 7725, end: 7730 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'skipAddress', + loc: { start: 8601, end: 8612 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LDMSGADDR NIP' ] + }, + loc: { start: 8577, end: 8643 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 8619, end: 8624 } }, + loc: { start: 8619, end: 8624 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeAddress', + loc: { start: 9222, end: 9234 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 9269, end: 9276 } }, + loc: { start: 9269, end: 9276 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'address', + loc: { start: 9250, end: 9257 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 9259, end: 9266 } + }, + typeArgs: [], + loc: { start: 9259, end: 9266 } + }, + loc: { start: 9250, end: 9266 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'STSLICER' ] + }, + loc: { start: 9206, end: 9289 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 9241, end: 9248 } }, + loc: { start: 9241, end: 9248 } + } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 9482, end: 9498 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'hash', + loc: { start: 9505, end: 9509 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 9514, end: 9515 } + }, + typeArgs: [ + { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9511, end: 9514 } + }, + loc: { start: 9511, end: 9514 } + } + ], + loc: { start: 9514, end: 9515 } + }, + initializer: undefined, + loc: { start: 9505, end: 9515 } + } + ], + loc: { start: 9475, end: 9518 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'emptyBasechainAddress', + loc: { start: 9897, end: 9918 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 9922, end: 9938 } + }, + typeArgs: [], + loc: { start: 9922, end: 9938 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'struct_instance', + type: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 9952, end: 9968 } + }, + typeArgs: [], + args: [ + { + kind: 'struct_field_initializer', + field: { + kind: 'id', + text: 'hash', + loc: { start: 9971, end: 9975 } + }, + initializer: { kind: 'null', loc: { start: 9977, end: 9981 } }, + loc: { start: 9971, end: 9981 } + } + ], + loc: { start: 9952, end: 9983 } + }, + loc: { start: 9945, end: 9984 } + } + ] + }, + loc: { start: 9886, end: 9986 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'newBasechainAddress', + loc: { start: 10311, end: 10330 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 10343, end: 10359 } + }, + typeArgs: [], + loc: { start: 10343, end: 10359 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'hash', + loc: { start: 10331, end: 10335 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10337, end: 10340 } + }, + loc: { start: 10337, end: 10340 } + }, + loc: { start: 10331, end: 10340 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'struct_instance', + type: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 10373, end: 10389 } + }, + typeArgs: [], + args: [ + { + kind: 'struct_field_initializer', + field: { + kind: 'id', + text: 'hash', + loc: { start: 10392, end: 10396 } + }, + initializer: { + kind: 'var', + name: 'hash', + loc: { start: 10392, end: 10396 } + }, + loc: { start: 10392, end: 10396 } + } + ], + loc: { start: 10373, end: 10398 } + }, + loc: { start: 10366, end: 10399 } + } + ] + }, + loc: { start: 10300, end: 10401 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'contractBasechainAddress', + loc: { start: 10865, end: 10889 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 10905, end: 10921 } + }, + typeArgs: [], + loc: { start: 10905, end: 10921 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 's', + loc: { start: 10890, end: 10891 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 10893, end: 10902 } + }, + typeArgs: [], + loc: { start: 10893, end: 10902 } + }, + loc: { start: 10890, end: 10902 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'hash', + loc: { start: 10932, end: 10936 } + }, + type: undefined, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractHash', + loc: { start: 10939, end: 10951 } + }, + typeArgs: [], + args: [ + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 10952, end: 10953 } + }, + field: { + kind: 'id', + text: 'code', + loc: { start: 10954, end: 10958 } + }, + loc: { start: 10952, end: 10958 } + }, + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 10960, end: 10961 } + }, + field: { + kind: 'id', + text: 'data', + loc: { start: 10962, end: 10966 } + }, + loc: { start: 10960, end: 10966 } + } + ], + loc: { start: 10939, end: 10967 } + }, + loc: { start: 10928, end: 10968 } + }, + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'newBasechainAddress', + loc: { start: 10980, end: 10999 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'hash', + loc: { start: 11000, end: 11004 } + } + ], + loc: { start: 10980, end: 11005 } + }, + loc: { start: 10973, end: 11006 } + } + ] + }, + loc: { start: 10854, end: 11008 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeBasechainAddress', + loc: { start: 11633, end: 11654 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 11698, end: 11705 } + }, + loc: { start: 11698, end: 11705 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'address', + loc: { start: 11670, end: 11677 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 11679, end: 11695 } + }, + typeArgs: [], + loc: { start: 11679, end: 11695 } + }, + loc: { start: 11670, end: 11695 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'address', + loc: { start: 11716, end: 11723 } + }, + field: { + kind: 'id', + text: 'hash', + loc: { start: 11724, end: 11728 } + }, + loc: { start: 11716, end: 11728 } + }, + right: { + kind: 'null', + loc: { start: 11732, end: 11736 } + }, + loc: { start: 11716, end: 11736 } + }, + trueStatements: [ + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 11755, end: 11759 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 11760, end: 11769 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 11770, end: 11771 } + }, + { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 11773, end: 11774 } + } + ], + loc: { start: 11755, end: 11775 } + }, + loc: { start: 11748, end: 11776 } + } + ], + falseStatements: undefined, + loc: { start: 11712, end: 11790 } + }, + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 11803, end: 11807 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 11817, end: 11826 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '2', + value: 1024n, + loc: { start: 11827, end: 11842 } + }, + { + kind: 'op_binary', + op: '+', + left: { + kind: 'number', + base: '10', + value: 3n, + loc: { start: 11844, end: 11845 } + }, + right: { + kind: 'number', + base: '10', + value: 8n, + loc: { start: 11848, end: 11849 } + }, + loc: { start: 11844, end: 11849 } + } + ], + loc: { start: 11803, end: 11850 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 11860, end: 11869 } + }, + typeArgs: [], + args: [ + { + kind: 'op_unary', + op: '!!', + operand: { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'address', + loc: { start: 11870, end: 11877 } + }, + field: { + kind: 'id', + text: 'hash', + loc: { start: 11878, end: 11882 } + }, + loc: { start: 11870, end: 11882 } + }, + loc: { start: 11870, end: 11884 } + }, + { + kind: 'number', + base: '10', + value: 256n, + loc: { start: 11886, end: 11889 } + } + ], + loc: { start: 11803, end: 11890 } + }, + loc: { start: 11796, end: 11891 } + } + ] + }, + loc: { start: 11621, end: 11893 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 11661, end: 11668 } }, + loc: { start: 11661, end: 11668 } + } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'forceBasechain', + loc: { start: 12980, end: 12994 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'address', + loc: { start: 12995, end: 13002 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 13004, end: 13011 } + }, + typeArgs: [], + loc: { start: 13004, end: 13011 } + }, + loc: { start: 12995, end: 13011 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'REWRITESTDADDR DROP 138 THROWIF' ] + }, + loc: { start: 12972, end: 13048 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'forceWorkchain', + loc: { start: 14243, end: 14257 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'address', + loc: { start: 14258, end: 14265 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 14267, end: 14274 } + }, + typeArgs: [], + loc: { start: 14267, end: 14274 } + }, + loc: { start: 14258, end: 14274 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'workchain', + loc: { start: 14276, end: 14285 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14287, end: 14290 } + }, + loc: { start: 14287, end: 14290 } + }, + loc: { start: 14276, end: 14290 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'errorCode', + loc: { start: 14292, end: 14301 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14303, end: 14306 } + }, + loc: { start: 14303, end: 14306 } + }, + loc: { start: 14292, end: 14306 } + } + ], + body: { + kind: 'asm_body', + shuffle: { + args: [ + { + kind: 'id', + text: 'errorCode', + loc: { start: 14210, end: 14219 } + }, + { + kind: 'id', + text: 'workchain', + loc: { start: 14220, end: 14229 } + }, + { + kind: 'id', + text: 'address', + loc: { start: 14230, end: 14237 } + } + ], + ret: [] + }, + instructions: [ 'REWRITESTDADDR\n DROP\n CMP\n THROWANYIF' ] + }, + loc: { start: 14206, end: 14362 } + } + ] + }, + 'parseVarAddress' => { + kind: 'tact', + path: 'std/internal/address.tact', + code: '/// Extension function for the `Slice` type. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Casts the `Slice` to an `Address` in a given `chain` ID and returns it. The inverse of `Address.asSlice()` and a safe but more gas-expensive version of `Slice.asAddressUnsafe()`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + "/// let a: Address = myAddress(); // let's assume we're in a basechain\n" + + '/// let a2: Address = a.asSlice().asAddress(0); // so the chain ID is 0\n' + + '///\n' + + '/// a == a2; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 136: [Invalid standard address] — Thrown when the given `Slice` contains an invalid\n' + + '/// tag prefix (not `0b100`) or an invalid account ID length (not 256 bits).\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#sliceasaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#sliceasaddressunsafe\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#addressasslice\n' + + '///\n' + + '/// [Invalid standard address]: https://docs.tact-lang.org/book/exit-codes#136\n' + + '///\n' + + 'extends fun asAddress(self: Slice, chain: Int): Address {\n' + + ' // 11 bits for the prefix,\n' + + ' // 256 bits for the address itself\n' + + ' throwUnless(TactExitCodeInvalidStandardAddress, self.bits() == 267);\n' + + '\n' + + ' if (chain == -1) {\n' + + ' // 1279 = 0b100_1111_1111,\n' + + ' // i.e. internal address prefix and chain ID -1\n' + + ' throwUnless(TactExitCodeInvalidStandardAddress, self.preloadUint(11) == 1279);\n' + + ' } else {\n' + + ' // Only check the correct internal address prefix,\n' + + ' // but do not verify the chain ID\n' + + ' throwUnless(TactExitCodeInvalidStandardAddress, self.preloadUint(3) == 4);\n' + + ' }\n' + + '\n' + + ' // Proceed with the cast\n' + + ' return self.asAddressUnsafe();\n' + + '}\n' + + '\n' + + '/// Extension function for the `Slice` type. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Unsafely casts the `Slice` to an `Address` and returns it. The inverse of `Address.asSlice()`.\n' + + '///\n' + + '/// This function does **not** perform any checks on the contents of the `Slice`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let a: Address = myAddress();\n' + + '/// let a2: Address = a.asSlice().asAddressUnsafe();\n' + + '///\n' + + '/// a == a2; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// Use it only if you want to optimize the code for gas and can guarantee in advance that the `Slice` contains the data of an `Address`.\n' + + '///\n' + + '/// Otherwise, use a safer but more gas-expensive `Slice.asAddress()` function.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#sliceasaddressunsafe\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#sliceasaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#addressasslice\n' + + '///\n' + + 'asm extends fun asAddressUnsafe(self: Slice): Address {}\n' + + '\n' + + '/// Extension function for the `Address` type.\n' + + '///\n' + + '/// Casts `self` back to the underlying `Slice` and returns it. The inverse of `Slice.asAddressUnsafe()`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let a: Address = myAddress();\n' + + '/// let fizz: Slice = beginCell().storeAddress(a).asSlice();\n' + + '/// let buzz: Slice = a.asSlice(); // cheap, unlike the previous statement\n' + + '///\n' + + '/// fizz == buzz; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#addressasslice\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#sliceasaddressunsafe\n' + + '///\n' + + 'asm extends fun asSlice(self: Address): Slice {}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Creates a new `Address` based on the `chain` ID and the SHA-256 encoded `hash` value (account ID).\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// Attempts to specify an uncommon `chain` ID (not -1 or 0) that can be detected in compile-time will result in a compilation error.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let oldTonFoundationAddr: Address =\n' + + '/// newAddress(0, 0x83dfd552e63729b472fcbcc8c45ebcc6691702558b68ec7527e1ba403a0f31a8);\n' + + '/// // ↑ ↑\n' + + "/// // | sha-256 hash of contract's init package (StateInit)\n" + + '/// // chain id: 0 is a workchain, -1 is a masterchain\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-addresses#newaddress\n' + + '///\n' + + 'inline fun newAddress(chain: Int, hash: Int): Address {\n' + + ' return beginCell()\n' + + ' .storeUint(0b10_0, 3)\n' + + ' .storeInt(chain, 8)\n' + + ' .storeUint(hash, 256)\n' + + ' .endCell()\n' + + ' .asSlice()\n' + + ' .asAddressUnsafe();\n' + + '}\n' + + '\n' + + '/// Struct representing the standard address on TON Blockchain with signed 8-bit `workchain` ID and an unsigned 256-bit `address` in the specified `workchain`. Available since Tact 1.5.0.\n' + + '///\n' + + '/// At the moment, only `workchain` IDs used on TON are 0 of the basechain and -1 of the masterchain.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#parsestdaddress\n' + + '/// * https://github.com/ton-blockchain/ton/blob/master/crypto/block/block.tlb#L105-L106\n' + + '///\n' + + 'struct StdAddress {\n' + + ' workchain: Int as int8;\n' + + ' address: Int as uint256;\n' + + '}\n' + + '\n' + + '/// Struct representing the address of variable length with signed 32-bit `workchain` ID and a `Slice` containing unsigned `address` in the specified `workchain`. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Variable-length addresses are intended for future extensions, and while validators must be ready to accept them in inbound messages, the standard (non-variable) addresses are used whenever possible.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#parsevaraddress\n' + + '/// * https://github.com/ton-blockchain/ton/blob/master/crypto/block/block.tlb#L107-L108\n' + + '///\n' + + 'struct VarAddress {\n' + + ' workchain: Int as int32;\n' + + ' address: Slice;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Converts a `slice` containing an address into the `StdAddress` Struct and returns it.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let addr = address("EQDtFpEwcFAEcRe5mLVh2N6C0x-_hJEM7W61_JLnSF74p4q2");\n' + + '/// let parsedAddr = parseStdAddress(addr.asSlice());\n' + + '///\n' + + '/// parsedAddr.workchain; // 0\n' + + '/// parsedAddr.address; // 107...287\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-addresses#parsestdaddress\n' + + '///\n' + + 'asm fun parseStdAddress(slice: Slice): StdAddress { REWRITESTDADDR }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Converts a `slice` containing an address of variable length into the `VarAddress` Struct and returns it.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let varAddrSlice = beginCell()\n' + + '/// .storeUint(6, 3) // to recognize the following as a VarAddress\n' + + '/// .storeUint(123, 9) // make address occupy 123 bits\n' + + '/// .storeUint(234, 32) // specify workchain ID of 234\n' + + '/// .storeUint(345, 123) // specify address of 345\n' + + '/// .asSlice();\n' + + '/// let parsedVarAddr = parseVarAddress(varAddrSlice);\n' + + '///\n' + + '/// parsedVarAddr.workchain; // 234\n' + + '/// parsedVarAddr.address; // CS{Cell{002...2b3} bits: 44..167; refs: 0..0}\n' + + '/// parsedVarAddr.address.loadUint(123); // 345\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-addresses#parsevaraddress\n' + + '///\n' + + 'asm fun parseVarAddress(slice: Slice): VarAddress { REWRITEVARADDR }\n' + + '\n' + + '/// Extension mutation function for the `Slice` type.\n' + + '///\n' + + '/// Loads and returns an `Address` from the `Slice`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let s: Slice = beginCell().storeAddress(myAddress()).asSlice();\n' + + '/// let fizz: Address = s.loadAddress();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + "/// * 8: [Cell overflow] — Thrown when attempting to load an `Address` when `Slice` doesn't contain it.\n" + + '/// * 9: [Cell underflow] — Thrown when attempting to load more data than `Slice` contains.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#sliceloadaddress\n' + + '///\n' + + '/// [Cell overflow]: https://docs.tact-lang.org/book/exit-codes#8\n' + + '/// [Cell underflow]: https://docs.tact-lang.org/book/exit-codes#9\n' + + '///\n' + + 'asm(-> 1 0) extends mutates fun loadAddress(self: Slice): Address { LDMSGADDR }\n' + + '\n' + + '/// Extension mutation function for the `Slice` type. Available since Tact 1.6.2.\n' + + '///\n' + + '/// Skips an `Address` from the `Slice`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let s1: Slice = beginCell()\n' + + '/// .storeAddress(myAddress())\n' + + '/// .storeUint(42, 32)\n' + + '/// .asSlice();\n' + + '///\n' + + '/// s1.skipAddress();\n' + + '/// let fizz: Int = s1.loadUint(32); // 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + "/// * 8: [Cell overflow] — Thrown when attempting to skip an `Address` when `Slice` doesn't contain it.\n" + + '/// * 9: [Cell underflow] — Thrown when attempting to skip more data than `Slice` contains.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#sliceskipaddress\n' + + '///\n' + + '/// [Cell overflow]: https://docs.tact-lang.org/book/exit-codes#8\n' + + '/// [Cell underflow]: https://docs.tact-lang.org/book/exit-codes#9\n' + + '///\n' + + 'asm extends mutates fun skipAddress(self: Slice) { LDMSGADDR NIP }\n' + + '\n' + + '/// Extension function for the `Builder` type.\n' + + '///\n' + + '/// Stores the `address` in the copy of the `Builder`. Returns that copy.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b.storeAddress(myAddress());\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 8: [Cell overflow] — Thrown when attempting to store an `address` into the `Builder` when it cannot fit it.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#builderstoreaddress\n' + + '///\n' + + '/// [Cell overflow]: https://docs.tact-lang.org/book/exit-codes#8\n' + + '///\n' + + 'asm extends fun storeAddress(self: Builder, address: Address): Builder { STSLICER }\n' + + '\n' + + '/// Struct representing a basechain address. Available since Tact 1.6.0.\n' + + '///\n' + + '/// A basechain address (workchain 0) can be either empty (null hash) or contain a 256-bit hash value.\n' + + '///\n' + + 'struct BasechainAddress {\n' + + ' hash: Int?;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Creates and returns an empty basechain address with a null hash.\n' + + '///\n' + + '/// When serialized, an empty basechain address is represented as `addr_none`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let emptyAddr: BasechainAddress = emptyBasechainAddress();\n' + + '/// emptyAddr.hash == null; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + 'inline fun emptyBasechainAddress(): BasechainAddress {\n' + + ' return BasechainAddress { hash: null };\n' + + '}\n' + + '\n' + + '/// Global f'... 4363 more characters, + imports: [], + items: [ + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'asAddress', + loc: { start: 998, end: 1007 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 1034, end: 1041 } + }, + typeArgs: [], + loc: { start: 1034, end: 1041 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'chain', + loc: { start: 1021, end: 1026 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1028, end: 1031 } + }, + loc: { start: 1028, end: 1031 } + }, + loc: { start: 1021, end: 1031 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throwUnless', + loc: { start: 1118, end: 1129 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'TactExitCodeInvalidStandardAddress', + loc: { start: 1130, end: 1164 } + }, + { + kind: 'op_binary', + op: '==', + left: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 1166, end: 1170 } + }, + method: { + kind: 'id', + text: 'bits', + loc: { start: 1171, end: 1175 } + }, + typeArgs: [], + args: [], + loc: { start: 1166, end: 1177 } + }, + right: { + kind: 'number', + base: '10', + value: 267n, + loc: { start: 1181, end: 1184 } + }, + loc: { start: 1166, end: 1184 } + } + ], + loc: { start: 1118, end: 1185 } + }, + loc: { start: 1118, end: 1186 } + }, + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'chain', + loc: { start: 1196, end: 1201 } + }, + right: { + kind: 'op_unary', + op: '-', + operand: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1206, end: 1207 } + }, + loc: { start: 1205, end: 1207 } + }, + loc: { start: 1196, end: 1207 } + }, + trueStatements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throwUnless', + loc: { start: 1310, end: 1321 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'TactExitCodeInvalidStandardAddress', + loc: { start: 1322, end: 1356 } + }, + { + kind: 'op_binary', + op: '==', + left: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 1358, end: 1362 } + }, + method: { + kind: 'id', + text: 'preloadUint', + loc: { start: 1363, end: 1374 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 11n, + loc: { start: 1375, end: 1377 } + } + ], + loc: { start: 1358, end: 1378 } + }, + right: { + kind: 'number', + base: '10', + value: 1279n, + loc: { start: 1382, end: 1386 } + }, + loc: { start: 1358, end: 1386 } + } + ], + loc: { start: 1310, end: 1387 } + }, + loc: { start: 1310, end: 1388 } + } + ], + falseStatements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throwUnless', + loc: { start: 1511, end: 1522 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'TactExitCodeInvalidStandardAddress', + loc: { start: 1523, end: 1557 } + }, + { + kind: 'op_binary', + op: '==', + left: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 1559, end: 1563 } + }, + method: { + kind: 'id', + text: 'preloadUint', + loc: { start: 1564, end: 1575 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 3n, + loc: { start: 1576, end: 1577 } + } + ], + loc: { start: 1559, end: 1578 } + }, + right: { + kind: 'number', + base: '10', + value: 4n, + loc: { start: 1582, end: 1583 } + }, + loc: { start: 1559, end: 1583 } + } + ], + loc: { start: 1511, end: 1584 } + }, + loc: { start: 1511, end: 1585 } + } + ], + loc: { start: 1192, end: 1591 } + }, + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 1633, end: 1637 } + }, + method: { + kind: 'id', + text: 'asAddressUnsafe', + loc: { start: 1638, end: 1653 } + }, + typeArgs: [], + args: [], + loc: { start: 1633, end: 1655 } + }, + loc: { start: 1626, end: 1656 } + } + ] + }, + loc: { start: 986, end: 1658 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 1014, end: 1019 } }, + loc: { start: 1014, end: 1019 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'asAddressUnsafe', + loc: { start: 2554, end: 2569 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 2584, end: 2591 } + }, + typeArgs: [], + loc: { start: 2584, end: 2591 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ '' ] + }, + loc: { start: 2538, end: 2594 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 2576, end: 2581 } }, + loc: { start: 2576, end: 2581 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'asSlice', + loc: { start: 3188, end: 3195 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 3212, end: 3217 } }, + loc: { start: 3212, end: 3217 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ '' ] + }, + loc: { start: 3172, end: 3220 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3202, end: 3209 } + }, + typeArgs: [], + loc: { start: 3202, end: 3209 } + } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'newAddress', + loc: { start: 4029, end: 4039 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 4064, end: 4071 } + }, + typeArgs: [], + loc: { start: 4064, end: 4071 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'chain', + loc: { start: 4040, end: 4045 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4047, end: 4050 } + }, + loc: { start: 4047, end: 4050 } + }, + loc: { start: 4040, end: 4050 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'hash', + loc: { start: 4052, end: 4056 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4058, end: 4061 } + }, + loc: { start: 4058, end: 4061 } + }, + loc: { start: 4052, end: 4061 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'static_call', + function: { + kind: 'id', + text: 'beginCell', + loc: { start: 4085, end: 4094 } + }, + typeArgs: [], + args: [], + loc: { start: 4085, end: 4096 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 4106, end: 4115 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '2', + value: 4n, + loc: { start: 4116, end: 4122 } + }, + { + kind: 'number', + base: '10', + value: 3n, + loc: { start: 4124, end: 4125 } + } + ], + loc: { start: 4085, end: 4126 } + }, + method: { + kind: 'id', + text: 'storeInt', + loc: { start: 4136, end: 4144 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'chain', + loc: { start: 4145, end: 4150 } + }, + { + kind: 'number', + base: '10', + value: 8n, + loc: { start: 4152, end: 4153 } + } + ], + loc: { start: 4085, end: 4154 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 4164, end: 4173 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'hash', + loc: { start: 4174, end: 4178 } + }, + { + kind: 'number', + base: '10', + value: 256n, + loc: { start: 4180, end: 4183 } + } + ], + loc: { start: 4085, end: 4184 } + }, + method: { + kind: 'id', + text: 'endCell', + loc: { start: 4194, end: 4201 } + }, + typeArgs: [], + args: [], + loc: { start: 4085, end: 4203 } + }, + method: { + kind: 'id', + text: 'asSlice', + loc: { start: 4213, end: 4220 } + }, + typeArgs: [], + args: [], + loc: { start: 4085, end: 4222 } + }, + method: { + kind: 'id', + text: 'asAddressUnsafe', + loc: { start: 4232, end: 4247 } + }, + typeArgs: [], + args: [], + loc: { start: 4085, end: 4249 } + }, + loc: { start: 4078, end: 4250 } + } + ] + }, + loc: { start: 4018, end: 4252 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'StdAddress', + loc: { start: 4729, end: 4739 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'workchain', + loc: { start: 4746, end: 4755 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 8, + loc: { start: 4757, end: 4768 } + }, + loc: { start: 4757, end: 4760 } + }, + initializer: undefined, + loc: { start: 4746, end: 4768 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'address', + loc: { start: 4774, end: 4781 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'unsigned', + width: 256, + loc: { start: 4783, end: 4797 } + }, + loc: { start: 4783, end: 4786 } + }, + initializer: undefined, + loc: { start: 4774, end: 4797 } + } + ], + loc: { start: 4722, end: 4800 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'VarAddress', + loc: { start: 5381, end: 5391 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'workchain', + loc: { start: 5398, end: 5407 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 32, + loc: { start: 5409, end: 5421 } + }, + loc: { start: 5409, end: 5412 } + }, + initializer: undefined, + loc: { start: 5398, end: 5421 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'address', + loc: { start: 5427, end: 5434 } + }, + type: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 5436, end: 5441 } }, + loc: { start: 5436, end: 5441 } + }, + initializer: undefined, + loc: { start: 5427, end: 5441 } + } + ], + loc: { start: 5374, end: 5444 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'parseStdAddress', + loc: { start: 5946, end: 5961 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StdAddress', + loc: { start: 5977, end: 5987 } + }, + typeArgs: [], + loc: { start: 5977, end: 5987 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'slice', + loc: { start: 5962, end: 5967 } + }, + type: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 5969, end: 5974 } }, + loc: { start: 5969, end: 5974 } + }, + loc: { start: 5962, end: 5974 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'REWRITESTDADDR' ] + }, + loc: { start: 5938, end: 6006 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'parseVarAddress', + loc: { start: 6898, end: 6913 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'VarAddress', + loc: { start: 6929, end: 6939 } + }, + typeArgs: [], + loc: { start: 6929, end: 6939 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'slice', + loc: { start: 6914, end: 6919 } + }, + type: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 6921, end: 6926 } }, + loc: { start: 6921, end: 6926 } + }, + loc: { start: 6914, end: 6926 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'REWRITEVARADDR' ] + }, + loc: { start: 6890, end: 6958 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadAddress', + loc: { start: 7707, end: 7718 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 7733, end: 7740 } + }, + typeArgs: [], + loc: { start: 7733, end: 7740 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { + args: [], + ret: [ + { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 7682, end: 7683 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 7684, end: 7685 } + } + ] + }, + instructions: [ 'LDMSGADDR' ] + }, + loc: { start: 7675, end: 7754 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 7725, end: 7730 } }, + loc: { start: 7725, end: 7730 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'skipAddress', + loc: { start: 8601, end: 8612 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LDMSGADDR NIP' ] + }, + loc: { start: 8577, end: 8643 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 8619, end: 8624 } }, + loc: { start: 8619, end: 8624 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeAddress', + loc: { start: 9222, end: 9234 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 9269, end: 9276 } }, + loc: { start: 9269, end: 9276 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'address', + loc: { start: 9250, end: 9257 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 9259, end: 9266 } + }, + typeArgs: [], + loc: { start: 9259, end: 9266 } + }, + loc: { start: 9250, end: 9266 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'STSLICER' ] + }, + loc: { start: 9206, end: 9289 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 9241, end: 9248 } }, + loc: { start: 9241, end: 9248 } + } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 9482, end: 9498 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'hash', + loc: { start: 9505, end: 9509 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 9514, end: 9515 } + }, + typeArgs: [ + { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9511, end: 9514 } + }, + loc: { start: 9511, end: 9514 } + } + ], + loc: { start: 9514, end: 9515 } + }, + initializer: undefined, + loc: { start: 9505, end: 9515 } + } + ], + loc: { start: 9475, end: 9518 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'emptyBasechainAddress', + loc: { start: 9897, end: 9918 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 9922, end: 9938 } + }, + typeArgs: [], + loc: { start: 9922, end: 9938 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'struct_instance', + type: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 9952, end: 9968 } + }, + typeArgs: [], + args: [ + { + kind: 'struct_field_initializer', + field: { + kind: 'id', + text: 'hash', + loc: { start: 9971, end: 9975 } + }, + initializer: { kind: 'null', loc: { start: 9977, end: 9981 } }, + loc: { start: 9971, end: 9981 } + } + ], + loc: { start: 9952, end: 9983 } + }, + loc: { start: 9945, end: 9984 } + } + ] + }, + loc: { start: 9886, end: 9986 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'newBasechainAddress', + loc: { start: 10311, end: 10330 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 10343, end: 10359 } + }, + typeArgs: [], + loc: { start: 10343, end: 10359 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'hash', + loc: { start: 10331, end: 10335 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10337, end: 10340 } + }, + loc: { start: 10337, end: 10340 } + }, + loc: { start: 10331, end: 10340 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'struct_instance', + type: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 10373, end: 10389 } + }, + typeArgs: [], + args: [ + { + kind: 'struct_field_initializer', + field: { + kind: 'id', + text: 'hash', + loc: { start: 10392, end: 10396 } + }, + initializer: { + kind: 'var', + name: 'hash', + loc: { start: 10392, end: 10396 } + }, + loc: { start: 10392, end: 10396 } + } + ], + loc: { start: 10373, end: 10398 } + }, + loc: { start: 10366, end: 10399 } + } + ] + }, + loc: { start: 10300, end: 10401 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'contractBasechainAddress', + loc: { start: 10865, end: 10889 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 10905, end: 10921 } + }, + typeArgs: [], + loc: { start: 10905, end: 10921 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 's', + loc: { start: 10890, end: 10891 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 10893, end: 10902 } + }, + typeArgs: [], + loc: { start: 10893, end: 10902 } + }, + loc: { start: 10890, end: 10902 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'hash', + loc: { start: 10932, end: 10936 } + }, + type: undefined, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractHash', + loc: { start: 10939, end: 10951 } + }, + typeArgs: [], + args: [ + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 10952, end: 10953 } + }, + field: { + kind: 'id', + text: 'code', + loc: { start: 10954, end: 10958 } + }, + loc: { start: 10952, end: 10958 } + }, + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 10960, end: 10961 } + }, + field: { + kind: 'id', + text: 'data', + loc: { start: 10962, end: 10966 } + }, + loc: { start: 10960, end: 10966 } + } + ], + loc: { start: 10939, end: 10967 } + }, + loc: { start: 10928, end: 10968 } + }, + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'newBasechainAddress', + loc: { start: 10980, end: 10999 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'hash', + loc: { start: 11000, end: 11004 } + } + ], + loc: { start: 10980, end: 11005 } + }, + loc: { start: 10973, end: 11006 } + } + ] + }, + loc: { start: 10854, end: 11008 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeBasechainAddress', + loc: { start: 11633, end: 11654 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 11698, end: 11705 } + }, + loc: { start: 11698, end: 11705 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'address', + loc: { start: 11670, end: 11677 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 11679, end: 11695 } + }, + typeArgs: [], + loc: { start: 11679, end: 11695 } + }, + loc: { start: 11670, end: 11695 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'address', + loc: { start: 11716, end: 11723 } + }, + field: { + kind: 'id', + text: 'hash', + loc: { start: 11724, end: 11728 } + }, + loc: { start: 11716, end: 11728 } + }, + right: { + kind: 'null', + loc: { start: 11732, end: 11736 } + }, + loc: { start: 11716, end: 11736 } + }, + trueStatements: [ + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 11755, end: 11759 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 11760, end: 11769 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 11770, end: 11771 } + }, + { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 11773, end: 11774 } + } + ], + loc: { start: 11755, end: 11775 } + }, + loc: { start: 11748, end: 11776 } + } + ], + falseStatements: undefined, + loc: { start: 11712, end: 11790 } + }, + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 11803, end: 11807 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 11817, end: 11826 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '2', + value: 1024n, + loc: { start: 11827, end: 11842 } + }, + { + kind: 'op_binary', + op: '+', + left: { + kind: 'number', + base: '10', + value: 3n, + loc: { start: 11844, end: 11845 } + }, + right: { + kind: 'number', + base: '10', + value: 8n, + loc: { start: 11848, end: 11849 } + }, + loc: { start: 11844, end: 11849 } + } + ], + loc: { start: 11803, end: 11850 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 11860, end: 11869 } + }, + typeArgs: [], + args: [ + { + kind: 'op_unary', + op: '!!', + operand: { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'address', + loc: { start: 11870, end: 11877 } + }, + field: { + kind: 'id', + text: 'hash', + loc: { start: 11878, end: 11882 } + }, + loc: { start: 11870, end: 11882 } + }, + loc: { start: 11870, end: 11884 } + }, + { + kind: 'number', + base: '10', + value: 256n, + loc: { start: 11886, end: 11889 } + } + ], + loc: { start: 11803, end: 11890 } + }, + loc: { start: 11796, end: 11891 } + } + ] + }, + loc: { start: 11621, end: 11893 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 11661, end: 11668 } }, + loc: { start: 11661, end: 11668 } + } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'forceBasechain', + loc: { start: 12980, end: 12994 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'address', + loc: { start: 12995, end: 13002 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 13004, end: 13011 } + }, + typeArgs: [], + loc: { start: 13004, end: 13011 } + }, + loc: { start: 12995, end: 13011 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'REWRITESTDADDR DROP 138 THROWIF' ] + }, + loc: { start: 12972, end: 13048 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'forceWorkchain', + loc: { start: 14243, end: 14257 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'address', + loc: { start: 14258, end: 14265 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 14267, end: 14274 } + }, + typeArgs: [], + loc: { start: 14267, end: 14274 } + }, + loc: { start: 14258, end: 14274 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'workchain', + loc: { start: 14276, end: 14285 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14287, end: 14290 } + }, + loc: { start: 14287, end: 14290 } + }, + loc: { start: 14276, end: 14290 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'errorCode', + loc: { start: 14292, end: 14301 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14303, end: 14306 } + }, + loc: { start: 14303, end: 14306 } + }, + loc: { start: 14292, end: 14306 } + } + ], + body: { + kind: 'asm_body', + shuffle: { + args: [ + { + kind: 'id', + text: 'errorCode', + loc: { start: 14210, end: 14219 } + }, + { + kind: 'id', + text: 'workchain', + loc: { start: 14220, end: 14229 } + }, + { + kind: 'id', + text: 'address', + loc: { start: 14230, end: 14237 } + } + ], + ret: [] + }, + instructions: [ 'REWRITESTDADDR\n DROP\n CMP\n THROWANYIF' ] + }, + loc: { start: 14206, end: 14362 } + } + ] + }, + 'emptyBasechainAddress' => { + kind: 'tact', + path: 'std/internal/address.tact', + code: '/// Extension function for the `Slice` type. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Casts the `Slice` to an `Address` in a given `chain` ID and returns it. The inverse of `Address.asSlice()` and a safe but more gas-expensive version of `Slice.asAddressUnsafe()`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + "/// let a: Address = myAddress(); // let's assume we're in a basechain\n" + + '/// let a2: Address = a.asSlice().asAddress(0); // so the chain ID is 0\n' + + '///\n' + + '/// a == a2; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 136: [Invalid standard address] — Thrown when the given `Slice` contains an invalid\n' + + '/// tag prefix (not `0b100`) or an invalid account ID length (not 256 bits).\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#sliceasaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#sliceasaddressunsafe\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#addressasslice\n' + + '///\n' + + '/// [Invalid standard address]: https://docs.tact-lang.org/book/exit-codes#136\n' + + '///\n' + + 'extends fun asAddress(self: Slice, chain: Int): Address {\n' + + ' // 11 bits for the prefix,\n' + + ' // 256 bits for the address itself\n' + + ' throwUnless(TactExitCodeInvalidStandardAddress, self.bits() == 267);\n' + + '\n' + + ' if (chain == -1) {\n' + + ' // 1279 = 0b100_1111_1111,\n' + + ' // i.e. internal address prefix and chain ID -1\n' + + ' throwUnless(TactExitCodeInvalidStandardAddress, self.preloadUint(11) == 1279);\n' + + ' } else {\n' + + ' // Only check the correct internal address prefix,\n' + + ' // but do not verify the chain ID\n' + + ' throwUnless(TactExitCodeInvalidStandardAddress, self.preloadUint(3) == 4);\n' + + ' }\n' + + '\n' + + ' // Proceed with the cast\n' + + ' return self.asAddressUnsafe();\n' + + '}\n' + + '\n' + + '/// Extension function for the `Slice` type. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Unsafely casts the `Slice` to an `Address` and returns it. The inverse of `Address.asSlice()`.\n' + + '///\n' + + '/// This function does **not** perform any checks on the contents of the `Slice`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let a: Address = myAddress();\n' + + '/// let a2: Address = a.asSlice().asAddressUnsafe();\n' + + '///\n' + + '/// a == a2; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// Use it only if you want to optimize the code for gas and can guarantee in advance that the `Slice` contains the data of an `Address`.\n' + + '///\n' + + '/// Otherwise, use a safer but more gas-expensive `Slice.asAddress()` function.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#sliceasaddressunsafe\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#sliceasaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#addressasslice\n' + + '///\n' + + 'asm extends fun asAddressUnsafe(self: Slice): Address {}\n' + + '\n' + + '/// Extension function for the `Address` type.\n' + + '///\n' + + '/// Casts `self` back to the underlying `Slice` and returns it. The inverse of `Slice.asAddressUnsafe()`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let a: Address = myAddress();\n' + + '/// let fizz: Slice = beginCell().storeAddress(a).asSlice();\n' + + '/// let buzz: Slice = a.asSlice(); // cheap, unlike the previous statement\n' + + '///\n' + + '/// fizz == buzz; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#addressasslice\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#sliceasaddressunsafe\n' + + '///\n' + + 'asm extends fun asSlice(self: Address): Slice {}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Creates a new `Address` based on the `chain` ID and the SHA-256 encoded `hash` value (account ID).\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// Attempts to specify an uncommon `chain` ID (not -1 or 0) that can be detected in compile-time will result in a compilation error.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let oldTonFoundationAddr: Address =\n' + + '/// newAddress(0, 0x83dfd552e63729b472fcbcc8c45ebcc6691702558b68ec7527e1ba403a0f31a8);\n' + + '/// // ↑ ↑\n' + + "/// // | sha-256 hash of contract's init package (StateInit)\n" + + '/// // chain id: 0 is a workchain, -1 is a masterchain\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-addresses#newaddress\n' + + '///\n' + + 'inline fun newAddress(chain: Int, hash: Int): Address {\n' + + ' return beginCell()\n' + + ' .storeUint(0b10_0, 3)\n' + + ' .storeInt(chain, 8)\n' + + ' .storeUint(hash, 256)\n' + + ' .endCell()\n' + + ' .asSlice()\n' + + ' .asAddressUnsafe();\n' + + '}\n' + + '\n' + + '/// Struct representing the standard address on TON Blockchain with signed 8-bit `workchain` ID and an unsigned 256-bit `address` in the specified `workchain`. Available since Tact 1.5.0.\n' + + '///\n' + + '/// At the moment, only `workchain` IDs used on TON are 0 of the basechain and -1 of the masterchain.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#parsestdaddress\n' + + '/// * https://github.com/ton-blockchain/ton/blob/master/crypto/block/block.tlb#L105-L106\n' + + '///\n' + + 'struct StdAddress {\n' + + ' workchain: Int as int8;\n' + + ' address: Int as uint256;\n' + + '}\n' + + '\n' + + '/// Struct representing the address of variable length with signed 32-bit `workchain` ID and a `Slice` containing unsigned `address` in the specified `workchain`. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Variable-length addresses are intended for future extensions, and while validators must be ready to accept them in inbound messages, the standard (non-variable) addresses are used whenever possible.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#parsevaraddress\n' + + '/// * https://github.com/ton-blockchain/ton/blob/master/crypto/block/block.tlb#L107-L108\n' + + '///\n' + + 'struct VarAddress {\n' + + ' workchain: Int as int32;\n' + + ' address: Slice;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Converts a `slice` containing an address into the `StdAddress` Struct and returns it.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let addr = address("EQDtFpEwcFAEcRe5mLVh2N6C0x-_hJEM7W61_JLnSF74p4q2");\n' + + '/// let parsedAddr = parseStdAddress(addr.asSlice());\n' + + '///\n' + + '/// parsedAddr.workchain; // 0\n' + + '/// parsedAddr.address; // 107...287\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-addresses#parsestdaddress\n' + + '///\n' + + 'asm fun parseStdAddress(slice: Slice): StdAddress { REWRITESTDADDR }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Converts a `slice` containing an address of variable length into the `VarAddress` Struct and returns it.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let varAddrSlice = beginCell()\n' + + '/// .storeUint(6, 3) // to recognize the following as a VarAddress\n' + + '/// .storeUint(123, 9) // make address occupy 123 bits\n' + + '/// .storeUint(234, 32) // specify workchain ID of 234\n' + + '/// .storeUint(345, 123) // specify address of 345\n' + + '/// .asSlice();\n' + + '/// let parsedVarAddr = parseVarAddress(varAddrSlice);\n' + + '///\n' + + '/// parsedVarAddr.workchain; // 234\n' + + '/// parsedVarAddr.address; // CS{Cell{002...2b3} bits: 44..167; refs: 0..0}\n' + + '/// parsedVarAddr.address.loadUint(123); // 345\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-addresses#parsevaraddress\n' + + '///\n' + + 'asm fun parseVarAddress(slice: Slice): VarAddress { REWRITEVARADDR }\n' + + '\n' + + '/// Extension mutation function for the `Slice` type.\n' + + '///\n' + + '/// Loads and returns an `Address` from the `Slice`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let s: Slice = beginCell().storeAddress(myAddress()).asSlice();\n' + + '/// let fizz: Address = s.loadAddress();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + "/// * 8: [Cell overflow] — Thrown when attempting to load an `Address` when `Slice` doesn't contain it.\n" + + '/// * 9: [Cell underflow] — Thrown when attempting to load more data than `Slice` contains.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#sliceloadaddress\n' + + '///\n' + + '/// [Cell overflow]: https://docs.tact-lang.org/book/exit-codes#8\n' + + '/// [Cell underflow]: https://docs.tact-lang.org/book/exit-codes#9\n' + + '///\n' + + 'asm(-> 1 0) extends mutates fun loadAddress(self: Slice): Address { LDMSGADDR }\n' + + '\n' + + '/// Extension mutation function for the `Slice` type. Available since Tact 1.6.2.\n' + + '///\n' + + '/// Skips an `Address` from the `Slice`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let s1: Slice = beginCell()\n' + + '/// .storeAddress(myAddress())\n' + + '/// .storeUint(42, 32)\n' + + '/// .asSlice();\n' + + '///\n' + + '/// s1.skipAddress();\n' + + '/// let fizz: Int = s1.loadUint(32); // 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + "/// * 8: [Cell overflow] — Thrown when attempting to skip an `Address` when `Slice` doesn't contain it.\n" + + '/// * 9: [Cell underflow] — Thrown when attempting to skip more data than `Slice` contains.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#sliceskipaddress\n' + + '///\n' + + '/// [Cell overflow]: https://docs.tact-lang.org/book/exit-codes#8\n' + + '/// [Cell underflow]: https://docs.tact-lang.org/book/exit-codes#9\n' + + '///\n' + + 'asm extends mutates fun skipAddress(self: Slice) { LDMSGADDR NIP }\n' + + '\n' + + '/// Extension function for the `Builder` type.\n' + + '///\n' + + '/// Stores the `address` in the copy of the `Builder`. Returns that copy.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b.storeAddress(myAddress());\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 8: [Cell overflow] — Thrown when attempting to store an `address` into the `Builder` when it cannot fit it.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#builderstoreaddress\n' + + '///\n' + + '/// [Cell overflow]: https://docs.tact-lang.org/book/exit-codes#8\n' + + '///\n' + + 'asm extends fun storeAddress(self: Builder, address: Address): Builder { STSLICER }\n' + + '\n' + + '/// Struct representing a basechain address. Available since Tact 1.6.0.\n' + + '///\n' + + '/// A basechain address (workchain 0) can be either empty (null hash) or contain a 256-bit hash value.\n' + + '///\n' + + 'struct BasechainAddress {\n' + + ' hash: Int?;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Creates and returns an empty basechain address with a null hash.\n' + + '///\n' + + '/// When serialized, an empty basechain address is represented as `addr_none`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let emptyAddr: BasechainAddress = emptyBasechainAddress();\n' + + '/// emptyAddr.hash == null; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + 'inline fun emptyBasechainAddress(): BasechainAddress {\n' + + ' return BasechainAddress { hash: null };\n' + + '}\n' + + '\n' + + '/// Global f'... 4363 more characters, + imports: [], + items: [ + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'asAddress', + loc: { start: 998, end: 1007 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 1034, end: 1041 } + }, + typeArgs: [], + loc: { start: 1034, end: 1041 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'chain', + loc: { start: 1021, end: 1026 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1028, end: 1031 } + }, + loc: { start: 1028, end: 1031 } + }, + loc: { start: 1021, end: 1031 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throwUnless', + loc: { start: 1118, end: 1129 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'TactExitCodeInvalidStandardAddress', + loc: { start: 1130, end: 1164 } + }, + { + kind: 'op_binary', + op: '==', + left: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 1166, end: 1170 } + }, + method: { + kind: 'id', + text: 'bits', + loc: { start: 1171, end: 1175 } + }, + typeArgs: [], + args: [], + loc: { start: 1166, end: 1177 } + }, + right: { + kind: 'number', + base: '10', + value: 267n, + loc: { start: 1181, end: 1184 } + }, + loc: { start: 1166, end: 1184 } + } + ], + loc: { start: 1118, end: 1185 } + }, + loc: { start: 1118, end: 1186 } + }, + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'chain', + loc: { start: 1196, end: 1201 } + }, + right: { + kind: 'op_unary', + op: '-', + operand: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1206, end: 1207 } + }, + loc: { start: 1205, end: 1207 } + }, + loc: { start: 1196, end: 1207 } + }, + trueStatements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throwUnless', + loc: { start: 1310, end: 1321 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'TactExitCodeInvalidStandardAddress', + loc: { start: 1322, end: 1356 } + }, + { + kind: 'op_binary', + op: '==', + left: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 1358, end: 1362 } + }, + method: { + kind: 'id', + text: 'preloadUint', + loc: { start: 1363, end: 1374 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 11n, + loc: { start: 1375, end: 1377 } + } + ], + loc: { start: 1358, end: 1378 } + }, + right: { + kind: 'number', + base: '10', + value: 1279n, + loc: { start: 1382, end: 1386 } + }, + loc: { start: 1358, end: 1386 } + } + ], + loc: { start: 1310, end: 1387 } + }, + loc: { start: 1310, end: 1388 } + } + ], + falseStatements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throwUnless', + loc: { start: 1511, end: 1522 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'TactExitCodeInvalidStandardAddress', + loc: { start: 1523, end: 1557 } + }, + { + kind: 'op_binary', + op: '==', + left: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 1559, end: 1563 } + }, + method: { + kind: 'id', + text: 'preloadUint', + loc: { start: 1564, end: 1575 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 3n, + loc: { start: 1576, end: 1577 } + } + ], + loc: { start: 1559, end: 1578 } + }, + right: { + kind: 'number', + base: '10', + value: 4n, + loc: { start: 1582, end: 1583 } + }, + loc: { start: 1559, end: 1583 } + } + ], + loc: { start: 1511, end: 1584 } + }, + loc: { start: 1511, end: 1585 } + } + ], + loc: { start: 1192, end: 1591 } + }, + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 1633, end: 1637 } + }, + method: { + kind: 'id', + text: 'asAddressUnsafe', + loc: { start: 1638, end: 1653 } + }, + typeArgs: [], + args: [], + loc: { start: 1633, end: 1655 } + }, + loc: { start: 1626, end: 1656 } + } + ] + }, + loc: { start: 986, end: 1658 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 1014, end: 1019 } }, + loc: { start: 1014, end: 1019 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'asAddressUnsafe', + loc: { start: 2554, end: 2569 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 2584, end: 2591 } + }, + typeArgs: [], + loc: { start: 2584, end: 2591 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ '' ] + }, + loc: { start: 2538, end: 2594 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 2576, end: 2581 } }, + loc: { start: 2576, end: 2581 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'asSlice', + loc: { start: 3188, end: 3195 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 3212, end: 3217 } }, + loc: { start: 3212, end: 3217 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ '' ] + }, + loc: { start: 3172, end: 3220 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3202, end: 3209 } + }, + typeArgs: [], + loc: { start: 3202, end: 3209 } + } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'newAddress', + loc: { start: 4029, end: 4039 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 4064, end: 4071 } + }, + typeArgs: [], + loc: { start: 4064, end: 4071 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'chain', + loc: { start: 4040, end: 4045 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4047, end: 4050 } + }, + loc: { start: 4047, end: 4050 } + }, + loc: { start: 4040, end: 4050 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'hash', + loc: { start: 4052, end: 4056 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4058, end: 4061 } + }, + loc: { start: 4058, end: 4061 } + }, + loc: { start: 4052, end: 4061 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'static_call', + function: { + kind: 'id', + text: 'beginCell', + loc: { start: 4085, end: 4094 } + }, + typeArgs: [], + args: [], + loc: { start: 4085, end: 4096 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 4106, end: 4115 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '2', + value: 4n, + loc: { start: 4116, end: 4122 } + }, + { + kind: 'number', + base: '10', + value: 3n, + loc: { start: 4124, end: 4125 } + } + ], + loc: { start: 4085, end: 4126 } + }, + method: { + kind: 'id', + text: 'storeInt', + loc: { start: 4136, end: 4144 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'chain', + loc: { start: 4145, end: 4150 } + }, + { + kind: 'number', + base: '10', + value: 8n, + loc: { start: 4152, end: 4153 } + } + ], + loc: { start: 4085, end: 4154 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 4164, end: 4173 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'hash', + loc: { start: 4174, end: 4178 } + }, + { + kind: 'number', + base: '10', + value: 256n, + loc: { start: 4180, end: 4183 } + } + ], + loc: { start: 4085, end: 4184 } + }, + method: { + kind: 'id', + text: 'endCell', + loc: { start: 4194, end: 4201 } + }, + typeArgs: [], + args: [], + loc: { start: 4085, end: 4203 } + }, + method: { + kind: 'id', + text: 'asSlice', + loc: { start: 4213, end: 4220 } + }, + typeArgs: [], + args: [], + loc: { start: 4085, end: 4222 } + }, + method: { + kind: 'id', + text: 'asAddressUnsafe', + loc: { start: 4232, end: 4247 } + }, + typeArgs: [], + args: [], + loc: { start: 4085, end: 4249 } + }, + loc: { start: 4078, end: 4250 } + } + ] + }, + loc: { start: 4018, end: 4252 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'StdAddress', + loc: { start: 4729, end: 4739 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'workchain', + loc: { start: 4746, end: 4755 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 8, + loc: { start: 4757, end: 4768 } + }, + loc: { start: 4757, end: 4760 } + }, + initializer: undefined, + loc: { start: 4746, end: 4768 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'address', + loc: { start: 4774, end: 4781 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'unsigned', + width: 256, + loc: { start: 4783, end: 4797 } + }, + loc: { start: 4783, end: 4786 } + }, + initializer: undefined, + loc: { start: 4774, end: 4797 } + } + ], + loc: { start: 4722, end: 4800 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'VarAddress', + loc: { start: 5381, end: 5391 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'workchain', + loc: { start: 5398, end: 5407 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 32, + loc: { start: 5409, end: 5421 } + }, + loc: { start: 5409, end: 5412 } + }, + initializer: undefined, + loc: { start: 5398, end: 5421 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'address', + loc: { start: 5427, end: 5434 } + }, + type: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 5436, end: 5441 } }, + loc: { start: 5436, end: 5441 } + }, + initializer: undefined, + loc: { start: 5427, end: 5441 } + } + ], + loc: { start: 5374, end: 5444 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'parseStdAddress', + loc: { start: 5946, end: 5961 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StdAddress', + loc: { start: 5977, end: 5987 } + }, + typeArgs: [], + loc: { start: 5977, end: 5987 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'slice', + loc: { start: 5962, end: 5967 } + }, + type: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 5969, end: 5974 } }, + loc: { start: 5969, end: 5974 } + }, + loc: { start: 5962, end: 5974 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'REWRITESTDADDR' ] + }, + loc: { start: 5938, end: 6006 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'parseVarAddress', + loc: { start: 6898, end: 6913 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'VarAddress', + loc: { start: 6929, end: 6939 } + }, + typeArgs: [], + loc: { start: 6929, end: 6939 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'slice', + loc: { start: 6914, end: 6919 } + }, + type: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 6921, end: 6926 } }, + loc: { start: 6921, end: 6926 } + }, + loc: { start: 6914, end: 6926 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'REWRITEVARADDR' ] + }, + loc: { start: 6890, end: 6958 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadAddress', + loc: { start: 7707, end: 7718 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 7733, end: 7740 } + }, + typeArgs: [], + loc: { start: 7733, end: 7740 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { + args: [], + ret: [ + { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 7682, end: 7683 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 7684, end: 7685 } + } + ] + }, + instructions: [ 'LDMSGADDR' ] + }, + loc: { start: 7675, end: 7754 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 7725, end: 7730 } }, + loc: { start: 7725, end: 7730 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'skipAddress', + loc: { start: 8601, end: 8612 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LDMSGADDR NIP' ] + }, + loc: { start: 8577, end: 8643 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 8619, end: 8624 } }, + loc: { start: 8619, end: 8624 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeAddress', + loc: { start: 9222, end: 9234 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 9269, end: 9276 } }, + loc: { start: 9269, end: 9276 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'address', + loc: { start: 9250, end: 9257 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 9259, end: 9266 } + }, + typeArgs: [], + loc: { start: 9259, end: 9266 } + }, + loc: { start: 9250, end: 9266 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'STSLICER' ] + }, + loc: { start: 9206, end: 9289 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 9241, end: 9248 } }, + loc: { start: 9241, end: 9248 } + } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 9482, end: 9498 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'hash', + loc: { start: 9505, end: 9509 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 9514, end: 9515 } + }, + typeArgs: [ + { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9511, end: 9514 } + }, + loc: { start: 9511, end: 9514 } + } + ], + loc: { start: 9514, end: 9515 } + }, + initializer: undefined, + loc: { start: 9505, end: 9515 } + } + ], + loc: { start: 9475, end: 9518 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'emptyBasechainAddress', + loc: { start: 9897, end: 9918 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 9922, end: 9938 } + }, + typeArgs: [], + loc: { start: 9922, end: 9938 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'struct_instance', + type: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 9952, end: 9968 } + }, + typeArgs: [], + args: [ + { + kind: 'struct_field_initializer', + field: { + kind: 'id', + text: 'hash', + loc: { start: 9971, end: 9975 } + }, + initializer: { kind: 'null', loc: { start: 9977, end: 9981 } }, + loc: { start: 9971, end: 9981 } + } + ], + loc: { start: 9952, end: 9983 } + }, + loc: { start: 9945, end: 9984 } + } + ] + }, + loc: { start: 9886, end: 9986 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'newBasechainAddress', + loc: { start: 10311, end: 10330 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 10343, end: 10359 } + }, + typeArgs: [], + loc: { start: 10343, end: 10359 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'hash', + loc: { start: 10331, end: 10335 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10337, end: 10340 } + }, + loc: { start: 10337, end: 10340 } + }, + loc: { start: 10331, end: 10340 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'struct_instance', + type: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 10373, end: 10389 } + }, + typeArgs: [], + args: [ + { + kind: 'struct_field_initializer', + field: { + kind: 'id', + text: 'hash', + loc: { start: 10392, end: 10396 } + }, + initializer: { + kind: 'var', + name: 'hash', + loc: { start: 10392, end: 10396 } + }, + loc: { start: 10392, end: 10396 } + } + ], + loc: { start: 10373, end: 10398 } + }, + loc: { start: 10366, end: 10399 } + } + ] + }, + loc: { start: 10300, end: 10401 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'contractBasechainAddress', + loc: { start: 10865, end: 10889 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 10905, end: 10921 } + }, + typeArgs: [], + loc: { start: 10905, end: 10921 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 's', + loc: { start: 10890, end: 10891 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 10893, end: 10902 } + }, + typeArgs: [], + loc: { start: 10893, end: 10902 } + }, + loc: { start: 10890, end: 10902 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'hash', + loc: { start: 10932, end: 10936 } + }, + type: undefined, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractHash', + loc: { start: 10939, end: 10951 } + }, + typeArgs: [], + args: [ + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 10952, end: 10953 } + }, + field: { + kind: 'id', + text: 'code', + loc: { start: 10954, end: 10958 } + }, + loc: { start: 10952, end: 10958 } + }, + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 10960, end: 10961 } + }, + field: { + kind: 'id', + text: 'data', + loc: { start: 10962, end: 10966 } + }, + loc: { start: 10960, end: 10966 } + } + ], + loc: { start: 10939, end: 10967 } + }, + loc: { start: 10928, end: 10968 } + }, + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'newBasechainAddress', + loc: { start: 10980, end: 10999 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'hash', + loc: { start: 11000, end: 11004 } + } + ], + loc: { start: 10980, end: 11005 } + }, + loc: { start: 10973, end: 11006 } + } + ] + }, + loc: { start: 10854, end: 11008 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeBasechainAddress', + loc: { start: 11633, end: 11654 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 11698, end: 11705 } + }, + loc: { start: 11698, end: 11705 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'address', + loc: { start: 11670, end: 11677 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 11679, end: 11695 } + }, + typeArgs: [], + loc: { start: 11679, end: 11695 } + }, + loc: { start: 11670, end: 11695 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'address', + loc: { start: 11716, end: 11723 } + }, + field: { + kind: 'id', + text: 'hash', + loc: { start: 11724, end: 11728 } + }, + loc: { start: 11716, end: 11728 } + }, + right: { + kind: 'null', + loc: { start: 11732, end: 11736 } + }, + loc: { start: 11716, end: 11736 } + }, + trueStatements: [ + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 11755, end: 11759 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 11760, end: 11769 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 11770, end: 11771 } + }, + { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 11773, end: 11774 } + } + ], + loc: { start: 11755, end: 11775 } + }, + loc: { start: 11748, end: 11776 } + } + ], + falseStatements: undefined, + loc: { start: 11712, end: 11790 } + }, + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 11803, end: 11807 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 11817, end: 11826 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '2', + value: 1024n, + loc: { start: 11827, end: 11842 } + }, + { + kind: 'op_binary', + op: '+', + left: { + kind: 'number', + base: '10', + value: 3n, + loc: { start: 11844, end: 11845 } + }, + right: { + kind: 'number', + base: '10', + value: 8n, + loc: { start: 11848, end: 11849 } + }, + loc: { start: 11844, end: 11849 } + } + ], + loc: { start: 11803, end: 11850 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 11860, end: 11869 } + }, + typeArgs: [], + args: [ + { + kind: 'op_unary', + op: '!!', + operand: { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'address', + loc: { start: 11870, end: 11877 } + }, + field: { + kind: 'id', + text: 'hash', + loc: { start: 11878, end: 11882 } + }, + loc: { start: 11870, end: 11882 } + }, + loc: { start: 11870, end: 11884 } + }, + { + kind: 'number', + base: '10', + value: 256n, + loc: { start: 11886, end: 11889 } + } + ], + loc: { start: 11803, end: 11890 } + }, + loc: { start: 11796, end: 11891 } + } + ] + }, + loc: { start: 11621, end: 11893 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 11661, end: 11668 } }, + loc: { start: 11661, end: 11668 } + } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'forceBasechain', + loc: { start: 12980, end: 12994 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'address', + loc: { start: 12995, end: 13002 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 13004, end: 13011 } + }, + typeArgs: [], + loc: { start: 13004, end: 13011 } + }, + loc: { start: 12995, end: 13011 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'REWRITESTDADDR DROP 138 THROWIF' ] + }, + loc: { start: 12972, end: 13048 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'forceWorkchain', + loc: { start: 14243, end: 14257 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'address', + loc: { start: 14258, end: 14265 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 14267, end: 14274 } + }, + typeArgs: [], + loc: { start: 14267, end: 14274 } + }, + loc: { start: 14258, end: 14274 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'workchain', + loc: { start: 14276, end: 14285 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14287, end: 14290 } + }, + loc: { start: 14287, end: 14290 } + }, + loc: { start: 14276, end: 14290 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'errorCode', + loc: { start: 14292, end: 14301 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14303, end: 14306 } + }, + loc: { start: 14303, end: 14306 } + }, + loc: { start: 14292, end: 14306 } + } + ], + body: { + kind: 'asm_body', + shuffle: { + args: [ + { + kind: 'id', + text: 'errorCode', + loc: { start: 14210, end: 14219 } + }, + { + kind: 'id', + text: 'workchain', + loc: { start: 14220, end: 14229 } + }, + { + kind: 'id', + text: 'address', + loc: { start: 14230, end: 14237 } + } + ], + ret: [] + }, + instructions: [ 'REWRITESTDADDR\n DROP\n CMP\n THROWANYIF' ] + }, + loc: { start: 14206, end: 14362 } + } + ] + }, + 'newBasechainAddress' => { + kind: 'tact', + path: 'std/internal/address.tact', + code: '/// Extension function for the `Slice` type. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Casts the `Slice` to an `Address` in a given `chain` ID and returns it. The inverse of `Address.asSlice()` and a safe but more gas-expensive version of `Slice.asAddressUnsafe()`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + "/// let a: Address = myAddress(); // let's assume we're in a basechain\n" + + '/// let a2: Address = a.asSlice().asAddress(0); // so the chain ID is 0\n' + + '///\n' + + '/// a == a2; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 136: [Invalid standard address] — Thrown when the given `Slice` contains an invalid\n' + + '/// tag prefix (not `0b100`) or an invalid account ID length (not 256 bits).\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#sliceasaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#sliceasaddressunsafe\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#addressasslice\n' + + '///\n' + + '/// [Invalid standard address]: https://docs.tact-lang.org/book/exit-codes#136\n' + + '///\n' + + 'extends fun asAddress(self: Slice, chain: Int): Address {\n' + + ' // 11 bits for the prefix,\n' + + ' // 256 bits for the address itself\n' + + ' throwUnless(TactExitCodeInvalidStandardAddress, self.bits() == 267);\n' + + '\n' + + ' if (chain == -1) {\n' + + ' // 1279 = 0b100_1111_1111,\n' + + ' // i.e. internal address prefix and chain ID -1\n' + + ' throwUnless(TactExitCodeInvalidStandardAddress, self.preloadUint(11) == 1279);\n' + + ' } else {\n' + + ' // Only check the correct internal address prefix,\n' + + ' // but do not verify the chain ID\n' + + ' throwUnless(TactExitCodeInvalidStandardAddress, self.preloadUint(3) == 4);\n' + + ' }\n' + + '\n' + + ' // Proceed with the cast\n' + + ' return self.asAddressUnsafe();\n' + + '}\n' + + '\n' + + '/// Extension function for the `Slice` type. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Unsafely casts the `Slice` to an `Address` and returns it. The inverse of `Address.asSlice()`.\n' + + '///\n' + + '/// This function does **not** perform any checks on the contents of the `Slice`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let a: Address = myAddress();\n' + + '/// let a2: Address = a.asSlice().asAddressUnsafe();\n' + + '///\n' + + '/// a == a2; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// Use it only if you want to optimize the code for gas and can guarantee in advance that the `Slice` contains the data of an `Address`.\n' + + '///\n' + + '/// Otherwise, use a safer but more gas-expensive `Slice.asAddress()` function.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#sliceasaddressunsafe\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#sliceasaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#addressasslice\n' + + '///\n' + + 'asm extends fun asAddressUnsafe(self: Slice): Address {}\n' + + '\n' + + '/// Extension function for the `Address` type.\n' + + '///\n' + + '/// Casts `self` back to the underlying `Slice` and returns it. The inverse of `Slice.asAddressUnsafe()`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let a: Address = myAddress();\n' + + '/// let fizz: Slice = beginCell().storeAddress(a).asSlice();\n' + + '/// let buzz: Slice = a.asSlice(); // cheap, unlike the previous statement\n' + + '///\n' + + '/// fizz == buzz; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#addressasslice\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#sliceasaddressunsafe\n' + + '///\n' + + 'asm extends fun asSlice(self: Address): Slice {}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Creates a new `Address` based on the `chain` ID and the SHA-256 encoded `hash` value (account ID).\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// Attempts to specify an uncommon `chain` ID (not -1 or 0) that can be detected in compile-time will result in a compilation error.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let oldTonFoundationAddr: Address =\n' + + '/// newAddress(0, 0x83dfd552e63729b472fcbcc8c45ebcc6691702558b68ec7527e1ba403a0f31a8);\n' + + '/// // ↑ ↑\n' + + "/// // | sha-256 hash of contract's init package (StateInit)\n" + + '/// // chain id: 0 is a workchain, -1 is a masterchain\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-addresses#newaddress\n' + + '///\n' + + 'inline fun newAddress(chain: Int, hash: Int): Address {\n' + + ' return beginCell()\n' + + ' .storeUint(0b10_0, 3)\n' + + ' .storeInt(chain, 8)\n' + + ' .storeUint(hash, 256)\n' + + ' .endCell()\n' + + ' .asSlice()\n' + + ' .asAddressUnsafe();\n' + + '}\n' + + '\n' + + '/// Struct representing the standard address on TON Blockchain with signed 8-bit `workchain` ID and an unsigned 256-bit `address` in the specified `workchain`. Available since Tact 1.5.0.\n' + + '///\n' + + '/// At the moment, only `workchain` IDs used on TON are 0 of the basechain and -1 of the masterchain.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#parsestdaddress\n' + + '/// * https://github.com/ton-blockchain/ton/blob/master/crypto/block/block.tlb#L105-L106\n' + + '///\n' + + 'struct StdAddress {\n' + + ' workchain: Int as int8;\n' + + ' address: Int as uint256;\n' + + '}\n' + + '\n' + + '/// Struct representing the address of variable length with signed 32-bit `workchain` ID and a `Slice` containing unsigned `address` in the specified `workchain`. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Variable-length addresses are intended for future extensions, and while validators must be ready to accept them in inbound messages, the standard (non-variable) addresses are used whenever possible.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#parsevaraddress\n' + + '/// * https://github.com/ton-blockchain/ton/blob/master/crypto/block/block.tlb#L107-L108\n' + + '///\n' + + 'struct VarAddress {\n' + + ' workchain: Int as int32;\n' + + ' address: Slice;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Converts a `slice` containing an address into the `StdAddress` Struct and returns it.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let addr = address("EQDtFpEwcFAEcRe5mLVh2N6C0x-_hJEM7W61_JLnSF74p4q2");\n' + + '/// let parsedAddr = parseStdAddress(addr.asSlice());\n' + + '///\n' + + '/// parsedAddr.workchain; // 0\n' + + '/// parsedAddr.address; // 107...287\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-addresses#parsestdaddress\n' + + '///\n' + + 'asm fun parseStdAddress(slice: Slice): StdAddress { REWRITESTDADDR }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Converts a `slice` containing an address of variable length into the `VarAddress` Struct and returns it.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let varAddrSlice = beginCell()\n' + + '/// .storeUint(6, 3) // to recognize the following as a VarAddress\n' + + '/// .storeUint(123, 9) // make address occupy 123 bits\n' + + '/// .storeUint(234, 32) // specify workchain ID of 234\n' + + '/// .storeUint(345, 123) // specify address of 345\n' + + '/// .asSlice();\n' + + '/// let parsedVarAddr = parseVarAddress(varAddrSlice);\n' + + '///\n' + + '/// parsedVarAddr.workchain; // 234\n' + + '/// parsedVarAddr.address; // CS{Cell{002...2b3} bits: 44..167; refs: 0..0}\n' + + '/// parsedVarAddr.address.loadUint(123); // 345\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-addresses#parsevaraddress\n' + + '///\n' + + 'asm fun parseVarAddress(slice: Slice): VarAddress { REWRITEVARADDR }\n' + + '\n' + + '/// Extension mutation function for the `Slice` type.\n' + + '///\n' + + '/// Loads and returns an `Address` from the `Slice`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let s: Slice = beginCell().storeAddress(myAddress()).asSlice();\n' + + '/// let fizz: Address = s.loadAddress();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + "/// * 8: [Cell overflow] — Thrown when attempting to load an `Address` when `Slice` doesn't contain it.\n" + + '/// * 9: [Cell underflow] — Thrown when attempting to load more data than `Slice` contains.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#sliceloadaddress\n' + + '///\n' + + '/// [Cell overflow]: https://docs.tact-lang.org/book/exit-codes#8\n' + + '/// [Cell underflow]: https://docs.tact-lang.org/book/exit-codes#9\n' + + '///\n' + + 'asm(-> 1 0) extends mutates fun loadAddress(self: Slice): Address { LDMSGADDR }\n' + + '\n' + + '/// Extension mutation function for the `Slice` type. Available since Tact 1.6.2.\n' + + '///\n' + + '/// Skips an `Address` from the `Slice`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let s1: Slice = beginCell()\n' + + '/// .storeAddress(myAddress())\n' + + '/// .storeUint(42, 32)\n' + + '/// .asSlice();\n' + + '///\n' + + '/// s1.skipAddress();\n' + + '/// let fizz: Int = s1.loadUint(32); // 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + "/// * 8: [Cell overflow] — Thrown when attempting to skip an `Address` when `Slice` doesn't contain it.\n" + + '/// * 9: [Cell underflow] — Thrown when attempting to skip more data than `Slice` contains.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#sliceskipaddress\n' + + '///\n' + + '/// [Cell overflow]: https://docs.tact-lang.org/book/exit-codes#8\n' + + '/// [Cell underflow]: https://docs.tact-lang.org/book/exit-codes#9\n' + + '///\n' + + 'asm extends mutates fun skipAddress(self: Slice) { LDMSGADDR NIP }\n' + + '\n' + + '/// Extension function for the `Builder` type.\n' + + '///\n' + + '/// Stores the `address` in the copy of the `Builder`. Returns that copy.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b.storeAddress(myAddress());\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 8: [Cell overflow] — Thrown when attempting to store an `address` into the `Builder` when it cannot fit it.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#builderstoreaddress\n' + + '///\n' + + '/// [Cell overflow]: https://docs.tact-lang.org/book/exit-codes#8\n' + + '///\n' + + 'asm extends fun storeAddress(self: Builder, address: Address): Builder { STSLICER }\n' + + '\n' + + '/// Struct representing a basechain address. Available since Tact 1.6.0.\n' + + '///\n' + + '/// A basechain address (workchain 0) can be either empty (null hash) or contain a 256-bit hash value.\n' + + '///\n' + + 'struct BasechainAddress {\n' + + ' hash: Int?;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Creates and returns an empty basechain address with a null hash.\n' + + '///\n' + + '/// When serialized, an empty basechain address is represented as `addr_none`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let emptyAddr: BasechainAddress = emptyBasechainAddress();\n' + + '/// emptyAddr.hash == null; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + 'inline fun emptyBasechainAddress(): BasechainAddress {\n' + + ' return BasechainAddress { hash: null };\n' + + '}\n' + + '\n' + + '/// Global f'... 4363 more characters, + imports: [], + items: [ + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'asAddress', + loc: { start: 998, end: 1007 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 1034, end: 1041 } + }, + typeArgs: [], + loc: { start: 1034, end: 1041 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'chain', + loc: { start: 1021, end: 1026 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1028, end: 1031 } + }, + loc: { start: 1028, end: 1031 } + }, + loc: { start: 1021, end: 1031 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throwUnless', + loc: { start: 1118, end: 1129 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'TactExitCodeInvalidStandardAddress', + loc: { start: 1130, end: 1164 } + }, + { + kind: 'op_binary', + op: '==', + left: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 1166, end: 1170 } + }, + method: { + kind: 'id', + text: 'bits', + loc: { start: 1171, end: 1175 } + }, + typeArgs: [], + args: [], + loc: { start: 1166, end: 1177 } + }, + right: { + kind: 'number', + base: '10', + value: 267n, + loc: { start: 1181, end: 1184 } + }, + loc: { start: 1166, end: 1184 } + } + ], + loc: { start: 1118, end: 1185 } + }, + loc: { start: 1118, end: 1186 } + }, + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'chain', + loc: { start: 1196, end: 1201 } + }, + right: { + kind: 'op_unary', + op: '-', + operand: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1206, end: 1207 } + }, + loc: { start: 1205, end: 1207 } + }, + loc: { start: 1196, end: 1207 } + }, + trueStatements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throwUnless', + loc: { start: 1310, end: 1321 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'TactExitCodeInvalidStandardAddress', + loc: { start: 1322, end: 1356 } + }, + { + kind: 'op_binary', + op: '==', + left: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 1358, end: 1362 } + }, + method: { + kind: 'id', + text: 'preloadUint', + loc: { start: 1363, end: 1374 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 11n, + loc: { start: 1375, end: 1377 } + } + ], + loc: { start: 1358, end: 1378 } + }, + right: { + kind: 'number', + base: '10', + value: 1279n, + loc: { start: 1382, end: 1386 } + }, + loc: { start: 1358, end: 1386 } + } + ], + loc: { start: 1310, end: 1387 } + }, + loc: { start: 1310, end: 1388 } + } + ], + falseStatements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throwUnless', + loc: { start: 1511, end: 1522 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'TactExitCodeInvalidStandardAddress', + loc: { start: 1523, end: 1557 } + }, + { + kind: 'op_binary', + op: '==', + left: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 1559, end: 1563 } + }, + method: { + kind: 'id', + text: 'preloadUint', + loc: { start: 1564, end: 1575 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 3n, + loc: { start: 1576, end: 1577 } + } + ], + loc: { start: 1559, end: 1578 } + }, + right: { + kind: 'number', + base: '10', + value: 4n, + loc: { start: 1582, end: 1583 } + }, + loc: { start: 1559, end: 1583 } + } + ], + loc: { start: 1511, end: 1584 } + }, + loc: { start: 1511, end: 1585 } + } + ], + loc: { start: 1192, end: 1591 } + }, + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 1633, end: 1637 } + }, + method: { + kind: 'id', + text: 'asAddressUnsafe', + loc: { start: 1638, end: 1653 } + }, + typeArgs: [], + args: [], + loc: { start: 1633, end: 1655 } + }, + loc: { start: 1626, end: 1656 } + } + ] + }, + loc: { start: 986, end: 1658 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 1014, end: 1019 } }, + loc: { start: 1014, end: 1019 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'asAddressUnsafe', + loc: { start: 2554, end: 2569 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 2584, end: 2591 } + }, + typeArgs: [], + loc: { start: 2584, end: 2591 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ '' ] + }, + loc: { start: 2538, end: 2594 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 2576, end: 2581 } }, + loc: { start: 2576, end: 2581 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'asSlice', + loc: { start: 3188, end: 3195 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 3212, end: 3217 } }, + loc: { start: 3212, end: 3217 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ '' ] + }, + loc: { start: 3172, end: 3220 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3202, end: 3209 } + }, + typeArgs: [], + loc: { start: 3202, end: 3209 } + } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'newAddress', + loc: { start: 4029, end: 4039 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 4064, end: 4071 } + }, + typeArgs: [], + loc: { start: 4064, end: 4071 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'chain', + loc: { start: 4040, end: 4045 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4047, end: 4050 } + }, + loc: { start: 4047, end: 4050 } + }, + loc: { start: 4040, end: 4050 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'hash', + loc: { start: 4052, end: 4056 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4058, end: 4061 } + }, + loc: { start: 4058, end: 4061 } + }, + loc: { start: 4052, end: 4061 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'static_call', + function: { + kind: 'id', + text: 'beginCell', + loc: { start: 4085, end: 4094 } + }, + typeArgs: [], + args: [], + loc: { start: 4085, end: 4096 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 4106, end: 4115 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '2', + value: 4n, + loc: { start: 4116, end: 4122 } + }, + { + kind: 'number', + base: '10', + value: 3n, + loc: { start: 4124, end: 4125 } + } + ], + loc: { start: 4085, end: 4126 } + }, + method: { + kind: 'id', + text: 'storeInt', + loc: { start: 4136, end: 4144 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'chain', + loc: { start: 4145, end: 4150 } + }, + { + kind: 'number', + base: '10', + value: 8n, + loc: { start: 4152, end: 4153 } + } + ], + loc: { start: 4085, end: 4154 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 4164, end: 4173 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'hash', + loc: { start: 4174, end: 4178 } + }, + { + kind: 'number', + base: '10', + value: 256n, + loc: { start: 4180, end: 4183 } + } + ], + loc: { start: 4085, end: 4184 } + }, + method: { + kind: 'id', + text: 'endCell', + loc: { start: 4194, end: 4201 } + }, + typeArgs: [], + args: [], + loc: { start: 4085, end: 4203 } + }, + method: { + kind: 'id', + text: 'asSlice', + loc: { start: 4213, end: 4220 } + }, + typeArgs: [], + args: [], + loc: { start: 4085, end: 4222 } + }, + method: { + kind: 'id', + text: 'asAddressUnsafe', + loc: { start: 4232, end: 4247 } + }, + typeArgs: [], + args: [], + loc: { start: 4085, end: 4249 } + }, + loc: { start: 4078, end: 4250 } + } + ] + }, + loc: { start: 4018, end: 4252 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'StdAddress', + loc: { start: 4729, end: 4739 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'workchain', + loc: { start: 4746, end: 4755 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 8, + loc: { start: 4757, end: 4768 } + }, + loc: { start: 4757, end: 4760 } + }, + initializer: undefined, + loc: { start: 4746, end: 4768 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'address', + loc: { start: 4774, end: 4781 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'unsigned', + width: 256, + loc: { start: 4783, end: 4797 } + }, + loc: { start: 4783, end: 4786 } + }, + initializer: undefined, + loc: { start: 4774, end: 4797 } + } + ], + loc: { start: 4722, end: 4800 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'VarAddress', + loc: { start: 5381, end: 5391 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'workchain', + loc: { start: 5398, end: 5407 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 32, + loc: { start: 5409, end: 5421 } + }, + loc: { start: 5409, end: 5412 } + }, + initializer: undefined, + loc: { start: 5398, end: 5421 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'address', + loc: { start: 5427, end: 5434 } + }, + type: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 5436, end: 5441 } }, + loc: { start: 5436, end: 5441 } + }, + initializer: undefined, + loc: { start: 5427, end: 5441 } + } + ], + loc: { start: 5374, end: 5444 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'parseStdAddress', + loc: { start: 5946, end: 5961 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StdAddress', + loc: { start: 5977, end: 5987 } + }, + typeArgs: [], + loc: { start: 5977, end: 5987 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'slice', + loc: { start: 5962, end: 5967 } + }, + type: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 5969, end: 5974 } }, + loc: { start: 5969, end: 5974 } + }, + loc: { start: 5962, end: 5974 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'REWRITESTDADDR' ] + }, + loc: { start: 5938, end: 6006 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'parseVarAddress', + loc: { start: 6898, end: 6913 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'VarAddress', + loc: { start: 6929, end: 6939 } + }, + typeArgs: [], + loc: { start: 6929, end: 6939 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'slice', + loc: { start: 6914, end: 6919 } + }, + type: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 6921, end: 6926 } }, + loc: { start: 6921, end: 6926 } + }, + loc: { start: 6914, end: 6926 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'REWRITEVARADDR' ] + }, + loc: { start: 6890, end: 6958 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadAddress', + loc: { start: 7707, end: 7718 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 7733, end: 7740 } + }, + typeArgs: [], + loc: { start: 7733, end: 7740 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { + args: [], + ret: [ + { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 7682, end: 7683 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 7684, end: 7685 } + } + ] + }, + instructions: [ 'LDMSGADDR' ] + }, + loc: { start: 7675, end: 7754 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 7725, end: 7730 } }, + loc: { start: 7725, end: 7730 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'skipAddress', + loc: { start: 8601, end: 8612 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LDMSGADDR NIP' ] + }, + loc: { start: 8577, end: 8643 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 8619, end: 8624 } }, + loc: { start: 8619, end: 8624 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeAddress', + loc: { start: 9222, end: 9234 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 9269, end: 9276 } }, + loc: { start: 9269, end: 9276 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'address', + loc: { start: 9250, end: 9257 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 9259, end: 9266 } + }, + typeArgs: [], + loc: { start: 9259, end: 9266 } + }, + loc: { start: 9250, end: 9266 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'STSLICER' ] + }, + loc: { start: 9206, end: 9289 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 9241, end: 9248 } }, + loc: { start: 9241, end: 9248 } + } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 9482, end: 9498 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'hash', + loc: { start: 9505, end: 9509 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 9514, end: 9515 } + }, + typeArgs: [ + { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9511, end: 9514 } + }, + loc: { start: 9511, end: 9514 } + } + ], + loc: { start: 9514, end: 9515 } + }, + initializer: undefined, + loc: { start: 9505, end: 9515 } + } + ], + loc: { start: 9475, end: 9518 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'emptyBasechainAddress', + loc: { start: 9897, end: 9918 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 9922, end: 9938 } + }, + typeArgs: [], + loc: { start: 9922, end: 9938 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'struct_instance', + type: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 9952, end: 9968 } + }, + typeArgs: [], + args: [ + { + kind: 'struct_field_initializer', + field: { + kind: 'id', + text: 'hash', + loc: { start: 9971, end: 9975 } + }, + initializer: { kind: 'null', loc: { start: 9977, end: 9981 } }, + loc: { start: 9971, end: 9981 } + } + ], + loc: { start: 9952, end: 9983 } + }, + loc: { start: 9945, end: 9984 } + } + ] + }, + loc: { start: 9886, end: 9986 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'newBasechainAddress', + loc: { start: 10311, end: 10330 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 10343, end: 10359 } + }, + typeArgs: [], + loc: { start: 10343, end: 10359 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'hash', + loc: { start: 10331, end: 10335 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10337, end: 10340 } + }, + loc: { start: 10337, end: 10340 } + }, + loc: { start: 10331, end: 10340 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'struct_instance', + type: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 10373, end: 10389 } + }, + typeArgs: [], + args: [ + { + kind: 'struct_field_initializer', + field: { + kind: 'id', + text: 'hash', + loc: { start: 10392, end: 10396 } + }, + initializer: { + kind: 'var', + name: 'hash', + loc: { start: 10392, end: 10396 } + }, + loc: { start: 10392, end: 10396 } + } + ], + loc: { start: 10373, end: 10398 } + }, + loc: { start: 10366, end: 10399 } + } + ] + }, + loc: { start: 10300, end: 10401 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'contractBasechainAddress', + loc: { start: 10865, end: 10889 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 10905, end: 10921 } + }, + typeArgs: [], + loc: { start: 10905, end: 10921 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 's', + loc: { start: 10890, end: 10891 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 10893, end: 10902 } + }, + typeArgs: [], + loc: { start: 10893, end: 10902 } + }, + loc: { start: 10890, end: 10902 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'hash', + loc: { start: 10932, end: 10936 } + }, + type: undefined, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractHash', + loc: { start: 10939, end: 10951 } + }, + typeArgs: [], + args: [ + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 10952, end: 10953 } + }, + field: { + kind: 'id', + text: 'code', + loc: { start: 10954, end: 10958 } + }, + loc: { start: 10952, end: 10958 } + }, + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 10960, end: 10961 } + }, + field: { + kind: 'id', + text: 'data', + loc: { start: 10962, end: 10966 } + }, + loc: { start: 10960, end: 10966 } + } + ], + loc: { start: 10939, end: 10967 } + }, + loc: { start: 10928, end: 10968 } + }, + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'newBasechainAddress', + loc: { start: 10980, end: 10999 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'hash', + loc: { start: 11000, end: 11004 } + } + ], + loc: { start: 10980, end: 11005 } + }, + loc: { start: 10973, end: 11006 } + } + ] + }, + loc: { start: 10854, end: 11008 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeBasechainAddress', + loc: { start: 11633, end: 11654 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 11698, end: 11705 } + }, + loc: { start: 11698, end: 11705 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'address', + loc: { start: 11670, end: 11677 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 11679, end: 11695 } + }, + typeArgs: [], + loc: { start: 11679, end: 11695 } + }, + loc: { start: 11670, end: 11695 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'address', + loc: { start: 11716, end: 11723 } + }, + field: { + kind: 'id', + text: 'hash', + loc: { start: 11724, end: 11728 } + }, + loc: { start: 11716, end: 11728 } + }, + right: { + kind: 'null', + loc: { start: 11732, end: 11736 } + }, + loc: { start: 11716, end: 11736 } + }, + trueStatements: [ + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 11755, end: 11759 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 11760, end: 11769 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 11770, end: 11771 } + }, + { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 11773, end: 11774 } + } + ], + loc: { start: 11755, end: 11775 } + }, + loc: { start: 11748, end: 11776 } + } + ], + falseStatements: undefined, + loc: { start: 11712, end: 11790 } + }, + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 11803, end: 11807 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 11817, end: 11826 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '2', + value: 1024n, + loc: { start: 11827, end: 11842 } + }, + { + kind: 'op_binary', + op: '+', + left: { + kind: 'number', + base: '10', + value: 3n, + loc: { start: 11844, end: 11845 } + }, + right: { + kind: 'number', + base: '10', + value: 8n, + loc: { start: 11848, end: 11849 } + }, + loc: { start: 11844, end: 11849 } + } + ], + loc: { start: 11803, end: 11850 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 11860, end: 11869 } + }, + typeArgs: [], + args: [ + { + kind: 'op_unary', + op: '!!', + operand: { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'address', + loc: { start: 11870, end: 11877 } + }, + field: { + kind: 'id', + text: 'hash', + loc: { start: 11878, end: 11882 } + }, + loc: { start: 11870, end: 11882 } + }, + loc: { start: 11870, end: 11884 } + }, + { + kind: 'number', + base: '10', + value: 256n, + loc: { start: 11886, end: 11889 } + } + ], + loc: { start: 11803, end: 11890 } + }, + loc: { start: 11796, end: 11891 } + } + ] + }, + loc: { start: 11621, end: 11893 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 11661, end: 11668 } }, + loc: { start: 11661, end: 11668 } + } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'forceBasechain', + loc: { start: 12980, end: 12994 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'address', + loc: { start: 12995, end: 13002 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 13004, end: 13011 } + }, + typeArgs: [], + loc: { start: 13004, end: 13011 } + }, + loc: { start: 12995, end: 13011 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'REWRITESTDADDR DROP 138 THROWIF' ] + }, + loc: { start: 12972, end: 13048 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'forceWorkchain', + loc: { start: 14243, end: 14257 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'address', + loc: { start: 14258, end: 14265 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 14267, end: 14274 } + }, + typeArgs: [], + loc: { start: 14267, end: 14274 } + }, + loc: { start: 14258, end: 14274 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'workchain', + loc: { start: 14276, end: 14285 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14287, end: 14290 } + }, + loc: { start: 14287, end: 14290 } + }, + loc: { start: 14276, end: 14290 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'errorCode', + loc: { start: 14292, end: 14301 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14303, end: 14306 } + }, + loc: { start: 14303, end: 14306 } + }, + loc: { start: 14292, end: 14306 } + } + ], + body: { + kind: 'asm_body', + shuffle: { + args: [ + { + kind: 'id', + text: 'errorCode', + loc: { start: 14210, end: 14219 } + }, + { + kind: 'id', + text: 'workchain', + loc: { start: 14220, end: 14229 } + }, + { + kind: 'id', + text: 'address', + loc: { start: 14230, end: 14237 } + } + ], + ret: [] + }, + instructions: [ 'REWRITESTDADDR\n DROP\n CMP\n THROWANYIF' ] + }, + loc: { start: 14206, end: 14362 } + } + ] + }, + 'contractBasechainAddress' => { + kind: 'tact', + path: 'std/internal/address.tact', + code: '/// Extension function for the `Slice` type. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Casts the `Slice` to an `Address` in a given `chain` ID and returns it. The inverse of `Address.asSlice()` and a safe but more gas-expensive version of `Slice.asAddressUnsafe()`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + "/// let a: Address = myAddress(); // let's assume we're in a basechain\n" + + '/// let a2: Address = a.asSlice().asAddress(0); // so the chain ID is 0\n' + + '///\n' + + '/// a == a2; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 136: [Invalid standard address] — Thrown when the given `Slice` contains an invalid\n' + + '/// tag prefix (not `0b100`) or an invalid account ID length (not 256 bits).\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#sliceasaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#sliceasaddressunsafe\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#addressasslice\n' + + '///\n' + + '/// [Invalid standard address]: https://docs.tact-lang.org/book/exit-codes#136\n' + + '///\n' + + 'extends fun asAddress(self: Slice, chain: Int): Address {\n' + + ' // 11 bits for the prefix,\n' + + ' // 256 bits for the address itself\n' + + ' throwUnless(TactExitCodeInvalidStandardAddress, self.bits() == 267);\n' + + '\n' + + ' if (chain == -1) {\n' + + ' // 1279 = 0b100_1111_1111,\n' + + ' // i.e. internal address prefix and chain ID -1\n' + + ' throwUnless(TactExitCodeInvalidStandardAddress, self.preloadUint(11) == 1279);\n' + + ' } else {\n' + + ' // Only check the correct internal address prefix,\n' + + ' // but do not verify the chain ID\n' + + ' throwUnless(TactExitCodeInvalidStandardAddress, self.preloadUint(3) == 4);\n' + + ' }\n' + + '\n' + + ' // Proceed with the cast\n' + + ' return self.asAddressUnsafe();\n' + + '}\n' + + '\n' + + '/// Extension function for the `Slice` type. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Unsafely casts the `Slice` to an `Address` and returns it. The inverse of `Address.asSlice()`.\n' + + '///\n' + + '/// This function does **not** perform any checks on the contents of the `Slice`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let a: Address = myAddress();\n' + + '/// let a2: Address = a.asSlice().asAddressUnsafe();\n' + + '///\n' + + '/// a == a2; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// Use it only if you want to optimize the code for gas and can guarantee in advance that the `Slice` contains the data of an `Address`.\n' + + '///\n' + + '/// Otherwise, use a safer but more gas-expensive `Slice.asAddress()` function.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#sliceasaddressunsafe\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#sliceasaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#addressasslice\n' + + '///\n' + + 'asm extends fun asAddressUnsafe(self: Slice): Address {}\n' + + '\n' + + '/// Extension function for the `Address` type.\n' + + '///\n' + + '/// Casts `self` back to the underlying `Slice` and returns it. The inverse of `Slice.asAddressUnsafe()`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let a: Address = myAddress();\n' + + '/// let fizz: Slice = beginCell().storeAddress(a).asSlice();\n' + + '/// let buzz: Slice = a.asSlice(); // cheap, unlike the previous statement\n' + + '///\n' + + '/// fizz == buzz; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#addressasslice\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#sliceasaddressunsafe\n' + + '///\n' + + 'asm extends fun asSlice(self: Address): Slice {}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Creates a new `Address` based on the `chain` ID and the SHA-256 encoded `hash` value (account ID).\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// Attempts to specify an uncommon `chain` ID (not -1 or 0) that can be detected in compile-time will result in a compilation error.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let oldTonFoundationAddr: Address =\n' + + '/// newAddress(0, 0x83dfd552e63729b472fcbcc8c45ebcc6691702558b68ec7527e1ba403a0f31a8);\n' + + '/// // ↑ ↑\n' + + "/// // | sha-256 hash of contract's init package (StateInit)\n" + + '/// // chain id: 0 is a workchain, -1 is a masterchain\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-addresses#newaddress\n' + + '///\n' + + 'inline fun newAddress(chain: Int, hash: Int): Address {\n' + + ' return beginCell()\n' + + ' .storeUint(0b10_0, 3)\n' + + ' .storeInt(chain, 8)\n' + + ' .storeUint(hash, 256)\n' + + ' .endCell()\n' + + ' .asSlice()\n' + + ' .asAddressUnsafe();\n' + + '}\n' + + '\n' + + '/// Struct representing the standard address on TON Blockchain with signed 8-bit `workchain` ID and an unsigned 256-bit `address` in the specified `workchain`. Available since Tact 1.5.0.\n' + + '///\n' + + '/// At the moment, only `workchain` IDs used on TON are 0 of the basechain and -1 of the masterchain.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#parsestdaddress\n' + + '/// * https://github.com/ton-blockchain/ton/blob/master/crypto/block/block.tlb#L105-L106\n' + + '///\n' + + 'struct StdAddress {\n' + + ' workchain: Int as int8;\n' + + ' address: Int as uint256;\n' + + '}\n' + + '\n' + + '/// Struct representing the address of variable length with signed 32-bit `workchain` ID and a `Slice` containing unsigned `address` in the specified `workchain`. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Variable-length addresses are intended for future extensions, and while validators must be ready to accept them in inbound messages, the standard (non-variable) addresses are used whenever possible.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#parsevaraddress\n' + + '/// * https://github.com/ton-blockchain/ton/blob/master/crypto/block/block.tlb#L107-L108\n' + + '///\n' + + 'struct VarAddress {\n' + + ' workchain: Int as int32;\n' + + ' address: Slice;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Converts a `slice` containing an address into the `StdAddress` Struct and returns it.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let addr = address("EQDtFpEwcFAEcRe5mLVh2N6C0x-_hJEM7W61_JLnSF74p4q2");\n' + + '/// let parsedAddr = parseStdAddress(addr.asSlice());\n' + + '///\n' + + '/// parsedAddr.workchain; // 0\n' + + '/// parsedAddr.address; // 107...287\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-addresses#parsestdaddress\n' + + '///\n' + + 'asm fun parseStdAddress(slice: Slice): StdAddress { REWRITESTDADDR }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Converts a `slice` containing an address of variable length into the `VarAddress` Struct and returns it.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let varAddrSlice = beginCell()\n' + + '/// .storeUint(6, 3) // to recognize the following as a VarAddress\n' + + '/// .storeUint(123, 9) // make address occupy 123 bits\n' + + '/// .storeUint(234, 32) // specify workchain ID of 234\n' + + '/// .storeUint(345, 123) // specify address of 345\n' + + '/// .asSlice();\n' + + '/// let parsedVarAddr = parseVarAddress(varAddrSlice);\n' + + '///\n' + + '/// parsedVarAddr.workchain; // 234\n' + + '/// parsedVarAddr.address; // CS{Cell{002...2b3} bits: 44..167; refs: 0..0}\n' + + '/// parsedVarAddr.address.loadUint(123); // 345\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-addresses#parsevaraddress\n' + + '///\n' + + 'asm fun parseVarAddress(slice: Slice): VarAddress { REWRITEVARADDR }\n' + + '\n' + + '/// Extension mutation function for the `Slice` type.\n' + + '///\n' + + '/// Loads and returns an `Address` from the `Slice`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let s: Slice = beginCell().storeAddress(myAddress()).asSlice();\n' + + '/// let fizz: Address = s.loadAddress();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + "/// * 8: [Cell overflow] — Thrown when attempting to load an `Address` when `Slice` doesn't contain it.\n" + + '/// * 9: [Cell underflow] — Thrown when attempting to load more data than `Slice` contains.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#sliceloadaddress\n' + + '///\n' + + '/// [Cell overflow]: https://docs.tact-lang.org/book/exit-codes#8\n' + + '/// [Cell underflow]: https://docs.tact-lang.org/book/exit-codes#9\n' + + '///\n' + + 'asm(-> 1 0) extends mutates fun loadAddress(self: Slice): Address { LDMSGADDR }\n' + + '\n' + + '/// Extension mutation function for the `Slice` type. Available since Tact 1.6.2.\n' + + '///\n' + + '/// Skips an `Address` from the `Slice`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let s1: Slice = beginCell()\n' + + '/// .storeAddress(myAddress())\n' + + '/// .storeUint(42, 32)\n' + + '/// .asSlice();\n' + + '///\n' + + '/// s1.skipAddress();\n' + + '/// let fizz: Int = s1.loadUint(32); // 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + "/// * 8: [Cell overflow] — Thrown when attempting to skip an `Address` when `Slice` doesn't contain it.\n" + + '/// * 9: [Cell underflow] — Thrown when attempting to skip more data than `Slice` contains.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#sliceskipaddress\n' + + '///\n' + + '/// [Cell overflow]: https://docs.tact-lang.org/book/exit-codes#8\n' + + '/// [Cell underflow]: https://docs.tact-lang.org/book/exit-codes#9\n' + + '///\n' + + 'asm extends mutates fun skipAddress(self: Slice) { LDMSGADDR NIP }\n' + + '\n' + + '/// Extension function for the `Builder` type.\n' + + '///\n' + + '/// Stores the `address` in the copy of the `Builder`. Returns that copy.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b.storeAddress(myAddress());\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 8: [Cell overflow] — Thrown when attempting to store an `address` into the `Builder` when it cannot fit it.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#builderstoreaddress\n' + + '///\n' + + '/// [Cell overflow]: https://docs.tact-lang.org/book/exit-codes#8\n' + + '///\n' + + 'asm extends fun storeAddress(self: Builder, address: Address): Builder { STSLICER }\n' + + '\n' + + '/// Struct representing a basechain address. Available since Tact 1.6.0.\n' + + '///\n' + + '/// A basechain address (workchain 0) can be either empty (null hash) or contain a 256-bit hash value.\n' + + '///\n' + + 'struct BasechainAddress {\n' + + ' hash: Int?;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Creates and returns an empty basechain address with a null hash.\n' + + '///\n' + + '/// When serialized, an empty basechain address is represented as `addr_none`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let emptyAddr: BasechainAddress = emptyBasechainAddress();\n' + + '/// emptyAddr.hash == null; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + 'inline fun emptyBasechainAddress(): BasechainAddress {\n' + + ' return BasechainAddress { hash: null };\n' + + '}\n' + + '\n' + + '/// Global f'... 4363 more characters, + imports: [], + items: [ + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'asAddress', + loc: { start: 998, end: 1007 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 1034, end: 1041 } + }, + typeArgs: [], + loc: { start: 1034, end: 1041 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'chain', + loc: { start: 1021, end: 1026 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1028, end: 1031 } + }, + loc: { start: 1028, end: 1031 } + }, + loc: { start: 1021, end: 1031 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throwUnless', + loc: { start: 1118, end: 1129 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'TactExitCodeInvalidStandardAddress', + loc: { start: 1130, end: 1164 } + }, + { + kind: 'op_binary', + op: '==', + left: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 1166, end: 1170 } + }, + method: { + kind: 'id', + text: 'bits', + loc: { start: 1171, end: 1175 } + }, + typeArgs: [], + args: [], + loc: { start: 1166, end: 1177 } + }, + right: { + kind: 'number', + base: '10', + value: 267n, + loc: { start: 1181, end: 1184 } + }, + loc: { start: 1166, end: 1184 } + } + ], + loc: { start: 1118, end: 1185 } + }, + loc: { start: 1118, end: 1186 } + }, + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'chain', + loc: { start: 1196, end: 1201 } + }, + right: { + kind: 'op_unary', + op: '-', + operand: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1206, end: 1207 } + }, + loc: { start: 1205, end: 1207 } + }, + loc: { start: 1196, end: 1207 } + }, + trueStatements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throwUnless', + loc: { start: 1310, end: 1321 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'TactExitCodeInvalidStandardAddress', + loc: { start: 1322, end: 1356 } + }, + { + kind: 'op_binary', + op: '==', + left: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 1358, end: 1362 } + }, + method: { + kind: 'id', + text: 'preloadUint', + loc: { start: 1363, end: 1374 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 11n, + loc: { start: 1375, end: 1377 } + } + ], + loc: { start: 1358, end: 1378 } + }, + right: { + kind: 'number', + base: '10', + value: 1279n, + loc: { start: 1382, end: 1386 } + }, + loc: { start: 1358, end: 1386 } + } + ], + loc: { start: 1310, end: 1387 } + }, + loc: { start: 1310, end: 1388 } + } + ], + falseStatements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throwUnless', + loc: { start: 1511, end: 1522 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'TactExitCodeInvalidStandardAddress', + loc: { start: 1523, end: 1557 } + }, + { + kind: 'op_binary', + op: '==', + left: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 1559, end: 1563 } + }, + method: { + kind: 'id', + text: 'preloadUint', + loc: { start: 1564, end: 1575 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 3n, + loc: { start: 1576, end: 1577 } + } + ], + loc: { start: 1559, end: 1578 } + }, + right: { + kind: 'number', + base: '10', + value: 4n, + loc: { start: 1582, end: 1583 } + }, + loc: { start: 1559, end: 1583 } + } + ], + loc: { start: 1511, end: 1584 } + }, + loc: { start: 1511, end: 1585 } + } + ], + loc: { start: 1192, end: 1591 } + }, + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 1633, end: 1637 } + }, + method: { + kind: 'id', + text: 'asAddressUnsafe', + loc: { start: 1638, end: 1653 } + }, + typeArgs: [], + args: [], + loc: { start: 1633, end: 1655 } + }, + loc: { start: 1626, end: 1656 } + } + ] + }, + loc: { start: 986, end: 1658 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 1014, end: 1019 } }, + loc: { start: 1014, end: 1019 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'asAddressUnsafe', + loc: { start: 2554, end: 2569 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 2584, end: 2591 } + }, + typeArgs: [], + loc: { start: 2584, end: 2591 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ '' ] + }, + loc: { start: 2538, end: 2594 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 2576, end: 2581 } }, + loc: { start: 2576, end: 2581 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'asSlice', + loc: { start: 3188, end: 3195 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 3212, end: 3217 } }, + loc: { start: 3212, end: 3217 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ '' ] + }, + loc: { start: 3172, end: 3220 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3202, end: 3209 } + }, + typeArgs: [], + loc: { start: 3202, end: 3209 } + } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'newAddress', + loc: { start: 4029, end: 4039 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 4064, end: 4071 } + }, + typeArgs: [], + loc: { start: 4064, end: 4071 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'chain', + loc: { start: 4040, end: 4045 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4047, end: 4050 } + }, + loc: { start: 4047, end: 4050 } + }, + loc: { start: 4040, end: 4050 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'hash', + loc: { start: 4052, end: 4056 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4058, end: 4061 } + }, + loc: { start: 4058, end: 4061 } + }, + loc: { start: 4052, end: 4061 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'static_call', + function: { + kind: 'id', + text: 'beginCell', + loc: { start: 4085, end: 4094 } + }, + typeArgs: [], + args: [], + loc: { start: 4085, end: 4096 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 4106, end: 4115 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '2', + value: 4n, + loc: { start: 4116, end: 4122 } + }, + { + kind: 'number', + base: '10', + value: 3n, + loc: { start: 4124, end: 4125 } + } + ], + loc: { start: 4085, end: 4126 } + }, + method: { + kind: 'id', + text: 'storeInt', + loc: { start: 4136, end: 4144 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'chain', + loc: { start: 4145, end: 4150 } + }, + { + kind: 'number', + base: '10', + value: 8n, + loc: { start: 4152, end: 4153 } + } + ], + loc: { start: 4085, end: 4154 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 4164, end: 4173 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'hash', + loc: { start: 4174, end: 4178 } + }, + { + kind: 'number', + base: '10', + value: 256n, + loc: { start: 4180, end: 4183 } + } + ], + loc: { start: 4085, end: 4184 } + }, + method: { + kind: 'id', + text: 'endCell', + loc: { start: 4194, end: 4201 } + }, + typeArgs: [], + args: [], + loc: { start: 4085, end: 4203 } + }, + method: { + kind: 'id', + text: 'asSlice', + loc: { start: 4213, end: 4220 } + }, + typeArgs: [], + args: [], + loc: { start: 4085, end: 4222 } + }, + method: { + kind: 'id', + text: 'asAddressUnsafe', + loc: { start: 4232, end: 4247 } + }, + typeArgs: [], + args: [], + loc: { start: 4085, end: 4249 } + }, + loc: { start: 4078, end: 4250 } + } + ] + }, + loc: { start: 4018, end: 4252 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'StdAddress', + loc: { start: 4729, end: 4739 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'workchain', + loc: { start: 4746, end: 4755 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 8, + loc: { start: 4757, end: 4768 } + }, + loc: { start: 4757, end: 4760 } + }, + initializer: undefined, + loc: { start: 4746, end: 4768 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'address', + loc: { start: 4774, end: 4781 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'unsigned', + width: 256, + loc: { start: 4783, end: 4797 } + }, + loc: { start: 4783, end: 4786 } + }, + initializer: undefined, + loc: { start: 4774, end: 4797 } + } + ], + loc: { start: 4722, end: 4800 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'VarAddress', + loc: { start: 5381, end: 5391 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'workchain', + loc: { start: 5398, end: 5407 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 32, + loc: { start: 5409, end: 5421 } + }, + loc: { start: 5409, end: 5412 } + }, + initializer: undefined, + loc: { start: 5398, end: 5421 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'address', + loc: { start: 5427, end: 5434 } + }, + type: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 5436, end: 5441 } }, + loc: { start: 5436, end: 5441 } + }, + initializer: undefined, + loc: { start: 5427, end: 5441 } + } + ], + loc: { start: 5374, end: 5444 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'parseStdAddress', + loc: { start: 5946, end: 5961 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StdAddress', + loc: { start: 5977, end: 5987 } + }, + typeArgs: [], + loc: { start: 5977, end: 5987 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'slice', + loc: { start: 5962, end: 5967 } + }, + type: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 5969, end: 5974 } }, + loc: { start: 5969, end: 5974 } + }, + loc: { start: 5962, end: 5974 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'REWRITESTDADDR' ] + }, + loc: { start: 5938, end: 6006 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'parseVarAddress', + loc: { start: 6898, end: 6913 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'VarAddress', + loc: { start: 6929, end: 6939 } + }, + typeArgs: [], + loc: { start: 6929, end: 6939 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'slice', + loc: { start: 6914, end: 6919 } + }, + type: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 6921, end: 6926 } }, + loc: { start: 6921, end: 6926 } + }, + loc: { start: 6914, end: 6926 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'REWRITEVARADDR' ] + }, + loc: { start: 6890, end: 6958 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadAddress', + loc: { start: 7707, end: 7718 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 7733, end: 7740 } + }, + typeArgs: [], + loc: { start: 7733, end: 7740 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { + args: [], + ret: [ + { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 7682, end: 7683 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 7684, end: 7685 } + } + ] + }, + instructions: [ 'LDMSGADDR' ] + }, + loc: { start: 7675, end: 7754 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 7725, end: 7730 } }, + loc: { start: 7725, end: 7730 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'skipAddress', + loc: { start: 8601, end: 8612 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LDMSGADDR NIP' ] + }, + loc: { start: 8577, end: 8643 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 8619, end: 8624 } }, + loc: { start: 8619, end: 8624 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeAddress', + loc: { start: 9222, end: 9234 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 9269, end: 9276 } }, + loc: { start: 9269, end: 9276 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'address', + loc: { start: 9250, end: 9257 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 9259, end: 9266 } + }, + typeArgs: [], + loc: { start: 9259, end: 9266 } + }, + loc: { start: 9250, end: 9266 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'STSLICER' ] + }, + loc: { start: 9206, end: 9289 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 9241, end: 9248 } }, + loc: { start: 9241, end: 9248 } + } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 9482, end: 9498 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'hash', + loc: { start: 9505, end: 9509 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 9514, end: 9515 } + }, + typeArgs: [ + { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9511, end: 9514 } + }, + loc: { start: 9511, end: 9514 } + } + ], + loc: { start: 9514, end: 9515 } + }, + initializer: undefined, + loc: { start: 9505, end: 9515 } + } + ], + loc: { start: 9475, end: 9518 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'emptyBasechainAddress', + loc: { start: 9897, end: 9918 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 9922, end: 9938 } + }, + typeArgs: [], + loc: { start: 9922, end: 9938 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'struct_instance', + type: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 9952, end: 9968 } + }, + typeArgs: [], + args: [ + { + kind: 'struct_field_initializer', + field: { + kind: 'id', + text: 'hash', + loc: { start: 9971, end: 9975 } + }, + initializer: { kind: 'null', loc: { start: 9977, end: 9981 } }, + loc: { start: 9971, end: 9981 } + } + ], + loc: { start: 9952, end: 9983 } + }, + loc: { start: 9945, end: 9984 } + } + ] + }, + loc: { start: 9886, end: 9986 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'newBasechainAddress', + loc: { start: 10311, end: 10330 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 10343, end: 10359 } + }, + typeArgs: [], + loc: { start: 10343, end: 10359 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'hash', + loc: { start: 10331, end: 10335 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10337, end: 10340 } + }, + loc: { start: 10337, end: 10340 } + }, + loc: { start: 10331, end: 10340 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'struct_instance', + type: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 10373, end: 10389 } + }, + typeArgs: [], + args: [ + { + kind: 'struct_field_initializer', + field: { + kind: 'id', + text: 'hash', + loc: { start: 10392, end: 10396 } + }, + initializer: { + kind: 'var', + name: 'hash', + loc: { start: 10392, end: 10396 } + }, + loc: { start: 10392, end: 10396 } + } + ], + loc: { start: 10373, end: 10398 } + }, + loc: { start: 10366, end: 10399 } + } + ] + }, + loc: { start: 10300, end: 10401 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'contractBasechainAddress', + loc: { start: 10865, end: 10889 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 10905, end: 10921 } + }, + typeArgs: [], + loc: { start: 10905, end: 10921 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 's', + loc: { start: 10890, end: 10891 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 10893, end: 10902 } + }, + typeArgs: [], + loc: { start: 10893, end: 10902 } + }, + loc: { start: 10890, end: 10902 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'hash', + loc: { start: 10932, end: 10936 } + }, + type: undefined, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractHash', + loc: { start: 10939, end: 10951 } + }, + typeArgs: [], + args: [ + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 10952, end: 10953 } + }, + field: { + kind: 'id', + text: 'code', + loc: { start: 10954, end: 10958 } + }, + loc: { start: 10952, end: 10958 } + }, + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 10960, end: 10961 } + }, + field: { + kind: 'id', + text: 'data', + loc: { start: 10962, end: 10966 } + }, + loc: { start: 10960, end: 10966 } + } + ], + loc: { start: 10939, end: 10967 } + }, + loc: { start: 10928, end: 10968 } + }, + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'newBasechainAddress', + loc: { start: 10980, end: 10999 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'hash', + loc: { start: 11000, end: 11004 } + } + ], + loc: { start: 10980, end: 11005 } + }, + loc: { start: 10973, end: 11006 } + } + ] + }, + loc: { start: 10854, end: 11008 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeBasechainAddress', + loc: { start: 11633, end: 11654 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 11698, end: 11705 } + }, + loc: { start: 11698, end: 11705 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'address', + loc: { start: 11670, end: 11677 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 11679, end: 11695 } + }, + typeArgs: [], + loc: { start: 11679, end: 11695 } + }, + loc: { start: 11670, end: 11695 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'address', + loc: { start: 11716, end: 11723 } + }, + field: { + kind: 'id', + text: 'hash', + loc: { start: 11724, end: 11728 } + }, + loc: { start: 11716, end: 11728 } + }, + right: { + kind: 'null', + loc: { start: 11732, end: 11736 } + }, + loc: { start: 11716, end: 11736 } + }, + trueStatements: [ + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 11755, end: 11759 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 11760, end: 11769 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 11770, end: 11771 } + }, + { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 11773, end: 11774 } + } + ], + loc: { start: 11755, end: 11775 } + }, + loc: { start: 11748, end: 11776 } + } + ], + falseStatements: undefined, + loc: { start: 11712, end: 11790 } + }, + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 11803, end: 11807 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 11817, end: 11826 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '2', + value: 1024n, + loc: { start: 11827, end: 11842 } + }, + { + kind: 'op_binary', + op: '+', + left: { + kind: 'number', + base: '10', + value: 3n, + loc: { start: 11844, end: 11845 } + }, + right: { + kind: 'number', + base: '10', + value: 8n, + loc: { start: 11848, end: 11849 } + }, + loc: { start: 11844, end: 11849 } + } + ], + loc: { start: 11803, end: 11850 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 11860, end: 11869 } + }, + typeArgs: [], + args: [ + { + kind: 'op_unary', + op: '!!', + operand: { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'address', + loc: { start: 11870, end: 11877 } + }, + field: { + kind: 'id', + text: 'hash', + loc: { start: 11878, end: 11882 } + }, + loc: { start: 11870, end: 11882 } + }, + loc: { start: 11870, end: 11884 } + }, + { + kind: 'number', + base: '10', + value: 256n, + loc: { start: 11886, end: 11889 } + } + ], + loc: { start: 11803, end: 11890 } + }, + loc: { start: 11796, end: 11891 } + } + ] + }, + loc: { start: 11621, end: 11893 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 11661, end: 11668 } }, + loc: { start: 11661, end: 11668 } + } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'forceBasechain', + loc: { start: 12980, end: 12994 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'address', + loc: { start: 12995, end: 13002 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 13004, end: 13011 } + }, + typeArgs: [], + loc: { start: 13004, end: 13011 } + }, + loc: { start: 12995, end: 13011 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'REWRITESTDADDR DROP 138 THROWIF' ] + }, + loc: { start: 12972, end: 13048 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'forceWorkchain', + loc: { start: 14243, end: 14257 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'address', + loc: { start: 14258, end: 14265 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 14267, end: 14274 } + }, + typeArgs: [], + loc: { start: 14267, end: 14274 } + }, + loc: { start: 14258, end: 14274 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'workchain', + loc: { start: 14276, end: 14285 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14287, end: 14290 } + }, + loc: { start: 14287, end: 14290 } + }, + loc: { start: 14276, end: 14290 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'errorCode', + loc: { start: 14292, end: 14301 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14303, end: 14306 } + }, + loc: { start: 14303, end: 14306 } + }, + loc: { start: 14292, end: 14306 } + } + ], + body: { + kind: 'asm_body', + shuffle: { + args: [ + { + kind: 'id', + text: 'errorCode', + loc: { start: 14210, end: 14219 } + }, + { + kind: 'id', + text: 'workchain', + loc: { start: 14220, end: 14229 } + }, + { + kind: 'id', + text: 'address', + loc: { start: 14230, end: 14237 } + } + ], + ret: [] + }, + instructions: [ 'REWRITESTDADDR\n DROP\n CMP\n THROWANYIF' ] + }, + loc: { start: 14206, end: 14362 } + } + ] + }, + 'forceBasechain' => { + kind: 'tact', + path: 'std/internal/address.tact', + code: '/// Extension function for the `Slice` type. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Casts the `Slice` to an `Address` in a given `chain` ID and returns it. The inverse of `Address.asSlice()` and a safe but more gas-expensive version of `Slice.asAddressUnsafe()`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + "/// let a: Address = myAddress(); // let's assume we're in a basechain\n" + + '/// let a2: Address = a.asSlice().asAddress(0); // so the chain ID is 0\n' + + '///\n' + + '/// a == a2; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 136: [Invalid standard address] — Thrown when the given `Slice` contains an invalid\n' + + '/// tag prefix (not `0b100`) or an invalid account ID length (not 256 bits).\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#sliceasaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#sliceasaddressunsafe\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#addressasslice\n' + + '///\n' + + '/// [Invalid standard address]: https://docs.tact-lang.org/book/exit-codes#136\n' + + '///\n' + + 'extends fun asAddress(self: Slice, chain: Int): Address {\n' + + ' // 11 bits for the prefix,\n' + + ' // 256 bits for the address itself\n' + + ' throwUnless(TactExitCodeInvalidStandardAddress, self.bits() == 267);\n' + + '\n' + + ' if (chain == -1) {\n' + + ' // 1279 = 0b100_1111_1111,\n' + + ' // i.e. internal address prefix and chain ID -1\n' + + ' throwUnless(TactExitCodeInvalidStandardAddress, self.preloadUint(11) == 1279);\n' + + ' } else {\n' + + ' // Only check the correct internal address prefix,\n' + + ' // but do not verify the chain ID\n' + + ' throwUnless(TactExitCodeInvalidStandardAddress, self.preloadUint(3) == 4);\n' + + ' }\n' + + '\n' + + ' // Proceed with the cast\n' + + ' return self.asAddressUnsafe();\n' + + '}\n' + + '\n' + + '/// Extension function for the `Slice` type. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Unsafely casts the `Slice` to an `Address` and returns it. The inverse of `Address.asSlice()`.\n' + + '///\n' + + '/// This function does **not** perform any checks on the contents of the `Slice`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let a: Address = myAddress();\n' + + '/// let a2: Address = a.asSlice().asAddressUnsafe();\n' + + '///\n' + + '/// a == a2; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// Use it only if you want to optimize the code for gas and can guarantee in advance that the `Slice` contains the data of an `Address`.\n' + + '///\n' + + '/// Otherwise, use a safer but more gas-expensive `Slice.asAddress()` function.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#sliceasaddressunsafe\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#sliceasaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#addressasslice\n' + + '///\n' + + 'asm extends fun asAddressUnsafe(self: Slice): Address {}\n' + + '\n' + + '/// Extension function for the `Address` type.\n' + + '///\n' + + '/// Casts `self` back to the underlying `Slice` and returns it. The inverse of `Slice.asAddressUnsafe()`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let a: Address = myAddress();\n' + + '/// let fizz: Slice = beginCell().storeAddress(a).asSlice();\n' + + '/// let buzz: Slice = a.asSlice(); // cheap, unlike the previous statement\n' + + '///\n' + + '/// fizz == buzz; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#addressasslice\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#sliceasaddressunsafe\n' + + '///\n' + + 'asm extends fun asSlice(self: Address): Slice {}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Creates a new `Address` based on the `chain` ID and the SHA-256 encoded `hash` value (account ID).\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// Attempts to specify an uncommon `chain` ID (not -1 or 0) that can be detected in compile-time will result in a compilation error.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let oldTonFoundationAddr: Address =\n' + + '/// newAddress(0, 0x83dfd552e63729b472fcbcc8c45ebcc6691702558b68ec7527e1ba403a0f31a8);\n' + + '/// // ↑ ↑\n' + + "/// // | sha-256 hash of contract's init package (StateInit)\n" + + '/// // chain id: 0 is a workchain, -1 is a masterchain\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-addresses#newaddress\n' + + '///\n' + + 'inline fun newAddress(chain: Int, hash: Int): Address {\n' + + ' return beginCell()\n' + + ' .storeUint(0b10_0, 3)\n' + + ' .storeInt(chain, 8)\n' + + ' .storeUint(hash, 256)\n' + + ' .endCell()\n' + + ' .asSlice()\n' + + ' .asAddressUnsafe();\n' + + '}\n' + + '\n' + + '/// Struct representing the standard address on TON Blockchain with signed 8-bit `workchain` ID and an unsigned 256-bit `address` in the specified `workchain`. Available since Tact 1.5.0.\n' + + '///\n' + + '/// At the moment, only `workchain` IDs used on TON are 0 of the basechain and -1 of the masterchain.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#parsestdaddress\n' + + '/// * https://github.com/ton-blockchain/ton/blob/master/crypto/block/block.tlb#L105-L106\n' + + '///\n' + + 'struct StdAddress {\n' + + ' workchain: Int as int8;\n' + + ' address: Int as uint256;\n' + + '}\n' + + '\n' + + '/// Struct representing the address of variable length with signed 32-bit `workchain` ID and a `Slice` containing unsigned `address` in the specified `workchain`. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Variable-length addresses are intended for future extensions, and while validators must be ready to accept them in inbound messages, the standard (non-variable) addresses are used whenever possible.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#parsevaraddress\n' + + '/// * https://github.com/ton-blockchain/ton/blob/master/crypto/block/block.tlb#L107-L108\n' + + '///\n' + + 'struct VarAddress {\n' + + ' workchain: Int as int32;\n' + + ' address: Slice;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Converts a `slice` containing an address into the `StdAddress` Struct and returns it.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let addr = address("EQDtFpEwcFAEcRe5mLVh2N6C0x-_hJEM7W61_JLnSF74p4q2");\n' + + '/// let parsedAddr = parseStdAddress(addr.asSlice());\n' + + '///\n' + + '/// parsedAddr.workchain; // 0\n' + + '/// parsedAddr.address; // 107...287\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-addresses#parsestdaddress\n' + + '///\n' + + 'asm fun parseStdAddress(slice: Slice): StdAddress { REWRITESTDADDR }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Converts a `slice` containing an address of variable length into the `VarAddress` Struct and returns it.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let varAddrSlice = beginCell()\n' + + '/// .storeUint(6, 3) // to recognize the following as a VarAddress\n' + + '/// .storeUint(123, 9) // make address occupy 123 bits\n' + + '/// .storeUint(234, 32) // specify workchain ID of 234\n' + + '/// .storeUint(345, 123) // specify address of 345\n' + + '/// .asSlice();\n' + + '/// let parsedVarAddr = parseVarAddress(varAddrSlice);\n' + + '///\n' + + '/// parsedVarAddr.workchain; // 234\n' + + '/// parsedVarAddr.address; // CS{Cell{002...2b3} bits: 44..167; refs: 0..0}\n' + + '/// parsedVarAddr.address.loadUint(123); // 345\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-addresses#parsevaraddress\n' + + '///\n' + + 'asm fun parseVarAddress(slice: Slice): VarAddress { REWRITEVARADDR }\n' + + '\n' + + '/// Extension mutation function for the `Slice` type.\n' + + '///\n' + + '/// Loads and returns an `Address` from the `Slice`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let s: Slice = beginCell().storeAddress(myAddress()).asSlice();\n' + + '/// let fizz: Address = s.loadAddress();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + "/// * 8: [Cell overflow] — Thrown when attempting to load an `Address` when `Slice` doesn't contain it.\n" + + '/// * 9: [Cell underflow] — Thrown when attempting to load more data than `Slice` contains.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#sliceloadaddress\n' + + '///\n' + + '/// [Cell overflow]: https://docs.tact-lang.org/book/exit-codes#8\n' + + '/// [Cell underflow]: https://docs.tact-lang.org/book/exit-codes#9\n' + + '///\n' + + 'asm(-> 1 0) extends mutates fun loadAddress(self: Slice): Address { LDMSGADDR }\n' + + '\n' + + '/// Extension mutation function for the `Slice` type. Available since Tact 1.6.2.\n' + + '///\n' + + '/// Skips an `Address` from the `Slice`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let s1: Slice = beginCell()\n' + + '/// .storeAddress(myAddress())\n' + + '/// .storeUint(42, 32)\n' + + '/// .asSlice();\n' + + '///\n' + + '/// s1.skipAddress();\n' + + '/// let fizz: Int = s1.loadUint(32); // 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + "/// * 8: [Cell overflow] — Thrown when attempting to skip an `Address` when `Slice` doesn't contain it.\n" + + '/// * 9: [Cell underflow] — Thrown when attempting to skip more data than `Slice` contains.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#sliceskipaddress\n' + + '///\n' + + '/// [Cell overflow]: https://docs.tact-lang.org/book/exit-codes#8\n' + + '/// [Cell underflow]: https://docs.tact-lang.org/book/exit-codes#9\n' + + '///\n' + + 'asm extends mutates fun skipAddress(self: Slice) { LDMSGADDR NIP }\n' + + '\n' + + '/// Extension function for the `Builder` type.\n' + + '///\n' + + '/// Stores the `address` in the copy of the `Builder`. Returns that copy.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b.storeAddress(myAddress());\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 8: [Cell overflow] — Thrown when attempting to store an `address` into the `Builder` when it cannot fit it.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#builderstoreaddress\n' + + '///\n' + + '/// [Cell overflow]: https://docs.tact-lang.org/book/exit-codes#8\n' + + '///\n' + + 'asm extends fun storeAddress(self: Builder, address: Address): Builder { STSLICER }\n' + + '\n' + + '/// Struct representing a basechain address. Available since Tact 1.6.0.\n' + + '///\n' + + '/// A basechain address (workchain 0) can be either empty (null hash) or contain a 256-bit hash value.\n' + + '///\n' + + 'struct BasechainAddress {\n' + + ' hash: Int?;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Creates and returns an empty basechain address with a null hash.\n' + + '///\n' + + '/// When serialized, an empty basechain address is represented as `addr_none`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let emptyAddr: BasechainAddress = emptyBasechainAddress();\n' + + '/// emptyAddr.hash == null; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + 'inline fun emptyBasechainAddress(): BasechainAddress {\n' + + ' return BasechainAddress { hash: null };\n' + + '}\n' + + '\n' + + '/// Global f'... 4363 more characters, + imports: [], + items: [ + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'asAddress', + loc: { start: 998, end: 1007 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 1034, end: 1041 } + }, + typeArgs: [], + loc: { start: 1034, end: 1041 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'chain', + loc: { start: 1021, end: 1026 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1028, end: 1031 } + }, + loc: { start: 1028, end: 1031 } + }, + loc: { start: 1021, end: 1031 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throwUnless', + loc: { start: 1118, end: 1129 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'TactExitCodeInvalidStandardAddress', + loc: { start: 1130, end: 1164 } + }, + { + kind: 'op_binary', + op: '==', + left: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 1166, end: 1170 } + }, + method: { + kind: 'id', + text: 'bits', + loc: { start: 1171, end: 1175 } + }, + typeArgs: [], + args: [], + loc: { start: 1166, end: 1177 } + }, + right: { + kind: 'number', + base: '10', + value: 267n, + loc: { start: 1181, end: 1184 } + }, + loc: { start: 1166, end: 1184 } + } + ], + loc: { start: 1118, end: 1185 } + }, + loc: { start: 1118, end: 1186 } + }, + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'chain', + loc: { start: 1196, end: 1201 } + }, + right: { + kind: 'op_unary', + op: '-', + operand: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1206, end: 1207 } + }, + loc: { start: 1205, end: 1207 } + }, + loc: { start: 1196, end: 1207 } + }, + trueStatements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throwUnless', + loc: { start: 1310, end: 1321 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'TactExitCodeInvalidStandardAddress', + loc: { start: 1322, end: 1356 } + }, + { + kind: 'op_binary', + op: '==', + left: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 1358, end: 1362 } + }, + method: { + kind: 'id', + text: 'preloadUint', + loc: { start: 1363, end: 1374 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 11n, + loc: { start: 1375, end: 1377 } + } + ], + loc: { start: 1358, end: 1378 } + }, + right: { + kind: 'number', + base: '10', + value: 1279n, + loc: { start: 1382, end: 1386 } + }, + loc: { start: 1358, end: 1386 } + } + ], + loc: { start: 1310, end: 1387 } + }, + loc: { start: 1310, end: 1388 } + } + ], + falseStatements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throwUnless', + loc: { start: 1511, end: 1522 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'TactExitCodeInvalidStandardAddress', + loc: { start: 1523, end: 1557 } + }, + { + kind: 'op_binary', + op: '==', + left: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 1559, end: 1563 } + }, + method: { + kind: 'id', + text: 'preloadUint', + loc: { start: 1564, end: 1575 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 3n, + loc: { start: 1576, end: 1577 } + } + ], + loc: { start: 1559, end: 1578 } + }, + right: { + kind: 'number', + base: '10', + value: 4n, + loc: { start: 1582, end: 1583 } + }, + loc: { start: 1559, end: 1583 } + } + ], + loc: { start: 1511, end: 1584 } + }, + loc: { start: 1511, end: 1585 } + } + ], + loc: { start: 1192, end: 1591 } + }, + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 1633, end: 1637 } + }, + method: { + kind: 'id', + text: 'asAddressUnsafe', + loc: { start: 1638, end: 1653 } + }, + typeArgs: [], + args: [], + loc: { start: 1633, end: 1655 } + }, + loc: { start: 1626, end: 1656 } + } + ] + }, + loc: { start: 986, end: 1658 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 1014, end: 1019 } }, + loc: { start: 1014, end: 1019 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'asAddressUnsafe', + loc: { start: 2554, end: 2569 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 2584, end: 2591 } + }, + typeArgs: [], + loc: { start: 2584, end: 2591 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ '' ] + }, + loc: { start: 2538, end: 2594 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 2576, end: 2581 } }, + loc: { start: 2576, end: 2581 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'asSlice', + loc: { start: 3188, end: 3195 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 3212, end: 3217 } }, + loc: { start: 3212, end: 3217 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ '' ] + }, + loc: { start: 3172, end: 3220 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3202, end: 3209 } + }, + typeArgs: [], + loc: { start: 3202, end: 3209 } + } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'newAddress', + loc: { start: 4029, end: 4039 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 4064, end: 4071 } + }, + typeArgs: [], + loc: { start: 4064, end: 4071 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'chain', + loc: { start: 4040, end: 4045 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4047, end: 4050 } + }, + loc: { start: 4047, end: 4050 } + }, + loc: { start: 4040, end: 4050 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'hash', + loc: { start: 4052, end: 4056 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4058, end: 4061 } + }, + loc: { start: 4058, end: 4061 } + }, + loc: { start: 4052, end: 4061 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'static_call', + function: { + kind: 'id', + text: 'beginCell', + loc: { start: 4085, end: 4094 } + }, + typeArgs: [], + args: [], + loc: { start: 4085, end: 4096 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 4106, end: 4115 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '2', + value: 4n, + loc: { start: 4116, end: 4122 } + }, + { + kind: 'number', + base: '10', + value: 3n, + loc: { start: 4124, end: 4125 } + } + ], + loc: { start: 4085, end: 4126 } + }, + method: { + kind: 'id', + text: 'storeInt', + loc: { start: 4136, end: 4144 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'chain', + loc: { start: 4145, end: 4150 } + }, + { + kind: 'number', + base: '10', + value: 8n, + loc: { start: 4152, end: 4153 } + } + ], + loc: { start: 4085, end: 4154 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 4164, end: 4173 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'hash', + loc: { start: 4174, end: 4178 } + }, + { + kind: 'number', + base: '10', + value: 256n, + loc: { start: 4180, end: 4183 } + } + ], + loc: { start: 4085, end: 4184 } + }, + method: { + kind: 'id', + text: 'endCell', + loc: { start: 4194, end: 4201 } + }, + typeArgs: [], + args: [], + loc: { start: 4085, end: 4203 } + }, + method: { + kind: 'id', + text: 'asSlice', + loc: { start: 4213, end: 4220 } + }, + typeArgs: [], + args: [], + loc: { start: 4085, end: 4222 } + }, + method: { + kind: 'id', + text: 'asAddressUnsafe', + loc: { start: 4232, end: 4247 } + }, + typeArgs: [], + args: [], + loc: { start: 4085, end: 4249 } + }, + loc: { start: 4078, end: 4250 } + } + ] + }, + loc: { start: 4018, end: 4252 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'StdAddress', + loc: { start: 4729, end: 4739 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'workchain', + loc: { start: 4746, end: 4755 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 8, + loc: { start: 4757, end: 4768 } + }, + loc: { start: 4757, end: 4760 } + }, + initializer: undefined, + loc: { start: 4746, end: 4768 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'address', + loc: { start: 4774, end: 4781 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'unsigned', + width: 256, + loc: { start: 4783, end: 4797 } + }, + loc: { start: 4783, end: 4786 } + }, + initializer: undefined, + loc: { start: 4774, end: 4797 } + } + ], + loc: { start: 4722, end: 4800 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'VarAddress', + loc: { start: 5381, end: 5391 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'workchain', + loc: { start: 5398, end: 5407 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 32, + loc: { start: 5409, end: 5421 } + }, + loc: { start: 5409, end: 5412 } + }, + initializer: undefined, + loc: { start: 5398, end: 5421 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'address', + loc: { start: 5427, end: 5434 } + }, + type: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 5436, end: 5441 } }, + loc: { start: 5436, end: 5441 } + }, + initializer: undefined, + loc: { start: 5427, end: 5441 } + } + ], + loc: { start: 5374, end: 5444 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'parseStdAddress', + loc: { start: 5946, end: 5961 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StdAddress', + loc: { start: 5977, end: 5987 } + }, + typeArgs: [], + loc: { start: 5977, end: 5987 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'slice', + loc: { start: 5962, end: 5967 } + }, + type: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 5969, end: 5974 } }, + loc: { start: 5969, end: 5974 } + }, + loc: { start: 5962, end: 5974 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'REWRITESTDADDR' ] + }, + loc: { start: 5938, end: 6006 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'parseVarAddress', + loc: { start: 6898, end: 6913 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'VarAddress', + loc: { start: 6929, end: 6939 } + }, + typeArgs: [], + loc: { start: 6929, end: 6939 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'slice', + loc: { start: 6914, end: 6919 } + }, + type: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 6921, end: 6926 } }, + loc: { start: 6921, end: 6926 } + }, + loc: { start: 6914, end: 6926 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'REWRITEVARADDR' ] + }, + loc: { start: 6890, end: 6958 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadAddress', + loc: { start: 7707, end: 7718 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 7733, end: 7740 } + }, + typeArgs: [], + loc: { start: 7733, end: 7740 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { + args: [], + ret: [ + { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 7682, end: 7683 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 7684, end: 7685 } + } + ] + }, + instructions: [ 'LDMSGADDR' ] + }, + loc: { start: 7675, end: 7754 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 7725, end: 7730 } }, + loc: { start: 7725, end: 7730 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'skipAddress', + loc: { start: 8601, end: 8612 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LDMSGADDR NIP' ] + }, + loc: { start: 8577, end: 8643 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 8619, end: 8624 } }, + loc: { start: 8619, end: 8624 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeAddress', + loc: { start: 9222, end: 9234 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 9269, end: 9276 } }, + loc: { start: 9269, end: 9276 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'address', + loc: { start: 9250, end: 9257 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 9259, end: 9266 } + }, + typeArgs: [], + loc: { start: 9259, end: 9266 } + }, + loc: { start: 9250, end: 9266 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'STSLICER' ] + }, + loc: { start: 9206, end: 9289 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 9241, end: 9248 } }, + loc: { start: 9241, end: 9248 } + } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 9482, end: 9498 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'hash', + loc: { start: 9505, end: 9509 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 9514, end: 9515 } + }, + typeArgs: [ + { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9511, end: 9514 } + }, + loc: { start: 9511, end: 9514 } + } + ], + loc: { start: 9514, end: 9515 } + }, + initializer: undefined, + loc: { start: 9505, end: 9515 } + } + ], + loc: { start: 9475, end: 9518 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'emptyBasechainAddress', + loc: { start: 9897, end: 9918 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 9922, end: 9938 } + }, + typeArgs: [], + loc: { start: 9922, end: 9938 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'struct_instance', + type: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 9952, end: 9968 } + }, + typeArgs: [], + args: [ + { + kind: 'struct_field_initializer', + field: { + kind: 'id', + text: 'hash', + loc: { start: 9971, end: 9975 } + }, + initializer: { kind: 'null', loc: { start: 9977, end: 9981 } }, + loc: { start: 9971, end: 9981 } + } + ], + loc: { start: 9952, end: 9983 } + }, + loc: { start: 9945, end: 9984 } + } + ] + }, + loc: { start: 9886, end: 9986 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'newBasechainAddress', + loc: { start: 10311, end: 10330 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 10343, end: 10359 } + }, + typeArgs: [], + loc: { start: 10343, end: 10359 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'hash', + loc: { start: 10331, end: 10335 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10337, end: 10340 } + }, + loc: { start: 10337, end: 10340 } + }, + loc: { start: 10331, end: 10340 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'struct_instance', + type: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 10373, end: 10389 } + }, + typeArgs: [], + args: [ + { + kind: 'struct_field_initializer', + field: { + kind: 'id', + text: 'hash', + loc: { start: 10392, end: 10396 } + }, + initializer: { + kind: 'var', + name: 'hash', + loc: { start: 10392, end: 10396 } + }, + loc: { start: 10392, end: 10396 } + } + ], + loc: { start: 10373, end: 10398 } + }, + loc: { start: 10366, end: 10399 } + } + ] + }, + loc: { start: 10300, end: 10401 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'contractBasechainAddress', + loc: { start: 10865, end: 10889 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 10905, end: 10921 } + }, + typeArgs: [], + loc: { start: 10905, end: 10921 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 's', + loc: { start: 10890, end: 10891 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 10893, end: 10902 } + }, + typeArgs: [], + loc: { start: 10893, end: 10902 } + }, + loc: { start: 10890, end: 10902 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'hash', + loc: { start: 10932, end: 10936 } + }, + type: undefined, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractHash', + loc: { start: 10939, end: 10951 } + }, + typeArgs: [], + args: [ + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 10952, end: 10953 } + }, + field: { + kind: 'id', + text: 'code', + loc: { start: 10954, end: 10958 } + }, + loc: { start: 10952, end: 10958 } + }, + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 10960, end: 10961 } + }, + field: { + kind: 'id', + text: 'data', + loc: { start: 10962, end: 10966 } + }, + loc: { start: 10960, end: 10966 } + } + ], + loc: { start: 10939, end: 10967 } + }, + loc: { start: 10928, end: 10968 } + }, + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'newBasechainAddress', + loc: { start: 10980, end: 10999 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'hash', + loc: { start: 11000, end: 11004 } + } + ], + loc: { start: 10980, end: 11005 } + }, + loc: { start: 10973, end: 11006 } + } + ] + }, + loc: { start: 10854, end: 11008 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeBasechainAddress', + loc: { start: 11633, end: 11654 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 11698, end: 11705 } + }, + loc: { start: 11698, end: 11705 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'address', + loc: { start: 11670, end: 11677 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 11679, end: 11695 } + }, + typeArgs: [], + loc: { start: 11679, end: 11695 } + }, + loc: { start: 11670, end: 11695 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'address', + loc: { start: 11716, end: 11723 } + }, + field: { + kind: 'id', + text: 'hash', + loc: { start: 11724, end: 11728 } + }, + loc: { start: 11716, end: 11728 } + }, + right: { + kind: 'null', + loc: { start: 11732, end: 11736 } + }, + loc: { start: 11716, end: 11736 } + }, + trueStatements: [ + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 11755, end: 11759 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 11760, end: 11769 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 11770, end: 11771 } + }, + { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 11773, end: 11774 } + } + ], + loc: { start: 11755, end: 11775 } + }, + loc: { start: 11748, end: 11776 } + } + ], + falseStatements: undefined, + loc: { start: 11712, end: 11790 } + }, + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 11803, end: 11807 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 11817, end: 11826 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '2', + value: 1024n, + loc: { start: 11827, end: 11842 } + }, + { + kind: 'op_binary', + op: '+', + left: { + kind: 'number', + base: '10', + value: 3n, + loc: { start: 11844, end: 11845 } + }, + right: { + kind: 'number', + base: '10', + value: 8n, + loc: { start: 11848, end: 11849 } + }, + loc: { start: 11844, end: 11849 } + } + ], + loc: { start: 11803, end: 11850 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 11860, end: 11869 } + }, + typeArgs: [], + args: [ + { + kind: 'op_unary', + op: '!!', + operand: { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'address', + loc: { start: 11870, end: 11877 } + }, + field: { + kind: 'id', + text: 'hash', + loc: { start: 11878, end: 11882 } + }, + loc: { start: 11870, end: 11882 } + }, + loc: { start: 11870, end: 11884 } + }, + { + kind: 'number', + base: '10', + value: 256n, + loc: { start: 11886, end: 11889 } + } + ], + loc: { start: 11803, end: 11890 } + }, + loc: { start: 11796, end: 11891 } + } + ] + }, + loc: { start: 11621, end: 11893 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 11661, end: 11668 } }, + loc: { start: 11661, end: 11668 } + } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'forceBasechain', + loc: { start: 12980, end: 12994 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'address', + loc: { start: 12995, end: 13002 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 13004, end: 13011 } + }, + typeArgs: [], + loc: { start: 13004, end: 13011 } + }, + loc: { start: 12995, end: 13011 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'REWRITESTDADDR DROP 138 THROWIF' ] + }, + loc: { start: 12972, end: 13048 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'forceWorkchain', + loc: { start: 14243, end: 14257 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'address', + loc: { start: 14258, end: 14265 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 14267, end: 14274 } + }, + typeArgs: [], + loc: { start: 14267, end: 14274 } + }, + loc: { start: 14258, end: 14274 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'workchain', + loc: { start: 14276, end: 14285 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14287, end: 14290 } + }, + loc: { start: 14287, end: 14290 } + }, + loc: { start: 14276, end: 14290 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'errorCode', + loc: { start: 14292, end: 14301 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14303, end: 14306 } + }, + loc: { start: 14303, end: 14306 } + }, + loc: { start: 14292, end: 14306 } + } + ], + body: { + kind: 'asm_body', + shuffle: { + args: [ + { + kind: 'id', + text: 'errorCode', + loc: { start: 14210, end: 14219 } + }, + { + kind: 'id', + text: 'workchain', + loc: { start: 14220, end: 14229 } + }, + { + kind: 'id', + text: 'address', + loc: { start: 14230, end: 14237 } + } + ], + ret: [] + }, + instructions: [ 'REWRITESTDADDR\n DROP\n CMP\n THROWANYIF' ] + }, + loc: { start: 14206, end: 14362 } + } + ] + }, + 'forceWorkchain' => { + kind: 'tact', + path: 'std/internal/address.tact', + code: '/// Extension function for the `Slice` type. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Casts the `Slice` to an `Address` in a given `chain` ID and returns it. The inverse of `Address.asSlice()` and a safe but more gas-expensive version of `Slice.asAddressUnsafe()`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + "/// let a: Address = myAddress(); // let's assume we're in a basechain\n" + + '/// let a2: Address = a.asSlice().asAddress(0); // so the chain ID is 0\n' + + '///\n' + + '/// a == a2; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 136: [Invalid standard address] — Thrown when the given `Slice` contains an invalid\n' + + '/// tag prefix (not `0b100`) or an invalid account ID length (not 256 bits).\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#sliceasaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#sliceasaddressunsafe\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#addressasslice\n' + + '///\n' + + '/// [Invalid standard address]: https://docs.tact-lang.org/book/exit-codes#136\n' + + '///\n' + + 'extends fun asAddress(self: Slice, chain: Int): Address {\n' + + ' // 11 bits for the prefix,\n' + + ' // 256 bits for the address itself\n' + + ' throwUnless(TactExitCodeInvalidStandardAddress, self.bits() == 267);\n' + + '\n' + + ' if (chain == -1) {\n' + + ' // 1279 = 0b100_1111_1111,\n' + + ' // i.e. internal address prefix and chain ID -1\n' + + ' throwUnless(TactExitCodeInvalidStandardAddress, self.preloadUint(11) == 1279);\n' + + ' } else {\n' + + ' // Only check the correct internal address prefix,\n' + + ' // but do not verify the chain ID\n' + + ' throwUnless(TactExitCodeInvalidStandardAddress, self.preloadUint(3) == 4);\n' + + ' }\n' + + '\n' + + ' // Proceed with the cast\n' + + ' return self.asAddressUnsafe();\n' + + '}\n' + + '\n' + + '/// Extension function for the `Slice` type. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Unsafely casts the `Slice` to an `Address` and returns it. The inverse of `Address.asSlice()`.\n' + + '///\n' + + '/// This function does **not** perform any checks on the contents of the `Slice`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let a: Address = myAddress();\n' + + '/// let a2: Address = a.asSlice().asAddressUnsafe();\n' + + '///\n' + + '/// a == a2; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// Use it only if you want to optimize the code for gas and can guarantee in advance that the `Slice` contains the data of an `Address`.\n' + + '///\n' + + '/// Otherwise, use a safer but more gas-expensive `Slice.asAddress()` function.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#sliceasaddressunsafe\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#sliceasaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#addressasslice\n' + + '///\n' + + 'asm extends fun asAddressUnsafe(self: Slice): Address {}\n' + + '\n' + + '/// Extension function for the `Address` type.\n' + + '///\n' + + '/// Casts `self` back to the underlying `Slice` and returns it. The inverse of `Slice.asAddressUnsafe()`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let a: Address = myAddress();\n' + + '/// let fizz: Slice = beginCell().storeAddress(a).asSlice();\n' + + '/// let buzz: Slice = a.asSlice(); // cheap, unlike the previous statement\n' + + '///\n' + + '/// fizz == buzz; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#addressasslice\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#sliceasaddressunsafe\n' + + '///\n' + + 'asm extends fun asSlice(self: Address): Slice {}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Creates a new `Address` based on the `chain` ID and the SHA-256 encoded `hash` value (account ID).\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// Attempts to specify an uncommon `chain` ID (not -1 or 0) that can be detected in compile-time will result in a compilation error.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let oldTonFoundationAddr: Address =\n' + + '/// newAddress(0, 0x83dfd552e63729b472fcbcc8c45ebcc6691702558b68ec7527e1ba403a0f31a8);\n' + + '/// // ↑ ↑\n' + + "/// // | sha-256 hash of contract's init package (StateInit)\n" + + '/// // chain id: 0 is a workchain, -1 is a masterchain\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-addresses#newaddress\n' + + '///\n' + + 'inline fun newAddress(chain: Int, hash: Int): Address {\n' + + ' return beginCell()\n' + + ' .storeUint(0b10_0, 3)\n' + + ' .storeInt(chain, 8)\n' + + ' .storeUint(hash, 256)\n' + + ' .endCell()\n' + + ' .asSlice()\n' + + ' .asAddressUnsafe();\n' + + '}\n' + + '\n' + + '/// Struct representing the standard address on TON Blockchain with signed 8-bit `workchain` ID and an unsigned 256-bit `address` in the specified `workchain`. Available since Tact 1.5.0.\n' + + '///\n' + + '/// At the moment, only `workchain` IDs used on TON are 0 of the basechain and -1 of the masterchain.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#parsestdaddress\n' + + '/// * https://github.com/ton-blockchain/ton/blob/master/crypto/block/block.tlb#L105-L106\n' + + '///\n' + + 'struct StdAddress {\n' + + ' workchain: Int as int8;\n' + + ' address: Int as uint256;\n' + + '}\n' + + '\n' + + '/// Struct representing the address of variable length with signed 32-bit `workchain` ID and a `Slice` containing unsigned `address` in the specified `workchain`. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Variable-length addresses are intended for future extensions, and while validators must be ready to accept them in inbound messages, the standard (non-variable) addresses are used whenever possible.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#parsevaraddress\n' + + '/// * https://github.com/ton-blockchain/ton/blob/master/crypto/block/block.tlb#L107-L108\n' + + '///\n' + + 'struct VarAddress {\n' + + ' workchain: Int as int32;\n' + + ' address: Slice;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Converts a `slice` containing an address into the `StdAddress` Struct and returns it.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let addr = address("EQDtFpEwcFAEcRe5mLVh2N6C0x-_hJEM7W61_JLnSF74p4q2");\n' + + '/// let parsedAddr = parseStdAddress(addr.asSlice());\n' + + '///\n' + + '/// parsedAddr.workchain; // 0\n' + + '/// parsedAddr.address; // 107...287\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-addresses#parsestdaddress\n' + + '///\n' + + 'asm fun parseStdAddress(slice: Slice): StdAddress { REWRITESTDADDR }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Converts a `slice` containing an address of variable length into the `VarAddress` Struct and returns it.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let varAddrSlice = beginCell()\n' + + '/// .storeUint(6, 3) // to recognize the following as a VarAddress\n' + + '/// .storeUint(123, 9) // make address occupy 123 bits\n' + + '/// .storeUint(234, 32) // specify workchain ID of 234\n' + + '/// .storeUint(345, 123) // specify address of 345\n' + + '/// .asSlice();\n' + + '/// let parsedVarAddr = parseVarAddress(varAddrSlice);\n' + + '///\n' + + '/// parsedVarAddr.workchain; // 234\n' + + '/// parsedVarAddr.address; // CS{Cell{002...2b3} bits: 44..167; refs: 0..0}\n' + + '/// parsedVarAddr.address.loadUint(123); // 345\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-addresses#parsevaraddress\n' + + '///\n' + + 'asm fun parseVarAddress(slice: Slice): VarAddress { REWRITEVARADDR }\n' + + '\n' + + '/// Extension mutation function for the `Slice` type.\n' + + '///\n' + + '/// Loads and returns an `Address` from the `Slice`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let s: Slice = beginCell().storeAddress(myAddress()).asSlice();\n' + + '/// let fizz: Address = s.loadAddress();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + "/// * 8: [Cell overflow] — Thrown when attempting to load an `Address` when `Slice` doesn't contain it.\n" + + '/// * 9: [Cell underflow] — Thrown when attempting to load more data than `Slice` contains.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#sliceloadaddress\n' + + '///\n' + + '/// [Cell overflow]: https://docs.tact-lang.org/book/exit-codes#8\n' + + '/// [Cell underflow]: https://docs.tact-lang.org/book/exit-codes#9\n' + + '///\n' + + 'asm(-> 1 0) extends mutates fun loadAddress(self: Slice): Address { LDMSGADDR }\n' + + '\n' + + '/// Extension mutation function for the `Slice` type. Available since Tact 1.6.2.\n' + + '///\n' + + '/// Skips an `Address` from the `Slice`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let s1: Slice = beginCell()\n' + + '/// .storeAddress(myAddress())\n' + + '/// .storeUint(42, 32)\n' + + '/// .asSlice();\n' + + '///\n' + + '/// s1.skipAddress();\n' + + '/// let fizz: Int = s1.loadUint(32); // 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + "/// * 8: [Cell overflow] — Thrown when attempting to skip an `Address` when `Slice` doesn't contain it.\n" + + '/// * 9: [Cell underflow] — Thrown when attempting to skip more data than `Slice` contains.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#sliceskipaddress\n' + + '///\n' + + '/// [Cell overflow]: https://docs.tact-lang.org/book/exit-codes#8\n' + + '/// [Cell underflow]: https://docs.tact-lang.org/book/exit-codes#9\n' + + '///\n' + + 'asm extends mutates fun skipAddress(self: Slice) { LDMSGADDR NIP }\n' + + '\n' + + '/// Extension function for the `Builder` type.\n' + + '///\n' + + '/// Stores the `address` in the copy of the `Builder`. Returns that copy.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b.storeAddress(myAddress());\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 8: [Cell overflow] — Thrown when attempting to store an `address` into the `Builder` when it cannot fit it.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#builderstoreaddress\n' + + '///\n' + + '/// [Cell overflow]: https://docs.tact-lang.org/book/exit-codes#8\n' + + '///\n' + + 'asm extends fun storeAddress(self: Builder, address: Address): Builder { STSLICER }\n' + + '\n' + + '/// Struct representing a basechain address. Available since Tact 1.6.0.\n' + + '///\n' + + '/// A basechain address (workchain 0) can be either empty (null hash) or contain a 256-bit hash value.\n' + + '///\n' + + 'struct BasechainAddress {\n' + + ' hash: Int?;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Creates and returns an empty basechain address with a null hash.\n' + + '///\n' + + '/// When serialized, an empty basechain address is represented as `addr_none`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let emptyAddr: BasechainAddress = emptyBasechainAddress();\n' + + '/// emptyAddr.hash == null; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + 'inline fun emptyBasechainAddress(): BasechainAddress {\n' + + ' return BasechainAddress { hash: null };\n' + + '}\n' + + '\n' + + '/// Global f'... 4363 more characters, + imports: [], + items: [ + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'asAddress', + loc: { start: 998, end: 1007 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 1034, end: 1041 } + }, + typeArgs: [], + loc: { start: 1034, end: 1041 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'chain', + loc: { start: 1021, end: 1026 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1028, end: 1031 } + }, + loc: { start: 1028, end: 1031 } + }, + loc: { start: 1021, end: 1031 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throwUnless', + loc: { start: 1118, end: 1129 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'TactExitCodeInvalidStandardAddress', + loc: { start: 1130, end: 1164 } + }, + { + kind: 'op_binary', + op: '==', + left: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 1166, end: 1170 } + }, + method: { + kind: 'id', + text: 'bits', + loc: { start: 1171, end: 1175 } + }, + typeArgs: [], + args: [], + loc: { start: 1166, end: 1177 } + }, + right: { + kind: 'number', + base: '10', + value: 267n, + loc: { start: 1181, end: 1184 } + }, + loc: { start: 1166, end: 1184 } + } + ], + loc: { start: 1118, end: 1185 } + }, + loc: { start: 1118, end: 1186 } + }, + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'chain', + loc: { start: 1196, end: 1201 } + }, + right: { + kind: 'op_unary', + op: '-', + operand: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1206, end: 1207 } + }, + loc: { start: 1205, end: 1207 } + }, + loc: { start: 1196, end: 1207 } + }, + trueStatements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throwUnless', + loc: { start: 1310, end: 1321 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'TactExitCodeInvalidStandardAddress', + loc: { start: 1322, end: 1356 } + }, + { + kind: 'op_binary', + op: '==', + left: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 1358, end: 1362 } + }, + method: { + kind: 'id', + text: 'preloadUint', + loc: { start: 1363, end: 1374 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 11n, + loc: { start: 1375, end: 1377 } + } + ], + loc: { start: 1358, end: 1378 } + }, + right: { + kind: 'number', + base: '10', + value: 1279n, + loc: { start: 1382, end: 1386 } + }, + loc: { start: 1358, end: 1386 } + } + ], + loc: { start: 1310, end: 1387 } + }, + loc: { start: 1310, end: 1388 } + } + ], + falseStatements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throwUnless', + loc: { start: 1511, end: 1522 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'TactExitCodeInvalidStandardAddress', + loc: { start: 1523, end: 1557 } + }, + { + kind: 'op_binary', + op: '==', + left: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 1559, end: 1563 } + }, + method: { + kind: 'id', + text: 'preloadUint', + loc: { start: 1564, end: 1575 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 3n, + loc: { start: 1576, end: 1577 } + } + ], + loc: { start: 1559, end: 1578 } + }, + right: { + kind: 'number', + base: '10', + value: 4n, + loc: { start: 1582, end: 1583 } + }, + loc: { start: 1559, end: 1583 } + } + ], + loc: { start: 1511, end: 1584 } + }, + loc: { start: 1511, end: 1585 } + } + ], + loc: { start: 1192, end: 1591 } + }, + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 1633, end: 1637 } + }, + method: { + kind: 'id', + text: 'asAddressUnsafe', + loc: { start: 1638, end: 1653 } + }, + typeArgs: [], + args: [], + loc: { start: 1633, end: 1655 } + }, + loc: { start: 1626, end: 1656 } + } + ] + }, + loc: { start: 986, end: 1658 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 1014, end: 1019 } }, + loc: { start: 1014, end: 1019 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'asAddressUnsafe', + loc: { start: 2554, end: 2569 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 2584, end: 2591 } + }, + typeArgs: [], + loc: { start: 2584, end: 2591 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ '' ] + }, + loc: { start: 2538, end: 2594 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 2576, end: 2581 } }, + loc: { start: 2576, end: 2581 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'asSlice', + loc: { start: 3188, end: 3195 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 3212, end: 3217 } }, + loc: { start: 3212, end: 3217 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ '' ] + }, + loc: { start: 3172, end: 3220 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3202, end: 3209 } + }, + typeArgs: [], + loc: { start: 3202, end: 3209 } + } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'newAddress', + loc: { start: 4029, end: 4039 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 4064, end: 4071 } + }, + typeArgs: [], + loc: { start: 4064, end: 4071 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'chain', + loc: { start: 4040, end: 4045 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4047, end: 4050 } + }, + loc: { start: 4047, end: 4050 } + }, + loc: { start: 4040, end: 4050 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'hash', + loc: { start: 4052, end: 4056 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4058, end: 4061 } + }, + loc: { start: 4058, end: 4061 } + }, + loc: { start: 4052, end: 4061 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'static_call', + function: { + kind: 'id', + text: 'beginCell', + loc: { start: 4085, end: 4094 } + }, + typeArgs: [], + args: [], + loc: { start: 4085, end: 4096 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 4106, end: 4115 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '2', + value: 4n, + loc: { start: 4116, end: 4122 } + }, + { + kind: 'number', + base: '10', + value: 3n, + loc: { start: 4124, end: 4125 } + } + ], + loc: { start: 4085, end: 4126 } + }, + method: { + kind: 'id', + text: 'storeInt', + loc: { start: 4136, end: 4144 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'chain', + loc: { start: 4145, end: 4150 } + }, + { + kind: 'number', + base: '10', + value: 8n, + loc: { start: 4152, end: 4153 } + } + ], + loc: { start: 4085, end: 4154 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 4164, end: 4173 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'hash', + loc: { start: 4174, end: 4178 } + }, + { + kind: 'number', + base: '10', + value: 256n, + loc: { start: 4180, end: 4183 } + } + ], + loc: { start: 4085, end: 4184 } + }, + method: { + kind: 'id', + text: 'endCell', + loc: { start: 4194, end: 4201 } + }, + typeArgs: [], + args: [], + loc: { start: 4085, end: 4203 } + }, + method: { + kind: 'id', + text: 'asSlice', + loc: { start: 4213, end: 4220 } + }, + typeArgs: [], + args: [], + loc: { start: 4085, end: 4222 } + }, + method: { + kind: 'id', + text: 'asAddressUnsafe', + loc: { start: 4232, end: 4247 } + }, + typeArgs: [], + args: [], + loc: { start: 4085, end: 4249 } + }, + loc: { start: 4078, end: 4250 } + } + ] + }, + loc: { start: 4018, end: 4252 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'StdAddress', + loc: { start: 4729, end: 4739 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'workchain', + loc: { start: 4746, end: 4755 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 8, + loc: { start: 4757, end: 4768 } + }, + loc: { start: 4757, end: 4760 } + }, + initializer: undefined, + loc: { start: 4746, end: 4768 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'address', + loc: { start: 4774, end: 4781 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'unsigned', + width: 256, + loc: { start: 4783, end: 4797 } + }, + loc: { start: 4783, end: 4786 } + }, + initializer: undefined, + loc: { start: 4774, end: 4797 } + } + ], + loc: { start: 4722, end: 4800 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'VarAddress', + loc: { start: 5381, end: 5391 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'workchain', + loc: { start: 5398, end: 5407 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 32, + loc: { start: 5409, end: 5421 } + }, + loc: { start: 5409, end: 5412 } + }, + initializer: undefined, + loc: { start: 5398, end: 5421 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'address', + loc: { start: 5427, end: 5434 } + }, + type: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 5436, end: 5441 } }, + loc: { start: 5436, end: 5441 } + }, + initializer: undefined, + loc: { start: 5427, end: 5441 } + } + ], + loc: { start: 5374, end: 5444 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'parseStdAddress', + loc: { start: 5946, end: 5961 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StdAddress', + loc: { start: 5977, end: 5987 } + }, + typeArgs: [], + loc: { start: 5977, end: 5987 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'slice', + loc: { start: 5962, end: 5967 } + }, + type: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 5969, end: 5974 } }, + loc: { start: 5969, end: 5974 } + }, + loc: { start: 5962, end: 5974 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'REWRITESTDADDR' ] + }, + loc: { start: 5938, end: 6006 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'parseVarAddress', + loc: { start: 6898, end: 6913 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'VarAddress', + loc: { start: 6929, end: 6939 } + }, + typeArgs: [], + loc: { start: 6929, end: 6939 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'slice', + loc: { start: 6914, end: 6919 } + }, + type: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 6921, end: 6926 } }, + loc: { start: 6921, end: 6926 } + }, + loc: { start: 6914, end: 6926 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'REWRITEVARADDR' ] + }, + loc: { start: 6890, end: 6958 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadAddress', + loc: { start: 7707, end: 7718 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 7733, end: 7740 } + }, + typeArgs: [], + loc: { start: 7733, end: 7740 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { + args: [], + ret: [ + { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 7682, end: 7683 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 7684, end: 7685 } + } + ] + }, + instructions: [ 'LDMSGADDR' ] + }, + loc: { start: 7675, end: 7754 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 7725, end: 7730 } }, + loc: { start: 7725, end: 7730 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'skipAddress', + loc: { start: 8601, end: 8612 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LDMSGADDR NIP' ] + }, + loc: { start: 8577, end: 8643 } + } + }, + selfType: { + kind: 'TySlice', + format: { kind: 'SFDefault', loc: { start: 8619, end: 8624 } }, + loc: { start: 8619, end: 8624 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeAddress', + loc: { start: 9222, end: 9234 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 9269, end: 9276 } }, + loc: { start: 9269, end: 9276 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'address', + loc: { start: 9250, end: 9257 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 9259, end: 9266 } + }, + typeArgs: [], + loc: { start: 9259, end: 9266 } + }, + loc: { start: 9250, end: 9266 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'STSLICER' ] + }, + loc: { start: 9206, end: 9289 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 9241, end: 9248 } }, + loc: { start: 9241, end: 9248 } + } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 9482, end: 9498 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'hash', + loc: { start: 9505, end: 9509 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 9514, end: 9515 } + }, + typeArgs: [ + { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9511, end: 9514 } + }, + loc: { start: 9511, end: 9514 } + } + ], + loc: { start: 9514, end: 9515 } + }, + initializer: undefined, + loc: { start: 9505, end: 9515 } + } + ], + loc: { start: 9475, end: 9518 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'emptyBasechainAddress', + loc: { start: 9897, end: 9918 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 9922, end: 9938 } + }, + typeArgs: [], + loc: { start: 9922, end: 9938 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'struct_instance', + type: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 9952, end: 9968 } + }, + typeArgs: [], + args: [ + { + kind: 'struct_field_initializer', + field: { + kind: 'id', + text: 'hash', + loc: { start: 9971, end: 9975 } + }, + initializer: { kind: 'null', loc: { start: 9977, end: 9981 } }, + loc: { start: 9971, end: 9981 } + } + ], + loc: { start: 9952, end: 9983 } + }, + loc: { start: 9945, end: 9984 } + } + ] + }, + loc: { start: 9886, end: 9986 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'newBasechainAddress', + loc: { start: 10311, end: 10330 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 10343, end: 10359 } + }, + typeArgs: [], + loc: { start: 10343, end: 10359 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'hash', + loc: { start: 10331, end: 10335 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10337, end: 10340 } + }, + loc: { start: 10337, end: 10340 } + }, + loc: { start: 10331, end: 10340 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'struct_instance', + type: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 10373, end: 10389 } + }, + typeArgs: [], + args: [ + { + kind: 'struct_field_initializer', + field: { + kind: 'id', + text: 'hash', + loc: { start: 10392, end: 10396 } + }, + initializer: { + kind: 'var', + name: 'hash', + loc: { start: 10392, end: 10396 } + }, + loc: { start: 10392, end: 10396 } + } + ], + loc: { start: 10373, end: 10398 } + }, + loc: { start: 10366, end: 10399 } + } + ] + }, + loc: { start: 10300, end: 10401 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'contractBasechainAddress', + loc: { start: 10865, end: 10889 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 10905, end: 10921 } + }, + typeArgs: [], + loc: { start: 10905, end: 10921 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 's', + loc: { start: 10890, end: 10891 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 10893, end: 10902 } + }, + typeArgs: [], + loc: { start: 10893, end: 10902 } + }, + loc: { start: 10890, end: 10902 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'hash', + loc: { start: 10932, end: 10936 } + }, + type: undefined, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractHash', + loc: { start: 10939, end: 10951 } + }, + typeArgs: [], + args: [ + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 10952, end: 10953 } + }, + field: { + kind: 'id', + text: 'code', + loc: { start: 10954, end: 10958 } + }, + loc: { start: 10952, end: 10958 } + }, + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 10960, end: 10961 } + }, + field: { + kind: 'id', + text: 'data', + loc: { start: 10962, end: 10966 } + }, + loc: { start: 10960, end: 10966 } + } + ], + loc: { start: 10939, end: 10967 } + }, + loc: { start: 10928, end: 10968 } + }, + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'newBasechainAddress', + loc: { start: 10980, end: 10999 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'hash', + loc: { start: 11000, end: 11004 } + } + ], + loc: { start: 10980, end: 11005 } + }, + loc: { start: 10973, end: 11006 } + } + ] + }, + loc: { start: 10854, end: 11008 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeBasechainAddress', + loc: { start: 11633, end: 11654 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 11698, end: 11705 } + }, + loc: { start: 11698, end: 11705 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'address', + loc: { start: 11670, end: 11677 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 11679, end: 11695 } + }, + typeArgs: [], + loc: { start: 11679, end: 11695 } + }, + loc: { start: 11670, end: 11695 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'address', + loc: { start: 11716, end: 11723 } + }, + field: { + kind: 'id', + text: 'hash', + loc: { start: 11724, end: 11728 } + }, + loc: { start: 11716, end: 11728 } + }, + right: { + kind: 'null', + loc: { start: 11732, end: 11736 } + }, + loc: { start: 11716, end: 11736 } + }, + trueStatements: [ + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 11755, end: 11759 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 11760, end: 11769 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 11770, end: 11771 } + }, + { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 11773, end: 11774 } + } + ], + loc: { start: 11755, end: 11775 } + }, + loc: { start: 11748, end: 11776 } + } + ], + falseStatements: undefined, + loc: { start: 11712, end: 11790 } + }, + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 11803, end: 11807 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 11817, end: 11826 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '2', + value: 1024n, + loc: { start: 11827, end: 11842 } + }, + { + kind: 'op_binary', + op: '+', + left: { + kind: 'number', + base: '10', + value: 3n, + loc: { start: 11844, end: 11845 } + }, + right: { + kind: 'number', + base: '10', + value: 8n, + loc: { start: 11848, end: 11849 } + }, + loc: { start: 11844, end: 11849 } + } + ], + loc: { start: 11803, end: 11850 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 11860, end: 11869 } + }, + typeArgs: [], + args: [ + { + kind: 'op_unary', + op: '!!', + operand: { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'address', + loc: { start: 11870, end: 11877 } + }, + field: { + kind: 'id', + text: 'hash', + loc: { start: 11878, end: 11882 } + }, + loc: { start: 11870, end: 11882 } + }, + loc: { start: 11870, end: 11884 } + }, + { + kind: 'number', + base: '10', + value: 256n, + loc: { start: 11886, end: 11889 } + } + ], + loc: { start: 11803, end: 11890 } + }, + loc: { start: 11796, end: 11891 } + } + ] + }, + loc: { start: 11621, end: 11893 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { kind: 'SFDefault', loc: { start: 11661, end: 11668 } }, + loc: { start: 11661, end: 11668 } + } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'forceBasechain', + loc: { start: 12980, end: 12994 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'address', + loc: { start: 12995, end: 13002 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 13004, end: 13011 } + }, + typeArgs: [], + loc: { start: 13004, end: 13011 } + }, + loc: { start: 12995, end: 13011 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'REWRITESTDADDR DROP 138 THROWIF' ] + }, + loc: { start: 12972, end: 13048 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'forceWorkchain', + loc: { start: 14243, end: 14257 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'address', + loc: { start: 14258, end: 14265 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 14267, end: 14274 } + }, + typeArgs: [], + loc: { start: 14267, end: 14274 } + }, + loc: { start: 14258, end: 14274 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'workchain', + loc: { start: 14276, end: 14285 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14287, end: 14290 } + }, + loc: { start: 14287, end: 14290 } + }, + loc: { start: 14276, end: 14290 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'errorCode', + loc: { start: 14292, end: 14301 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14303, end: 14306 } + }, + loc: { start: 14303, end: 14306 } + }, + loc: { start: 14292, end: 14306 } + } + ], + body: { + kind: 'asm_body', + shuffle: { + args: [ + { + kind: 'id', + text: 'errorCode', + loc: { start: 14210, end: 14219 } + }, + { + kind: 'id', + text: 'workchain', + loc: { start: 14220, end: 14229 } + }, + { + kind: 'id', + text: 'address', + loc: { start: 14230, end: 14237 } + } + ], + ret: [] + }, + instructions: [ 'REWRITESTDADDR\n DROP\n CMP\n THROWANYIF' ] + }, + loc: { start: 14206, end: 14362 } + } + ] + }, + 'now' => { + kind: 'tact', + path: 'std/internal/time.tact', + code: '/// Global function.\n' + + '///\n' + + '/// Returns the current Unix time.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let timeOffset: Int = now() + 1000; // thousand seconds from now()\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#now\n' + + '///\n' + + 'asm fun now(): Int { NOW }\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Returns the `Int` value of the logical time of the current transaction.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let lt: Int = curLt();\n' + + '/// nativeRandomize(lt); // equivalent to calling nativeRandomizeLt()\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-contextstate#curlt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomize\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomizelt\n' + + '///\n' + + 'asm fun curLt(): Int { LTIME }\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Returns the `Int` value of the starting logical time of the current block.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let time: Int = blockLt();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#blocklt\n' + + '///\n' + + 'asm fun blockLt(): Int { BLOCKLT }\n', + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'now', loc: { start: 263, end: 266 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 270, end: 273 } + }, + loc: { start: 270, end: 273 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'NOW' ] + }, + loc: { start: 255, end: 281 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'curLt', loc: { start: 785, end: 790 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 794, end: 797 } + }, + loc: { start: 794, end: 797 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LTIME' ] + }, + loc: { start: 777, end: 807 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'blockLt', + loc: { start: 1108, end: 1115 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1119, end: 1122 } + }, + loc: { start: 1119, end: 1122 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'BLOCKLT' ] + }, + loc: { start: 1100, end: 1134 } + } + ] + }, + 'curLt' => { + kind: 'tact', + path: 'std/internal/time.tact', + code: '/// Global function.\n' + + '///\n' + + '/// Returns the current Unix time.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let timeOffset: Int = now() + 1000; // thousand seconds from now()\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#now\n' + + '///\n' + + 'asm fun now(): Int { NOW }\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Returns the `Int` value of the logical time of the current transaction.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let lt: Int = curLt();\n' + + '/// nativeRandomize(lt); // equivalent to calling nativeRandomizeLt()\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-contextstate#curlt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomize\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomizelt\n' + + '///\n' + + 'asm fun curLt(): Int { LTIME }\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Returns the `Int` value of the starting logical time of the current block.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let time: Int = blockLt();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#blocklt\n' + + '///\n' + + 'asm fun blockLt(): Int { BLOCKLT }\n', + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'now', loc: { start: 263, end: 266 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 270, end: 273 } + }, + loc: { start: 270, end: 273 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'NOW' ] + }, + loc: { start: 255, end: 281 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'curLt', loc: { start: 785, end: 790 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 794, end: 797 } + }, + loc: { start: 794, end: 797 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LTIME' ] + }, + loc: { start: 777, end: 807 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'blockLt', + loc: { start: 1108, end: 1115 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1119, end: 1122 } + }, + loc: { start: 1119, end: 1122 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'BLOCKLT' ] + }, + loc: { start: 1100, end: 1134 } + } + ] + }, + 'blockLt' => { + kind: 'tact', + path: 'std/internal/time.tact', + code: '/// Global function.\n' + + '///\n' + + '/// Returns the current Unix time.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let timeOffset: Int = now() + 1000; // thousand seconds from now()\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#now\n' + + '///\n' + + 'asm fun now(): Int { NOW }\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Returns the `Int` value of the logical time of the current transaction.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let lt: Int = curLt();\n' + + '/// nativeRandomize(lt); // equivalent to calling nativeRandomizeLt()\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-contextstate#curlt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomize\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomizelt\n' + + '///\n' + + 'asm fun curLt(): Int { LTIME }\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Returns the `Int` value of the starting logical time of the current block.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let time: Int = blockLt();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#blocklt\n' + + '///\n' + + 'asm fun blockLt(): Int { BLOCKLT }\n', + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'now', loc: { start: 263, end: 266 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 270, end: 273 } + }, + loc: { start: 270, end: 273 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'NOW' ] + }, + loc: { start: 255, end: 281 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'curLt', loc: { start: 785, end: 790 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 794, end: 797 } + }, + loc: { start: 794, end: 797 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LTIME' ] + }, + loc: { start: 777, end: 807 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'blockLt', + loc: { start: 1108, end: 1115 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1119, end: 1122 } + }, + loc: { start: 1119, end: 1122 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'BLOCKLT' ] + }, + loc: { start: 1100, end: 1134 } + } + ] + }, + 'f' => { + kind: 'tact', + path: '/home/user/Documents/work/tact5/src/next/example/scope1-b.tact', + code: 'fun f(): Int { return 1; }', + imports: [ + { + kind: 'tact', + source: { + kind: 'tact', + path: 'std/stdlib.tact', + code: 'import "./internal/exit-codes";\n' + + 'import "./internal/primitives";\n' + + 'import "./internal/cells";\n' + + 'import "./internal/crypto";\n' + + 'import "./internal/text";\n' + + 'import "./internal/math";\n' + + 'import "./internal/contract";\n' + + 'import "./internal/debug";\n' + + 'import "./internal/context";\n' + + 'import "./internal/reserve";\n' + + 'import "./internal/send";\n' + + 'import "./internal/config";\n' + + 'import "./internal/base";\n' + + 'import "./internal/address";\n' + + 'import "./internal/time";\n', + imports: [ + { + kind: 'tact', + source: { + kind: 'tact', + path: 'std/internal/exit-codes.tact', + code: '/// Configurable since Tact 1.6.\n' + + '///\n' + + '/// Thrown when a null reference exception occurs during the compute phase.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#128\n' + + '///\n' + + 'const TactExitCodeNullReferenceException: Int = 128;\n' + + '\n' + + '/// Thrown when there is a failed deserialization attempt:\n' + + '/// a certain opcode prefix was expected, but a different one was parsed.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#129\n' + + '///\n' + + 'const TactExitCodeInvalidSerializationPrefix: Int = 129;\n' + + '\n' + + '/// Thrown when there is no receiver for the opcode of the received message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#130\n' + + '///\n' + + 'const TactExitCodeInvalidIncomingMessage: Int = 130;\n' + + '\n' + + '/// Constraints error. Reserved, but never thrown.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#131\n' + + '///\n' + + 'const TactExitCodeConstraintsError: Int = 131;\n' + + '\n' + + '/// Thrown when the sender is not the owner of the contract inheriting\n' + + '/// the `Ownable` trait and there has been a mismatch of the `self.owner`\n' + + "/// and the sender's address.\n" + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#132\n' + + '///\n' + + 'const TactExitCodeAccessDenied: Int = 132;\n' + + '\n' + + '/// Thrown when a message has been sent to a contract inheriting the `Stoppable`\n' + + '/// trait and has the `self.stopped` flag set to `true`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#133\n' + + '///\n' + + 'const TactExitCodeContractStopped: Int = 133;\n' + + '\n' + + '/// Thrown when an invalid or unexpected argument is passed to a function or method.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#134\n' + + '///\n' + + 'const TactExitCodeInvalidArgument: Int = 134;\n' + + '\n' + + "/// Thrown when a contract's code is missing.\n" + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#135\n' + + '///\n' + + 'const TactExitCodeContractCodeNotFound: Int = 135;\n' + + '\n' + + '/// Thrown when an address does not conform to the expected standard format.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#136\n' + + '///\n' + + 'const TactExitCodeInvalidStandardAddress: Int = 136;\n' + + '\n' + + '/// Available since Tact 1.6.3.\n' + + '///\n' + + '/// Thrown when the address does not belong to a basechain (chain ID 0).\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#138\n' + + '///\n' + + 'const TactExitCodeNotBasechainAddress: Int = 138;\n', + imports: [], + items: [ + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeNullReferenceException', + loc: { start: 183, end: 217 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 219, end: 222 } + }, + loc: { start: 219, end: 222 } + }, + initializer: { + kind: 'number', + base: '10', + value: 128n, + loc: { start: 225, end: 228 } + } + }, + loc: { start: 177, end: 229 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeInvalidSerializationPrefix', + loc: { start: 434, end: 472 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 474, end: 477 } + }, + loc: { start: 474, end: 477 } + }, + initializer: { + kind: 'number', + base: '10', + value: 129n, + loc: { start: 480, end: 483 } + } + }, + loc: { start: 428, end: 484 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeInvalidIncomingMessage', + loc: { start: 633, end: 667 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 669, end: 672 } + }, + loc: { start: 669, end: 672 } + }, + initializer: { + kind: 'number', + base: '10', + value: 130n, + loc: { start: 675, end: 678 } + } + }, + loc: { start: 627, end: 679 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeConstraintsError', + loc: { start: 802, end: 830 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 832, end: 835 } + }, + loc: { start: 832, end: 835 } + }, + initializer: { + kind: 'number', + base: '10', + value: 131n, + loc: { start: 838, end: 841 } + } + }, + loc: { start: 796, end: 842 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeAccessDenied', + loc: { start: 1089, end: 1113 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1115, end: 1118 } + }, + loc: { start: 1115, end: 1118 } + }, + initializer: { + kind: 'number', + base: '10', + value: 132n, + loc: { start: 1121, end: 1124 } + } + }, + loc: { start: 1083, end: 1125 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeContractStopped', + loc: { start: 1335, end: 1362 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1364, end: 1367 } + }, + loc: { start: 1364, end: 1367 } + }, + initializer: { + kind: 'number', + base: '10', + value: 133n, + loc: { start: 1370, end: 1373 } + } + }, + loc: { start: 1329, end: 1374 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeInvalidArgument', + loc: { start: 1531, end: 1558 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1560, end: 1563 } + }, + loc: { start: 1560, end: 1563 } + }, + initializer: { + kind: 'number', + base: '10', + value: 134n, + loc: { start: 1566, end: 1569 } + } + }, + loc: { start: 1525, end: 1570 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeContractCodeNotFound', + loc: { start: 1688, end: 1720 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1722, end: 1725 } + }, + loc: { start: 1722, end: 1725 } + }, + initializer: { + kind: 'number', + base: '10', + value: 135n, + loc: { start: 1728, end: 1731 } + } + }, + loc: { start: 1682, end: 1732 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeInvalidStandardAddress', + loc: { start: 1881, end: 1915 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1917, end: 1920 } + }, + loc: { start: 1917, end: 1920 } + }, + initializer: { + kind: 'number', + base: '10', + value: 136n, + loc: { start: 1923, end: 1926 } + } + }, + loc: { start: 1875, end: 1927 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeNotBasechainAddress', + loc: { start: 2108, end: 2139 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2141, end: 2144 } + }, + loc: { start: 2141, end: 2144 } + }, + initializer: { + kind: 'number', + base: '10', + value: 138n, + loc: { start: 2147, end: 2150 } + } + }, + loc: { start: 2102, end: 2151 } + } + ] + }, + loc: { start: 0, end: 31 } + }, + { + kind: 'tact', + source: { + kind: 'tact', + path: 'std/internal/primitives.tact', + code: '/// `Int` is the primitive 257-bit signed integer type.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/integers\n' + + '///\n' + + 'primitive Int;\n' + + '\n' + + '/// `Bool` is the classical boolean type, which can hold only two values: `true` and `false`.\n' + + '/// It is convenient for boolean and logical operations, as well as for storing flags.\n' + + '///\n' + + '/// There are no implicit type conversions in Tact, so addition `+` of two boolean values is\n' + + '/// not possible. However, many comparison operators are available.\n' + + '///\n' + + '/// Persisting bools to state is very space-efficient, as they only occupy 1 bit.\n' + + '/// Storing 1000 bools in state [costs](https://ton.org/docs/develop/smart-contracts/fees#how-to-calculate-fees)\n' + + '/// about 0.00072 TON per year.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/types#booleans\n' + + '///\n' + + 'primitive Bool;\n' + + '\n' + + '/// `Builder` is a cell manipulation primitive used for cell creation instructions.\n' + + '/// They are immutable just like cells and allow constructing new cells from previously\n' + + '/// stored values and cells.\n' + + '///\n' + + '/// Unlike cells, values of type `Builder` appear only on the [TVM] stack and cannot\n' + + '/// be stored in persistent storage. This means, for example, that persistent storage\n' + + '/// fields with type `Builder` are actually stored as cells under the hood.\n' + + '///\n' + + '/// The `Builder` type represents partially composed cells, for which fast operations\n' + + '/// to append integers, other cells, references to other cells, and many other operations\n' + + '/// are defined.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/book/cells#builders\n' + + '/// * https://docs.tact-lang.org/ref/core-cells\n' + + '///\n' + + '/// [TVM]: https://docs.ton.org/learn/tvm-instructions/tvm-overview\n' + + 'primitive Builder;\n' + + '\n' + + '/// `Slice` is a cell manipulation primitive used for cell parsing instructions.\n' + + '/// Unlike cells, slices are mutable and allow extraction or loading of data previously\n' + + '/// stored in cells via serialization instructions. Also unlike cells, values of type `Slice`\n' + + '/// appear only on the [TVM] stack and cannot be stored in persistent storage.\n' + + '/// This means, for example, that persistent storage fields with type `Slice` would actually\n' + + '/// be stored as cells under the hood.\n' + + '///\n' + + '/// The `Slice` type represents either the remainder of a partially parsed cell or a value (subcell)\n' + + '/// residing inside such a cell, extracted from it by a parsing instruction.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/book/cells#slices\n' + + '/// * https://docs.tact-lang.org/ref/core-cells\n' + + '///\n' + + '/// [TVM]: https://docs.ton.org/learn/tvm-instructions/tvm-overview\n' + + 'primitive Slice;\n' + + '\n' + + '/// `Cell` is a primitive and a data structure, which ordinarily consists of up to 1023 continuously\n' + + '/// laid out bits and up to 4 references (refs) to other cells. Circular references are forbidden and\n' + + '/// cannot be created by means of [TVM], which means cells can be viewed as [quadtrees]\n' + + '/// or [directed acyclic graphs (DAGs)][dag] of themselves.\n' + + '///\n' + + '/// Contract code itself is represented by a tree of cells.\n' + + '///\n' + + '/// Cells and cell primitives are bit-oriented, not byte-oriented: [TVM] regards data kept in cells\n' + + '/// as sequences (strings or streams) of up to 1023 bits, not bytes. If necessary, contracts are\n' + + '/// free to use, for example, 21-bit integer fields serialized into [TVM] cells, thus using fewer\n' + + '/// persistent storage bytes to represent the same data.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/book/cells#cells\n' + + '/// * https://docs.tact-lang.org/ref/core-cells\n' + + '///\n' + + '/// [TVM]: https://docs.ton.org/learn/tvm-instructions/tvm-overview\n' + + '/// [quadtrees]: https://en.wikipedia.org/wiki/Quadtree\n' + + '/// [dag]: https://en.wikipedia.org/wiki/Directed_acyclic_graph\n' + + 'primitive Cell;\n' + + '\n' + + '/// `Address` is a primitive type that represents a [smart contract address] in TON Blockchain.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/types#primitive-types\n' + + '///\n' + + '/// [smart contract address]: https://docs.ton.org/learn/overviews/addresses#address-of-smart-contract\n' + + 'primitive Address;\n' + + '\n' + + '/// `String` is an immutable sequence of characters, which means that once a `String` is created,\n' + + '/// it cannot be changed. Strings are useful for storing text, so they can be converted to a `Cell`\n' + + '/// type to be used as message bodies.\n' + + '///\n' + + '/// To concatenate strings, use a `StringBuilder`.\n' + + '///\n' + + '/// To use `String` literals directly, see: [String literals].\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/book/types#primitive-types\n' + + '/// * https://docs.tact-lang.org/ref/core-strings\n' + + '///\n' + + '/// [String literals]: https://docs.tact-lang.org/book/expressions#string-literals\n' + + '///\n' + + 'primitive String;\n' + + '\n' + + '/// `StringBuilder` is a primitive used for efficient string concatenation.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/book/types#primitive-types\n' + + '/// * https://docs.tact-lang.org/ref/core-strings\n' + + '///\n' + + 'primitive StringBuilder;\n', + imports: [], + items: [] + }, + loc: { start: 32, end: 63 } + }, + { + kind: 'tact', + source: { + kind: 'tact', + path: 'std/internal/cells.tact', + code: '//\n' + + '// Builder\n' + + '//\n' + + '\n' + + '/// Creates a new empty `Builder`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#begincell\n' + + '///\n' + + 'asm fun beginCell(): Builder { NEWC }\n' + + '\n' + + '/// Extension function for the `Builder` type.\n' + + '///\n' + + '/// Stores a signed `bits`-bit `value` into the copy of the `Builder` for 0 ≤ `bits` ≤ 257.\n' + + '/// Returns that copy of the `Builder`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b.storeInt(42, 7);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to provide an insufficient or out-of-bounds `bits` number.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#builderstoreint\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + '@name(store_int) // special treatment in Func compiler, so not replaced with asm "STIX"\n' + + 'extends native storeInt(self: Builder, value: Int, bits: Int): Builder;\n' + + '\n' + + '/// Extension function for the `Builder` type.\n' + + '///\n' + + '/// Stores an unsigned `bits`-bit `value` into the copy of the `Builder` for 0 ≤ `bits` ≤ 256.\n' + + '/// Returns that copy of the `Builder`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b.storeUint(42, 6);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to store a negative `value` or provide an insufficient or out-of-bounds `bits` number.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#builderstoreuint\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + '@name(store_uint) // special treatment in Func compiler, so not replaced with asm "STUX"\n' + + 'extends native storeUint(self: Builder, value: Int, bits: Int): Builder;\n' + + '\n' + + '/// Extension function for the `Builder` type.\n' + + '///\n' + + '/// Stores a `Bool` `value` into the copy of the `Builder`.\n' + + '/// Writes 1 as a single bit if `value` is `true`, and writes 0 otherwise.\n' + + '/// Returns that copy of the `Builder`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b.storeBool(true); // writes 1\n' + + '/// let buzz: Builder = b.storeBool(false); // writes 0\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#builderstorebool\n' + + '///\n' + + 'asm(value self) extends fun storeBool(self: Builder, value: Bool): Builder { 1 STI }\n' + + '\n' + + '/// Extension function for the `Builder` type. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Alias to `Builder.storeBool()`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b.storeBit(true); // writes 1\n' + + '/// let buzz: Builder = b.storeBit(false); // writes 0\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#builderstorebit\n' + + '///\n' + + 'asm(value self) extends fun storeBit(self: Builder, value: Bool): Builder { 1 STI }\n' + + '\n' + + '/// Extension function for the `Builder` type.\n' + + '///\n' + + '/// Stores (serializes) an unsigned `Int` `value` in the range from 0 to 2^120 − 1 inclusive into the copy of the `Builder`. The serialization of `value` consists of a 4-bit unsigned big-endian integer `l`, which is the smallest integer `l` ≥ 0, such that `value` < 2^(8 * `l`), followed by an 8 * `l`-bit unsigned big-endian representation of `value`. Returns that copy of the `Builder`.\n' + + '///\n' + + '/// This is the most common way of storing nanoToncoins.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b.storeCoins(42);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to store an out-of-bounds `value`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#builderstorecoins\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm extends fun storeCoins(self: Builder, value: Int): Builder { STVARUINT16 }\n' + + '\n' + + '/// Extension function for the `Builder` type. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Alias to `Builder.storeCoins()`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b.storeVarUint16(42);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#builderstorevaruint16\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#builderstorecoins\n' + + '///\n' + + 'asm extends fun storeVarUint16(self: Builder, value: Int): Builder { STVARUINT16 }\n' + + '\n' + + '/// Extension function for the `Builder` type. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Similar to `Builder.storeCoins()`, but with a different `value` range: from -2^119 to 2^119 - 1 inclusive.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b.storeVarInt16(-42);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to store an out-of-bounds `value`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#builderstorevarint16\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm extends fun storeVarInt16(self: Builder, value: Int): Builder { STVARINT16 }\n' + + '\n' + + '/// Extension function for the `Builder` type. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Stores (serializes) an unsigned `Int` `value` in the range from 0 to 2^248 − 1 inclusive into the copy of the `Builder`. The serialization of `value` consists of a 5-bit unsigned big-endian integer `l`, which is the smallest integer `l` ≥ 0, such that `value` < 2^8 * `l`, followed by an 8 * `l`-bit unsigned big-endian representation of `value`. Returns that copy of the `Builder`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b.storeVarUint32(420000);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to store an out-of-bounds `value`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#builderstorevaruint32\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm extends fun storeVarUint32(self: Builder, value: Int): Builder { STVARUINT32 }\n' + + '\n' + + '/// Extension function for the `Builder` type. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Similar to `Builder.storeVarUint32()`, but with a different `value` range: from -2^247 to 2^247 - 1 inclusive.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b.storeVarInt32(-420000);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to store an out-of-bounds `value`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#builderstorevarint32\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm extends fun storeVarInt32(self: Builder, value: Int): Builder { STVARINT32 }\n' + + '\n' + + '/// Extension function for the `Builder` type.\n' + + '///\n' + + '/// Stores a reference `cell` into a copy of the `Builder`.\n' + + '/// Returns that copy of the `Builder`.\n' + + '///\n' + + '/// Note that a single `Cell` can contain up to 4 references.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b.storeRef(emptyCell());\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 8: [Cell overflow] — Thrown when attempting to store more than 4 references in a single `Cell`.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#builderstoreref\n' + + '///\n' + + '/// [Cell overflow]: https://docs.tact-lang.org/book/exit-codes#8\n' + + '///\n' + + 'asm(cell self) extends fun storeRef(self: Builder, cell: Cell): Builder { STREF }\n' + + '\n' + + '/// Extension function for the `Builder` type.\n' + + '///\n' + + '/// Stores a `slice` into a copy of the `Builder`.\n' + + '/// Returns that copy of the `Builder`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let s: Slice = emptyCell().asSlice();\n' + + '/// let fizz: Builder = b.storeSlice(s);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#builderstoreslice\n' + + '///\n' + + 'asm extends fun storeSlice(self: Builder, slice: Slice): Builder { STSLICER }\n' + + '\n' + + '/// Extension function for the `Builder` type. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Appends all data from the `other` builder to the copy of the `self` builder. Returns that copy.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example(op: Int, queryId: Int, payload: Builder) {\n' + + '/// let msgBody = beginCell().storeUint(op, 32).storeUint(queryId, 64);\n' + + '/// if (payload.bits() != 0) {\n' + + '/// msgBody = msgBody.storeBuilder(payload); // assignment is important here\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#builderstorebuilder\n' + + '///\n' + + 'asm extends fun storeBuilder(self: Builder, other: Builder): Builder { STBR }\n' + + '\n' + + '/// Extension function for the `Builder` type. Available since Tact 1.5.0.\n' + + '///\n' + + '/// If the `cell` is not `null`, stores 1 as a single bit and then reference `cell` into the copy of the `Builder`. Returns that copy.\n' + + '///\n' + + '/// If the `cell` is `null`, only stores 0 as a single bit into the copy of the `Builder`. Returns that copy.\n' + + '///\n' + + '/// Note that a single `Cell` can contain up to 4 references.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b\n' + + '/// .storeMaybeRef(emptyCell()) // 1, then empty cell\n' + + '/// .storeMaybeRef(null); // 0\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 8: [Cell overflow] — Thrown when attempting to store more than 4 references in a single `Cell`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#builderstoremayberef\n' + + '///\n' + + '/// [Cell overflow]: https://docs.tact-lang.org/book/exit-codes#8\n' + + '///\n' + + 'asm(cell self) extends fun storeMaybeRef(self: Builder, cell: Cell?): Builder { STOPTREF }\n' + + '\n' + + '/// Extension function for the `Builder` type.\n' + + '///\n' + + '/// Converts a `Builder` into an ordinary `Cell`.\n' + + '///\n' + + '/// NOTE: **Gas expensive!** This function uses 500 gas units or more.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let c: Cell = b.endCell();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/'... 40707 more characters, + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'beginCell', + loc: { start: 218, end: 227 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 231, end: 238 } + }, + loc: { start: 231, end: 238 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'NEWC' ] + }, + loc: { start: 210, end: 247 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeInt', + loc: { start: 984, end: 992 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 1032, end: 1039 } + }, + loc: { start: 1032, end: 1039 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'value', + loc: { start: 1008, end: 1013 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1015, end: 1018 } + }, + loc: { start: 1015, end: 1018 } + }, + loc: { start: 1008, end: 1018 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 1020, end: 1024 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1026, end: 1029 } + }, + loc: { start: 1026, end: 1029 } + }, + loc: { start: 1020, end: 1029 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'store_int', + loc: { start: 887, end: 896 } + } + }, + loc: { start: 881, end: 1040 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 999, end: 1006 } + }, + loc: { start: 999, end: 1006 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeUint', + loc: { start: 1817, end: 1826 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 1866, end: 1873 } + }, + loc: { start: 1866, end: 1873 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'value', + loc: { start: 1842, end: 1847 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1849, end: 1852 } + }, + loc: { start: 1849, end: 1852 } + }, + loc: { start: 1842, end: 1852 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 1854, end: 1858 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1860, end: 1863 } + }, + loc: { start: 1860, end: 1863 } + }, + loc: { start: 1854, end: 1863 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'store_uint', + loc: { start: 1719, end: 1729 } + } + }, + loc: { start: 1713, end: 1874 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 1833, end: 1840 } + }, + loc: { start: 1833, end: 1840 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeBool', + loc: { start: 2420, end: 2429 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 2459, end: 2466 } + }, + loc: { start: 2459, end: 2466 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'value', + loc: { start: 2445, end: 2450 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 2452, end: 2456 } + }, + typeArgs: [], + loc: { start: 2452, end: 2456 } + }, + loc: { start: 2445, end: 2456 } + } + ], + body: { + kind: 'asm_body', + shuffle: { + args: [ + { + kind: 'id', + text: 'value', + loc: { start: 2396, end: 2401 } + }, + { + kind: 'id', + text: 'self', + loc: { start: 2402, end: 2406 } + } + ], + ret: [] + }, + instructions: [ '1 STI' ] + }, + loc: { start: 2392, end: 2476 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 2436, end: 2443 } + }, + loc: { start: 2436, end: 2443 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeBit', + loc: { start: 2902, end: 2910 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 2940, end: 2947 } + }, + loc: { start: 2940, end: 2947 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'value', + loc: { start: 2926, end: 2931 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 2933, end: 2937 } + }, + typeArgs: [], + loc: { start: 2933, end: 2937 } + }, + loc: { start: 2926, end: 2937 } + } + ], + body: { + kind: 'asm_body', + shuffle: { + args: [ + { + kind: 'id', + text: 'value', + loc: { start: 2878, end: 2883 } + }, + { + kind: 'id', + text: 'self', + loc: { start: 2884, end: 2888 } + } + ], + ret: [] + }, + instructions: [ '1 STI' ] + }, + loc: { start: 2874, end: 2957 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 2917, end: 2924 } + }, + loc: { start: 2917, end: 2924 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeCoins', + loc: { start: 3902, end: 3912 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 3941, end: 3948 } + }, + loc: { start: 3941, end: 3948 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'value', + loc: { start: 3928, end: 3933 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3935, end: 3938 } + }, + loc: { start: 3935, end: 3938 } + }, + loc: { start: 3928, end: 3938 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'STVARUINT16' ] + }, + loc: { start: 3886, end: 3964 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 3919, end: 3926 } + }, + loc: { start: 3919, end: 3926 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeVarUint16', + loc: { start: 4389, end: 4403 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 4432, end: 4439 } + }, + loc: { start: 4432, end: 4439 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'value', + loc: { start: 4419, end: 4424 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4426, end: 4429 } + }, + loc: { start: 4426, end: 4429 } + }, + loc: { start: 4419, end: 4429 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'STVARUINT16' ] + }, + loc: { start: 4373, end: 4455 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 4410, end: 4417 } + }, + loc: { start: 4410, end: 4417 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeVarInt16', + loc: { start: 5096, end: 5109 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 5138, end: 5145 } + }, + loc: { start: 5138, end: 5145 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'value', + loc: { start: 5125, end: 5130 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5132, end: 5135 } + }, + loc: { start: 5132, end: 5135 } + }, + loc: { start: 5125, end: 5135 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'STVARINT16' ] + }, + loc: { start: 5080, end: 5160 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 5116, end: 5123 } + }, + loc: { start: 5116, end: 5123 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeVarUint32', + loc: { start: 6082, end: 6096 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 6125, end: 6132 } + }, + loc: { start: 6125, end: 6132 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'value', + loc: { start: 6112, end: 6117 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6119, end: 6122 } + }, + loc: { start: 6119, end: 6122 } + }, + loc: { start: 6112, end: 6122 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'STVARUINT32' ] + }, + loc: { start: 6066, end: 6148 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 6103, end: 6110 } + }, + loc: { start: 6103, end: 6110 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeVarInt32', + loc: { start: 6797, end: 6810 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 6839, end: 6846 } + }, + loc: { start: 6839, end: 6846 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'value', + loc: { start: 6826, end: 6831 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6833, end: 6836 } + }, + loc: { start: 6833, end: 6836 } + }, + loc: { start: 6826, end: 6836 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'STVARINT32' ] + }, + loc: { start: 6781, end: 6861 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 6817, end: 6824 } + }, + loc: { start: 6817, end: 6824 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeRef', + loc: { start: 7529, end: 7537 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 7566, end: 7573 } + }, + loc: { start: 7566, end: 7573 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cell', + loc: { start: 7553, end: 7557 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 7559, end: 7563 } + }, + loc: { start: 7559, end: 7563 } + }, + loc: { start: 7553, end: 7563 } + } + ], + body: { + kind: 'asm_body', + shuffle: { + args: [ + { + kind: 'id', + text: 'cell', + loc: { start: 7506, end: 7510 } + }, + { + kind: 'id', + text: 'self', + loc: { start: 7511, end: 7515 } + } + ], + ret: [] + }, + instructions: [ 'STREF' ] + }, + loc: { start: 7502, end: 7583 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 7544, end: 7551 } + }, + loc: { start: 7544, end: 7551 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeSlice', + loc: { start: 8005, end: 8015 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 8046, end: 8053 } + }, + loc: { start: 8046, end: 8053 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'slice', + loc: { start: 8031, end: 8036 } + }, + type: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 8038, end: 8043 } + }, + loc: { start: 8038, end: 8043 } + }, + loc: { start: 8031, end: 8043 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'STSLICER' ] + }, + loc: { start: 7989, end: 8066 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 8022, end: 8029 } + }, + loc: { start: 8022, end: 8029 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeBuilder', + loc: { start: 8633, end: 8645 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 8678, end: 8685 } + }, + loc: { start: 8678, end: 8685 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'other', + loc: { start: 8661, end: 8666 } + }, + type: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 8668, end: 8675 } + }, + loc: { start: 8668, end: 8675 } + }, + loc: { start: 8661, end: 8675 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'STBR' ] + }, + loc: { start: 8617, end: 8694 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 8652, end: 8659 } + }, + loc: { start: 8652, end: 8659 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeMaybeRef', + loc: { start: 9622, end: 9635 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 9665, end: 9672 } + }, + loc: { start: 9665, end: 9672 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cell', + loc: { start: 9651, end: 9655 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 9661, end: 9662 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 9657, end: 9661 } + }, + loc: { start: 9657, end: 9661 } + } + ], + loc: { start: 9661, end: 9662 } + }, + loc: { start: 9651, end: 9662 } + } + ], + body: { + kind: 'asm_body', + shuffle: { + args: [ + { + kind: 'id', + text: 'cell', + loc: { start: 9599, end: 9603 } + }, + { + kind: 'id', + text: 'self', + loc: { start: 9604, end: 9608 } + } + ], + ret: [] + }, + instructions: [ 'STOPTREF' ] + }, + loc: { start: 9595, end: 9685 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 9642, end: 9649 } + }, + loc: { start: 9642, end: 9649 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'endCell', + loc: { start: 10082, end: 10089 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 10106, end: 10110 } + }, + loc: { start: 10106, end: 10110 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ENDC' ] + }, + loc: { start: 10066, end: 10119 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 10096, end: 10103 } + }, + loc: { start: 10096, end: 10103 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'refs', + loc: { start: 10479, end: 10483 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10500, end: 10503 } + }, + loc: { start: 10500, end: 10503 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'BREFS' ] + }, + loc: { start: 10463, end: 10513 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 10490, end: 10497 } + }, + loc: { start: 10490, end: 10497 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'bits', + loc: { start: 10867, end: 10871 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10888, end: 10891 } + }, + loc: { start: 10888, end: 10891 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'BBITS' ] + }, + loc: { start: 10851, end: 10901 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 10878, end: 10885 } + }, + loc: { start: 10878, end: 10885 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'depth', + loc: { start: 11403, end: 11408 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11425, end: 11428 } + }, + loc: { start: 11425, end: 11428 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'BDEPTH' ] + }, + loc: { start: 11387, end: 11439 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 11415, end: 11422 } + }, + loc: { start: 11415, end: 11422 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'beginParse', + loc: { start: 11787, end: 11797 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 11811, end: 11816 } + }, + loc: { start: 11811, end: 11816 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'CTOS' ] + }, + loc: { start: 11771, end: 11825 } + } + }, + selfType: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 11804, end: 11808 } + }, + loc: { start: 11804, end: 11808 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadRef', + loc: { start: 12822, end: 12829 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 12844, end: 12848 } + }, + loc: { start: 12844, end: 12848 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { + args: [], + ret: [ + { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 12797, end: 12798 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 12799, end: 12800 } + } + ] + }, + instructions: [ 'LDREF' ] + }, + loc: { start: 12790, end: 12858 } + } + }, + selfType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 12836, end: 12841 } + }, + loc: { start: 12836, end: 12841 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'skipRef', + loc: { start: 13772, end: 13779 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LDREF NIP' ] + }, + loc: { start: 13748, end: 13806 } + } + }, + selfType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 13786, end: 13791 } + }, + loc: { start: 13786, end: 13791 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'preloadRef', + loc: { start: 14937, end: 14947 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 14962, end: 14966 } + }, + loc: { start: 14962, end: 14966 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'PLDREF' ] + }, + loc: { start: 14921, end: 14977 } + } + }, + selfType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 14954, end: 14959 } + }, + loc: { start: 14954, end: 14959 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadMaybeRef', + loc: { start: 16024, end: 16036 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 16055, end: 16056 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 16051, end: 16055 } + }, + loc: { start: 16051, end: 16055 } + } + ], + loc: { start: 16055, end: 16056 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { + args: [], + ret: [ + { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15999, end: 16000 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 16001, end: 16002 } + } + ] + }, + instructions: [ 'LDOPTREF' ] + }, + loc: { start: 15992, end: 16069 } + } + }, + selfType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 16043, end: 16048 } + }, + loc: { start: 16043, end: 16048 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'skipMaybeRef', + loc: { start: 17041, end: 17053 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LDOPTREF NIP' ] + }, + loc: { start: 17017, end: 17083 } + } + }, + selfType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 17060, end: 17065 } + }, + loc: { start: 17060, end: 17065 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'preloadMaybeRef', + loc: { start: 18449, end: 18464 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 18483, end: 18484 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 18479, end: 18483 } + }, + loc: { start: 18479, end: 18483 } + } + ], + loc: { start: 18483, end: 18484 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'PLDOPTREF' ] + }, + loc: { start: 18433, end: 18498 } + } + }, + selfType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 18471, end: 18476 } + }, + loc: { start: 18471, end: 18476 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadBits', + loc: { start: 19377, end: 19385 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 19408, end: 19413 } + }, + loc: { start: 19408, end: 19413 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'l', + loc: { start: 19399, end: 19400 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 19402, end: 19405 } + }, + loc: { start: 19402, end: 19405 } + }, + loc: { start: 19399, end: 19405 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'load_bits', + loc: { start: 19268, end: 19277 } + } + }, + loc: { start: 19262, end: 19414 } + } + }, + selfType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 19392, end: 19397 } + }, + loc: { start: 19392, end: 19397 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'preloadBits', + loc: { start: 20333, end: 20344 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 20367, end: 20372 } + }, + loc: { start: 20367, end: 20372 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'l', + loc: { start: 20358, end: 20359 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 20361, end: 20364 } + }, + loc: { start: 20361, end: 20364 } + }, + loc: { start: 20358, end: 20364 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'preload_bits', + loc: { start: 20228, end: 20240 } + } + }, + loc: { start: 20222, end: 20373 } + } + }, + selfType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 20351, end: 20356 } + }, + loc: { start: 20351, end: 20356 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadInt', + loc: { start: 21236, end: 21243 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 21266, end: 21269 } + }, + loc: { start: 21266, end: 21269 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'l', + loc: { start: 21257, end: 21258 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 21260, end: 21263 } + }, + loc: { start: 21260, end: 21263 } + }, + loc: { start: 21257, end: 21263 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'load_int', + loc: { start: 21132, end: 21140 } + } + }, + loc: { start: 21126, end: 21270 } + } + }, + selfType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 21250, end: 21255 } + }, + loc: { start: 21250, end: 21255 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'preloadInt', + loc: { start: 22164, end: 22174 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 22197, end: 22200 } + }, + loc: { start: 22197, end: 22200 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'l', + loc: { start: 22188, end: 22189 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 22191, end: 22194 } + }, + loc: { start: 22191, end: 22194 } + }, + loc: { start: 22188, end: 22194 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'preload_int', + loc: { start: 22064, end: 22075 } + } + }, + loc: { start: 22058, end: 22201 } + } + }, + selfType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 22181, end: 22186 } + }, + loc: { start: 22181, end: 22186 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadUint', + loc: { start: 23071, end: 23079 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 23102, end: 23105 } + }, + loc: { start: 23102, end: 23105 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'l', + loc: { start: 23093, end: 23094 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 23096, end: 23099 } + }, + loc: { start: 23096, end: 23099 } + }, + loc: { start: 23093, end: 23099 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'load_uint', + loc: { start: 22966, end: 22975 } + } + }, + loc: { start: 22960, end: 23106 } + } + }, + selfType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 23086, end: 23091 } + }, + loc: { start: 23086, end: 23091 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'preloadUint', + loc: { start: 24007, end: 24018 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 24041, end: 24044 } + }, + loc: { start: 24041, end: 24044 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'l', + loc: { start: 24032, end: 24033 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 24035, end: 24038 } + }, + loc: { start: 24035, end: 24038 } + }, + loc: { start: 24032, end: 24038 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'preload_uint', + loc: { start: 23906, end: 23918 } + } + }, + loc: { start: 23900, end: 24045 } + } + }, + selfType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 24025, end: 24030 } + }, + loc: { start: 24025, end: 24030 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadBool', + loc: { start: 24834, end: 24842 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 24857, end: 24861 } + }, + typeArgs: [], + loc: { start: 24857, end: 24861 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { + args: [], + ret: [ + { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 24809, end: 24810 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 24811, end: 24812 } + } + ] + }, + instructions: [ '1 LDI' ] + }, + loc: { start: 24802, end: 24871 } + } + }, + selfType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 24849, end: 24854 } + }, + loc: { start: 24849, end: 24854 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'skipBool', + loc: { start: 25769, end: 25777 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ '1 LDI NIP' ] + }, + loc: { start: 25745, end: 25804 } + } + }, + selfType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 25784, end: 25789 } + }, + loc: { start: 25784, end: 25789 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadBit', + loc: { start: 26558, end: 26565 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 26580, end: 26584 } + }, + typeArgs: [], + loc: { start: 26580, end: 26584 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { + args: [], + ret: [ + { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 26533, end: 26534 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 26535, end: 26536 } + } + ] + }, + instructions: [ '1 LDI' ] + }, + loc: { start: 26526, end: 26594 } + } + }, + selfType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 26572, end: 26577 } + }, + loc: { start: 26572, end: 26577 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadCoins', + loc: { start: 27454, end: 27463 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 27478, end: 27481 } + }, + loc: { start: 27478, end: 27481 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { + args: [], + ret: [ + { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 27429, end: 27430 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 27431, end: 27432 } + } + ] + }, + instructions: [ 'LDVARUINT16' ] + }, + loc: { start: 27422, end: 27497 } + } + }, + selfType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 27470, end: 27475 } + }, + loc: { start: 27470, end: 27475 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'skipCoins', + loc: { start: 28454, end: 28463 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LDVARUINT16 NIP' ] + }, + loc: { start: 28430, end: 28496 } + } + }, + selfType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 28470, end: 28475 } + }, + loc: { start: 28470, end: 28475 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadVarUint16', + loc: { start: 29318, end: 29331 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 29346, end: 29349 } + }, + loc: { start: 29346, end: 29349 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { + args: [], + ret: [ + { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 29293, end: 29294 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 29295, end: 29296 } + } + ] + }, + instructions: [ 'LDVARUINT16' ] + }, + loc: { start: 29286, end: 29365 } + } + }, + selfType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 29338, end: 29343 } + }, + loc: { start: 29338, end: 29343 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'skipVarUint16', + loc: { start: 30263, end: 30276 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LDVARUINT16 NIP' ] + }, + loc: { start: 30239, end: 30309 } + } + }, + selfType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 30283, end: 30288 } + }, + loc: { start: 30283, end: 30288 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadVarInt16', + loc: { start: 31141, end: 31153 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 31168, end: 31171 } + }, + loc: { start: 31168, end: 31171 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { + args: [], + ret: [ + { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 31116, end: 31117 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 31118, end: 31119 } + } + ] + }, + instructions: [ 'LDVARINT16' ] + }, + loc: { start: 31109, end: 31186 } + } + }, + selfType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 31160, end: 31165 } + }, + loc: { start: 31160, end: 31165 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'skipVarInt16', + loc: { start: 32093, end: 32105 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LDVARINT16 NIP' ] + }, + loc: { start: 32069, end: 32137 } + } + }, + selfType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 32112, end: 32117 } + }, + loc: { start: 32112, end: 32117 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadVarUint32', + loc: { start: 32987, end: 33000 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 33015, end: 33018 } + }, + loc: { start: 33015, end: 33018 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { + args: [], + ret: [ + { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 32962, end: 32963 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 32964, end: 32965 } + } + ] + }, + instructions: [ 'LDVARUINT32' ] + }, + loc: { start: 32955, end: 33034 } + } + }, + selfType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 33007, end: 33012 } + }, + loc: { start: 33007, end: 33012 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'skipVarUint32', + loc: { start: 34007, end: 34020 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LDVARUINT32 NIP' ] + }, + loc: { start: 33983, end: 34053 } + } + }, + selfType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 34027, end: 34032 } + }, + loc: { start: 34027, end: 34032 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadVarInt32', + loc: { start: 34897, end: 34909 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 34924, end: 34927 } + }, + loc: { start: 34924, end: 34927 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { + args: [], + ret: [ + { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 34872, end: 34873 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 34874, end: 34875 } + } + ] + }, + instructions: [ 'LDVARINT32' ] + }, + loc: { start: 34865, end: 34942 } + } + }, + selfType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 34916, end: 34921 } + }, + loc: { start: 34916, end: 34921 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'skipVarInt32', + loc: { start: 35854, end: 35866 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LDVARINT32 NIP' ] + }, + loc: { start: 35830, end: 35898 } + } + }, + selfType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 35873, end: 35878 } + }, + loc: { start: 35873, end: 35878 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'skipBits', + loc: { start: 36746, end: 36754 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'l', + loc: { start: 36768, end: 36769 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 36771, end: 36774 } + }, + loc: { start: 36771, end: 36774 } + }, + loc: { start: 36768, end: 36774 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SDSKIPFIRST' ] + }, + loc: { start: 36722, end: 36791 } + } + }, + selfType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 36761, end: 36766 } + }, + loc: { start: 36761, end: 36766 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'endParse', + loc: { start: 37397, end: 37405 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ENDS' ] + }, + loc: { start: 37381, end: 37427 } + } + }, + selfType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 37412, end: 37417 } + }, + loc: { start: 37412, end: 37417 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'skipLastBits', + loc: { start: 38319, end: 38331 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 38356, end: 38361 } + }, + loc: { start: 38356, end: 38361 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'len', + loc: { start: 38345, end: 38348 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 38350, end: 38353 } + }, + loc: { start: 38350, end: 38353 } + }, + loc: { start: 38345, end: 38353 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SDSKIPLAST' ] + }, + loc: { start: 38303, end: 38376 } + } + }, + selfType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 38338, end: 38343 } + }, + loc: { start: 38338, end: 38343 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'firstBits', + loc: { start: 39373, end: 39382 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 39407, end: 39412 } + }, + loc: { start: 39407, end: 39412 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'len', + loc: { start: 39396, end: 39399 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 39401, end: 39404 } + }, + loc: { start: 39401, end: 39404 } + }, + loc: { start: 39396, end: 39404 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SDCUTFIRST' ] + }, + loc: { start: 39357, end: 39427 } + } + }, + selfType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 39389, end: 39394 } + }, + loc: { start: 39389, end: 39394 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'lastBits', + loc: { start: 40218, end: 40226 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 40251, end: 40256 } + }, + loc: { start: 40251, end: 40256 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'len', + loc: { start: 40240, end: 40243 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 40245, end: 40248 } + }, + loc: { start: 40245, end: 40248 } + }, + loc: { start: 40240, end: 40248 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SDCUTLAST' ] + }, + loc: { start: 40202, end: 40270 } + } + }, + selfType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 40233, end: 40238 } + }, + loc: { start: 40233, end: 40238 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'depth', + loc: { start: 40758, end: 40763 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 40778, end: 40781 } + }, + loc: { start: 40778, end: 40781 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SDEPTH' ] + }, + loc: { start: 40742, end: 40792 } + } + }, + selfType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 40770, end: 40775 } + }, + loc: { start: 40770, end: 40775 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'refs', + loc: { start: 41166, end: 41170 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 41185, end: 41188 } + }, + loc: { start: 41185, end: 41188 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SREFS' ] + }, + loc: { start: 41150, end: 41198 } + } + }, + selfType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 41177, end: 41182 } + }, + loc: { start: 41177, end: 41182 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'bits', + loc: { start: 41550, end: 41554 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 41569, end: 41572 } + }, + loc: { start: 41569, end: 41572 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SBITS' ] + }, + loc: { start: 41534, end: 41582 } + } + }, + selfType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 41561, end: 41566 } + }, + loc: { start: 41561, end: 41566 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'empty', + loc: { start: 42117, end: 42122 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 42137, end: 42141 } + }, + typeArgs: [], + loc: { start: 42137, end: 42141 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SEMPTY' ] + }, + loc: { start: 42101, end: 42152 } + } + }, + selfType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 42129, end: 42134 } + }, + loc: { start: 42129, end: 42134 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'dataEmpty', + loc: { start: 42682, end: 42691 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 42706, end: 42710 } + }, + typeArgs: [], + loc: { start: 42706, end: 42710 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SDEMPTY' ] + }, + loc: { start: 42666, end: 42722 } + } + }, + selfType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 42698, end: 42703 } + }, + loc: { start: 42698, end: 42703 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'refsEmpty', + loc: { start: 43231, end: 43240 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 43255, end: 43259 } + }, + typeArgs: [], + loc: { start: 43255, end: 43259 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SREMPTY' ] + }, + loc: { start: 43215, end: 43271 } + } + }, + selfType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 43247, end: 43252 } + }, + loc: { start: 43247, end: 43252 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'asSlice', + loc: { start: 43671, end: 43678 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 43695, end: 43700 } + }, + loc: { start: 43695, end: 43700 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 43714, end: 43718 } + }, + method: { + kind: 'id', + text: 'endCell', + loc: { start: 43719, end: 43726 } + }, + typeArgs: [], + args: [], + loc: { start: 43714, end: 43728 } + }, + method: { + kind: 'id', + text: 'beginParse', + loc: { start: 43729, end: 43739 } + }, + typeArgs: [], + args: [], + loc: { start: 43714, end: 43741 } + }, + loc: { start: 43707, end: 43742 } + } + ] + }, + loc: { start: 43652, end: 43744 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 43685, end: 43692 } + }, + loc: { start: 43685, end: 43692 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'asSlice', + loc: { start: 44098, end: 44105 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 44119, end: 44124 } + }, + loc: { start: 44119, end: 44124 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 44138, end: 44142 } + }, + method: { + kind: 'id', + text: 'beginParse', + loc: { start: 44143, end: 44153 } + }, + typeArgs: [], + args: [], + loc: { start: 44138, end: 44155 } + }, + loc: { start: 44131, end: 44156 } + } + ] + }, + loc: { start: 44079, end: 44158 } + } + }, + selfType: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 44112, end: 44116 } + }, + loc: { start: 44112, end: 44116 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'asCell', + loc: { start: 44714, end: 44720 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 44735, end: 44739 } + }, + loc: { start: 44735, end: 44739 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'static_call', + function: { + kind: 'id', + text: 'beginCell', + loc: { start: 44753, end: 44762 } + }, + typeArgs: [], + args: [], + loc: { start: 44753, end: 44764 } + }, + method: { + kind: 'id', + text: 'storeSlice', + loc: { start: 44774, end: 44784 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'self', + loc: { start: 44785, end: 44789 } + } + ], + loc: { start: 44753, end: 44790 } + }, + method: { + kind: 'id', + text: 'endCell', + loc: { start: 44800, end: 44807 } + }, + typeArgs: [], + args: [], + loc: { start: 44753, end: 44809 } + }, + loc: { start: 44746, end: 44810 } + } + ] + }, + loc: { start: 44695, end: 44812 } + } + }, + selfType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 44727, end: 44732 } + }, + loc: { start: 44727, end: 44732 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'asCell', + loc: { start: 45173, end: 45179 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 45196, end: 45200 } + }, + loc: { start: 45196, end: 45200 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 45214, end: 45218 } + }, + method: { + kind: 'id', + text: 'endCell', + loc: { start: 45219, end: 45226 } + }, + typeArgs: [], + args: [], + loc: { start: 45214, end: 45228 } + }, + loc: { start: 45207, end: 45229 } + } + ] + }, + loc: { start: 45154, end: 45231 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 45186, end: 45193 } + }, + loc: { start: 45186, end: 45193 } + } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'emptyCell', + loc: { start: 45592, end: 45601 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 45605, end: 45609 } + }, + loc: { start: 45605, end: 45609 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + ' PUSHREF // Pure Fift: "" turns it into a cell at compile time' + ] + }, + loc: { start: 45584, end: 45711 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'emptySlice', + loc: { start: 46077, end: 46087 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 46091, end: 46096 } + }, + loc: { start: 46091, end: 46096 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'b{} PUSHSLICE' ] + }, + loc: { start: 46069, end: 46118 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'DataSize', + loc: { start: 46431, end: 46439 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'cells', + loc: { start: 46516, end: 46521 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 46523, end: 46526 } + }, + loc: { start: 46523, end: 46526 } + }, + initializer: undefined, + loc: { start: 46516, end: 46526 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bits', + loc: { start: 46615, end: 46619 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 46621, end: 46624 } + }, + loc: { start: 46621, end: 46624 } + }, + initializer: undefined, + loc: { start: 46615, end: 46624 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'refs', + loc: { start: 46713, end: 46717 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 46719, end: 46722 } + }, + loc: { start: 46719, end: 46722 } + }, + initializer: undefined, + loc: { start: 46713, end: 46722 } + } + ], + loc: { start: 46424, end: 46725 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'computeDataSize', + loc: { start: 48450, end: 48465 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'DataSize', + loc: { start: 48495, end: 48503 } + }, + typeArgs: [], + loc: { start: 48495, end: 48503 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'maxCells', + loc: { start: 48479, end: 48487 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 48489, end: 48492 } + }, + loc: { start: 48489, end: 48492 } + }, + loc: { start: 48479, end: 48492 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'CDATASIZE' ] + }, + loc: { start: 48434, end: 48517 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 48476, end: 48477 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 48472, end: 48476 } + }, + loc: { start: 48472, end: 48476 } + } + ], + loc: { start: 48476, end: 48477 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'computeDataSize', + loc: { start: 50094, end: 50109 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'DataSize', + loc: { start: 50139, end: 50147 } + }, + typeArgs: [], + loc: { start: 50139, end: 50147 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'maxCells', + loc: { start: 50123, end: 50131 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 50133, end: 50136 } + }, + loc: { start: 50133, end: 50136 } + }, + loc: { start: 50123, end: 50136 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SDATASIZE' ] + }, + loc: { start: 50078, end: 50161 } + } + }, + selfType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 50116, end: 50121 } + }, + loc: { start: 50116, end: 50121 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'depth', + loc: { start: 50672, end: 50677 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 50692, end: 50695 } + }, + loc: { start: 50692, end: 50695 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'CDEPTH' ] + }, + loc: { start: 50656, end: 50706 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 50688, end: 50689 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 50684, end: 50688 } + }, + loc: { start: 50684, end: 50688 } + } + ], + loc: { start: 50688, end: 50689 } + } + } + ] + }, + loc: { start: 64, end: 90 } + }, + { + kind: 'tact', + source: { + kind: 'tact', + path: 'std/internal/crypto.tact', + code: '/// Extension function for the `Cell` type.\n' + + '///\n' + + '/// Calculates and returns an `Int` value of the [SHA-256] hash of the\n' + + '/// [standard `Cell` representation][std-representation] of the given `Cell`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let c: Cell = emptyCell();\n' + + '/// let fizz: Int = c.hash();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#cellhash\n' + + '///\n' + + '/// [SHA-256]: https://en.wikipedia.org/wiki/SHA-2#Hash_standard\n' + + '/// [std-representation]: https://docs.tact-lang.org/book/cells#cells-representation\n' + + '///\n' + + 'asm extends fun hash(self: Cell): Int { HASHCU }\n' + + '\n' + + '/// Extension function for the `Slice` type.\n' + + '///\n' + + '/// Calculates and returns an `Int` value of the [SHA-256] hash of the\n' + + '/// [standard `Slice` representation][std-representation] of the given `Slice`.\n' + + '///\n' + + '/// NOTE: **Gas expensive!** This function uses 500 gas units or more.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let s: Slice = beginCell().asSlice();\n' + + '/// let fizz: Int = s.hash();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#slicehash\n' + + '///\n' + + '/// [SHA-256]: https://en.wikipedia.org/wiki/SHA-2#Hash_standard\n' + + '/// [std-representation]: https://docs.tact-lang.org/book/cells#cells-representation\n' + + '///\n' + + 'asm extends fun hash(self: Slice): Int { HASHSU }\n' + + '\n' + + '/// Extension function for the `Slice` type. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Calculates and returns an `Int` value of the SHA-256 hash of the data bits from the given `Slice`, which should have a number of bits divisible by 8.\n' + + '///\n' + + '/// Unlike `sha256()`, this function is gas-efficient and **only** hashes the data of the given `Slice`, i.e. up to 1023 bits, ignoring the refs.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// // Base64-encoded BoC with "Hello, World!"\n' + + '/// let short: Slice = slice("te6cckEBAQEADgAAGEhlbGxvIHdvcmxkIXgtxbw=");\n' + + '///\n' + + "/// // It's enough to only take the hash of the data\n" + + '/// sha256(short) == short.hashData(); // true\n' + + '///\n' + + '/// // But if we construct a slice larger than 1023 bits with all refs combined,\n' + + "/// // we must use sha256() or we'll get skewed results or even collisions\n" + + '///\n' + + '/// let tmp: Builder = beginCell();\n' + + '/// repeat (127) { tmp = tmp.storeUint(69, 8) } // storing 127 bytes\n' + + '/// let ref: Cell = beginCell().storeUint(33, 8).endCell();\n' + + '/// let long: Slice = tmp.storeRef(ref).asSlice(); // plus a ref with a single byte\n' + + '///\n' + + "/// // Hashing just the data bits in the current slice isn't enough\n" + + '/// sha256(long) == long.hashData(); // false!\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 9: [Cell underflow] — Thrown when attempting to specify a `Slice` with number of bits **not** divisible by 8.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#slicehashdata\n' + + '///\n' + + '/// [Cell underflow]: https://docs.tact-lang.org/book/exit-codes#9\n' + + '///\n' + + 'asm extends fun hashData(self: Slice): Int { ONE HASHEXT_SHA256 }\n' + + '\n' + + '/// Extension function for the `String` type. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Calculates and returns an `Int` value of the SHA-256 hash of the data bits from the given `String`, which should have a number of bits divisible by 8.\n' + + '///\n' + + '/// Unlike `sha256()`, this function is gas-efficient and **only** hashes up to 127 bytes of the given string. Using longer strings would cause collisions if their first 127 bytes are the same.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let roll: Int = "Never gonna give you up!".hashData(); // just the hash of the data\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 9: [Cell underflow] — Thrown when attempting to specify a `String` with number of bits **not** divisible by 8.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#stringhashdata\n' + + '///\n' + + '/// [Cell underflow]: https://docs.tact-lang.org/book/exit-codes#9\n' + + '///\n' + + 'asm extends fun hashData(self: String): Int { ONE HASHEXT_SHA256 }\n' + + '\n' + + '/// Checks the [Ed25519] `signature` of the 256-bit unsigned `Int` `hash` using a `publicKey`,\n' + + '/// represented by a 256-bit unsigned `Int`. The signature must contain at least 512 bits of data, but\n' + + '/// only the first 512 bits are used.\n' + + '///\n' + + '/// Returns `true` if the signature is valid, `false` otherwise.\n' + + '///\n' + + '/// ```tact\n' + + '/// message ExtMsg {\n' + + '/// signature: Slice;\n' + + '/// data: Cell;\n' + + '/// }\n' + + '///\n' + + '/// contract Showcase {\n' + + '/// /// Persistent state variables\n' + + '/// pub: Int as uint256; // public key as a 256-bit unsigned Int\n' + + '///\n' + + '/// /// Constructor function init(), where all variables are initialized\n' + + '/// init(pub: Int) {\n' + + '/// self.pub = pub; // storing the public key upon contract initialization\n' + + '/// }\n' + + '///\n' + + '/// /// External message receiver, which accepts message ExtMsg\n' + + '/// external(msg: ExtMsg) {\n' + + '/// let hash: Int = beginCell().storeRef(msg.data).endCell().hash();\n' + + '/// let check: Bool = checkSignature(hash, msg.signature, self.pub);\n' + + '/// // ---- ------------- --------\n' + + '/// // ↑ ↑ ↑\n' + + '/// // | | publicKey stored in our contract\n' + + '/// // | signature obtained from the received message\n' + + '/// // hash calculated using the data from the received message\n' + + '/// // ... follow-up logic ...\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// NOTE: The first 10 calls of this function are very cheap regarding gas usage. However,\n' + + '/// the 11th call and onward consume more than 4 thousand gas units.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-crypto#checksignature\n' + + '///\n' + + '/// [Ed25519]: https://en.wikipedia.org/wiki/EdDSA#Ed25519\n' + + '///\n' + + 'asm fun checkSignature(hash: Int, signature: Slice, publicKey: Int): Bool { CHKSIGNU }\n' + + '\n' + + '/// Checks the [Ed25519] `signature` of the `data` using a `publicKey`, similar to `checkSignature()`.\n' + + '/// Verification itself is done indirectly on a [SHA-256] hash of the `data`.\n' + + '///\n' + + '/// Returns `true` if the signature is valid, `false` otherwise.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let data: Slice = someData;\n' + + '/// let signature: Slice = someSignature;\n' + + '/// let publicKey: Int = 42;\n' + + '///\n' + + '/// let check: Bool = checkDataSignature(data, signature, publicKey);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// NOTE: The first 10 calls of this function are very cheap regarding gas usage. However,\n' + + '/// the 11th call and onward consume more than 4 thousand gas units.\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 9: [Cell underflow] — Thrown when the bit length of `data` is **not** divisible by 8.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-crypto#checkdatasignature\n' + + '///\n' + + '/// [Cell underflow]: https://docs.tact-lang.org/book/exit-codes#9\n' + + '/// [Ed25519]: https://en.wikipedia.org/wiki/EdDSA#Ed25519\n' + + '/// [SHA-256]: https://en.wikipedia.org/wiki/SHA-2#Hash_standard\n' + + '///\n' + + 'asm fun checkDataSignature(data: Slice, signature: Slice, publicKey: Int): Bool { CHKSIGNS }\n' + + '\n' + + '/// A struct that contains a 512-bit [Ed25519] signature and the data it signs.\n' + + '///\n' + + '/// ```tact\n' + + '/// message MessageWithSignedData {\n' + + '/// // The `bundle.signature` contains the 512-bit Ed25519 signature\n' + + '/// // of the remaining data fields of this message struct,\n' + + '/// // while `bundle.signedData` references those data fields.\n' + + '/// // In this case, the fields are `walletId` and `seqno`.\n' + + '/// bundle: SignedBundle;\n' + + '///\n' + + '/// // These fields are common to external messages to user wallets.\n' + + '/// walletId: Int as int32;\n' + + '/// seqno: Int as uint32;\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-crypto#signedbundle\n' + + '/// * https://docs.tact-lang.org/ref/core-crypto#signedbundleverifysignature\n' + + '///\n' + + '/// [Ed25519]: https://en.wikipedia.org/wiki/EdDSA#Ed25519\n' + + '///\n' + + 'struct SignedBundle {\n' + + ' /// A 512-bit Ed25519 signature of the `signedData`.\n' + + ' signature: Slice as bytes64;\n' + + '\n' + + ' /// The remaining non-serialized data of the enclosing struct or message struct,\n' + + ' /// which was used to obtain the 512-bit Ed25519 `signature`.\n' + + ' signedData: Slice as remaining;\n' + + '}\n' + + '\n' + + '/// Extension function for the `SignedBundle` struct. Available since Tact 1.6.6.\n' + + '///\n' + + '/// Checks whether `self.signedData` was signed by the 512-bit [Ed25519] signature `self.signature`,\n' + + '/// using the given `publicKey`. Returns `true` if the signature is valid, `false` otherwise.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Example(publicKey: Int as uint256) {\n' + + '/// external(msg: MessageWithSignedData) {\n' + + '/// // Checks that the signature of the SignedBundle from the incoming external\n' + + "/// // message wasn't forged and made by the owner of this self.publicKey with\n" + + '/// // its respective private key managed elsewhere.\n' + + '/// throwUnless(35, msg.bundle.verifySignature(self.publicKey));\n' + + '///\n' + + '/// // ...rest of the checks and code...\n' + + '/// }\n' + + '/// }\n' + + '///\n' + + '/// message MessageWithSignedData {\n' + + '/// // The `bundle.signature` contains the 512-bit Ed25519 signature\n' + + '/// // of the remaining data fields of this message struct,\n' + + '/// // while `bundle.signedData` references those data fields.\n' + + '/// // In this case, the fields are `walletId` and `seqno`.\n' + + '/// bundle: SignedBundle;\n' + + '///\n' + + '/// // These fields are common to external messages to user wallets.\n' + + '/// walletId: Int as int32;\n' + + '/// seqno: Int as uint32;\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-crypto#signedbundleverifysignature\n' + + '///\n' + + '/// [Ed25519]: https://en.wikipedia.org/wiki/EdDSA#Ed25519\n' + + '///\n' + + 'inline extends fun verifySignature(self: SignedBundle, publicKey: Int): Bool {\n' + + ' return checkSignature(self.signedData.hash(), self.signature, publicKey);\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.6.\n' + + '///\n' + + '/// Computes and returns the Ethereum-compatible [Keccak-256] hash as a 256-bit unsigned `Int` from the passed `Slice` `data`.\n' + + '///\n' + + '/// The `data` slice should have a number of bits divisible by 8 and no more than a single reference per cell, because only the first reference of each nested cell will be taken into account.\n' + + '///\n' + + '/// #### Usage\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Examples() {\n' + + '/// receive(rawMsg: Slice) {\n' + + '/// // Hash incoming messa'... 1135 more characters, + imports: [], + items: [ + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'hash', + loc: { start: 554, end: 558 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 572, end: 575 } + }, + loc: { start: 572, end: 575 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'HASHCU' ] + }, + loc: { start: 538, end: 586 } + } + }, + selfType: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 565, end: 569 } + }, + loc: { start: 565, end: 569 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'hash', + loc: { start: 1232, end: 1236 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1251, end: 1254 } + }, + loc: { start: 1251, end: 1254 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'HASHSU' ] + }, + loc: { start: 1216, end: 1265 } + } + }, + selfType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 1243, end: 1248 } + }, + loc: { start: 1243, end: 1248 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'hashData', + loc: { start: 2808, end: 2816 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2831, end: 2834 } + }, + loc: { start: 2831, end: 2834 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ONE HASHEXT_SHA256' ] + }, + loc: { start: 2792, end: 2857 } + } + }, + selfType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 2823, end: 2828 } + }, + loc: { start: 2823, end: 2828 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'hashData', + loc: { start: 3740, end: 3748 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3764, end: 3767 } + }, + loc: { start: 3764, end: 3767 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ONE HASHEXT_SHA256' ] + }, + loc: { start: 3724, end: 3790 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 3755, end: 3761 } + }, + typeArgs: [], + loc: { start: 3755, end: 3761 } + } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'checkSignature', + loc: { start: 5592, end: 5606 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 5653, end: 5657 } + }, + typeArgs: [], + loc: { start: 5653, end: 5657 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'hash', + loc: { start: 5607, end: 5611 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5613, end: 5616 } + }, + loc: { start: 5613, end: 5616 } + }, + loc: { start: 5607, end: 5616 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'signature', + loc: { start: 5618, end: 5627 } + }, + type: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 5629, end: 5634 } + }, + loc: { start: 5629, end: 5634 } + }, + loc: { start: 5618, end: 5634 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'publicKey', + loc: { start: 5636, end: 5645 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5647, end: 5650 } + }, + loc: { start: 5647, end: 5650 } + }, + loc: { start: 5636, end: 5650 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'CHKSIGNU' ] + }, + loc: { start: 5584, end: 5670 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'checkDataSignature', + loc: { start: 6731, end: 6749 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 6798, end: 6802 } + }, + typeArgs: [], + loc: { start: 6798, end: 6802 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'data', + loc: { start: 6750, end: 6754 } + }, + type: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 6756, end: 6761 } + }, + loc: { start: 6756, end: 6761 } + }, + loc: { start: 6750, end: 6761 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'signature', + loc: { start: 6763, end: 6772 } + }, + type: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 6774, end: 6779 } + }, + loc: { start: 6774, end: 6779 } + }, + loc: { start: 6763, end: 6779 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'publicKey', + loc: { start: 6781, end: 6790 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6792, end: 6795 } + }, + loc: { start: 6792, end: 6795 } + }, + loc: { start: 6781, end: 6795 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'CHKSIGNS' ] + }, + loc: { start: 6723, end: 6815 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'SignedBundle', + loc: { start: 7626, end: 7638 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'signature', + loc: { start: 7702, end: 7711 } + }, + type: { + kind: 'TySlice', + format: { + kind: 'SFBits', + bits: 512, + loc: { start: 7713, end: 7729 } + }, + loc: { start: 7713, end: 7718 } + }, + initializer: undefined, + loc: { start: 7702, end: 7729 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'signedData', + loc: { start: 7887, end: 7897 } + }, + type: { + kind: 'TySlice', + format: { + kind: 'SFRemaining', + loc: { start: 7899, end: 7917 } + }, + loc: { start: 7899, end: 7904 } + }, + initializer: undefined, + loc: { start: 7887, end: 7917 } + } + ], + loc: { start: 7619, end: 7920 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'verifySignature', + loc: { start: 9355, end: 9370 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 9408, end: 9412 } + }, + typeArgs: [], + loc: { start: 9408, end: 9412 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'publicKey', + loc: { start: 9391, end: 9400 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9402, end: 9405 } + }, + loc: { start: 9402, end: 9405 } + }, + loc: { start: 9391, end: 9405 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'checkSignature', + loc: { start: 9426, end: 9440 } + }, + typeArgs: [], + args: [ + { + kind: 'method_call', + self: { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'self', + loc: { start: 9441, end: 9445 } + }, + field: { + kind: 'id', + text: 'signedData', + loc: { start: 9446, end: 9456 } + }, + loc: { start: 9441, end: 9456 } + }, + method: { + kind: 'id', + text: 'hash', + loc: { start: 9457, end: 9461 } + }, + typeArgs: [], + args: [], + loc: { start: 9441, end: 9463 } + }, + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'self', + loc: { start: 9465, end: 9469 } + }, + field: { + kind: 'id', + text: 'signature', + loc: { start: 9470, end: 9479 } + }, + loc: { start: 9465, end: 9479 } + }, + { + kind: 'var', + name: 'publicKey', + loc: { start: 9481, end: 9490 } + } + ], + loc: { start: 9426, end: 9491 } + }, + loc: { start: 9419, end: 9492 } + } + ] + }, + loc: { start: 9336, end: 9494 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'SignedBundle', + loc: { start: 9377, end: 9389 } + }, + typeArgs: [], + loc: { start: 9377, end: 9389 } + } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'keccak256', + loc: { start: 10942, end: 10951 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10966, end: 10969 } + }, + loc: { start: 10966, end: 10969 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'data', + loc: { start: 10952, end: 10956 } + }, + type: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 10958, end: 10963 } + }, + loc: { start: 10958, end: 10963 } + }, + loc: { start: 10952, end: 10963 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '<{\n' + + ' <{ DUP SREFS }> PUSHCONT\n' + + ' <{ LDREFRTOS }> PUSHCONT\n' + + ' WHILE\n' + + ' DEPTH\n' + + ' HASHEXT_KECCAK256\n' + + ' }> PUSHCONT\n' + + ' 1 1 CALLXARGS' + ] + }, + loc: { start: 10934, end: 11134 } + } + ] + }, + loc: { start: 91, end: 118 } + }, + { + kind: 'tact', + source: { + kind: 'tact', + path: 'std/internal/text.tact', + code: '//\n' + + '// String builder\n' + + '//\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Creates and returns an empty `StringBuilder`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example(): String {\n' + + '/// let fizz: StringBuilder = beginString();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#beginstring\n' + + '///\n' + + '@name(__tact_string_builder_start_string)\n' + + 'native beginString(): StringBuilder;\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Creates and returns an empty `StringBuilder` for building a comment string, which prefixes\n' + + '/// the resulting `String` with four null bytes. This format is used for passing text comments\n' + + '/// as message bodies.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example(): String {\n' + + '/// let fizz: StringBuilder = beginComment();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#begincomment\n' + + '///\n' + + '@name(__tact_string_builder_start_comment)\n' + + 'native beginComment(): StringBuilder;\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Creates and returns an empty `StringBuilder` for building a tail string, which prefixes\n' + + '/// the resulting `String` with a single null byte. This format is used in various standards\n' + + '/// such as NFT or Jetton.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example(): String {\n' + + '/// let fizz: StringBuilder = beginTailString();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#begintailstring\n' + + '///\n' + + '@name(__tact_string_builder_start_tail_string)\n' + + 'native beginTailString(): StringBuilder;\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Creates and returns a new `StringBuilder` from an existing `StringBuilder` `b`. Useful when\n' + + '/// you need to serialize an existing `String` to a `Cell` along with other data.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example(): String {\n' + + '/// let fizz: StringBuilder = beginStringFromBuilder(beginString());\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#beginstringfrombuilder\n' + + '///\n' + + '@name(__tact_string_builder_start)\n' + + 'native beginStringFromBuilder(b: Builder): StringBuilder;\n' + + '\n' + + '/// Extension mutation function for the `StringBuilder` type.\n' + + '///\n' + + '/// Appends a `String` `s` to the `StringBuilder`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fizz: StringBuilder = beginString();\n' + + '/// fizz.append("oh");\n' + + '/// fizz.append("my");\n' + + '/// fizz.append("Tact!");\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#stringbuilderappend\n' + + '///\n' + + '@name(__tact_string_builder_append)\n' + + 'extends mutates native append(self: StringBuilder, s: String);\n' + + '\n' + + '/// Extension function for the `StringBuilder` type.\n' + + '///\n' + + '/// Returns a new `StringBuilder` after concatenating it with a `String` `s`. It can be chained,\n' + + '/// unlike `StringBuilder.append()`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fizz: StringBuilder = beginString()\n' + + '/// .concat("oh")\n' + + '/// .concat("my")\n' + + '/// .concat("Tact!");\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#stringbuilderconcat\n' + + '///\n' + + '@name(__tact_string_builder_append_not_mut)\n' + + 'extends native concat(self: StringBuilder, s: String): StringBuilder;\n' + + '\n' + + '/// Extension function for the `StringBuilder` type.\n' + + '///\n' + + '/// Returns an assembled `Cell` from a `StringBuilder`.\n' + + '///\n' + + '/// NOTE: **Gas expensive!** This function uses 500 gas units or more.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fizz: StringBuilder = beginString();\n' + + '/// let buzz: Cell = fizz.toCell();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#stringbuildertocell\n' + + '///\n' + + '@name(__tact_string_builder_end)\n' + + 'extends native toCell(self: StringBuilder): Cell;\n' + + '\n' + + '/// Extension function for the `StringBuilder` type.\n' + + '///\n' + + '/// Returns a built `String` from a `StringBuilder`.\n' + + '///\n' + + '/// NOTE: **Gas expensive!** This function uses 500 gas units or more.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fizz: StringBuilder = beginString();\n' + + '/// let buzz: String = fizz.toString();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#stringbuildertostring\n' + + '///\n' + + '@name(__tact_string_builder_end_slice)\n' + + 'extends native toString(self: StringBuilder): String;\n' + + '\n' + + '/// Extension function for the `StringBuilder` type.\n' + + '///\n' + + '/// Returns an assembled `Cell` as a `Slice` from a `StringBuilder`.\n' + + '/// An alias to `self.toCell().asSlice()`.\n' + + '///\n' + + '/// NOTE: **Gas expensive!** This function uses 500 gas units or more.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let s: StringBuilder = beginString();\n' + + '/// let fizz: Slice = s.toSlice();\n' + + '/// let buzz: Slice = s.toCell().asSlice();\n' + + '///\n' + + '/// fizz == buzz; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#stringbuildertoslice\n' + + '///\n' + + '@name(__tact_string_builder_end_slice)\n' + + 'extends native toSlice(self: StringBuilder): Slice;\n' + + '\n' + + '//\n' + + '// String conversion\n' + + '//\n' + + '\n' + + '/// Extension function for the `Int` type.\n' + + '///\n' + + '/// Returns a `String` from an `Int` value.\n' + + '///\n' + + '/// NOTE: **Gas expensive!** This function uses 500 gas units or more.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fizz: String = (84 - 42).toString();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#inttostring\n' + + '///\n' + + 'asm extends fun toString(self: Int): String {\n' + + ' // x\n' + + '\n' + + ' <{\n' + + ' // x\n' + + ' NEWC // x b\n' + + ' OVER // x b x\n' + + ' 0 LESSINT // x b <0?\n' + + ' <{\n' + + ' // x b\n' + + ' 45 PUSHINT // x b 45\n' + + ' SWAP // x 45 b\n' + + ' 8 STU // x b\n' + + ' SWAP // b x\n' + + ' NEGATE // b -x\n' + + ' SWAP // -x b\n' + + ' }>CONT IF\n' + + ' // x b\n' + + '\n' + + ' SWAP // b x\n' + + '\n' + + ' <{\n' + + ' // b x\n' + + ' 10 PUSHINT DIVMOD // b x/10 x%10\n' + + ' 48 ADDCONST // b x/10 (x%10+48)\n' + + ' s2 s2 s0 XC2PU ISZERO // (x%10+48) b x/10 x/10==0?\n' + + ' }>CONT UNTIL\n' + + ' // ... b x\n' + + '\n' + + ' DROP // ... b\n' + + ' DEPTH DEC // ... b n\n' + + ' <{ 8 STU }>CONT REPEAT // b\n' + + ' }>CONT 1 1 CALLXARGS\n' + + ' // b\n' + + '\n' + + ' ENDC CTOS // s\n' + + '}\n' + + '\n' + + '/// Extension function for the `Int` type.\n' + + '///\n' + + '/// Returns a `String` from an `Int` value using a [fixed-point representation] of a fractional\n' + + '/// number, where `self` is the significant part of the number and `digits` is the number\n' + + '/// of digits in the fractional part.\n' + + '///\n' + + '/// NOTE: **Gas expensive!** This function uses 500 gas units or more.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fizz: String = (42).toFloatString(9); // "0.000000042"\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 134: [Invalid argument] — Thrown when the given `digits` value is out of range.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-strings#inttofloatstring\n' + + '///\n' + + '/// [fixed-point representation]: https://en.wikipedia.org/wiki/Fixed-point_arithmetic\n' + + '/// [Invalid argument]: https://docs.tact-lang.org/book/exit-codes#134\n' + + '///\n' + + 'asm extends fun toFloatString(self: Int, digits: Int): String {\n' + + ' // x digits\n' + + '\n' + + ' DUP // x digits digits\n' + + ' 1 LESSINT // x digits digits<=0\n' + + ' 134 THROWIF // x digits\n' + + ' DUP // x digits digits\n' + + ' 77 GTINT // x digits digits>77\n' + + ' 134 THROWIF // x digits\n' + + '\n' + + ' NEWC // x digits b\n' + + ' ROTREV // b x digits\n' + + ' s1 PUSH // b x digits x\n' + + ' 0 LESSINT // b x digits x<0?\n' + + '\n' + + ' <{\n' + + ' // b x digits\n' + + ' ROT // x digits b\n' + + ' x{2d} STSLICECONST // x digits b\n' + + ' ROT // digits b x\n' + + ' NEGATE // digits b -x\n' + + ' ROT // b -x digits\n' + + ' }>CONT IF\n' + + '\n' + + ' // b x digits\n' + + ' ONE // b x digits 1\n' + + ' OVER // b x digits 1 digits\n' + + '\n' + + ' <{ 10 MULCONST }>CONT REPEAT // b x digits 10^digits\n' + + '\n' + + ' s1 s2 XCHG // b digits x 10^digits\n' + + ' DIVMOD // b digits left right\n' + + ' s3 s3 XCHG2 // right digits b left\n' + + '\n' + + ' <{\n' + + ' // b x\n' + + '\n' + + ' <{\n' + + ' // b x\n' + + ' 10 PUSHINT DIVMOD // b x/10 x%10\n' + + ' 48 ADDCONST // b x/10 (x%10+48)\n' + + ' s2 s2 s0 XC2PU ISZERO // (x%10+48) b x/10 x/10==0?\n' + + ' }>CONT UNTIL\n' + + ' // ... b x\n' + + '\n' + + ' DROP // ... b\n' + + ' DEPTH DEC // ... b n\n' + + ' <{ 8 STU }>CONT REPEAT // b\n' + + ' }>CONT 2 1 CALLXARGS\n' + + '\n' + + ' // right digits "left"\n' + + '\n' + + ' ROT // digits "left" right\n' + + ' DUP // digits "left" right right\n' + + ' ISZERO // digits "left" right right==0?\n' + + '\n' + + ' <{\n' + + ' // digits "left" right\n' + + ' DROP // digits "left"\n' + + ' NIP // "left"\n' + + ' }>CONT\n' + + '\n' + + ' <{\n' + + ' // digits "left" right\n' + + ' ZERO // digits "left" right 0\n' + + ' SWAP // digits "left" 0 right\n' + + '\n' + + ' <{\n' + + ' // digits "left" i right\n' + + ' DUP // digits "left" i right right\n' + + ' 10 PUSHINT // digits "left" i right right 10\n' + + ' MOD // digits "left" i right right%10\n' + + ' ISZERO // digits "left" i right right%10==0?\n' + + ' }>CONT\n' + + '\n' + + ' <{\n' + + ' // digits "left" i right\n' + + ' 10 PUSHINT // digits "left" i right 10\n' + + ' DIV // digits "left" i right/10\n' + + ' SWAP // digits "left" right/10 i\n' + + ' INC // digits "left" right/10 i+1\n' + + ' SWAP // digits "left" i+1 right/10\n' + + ' }>CONT\n' + + '\n' + + ' WHILE // digits "left" i right\n' + + '\n' + + ' <{\n' + + ' // x\n' + + ' NEWC // x b\n' + + ' SWAP // b x\n' + + '\n' + + ' <{\n' + + ' // b x\n' + + ' 10 PUSHINT DIVMOD // b x/10 x%10\n' + + ' 48 ADDCONST // b x/10 (x%10+48)\n' + + ' s2 s2 s0 XC2PU ISZERO // (x%10+48) b x/10 x/10==0?\n' + + ' }>CONT UNTIL\n' + + ' // ... b x\n' + + '\n' + + ' DROP // ... b\n' + + ' DEPTH DEC DUP // ... b n n\n' + + ' ROTREV // ... n b n\n' + + ' <{\n' + + ' // ... c n b\n' + + ' s1 s2 XCHG // ... n c b\n' + + ' 8 STU // ... n b\n' + + ' }>CONT REPEAT // n b\n' + + ' }>CONT 1 2 CALLXARGS\n' + + ' // digits "left" i right_digits "right"\n' + + ' ROTREV // digits "left" "right" i right_digits\n' + + ' ADD // digits "left" "right" right_digits\n' + + '\n' + + ' s3 s1 XCHG // "right" "left" digits right_digits\n' + + ' SUB // "right" "left" digits_diff\n' + + ' SWAP // "right" digits_diff "left"\n' + + ' x{2e} STSLICECONST // "right" digits_diff "left."\n' + + ' SWAP // "right" "left." digits_diff\n' + + '\n' + + ' <{\n' + + ' // "right" "left."\n' + + ' x{30} STSLICECONST // "right" "left.0"\n' + + ' }>CONT REPEAT // "right" "left.000"\n' + + '\n' + + ' STB // "left.000right"\n' + + ' }>CONT\n' + + '\n' + + ' IFELSE // b\n' + + '\n' + + ' ENDC CTOS // s\n' + + '}\n' + + '\n' + + '/// Extension function for the `Int` type.\n' + + '///\n' + + '/// Returns a `String` from an `Int` value using a [fixed-point representatio'... 6219 more characters, + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'beginString', + loc: { start: 329, end: 340 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 344, end: 357 } + }, + typeArgs: [], + loc: { start: 344, end: 357 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_string_builder_start_string', + loc: { start: 286, end: 320 } + } + }, + loc: { start: 280, end: 358 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'beginComment', + loc: { start: 830, end: 842 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 846, end: 859 } + }, + typeArgs: [], + loc: { start: 846, end: 859 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_string_builder_start_comment', + loc: { start: 786, end: 821 } + } + }, + loc: { start: 780, end: 860 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'beginTailString', + loc: { start: 1341, end: 1356 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 1360, end: 1373 } + }, + typeArgs: [], + loc: { start: 1360, end: 1373 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_string_builder_start_tail_string', + loc: { start: 1293, end: 1332 } + } + }, + loc: { start: 1287, end: 1374 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'beginStringFromBuilder', + loc: { start: 1836, end: 1858 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 1872, end: 1885 } + }, + typeArgs: [], + loc: { start: 1872, end: 1885 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'b', + loc: { start: 1859, end: 1860 } + }, + type: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 1862, end: 1869 } + }, + loc: { start: 1862, end: 1869 } + }, + loc: { start: 1859, end: 1869 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_string_builder_start', + loc: { start: 1800, end: 1827 } + } + }, + loc: { start: 1794, end: 1886 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'append', + loc: { start: 2328, end: 2334 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 's', + loc: { start: 2356, end: 2357 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 2359, end: 2365 } + }, + typeArgs: [], + loc: { start: 2359, end: 2365 } + }, + loc: { start: 2356, end: 2365 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_string_builder_append', + loc: { start: 2275, end: 2303 } + } + }, + loc: { start: 2269, end: 2367 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 2341, end: 2354 } + }, + typeArgs: [], + loc: { start: 2341, end: 2354 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'concat', + loc: { start: 2880, end: 2886 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 2920, end: 2933 } + }, + typeArgs: [], + loc: { start: 2920, end: 2933 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 's', + loc: { start: 2908, end: 2909 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 2911, end: 2917 } + }, + typeArgs: [], + loc: { start: 2911, end: 2917 } + }, + loc: { start: 2908, end: 2917 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_string_builder_append_not_mut', + loc: { start: 2827, end: 2863 } + } + }, + loc: { start: 2821, end: 2934 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 2893, end: 2906 } + }, + typeArgs: [], + loc: { start: 2893, end: 2906 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'toCell', + loc: { start: 3392, end: 3398 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 3421, end: 3425 } + }, + loc: { start: 3421, end: 3425 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_string_builder_end', + loc: { start: 3350, end: 3375 } + } + }, + loc: { start: 3344, end: 3426 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 3405, end: 3418 } + }, + typeArgs: [], + loc: { start: 3405, end: 3418 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'toString', + loc: { start: 3893, end: 3901 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 3924, end: 3930 } + }, + typeArgs: [], + loc: { start: 3924, end: 3930 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_string_builder_end_slice', + loc: { start: 3845, end: 3876 } + } + }, + loc: { start: 3839, end: 3931 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 3908, end: 3921 } + }, + typeArgs: [], + loc: { start: 3908, end: 3921 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'toSlice', + loc: { start: 4530, end: 4537 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 4560, end: 4565 } + }, + loc: { start: 4560, end: 4565 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_string_builder_end_slice', + loc: { start: 4482, end: 4513 } + } + }, + loc: { start: 4476, end: 4566 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 4544, end: 4557 } + }, + typeArgs: [], + loc: { start: 4544, end: 4557 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'toString', + loc: { start: 4950, end: 4958 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 4971, end: 4977 } + }, + typeArgs: [], + loc: { start: 4971, end: 4977 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '<{\n' + + ' // x\n' + + ' NEWC // x b\n' + + ' OVER // x b x\n' + + ' 0 LESSINT // x b <0?\n' + + ' <{\n' + + ' // x b\n' + + ' 45 PUSHINT // x b 45\n' + + ' SWAP // x 45 b\n' + + ' 8 STU // x b\n' + + ' SWAP // b x\n' + + ' NEGATE // b -x\n' + + ' SWAP // -x b\n' + + ' }>CONT IF\n' + + ' // x b\n' + + '\n' + + ' SWAP // b x\n' + + '\n' + + ' <{\n' + + ' // b x\n' + + ' 10 PUSHINT DIVMOD // b x/10 x%10\n' + + ' 48 ADDCONST // b x/10 (x%10+48)\n' + + ' s2 s2 s0 XC2PU ISZERO // (x%10+48) b x/10 x/10==0?\n' + + ' }>CONT UNTIL\n' + + ' // ... b x\n' + + '\n' + + ' DROP // ... b\n' + + ' DEPTH DEC // ... b n\n' + + ' <{ 8 STU }>CONT REPEAT // b\n' + + ' }>CONT 1 1 CALLXARGS\n' + + ' // b\n' + + '\n' + + ' ENDC CTOS // s' + ] + }, + loc: { start: 4934, end: 5692 } + } + }, + selfType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4965, end: 4968 } + }, + loc: { start: 4965, end: 4968 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'toFloatString', + loc: { start: 6527, end: 6540 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 6566, end: 6572 } + }, + typeArgs: [], + loc: { start: 6566, end: 6572 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'digits', + loc: { start: 6552, end: 6558 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6560, end: 6563 } + }, + loc: { start: 6560, end: 6563 } + }, + loc: { start: 6552, end: 6563 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'DUP // x digits digits\n' + + ' 1 LESSINT // x digits digits<=0\n' + + ' 134 THROWIF // x digits\n' + + ' DUP // x digits digits\n' + + ' 77 GTINT // x digits digits>77\n' + + ' 134 THROWIF // x digits\n' + + '\n' + + ' NEWC // x digits b\n' + + ' ROTREV // b x digits\n' + + ' s1 PUSH // b x digits x\n' + + ' 0 LESSINT // b x digits x<0?\n' + + '\n' + + ' <{\n' + + ' // b x digits\n' + + ' ROT // x digits b\n' + + ' x{2d} STSLICECONST // x digits b\n' + + ' ROT // digits b x\n' + + ' NEGATE // digits b -x\n' + + ' ROT // b -x digits\n' + + ' }>CONT IF\n' + + '\n' + + ' // b x digits\n' + + ' ONE // b x digits 1\n' + + ' OVER // b x digits 1 digits\n' + + '\n' + + ' <{ 10 MULCONST }>CONT REPEAT // b x digits 10^digits\n' + + '\n' + + ' s1 s2 XCHG // b digits x 10^digits\n' + + ' DIVMOD // b digits left right\n' + + ' s3 s3 XCHG2 // right digits b left\n' + + '\n' + + ' <{\n' + + ' // b x\n' + + '\n' + + ' <{\n' + + ' // b x\n' + + ' 10 PUSHINT DIVMOD // b x/10 x%10\n' + + ' 48 ADDCONST // b x/10 (x%10+48)\n' + + ' s2 s2 s0 XC2PU ISZERO // (x%10+48) b x/10 x/10==0?\n' + + ' }>CONT UNTIL\n' + + ' // ... b x\n' + + '\n' + + ' DROP // ... b\n' + + ' DEPTH DEC // ... b n\n' + + ' <{ 8 STU }>CONT REPEAT // b\n' + + ' }>CONT 2 1 CALLXARGS\n' + + '\n' + + ' // right digits "left"\n' + + '\n' + + ' ROT // digits "left" right\n' + + ' DUP // digits "left" right right\n' + + ' ISZERO // digits "left" right right==0?\n' + + '\n' + + ' <{\n' + + ' // digits "left" right\n' + + ' DROP // digits "left"\n' + + ' NIP // "left"\n' + + ' }>CONT\n' + + '\n' + + ' <{\n' + + ' // digits "left" right\n' + + ' ZERO // digits "left" right 0\n' + + ' SWAP // digits "left" 0 right\n' + + '\n' + + ' <{\n' + + ' // digits "left" i right\n' + + ' DUP // digits "left" i right right\n' + + ' 10 PUSHINT // digits "left" i right right 10\n' + + ' MOD // digits "left" i right right%10\n' + + ' ISZERO // digits "left" i right right%10==0?\n' + + ' }>CONT\n' + + '\n' + + ' <{\n' + + ' // digits "left" i right\n' + + ' 10 PUSHINT // digits "left" i right 10\n' + + ' DIV // digits "left" i right/10\n' + + ' SWAP // digits "left" right/10 i\n' + + ' INC // digits "left" right/10 i+1\n' + + ' SWAP // digits "left" i+1 right/10\n' + + ' }>CONT\n' + + '\n' + + ' WHILE // digits "left" i right\n' + + '\n' + + ' <{\n' + + ' // x\n' + + ' NEWC // x b\n' + + ' SWAP // b x\n' + + '\n' + + ' <{\n' + + ' // b x\n' + + ' 10 PUSHINT DIVMOD // b x/10 x%10\n' + + ' 48 ADDCONST // b x/10 (x%10+48)\n' + + ' s2 s2 s0 XC2PU ISZERO // (x%10+48) b x/10 x/10==0?\n' + + ' }>CONT UNTIL\n' + + ' // ... b x\n' + + '\n' + + ' DROP // ... b\n' + + ' DEPTH DEC DUP // ... b n n\n' + + ' ROTREV // ... n b n\n' + + ' <{\n' + + ' // ... c n b\n' + + ' s1 s2 XCHG // ... n c b\n' + + ' 8 STU // ... n b\n' + + ' }>CONT REPEAT // n b\n' + + ' }>CONT 1 2 CALLXARGS\n' + + ' // digits "left" i right_digits "right"\n' + + ' ROTREV // digits "left" "right" i right_digits\n' + + ' ADD // digits "left" "right" right_digits\n' + + '\n' + + ' s3 s1 XCHG // "right" "left" digits right_digits\n' + + ' SUB // "right" "left" digits_diff\n' + + ' SWAP // "right" digits_diff "left"\n' + + ' x{2e} STSLICECONST // "right" digits_diff "left."\n' + + ' SWAP // "right" "left." digits_diff\n' + + '\n' + + ' <{\n' + + ' // "right" "left."\n' + + ' x{30} STSLICECONST // "right" "left.0"\n' + + ' }>CONT REPEAT // "right" "left.000"\n' + + '\n' + + ' STB // "left.000right"\n' + + ' }>CONT\n' + + '\n' + + ' IFELSE // b\n' + + '\n' + + ' ENDC CTOS // s' + ] + }, + loc: { start: 6511, end: 9874 } + } + }, + selfType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6547, end: 6550 } + }, + loc: { start: 6547, end: 6550 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'toCoinsString', + loc: { start: 10653, end: 10666 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 10679, end: 10685 } + }, + typeArgs: [], + loc: { start: 10679, end: 10685 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 10699, end: 10703 } + }, + method: { + kind: 'id', + text: 'toFloatString', + loc: { start: 10704, end: 10717 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 9n, + loc: { start: 10718, end: 10719 } + } + ], + loc: { start: 10699, end: 10720 } + }, + loc: { start: 10692, end: 10721 } + } + ] + }, + loc: { start: 10634, end: 10723 } + } + }, + selfType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10673, end: 10676 } + }, + loc: { start: 10673, end: 10676 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'asComment', + loc: { start: 11442, end: 11451 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 11467, end: 11471 } + }, + loc: { start: 11467, end: 11471 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'b', + loc: { start: 11482, end: 11483 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StringBuilder', + loc: { start: 11485, end: 11498 } + }, + typeArgs: [], + loc: { start: 11485, end: 11498 } + }, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'beginComment', + loc: { start: 11501, end: 11513 } + }, + typeArgs: [], + args: [], + loc: { start: 11501, end: 11515 } + }, + loc: { start: 11478, end: 11516 } + }, + { + kind: 'statement_expression', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'b', + loc: { start: 11521, end: 11522 } + }, + method: { + kind: 'id', + text: 'append', + loc: { start: 11523, end: 11529 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'self', + loc: { start: 11530, end: 11534 } + } + ], + loc: { start: 11521, end: 11535 } + }, + loc: { start: 11521, end: 11536 } + }, + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'b', + loc: { start: 11548, end: 11549 } + }, + method: { + kind: 'id', + text: 'toCell', + loc: { start: 11550, end: 11556 } + }, + typeArgs: [], + args: [], + loc: { start: 11548, end: 11558 } + }, + loc: { start: 11541, end: 11559 } + } + ] + }, + loc: { start: 11430, end: 11561 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 11458, end: 11464 } + }, + typeArgs: [], + loc: { start: 11458, end: 11464 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'asSlice', + loc: { start: 12075, end: 12082 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 12098, end: 12103 } + }, + loc: { start: 12098, end: 12103 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_str_to_slice', + loc: { start: 12039, end: 12058 } + } + }, + loc: { start: 12033, end: 12104 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 12089, end: 12095 } + }, + typeArgs: [], + loc: { start: 12089, end: 12095 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'asString', + loc: { start: 12598, end: 12606 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 12621, end: 12627 } + }, + typeArgs: [], + loc: { start: 12621, end: 12627 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_slice_to_str', + loc: { start: 12562, end: 12581 } + } + }, + loc: { start: 12556, end: 12628 } + } + }, + selfType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 12613, end: 12618 } + }, + loc: { start: 12613, end: 12618 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'fromBase64', + loc: { start: 13537, end: 13547 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 13563, end: 13568 } + }, + loc: { start: 13563, end: 13568 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 13582, end: 13586 } + }, + method: { + kind: 'id', + text: 'asSlice', + loc: { start: 13587, end: 13594 } + }, + typeArgs: [], + args: [], + loc: { start: 13582, end: 13596 } + }, + method: { + kind: 'id', + text: 'fromBase64', + loc: { start: 13597, end: 13607 } + }, + typeArgs: [], + args: [], + loc: { start: 13582, end: 13609 } + }, + loc: { start: 13575, end: 13610 } + } + ] + }, + loc: { start: 13518, end: 13612 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 13554, end: 13560 } + }, + typeArgs: [], + loc: { start: 13554, end: 13560 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'fromBase64', + loc: { start: 14642, end: 14652 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 14667, end: 14672 } + }, + loc: { start: 14667, end: 14672 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'size', + loc: { start: 14683, end: 14687 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14689, end: 14692 } + }, + loc: { start: 14689, end: 14692 } + }, + expression: { + kind: 'op_binary', + op: '/', + left: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 14695, end: 14699 } + }, + method: { + kind: 'id', + text: 'bits', + loc: { start: 14700, end: 14704 } + }, + typeArgs: [], + args: [], + loc: { start: 14695, end: 14706 } + }, + right: { + kind: 'number', + base: '10', + value: 8n, + loc: { start: 14709, end: 14710 } + }, + loc: { start: 14695, end: 14710 } + }, + loc: { start: 14679, end: 14711 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'result', + loc: { start: 14720, end: 14726 } + }, + type: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 14728, end: 14735 } + }, + loc: { start: 14728, end: 14735 } + }, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'beginCell', + loc: { start: 14738, end: 14747 } + }, + typeArgs: [], + args: [], + loc: { start: 14738, end: 14749 } + }, + loc: { start: 14716, end: 14750 } + }, + { + kind: 'statement_repeat', + iterations: { + kind: 'var', + name: 'size', + loc: { start: 14764, end: 14768 } + }, + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'code', + loc: { start: 14784, end: 14788 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14790, end: 14793 } + }, + loc: { start: 14790, end: 14793 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 14796, end: 14800 } + }, + method: { + kind: 'id', + text: 'loadUint', + loc: { start: 14801, end: 14809 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 8n, + loc: { start: 14810, end: 14811 } + } + ], + loc: { start: 14796, end: 14812 } + }, + loc: { start: 14780, end: 14813 } + }, + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '&&', + left: { + kind: 'op_binary', + op: '>=', + left: { + kind: 'var', + name: 'code', + loc: { start: 14826, end: 14830 } + }, + right: { + kind: 'number', + base: '10', + value: 65n, + loc: { start: 14834, end: 14836 } + }, + loc: { start: 14826, end: 14836 } + }, + right: { + kind: 'op_binary', + op: '<=', + left: { + kind: 'var', + name: 'code', + loc: { start: 14840, end: 14844 } + }, + right: { + kind: 'number', + base: '10', + value: 90n, + loc: { start: 14848, end: 14850 } + }, + loc: { start: 14840, end: 14850 } + }, + loc: { start: 14826, end: 14850 } + }, + trueStatements: [ + { + kind: 'statement_assign', + path: { + kind: 'var', + name: 'result', + loc: { start: 14873, end: 14879 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'result', + loc: { + start: 14882, + end: 14888 + } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { + start: 14889, + end: 14898 + } + }, + typeArgs: [], + args: [ + { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'code', + loc: { + start: 14899, + end: 14903 + } + }, + right: { + kind: 'number', + base: '10', + value: 65n, + loc: { + start: 14906, + end: 14908 + } + }, + loc: { + start: 14899, + end: 14908 + } + }, + { + kind: 'number', + base: '10', + value: 6n, + loc: { + start: 14910, + end: 14911 + } + } + ], + loc: { start: 14882, end: 14912 } + }, + loc: { start: 14873, end: 14913 } + } + ], + falseStatements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '&&', + left: { + kind: 'op_binary', + op: '>=', + left: { + kind: 'var', + name: 'code', + loc: { + start: 14933, + end: 14937 + } + }, + right: { + kind: 'number', + base: '10', + value: 97n, + loc: { + start: 14941, + end: 14943 + } + }, + loc: { + start: 14933, + end: 14943 + } + }, + right: { + kind: 'op_binary', + op: '<=', + left: { + kind: 'var', + name: 'code', + loc: { + start: 14947, + end: 14951 + } + }, + right: { + kind: 'number', + base: '10', + value: 122n, + loc: { + start: 14955, + end: 14958 + } + }, + loc: { + start: 14947, + end: 14958 + } + }, + loc: { start: 14933, end: 14958 } + }, + trueStatements: [ + { + kind: 'statement_assign', + path: { + kind: 'var', + name: 'result', + loc: { + start: 14981, + end: 14987 + } + }, + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'result', + loc: { + start: 14990, + end: 14996 + } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { + start: 14997, + end: 15006 + } + }, + typeArgs: [], + args: [ + { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'code', + loc: { + start: 15007, + end: 15011 + } + }, + right: { + kind: 'op_binary', + op: '-', + left: { + kind: 'number', + base: '10', + value: 97n, + loc: { + start: 15015, + end: 15017 + } + }, + right: { + kind: 'number', + base: '10', + value: 26n, + loc: { + start: 15020, + end: 15022 + } + }, + loc: { + start: 15015, + end: 15022 + } + }, + loc: { + start: 15007, + end: 15023 + } + }, + { + kind: 'number', + base: '10', + value: 6n, + loc: { + start: 15025, + end: 15026 + } + } + ], + loc: { + start: 14990, + end: 15027 + } + }, + loc: { + start: 14981, + end: 15028 + } + } + ], + falseStatements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '&&', + left: { + kind: 'op_binary', + op: '>=', + left: { + kind: 'var', + name: 'code', + loc: { + start: 15048, + end: 15052 + } + }, + right: { + kind: 'number', + base: '10', + value: 48n, + loc: { + start: 15056, + end: 15058 + } + }, + loc: { + start: 15048, + end: 15058 + } + }, + right: { + kind: 'op_binary', + op: '<=', + left: { + kind: 'var', + name: 'code', + loc: { + start: 15062, + end: 15066 + } + }, + right: { + kind: 'number', + base: '10', + value: 57n, + loc: { + start: 15070, + end: 15072 + } + }, + loc: { + start: 15062, + end: 15072 + } + }, + loc: { + start: 15048, + end: 15072 + } + }, + trueStatements: [ + { + kind: 'statement_assign', + path: { + kind: 'var', + name: 'result', + loc: { + start: 15095, + end: 15101 + } + }, + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'result', + loc: { + start: 15104, + end: 15110 + } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { + start: 15111, + end: 15120 + } + }, + typeArgs: [], + args: [ + { + kind: 'op_binary', + op: '+', + left: { + kind: 'var', + name: 'code', + loc: { + start: 15121, + end: 15125 + } + }, + right: { + kind: 'op_binary', + op: '-', + left: { + kind: 'number', + base: '10', + value: 52n, + loc: { + start: 15129, + end: 15131 + } + }, + right: { + kind: 'number', + base: '10', + value: 48n, + loc: { + start: 15134, + end: 15136 + } + }, + loc: { + start: 15129, + end: 15136 + } + }, + loc: { + start: 15121, + end: 15137 + } + }, + { + kind: 'number', + base: '10', + value: 6n, + loc: { + start: 15139, + end: 15140 + } + } + ], + loc: { + start: 15104, + end: 15141 + } + }, + loc: { + start: 15095, + end: 15142 + } + } + ], + falseStatements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '||', + left: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'code', + loc: { + start: 15162, + end: 15166 + } + }, + right: { + kind: 'number', + base: '10', + value: 45n, + loc: { + start: 15170, + end: 15172 + } + }, + loc: { + start: 15162, + end: 15172 + } + }, + right: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'code', + loc: { + start: 15176, + end: 15180 + } + }, + right: { + kind: 'number', + base: '10', + value: 43n, + loc: { + start: 15184, + end: 15186 + } + }, + loc: { + start: 15176, + end: 15186 + } + }, + loc: { + start: 15162, + end: 15186 + } + }, + trueStatements: [ + { + kind: 'statement_assign', + path: { + kind: 'var', + name: 'result', + loc: { + start: 15212, + end: 15218 + } + }, + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'result', + loc: { + start: 15221, + end: 15227 + } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { + start: 15228, + end: 15237 + } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 62n, + loc: { + start: 15238, + end: 15240 + } + }, + { + kind: 'number', + base: '10', + value: 6n, + loc: { + start: 15242, + end: 15243 + } + } + ], + loc: { + start: 15221, + end: 15244 + } + }, + loc: { + start: 15212, + end: 15245 + } + } + ], + falseStatements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '||', + left: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'code', + loc: { + start: 15265, + end: 15269 + } + }, + right: { + kind: 'number', + base: '10', + value: 95n, + loc: { + start: 15273, + end: 15275 + } + }, + loc: { + start: 15265, + end: 15275 + } + }, + right: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'code', + loc: { + start: 15279, + end: 15283 + } + }, + right: { + kind: 'number', + base: '10', + value: 47n, + loc: { + start: 15287, + end: 15289 + } + }, + loc: { + start: 15279, + end: 15289 + } + }, + loc: { + start: 15265, + end: 15289 + } + }, + trueStatements: [ + { + kind: 'statement_assign', + path: { + kind: 'var', + name: 'result', + loc: { + start: 15315, + end: 15321 + } + }, + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'result', + loc: { + start: 15324, + end: 15330 + } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { + start: 15331, + end: 15340 + } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 63n, + loc: { + start: 15341, + end: 15343 + } + }, + { + kind: 'number', + base: '10', + value: 6n, + loc: { + start: 15345, + end: 15346 + } + } + ], + loc: { + start: 15324, + end: 15347 + } + }, + loc: { + start: 15315, + end: 15348 + } + } + ], + falseStatements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'code', + loc: { + start: 15368, + end: 15372 + } + }, + right: { + kind: 'number', + base: '10', + value: 61n, + loc: { + start: 15376, + end: 15378 + } + }, + loc: { + start: 15368, + end: 15378 + } + }, + trueStatements: [], + falseStatements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throw', + loc: { + start: 15436, + end: 15441 + } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'TactExitCodeInvalidArgument', + loc: { + start: 15442, + end: 15469 + } + } + ], + loc: { + start: 15436, + end: 15470 + } + }, + loc: { + start: 15436, + end: 15471 + } + } + ], + loc: { + start: 15364, + end: 15481 + } + } + ], + loc: { + start: 15261, + end: 15481 + } + } + ], + loc: { + start: 15158, + end: 15481 + } + } + ], + loc: { + start: 15044, + end: 15481 + } + } + ], + loc: { start: 14929, end: 15481 } + } + ], + loc: { start: 14822, end: 15481 } + } + ], + loc: { start: 14756, end: 15487 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'total', + loc: { start: 15512, end: 15517 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15519, end: 15522 } + }, + loc: { start: 15519, end: 15522 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'result', + loc: { start: 15525, end: 15531 } + }, + method: { + kind: 'id', + text: 'bits', + loc: { start: 15532, end: 15536 } + }, + typeArgs: [], + args: [], + loc: { start: 15525, end: 15538 } + }, + loc: { start: 15508, end: 15539 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'padding', + loc: { start: 15548, end: 15555 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15557, end: 15560 } + }, + loc: { start: 15557, end: 15560 } + }, + expression: { + kind: 'op_binary', + op: '%', + left: { + kind: 'var', + name: 'total', + loc: { start: 15563, end: 15568 } + }, + right: { + kind: 'number', + base: '10', + value: 8n, + loc: { start: 15571, end: 15572 } + }, + loc: { start: 15563, end: 15572 } + }, + loc: { start: 15544, end: 15573 } + }, + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '!=', + left: { + kind: 'var', + name: 'padding', + loc: { start: 15582, end: 15589 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15593, end: 15594 } + }, + loc: { start: 15582, end: 15594 } + }, + trueStatements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 's', + loc: { start: 15610, end: 15611 } + }, + type: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 15613, end: 15618 } + }, + loc: { start: 15613, end: 15618 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'result', + loc: { start: 15621, end: 15627 } + }, + method: { + kind: 'id', + text: 'asSlice', + loc: { start: 15628, end: 15635 } + }, + typeArgs: [], + args: [], + loc: { start: 15621, end: 15637 } + }, + loc: { start: 15606, end: 15638 } + }, + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 's', + loc: { start: 15654, end: 15655 } + }, + method: { + kind: 'id', + text: 'loadBits', + loc: { start: 15656, end: 15664 } + }, + typeArgs: [], + args: [ + { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'total', + loc: { + start: 15665, + end: 15670 + } + }, + right: { + kind: 'var', + name: 'padding', + loc: { + start: 15673, + end: 15680 + } + }, + loc: { start: 15665, end: 15680 } + } + ], + loc: { start: 15654, end: 15681 } + }, + loc: { start: 15647, end: 15682 } + } + ], + falseStatements: [ + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'result', + loc: { start: 15711, end: 15717 } + }, + method: { + kind: 'id', + text: 'asSlice', + loc: { start: 15718, end: 15725 } + }, + typeArgs: [], + args: [], + loc: { start: 15711, end: 15727 } + }, + loc: { start: 15704, end: 15728 } + } + ], + loc: { start: 15578, end: 15734 } + } + ] + }, + loc: { start: 14630, end: 15736 } + } + }, + selfType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 14659, end: 14664 } + }, + loc: { start: 14659, end: 14664 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'toString', + loc: { start: 16186, end: 16194 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'String', + loc: { start: 16211, end: 16217 } + }, + typeArgs: [], + loc: { start: 16211, end: 16217 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_address_to_user_friendly', + loc: { start: 16138, end: 16169 } + } + }, + loc: { start: 16132, end: 16218 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 16201, end: 16208 } + }, + typeArgs: [], + loc: { start: 16201, end: 16208 } + } + } + ] + }, + loc: { start: 119, end: 144 } + }, + { + kind: 'tact', + source: { + kind: 'tact', + path: 'std/internal/math.tact', + code: '// Prepare random\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Randomizes the pseudorandom number generator with the specified unsigned 256-bit `Int` `x` by mixing it with the current seed. The new seed is the unsigned 256-bit `Int` value of the SHA-256 hash of concatenated old seed and `x` in their 32-byte strings big-endian representation.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativeRandomize(42); // now, random numbers are less predictable\n' + + "/// let idk: Int = randomInt(); // ???, it's random,\n" + + '/// // but the seed was adjusted deterministically!\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify a negative value of `x`.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomize\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun nativeRandomize(x: Int) { ADDRAND }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Randomizes the random number generator with the logical time of the current transaction. Equivalent to calling `nativeRandomize(curLt())`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativeRandomizeLt(); // now, random numbers are unpredictable for users,\n' + + '/// // but still may be affected by validators or collators\n' + + '/// // as they determine the seed of the current block.\n' + + "/// let idk: Int = randomInt(); // ???, it's random!\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomizelt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomize\n' + + '/// * https://docs.tact-lang.org/ref/core-contextstate#curlt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + 'asm fun nativeRandomizeLt() { LTIME ADDRAND }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Prepares a random number generator by using `nativeRandomizeLt()`. Automatically called by `randomInt()` and `random()` functions.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// nativePrepareRandom(); // prepare the RNG\n' + + '/// // ... do your random things ...\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativepreparerandom\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomizelt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#randomint\n' + + '/// * https://docs.tact-lang.org/ref/core-random#random\n' + + '///\n' + + '@name(__tact_prepare_random)\n' + + 'native nativePrepareRandom();\n' + + '\n' + + '// Random\n' + + '\n' + + '// Generates a new pseudo-random unsigned 256-bit integer x.\n' + + '// The algorithm is as follows: if r is the old value of the random seed,\n' + + '// considered as a 32-byte array (by constructing the big-endian representation\n' + + '// of an unsigned 256-bit integer), then its sha512(r) is computed;\n' + + "// the first 32 bytes of this hash are stored as the new value r' of the random seed,\n" + + '// and the remaining 32 bytes are returned as the next random value x.\n' + + 'asm fun nativeRandom(): Int { RANDU256 }\n' + + '\n' + + '// Generates a new pseudo-random integer z in the range 0..range−1\n' + + '// (or range..−1, if range < 0).\n' + + '// More precisely, an unsigned random value x is generated as in `nativeRandom`;\n' + + '// then z := x * range / 2^256 is computed.\n' + + 'asm fun nativeRandomInterval(max: Int): Int { RAND }\n' + + '\n' + + '/// Generates and returns a new pseudo-random unsigned 256-bit `Int` value `x`.\n' + + '///\n' + + '/// The algorithm works as follows: first, the `sha512(r)` is computed. There, `r` is an old\n' + + '/// value of the random seed, which is taken as a 32-byte array constructed from the big-endian\n' + + '/// representation of an unsigned 256-bit `Int`. The first 32 bytes of this hash are stored as the new\n' + + "/// value `r'` of the random seed, and the remaining 32 bytes are returned as the next random value `x`.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + "/// let allYourRandomBelongToUs: Int = randomInt(); // ???, it's random :)\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-random#randomint\n' + + '///\n' + + 'inline fun randomInt(): Int {\n' + + ' nativePrepareRandom();\n' + + ' return nativeRandom();\n' + + '}\n' + + '\n' + + '/// Generates and returns a new pseudo-random unsigned `Int` value `x` in the provided semi-closed\n' + + '/// interval: `min` ≤ `x` < `max`, or `min` ≥ `x` > `max` if both `min` and `max` are negative.\n' + + '///\n' + + '/// Note that the `max` value is never included in the interval.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// random(42, 43); // 42, always\n' + + '/// random(0, 42); // 0-41, but never 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-random#random\n' + + '///\n' + + 'inline fun random(min: Int, max: Int): Int {\n' + + ' nativePrepareRandom();\n' + + ' return min + nativeRandomInterval(max - min);\n' + + '}\n' + + '\n' + + '// Math\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the minimum of two `Int` values `x` and `y`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// min(1, 2); // 1\n' + + '/// min(2, 2); // 2\n' + + '/// min(007, 3); // 3\n' + + '/// min(0x45, 3_0_0); // 69, nice\n' + + '/// // ↑ ↑\n' + + '/// // 69 300\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#min\n' + + '///\n' + + 'asm fun min(x: Int, y: Int): Int { MIN }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the maximum of two `Int` values `x` and `y`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// max(1, 2); // 2\n' + + '/// max(2, 2); // 2\n' + + '/// max(007, 3); // 7\n' + + '/// max(0x45, 3_0_0); // 300\n' + + '/// // ↑ ↑\n' + + '/// // 69 300\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#max\n' + + '///\n' + + 'asm fun max(x: Int, y: Int): Int { MAX }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the absolute value of the `Int` value `x`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// abs(42); // 42\n' + + '/// abs(-42); // 42\n' + + '/// abs(-(-(-42))); // 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-math#abs\n' + + '///\n' + + 'asm fun abs(x: Int): Int { ABS }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the logarithm of a number `num` > 0 to the base `base` ≥ 1. Results are rounded down.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// log(1000, 10); // 3, as 10^3 is 1000\n' + + '/// // ↑ ↑ ↑ ↑\n' + + '/// // num base base num\n' + + '///\n' + + '/// log(1001, 10); // 3\n' + + '/// log(999, 10); // 2\n' + + '/// try {\n' + + '/// log(-1000, 10); // exit code 5 because of the non-positive num\n' + + '/// }\n' + + '/// log(1024, 2); // 10\n' + + '/// try {\n' + + '/// log(1024, -2); // exit code 5 because the base is less than 1\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `num` value is non-positive\n' + + '/// or the given `base` value is less than 1.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log2\n' + + '///\n' + + '@name(__tact_log)\n' + + 'native log(num: Int, base: Int): Int;\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Similar to `log()`, but sets the `base` to 2.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// log2(1024); // 10, as 2^10 is 1024\n' + + '/// // ↑ ↑ ↑\n' + + '/// // num base₂ num\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `num` value is non-positive.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log2\n' + + '/// * https://docs.tact-lang.org/ref/core-math#log.\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes/#5\n' + + '///\n' + + 'asm fun log2(num: Int): Int { DUP 5 THROWIFNOT UBITSIZE DEC }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Computes and returns the exponentiation involving two numbers: the `base` and the exponent (or _power_) `exp`.\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Example {\n' + + '/// // Persistent state variables\n' + + '/// p23: Int = pow(2, 3); // raises 2 to the 3rd power, which is 8\n' + + '/// one: Int = pow(5, 0); // raises 5 to the power 0, which always produces 1\n' + + '/// // works at compile-time!\n' + + '///\n' + + '/// // Internal message receiver\n' + + '/// receive() {\n' + + '/// pow(self.p23, self.one + 1); // 64, works at run-time too!\n' + + '/// try {\n' + + '/// pow(0, -1); // exit code 5: Integer out of expected range\n' + + '/// }\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when the given `exp` value is negative.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow2\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes/#5\n' + + '///\n' + + 'inline fun pow(base: Int, exp: Int): Int {\n' + + ' throwUnless(5, exp >= 0);\n' + + ' let result = 1;\n' + + ' repeat (exp) {\n' + + ' result *= base;\n' + + ' }\n' + + ' return result;\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Similar to `pow()`, but sets the `base` to 2.\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Example {\n' + + '/// // Persistent state variables\n' + + '/// p23: Int = pow2(3); // raises 2 to the 3rd power, which is 8\n' + + '/// one: Int = pow2(0); // raises 2 to the power 0, which always produces 1\n' + + '/// // works at compile-time!\n' + + '///\n' + + '/// // Internal message receiver, which accepts message ExtMsg\n' + + '/// receive() {\n' + + '/// pow2(self.one + 1); // 4, works at run-time too!\n' + + '/// try {\n' + + '/// pow(-1); // exit code 5: Integer out of expected range\n' + + '/// }\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify a negative value of `exp`.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow2\n' + + '/// * https://docs.tact-lang.org/ref/core-math#pow\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun pow2(exp: Int): Int { POW2 }\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Computes and returns the sign of the `Int` value `x`. Produces 1 if the `x` is positive, -1 if the `x` is negative, and 0 if the `x` is 0.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun examples() {\n' + + '/// '... 5983 more characters, + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomize', + loc: { start: 965, end: 980 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 981, end: 982 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 984, end: 987 } + }, + loc: { start: 984, end: 987 } + }, + loc: { start: 981, end: 987 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ADDRAND' ] + }, + loc: { start: 957, end: 1000 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomizeLt', + loc: { start: 1822, end: 1839 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LTIME ADDRAND' ] + }, + loc: { start: 1814, end: 1859 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 2466, end: 2485 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_prepare_random', + loc: { start: 2436, end: 2457 } + } + }, + loc: { start: 2430, end: 2488 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandom', + loc: { start: 2949, end: 2961 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2965, end: 2968 } + }, + loc: { start: 2965, end: 2968 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RANDU256' ] + }, + loc: { start: 2941, end: 2981 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeRandomInterval', + loc: { start: 3216, end: 3236 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3248, end: 3251 } + }, + loc: { start: 3248, end: 3251 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'max', + loc: { start: 3237, end: 3240 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3242, end: 3245 } + }, + loc: { start: 3242, end: 3245 } + }, + loc: { start: 3237, end: 3245 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RAND' ] + }, + loc: { start: 3208, end: 3260 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'randomInt', + loc: { start: 3953, end: 3962 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3966, end: 3969 } + }, + loc: { start: 3966, end: 3969 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 3976, end: 3995 } + }, + typeArgs: [], + args: [], + loc: { start: 3976, end: 3997 } + }, + loc: { start: 3976, end: 3998 } + }, + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativeRandom', + loc: { start: 4010, end: 4022 } + }, + typeArgs: [], + args: [], + loc: { start: 4010, end: 4024 } + }, + loc: { start: 4003, end: 4025 } + } + ] + }, + loc: { start: 3942, end: 4027 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'random', + loc: { start: 4505, end: 4511 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4533, end: 4536 } + }, + loc: { start: 4533, end: 4536 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'min', + loc: { start: 4512, end: 4515 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4517, end: 4520 } + }, + loc: { start: 4517, end: 4520 } + }, + loc: { start: 4512, end: 4520 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'max', + loc: { start: 4522, end: 4525 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4527, end: 4530 } + }, + loc: { start: 4527, end: 4530 } + }, + loc: { start: 4522, end: 4530 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativePrepareRandom', + loc: { start: 4543, end: 4562 } + }, + typeArgs: [], + args: [], + loc: { start: 4543, end: 4564 } + }, + loc: { start: 4543, end: 4565 } + }, + { + kind: 'statement_return', + expression: { + kind: 'op_binary', + op: '+', + left: { + kind: 'var', + name: 'min', + loc: { start: 4577, end: 4580 } + }, + right: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativeRandomInterval', + loc: { start: 4583, end: 4603 } + }, + typeArgs: [], + args: [ + { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'max', + loc: { start: 4604, end: 4607 } + }, + right: { + kind: 'var', + name: 'min', + loc: { start: 4610, end: 4613 } + }, + loc: { start: 4604, end: 4613 } + } + ], + loc: { start: 4583, end: 4614 } + }, + loc: { start: 4577, end: 4614 } + }, + loc: { start: 4570, end: 4615 } + } + ] + }, + loc: { start: 4494, end: 4617 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'min', + loc: { start: 5017, end: 5020 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5038, end: 5041 } + }, + loc: { start: 5038, end: 5041 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5021, end: 5022 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5024, end: 5027 } + }, + loc: { start: 5024, end: 5027 } + }, + loc: { start: 5021, end: 5027 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 5029, end: 5030 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5032, end: 5035 } + }, + loc: { start: 5032, end: 5035 } + }, + loc: { start: 5029, end: 5035 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MIN' ] + }, + loc: { start: 5009, end: 5049 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'max', + loc: { start: 5435, end: 5438 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5456, end: 5459 } + }, + loc: { start: 5456, end: 5459 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5439, end: 5440 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5442, end: 5445 } + }, + loc: { start: 5442, end: 5445 } + }, + loc: { start: 5439, end: 5445 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 5447, end: 5448 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5450, end: 5453 } + }, + loc: { start: 5450, end: 5453 } + }, + loc: { start: 5447, end: 5453 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MAX' ] + }, + loc: { start: 5427, end: 5467 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'abs', + loc: { start: 5773, end: 5776 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5786, end: 5789 } + }, + loc: { start: 5786, end: 5789 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 5777, end: 5778 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 5780, end: 5783 } + }, + loc: { start: 5780, end: 5783 } + }, + loc: { start: 5777, end: 5783 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ABS' ] + }, + loc: { start: 5765, end: 5797 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'log', + loc: { start: 6721, end: 6724 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6747, end: 6750 } + }, + loc: { start: 6747, end: 6750 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 6725, end: 6728 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6730, end: 6733 } + }, + loc: { start: 6730, end: 6733 } + }, + loc: { start: 6725, end: 6733 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'base', + loc: { start: 6735, end: 6739 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6741, end: 6744 } + }, + loc: { start: 6741, end: 6744 } + }, + loc: { start: 6735, end: 6744 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_log', + loc: { start: 6702, end: 6712 } + } + }, + loc: { start: 6696, end: 6751 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'log2', + loc: { start: 7341, end: 7345 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7357, end: 7360 } + }, + loc: { start: 7357, end: 7360 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 7346, end: 7349 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7351, end: 7354 } + }, + loc: { start: 7351, end: 7354 } + }, + loc: { start: 7346, end: 7354 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DUP 5 THROWIFNOT UBITSIZE DEC' ] + }, + loc: { start: 7333, end: 7394 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'pow', + loc: { start: 8510, end: 8513 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8536, end: 8539 } + }, + loc: { start: 8536, end: 8539 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'base', + loc: { start: 8514, end: 8518 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8520, end: 8523 } + }, + loc: { start: 8520, end: 8523 } + }, + loc: { start: 8514, end: 8523 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'exp', + loc: { start: 8525, end: 8528 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8530, end: 8533 } + }, + loc: { start: 8530, end: 8533 } + }, + loc: { start: 8525, end: 8533 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throwUnless', + loc: { start: 8546, end: 8557 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 5n, + loc: { start: 8558, end: 8559 } + }, + { + kind: 'op_binary', + op: '>=', + left: { + kind: 'var', + name: 'exp', + loc: { start: 8561, end: 8564 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 8568, end: 8569 } + }, + loc: { start: 8561, end: 8569 } + } + ], + loc: { start: 8546, end: 8570 } + }, + loc: { start: 8546, end: 8571 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'result', + loc: { start: 8580, end: 8586 } + }, + type: undefined, + expression: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 8589, end: 8590 } + }, + loc: { start: 8576, end: 8591 } + }, + { + kind: 'statement_repeat', + iterations: { + kind: 'var', + name: 'exp', + loc: { start: 8604, end: 8607 } + }, + statements: [ + { + kind: 'statement_augmentedassign', + op: '*=', + path: { + kind: 'var', + name: 'result', + loc: { start: 8619, end: 8625 } + }, + expression: { + kind: 'var', + name: 'base', + loc: { start: 8629, end: 8633 } + }, + loc: { start: 8619, end: 8634 } + } + ], + loc: { start: 8596, end: 8640 } + }, + { + kind: 'statement_return', + expression: { + kind: 'var', + name: 'result', + loc: { start: 8652, end: 8658 } + }, + loc: { start: 8645, end: 8659 } + } + ] + }, + loc: { start: 8499, end: 8661 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'pow2', + loc: { start: 9733, end: 9737 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9749, end: 9752 } + }, + loc: { start: 9749, end: 9752 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'exp', + loc: { start: 9738, end: 9741 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9743, end: 9746 } + }, + loc: { start: 9743, end: 9746 } + }, + loc: { start: 9738, end: 9746 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'POW2' ] + }, + loc: { start: 9725, end: 9761 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sign', + loc: { start: 10233, end: 10237 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10247, end: 10250 } + }, + loc: { start: 10247, end: 10250 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 10238, end: 10239 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10241, end: 10244 } + }, + loc: { start: 10241, end: 10244 } + }, + loc: { start: 10238, end: 10244 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SGN' ] + }, + loc: { start: 10225, end: 10258 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'divc', + loc: { start: 10814, end: 10818 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10836, end: 10839 } + }, + loc: { start: 10836, end: 10839 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 10819, end: 10820 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10822, end: 10825 } + }, + loc: { start: 10822, end: 10825 } + }, + loc: { start: 10819, end: 10825 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 10827, end: 10828 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10830, end: 10833 } + }, + loc: { start: 10830, end: 10833 } + }, + loc: { start: 10827, end: 10833 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DIVC' ] + }, + loc: { start: 10806, end: 10848 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'muldivc', + loc: { start: 11615, end: 11622 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11648, end: 11651 } + }, + loc: { start: 11648, end: 11651 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 11623, end: 11624 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11626, end: 11629 } + }, + loc: { start: 11626, end: 11629 } + }, + loc: { start: 11623, end: 11629 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 11631, end: 11632 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11634, end: 11637 } + }, + loc: { start: 11634, end: 11637 } + }, + loc: { start: 11631, end: 11637 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 11639, end: 11640 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 11642, end: 11645 } + }, + loc: { start: 11642, end: 11645 } + }, + loc: { start: 11639, end: 11645 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULDIVC' ] + }, + loc: { start: 11607, end: 11663 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRight', + loc: { start: 12751, end: 12764 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12790, end: 12793 } + }, + loc: { start: 12790, end: 12793 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 12765, end: 12766 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12768, end: 12771 } + }, + loc: { start: 12768, end: 12771 } + }, + loc: { start: 12765, end: 12771 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 12773, end: 12774 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12776, end: 12779 } + }, + loc: { start: 12776, end: 12779 } + }, + loc: { start: 12773, end: 12779 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 12781, end: 12782 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12784, end: 12787 } + }, + loc: { start: 12784, end: 12787 } + }, + loc: { start: 12781, end: 12787 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFT' ] + }, + loc: { start: 12743, end: 12807 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRightRound', + loc: { start: 13862, end: 13880 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13906, end: 13909 } + }, + loc: { start: 13906, end: 13909 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 13881, end: 13882 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13884, end: 13887 } + }, + loc: { start: 13884, end: 13887 } + }, + loc: { start: 13881, end: 13887 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 13889, end: 13890 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13892, end: 13895 } + }, + loc: { start: 13892, end: 13895 } + }, + loc: { start: 13889, end: 13895 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 13897, end: 13898 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13900, end: 13903 } + }, + loc: { start: 13900, end: 13903 } + }, + loc: { start: 13897, end: 13903 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFTR' ] + }, + loc: { start: 13854, end: 13924 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'mulShiftRightCeil', + loc: { start: 14875, end: 14892 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14918, end: 14921 } + }, + loc: { start: 14918, end: 14921 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'x', + loc: { start: 14893, end: 14894 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14896, end: 14899 } + }, + loc: { start: 14896, end: 14899 } + }, + loc: { start: 14893, end: 14899 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'y', + loc: { start: 14901, end: 14902 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14904, end: 14907 } + }, + loc: { start: 14904, end: 14907 } + }, + loc: { start: 14901, end: 14907 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'z', + loc: { start: 14909, end: 14910 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14912, end: 14915 } + }, + loc: { start: 14912, end: 14915 } + }, + loc: { start: 14909, end: 14915 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MULRSHIFTC' ] + }, + loc: { start: 14867, end: 14936 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sqrt', + loc: { start: 15698, end: 15702 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15714, end: 15717 } + }, + loc: { start: 15714, end: 15717 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'num', + loc: { start: 15703, end: 15706 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15708, end: 15711 } + }, + loc: { start: 15708, end: 15711 } + }, + loc: { start: 15703, end: 15711 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'num', + loc: { start: 15728, end: 15731 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15735, end: 15736 } + }, + loc: { start: 15728, end: 15736 } + }, + trueStatements: [ + { + kind: 'statement_return', + expression: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15755, end: 15756 } + }, + loc: { start: 15748, end: 15757 } + } + ], + falseStatements: undefined, + loc: { start: 15724, end: 15763 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 's', + loc: { start: 15773, end: 15774 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15776, end: 15779 } + }, + loc: { start: 15776, end: 15779 } + }, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'log2', + loc: { start: 15782, end: 15786 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'num', + loc: { start: 15787, end: 15790 } + } + ], + loc: { start: 15782, end: 15791 } + }, + loc: { start: 15769, end: 15792 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'x', + loc: { start: 15801, end: 15802 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15804, end: 15807 } + }, + loc: { start: 15804, end: 15807 } + }, + expression: { + kind: 'conditional', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 's', + loc: { start: 15811, end: 15812 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15816, end: 15817 } + }, + loc: { start: 15811, end: 15817 } + }, + thenBranch: { + kind: 'op_binary', + op: '+', + left: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'num', + loc: { start: 15821, end: 15824 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15827, end: 15828 } + }, + loc: { start: 15821, end: 15828 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15832, end: 15833 } + }, + loc: { start: 15820, end: 15833 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15836, end: 15837 } + }, + loc: { start: 15820, end: 15837 } + }, + elseBranch: { + kind: 'op_binary', + op: '<<', + left: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15840, end: 15841 } + }, + right: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '+', + left: { + kind: 'var', + name: 's', + loc: { start: 15847, end: 15848 } + }, + right: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 15851, end: 15852 } + }, + loc: { start: 15847, end: 15852 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15856, end: 15857 } + }, + loc: { start: 15846, end: 15857 } + }, + loc: { start: 15840, end: 15858 } + }, + loc: { start: 15811, end: 15858 } + }, + loc: { start: 15797, end: 15860 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'q', + loc: { start: 15870, end: 15871 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15873, end: 15876 } + }, + loc: { start: 15873, end: 15876 } + }, + expression: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15879, end: 15880 } + }, + loc: { start: 15866, end: 15881 } + }, + { + kind: 'statement_until', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'q', + loc: { start: 15957, end: 15958 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 15962, end: 15963 } + }, + loc: { start: 15957, end: 15963 } + }, + statements: [ + { + kind: 'statement_assign', + path: { + kind: 'var', + name: 'q', + loc: { start: 15900, end: 15901 } + }, + expression: { + kind: 'op_binary', + op: '/', + left: { + kind: 'op_binary', + op: '-', + left: { + kind: 'static_call', + function: { + kind: 'id', + text: 'divc', + loc: { start: 15905, end: 15909 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'num', + loc: { start: 15910, end: 15913 } + }, + { + kind: 'var', + name: 'x', + loc: { start: 15915, end: 15916 } + } + ], + loc: { start: 15905, end: 15917 } + }, + right: { + kind: 'var', + name: 'x', + loc: { start: 15920, end: 15921 } + }, + loc: { start: 15905, end: 15921 } + }, + right: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 15925, end: 15926 } + }, + loc: { start: 15904, end: 15926 } + }, + loc: { start: 15900, end: 15927 } + }, + { + kind: 'statement_augmentedassign', + op: '+=', + path: { + kind: 'var', + name: 'x', + loc: { start: 15936, end: 15937 } + }, + expression: { + kind: 'var', + name: 'q', + loc: { start: 15941, end: 15942 } + }, + loc: { start: 15936, end: 15943 } + } + ], + loc: { start: 15887, end: 15965 } + }, + { + kind: 'statement_return', + expression: { + kind: 'var', + name: 'x', + loc: { start: 15978, end: 15979 } + }, + loc: { start: 15971, end: 15980 } + } + ] + }, + loc: { start: 15694, end: 15982 } + } + ] + }, + loc: { start: 145, end: 170 } + }, + { + kind: 'tact', + source: { + kind: 'tact', + path: 'std/internal/contract.tact', + code: '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Computes and returns an `Int` value of the SHA-256 hash of the `code` and `data` of the given contract. To assemble the `code` and `data` cells together for hashing, the standard `Cell` representation is used.\n' + + '///\n' + + '/// This hash is commonly called account ID. Together with the workchain ID it deterministically forms the address of the contract on TON Blockchain.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let initPkg: StateInit = initOf SomeContract();\n' + + '/// let accountId: Int = contractHash(initPkg.code, initPkg.data);\n' + + '/// let basechainAddr: Address = newAddress(0, accountId);\n' + + '/// let basechainAddr2: Address = contractAddressExt(0, initPkg.code, initPkg.data);\n' + + '///\n' + + '/// basechainAddr == basechainAddr2; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contracthash\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#newaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '///\n' + + 'asm fun contractHash(code: Cell, data: Cell): Int {\n' + + ' // According to the https://docs.tact-lang.org/book/cells#cells-representation,\n' + + ' // the layout for the Builder to hash goes as follows:\n' + + ' // 1) refs_descriptor:bits8 | bits_descriptor:bits8 | data:bitsN\n' + + ' //\n' + + ' // refs_descriptor: ref_count + ((exotic? & 1) * 8) + (mask * 32)\n' + + ' // 2 refs (code + data), non-exotic, zero-mask\n' + + ' //\n' + + ' // bits_descriptor: floor(bit_count / 8) + ceil(bit_count, 8)\n' + + ' // floor (5 bits / 8) + ceil(5 bits / 8) = 0 + 1 = 1\n' + + ' //\n' + + ' // data: [0b00110] + [0b100] = [0b00110100] = 0x34 (data + augmented bits)\n' + + ' // 0b00110 - data (split_depth, special, code, data, Library)\n' + + ' // 0b100 - augmented bits (Leading 1 + zeroes to make section multiple of eight)\n' + + ' //\n' + + ' // That is: (2 << 16) | (1 << 8) | 0x34 = 131380 for all three.\n' + + ' //\n' + + ' // 2) and 3) depth_descriptors: CDEPTH of `code` and CDEPTH of `data`\n' + + ' // 4) and 5) ref hashes: HASHCU of `code` and HASHCU of `data`\n' + + '\n' + + ' // Group 1: Computations and arrangements\n' + + ' s0 PUSH HASHCU // `data` hash\n' + + ' s2 PUSH HASHCU // `code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `code` depth\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + '\n' + + ' // Group 2: Composition of the Builder\n' + + ' NEWC\n' + + ' 24 STU // store refs_descriptor | bits_descriptor | data\n' + + ' 16 STU // store depth_descriptor for `code`\n' + + ' 16 STU // store depth_descriptor for `data`\n' + + ' 256 STU // store `code` hash\n' + + ' 256 STU // store `data` hash\n' + + '\n' + + ' // Group 3: SHA256 hash of the resulting Builder\n' + + ' ONE HASHEXT_SHA256\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + "/// Computes smart contract's `Address` in the `chain` ID using the contract's `code` and the contract's initial state `data`. Use the `initOf` expression to obtain the initial `code` and initial `data` of a given contract.\n" + + '///\n' + + '/// This function lets you specify arbitrary `chain` IDs, including the common -1 (masterchain) and 0 (basechain) ones.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let initPkg: StateInit = initOf SomeContract();\n' + + '/// let hereBeDragons: Address = contractAddressExt(0, initPkg.code, initPkg.data);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '/// * https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'inline fun contractAddressExt(chain: Int, code: Cell, data: Cell): Address {\n' + + ' let hash = contractHash(code, data);\n' + + ' return newAddress(chain, hash);\n' + + '}\n' + + '\n' + + '/// Struct containing the initial state, i.e. initial code and initial data of the given contract upon its deployment.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'struct StateInit {\n' + + ' /// Initial code of the contract (compiled bitcode)\n' + + ' code: Cell;\n' + + '\n' + + ' /// Initial data of the contract (parameters of `init()` function or contract parameters)\n' + + ' data: Cell;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.1.\n' + + '///\n' + + '/// Efficiently compares if the given address matches the basechain address of the contract.\n' + + '/// Returns true if addresses are the same, false otherwise.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let init = initOf SomeContract();\n' + + "/// init.hasSameBasechainAddress(sender()); // returns true if sender matches contract's basechain address\n" + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// This function provides a gas-optimized implementation compared to direct address comparison:\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let init = initOf SomeContract();\n' + + '/// sender() == contractAddress(sender()); // less efficient approach\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// Note that this function works only for basechain addresses!\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddress\n' + + '///\n' + + 'inline extends fun hasSameBasechainAddress(self: StateInit, sender: Address): Bool {\n' + + ' let senderAddress = parseStdAddress(sender.asSlice()).address;\n' + + ' let baseAddress = contractBasechainAddress(self);\n' + + ' return baseAddress.hash!! == senderAddress;\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + "/// Computes smart contract's `Address` in the workchain ID 0 (basechain) using the `StateInit` `s` of the contract. Alias to `contractAddressExt(0, s.code, s.data)`.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let s: StateInit = initOf SomeContract();\n' + + '/// let foundMeSome: Address = contractAddress(s);\n' + + '/// let andSomeMore: Address = contractAddressExt(0, s.code, s.data);\n' + + '///\n' + + '/// foundMeSome == andSomeMore; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#contractaddressext\n' + + '/// * https://docs.tact-lang.org/book/expressions#initof\n' + + '///\n' + + 'inline fun contractAddress(s: StateInit): Address {\n' + + ' return contractAddressExt(0, s.code, s.data);\n' + + '}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Returns the address of the current smart contract as an `Address`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let meMyselfAndI: Address = myAddress();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#myaddress\n' + + '///\n' + + 'asm fun myAddress(): Address { MYADDR }\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` balance of the smart contract as it was at the start of the compute phase of the current transaction.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let iNeedADolla: Int = myBalance();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#mybalance\n' + + '///\n' + + 'asm fun myBalance(): Int { BALANCE FIRST }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` amount of gas consumed by TVM in the current transaction so far. The resulting value includes the cost of calling this function.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let gas: Int = gasConsumed();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#gasconsumed\n' + + '///\n' + + 'asm fun gasConsumed(): Int { GASCONSUMED }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Returns the nanoToncoin `Int` amount of the accumulated storage fee debt. Storage fees are deducted from the incoming message value before the new contract balance is calculated.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let debt: Int = myStorageDue();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#mystoragedue\n' + + '///\n' + + 'asm fun myStorageDue(): Int { DUEPAYMENT }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Calculates and returns the storage fee in nanoToncoins `Int` for storing a contract with a given number of `cells` and `bits` for a number of `seconds`. Uses the prices of the masterchain if `isMasterchain` is `true`, otherwise the prices of the basechain. The current prices are obtained from the config param 18 of TON Blockchain.\n' + + '///\n' + + '/// Note, that specifying values of `cells` and `bits` higher than their maximum values listed in account state limits (`max_acc_state_cells` and `max_acc_state_bits`) will have the same result as with specifying the exact limits. In addition, make sure you take into account the deduplication of cells with the same hash.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fee: Int = getStorageFee(1_000, 1_000, 1_000, false);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify negative number of `cells`, `bits` or `seconds`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-gas#getstoragefee\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun getStorageFee(cells: Int, bits: Int, seconds: Int, isMasterchain: Bool): Int { GETSTORAGEFEE }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Calculates and returns the compute fee in nanoToncoins `Int` for a transaction that consumed `gasUsed` amount of gas. Uses the prices of the masterchain if `isMasterchain` is `true`, otherwise the prices of the basechain. The current prices are obtained from the config param 20 for the masterchain and config param 21 for the basechain of TON Blockchain.\n' + + '///\n' + + "/// When the `gasUsed` is less than a certain threshold called `flat_gas_limit`, there's a minimum price to pay based on the value of `flat_gas_price`. The less gas is used below this threshold, the higher the minimum price will be. See the example for `getSimpleComputeFee()` to derive that threshold.\n" + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fee: Int = getComputeFee(1_000, false);\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify negative value of `gasUsed`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-gas#getcomputefee\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + 'asm fun getComputeFee(gasUsed: Int, isMasterchain: Bool): Int { GETGASFEE }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Similar to `getComputeFee()`, but without the `flat_gas_price`, i.e. without a minimum price to pay if the `gasUsed` is less than a certain '... 8611 more characters, + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'contractHash', + loc: { start: 1027, end: 1039 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1065, end: 1068 } + }, + loc: { start: 1065, end: 1068 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 1040, end: 1044 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 1046, end: 1050 } + }, + loc: { start: 1046, end: 1050 } + }, + loc: { start: 1040, end: 1050 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'data', + loc: { start: 1052, end: 1056 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 1058, end: 1062 } + }, + loc: { start: 1058, end: 1062 } + }, + loc: { start: 1052, end: 1062 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 's0 PUSH HASHCU // `data` hash\n' + + ' s2 PUSH HASHCU // `code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `code` depth\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + '\n' + + ' // Group 2: Composition of the Builder\n' + + ' NEWC\n' + + ' 24 STU // store refs_descriptor | bits_descriptor | data\n' + + ' 16 STU // store depth_descriptor for `code`\n' + + ' 16 STU // store depth_descriptor for `data`\n' + + ' 256 STU // store `code` hash\n' + + ' 256 STU // store `data` hash\n' + + '\n' + + ' // Group 3: SHA256 hash of the resulting Builder\n' + + ' ONE HASHEXT_SHA256' + ] + }, + loc: { start: 1019, end: 2666 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'contractAddressExt', + loc: { start: 3391, end: 3409 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3447, end: 3454 } + }, + typeArgs: [], + loc: { start: 3447, end: 3454 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'chain', + loc: { start: 3410, end: 3415 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3417, end: 3420 } + }, + loc: { start: 3417, end: 3420 } + }, + loc: { start: 3410, end: 3420 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 3422, end: 3426 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 3428, end: 3432 } + }, + loc: { start: 3428, end: 3432 } + }, + loc: { start: 3422, end: 3432 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'data', + loc: { start: 3434, end: 3438 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 3440, end: 3444 } + }, + loc: { start: 3440, end: 3444 } + }, + loc: { start: 3434, end: 3444 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'hash', + loc: { start: 3465, end: 3469 } + }, + type: undefined, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractHash', + loc: { start: 3472, end: 3484 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'code', + loc: { start: 3485, end: 3489 } + }, + { + kind: 'var', + name: 'data', + loc: { start: 3491, end: 3495 } + } + ], + loc: { start: 3472, end: 3496 } + }, + loc: { start: 3461, end: 3497 } + }, + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'newAddress', + loc: { start: 3509, end: 3519 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'chain', + loc: { start: 3520, end: 3525 } + }, + { + kind: 'var', + name: 'hash', + loc: { start: 3527, end: 3531 } + } + ], + loc: { start: 3509, end: 3532 } + }, + loc: { start: 3502, end: 3533 } + } + ] + }, + loc: { start: 3380, end: 3535 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 3731, end: 3740 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'code', + loc: { start: 3803, end: 3807 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 3809, end: 3813 } + }, + loc: { start: 3809, end: 3813 } + }, + initializer: undefined, + loc: { start: 3803, end: 3813 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'data', + loc: { start: 3914, end: 3918 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 3920, end: 3924 } + }, + loc: { start: 3920, end: 3924 } + }, + initializer: undefined, + loc: { start: 3914, end: 3924 } + } + ], + loc: { start: 3724, end: 3927 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'hasSameBasechainAddress', + loc: { start: 4778, end: 4801 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 4837, end: 4841 } + }, + typeArgs: [], + loc: { start: 4837, end: 4841 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'sender', + loc: { start: 4819, end: 4825 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 4827, end: 4834 } + }, + typeArgs: [], + loc: { start: 4827, end: 4834 } + }, + loc: { start: 4819, end: 4834 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'senderAddress', + loc: { start: 4852, end: 4865 } + }, + type: undefined, + expression: { + kind: 'field_access', + aggregate: { + kind: 'static_call', + function: { + kind: 'id', + text: 'parseStdAddress', + loc: { start: 4868, end: 4883 } + }, + typeArgs: [], + args: [ + { + kind: 'method_call', + self: { + kind: 'var', + name: 'sender', + loc: { start: 4884, end: 4890 } + }, + method: { + kind: 'id', + text: 'asSlice', + loc: { start: 4891, end: 4898 } + }, + typeArgs: [], + args: [], + loc: { start: 4884, end: 4900 } + } + ], + loc: { start: 4868, end: 4901 } + }, + field: { + kind: 'id', + text: 'address', + loc: { start: 4902, end: 4909 } + }, + loc: { start: 4868, end: 4909 } + }, + loc: { start: 4848, end: 4910 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'baseAddress', + loc: { start: 4919, end: 4930 } + }, + type: undefined, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractBasechainAddress', + loc: { start: 4933, end: 4957 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'self', + loc: { start: 4958, end: 4962 } + } + ], + loc: { start: 4933, end: 4963 } + }, + loc: { start: 4915, end: 4964 } + }, + { + kind: 'statement_return', + expression: { + kind: 'op_binary', + op: '==', + left: { + kind: 'op_unary', + op: '!!', + operand: { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'baseAddress', + loc: { start: 4976, end: 4987 } + }, + field: { + kind: 'id', + text: 'hash', + loc: { start: 4988, end: 4992 } + }, + loc: { start: 4976, end: 4992 } + }, + loc: { start: 4976, end: 4994 } + }, + right: { + kind: 'var', + name: 'senderAddress', + loc: { start: 4998, end: 5011 } + }, + loc: { start: 4976, end: 5011 } + }, + loc: { start: 4969, end: 5012 } + } + ] + }, + loc: { start: 4759, end: 5014 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 4808, end: 4817 } + }, + typeArgs: [], + loc: { start: 4808, end: 4817 } + } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'contractAddress', + loc: { start: 5709, end: 5724 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 5740, end: 5747 } + }, + typeArgs: [], + loc: { start: 5740, end: 5747 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 's', + loc: { start: 5725, end: 5726 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 5728, end: 5737 } + }, + typeArgs: [], + loc: { start: 5728, end: 5737 } + }, + loc: { start: 5725, end: 5737 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractAddressExt', + loc: { start: 5761, end: 5779 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 5780, end: 5781 } + }, + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 5783, end: 5784 } + }, + field: { + kind: 'id', + text: 'code', + loc: { start: 5785, end: 5789 } + }, + loc: { start: 5783, end: 5789 } + }, + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 5791, end: 5792 } + }, + field: { + kind: 'id', + text: 'data', + loc: { start: 5793, end: 5797 } + }, + loc: { start: 5791, end: 5797 } + } + ], + loc: { start: 5761, end: 5798 } + }, + loc: { start: 5754, end: 5799 } + } + ] + }, + loc: { start: 5698, end: 5801 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myAddress', + loc: { start: 6082, end: 6091 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 6095, end: 6102 } + }, + typeArgs: [], + loc: { start: 6095, end: 6102 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MYADDR' ] + }, + loc: { start: 6074, end: 6113 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myBalance', + loc: { start: 6454, end: 6463 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6467, end: 6470 } + }, + loc: { start: 6467, end: 6470 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'BALANCE FIRST' ] + }, + loc: { start: 6446, end: 6488 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'gasConsumed', + loc: { start: 6880, end: 6891 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 6895, end: 6898 } + }, + loc: { start: 6895, end: 6898 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GASCONSUMED' ] + }, + loc: { start: 6872, end: 6914 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myStorageDue', + loc: { start: 7329, end: 7341 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 7345, end: 7348 } + }, + loc: { start: 7345, end: 7348 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'DUEPAYMENT' ] + }, + loc: { start: 7321, end: 7363 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getStorageFee', + loc: { start: 8517, end: 8530 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8590, end: 8593 } + }, + loc: { start: 8590, end: 8593 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 8531, end: 8536 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8538, end: 8541 } + }, + loc: { start: 8538, end: 8541 } + }, + loc: { start: 8531, end: 8541 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 8543, end: 8547 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8549, end: 8552 } + }, + loc: { start: 8549, end: 8552 } + }, + loc: { start: 8543, end: 8552 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'seconds', + loc: { start: 8554, end: 8561 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 8563, end: 8566 } + }, + loc: { start: 8563, end: 8566 } + }, + loc: { start: 8554, end: 8566 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 8568, end: 8581 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 8583, end: 8587 } + }, + typeArgs: [], + loc: { start: 8583, end: 8587 } + }, + loc: { start: 8568, end: 8587 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETSTORAGEFEE' ] + }, + loc: { start: 8509, end: 8611 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getComputeFee', + loc: { start: 9734, end: 9747 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9784, end: 9787 } + }, + loc: { start: 9784, end: 9787 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'gasUsed', + loc: { start: 9748, end: 9755 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9757, end: 9760 } + }, + loc: { start: 9757, end: 9760 } + }, + loc: { start: 9748, end: 9760 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 9762, end: 9775 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 9777, end: 9781 } + }, + typeArgs: [], + loc: { start: 9777, end: 9781 } + }, + loc: { start: 9762, end: 9781 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETGASFEE' ] + }, + loc: { start: 9726, end: 9801 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSimpleComputeFee', + loc: { start: 10689, end: 10708 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10745, end: 10748 } + }, + loc: { start: 10745, end: 10748 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'gasUsed', + loc: { start: 10709, end: 10716 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10718, end: 10721 } + }, + loc: { start: 10718, end: 10721 } + }, + loc: { start: 10709, end: 10721 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 10723, end: 10736 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 10738, end: 10742 } + }, + typeArgs: [], + loc: { start: 10738, end: 10742 } + }, + loc: { start: 10723, end: 10742 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETGASFEESIMPLE' ] + }, + loc: { start: 10681, end: 10768 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getForwardFee', + loc: { start: 12543, end: 12556 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12602, end: 12605 } + }, + loc: { start: 12602, end: 12605 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 12557, end: 12562 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12564, end: 12567 } + }, + loc: { start: 12564, end: 12567 } + }, + loc: { start: 12557, end: 12567 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 12569, end: 12573 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 12575, end: 12578 } + }, + loc: { start: 12575, end: 12578 } + }, + loc: { start: 12569, end: 12578 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 12580, end: 12593 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 12595, end: 12599 } + }, + typeArgs: [], + loc: { start: 12595, end: 12599 } + }, + loc: { start: 12580, end: 12599 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETFORWARDFEE' ] + }, + loc: { start: 12535, end: 12623 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSimpleForwardFee', + loc: { start: 13528, end: 13547 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13593, end: 13596 } + }, + loc: { start: 13593, end: 13596 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'cells', + loc: { start: 13548, end: 13553 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13555, end: 13558 } + }, + loc: { start: 13555, end: 13558 } + }, + loc: { start: 13548, end: 13558 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bits', + loc: { start: 13560, end: 13564 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 13566, end: 13569 } + }, + loc: { start: 13566, end: 13569 } + }, + loc: { start: 13560, end: 13569 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 13571, end: 13584 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 13586, end: 13590 } + }, + typeArgs: [], + loc: { start: 13586, end: 13590 } + }, + loc: { start: 13571, end: 13590 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETFORWARDFEESIMPLE' ] + }, + loc: { start: 13520, end: 13620 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getOriginalFwdFee', + loc: { start: 15782, end: 15799 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15835, end: 15838 } + }, + loc: { start: 15835, end: 15838 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'fwdFee', + loc: { start: 15800, end: 15806 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 15808, end: 15811 } + }, + loc: { start: 15808, end: 15811 } + }, + loc: { start: 15800, end: 15811 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'isMasterchain', + loc: { start: 15813, end: 15826 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 15828, end: 15832 } + }, + typeArgs: [], + loc: { start: 15828, end: 15832 } + }, + loc: { start: 15813, end: 15832 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'GETORIGINALFWDFEE' ] + }, + loc: { start: 15774, end: 15860 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'setGasLimit', + loc: { start: 16541, end: 16552 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'limit', + loc: { start: 16553, end: 16558 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 16560, end: 16563 } + }, + loc: { start: 16560, end: 16563 } + }, + loc: { start: 16553, end: 16563 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SETGASLIMIT' ] + }, + loc: { start: 16533, end: 16580 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getSeed', + loc: { start: 17350, end: 17357 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 17361, end: 17364 } + }, + loc: { start: 17361, end: 17364 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RANDSEED' ] + }, + loc: { start: 17342, end: 17377 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'setSeed', + loc: { start: 18258, end: 18265 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'seed', + loc: { start: 18266, end: 18270 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 18272, end: 18275 } + }, + loc: { start: 18272, end: 18275 } + }, + loc: { start: 18266, end: 18275 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SETRAND' ] + }, + loc: { start: 18250, end: 18288 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'myCode', + loc: { start: 18585, end: 18591 } + }, + typeParams: [], + returnType: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 18595, end: 18599 } + }, + loc: { start: 18595, end: 18599 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'MYCODE' ] + }, + loc: { start: 18577, end: 18610 } + } + ] + }, + loc: { start: 171, end: 200 } + }, + { + kind: 'tact', + source: { + kind: 'tact', + path: 'std/internal/debug.tact', + code: '// these are builtin functions, these get special treatment from FunC\n' + + '// hence, no asm here\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Unconditionally throws an exception with an error `code`.\n' + + '///\n' + + '/// Execution of the current context stops, statements after `throw` are not executed, and control is passed to the first `try...catch` block on the call stack. If there is no `try` or `try...catch` block among the calling functions, TVM will terminate the transaction.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun thisWillTerminateAbruptly() {\n' + + '/// throw(1042); // throwing with exit code 1042\n' + + '/// }\n' + + '///\n' + + '/// fun butThisWont() {\n' + + '/// try {\n' + + '/// throw(1042); // throwing with exit code 1042\n' + + '/// }\n' + + '///\n' + + '/// // ... follow-up logic ...\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify the `code` outside of 0-65535 range.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#throw\n' + + '/// * https://docs.tact-lang.org/book/statements#try-catch\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + '@name(throw)\n' + + 'native throw(code: Int);\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + "/// Similar to `throw()`, but throws an error `code` only if `condition` holds, i.e. `condition` is equal to `true`. Doesn't throw otherwise.\n" + + '///\n' + + '/// ```tact\n' + + '/// contract Ownership {\n' + + '/// owner: Address;\n' + + '///\n' + + '/// init() {\n' + + '/// self.owner = myAddress();\n' + + '/// }\n' + + '///\n' + + '/// receive() {\n' + + '/// // Check the sender is the owner of the contract,\n' + + "/// // and throw exit code 1024 if it's not\n" + + '/// throwIf(1024, sender() != self.owner);\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify the `code` outside of 0-65535 range.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#throwif\n' + + '/// * https://docs.tact-lang.org/book/statements#try-catch\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + '@name(throw_if)\n' + + 'native throwIf(code: Int, condition: Bool);\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + "/// Similar to `throw()`, but throws an error `code` only if `condition` does **not** hold, i.e. `condition` is equal to `true`. Doesn't throw otherwise.\n" + + '///\n' + + '/// This function is also similar to `require()`, but uses the specified `code` directly instead of generating one based on the given error message `String`.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract Ownership {\n' + + '/// owner: Address;\n' + + '///\n' + + '/// init() {\n' + + '/// self.owner = myAddress();\n' + + '/// }\n' + + '///\n' + + '/// receive() {\n' + + '/// // Check the sender is the owner of the contract,\n' + + "/// // and throw exit code 1024 if it's not\n" + + '/// throwUnless(1024, sender() == self.owner);\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 5: [Integer out of expected range] — Thrown when attempting to specify the `code` outside of 0-65535 range.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#throwunless\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#require\n' + + '/// * https://docs.tact-lang.org/book/statements#try-catch\n' + + '///\n' + + '/// [Integer out of expected range]: https://docs.tact-lang.org/book/exit-codes#5\n' + + '///\n' + + '@name(throw_unless)\n' + + 'native throwUnless(code: Int, condition: Bool);\n' + + '\n' + + '/// Global function. **Deprecated** since Tact 1.6.0.\n' + + '///\n' + + '/// Use `throw()` instead.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#throw\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#nativethrow\n' + + '///\n' + + '@name(throw)\n' + + 'native nativeThrow(code: Int);\n' + + '\n' + + '/// Global function. **Deprecated** since Tact 1.6.0.\n' + + '///\n' + + '/// Use `throwIf()` instead.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#throwif\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#nativethrowif\n' + + '///\n' + + '@name(throw_if)\n' + + 'native nativeThrowIf(code: Int, condition: Bool);\n' + + '\n' + + '/// Global function. **Deprecated** since Tact 1.6.0.\n' + + '///\n' + + '/// Use `throwUnless()` instead.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#throwunless\n' + + '/// * https://docs.tact-lang.org/ref/core-debug#nativethrowunless\n' + + '///\n' + + '@name(throw_unless)\n' + + 'native nativeThrowUnless(code: Int, condition: Bool);\n', + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'throw', + loc: { start: 1107, end: 1112 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 1113, end: 1117 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1119, end: 1122 } + }, + loc: { start: 1119, end: 1122 } + }, + loc: { start: 1113, end: 1122 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'throw', + loc: { start: 1093, end: 1098 } + } + }, + loc: { start: 1087, end: 1124 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'throwIf', + loc: { start: 2051, end: 2058 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 2059, end: 2063 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2065, end: 2068 } + }, + loc: { start: 2065, end: 2068 } + }, + loc: { start: 2059, end: 2068 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'condition', + loc: { start: 2070, end: 2079 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 2081, end: 2085 } + }, + typeArgs: [], + loc: { start: 2081, end: 2085 } + }, + loc: { start: 2070, end: 2085 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'throw_if', + loc: { start: 2034, end: 2042 } + } + }, + loc: { start: 2028, end: 2087 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'throwUnless', + loc: { start: 3256, end: 3267 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 3268, end: 3272 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3274, end: 3277 } + }, + loc: { start: 3274, end: 3277 } + }, + loc: { start: 3268, end: 3277 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'condition', + loc: { start: 3279, end: 3288 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 3290, end: 3294 } + }, + typeArgs: [], + loc: { start: 3290, end: 3294 } + }, + loc: { start: 3279, end: 3294 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'throw_unless', + loc: { start: 3235, end: 3247 } + } + }, + loc: { start: 3229, end: 3296 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeThrow', + loc: { start: 3534, end: 3545 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 3546, end: 3550 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3552, end: 3555 } + }, + loc: { start: 3552, end: 3555 } + }, + loc: { start: 3546, end: 3555 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'throw', + loc: { start: 3520, end: 3525 } + } + }, + loc: { start: 3514, end: 3557 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeThrowIf', + loc: { start: 3804, end: 3817 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 3818, end: 3822 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3824, end: 3827 } + }, + loc: { start: 3824, end: 3827 } + }, + loc: { start: 3818, end: 3827 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'condition', + loc: { start: 3829, end: 3838 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 3840, end: 3844 } + }, + typeArgs: [], + loc: { start: 3840, end: 3844 } + }, + loc: { start: 3829, end: 3844 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'throw_if', + loc: { start: 3787, end: 3795 } + } + }, + loc: { start: 3781, end: 3846 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeThrowUnless', + loc: { start: 4109, end: 4126 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'code', + loc: { start: 4127, end: 4131 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4133, end: 4136 } + }, + loc: { start: 4133, end: 4136 } + }, + loc: { start: 4127, end: 4136 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'condition', + loc: { start: 4138, end: 4147 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 4149, end: 4153 } + }, + typeArgs: [], + loc: { start: 4149, end: 4153 } + }, + loc: { start: 4138, end: 4153 } + } + ], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: 'throw_unless', + loc: { start: 4088, end: 4100 } + } + }, + loc: { start: 4082, end: 4155 } + } + ] + }, + loc: { start: 201, end: 227 } + }, + { + kind: 'tact', + source: { + kind: 'tact', + path: 'std/internal/context.tact', + code: '/// Represents the context of the current message.\n' + + 'struct Context {\n' + + ' /// Indicates whether the received message can\n' + + ' /// [bounce back](https://docs.ton.org/v3/documentation/smart-contracts/message-management/non-bounceable-messages).\n' + + ' bounceable: Bool;\n' + + '\n' + + ' /// Internal address of the sender on the TON Blockchain.\n' + + ' sender: Address;\n' + + '\n' + + ' /// Amount of [nanoToncoin](https://docs.tact-lang.org/book/integers#nanotoncoin) in the received message.\n' + + ' value: Int;\n' + + '\n' + + ' /// The remainder of the received message as a `Slice`. It follows the [internal message layout]\n' + + ' /// of TON, starting from the destination `Address` (`MsgAddressInt` in [TL-B notation]).\n' + + ' ///\n' + + ' /// [internal message layout]: https://docs.ton.org/develop/smart-contracts/messages#message-layout\n' + + ' /// [TL-B notation]: https://docs.ton.org/develop/data-formats/tl-b-language\n' + + ' raw: Slice;\n' + + '}\n' + + '\n' + + '/// Returns `Context` struct, which consists of:\n' + + '///\n' + + '/// * `bounceable` — Indicates whether the received message can [bounce back].\n' + + '/// * `sender` — Internal address of the sender on the TON blockchain.\n' + + '/// * `value` — Amount of [nanoToncoin] in the received message.\n' + + '/// * `raw` — The remainder of the received message as a `Slice`. It follows the [internal message layout] of TON, starting from the destination `Address` (`MsgAddressInt` in [TL-B notation]).\n' + + '///\n' + + '/// ```tact\n' + + '/// fun test() {\n' + + '/// let ctx: Context = context();\n' + + '/// require(ctx.value != 68 + 1, "Invalid amount of nanoToncoins, bye!");\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// Note: If you only need to know who sent the message, use the `sender()` function,\n' + + '/// as it is less gas-consuming.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#context\n' + + '///\n' + + '/// [bounce back]: https://docs.ton.org/v3/documentation/smart-contracts/message-management/non-bounceable-messages\n' + + '/// [nanoToncoin]: https://docs.tact-lang.org/book/integers#nanotoncoin\n' + + '/// [internal message layout]: https://docs.ton.org/develop/smart-contracts/messages#message-layout\n' + + '/// [TL-B notation]: https://docs.ton.org/develop/data-formats/tl-b-language\n' + + '///\n' + + '@name(__tact_context_get)\n' + + 'native context(): Context;\n' + + '\n' + + '/// Returns the `Address` of the sender of the current message.\n' + + '///\n' + + '/// ```tact\n' + + '/// contract MeSee {\n' + + '/// receive() {\n' + + '/// let whoSentMeMessage: Address = sender();\n' + + '/// }\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// Note: Behavior is undefined for [getter functions], because they cannot have a sender\n' + + '/// nor can they send messages.\n' + + '///\n' + + '/// Tip: To reduce gas usage, prefer using this function over calling `context().sender`\n' + + '/// when you only need to know the sender of the message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#sender\n' + + '///\n' + + '/// [getter functions]: https://docs.tact-lang.org/book/contracts#getter-functions\n' + + '///\n' + + '@name(__tact_context_get_sender)\n' + + 'native sender(): Address;\n' + + '\n' + + '/// Extension function for the `Context` structure.\n' + + '///\n' + + '/// Reads forward fee and returns it as `Int` amount of nanoToncoins.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let fwdFee: Int = context().readForwardFee();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-contextstate#contextreadforwardfee\n' + + '/// * https://docs.tact-lang.org/ref/core-gas#getoriginalfwdfee\n' + + '///\n' + + 'asm extends fun readForwardFee(self: Context): Int {\n' + + ' // Only the self.raw (Context.raw) is important,\n' + + ' // so all the other fields and loaded values will be dropped by `BLKDROP2`\n' + + ' //\n' + + ' // Context.raw starts at the dest:MsgAddressInt, following this TL-B scheme:\n' + + ' // int_msg_info$0\n' + + ' // ihr_disabled:Bool\n' + + ' // bounce:Bool\n' + + ' // bounced:Bool\n' + + ' // src:MsgAddress\n' + + ' // dest:MsgAddressInt ← here is the start\n' + + ' // value:CurrencyCollection\n' + + ' // ihr_fee:Grams\n' + + ' // fwd_fee:Grams\n' + + ' // created_lt:uint64\n' + + ' // created_at:uint32\n' + + ' // = CommonMsgInfoRelaxed;\n' + + '\n' + + ' LDMSGADDR // load dest:MsgAddressInt\n' + + ' LDGRAMS // load value:CurrencyCollection\n' + + ' ONE\n' + + ' SDSKIPFIRST // skip extra currency collection\n' + + ' LDGRAMS // load ihr_fee\n' + + " LDGRAMS // load fwd_fee, we'll be using this!\n" + + ' DROP // drop remaining Slice (with created_lt and created_at)\n' + + '\n' + + ' // There are 7 entries on the stack — first 3 fields of Context plus 4 loaded ones.\n' + + " // The topmost is fwd_fee, which is the only one we're after, so let's drop 6 entries below:\n" + + ' 6 1 BLKDROP2 // drop the loaded values as well as the first 3 fields of Context\n' + + '\n' + + ' ZERO // not masterchain\n' + + ' GETORIGINALFWDFEE // floor(fwd_fee * 2^16 / (2^16 - first_frac)), where\n' + + ' // first_frac is a value listed in config param 25\n' + + ' // of the blockchain: https://tonviewer.com/config#25\n' + + ' // this instruction effectively multiplies the fwd_fee by 1.5,\n' + + ' // at least for the current value of first_frac, which is 21845\n' + + '}\n', + imports: [], + items: [ + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'Context', + loc: { start: 58, end: 65 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounceable', + loc: { start: 244, end: 254 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 256, end: 260 } + }, + typeArgs: [], + loc: { start: 256, end: 260 } + }, + initializer: undefined, + loc: { start: 244, end: 260 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'sender', + loc: { start: 329, end: 335 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 337, end: 344 } + }, + typeArgs: [], + loc: { start: 337, end: 344 } + }, + initializer: undefined, + loc: { start: 329, end: 344 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 462, end: 467 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 469, end: 472 } + }, + loc: { start: 469, end: 472 } + }, + initializer: undefined, + loc: { start: 462, end: 472 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'raw', + loc: { start: 867, end: 870 } + }, + type: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 872, end: 877 } + }, + loc: { start: 872, end: 877 } + }, + initializer: undefined, + loc: { start: 867, end: 877 } + } + ], + loc: { start: 51, end: 880 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'context', + loc: { start: 2105, end: 2112 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Context', + loc: { start: 2116, end: 2123 } + }, + typeArgs: [], + loc: { start: 2116, end: 2123 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_context_get', + loc: { start: 2078, end: 2096 } + } + }, + loc: { start: 2072, end: 2124 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sender', + loc: { start: 2802, end: 2808 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 2812, end: 2819 } + }, + typeArgs: [], + loc: { start: 2812, end: 2819 } + }, + params: [], + body: { + kind: 'native_body', + nativeName: { + kind: 'func_id', + text: '__tact_context_get_sender', + loc: { start: 2768, end: 2793 } + } + }, + loc: { start: 2762, end: 2820 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'readForwardFee', + loc: { start: 3226, end: 3240 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3257, end: 3260 } + }, + loc: { start: 3257, end: 3260 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'LDMSGADDR // load dest:MsgAddressInt\n' + + ' LDGRAMS // load value:CurrencyCollection\n' + + ' ONE\n' + + ' SDSKIPFIRST // skip extra currency collection\n' + + ' LDGRAMS // load ihr_fee\n' + + " LDGRAMS // load fwd_fee, we'll be using this!\n" + + ' DROP // drop remaining Slice (with created_lt and created_at)\n' + + '\n' + + ' // There are 7 entries on the stack — first 3 fields of Context plus 4 loaded ones.\n' + + " // The topmost is fwd_fee, which is the only one we're after, so let's drop 6 entries below:\n" + + ' 6 1 BLKDROP2 // drop the loaded values as well as the first 3 fields of Context\n' + + '\n' + + ' ZERO // not masterchain\n' + + ' GETORIGINALFWDFEE // floor(fwd_fee * 2^16 / (2^16 - first_frac)), where\n' + + ' // first_frac is a value listed in config param 25\n' + + ' // of the blockchain: https://tonviewer.com/config#25\n' + + ' // this instruction effectively multiplies the fwd_fee by 1.5,\n' + + ' // at least for the current value of first_frac, which is 21845' + ] + }, + loc: { start: 3210, end: 4831 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Context', + loc: { start: 3247, end: 3254 } + }, + typeArgs: [], + loc: { start: 3247, end: 3254 } + } + } + ] + }, + loc: { start: 228, end: 256 } + }, + { + kind: 'tact', + source: { + kind: 'tact', + path: 'std/internal/reserve.tact', + code: '/// Executes the native `RAWRESERVE` instruction with the specified amount and mode.\n' + + '/// The `RAWRESERVE` instruction creates an output action to reserve a specific amount of\n' + + '/// [nanoToncoin] from the remaining balance of the account.\n' + + '///\n' + + '/// The `RAWRESERVE` instruction takes two arguments:\n' + + '/// * `amount`: The number of [nanoToncoin] to reserve.\n' + + '/// * `mode`: Determines the reservation behavior.\n' + + '///\n' + + '/// The `RAWRESERVE` instruction is roughly equivalent to creating an outbound message\n' + + '/// carrying the specified `amount` of [nanoToncoin] (or `b - amount` [nanoToncoin],\n' + + '/// where `b` is the remaining balance) to oneself.\n' + + '/// This ensures that subsequent output actions cannot spend more money than the remainder.\n' + + '///\n' + + '/// It is possible to use raw `Int` values and manually provide them for the `mode`,\n' + + "/// but for your convenience, there's a set of constants you may use to construct the\n" + + '/// compound `mode` with ease.\n' + + '///\n' + + '/// NOTE: Currently, `amount` must be a non-negative integer, and `mode` must be in the\n' + + '/// range `0..31`, inclusive.\n' + + '///\n' + + '/// Additionally, attempts to queue more than 255 reservations in one transaction throw an\n' + + '/// exception with [exit code 33]: `Action list is too long`.\n' + + '///\n' + + '/// NOTE: This function is gas-expensive and uses 500 gas units or more.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve\n' + + '///\n' + + '/// [exit code 33]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '/// [nanoToncoin]: https://docs.tact-lang.org/book/integers#nanotoncoin\n' + + 'asm fun nativeReserve(amount: Int, mode: Int) { RAWRESERVE }\n' + + '\n' + + '/// Reserves exactly the specified `amount` of\n' + + '/// [nanoToncoin](https://docs.tact-lang.org/book/integers#nanotoncoin).\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve-base-modes\n' + + '///\n' + + 'const ReserveExact: Int = 0;\n' + + '\n' + + '/// Reserves all but the specified `amount` of\n' + + '/// [nanoToncoin](https://docs.tact-lang.org/book/integers#nanotoncoin).\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve-base-modes\n' + + '///\n' + + 'const ReserveAllExcept: Int = 1;\n' + + '\n' + + '/// Reserves at most the specified `amount` of\n' + + '/// [nanoToncoin](https://docs.tact-lang.org/book/integers#nanotoncoin).\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve-base-modes\n' + + '///\n' + + 'const ReserveAtMost: Int = 2;\n' + + '\n' + + '/// Increases the `amount` by the original balance of the current account\n' + + '/// (before the compute phase), including all extra currencies.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve-optional-flags\n' + + '///\n' + + 'const ReserveAddOriginalBalance: Int = 4;\n' + + '\n' + + '/// Negates the `amount` value before performing the reservation.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve-optional-flags\n' + + '///\n' + + 'const ReserveInvertSign: Int = 8;\n' + + '\n' + + '/// Bounces the transaction if the reservation fails.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve-optional-flags\n' + + '///\n' + + 'const ReserveBounceIfActionFail: Int = 16;\n', + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeReserve', + loc: { start: 1509, end: 1522 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'amount', + loc: { start: 1523, end: 1529 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1531, end: 1534 } + }, + loc: { start: 1531, end: 1534 } + }, + loc: { start: 1523, end: 1534 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 1536, end: 1540 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1542, end: 1545 } + }, + loc: { start: 1542, end: 1545 } + }, + loc: { start: 1536, end: 1545 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RAWRESERVE' ] + }, + loc: { start: 1501, end: 1561 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'ReserveExact', + loc: { start: 1780, end: 1792 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1794, end: 1797 } + }, + loc: { start: 1794, end: 1797 } + }, + initializer: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 1800, end: 1801 } + } + }, + loc: { start: 1774, end: 1802 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'ReserveAllExcept', + loc: { start: 2021, end: 2037 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2039, end: 2042 } + }, + loc: { start: 2039, end: 2042 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 2045, end: 2046 } + } + }, + loc: { start: 2015, end: 2047 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'ReserveAtMost', + loc: { start: 2266, end: 2279 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2281, end: 2284 } + }, + loc: { start: 2281, end: 2284 } + }, + initializer: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 2287, end: 2288 } + } + }, + loc: { start: 2260, end: 2289 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'ReserveAddOriginalBalance', + loc: { start: 2530, end: 2555 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2557, end: 2560 } + }, + loc: { start: 2557, end: 2560 } + }, + initializer: { + kind: 'number', + base: '10', + value: 4n, + loc: { start: 2563, end: 2564 } + } + }, + loc: { start: 2524, end: 2565 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'ReserveInvertSign', + loc: { start: 2734, end: 2751 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2753, end: 2756 } + }, + loc: { start: 2753, end: 2756 } + }, + initializer: { + kind: 'number', + base: '10', + value: 8n, + loc: { start: 2759, end: 2760 } + } + }, + loc: { start: 2728, end: 2761 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'ReserveBounceIfActionFail', + loc: { start: 2918, end: 2943 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2945, end: 2948 } + }, + loc: { start: 2945, end: 2948 } + }, + initializer: { + kind: 'number', + base: '10', + value: 16n, + loc: { start: 2951, end: 2953 } + } + }, + loc: { start: 2912, end: 2954 } + } + ] + }, + loc: { start: 257, end: 285 } + }, + { + kind: 'tact', + source: { + kind: 'tact', + path: 'std/internal/send.tact', + code: '/// Ordinary message (default).\n' + + '///\n' + + '/// This constant is available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendDefaultMode: Int = 0;\n' + + '\n' + + '/// Carry all the remaining value of the inbound message in addition\n' + + '/// to the value initially indicated in the new message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendRemainingValue: Int = 64;\n' + + '\n' + + '/// Carry **all the remaining balance** of the current smart contract instead\n' + + '/// of the value originally indicated in the message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendRemainingBalance: Int = 128;\n' + + '\n' + + "/// Doesn't send the message, only estimates the forward fees\n" + + '/// if the message-sending function computes those.\n' + + '///\n' + + '/// This constant is available since Tact 1.5.0.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '/// * https://docs.tact-lang.org/book/send#message-sending-functions\n' + + '///\n' + + 'const SendOnlyEstimateFee: Int = 1024;\n' + + '\n' + + '/// **Deprecated** since Tact 1.6.5.\n' + + '///\n' + + '/// Pay forward fees separately from the message value.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendPayGasSeparately: Int = 1;\n' + + '\n' + + '/// Pay forward fees separately from the message value.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendPayFwdFeesSeparately: Int = 1;\n' + + '\n' + + '/// Ignore any errors arising while processing this message during the action phase.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendIgnoreErrors: Int = 2;\n' + + '\n' + + '/// Bounce transaction in case of any errors during action phase.\n' + + '/// Has no effect if flag +2, `SendIgnoreErrors` is used.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendBounceIfActionFail: Int = 16;\n' + + '\n' + + '/// Current account (contract) will be destroyed if its resulting balance is zero.\n' + + '/// This flag is often used with mode 128, `SendRemainingBalance`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendDestroyIfZero: Int = 32;\n' + + '\n' + + '/// Struct for specifying the message parameters of the `send()` function.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#send\n' + + '///\n' + + 'struct SendParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// Optional initial code of the contract (compiled bitcode).\n' + + ' code: Cell? = null;\n' + + '\n' + + ' /// Optional initial data of the contract (arguments of `init()` function or values of contract parameters).\n' + + ' data: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// Recipient internal `Address` on TON Blockchain.\n' + + ' to: Address;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '}\n' + + '\n' + + '/// Struct for specifying the message parameters of the `message()` function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#message\n' + + '///\n' + + 'struct MessageParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// Recipient internal `Address` on TON Blockchain.\n' + + ' to: Address;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Queues the message to be sent using the `MessageParameters` struct. Allows for cheaper non-deployment, regular messages compared to the `send()` function.\n' + + '///\n' + + '/// The `MessageParameters` struct is similar to `SendParameters` struct, but without the `code` and `data` fields.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// message(MessageParameters{\n' + + '/// to: sender(), // back to the sender,\n' + + '/// value: ton("1"), // with 1 Toncoin (1_000_000_000 nanoToncoin),\n' + + '/// // and no message body\n' + + '/// });\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 33: [Action list is too long] — Thrown when attempting to queue more than 255 messages.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-send#message\n' + + '/// * https://docs.tact-lang.org/book/message-mode\n' + + '///\n' + + '/// [Action list is too long]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '///\n' + + 'asm fun message(params: MessageParameters) {\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 106 PUSHINT // 1 + 4 + 4 + 64 + 32 + 1\n' + + ' STZEROES\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + ' STDICT\n' + + ' ENDC\n' + + ' SWAP\n' + + ' SENDRAWMSG\n' + + '}\n' + + '\n' + + '/// Global function. Queues the message to be sent using a `SendParameters` Struct.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// send(SendParameters{\n' + + '/// to: sender(), // back to the sender,\n' + + '/// value: ton("1"), // with 1 Toncoin (1_000_000_000 nanoToncoin),\n' + + '/// // and no message body\n' + + '/// });\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 33: [Action list is too long] — Thrown when attempting to queue more than 255 messages.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#send\n' + + '///\n' + + '/// [Action list is too long]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '///\n' + + 'asm fun send(params: SendParameters) {\n' + + ' // Instructions are grouped, and the stack states they produce as a group are shown right after.\n' + + ' // In the end, our message Cell should have the following TL-B structure:\n' + + ' // message$_ {X:Type}\n' + + ' // info:CommonMsgInfoRelaxed\n' + + ' // init:(Maybe (Either StateInit ^StateInit))\n' + + ' // body:(Either X ^X)\n' + + ' // = MessageRelaxed X;\n' + + '\n' + + ' // → Stack state\n' + + ' // s0: `params.bounce`\n' + + ' // s1: `params.to`\n' + + ' // s2: `params.value`\n' + + ' // s3: `params.data`\n' + + ' // s4: `params.code`\n' + + ' // s5: `params.body`\n' + + ' // s6: `params.mode`\n' + + ' // For brevity, the "params" prefix will be omitted from now on.\n' + + '\n' + + ' // Group 1: Storing the `bounce`, `to` and `value` into a Builder\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + '\n' + + ' // Group 2: Placing the Builder after code and data, then checking those for nullability\n' + + ' s2 XCHG0\n' + + ' DUP2\n' + + ' ISNULL\n' + + ' SWAP\n' + + ' ISNULL\n' + + ' AND\n' + + ' // → Stack state\n' + + ' // s0: -1 (true) if `data` and `code` are both null, 0 (false) otherwise\n' + + ' // s1: `code`\n' + + ' // s2: `data`\n' + + ' // s3: Builder\n' + + ' // s4: `body`\n' + + ' // s5: `mode`\n' + + '\n' + + ' // Group 3: Left branch of the IFELSE, executed if s0 is -1 (true)\n' + + ' <{\n' + + ' DROP2 // drop `data` and `code`, since either of those is null\n' + + ' b{0} STSLICECONST\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: Right branch of the IFELSE, executed if s0 is 0 (false)\n' + + ' <{\n' + + ' // _ split_depth:(Maybe (## 5))\n' + + ' // special:(Maybe TickTock)\n' + + ' // code:(Maybe ^Cell)\n' + + ' // data:(Maybe ^Cell)\n' + + ' // library:(Maybe ^Cell)\n' + + ' // = StateInit;\n' + + ' ROT // place message Builder on top\n' + + ' b{10} STSLICECONST // store Maybe = true, Either = false\n' + + ' // Start composing inlined StateInit\n' + + ' b{00} STSLICECONST // store split_depth and special first\n' + + ' STDICT // store code\n' + + ' STDICT // store data\n' + + ' b{0} STSLICECONST // store library\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: IFELSE that does the branching shown above\n' + + ' IFELSE\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: null or StateInit\n' + + ' // s2: `body`\n' + + ' // s3: `mode`\n' + + '\n' + + ' // Group 4: Finalizing the message\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: `mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG // https://github.com/tact-lang/tact/issues/1558\n' + + '}\n' + + '\n' + + '/// Struct for specifying the deployment message parameters of the `deploy()` function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#deploy\n' + + '///\n' + + 'struct DeployParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '\n' + + ' //'... 12658 more characters, + imports: [], + items: [ + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendDefaultMode', + loc: { start: 164, end: 179 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 181, end: 184 } + }, + loc: { start: 181, end: 184 } + }, + initializer: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 187, end: 188 } + } + }, + loc: { start: 158, end: 189 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendRemainingValue', + loc: { start: 396, end: 414 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 416, end: 419 } + }, + loc: { start: 416, end: 419 } + }, + initializer: { + kind: 'number', + base: '10', + value: 64n, + loc: { start: 422, end: 424 } + } + }, + loc: { start: 390, end: 425 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendRemainingBalance', + loc: { start: 638, end: 658 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 660, end: 663 } + }, + loc: { start: 660, end: 663 } + }, + initializer: { + kind: 'number', + base: '10', + value: 128n, + loc: { start: 666, end: 669 } + } + }, + loc: { start: 632, end: 670 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendOnlyEstimateFee', + loc: { start: 993, end: 1012 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1014, end: 1017 } + }, + loc: { start: 1014, end: 1017 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1024n, + loc: { start: 1020, end: 1024 } + } + }, + loc: { start: 987, end: 1025 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendPayGasSeparately', + loc: { start: 1207, end: 1227 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1229, end: 1232 } + }, + loc: { start: 1229, end: 1232 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1235, end: 1236 } + } + }, + loc: { start: 1201, end: 1237 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendPayFwdFeesSeparately', + loc: { start: 1378, end: 1402 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1404, end: 1407 } + }, + loc: { start: 1404, end: 1407 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1410, end: 1411 } + } + }, + loc: { start: 1372, end: 1412 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendIgnoreErrors', + loc: { start: 1582, end: 1598 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1600, end: 1603 } + }, + loc: { start: 1600, end: 1603 } + }, + initializer: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 1606, end: 1607 } + } + }, + loc: { start: 1576, end: 1608 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendBounceIfActionFail', + loc: { start: 1817, end: 1839 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1841, end: 1844 } + }, + loc: { start: 1841, end: 1844 } + }, + initializer: { + kind: 'number', + base: '10', + value: 16n, + loc: { start: 1847, end: 1849 } + } + }, + loc: { start: 1811, end: 1850 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendDestroyIfZero', + loc: { start: 2085, end: 2102 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2104, end: 2107 } + }, + loc: { start: 2104, end: 2107 } + }, + initializer: { + kind: 'number', + base: '10', + value: 32n, + loc: { start: 2110, end: 2112 } + } + }, + loc: { start: 2079, end: 2113 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'SendParameters', + loc: { start: 2260, end: 2274 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 2416, end: 2420 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2422, end: 2425 } + }, + loc: { start: 2422, end: 2425 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 2428, end: 2443 } + }, + loc: { start: 2416, end: 2443 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 2493, end: 2497 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2503, end: 2504 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2499, end: 2503 } + }, + loc: { start: 2499, end: 2503 } + } + ], + loc: { start: 2503, end: 2504 } + }, + initializer: { + kind: 'null', + loc: { start: 2507, end: 2511 } + }, + loc: { start: 2493, end: 2511 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'code', + loc: { start: 2584, end: 2588 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2594, end: 2595 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2590, end: 2594 } + }, + loc: { start: 2590, end: 2594 } + } + ], + loc: { start: 2594, end: 2595 } + }, + initializer: { + kind: 'null', + loc: { start: 2598, end: 2602 } + }, + loc: { start: 2584, end: 2602 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'data', + loc: { start: 2722, end: 2726 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2732, end: 2733 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2728, end: 2732 } + }, + loc: { start: 2728, end: 2732 } + } + ], + loc: { start: 2732, end: 2733 } + }, + initializer: { + kind: 'null', + loc: { start: 2736, end: 2740 } + }, + loc: { start: 2722, end: 2740 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 2936, end: 2941 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2943, end: 2946 } + }, + loc: { start: 2943, end: 2946 } + }, + initializer: undefined, + loc: { start: 2936, end: 2946 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'to', + loc: { start: 3009, end: 3011 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3013, end: 3020 } + }, + typeArgs: [], + loc: { start: 3013, end: 3020 } + }, + initializer: undefined, + loc: { start: 3009, end: 3020 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 3186, end: 3192 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 3194, end: 3198 } + }, + typeArgs: [], + loc: { start: 3194, end: 3198 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 3201, end: 3205 } + }, + loc: { start: 3186, end: 3205 } + } + ], + loc: { start: 2253, end: 3208 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'MessageParameters', + loc: { start: 3389, end: 3406 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 3548, end: 3552 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3554, end: 3557 } + }, + loc: { start: 3554, end: 3557 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 3560, end: 3575 } + }, + loc: { start: 3548, end: 3575 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 3625, end: 3629 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 3635, end: 3636 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 3631, end: 3635 } + }, + loc: { start: 3631, end: 3635 } + } + ], + loc: { start: 3635, end: 3636 } + }, + initializer: { + kind: 'null', + loc: { start: 3639, end: 3643 } + }, + loc: { start: 3625, end: 3643 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 3839, end: 3844 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3846, end: 3849 } + }, + loc: { start: 3846, end: 3849 } + }, + initializer: undefined, + loc: { start: 3839, end: 3849 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'to', + loc: { start: 3912, end: 3914 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3916, end: 3923 } + }, + typeArgs: [], + loc: { start: 3916, end: 3923 } + }, + initializer: undefined, + loc: { start: 3912, end: 3923 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 4089, end: 4095 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 4097, end: 4101 } + }, + typeArgs: [], + loc: { start: 4097, end: 4101 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 4104, end: 4108 } + }, + loc: { start: 4089, end: 4108 } + } + ], + loc: { start: 3382, end: 4111 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'message', + loc: { start: 5056, end: 5063 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 5064, end: 5070 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'MessageParameters', + loc: { start: 5072, end: 5089 } + }, + typeArgs: [], + loc: { start: 5072, end: 5089 } + }, + loc: { start: 5064, end: 5089 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 106 PUSHINT // 1 + 4 + 4 + 64 + 32 + 1\n' + + ' STZEROES\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + ' STDICT\n' + + ' ENDC\n' + + ' SWAP\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 5048, end: 5588 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'send', + loc: { start: 6219, end: 6223 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 6224, end: 6230 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'SendParameters', + loc: { start: 6232, end: 6246 } + }, + typeArgs: [], + loc: { start: 6232, end: 6246 } + }, + loc: { start: 6224, end: 6246 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + '\n' + + ' // Group 2: Placing the Builder after code and data, then checking those for nullability\n' + + ' s2 XCHG0\n' + + ' DUP2\n' + + ' ISNULL\n' + + ' SWAP\n' + + ' ISNULL\n' + + ' AND\n' + + ' // → Stack state\n' + + ' // s0: -1 (true) if `data` and `code` are both null, 0 (false) otherwise\n' + + ' // s1: `code`\n' + + ' // s2: `data`\n' + + ' // s3: Builder\n' + + ' // s4: `body`\n' + + ' // s5: `mode`\n' + + '\n' + + ' // Group 3: Left branch of the IFELSE, executed if s0 is -1 (true)\n' + + ' <{\n' + + ' DROP2 // drop `data` and `code`, since either of those is null\n' + + ' b{0} STSLICECONST\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: Right branch of the IFELSE, executed if s0 is 0 (false)\n' + + ' <{\n' + + ' // _ split_depth:(Maybe (## 5))\n' + + ' // special:(Maybe TickTock)\n' + + ' // code:(Maybe ^Cell)\n' + + ' // data:(Maybe ^Cell)\n' + + ' // library:(Maybe ^Cell)\n' + + ' // = StateInit;\n' + + ' ROT // place message Builder on top\n' + + ' b{10} STSLICECONST // store Maybe = true, Either = false\n' + + ' // Start composing inlined StateInit\n' + + ' b{00} STSLICECONST // store split_depth and special first\n' + + ' STDICT // store code\n' + + ' STDICT // store data\n' + + ' b{0} STSLICECONST // store library\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: IFELSE that does the branching shown above\n' + + ' IFELSE\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: null or StateInit\n' + + ' // s2: `body`\n' + + ' // s3: `mode`\n' + + '\n' + + ' // Group 4: Finalizing the message\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: `mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG // https://github.com/tact-lang/tact/issues/1558' + ] + }, + loc: { start: 6211, end: 9157 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'DeployParameters', + loc: { start: 9347, end: 9363 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 9505, end: 9509 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9511, end: 9514 } + }, + loc: { start: 9511, end: 9514 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 9517, end: 9532 } + }, + loc: { start: 9505, end: 9532 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 9582, end: 9586 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 9592, end: 9593 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 9588, end: 9592 } + }, + loc: { start: 9588, end: 9592 } + } + ], + loc: { start: 9592, end: 9593 } + }, + initializer: { + kind: 'null', + loc: { start: 9596, end: 9600 } + }, + loc: { start: 9582, end: 9600 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 9796, end: 9801 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9803, end: 9806 } + }, + loc: { start: 9803, end: 9806 } + }, + initializer: undefined, + loc: { start: 9796, end: 9806 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 9972, end: 9978 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 9980, end: 9984 } + }, + typeArgs: [], + loc: { start: 9980, end: 9984 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 9987, end: 9991 } + }, + loc: { start: 9972, end: 9991 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'init', + loc: { start: 10135, end: 10139 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 10141, end: 10150 } + }, + typeArgs: [], + loc: { start: 10141, end: 10150 } + }, + initializer: undefined, + loc: { start: 10135, end: 10150 } + } + ], + loc: { start: 9340, end: 10153 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'deploy', + loc: { start: 11796, end: 11802 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 11803, end: 11809 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'DeployParameters', + loc: { start: 11811, end: 11827 } + }, + typeArgs: [], + loc: { start: 11811, end: 11827 } + }, + loc: { start: 11803, end: 11827 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '4 1 BLKPUSH // pushes 2 copies of `init.code` and `init.data`\n' + + ' HASHCU // `init.data` hash\n' + + ' SWAP\n' + + ' HASHCU // `init.code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `init.data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `init.code` depth\n' + + '\n' + + ' // Group 2: Calculating destination address\n' + + ' // For almost identical logic and instructions,\n' + + ' // see comments inside `contractHash()` function in contract.tact\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + ' NEWC\n' + + ' 24 STU\n' + + ' 16 STU\n' + + ' 16 STU\n' + + ' 256 STU\n' + + ' 256 STU\n' + + ' ONE HASHEXT_SHA256 // obtains hash part (account id) of the address\n' + + ' // → Stack state\n' + + ' // s0: destAddr(hash part)\n' + + ' // s1: `init.data`\n' + + ' // s2: `init.code`\n' + + ' // s3 and below: `bounce`, `value`, `body`, `mode`\n' + + '\n' + + ' // Group 3: Building a message (CommonMsgInfoRelaxed)\n' + + ' s3 XCHG0 // swaps `bounce` with destAddr(hash part)\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' s1 s2 XCHG // swap `init.data` with `init.code`, placing code on s1\n' + + ' STREF // store `init.code`\n' + + ' STREF // store `init.data`\n' + + ' // Inline StateInit:\n' + + ' b{00010000000000} STSLICECONST\n' + + ' // 0 + 00 + 10 + 0 + 00000000\n' + + ' // 1) 0 - bounced = false\n' + + ' // 2) 00 - src = addr_none\n' + + ' // 3) 10 - tag of addr_std (part of dest)\n' + + ' // 4) 0 - Maybe Anycast = false\n' + + ' // 5) 00000000 - workchain_id (part of dest)\n' + + ' //\n' + + ' 256 STU // store destAddr(hash part)\n' + + ' SWAP // Builder on top, `value` below\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + '\n' + + ' // Group 4: Continue building a message (CommonMsgInfoRelaxed into MessageRelaxed)\n' + + ' // Remaining bits of MessageRelaxed:\n' + + ' b{1000110} STSLICECONST\n' + + ' // 10 + 0 + 0 + 1 + 1 + 0\n' + + ' // 10 - Maybe (Either StateInit ^StateInit) = true false\n' + + ' // 0 - split_depth:(Maybe (## 5)) = false\n' + + ' // 0 = special:(Maybe TickTock) = false\n' + + ' // 1 = code:(Maybe ^Cell) = true\n' + + ' // 1 = data:(Maybe ^Cell) = true\n' + + ' // 0 = library:(Maybe ^Cell) = false\n' + + ' //\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC // finalize the message\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: params.`mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 11788, end: 14770 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'cashback', + loc: { start: 15971, end: 15979 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'to', + loc: { start: 15980, end: 15982 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 15984, end: 15991 } + }, + typeArgs: [], + loc: { start: 15984, end: 15991 } + }, + loc: { start: 15980, end: 15991 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '16 PUSHINT // 0x10, i.e. 0x18 but with bounce = false\n' + + ' NEWC\n' + + ' 6 STU // .storeUint(0x10, 6)\n' + + ' STSLICE // .storeAddress(to)\n' + + ' 0 PUSHINT // 0\n' + + ' 111 STUR // .storeUint(0, 111)\n' + + ' // 4 zeros for coins and 107 zeros for lt, fees, etc.\n' + + ' ENDC\n' + + ' 66 PUSHINT // SendRemainingValue | SendIgnoreErrors\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 15963, end: 16385 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeSendMessage', + loc: { start: 16936, end: 16953 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 16954, end: 16957 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 16959, end: 16963 } + }, + loc: { start: 16959, end: 16963 } + }, + loc: { start: 16954, end: 16963 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 16965, end: 16969 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 16971, end: 16974 } + }, + loc: { start: 16971, end: 16974 } + }, + loc: { start: 16965, end: 16974 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDRAWMSG' ] + }, + loc: { start: 16928, end: 16990 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sendRawMessage', + loc: { start: 17751, end: 17765 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 17766, end: 17769 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 17771, end: 17775 } + }, + loc: { start: 17771, end: 17775 } + }, + loc: { start: 17766, end: 17775 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 17777, end: 17781 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 17783, end: 17786 } + }, + loc: { start: 17783, end: 17786 } + }, + loc: { start: 17777, end: 17786 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDRAWMSG' ] + }, + loc: { start: 17743, end: 17802 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeSendMessageReturnForwardFee', + loc: { start: 19063, end: 19096 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 19120, end: 19123 } + }, + loc: { start: 19120, end: 19123 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 19097, end: 19100 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 19102, end: 19106 } + }, + loc: { start: 19102, end: 19106 } + }, + loc: { start: 19097, end: 19106 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 19108, end: 19112 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 19114, end: 19117 } + }, + loc: { start: 19114, end: 19117 } + }, + loc: { start: 19108, end: 19117 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDMSG' ] + }, + loc: { start: 19055, end: 19135 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sendMessageReturnForwardFee', + loc: { start: 20186, end: 20213 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 20237, end: 20240 } + }, + loc: { start: 20237, end: 20240 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 20214, end: 20217 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 20219, end: 20223 } + }, + loc: { start: 20219, end: 20223 } + }, + loc: { start: 20214, end: 20223 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 20225, end: 20229 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 20231, end: 20234 } + }, + loc: { start: 20231, end: 20234 } + }, + loc: { start: 20225, end: 20234 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDMSG' ] + }, + loc: { start: 20178, end: 20252 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'emit', + loc: { start: 21033, end: 21037 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'body', + loc: { start: 21038, end: 21042 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 21044, end: 21048 } + }, + loc: { start: 21044, end: 21048 } + }, + loc: { start: 21038, end: 21048 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'c', + loc: { start: 21233, end: 21234 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 21236, end: 21240 } + }, + loc: { start: 21236, end: 21240 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'static_call', + function: { + kind: 'id', + text: 'beginCell', + loc: { start: 21243, end: 21252 } + }, + typeArgs: [], + args: [], + loc: { start: 21243, end: 21254 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 21264, end: 21273 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 15211807202738752817960438464513n, + loc: { start: 21274, end: 21306 } + }, + { + kind: 'number', + base: '10', + value: 104n, + loc: { start: 21308, end: 21311 } + } + ], + loc: { start: 21243, end: 21312 } + }, + method: { + kind: 'id', + text: 'storeRef', + loc: { start: 21322, end: 21330 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'body', + loc: { start: 21331, end: 21335 } + } + ], + loc: { start: 21243, end: 21336 } + }, + method: { + kind: 'id', + text: 'endCell', + loc: { start: 21346, end: 21353 } + }, + typeArgs: [], + args: [], + loc: { start: 21243, end: 21355 } + }, + loc: { start: 21229, end: 21356 } + }, + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'sendRawMessage', + loc: { start: 21361, end: 21375 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'c', + loc: { start: 21376, end: 21377 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 21379, end: 21380 } + } + ], + loc: { start: 21361, end: 21381 } + }, + loc: { start: 21361, end: 21382 } + } + ] + }, + loc: { start: 21022, end: 21384 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'acceptMessage', + loc: { start: 22124, end: 22137 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ACCEPT' ] + }, + loc: { start: 22116, end: 22150 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'commit', + loc: { start: 22638, end: 22644 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'COMMIT' ] + }, + loc: { start: 22630, end: 22657 } + } + ] + }, + loc: { start: 286, end: 311 } + }, + { + kind: 'tact', + source: { + kind: 'tact', + path: 'std/internal/config.tact', + code: '/// Loads a [configuration parameter] of TON Blockchain by its `id` number.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#getconfigparam\n' + + '///\n' + + '/// [configuration parameter]: https://docs.ton.org/develop/howto/blockchain-configs\n' + + '///\n' + + 'asm fun getConfigParam(id: Int): Cell? { CONFIGOPTPARAM }\n', + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'getConfigParam', + loc: { start: 254, end: 268 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 283, end: 284 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 279, end: 283 } + }, + loc: { start: 279, end: 283 } + } + ], + loc: { start: 283, end: 284 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'id', + loc: { start: 269, end: 271 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 273, end: 276 } + }, + loc: { start: 273, end: 276 } + }, + loc: { start: 269, end: 276 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'CONFIGOPTPARAM' ] + }, + loc: { start: 246, end: 303 } + } + ] + }, + loc: { start: 312, end: 339 } + }, + { + kind: 'tact', + source: { + kind: 'tact', + path: 'std/internal/base.tact', + code: '/// Describes the base logic that is available in all contracts and traits by default.\n' + + '///\n' + + '/// This trait is implicitly inherited by every other contract and trait.\n' + + '/// It contains a number of the most useful internal functions for any kind of contract,\n' + + '/// and a constant `self.storageReserve` aimed at advanced users of Tact.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-base/\n' + + 'trait BaseTrait {\n' + + ' /// The amount of nanoToncoins to reserve before forwarding a message with\n' + + ' /// `SendRemainingBalance` mode. Default is 0 (no reserve).\n' + + ' ///\n' + + ' /// ```tact\n' + + ' /// contract AllYourStorageBelongsToUs {\n' + + ' /// // This would change the behavior of `self.forward()` function,\n' + + ' /// // causing it to try reserving this amount of nanoToncoins before\n' + + ' /// // forwarding a message with `SendRemainingBalance` mode\n' + + ' /// override const storageReserve: Int = ton("0.1");\n' + + ' /// }\n' + + ' /// ```\n' + + ' ///\n' + + ' /// See: https://docs.tact-lang.org/ref/core-base#self-forward\n' + + ' ///\n' + + ' virtual const storageReserve: Int = 0;\n' + + '\n' + + ' /// Sends a bounceable message back to the sender of the current message.\n' + + ' /// An alias function to calling the `self.forward()` function with\n' + + ' /// the following arguments:\n' + + ' ///\n' + + ' /// ```tact\n' + + ' /// self.forward(sender(), body, true, null);\n' + + ' /// ↑ ↑ ↑ ↑\n' + + ' /// | | | init: StateInit?\n' + + ' /// | | bounce: Bool\n' + + ' /// | body: Cell?\n' + + ' /// to: Address\n' + + ' /// ```\n' + + ' ///\n' + + ' /// See: https://docs.tact-lang.org/ref/core-base#self-forward\n' + + ' ///\n' + + ' virtual inline fun reply(body: Cell?) {\n' + + ' self.forward(sender(), body, true, null);\n' + + ' }\n' + + '\n' + + ' /// Sends a non-bounceable message back to the sender of the current message.\n' + + ' /// An alias function to calling the `self.forward()` function with\n' + + ' /// the following arguments:\n' + + ' ///\n' + + ' /// ```tact\n' + + ' /// self.forward(sender(), body, false, null);\n' + + ' /// ↑ ↑ ↑ ↑\n' + + ' /// | | | init: StateInit?\n' + + ' /// | | bounce: Bool\n' + + ' /// | body: Cell?\n' + + ' /// to: Address\n' + + ' /// ```\n' + + ' ///\n' + + ' /// See: https://docs.tact-lang.org/ref/core-base#self-forward\n' + + ' ///\n' + + ' virtual inline fun notify(body: Cell?) {\n' + + ' self.forward(sender(), body, false, null);\n' + + ' }\n' + + '\n' + + ' /// Queues the message (bounceable or non-bounceable) to be sent to the specified address `to`.\n' + + ' /// Optionally, you may provide a `body` of the message and the `init` package with `initOf`.\n' + + ' ///\n' + + ' /// When `self.storageReserve` constant is overwritten to be greater than zero, before sending a\n' + + ' /// message it also tries to reserve the `self.storageReserve` amount of nanoToncoins from the\n' + + ' /// remaining balance before making the send in the `SendRemainingBalance` (128) mode.\n' + + ' ///\n' + + ' /// In case reservation attempt fails and in the default case without the attempt, the message\n' + + ' /// is sent with the `SendRemainingValue` (64) mode instead.\n' + + ' ///\n' + + ' /// > Note that `self.forward()` never sends additional nanoToncoins on top of what’s available on the balance.\n' + + ' /// > To be able to send more nanoToncoins with a single message, use the the `send` function.\n' + + ' ///\n' + + ' /// See: https://docs.tact-lang.org/ref/core-base#self-forward\n' + + ' ///\n' + + ' virtual fun forward(to: Address, body: Cell?, bounce: Bool, init: StateInit?) {\n' + + ' let code: Cell? = null;\n' + + ' let data: Cell? = null;\n' + + ' if (init != null) {\n' + + ' let init2: StateInit = init!!;\n' + + ' code = init2.code;\n' + + ' data = init2.data;\n' + + ' }\n' + + '\n' + + ' // Lock storage if needed\n' + + ' if (self.storageReserve > 0) { // Optimized in compile-time\n' + + ' let ctx: Context = context();\n' + + ' let balance: Int = myBalance();\n' + + ' let balanceBeforeMessage: Int = balance - ctx.value;\n' + + ' if (balanceBeforeMessage < self.storageReserve) {\n' + + ' nativeReserve(self.storageReserve, ReserveExact);\n' + + ' send(SendParameters {\n' + + ' bounce,\n' + + ' to,\n' + + ' value: 0,\n' + + ' mode: SendRemainingBalance | SendIgnoreErrors,\n' + + ' body,\n' + + ' code,\n' + + ' data,\n' + + ' });\n' + + ' return;\n' + + ' }\n' + + ' }\n' + + '\n' + + ' // Just send with remaining balance\n' + + ' send(SendParameters {\n' + + ' bounce,\n' + + ' to,\n' + + ' value: 0,\n' + + ' mode: SendRemainingValue | SendIgnoreErrors,\n' + + ' body,\n' + + ' code,\n' + + ' data,\n' + + ' });\n' + + ' }\n' + + '}\n', + imports: [], + items: [ + { + kind: 'trait', + name: { + kind: 'type_id', + text: 'BaseTrait', + loc: { start: 389, end: 398 } + }, + traits: [], + attributes: [], + declarations: [ + { + kind: 'field_const', + virtual: true, + override: false, + body: { + kind: 'constant', + name: { + kind: 'id', + text: 'storageReserve', + loc: { start: 1020, end: 1034 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1036, end: 1039 } + }, + loc: { start: 1036, end: 1039 } + }, + initializer: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 1042, end: 1043 } + } + }, + loc: { start: 1006, end: 1044 } + } + }, + { + kind: 'method', + mutates: false, + virtual: true, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'reply', + loc: { start: 1652, end: 1657 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'body', + loc: { start: 1658, end: 1662 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 1668, end: 1669 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 1664, end: 1668 } + }, + loc: { start: 1664, end: 1668 } + } + ], + loc: { start: 1668, end: 1669 } + }, + loc: { start: 1658, end: 1669 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 1681, end: 1685 } + }, + method: { + kind: 'id', + text: 'forward', + loc: { start: 1686, end: 1693 } + }, + typeArgs: [], + args: [ + { + kind: 'static_call', + function: { + kind: 'id', + text: 'sender', + loc: { start: 1694, end: 1700 } + }, + typeArgs: [], + args: [], + loc: { start: 1694, end: 1702 } + }, + { + kind: 'var', + name: 'body', + loc: { start: 1704, end: 1708 } + }, + { + kind: 'boolean', + value: true, + loc: { start: 1710, end: 1714 } + }, + { + kind: 'null', + loc: { start: 1716, end: 1720 } + } + ], + loc: { start: 1681, end: 1721 } + }, + loc: { start: 1681, end: 1722 } + } + ] + }, + loc: { start: 1633, end: 1728 } + } + }, + { + kind: 'method', + mutates: false, + virtual: true, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'notify', + loc: { start: 2341, end: 2347 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'body', + loc: { start: 2348, end: 2352 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2358, end: 2359 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2354, end: 2358 } + }, + loc: { start: 2354, end: 2358 } + } + ], + loc: { start: 2358, end: 2359 } + }, + loc: { start: 2348, end: 2359 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 2371, end: 2375 } + }, + method: { + kind: 'id', + text: 'forward', + loc: { start: 2376, end: 2383 } + }, + typeArgs: [], + args: [ + { + kind: 'static_call', + function: { + kind: 'id', + text: 'sender', + loc: { start: 2384, end: 2390 } + }, + typeArgs: [], + args: [], + loc: { start: 2384, end: 2392 } + }, + { + kind: 'var', + name: 'body', + loc: { start: 2394, end: 2398 } + }, + { + kind: 'boolean', + value: false, + loc: { start: 2400, end: 2405 } + }, + { + kind: 'null', + loc: { start: 2407, end: 2411 } + } + ], + loc: { start: 2371, end: 2412 } + }, + loc: { start: 2371, end: 2413 } + } + ] + }, + loc: { start: 2322, end: 2419 } + } + }, + { + kind: 'method', + mutates: false, + virtual: true, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'forward', + loc: { start: 3412, end: 3419 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'to', + loc: { start: 3420, end: 3422 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3424, end: 3431 } + }, + typeArgs: [], + loc: { start: 3424, end: 3431 } + }, + loc: { start: 3420, end: 3431 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'body', + loc: { start: 3433, end: 3437 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 3443, end: 3444 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 3439, end: 3443 } + }, + loc: { start: 3439, end: 3443 } + } + ], + loc: { start: 3443, end: 3444 } + }, + loc: { start: 3433, end: 3444 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 3446, end: 3452 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 3454, end: 3458 } + }, + typeArgs: [], + loc: { start: 3454, end: 3458 } + }, + loc: { start: 3446, end: 3458 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'init', + loc: { start: 3460, end: 3464 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 3475, end: 3476 } + }, + typeArgs: [ + { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 3466, end: 3475 } + }, + typeArgs: [], + loc: { start: 3466, end: 3475 } + } + ], + loc: { start: 3475, end: 3476 } + }, + loc: { start: 3460, end: 3476 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'code', + loc: { start: 3492, end: 3496 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 3502, end: 3503 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 3498, end: 3502 } + }, + loc: { start: 3498, end: 3502 } + } + ], + loc: { start: 3502, end: 3503 } + }, + expression: { + kind: 'null', + loc: { start: 3506, end: 3510 } + }, + loc: { start: 3488, end: 3511 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'data', + loc: { start: 3524, end: 3528 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 3534, end: 3535 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 3530, end: 3534 } + }, + loc: { start: 3530, end: 3534 } + } + ], + loc: { start: 3534, end: 3535 } + }, + expression: { + kind: 'null', + loc: { start: 3538, end: 3542 } + }, + loc: { start: 3520, end: 3543 } + }, + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '!=', + left: { + kind: 'var', + name: 'init', + loc: { start: 3556, end: 3560 } + }, + right: { + kind: 'null', + loc: { start: 3564, end: 3568 } + }, + loc: { start: 3556, end: 3568 } + }, + trueStatements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'init2', + loc: { start: 3588, end: 3593 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 3595, end: 3604 } + }, + typeArgs: [], + loc: { start: 3595, end: 3604 } + }, + expression: { + kind: 'op_unary', + op: '!!', + operand: { + kind: 'var', + name: 'init', + loc: { start: 3607, end: 3611 } + }, + loc: { start: 3607, end: 3613 } + }, + loc: { start: 3584, end: 3614 } + }, + { + kind: 'statement_assign', + path: { + kind: 'var', + name: 'code', + loc: { start: 3627, end: 3631 } + }, + expression: { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'init2', + loc: { start: 3634, end: 3639 } + }, + field: { + kind: 'id', + text: 'code', + loc: { start: 3640, end: 3644 } + }, + loc: { start: 3634, end: 3644 } + }, + loc: { start: 3627, end: 3645 } + }, + { + kind: 'statement_assign', + path: { + kind: 'var', + name: 'data', + loc: { start: 3658, end: 3662 } + }, + expression: { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'init2', + loc: { start: 3665, end: 3670 } + }, + field: { + kind: 'id', + text: 'data', + loc: { start: 3671, end: 3675 } + }, + loc: { start: 3665, end: 3675 } + }, + loc: { start: 3658, end: 3676 } + } + ], + falseStatements: undefined, + loc: { start: 3552, end: 3686 } + }, + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '>', + left: { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'self', + loc: { start: 3734, end: 3738 } + }, + field: { + kind: 'id', + text: 'storageReserve', + loc: { start: 3739, end: 3753 } + }, + loc: { start: 3734, end: 3753 } + }, + right: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 3756, end: 3757 } + }, + loc: { start: 3734, end: 3757 } + }, + trueStatements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'ctx', + loc: { start: 3806, end: 3809 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Context', + loc: { start: 3811, end: 3818 } + }, + typeArgs: [], + loc: { start: 3811, end: 3818 } + }, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'context', + loc: { start: 3821, end: 3828 } + }, + typeArgs: [], + args: [], + loc: { start: 3821, end: 3830 } + }, + loc: { start: 3802, end: 3831 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'balance', + loc: { start: 3848, end: 3855 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3857, end: 3860 } + }, + loc: { start: 3857, end: 3860 } + }, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'myBalance', + loc: { start: 3863, end: 3872 } + }, + typeArgs: [], + args: [], + loc: { start: 3863, end: 3874 } + }, + loc: { start: 3844, end: 3875 } + }, + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'balanceBeforeMessage', + loc: { start: 3892, end: 3912 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3914, end: 3917 } + }, + loc: { start: 3914, end: 3917 } + }, + expression: { + kind: 'op_binary', + op: '-', + left: { + kind: 'var', + name: 'balance', + loc: { start: 3920, end: 3927 } + }, + right: { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'ctx', + loc: { start: 3930, end: 3933 } + }, + field: { + kind: 'id', + text: 'value', + loc: { start: 3934, end: 3939 } + }, + loc: { start: 3930, end: 3939 } + }, + loc: { start: 3920, end: 3939 } + }, + loc: { start: 3888, end: 3940 } + }, + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '<', + left: { + kind: 'var', + name: 'balanceBeforeMessage', + loc: { start: 3957, end: 3977 } + }, + right: { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'self', + loc: { start: 3980, end: 3984 } + }, + field: { + kind: 'id', + text: 'storageReserve', + loc: { start: 3985, end: 3999 } + }, + loc: { start: 3980, end: 3999 } + }, + loc: { start: 3957, end: 3999 } + }, + trueStatements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'nativeReserve', + loc: { + start: 4019, + end: 4032 + } + }, + typeArgs: [], + args: [ + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'self', + loc: { + start: 4033, + end: 4037 + } + }, + field: { + kind: 'id', + text: 'storageReserve', + loc: { + start: 4038, + end: 4052 + } + }, + loc: { + start: 4033, + end: 4052 + } + }, + { + kind: 'var', + name: 'ReserveExact', + loc: { + start: 4054, + end: 4066 + } + } + ], + loc: { start: 4019, end: 4067 } + }, + loc: { start: 4019, end: 4068 } + }, + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'send', + loc: { + start: 4085, + end: 4089 + } + }, + typeArgs: [], + args: [ + { + kind: 'struct_instance', + type: { + kind: 'type_id', + text: 'SendParameters', + loc: { + start: 4090, + end: 4104 + } + }, + typeArgs: [], + args: [ + { + kind: 'struct_field_initializer', + field: { + kind: 'id', + text: 'bounce', + loc: { + start: 4127, + end: 4133 + } + }, + initializer: { + kind: 'var', + name: 'bounce', + loc: { + start: 4127, + end: 4133 + } + }, + loc: { + start: 4127, + end: 4133 + } + }, + { + kind: 'struct_field_initializer', + field: { + kind: 'id', + text: 'to', + loc: { + start: 4155, + end: 4157 + } + }, + initializer: { + kind: 'var', + name: 'to', + loc: { + start: 4155, + end: 4157 + } + }, + loc: { + start: 4155, + end: 4157 + } + }, + { + kind: 'struct_field_initializer', + field: { + kind: 'id', + text: 'value', + loc: { + start: 4179, + end: 4184 + } + }, + initializer: { + kind: 'number', + base: '10', + value: 0n, + loc: { + start: 4186, + end: 4187 + } + }, + loc: { + start: 4179, + end: 4187 + } + }, + { + kind: 'struct_field_initializer', + field: { + kind: 'id', + text: 'mode', + loc: { + start: 4209, + end: 4213 + } + }, + initializer: { + kind: 'op_binary', + op: '|', + left: { + kind: 'var', + name: 'SendRemainingBalance', + loc: { + start: 4215, + end: 4235 + } + }, + right: { + kind: 'var', + name: 'SendIgnoreErrors', + loc: { + start: 4238, + end: 4254 + } + }, + loc: { + start: 4215, + end: 4254 + } + }, + loc: { + start: 4209, + end: 4254 + } + }, + { + kind: 'struct_field_initializer', + field: { + kind: 'id', + text: 'body', + loc: { + start: 4276, + end: 4280 + } + }, + initializer: { + kind: 'var', + name: 'body', + loc: { + start: 4276, + end: 4280 + } + }, + loc: { + start: 4276, + end: 4280 + } + }, + { + kind: 'struct_field_initializer', + field: { + kind: 'id', + text: 'code', + loc: { + start: 4302, + end: 4306 + } + }, + initializer: { + kind: 'var', + name: 'code', + loc: { + start: 4302, + end: 4306 + } + }, + loc: { + start: 4302, + end: 4306 + } + }, + { + kind: 'struct_field_initializer', + field: { + kind: 'id', + text: 'data', + loc: { + start: 4328, + end: 4332 + } + }, + initializer: { + kind: 'var', + name: 'data', + loc: { + start: 4328, + end: 4332 + } + }, + loc: { + start: 4328, + end: 4332 + } + } + ], + loc: { + start: 4090, + end: 4351 + } + } + ], + loc: { start: 4085, end: 4352 } + }, + loc: { start: 4085, end: 4353 } + }, + { + kind: 'statement_return', + expression: undefined, + loc: { start: 4370, end: 4377 } + } + ], + falseStatements: undefined, + loc: { start: 3953, end: 4391 } + } + ], + falseStatements: undefined, + loc: { start: 3730, end: 4401 } + }, + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'send', + loc: { start: 4455, end: 4459 } + }, + typeArgs: [], + args: [ + { + kind: 'struct_instance', + type: { + kind: 'type_id', + text: 'SendParameters', + loc: { start: 4460, end: 4474 } + }, + typeArgs: [], + args: [ + { + kind: 'struct_field_initializer', + field: { + kind: 'id', + text: 'bounce', + loc: { + start: 4489, + end: 4495 + } + }, + initializer: { + kind: 'var', + name: 'bounce', + loc: { + start: 4489, + end: 4495 + } + }, + loc: { start: 4489, end: 4495 } + }, + { + kind: 'struct_field_initializer', + field: { + kind: 'id', + text: 'to', + loc: { + start: 4509, + end: 4511 + } + }, + initializer: { + kind: 'var', + name: 'to', + loc: { + start: 4509, + end: 4511 + } + }, + loc: { start: 4509, end: 4511 } + }, + { + kind: 'struct_field_initializer', + field: { + kind: 'id', + text: 'value', + loc: { + start: 4525, + end: 4530 + } + }, + initializer: { + kind: 'number', + base: '10', + value: 0n, + loc: { + start: 4532, + end: 4533 + } + }, + loc: { start: 4525, end: 4533 } + }, + { + kind: 'struct_field_initializer', + field: { + kind: 'id', + text: 'mode', + loc: { + start: 4547, + end: 4551 + } + }, + initializer: { + kind: 'op_binary', + op: '|', + left: { + kind: 'var', + name: 'SendRemainingValue', + loc: { + start: 4553, + end: 4571 + } + }, + right: { + kind: 'var', + name: 'SendIgnoreErrors', + loc: { + start: 4574, + end: 4590 + } + }, + loc: { + start: 4553, + end: 4590 + } + }, + loc: { start: 4547, end: 4590 } + }, + { + kind: 'struct_field_initializer', + field: { + kind: 'id', + text: 'body', + loc: { + start: 4604, + end: 4608 + } + }, + initializer: { + kind: 'var', + name: 'body', + loc: { + start: 4604, + end: 4608 + } + }, + loc: { start: 4604, end: 4608 } + }, + { + kind: 'struct_field_initializer', + field: { + kind: 'id', + text: 'code', + loc: { + start: 4622, + end: 4626 + } + }, + initializer: { + kind: 'var', + name: 'code', + loc: { + start: 4622, + end: 4626 + } + }, + loc: { start: 4622, end: 4626 } + }, + { + kind: 'struct_field_initializer', + field: { + kind: 'id', + text: 'data', + loc: { + start: 4640, + end: 4644 + } + }, + initializer: { + kind: 'var', + name: 'data', + loc: { + start: 4640, + end: 4644 + } + }, + loc: { start: 4640, end: 4644 } + } + ], + loc: { start: 4460, end: 4655 } + } + ], + loc: { start: 4455, end: 4656 } + }, + loc: { start: 4455, end: 4657 } + } + ] + }, + loc: { start: 3400, end: 4663 } + } + } + ], + loc: { start: 383, end: 4665 } + } + ] + }, + loc: { start: 340, end: 365 } + }, + { + kind: 'tact', + source: { + kind: 'tact', + path: 'std/internal/address.tact', + code: '/// Extension function for the `Slice` type. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Casts the `Slice` to an `Address` in a given `chain` ID and returns it. The inverse of `Address.asSlice()` and a safe but more gas-expensive version of `Slice.asAddressUnsafe()`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + "/// let a: Address = myAddress(); // let's assume we're in a basechain\n" + + '/// let a2: Address = a.asSlice().asAddress(0); // so the chain ID is 0\n' + + '///\n' + + '/// a == a2; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 136: [Invalid standard address] — Thrown when the given `Slice` contains an invalid\n' + + '/// tag prefix (not `0b100`) or an invalid account ID length (not 256 bits).\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#sliceasaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#sliceasaddressunsafe\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#addressasslice\n' + + '///\n' + + '/// [Invalid standard address]: https://docs.tact-lang.org/book/exit-codes#136\n' + + '///\n' + + 'extends fun asAddress(self: Slice, chain: Int): Address {\n' + + ' // 11 bits for the prefix,\n' + + ' // 256 bits for the address itself\n' + + ' throwUnless(TactExitCodeInvalidStandardAddress, self.bits() == 267);\n' + + '\n' + + ' if (chain == -1) {\n' + + ' // 1279 = 0b100_1111_1111,\n' + + ' // i.e. internal address prefix and chain ID -1\n' + + ' throwUnless(TactExitCodeInvalidStandardAddress, self.preloadUint(11) == 1279);\n' + + ' } else {\n' + + ' // Only check the correct internal address prefix,\n' + + ' // but do not verify the chain ID\n' + + ' throwUnless(TactExitCodeInvalidStandardAddress, self.preloadUint(3) == 4);\n' + + ' }\n' + + '\n' + + ' // Proceed with the cast\n' + + ' return self.asAddressUnsafe();\n' + + '}\n' + + '\n' + + '/// Extension function for the `Slice` type. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Unsafely casts the `Slice` to an `Address` and returns it. The inverse of `Address.asSlice()`.\n' + + '///\n' + + '/// This function does **not** perform any checks on the contents of the `Slice`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let a: Address = myAddress();\n' + + '/// let a2: Address = a.asSlice().asAddressUnsafe();\n' + + '///\n' + + '/// a == a2; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// Use it only if you want to optimize the code for gas and can guarantee in advance that the `Slice` contains the data of an `Address`.\n' + + '///\n' + + '/// Otherwise, use a safer but more gas-expensive `Slice.asAddress()` function.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#sliceasaddressunsafe\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#sliceasaddress\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#addressasslice\n' + + '///\n' + + 'asm extends fun asAddressUnsafe(self: Slice): Address {}\n' + + '\n' + + '/// Extension function for the `Address` type.\n' + + '///\n' + + '/// Casts `self` back to the underlying `Slice` and returns it. The inverse of `Slice.asAddressUnsafe()`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let a: Address = myAddress();\n' + + '/// let fizz: Slice = beginCell().storeAddress(a).asSlice();\n' + + '/// let buzz: Slice = a.asSlice(); // cheap, unlike the previous statement\n' + + '///\n' + + '/// fizz == buzz; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#addressasslice\n' + + '/// * https://docs.tact-lang.org/ref/core-cells#sliceasaddressunsafe\n' + + '///\n' + + 'asm extends fun asSlice(self: Address): Slice {}\n' + + '\n' + + '/// Global function.\n' + + '///\n' + + '/// Creates a new `Address` based on the `chain` ID and the SHA-256 encoded `hash` value (account ID).\n' + + '///\n' + + '/// This function tries to resolve constant values in compile-time whenever possible.\n' + + '///\n' + + '/// Attempts to specify an uncommon `chain` ID (not -1 or 0) that can be detected in compile-time will result in a compilation error.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let oldTonFoundationAddr: Address =\n' + + '/// newAddress(0, 0x83dfd552e63729b472fcbcc8c45ebcc6691702558b68ec7527e1ba403a0f31a8);\n' + + '/// // ↑ ↑\n' + + "/// // | sha-256 hash of contract's init package (StateInit)\n" + + '/// // chain id: 0 is a workchain, -1 is a masterchain\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-addresses#newaddress\n' + + '///\n' + + 'inline fun newAddress(chain: Int, hash: Int): Address {\n' + + ' return beginCell()\n' + + ' .storeUint(0b10_0, 3)\n' + + ' .storeInt(chain, 8)\n' + + ' .storeUint(hash, 256)\n' + + ' .endCell()\n' + + ' .asSlice()\n' + + ' .asAddressUnsafe();\n' + + '}\n' + + '\n' + + '/// Struct representing the standard address on TON Blockchain with signed 8-bit `workchain` ID and an unsigned 256-bit `address` in the specified `workchain`. Available since Tact 1.5.0.\n' + + '///\n' + + '/// At the moment, only `workchain` IDs used on TON are 0 of the basechain and -1 of the masterchain.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#parsestdaddress\n' + + '/// * https://github.com/ton-blockchain/ton/blob/master/crypto/block/block.tlb#L105-L106\n' + + '///\n' + + 'struct StdAddress {\n' + + ' workchain: Int as int8;\n' + + ' address: Int as uint256;\n' + + '}\n' + + '\n' + + '/// Struct representing the address of variable length with signed 32-bit `workchain` ID and a `Slice` containing unsigned `address` in the specified `workchain`. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Variable-length addresses are intended for future extensions, and while validators must be ready to accept them in inbound messages, the standard (non-variable) addresses are used whenever possible.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-addresses#parsevaraddress\n' + + '/// * https://github.com/ton-blockchain/ton/blob/master/crypto/block/block.tlb#L107-L108\n' + + '///\n' + + 'struct VarAddress {\n' + + ' workchain: Int as int32;\n' + + ' address: Slice;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Converts a `slice` containing an address into the `StdAddress` Struct and returns it.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let addr = address("EQDtFpEwcFAEcRe5mLVh2N6C0x-_hJEM7W61_JLnSF74p4q2");\n' + + '/// let parsedAddr = parseStdAddress(addr.asSlice());\n' + + '///\n' + + '/// parsedAddr.workchain; // 0\n' + + '/// parsedAddr.address; // 107...287\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-addresses#parsestdaddress\n' + + '///\n' + + 'asm fun parseStdAddress(slice: Slice): StdAddress { REWRITESTDADDR }\n' + + '\n' + + '/// Global function. Available since Tact 1.5.0.\n' + + '///\n' + + '/// Converts a `slice` containing an address of variable length into the `VarAddress` Struct and returns it.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let varAddrSlice = beginCell()\n' + + '/// .storeUint(6, 3) // to recognize the following as a VarAddress\n' + + '/// .storeUint(123, 9) // make address occupy 123 bits\n' + + '/// .storeUint(234, 32) // specify workchain ID of 234\n' + + '/// .storeUint(345, 123) // specify address of 345\n' + + '/// .asSlice();\n' + + '/// let parsedVarAddr = parseVarAddress(varAddrSlice);\n' + + '///\n' + + '/// parsedVarAddr.workchain; // 234\n' + + '/// parsedVarAddr.address; // CS{Cell{002...2b3} bits: 44..167; refs: 0..0}\n' + + '/// parsedVarAddr.address.loadUint(123); // 345\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-addresses#parsevaraddress\n' + + '///\n' + + 'asm fun parseVarAddress(slice: Slice): VarAddress { REWRITEVARADDR }\n' + + '\n' + + '/// Extension mutation function for the `Slice` type.\n' + + '///\n' + + '/// Loads and returns an `Address` from the `Slice`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let s: Slice = beginCell().storeAddress(myAddress()).asSlice();\n' + + '/// let fizz: Address = s.loadAddress();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + "/// * 8: [Cell overflow] — Thrown when attempting to load an `Address` when `Slice` doesn't contain it.\n" + + '/// * 9: [Cell underflow] — Thrown when attempting to load more data than `Slice` contains.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#sliceloadaddress\n' + + '///\n' + + '/// [Cell overflow]: https://docs.tact-lang.org/book/exit-codes#8\n' + + '/// [Cell underflow]: https://docs.tact-lang.org/book/exit-codes#9\n' + + '///\n' + + 'asm(-> 1 0) extends mutates fun loadAddress(self: Slice): Address { LDMSGADDR }\n' + + '\n' + + '/// Extension mutation function for the `Slice` type. Available since Tact 1.6.2.\n' + + '///\n' + + '/// Skips an `Address` from the `Slice`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let s1: Slice = beginCell()\n' + + '/// .storeAddress(myAddress())\n' + + '/// .storeUint(42, 32)\n' + + '/// .asSlice();\n' + + '///\n' + + '/// s1.skipAddress();\n' + + '/// let fizz: Int = s1.loadUint(32); // 42\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + "/// * 8: [Cell overflow] — Thrown when attempting to skip an `Address` when `Slice` doesn't contain it.\n" + + '/// * 9: [Cell underflow] — Thrown when attempting to skip more data than `Slice` contains.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#sliceskipaddress\n' + + '///\n' + + '/// [Cell overflow]: https://docs.tact-lang.org/book/exit-codes#8\n' + + '/// [Cell underflow]: https://docs.tact-lang.org/book/exit-codes#9\n' + + '///\n' + + 'asm extends mutates fun skipAddress(self: Slice) { LDMSGADDR NIP }\n' + + '\n' + + '/// Extension function for the `Builder` type.\n' + + '///\n' + + '/// Stores the `address` in the copy of the `Builder`. Returns that copy.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let b: Builder = beginCell();\n' + + '/// let fizz: Builder = b.storeAddress(myAddress());\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 8: [Cell overflow] — Thrown when attempting to store an `address` into the `Builder` when it cannot fit it.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-cells#builderstoreaddress\n' + + '///\n' + + '/// [Cell overflow]: https://docs.tact-lang.org/book/exit-codes#8\n' + + '///\n' + + 'asm extends fun storeAddress(self: Builder, address: Address): Builder { STSLICER }\n' + + '\n' + + '/// Struct representing a basechain address. Available since Tact 1.6.0.\n' + + '///\n' + + '/// A basechain address (workchain 0) can be either empty (null hash) or contain a 256-bit hash value.\n' + + '///\n' + + 'struct BasechainAddress {\n' + + ' hash: Int?;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Creates and returns an empty basechain address with a null hash.\n' + + '///\n' + + '/// When serialized, an empty basechain address is represented as `addr_none`.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let emptyAddr: BasechainAddress = emptyBasechainAddress();\n' + + '/// emptyAddr.hash == null; // true\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + 'inline fun emptyBasechainAddress(): BasechainAddress {\n' + + ' return BasechainAddress { hash: null };\n' + + '}\n' + + '\n' + + '/// Global f'... 4363 more characters, + imports: [], + items: [ + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'asAddress', + loc: { start: 998, end: 1007 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 1034, end: 1041 } + }, + typeArgs: [], + loc: { start: 1034, end: 1041 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'chain', + loc: { start: 1021, end: 1026 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1028, end: 1031 } + }, + loc: { start: 1028, end: 1031 } + }, + loc: { start: 1021, end: 1031 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throwUnless', + loc: { start: 1118, end: 1129 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'TactExitCodeInvalidStandardAddress', + loc: { start: 1130, end: 1164 } + }, + { + kind: 'op_binary', + op: '==', + left: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 1166, end: 1170 } + }, + method: { + kind: 'id', + text: 'bits', + loc: { start: 1171, end: 1175 } + }, + typeArgs: [], + args: [], + loc: { start: 1166, end: 1177 } + }, + right: { + kind: 'number', + base: '10', + value: 267n, + loc: { start: 1181, end: 1184 } + }, + loc: { start: 1166, end: 1184 } + } + ], + loc: { start: 1118, end: 1185 } + }, + loc: { start: 1118, end: 1186 } + }, + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'var', + name: 'chain', + loc: { start: 1196, end: 1201 } + }, + right: { + kind: 'op_unary', + op: '-', + operand: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1206, end: 1207 } + }, + loc: { start: 1205, end: 1207 } + }, + loc: { start: 1196, end: 1207 } + }, + trueStatements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throwUnless', + loc: { start: 1310, end: 1321 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'TactExitCodeInvalidStandardAddress', + loc: { start: 1322, end: 1356 } + }, + { + kind: 'op_binary', + op: '==', + left: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { + start: 1358, + end: 1362 + } + }, + method: { + kind: 'id', + text: 'preloadUint', + loc: { + start: 1363, + end: 1374 + } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 11n, + loc: { + start: 1375, + end: 1377 + } + } + ], + loc: { start: 1358, end: 1378 } + }, + right: { + kind: 'number', + base: '10', + value: 1279n, + loc: { start: 1382, end: 1386 } + }, + loc: { start: 1358, end: 1386 } + } + ], + loc: { start: 1310, end: 1387 } + }, + loc: { start: 1310, end: 1388 } + } + ], + falseStatements: [ + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'throwUnless', + loc: { start: 1511, end: 1522 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'TactExitCodeInvalidStandardAddress', + loc: { start: 1523, end: 1557 } + }, + { + kind: 'op_binary', + op: '==', + left: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { + start: 1559, + end: 1563 + } + }, + method: { + kind: 'id', + text: 'preloadUint', + loc: { + start: 1564, + end: 1575 + } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 3n, + loc: { + start: 1576, + end: 1577 + } + } + ], + loc: { start: 1559, end: 1578 } + }, + right: { + kind: 'number', + base: '10', + value: 4n, + loc: { start: 1582, end: 1583 } + }, + loc: { start: 1559, end: 1583 } + } + ], + loc: { start: 1511, end: 1584 } + }, + loc: { start: 1511, end: 1585 } + } + ], + loc: { start: 1192, end: 1591 } + }, + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 1633, end: 1637 } + }, + method: { + kind: 'id', + text: 'asAddressUnsafe', + loc: { start: 1638, end: 1653 } + }, + typeArgs: [], + args: [], + loc: { start: 1633, end: 1655 } + }, + loc: { start: 1626, end: 1656 } + } + ] + }, + loc: { start: 986, end: 1658 } + } + }, + selfType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 1014, end: 1019 } + }, + loc: { start: 1014, end: 1019 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'asAddressUnsafe', + loc: { start: 2554, end: 2569 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 2584, end: 2591 } + }, + typeArgs: [], + loc: { start: 2584, end: 2591 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ '' ] + }, + loc: { start: 2538, end: 2594 } + } + }, + selfType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 2576, end: 2581 } + }, + loc: { start: 2576, end: 2581 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'asSlice', + loc: { start: 3188, end: 3195 } + }, + typeParams: [], + returnType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 3212, end: 3217 } + }, + loc: { start: 3212, end: 3217 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ '' ] + }, + loc: { start: 3172, end: 3220 } + } + }, + selfType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3202, end: 3209 } + }, + typeArgs: [], + loc: { start: 3202, end: 3209 } + } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'newAddress', + loc: { start: 4029, end: 4039 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 4064, end: 4071 } + }, + typeArgs: [], + loc: { start: 4064, end: 4071 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'chain', + loc: { start: 4040, end: 4045 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4047, end: 4050 } + }, + loc: { start: 4047, end: 4050 } + }, + loc: { start: 4040, end: 4050 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'hash', + loc: { start: 4052, end: 4056 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 4058, end: 4061 } + }, + loc: { start: 4058, end: 4061 } + }, + loc: { start: 4052, end: 4061 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'static_call', + function: { + kind: 'id', + text: 'beginCell', + loc: { start: 4085, end: 4094 } + }, + typeArgs: [], + args: [], + loc: { start: 4085, end: 4096 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 4106, end: 4115 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '2', + value: 4n, + loc: { start: 4116, end: 4122 } + }, + { + kind: 'number', + base: '10', + value: 3n, + loc: { start: 4124, end: 4125 } + } + ], + loc: { start: 4085, end: 4126 } + }, + method: { + kind: 'id', + text: 'storeInt', + loc: { start: 4136, end: 4144 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'chain', + loc: { start: 4145, end: 4150 } + }, + { + kind: 'number', + base: '10', + value: 8n, + loc: { start: 4152, end: 4153 } + } + ], + loc: { start: 4085, end: 4154 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 4164, end: 4173 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'hash', + loc: { start: 4174, end: 4178 } + }, + { + kind: 'number', + base: '10', + value: 256n, + loc: { start: 4180, end: 4183 } + } + ], + loc: { start: 4085, end: 4184 } + }, + method: { + kind: 'id', + text: 'endCell', + loc: { start: 4194, end: 4201 } + }, + typeArgs: [], + args: [], + loc: { start: 4085, end: 4203 } + }, + method: { + kind: 'id', + text: 'asSlice', + loc: { start: 4213, end: 4220 } + }, + typeArgs: [], + args: [], + loc: { start: 4085, end: 4222 } + }, + method: { + kind: 'id', + text: 'asAddressUnsafe', + loc: { start: 4232, end: 4247 } + }, + typeArgs: [], + args: [], + loc: { start: 4085, end: 4249 } + }, + loc: { start: 4078, end: 4250 } + } + ] + }, + loc: { start: 4018, end: 4252 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'StdAddress', + loc: { start: 4729, end: 4739 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'workchain', + loc: { start: 4746, end: 4755 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 8, + loc: { start: 4757, end: 4768 } + }, + loc: { start: 4757, end: 4760 } + }, + initializer: undefined, + loc: { start: 4746, end: 4768 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'address', + loc: { start: 4774, end: 4781 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'unsigned', + width: 256, + loc: { start: 4783, end: 4797 } + }, + loc: { start: 4783, end: 4786 } + }, + initializer: undefined, + loc: { start: 4774, end: 4797 } + } + ], + loc: { start: 4722, end: 4800 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'VarAddress', + loc: { start: 5381, end: 5391 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'workchain', + loc: { start: 5398, end: 5407 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 32, + loc: { start: 5409, end: 5421 } + }, + loc: { start: 5409, end: 5412 } + }, + initializer: undefined, + loc: { start: 5398, end: 5421 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'address', + loc: { start: 5427, end: 5434 } + }, + type: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 5436, end: 5441 } + }, + loc: { start: 5436, end: 5441 } + }, + initializer: undefined, + loc: { start: 5427, end: 5441 } + } + ], + loc: { start: 5374, end: 5444 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'parseStdAddress', + loc: { start: 5946, end: 5961 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StdAddress', + loc: { start: 5977, end: 5987 } + }, + typeArgs: [], + loc: { start: 5977, end: 5987 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'slice', + loc: { start: 5962, end: 5967 } + }, + type: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 5969, end: 5974 } + }, + loc: { start: 5969, end: 5974 } + }, + loc: { start: 5962, end: 5974 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'REWRITESTDADDR' ] + }, + loc: { start: 5938, end: 6006 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'parseVarAddress', + loc: { start: 6898, end: 6913 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'VarAddress', + loc: { start: 6929, end: 6939 } + }, + typeArgs: [], + loc: { start: 6929, end: 6939 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'slice', + loc: { start: 6914, end: 6919 } + }, + type: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 6921, end: 6926 } + }, + loc: { start: 6921, end: 6926 } + }, + loc: { start: 6914, end: 6926 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'REWRITEVARADDR' ] + }, + loc: { start: 6890, end: 6958 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'loadAddress', + loc: { start: 7707, end: 7718 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 7733, end: 7740 } + }, + typeArgs: [], + loc: { start: 7733, end: 7740 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { + args: [], + ret: [ + { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 7682, end: 7683 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 7684, end: 7685 } + } + ] + }, + instructions: [ 'LDMSGADDR' ] + }, + loc: { start: 7675, end: 7754 } + } + }, + selfType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 7725, end: 7730 } + }, + loc: { start: 7725, end: 7730 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: true, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'skipAddress', + loc: { start: 8601, end: 8612 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LDMSGADDR NIP' ] + }, + loc: { start: 8577, end: 8643 } + } + }, + selfType: { + kind: 'TySlice', + format: { + kind: 'SFDefault', + loc: { start: 8619, end: 8624 } + }, + loc: { start: 8619, end: 8624 } + } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeAddress', + loc: { start: 9222, end: 9234 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 9269, end: 9276 } + }, + loc: { start: 9269, end: 9276 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'address', + loc: { start: 9250, end: 9257 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 9259, end: 9266 } + }, + typeArgs: [], + loc: { start: 9259, end: 9266 } + }, + loc: { start: 9250, end: 9266 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'STSLICER' ] + }, + loc: { start: 9206, end: 9289 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 9241, end: 9248 } + }, + loc: { start: 9241, end: 9248 } + } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 9482, end: 9498 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'hash', + loc: { start: 9505, end: 9509 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 9514, end: 9515 } + }, + typeArgs: [ + { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9511, end: 9514 } + }, + loc: { start: 9511, end: 9514 } + } + ], + loc: { start: 9514, end: 9515 } + }, + initializer: undefined, + loc: { start: 9505, end: 9515 } + } + ], + loc: { start: 9475, end: 9518 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'emptyBasechainAddress', + loc: { start: 9897, end: 9918 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 9922, end: 9938 } + }, + typeArgs: [], + loc: { start: 9922, end: 9938 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'struct_instance', + type: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 9952, end: 9968 } + }, + typeArgs: [], + args: [ + { + kind: 'struct_field_initializer', + field: { + kind: 'id', + text: 'hash', + loc: { start: 9971, end: 9975 } + }, + initializer: { + kind: 'null', + loc: { start: 9977, end: 9981 } + }, + loc: { start: 9971, end: 9981 } + } + ], + loc: { start: 9952, end: 9983 } + }, + loc: { start: 9945, end: 9984 } + } + ] + }, + loc: { start: 9886, end: 9986 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'newBasechainAddress', + loc: { start: 10311, end: 10330 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 10343, end: 10359 } + }, + typeArgs: [], + loc: { start: 10343, end: 10359 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'hash', + loc: { start: 10331, end: 10335 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 10337, end: 10340 } + }, + loc: { start: 10337, end: 10340 } + }, + loc: { start: 10331, end: 10340 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'struct_instance', + type: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 10373, end: 10389 } + }, + typeArgs: [], + args: [ + { + kind: 'struct_field_initializer', + field: { + kind: 'id', + text: 'hash', + loc: { start: 10392, end: 10396 } + }, + initializer: { + kind: 'var', + name: 'hash', + loc: { start: 10392, end: 10396 } + }, + loc: { start: 10392, end: 10396 } + } + ], + loc: { start: 10373, end: 10398 } + }, + loc: { start: 10366, end: 10399 } + } + ] + }, + loc: { start: 10300, end: 10401 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'contractBasechainAddress', + loc: { start: 10865, end: 10889 } + }, + typeParams: [], + returnType: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 10905, end: 10921 } + }, + typeArgs: [], + loc: { start: 10905, end: 10921 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 's', + loc: { start: 10890, end: 10891 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 10893, end: 10902 } + }, + typeArgs: [], + loc: { start: 10893, end: 10902 } + }, + loc: { start: 10890, end: 10902 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'hash', + loc: { start: 10932, end: 10936 } + }, + type: undefined, + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'contractHash', + loc: { start: 10939, end: 10951 } + }, + typeArgs: [], + args: [ + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 10952, end: 10953 } + }, + field: { + kind: 'id', + text: 'code', + loc: { start: 10954, end: 10958 } + }, + loc: { start: 10952, end: 10958 } + }, + { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 's', + loc: { start: 10960, end: 10961 } + }, + field: { + kind: 'id', + text: 'data', + loc: { start: 10962, end: 10966 } + }, + loc: { start: 10960, end: 10966 } + } + ], + loc: { start: 10939, end: 10967 } + }, + loc: { start: 10928, end: 10968 } + }, + { + kind: 'statement_return', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'newBasechainAddress', + loc: { start: 10980, end: 10999 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'hash', + loc: { start: 11000, end: 11004 } + } + ], + loc: { start: 10980, end: 11005 } + }, + loc: { start: 10973, end: 11006 } + } + ] + }, + loc: { start: 10854, end: 11008 } + }, + { + kind: 'extension', + fun: { + kind: 'method', + mutates: false, + virtual: false, + override: false, + get: undefined, + fun: { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'storeBasechainAddress', + loc: { start: 11633, end: 11654 } + }, + typeParams: [], + returnType: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 11698, end: 11705 } + }, + loc: { start: 11698, end: 11705 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'address', + loc: { start: 11670, end: 11677 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'BasechainAddress', + loc: { start: 11679, end: 11695 } + }, + typeArgs: [], + loc: { start: 11679, end: 11695 } + }, + loc: { start: 11670, end: 11695 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_condition', + condition: { + kind: 'op_binary', + op: '==', + left: { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'address', + loc: { start: 11716, end: 11723 } + }, + field: { + kind: 'id', + text: 'hash', + loc: { start: 11724, end: 11728 } + }, + loc: { start: 11716, end: 11728 } + }, + right: { + kind: 'null', + loc: { start: 11732, end: 11736 } + }, + loc: { start: 11716, end: 11736 } + }, + trueStatements: [ + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 11755, end: 11759 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 11760, end: 11769 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 11770, end: 11771 } + }, + { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 11773, end: 11774 } + } + ], + loc: { start: 11755, end: 11775 } + }, + loc: { start: 11748, end: 11776 } + } + ], + falseStatements: undefined, + loc: { start: 11712, end: 11790 } + }, + { + kind: 'statement_return', + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'var', + name: 'self', + loc: { start: 11803, end: 11807 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 11817, end: 11826 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '2', + value: 1024n, + loc: { start: 11827, end: 11842 } + }, + { + kind: 'op_binary', + op: '+', + left: { + kind: 'number', + base: '10', + value: 3n, + loc: { start: 11844, end: 11845 } + }, + right: { + kind: 'number', + base: '10', + value: 8n, + loc: { start: 11848, end: 11849 } + }, + loc: { start: 11844, end: 11849 } + } + ], + loc: { start: 11803, end: 11850 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 11860, end: 11869 } + }, + typeArgs: [], + args: [ + { + kind: 'op_unary', + op: '!!', + operand: { + kind: 'field_access', + aggregate: { + kind: 'var', + name: 'address', + loc: { start: 11870, end: 11877 } + }, + field: { + kind: 'id', + text: 'hash', + loc: { start: 11878, end: 11882 } + }, + loc: { start: 11870, end: 11882 } + }, + loc: { start: 11870, end: 11884 } + }, + { + kind: 'number', + base: '10', + value: 256n, + loc: { start: 11886, end: 11889 } + } + ], + loc: { start: 11803, end: 11890 } + }, + loc: { start: 11796, end: 11891 } + } + ] + }, + loc: { start: 11621, end: 11893 } + } + }, + selfType: { + kind: 'TyBuilder', + format: { + kind: 'SFDefault', + loc: { start: 11661, end: 11668 } + }, + loc: { start: 11661, end: 11668 } + } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'forceBasechain', + loc: { start: 12980, end: 12994 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'address', + loc: { start: 12995, end: 13002 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 13004, end: 13011 } + }, + typeArgs: [], + loc: { start: 13004, end: 13011 } + }, + loc: { start: 12995, end: 13011 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'REWRITESTDADDR DROP 138 THROWIF' ] + }, + loc: { start: 12972, end: 13048 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'forceWorkchain', + loc: { start: 14243, end: 14257 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'address', + loc: { start: 14258, end: 14265 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 14267, end: 14274 } + }, + typeArgs: [], + loc: { start: 14267, end: 14274 } + }, + loc: { start: 14258, end: 14274 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'workchain', + loc: { start: 14276, end: 14285 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14287, end: 14290 } + }, + loc: { start: 14287, end: 14290 } + }, + loc: { start: 14276, end: 14290 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'errorCode', + loc: { start: 14292, end: 14301 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 14303, end: 14306 } + }, + loc: { start: 14303, end: 14306 } + }, + loc: { start: 14292, end: 14306 } + } + ], + body: { + kind: 'asm_body', + shuffle: { + args: [ + { + kind: 'id', + text: 'errorCode', + loc: { start: 14210, end: 14219 } + }, + { + kind: 'id', + text: 'workchain', + loc: { start: 14220, end: 14229 } + }, + { + kind: 'id', + text: 'address', + loc: { start: 14230, end: 14237 } + } + ], + ret: [] + }, + instructions: [ + 'REWRITESTDADDR\n DROP\n CMP\n THROWANYIF' + ] + }, + loc: { start: 14206, end: 14362 } + } + ] + }, + loc: { start: 366, end: 394 } + }, + { + kind: 'tact', + source: { + kind: 'tact', + path: 'std/internal/time.tact', + code: '/// Global function.\n' + + '///\n' + + '/// Returns the current Unix time.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let timeOffset: Int = now() + 1000; // thousand seconds from now()\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#now\n' + + '///\n' + + 'asm fun now(): Int { NOW }\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Returns the `Int` value of the logical time of the current transaction.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let lt: Int = curLt();\n' + + '/// nativeRandomize(lt); // equivalent to calling nativeRandomizeLt()\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-contextstate#curlt\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomize\n' + + '/// * https://docs.tact-lang.org/ref/core-random#nativerandomizelt\n' + + '///\n' + + 'asm fun curLt(): Int { LTIME }\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Returns the `Int` value of the starting logical time of the current block.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// let time: Int = blockLt();\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#blocklt\n' + + '///\n' + + 'asm fun blockLt(): Int { BLOCKLT }\n', + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'now', + loc: { start: 263, end: 266 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 270, end: 273 } + }, + loc: { start: 270, end: 273 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'NOW' ] + }, + loc: { start: 255, end: 281 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'curLt', + loc: { start: 785, end: 790 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 794, end: 797 } + }, + loc: { start: 794, end: 797 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'LTIME' ] + }, + loc: { start: 777, end: 807 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'blockLt', + loc: { start: 1108, end: 1115 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1119, end: 1122 } + }, + loc: { start: 1119, end: 1122 } + }, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'BLOCKLT' ] + }, + loc: { start: 1100, end: 1134 } + } + ] + }, + loc: { start: 395, end: 420 } + } + ], + items: [] + }, + loc: { start: 0, end: 0 } + } + ], + items: [ + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'f', loc: { start: 4, end: 5 } }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9, end: 12 } + }, + loc: { start: 9, end: 12 } + }, + params: [], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_return', + expression: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 22, end: 23 } + }, + loc: { start: 15, end: 24 } + } + ] + }, + loc: { start: 0, end: 26 } + } + ] + } + }, + constants: Map(25) { + 'TactExitCodeNullReferenceException' => { + kind: 'tact', + path: 'std/internal/exit-codes.tact', + code: '/// Configurable since Tact 1.6.\n' + + '///\n' + + '/// Thrown when a null reference exception occurs during the compute phase.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#128\n' + + '///\n' + + 'const TactExitCodeNullReferenceException: Int = 128;\n' + + '\n' + + '/// Thrown when there is a failed deserialization attempt:\n' + + '/// a certain opcode prefix was expected, but a different one was parsed.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#129\n' + + '///\n' + + 'const TactExitCodeInvalidSerializationPrefix: Int = 129;\n' + + '\n' + + '/// Thrown when there is no receiver for the opcode of the received message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#130\n' + + '///\n' + + 'const TactExitCodeInvalidIncomingMessage: Int = 130;\n' + + '\n' + + '/// Constraints error. Reserved, but never thrown.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#131\n' + + '///\n' + + 'const TactExitCodeConstraintsError: Int = 131;\n' + + '\n' + + '/// Thrown when the sender is not the owner of the contract inheriting\n' + + '/// the `Ownable` trait and there has been a mismatch of the `self.owner`\n' + + "/// and the sender's address.\n" + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#132\n' + + '///\n' + + 'const TactExitCodeAccessDenied: Int = 132;\n' + + '\n' + + '/// Thrown when a message has been sent to a contract inheriting the `Stoppable`\n' + + '/// trait and has the `self.stopped` flag set to `true`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#133\n' + + '///\n' + + 'const TactExitCodeContractStopped: Int = 133;\n' + + '\n' + + '/// Thrown when an invalid or unexpected argument is passed to a function or method.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#134\n' + + '///\n' + + 'const TactExitCodeInvalidArgument: Int = 134;\n' + + '\n' + + "/// Thrown when a contract's code is missing.\n" + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#135\n' + + '///\n' + + 'const TactExitCodeContractCodeNotFound: Int = 135;\n' + + '\n' + + '/// Thrown when an address does not conform to the expected standard format.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#136\n' + + '///\n' + + 'const TactExitCodeInvalidStandardAddress: Int = 136;\n' + + '\n' + + '/// Available since Tact 1.6.3.\n' + + '///\n' + + '/// Thrown when the address does not belong to a basechain (chain ID 0).\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#138\n' + + '///\n' + + 'const TactExitCodeNotBasechainAddress: Int = 138;\n', + imports: [], + items: [ + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeNullReferenceException', + loc: { start: 183, end: 217 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 219, end: 222 } + }, + loc: { start: 219, end: 222 } + }, + initializer: { + kind: 'number', + base: '10', + value: 128n, + loc: { start: 225, end: 228 } + } + }, + loc: { start: 177, end: 229 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeInvalidSerializationPrefix', + loc: { start: 434, end: 472 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 474, end: 477 } + }, + loc: { start: 474, end: 477 } + }, + initializer: { + kind: 'number', + base: '10', + value: 129n, + loc: { start: 480, end: 483 } + } + }, + loc: { start: 428, end: 484 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeInvalidIncomingMessage', + loc: { start: 633, end: 667 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 669, end: 672 } + }, + loc: { start: 669, end: 672 } + }, + initializer: { + kind: 'number', + base: '10', + value: 130n, + loc: { start: 675, end: 678 } + } + }, + loc: { start: 627, end: 679 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeConstraintsError', + loc: { start: 802, end: 830 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 832, end: 835 } + }, + loc: { start: 832, end: 835 } + }, + initializer: { + kind: 'number', + base: '10', + value: 131n, + loc: { start: 838, end: 841 } + } + }, + loc: { start: 796, end: 842 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeAccessDenied', + loc: { start: 1089, end: 1113 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1115, end: 1118 } + }, + loc: { start: 1115, end: 1118 } + }, + initializer: { + kind: 'number', + base: '10', + value: 132n, + loc: { start: 1121, end: 1124 } + } + }, + loc: { start: 1083, end: 1125 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeContractStopped', + loc: { start: 1335, end: 1362 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1364, end: 1367 } + }, + loc: { start: 1364, end: 1367 } + }, + initializer: { + kind: 'number', + base: '10', + value: 133n, + loc: { start: 1370, end: 1373 } + } + }, + loc: { start: 1329, end: 1374 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeInvalidArgument', + loc: { start: 1531, end: 1558 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1560, end: 1563 } + }, + loc: { start: 1560, end: 1563 } + }, + initializer: { + kind: 'number', + base: '10', + value: 134n, + loc: { start: 1566, end: 1569 } + } + }, + loc: { start: 1525, end: 1570 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeContractCodeNotFound', + loc: { start: 1688, end: 1720 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1722, end: 1725 } + }, + loc: { start: 1722, end: 1725 } + }, + initializer: { + kind: 'number', + base: '10', + value: 135n, + loc: { start: 1728, end: 1731 } + } + }, + loc: { start: 1682, end: 1732 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeInvalidStandardAddress', + loc: { start: 1881, end: 1915 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1917, end: 1920 } + }, + loc: { start: 1917, end: 1920 } + }, + initializer: { + kind: 'number', + base: '10', + value: 136n, + loc: { start: 1923, end: 1926 } + } + }, + loc: { start: 1875, end: 1927 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeNotBasechainAddress', + loc: { start: 2108, end: 2139 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2141, end: 2144 } + }, + loc: { start: 2141, end: 2144 } + }, + initializer: { + kind: 'number', + base: '10', + value: 138n, + loc: { start: 2147, end: 2150 } + } + }, + loc: { start: 2102, end: 2151 } + } + ] + }, + 'TactExitCodeInvalidSerializationPrefix' => { + kind: 'tact', + path: 'std/internal/exit-codes.tact', + code: '/// Configurable since Tact 1.6.\n' + + '///\n' + + '/// Thrown when a null reference exception occurs during the compute phase.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#128\n' + + '///\n' + + 'const TactExitCodeNullReferenceException: Int = 128;\n' + + '\n' + + '/// Thrown when there is a failed deserialization attempt:\n' + + '/// a certain opcode prefix was expected, but a different one was parsed.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#129\n' + + '///\n' + + 'const TactExitCodeInvalidSerializationPrefix: Int = 129;\n' + + '\n' + + '/// Thrown when there is no receiver for the opcode of the received message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#130\n' + + '///\n' + + 'const TactExitCodeInvalidIncomingMessage: Int = 130;\n' + + '\n' + + '/// Constraints error. Reserved, but never thrown.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#131\n' + + '///\n' + + 'const TactExitCodeConstraintsError: Int = 131;\n' + + '\n' + + '/// Thrown when the sender is not the owner of the contract inheriting\n' + + '/// the `Ownable` trait and there has been a mismatch of the `self.owner`\n' + + "/// and the sender's address.\n" + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#132\n' + + '///\n' + + 'const TactExitCodeAccessDenied: Int = 132;\n' + + '\n' + + '/// Thrown when a message has been sent to a contract inheriting the `Stoppable`\n' + + '/// trait and has the `self.stopped` flag set to `true`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#133\n' + + '///\n' + + 'const TactExitCodeContractStopped: Int = 133;\n' + + '\n' + + '/// Thrown when an invalid or unexpected argument is passed to a function or method.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#134\n' + + '///\n' + + 'const TactExitCodeInvalidArgument: Int = 134;\n' + + '\n' + + "/// Thrown when a contract's code is missing.\n" + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#135\n' + + '///\n' + + 'const TactExitCodeContractCodeNotFound: Int = 135;\n' + + '\n' + + '/// Thrown when an address does not conform to the expected standard format.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#136\n' + + '///\n' + + 'const TactExitCodeInvalidStandardAddress: Int = 136;\n' + + '\n' + + '/// Available since Tact 1.6.3.\n' + + '///\n' + + '/// Thrown when the address does not belong to a basechain (chain ID 0).\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#138\n' + + '///\n' + + 'const TactExitCodeNotBasechainAddress: Int = 138;\n', + imports: [], + items: [ + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeNullReferenceException', + loc: { start: 183, end: 217 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 219, end: 222 } + }, + loc: { start: 219, end: 222 } + }, + initializer: { + kind: 'number', + base: '10', + value: 128n, + loc: { start: 225, end: 228 } + } + }, + loc: { start: 177, end: 229 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeInvalidSerializationPrefix', + loc: { start: 434, end: 472 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 474, end: 477 } + }, + loc: { start: 474, end: 477 } + }, + initializer: { + kind: 'number', + base: '10', + value: 129n, + loc: { start: 480, end: 483 } + } + }, + loc: { start: 428, end: 484 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeInvalidIncomingMessage', + loc: { start: 633, end: 667 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 669, end: 672 } + }, + loc: { start: 669, end: 672 } + }, + initializer: { + kind: 'number', + base: '10', + value: 130n, + loc: { start: 675, end: 678 } + } + }, + loc: { start: 627, end: 679 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeConstraintsError', + loc: { start: 802, end: 830 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 832, end: 835 } + }, + loc: { start: 832, end: 835 } + }, + initializer: { + kind: 'number', + base: '10', + value: 131n, + loc: { start: 838, end: 841 } + } + }, + loc: { start: 796, end: 842 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeAccessDenied', + loc: { start: 1089, end: 1113 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1115, end: 1118 } + }, + loc: { start: 1115, end: 1118 } + }, + initializer: { + kind: 'number', + base: '10', + value: 132n, + loc: { start: 1121, end: 1124 } + } + }, + loc: { start: 1083, end: 1125 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeContractStopped', + loc: { start: 1335, end: 1362 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1364, end: 1367 } + }, + loc: { start: 1364, end: 1367 } + }, + initializer: { + kind: 'number', + base: '10', + value: 133n, + loc: { start: 1370, end: 1373 } + } + }, + loc: { start: 1329, end: 1374 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeInvalidArgument', + loc: { start: 1531, end: 1558 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1560, end: 1563 } + }, + loc: { start: 1560, end: 1563 } + }, + initializer: { + kind: 'number', + base: '10', + value: 134n, + loc: { start: 1566, end: 1569 } + } + }, + loc: { start: 1525, end: 1570 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeContractCodeNotFound', + loc: { start: 1688, end: 1720 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1722, end: 1725 } + }, + loc: { start: 1722, end: 1725 } + }, + initializer: { + kind: 'number', + base: '10', + value: 135n, + loc: { start: 1728, end: 1731 } + } + }, + loc: { start: 1682, end: 1732 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeInvalidStandardAddress', + loc: { start: 1881, end: 1915 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1917, end: 1920 } + }, + loc: { start: 1917, end: 1920 } + }, + initializer: { + kind: 'number', + base: '10', + value: 136n, + loc: { start: 1923, end: 1926 } + } + }, + loc: { start: 1875, end: 1927 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeNotBasechainAddress', + loc: { start: 2108, end: 2139 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2141, end: 2144 } + }, + loc: { start: 2141, end: 2144 } + }, + initializer: { + kind: 'number', + base: '10', + value: 138n, + loc: { start: 2147, end: 2150 } + } + }, + loc: { start: 2102, end: 2151 } + } + ] + }, + 'TactExitCodeInvalidIncomingMessage' => { + kind: 'tact', + path: 'std/internal/exit-codes.tact', + code: '/// Configurable since Tact 1.6.\n' + + '///\n' + + '/// Thrown when a null reference exception occurs during the compute phase.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#128\n' + + '///\n' + + 'const TactExitCodeNullReferenceException: Int = 128;\n' + + '\n' + + '/// Thrown when there is a failed deserialization attempt:\n' + + '/// a certain opcode prefix was expected, but a different one was parsed.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#129\n' + + '///\n' + + 'const TactExitCodeInvalidSerializationPrefix: Int = 129;\n' + + '\n' + + '/// Thrown when there is no receiver for the opcode of the received message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#130\n' + + '///\n' + + 'const TactExitCodeInvalidIncomingMessage: Int = 130;\n' + + '\n' + + '/// Constraints error. Reserved, but never thrown.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#131\n' + + '///\n' + + 'const TactExitCodeConstraintsError: Int = 131;\n' + + '\n' + + '/// Thrown when the sender is not the owner of the contract inheriting\n' + + '/// the `Ownable` trait and there has been a mismatch of the `self.owner`\n' + + "/// and the sender's address.\n" + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#132\n' + + '///\n' + + 'const TactExitCodeAccessDenied: Int = 132;\n' + + '\n' + + '/// Thrown when a message has been sent to a contract inheriting the `Stoppable`\n' + + '/// trait and has the `self.stopped` flag set to `true`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#133\n' + + '///\n' + + 'const TactExitCodeContractStopped: Int = 133;\n' + + '\n' + + '/// Thrown when an invalid or unexpected argument is passed to a function or method.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#134\n' + + '///\n' + + 'const TactExitCodeInvalidArgument: Int = 134;\n' + + '\n' + + "/// Thrown when a contract's code is missing.\n" + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#135\n' + + '///\n' + + 'const TactExitCodeContractCodeNotFound: Int = 135;\n' + + '\n' + + '/// Thrown when an address does not conform to the expected standard format.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#136\n' + + '///\n' + + 'const TactExitCodeInvalidStandardAddress: Int = 136;\n' + + '\n' + + '/// Available since Tact 1.6.3.\n' + + '///\n' + + '/// Thrown when the address does not belong to a basechain (chain ID 0).\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#138\n' + + '///\n' + + 'const TactExitCodeNotBasechainAddress: Int = 138;\n', + imports: [], + items: [ + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeNullReferenceException', + loc: { start: 183, end: 217 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 219, end: 222 } + }, + loc: { start: 219, end: 222 } + }, + initializer: { + kind: 'number', + base: '10', + value: 128n, + loc: { start: 225, end: 228 } + } + }, + loc: { start: 177, end: 229 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeInvalidSerializationPrefix', + loc: { start: 434, end: 472 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 474, end: 477 } + }, + loc: { start: 474, end: 477 } + }, + initializer: { + kind: 'number', + base: '10', + value: 129n, + loc: { start: 480, end: 483 } + } + }, + loc: { start: 428, end: 484 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeInvalidIncomingMessage', + loc: { start: 633, end: 667 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 669, end: 672 } + }, + loc: { start: 669, end: 672 } + }, + initializer: { + kind: 'number', + base: '10', + value: 130n, + loc: { start: 675, end: 678 } + } + }, + loc: { start: 627, end: 679 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeConstraintsError', + loc: { start: 802, end: 830 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 832, end: 835 } + }, + loc: { start: 832, end: 835 } + }, + initializer: { + kind: 'number', + base: '10', + value: 131n, + loc: { start: 838, end: 841 } + } + }, + loc: { start: 796, end: 842 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeAccessDenied', + loc: { start: 1089, end: 1113 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1115, end: 1118 } + }, + loc: { start: 1115, end: 1118 } + }, + initializer: { + kind: 'number', + base: '10', + value: 132n, + loc: { start: 1121, end: 1124 } + } + }, + loc: { start: 1083, end: 1125 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeContractStopped', + loc: { start: 1335, end: 1362 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1364, end: 1367 } + }, + loc: { start: 1364, end: 1367 } + }, + initializer: { + kind: 'number', + base: '10', + value: 133n, + loc: { start: 1370, end: 1373 } + } + }, + loc: { start: 1329, end: 1374 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeInvalidArgument', + loc: { start: 1531, end: 1558 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1560, end: 1563 } + }, + loc: { start: 1560, end: 1563 } + }, + initializer: { + kind: 'number', + base: '10', + value: 134n, + loc: { start: 1566, end: 1569 } + } + }, + loc: { start: 1525, end: 1570 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeContractCodeNotFound', + loc: { start: 1688, end: 1720 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1722, end: 1725 } + }, + loc: { start: 1722, end: 1725 } + }, + initializer: { + kind: 'number', + base: '10', + value: 135n, + loc: { start: 1728, end: 1731 } + } + }, + loc: { start: 1682, end: 1732 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeInvalidStandardAddress', + loc: { start: 1881, end: 1915 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1917, end: 1920 } + }, + loc: { start: 1917, end: 1920 } + }, + initializer: { + kind: 'number', + base: '10', + value: 136n, + loc: { start: 1923, end: 1926 } + } + }, + loc: { start: 1875, end: 1927 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeNotBasechainAddress', + loc: { start: 2108, end: 2139 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2141, end: 2144 } + }, + loc: { start: 2141, end: 2144 } + }, + initializer: { + kind: 'number', + base: '10', + value: 138n, + loc: { start: 2147, end: 2150 } + } + }, + loc: { start: 2102, end: 2151 } + } + ] + }, + 'TactExitCodeConstraintsError' => { + kind: 'tact', + path: 'std/internal/exit-codes.tact', + code: '/// Configurable since Tact 1.6.\n' + + '///\n' + + '/// Thrown when a null reference exception occurs during the compute phase.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#128\n' + + '///\n' + + 'const TactExitCodeNullReferenceException: Int = 128;\n' + + '\n' + + '/// Thrown when there is a failed deserialization attempt:\n' + + '/// a certain opcode prefix was expected, but a different one was parsed.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#129\n' + + '///\n' + + 'const TactExitCodeInvalidSerializationPrefix: Int = 129;\n' + + '\n' + + '/// Thrown when there is no receiver for the opcode of the received message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#130\n' + + '///\n' + + 'const TactExitCodeInvalidIncomingMessage: Int = 130;\n' + + '\n' + + '/// Constraints error. Reserved, but never thrown.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#131\n' + + '///\n' + + 'const TactExitCodeConstraintsError: Int = 131;\n' + + '\n' + + '/// Thrown when the sender is not the owner of the contract inheriting\n' + + '/// the `Ownable` trait and there has been a mismatch of the `self.owner`\n' + + "/// and the sender's address.\n" + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#132\n' + + '///\n' + + 'const TactExitCodeAccessDenied: Int = 132;\n' + + '\n' + + '/// Thrown when a message has been sent to a contract inheriting the `Stoppable`\n' + + '/// trait and has the `self.stopped` flag set to `true`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#133\n' + + '///\n' + + 'const TactExitCodeContractStopped: Int = 133;\n' + + '\n' + + '/// Thrown when an invalid or unexpected argument is passed to a function or method.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#134\n' + + '///\n' + + 'const TactExitCodeInvalidArgument: Int = 134;\n' + + '\n' + + "/// Thrown when a contract's code is missing.\n" + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#135\n' + + '///\n' + + 'const TactExitCodeContractCodeNotFound: Int = 135;\n' + + '\n' + + '/// Thrown when an address does not conform to the expected standard format.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#136\n' + + '///\n' + + 'const TactExitCodeInvalidStandardAddress: Int = 136;\n' + + '\n' + + '/// Available since Tact 1.6.3.\n' + + '///\n' + + '/// Thrown when the address does not belong to a basechain (chain ID 0).\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#138\n' + + '///\n' + + 'const TactExitCodeNotBasechainAddress: Int = 138;\n', + imports: [], + items: [ + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeNullReferenceException', + loc: { start: 183, end: 217 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 219, end: 222 } + }, + loc: { start: 219, end: 222 } + }, + initializer: { + kind: 'number', + base: '10', + value: 128n, + loc: { start: 225, end: 228 } + } + }, + loc: { start: 177, end: 229 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeInvalidSerializationPrefix', + loc: { start: 434, end: 472 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 474, end: 477 } + }, + loc: { start: 474, end: 477 } + }, + initializer: { + kind: 'number', + base: '10', + value: 129n, + loc: { start: 480, end: 483 } + } + }, + loc: { start: 428, end: 484 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeInvalidIncomingMessage', + loc: { start: 633, end: 667 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 669, end: 672 } + }, + loc: { start: 669, end: 672 } + }, + initializer: { + kind: 'number', + base: '10', + value: 130n, + loc: { start: 675, end: 678 } + } + }, + loc: { start: 627, end: 679 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeConstraintsError', + loc: { start: 802, end: 830 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 832, end: 835 } + }, + loc: { start: 832, end: 835 } + }, + initializer: { + kind: 'number', + base: '10', + value: 131n, + loc: { start: 838, end: 841 } + } + }, + loc: { start: 796, end: 842 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeAccessDenied', + loc: { start: 1089, end: 1113 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1115, end: 1118 } + }, + loc: { start: 1115, end: 1118 } + }, + initializer: { + kind: 'number', + base: '10', + value: 132n, + loc: { start: 1121, end: 1124 } + } + }, + loc: { start: 1083, end: 1125 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeContractStopped', + loc: { start: 1335, end: 1362 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1364, end: 1367 } + }, + loc: { start: 1364, end: 1367 } + }, + initializer: { + kind: 'number', + base: '10', + value: 133n, + loc: { start: 1370, end: 1373 } + } + }, + loc: { start: 1329, end: 1374 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeInvalidArgument', + loc: { start: 1531, end: 1558 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1560, end: 1563 } + }, + loc: { start: 1560, end: 1563 } + }, + initializer: { + kind: 'number', + base: '10', + value: 134n, + loc: { start: 1566, end: 1569 } + } + }, + loc: { start: 1525, end: 1570 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeContractCodeNotFound', + loc: { start: 1688, end: 1720 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1722, end: 1725 } + }, + loc: { start: 1722, end: 1725 } + }, + initializer: { + kind: 'number', + base: '10', + value: 135n, + loc: { start: 1728, end: 1731 } + } + }, + loc: { start: 1682, end: 1732 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeInvalidStandardAddress', + loc: { start: 1881, end: 1915 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1917, end: 1920 } + }, + loc: { start: 1917, end: 1920 } + }, + initializer: { + kind: 'number', + base: '10', + value: 136n, + loc: { start: 1923, end: 1926 } + } + }, + loc: { start: 1875, end: 1927 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeNotBasechainAddress', + loc: { start: 2108, end: 2139 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2141, end: 2144 } + }, + loc: { start: 2141, end: 2144 } + }, + initializer: { + kind: 'number', + base: '10', + value: 138n, + loc: { start: 2147, end: 2150 } + } + }, + loc: { start: 2102, end: 2151 } + } + ] + }, + 'TactExitCodeAccessDenied' => { + kind: 'tact', + path: 'std/internal/exit-codes.tact', + code: '/// Configurable since Tact 1.6.\n' + + '///\n' + + '/// Thrown when a null reference exception occurs during the compute phase.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#128\n' + + '///\n' + + 'const TactExitCodeNullReferenceException: Int = 128;\n' + + '\n' + + '/// Thrown when there is a failed deserialization attempt:\n' + + '/// a certain opcode prefix was expected, but a different one was parsed.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#129\n' + + '///\n' + + 'const TactExitCodeInvalidSerializationPrefix: Int = 129;\n' + + '\n' + + '/// Thrown when there is no receiver for the opcode of the received message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#130\n' + + '///\n' + + 'const TactExitCodeInvalidIncomingMessage: Int = 130;\n' + + '\n' + + '/// Constraints error. Reserved, but never thrown.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#131\n' + + '///\n' + + 'const TactExitCodeConstraintsError: Int = 131;\n' + + '\n' + + '/// Thrown when the sender is not the owner of the contract inheriting\n' + + '/// the `Ownable` trait and there has been a mismatch of the `self.owner`\n' + + "/// and the sender's address.\n" + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#132\n' + + '///\n' + + 'const TactExitCodeAccessDenied: Int = 132;\n' + + '\n' + + '/// Thrown when a message has been sent to a contract inheriting the `Stoppable`\n' + + '/// trait and has the `self.stopped` flag set to `true`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#133\n' + + '///\n' + + 'const TactExitCodeContractStopped: Int = 133;\n' + + '\n' + + '/// Thrown when an invalid or unexpected argument is passed to a function or method.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#134\n' + + '///\n' + + 'const TactExitCodeInvalidArgument: Int = 134;\n' + + '\n' + + "/// Thrown when a contract's code is missing.\n" + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#135\n' + + '///\n' + + 'const TactExitCodeContractCodeNotFound: Int = 135;\n' + + '\n' + + '/// Thrown when an address does not conform to the expected standard format.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#136\n' + + '///\n' + + 'const TactExitCodeInvalidStandardAddress: Int = 136;\n' + + '\n' + + '/// Available since Tact 1.6.3.\n' + + '///\n' + + '/// Thrown when the address does not belong to a basechain (chain ID 0).\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#138\n' + + '///\n' + + 'const TactExitCodeNotBasechainAddress: Int = 138;\n', + imports: [], + items: [ + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeNullReferenceException', + loc: { start: 183, end: 217 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 219, end: 222 } + }, + loc: { start: 219, end: 222 } + }, + initializer: { + kind: 'number', + base: '10', + value: 128n, + loc: { start: 225, end: 228 } + } + }, + loc: { start: 177, end: 229 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeInvalidSerializationPrefix', + loc: { start: 434, end: 472 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 474, end: 477 } + }, + loc: { start: 474, end: 477 } + }, + initializer: { + kind: 'number', + base: '10', + value: 129n, + loc: { start: 480, end: 483 } + } + }, + loc: { start: 428, end: 484 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeInvalidIncomingMessage', + loc: { start: 633, end: 667 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 669, end: 672 } + }, + loc: { start: 669, end: 672 } + }, + initializer: { + kind: 'number', + base: '10', + value: 130n, + loc: { start: 675, end: 678 } + } + }, + loc: { start: 627, end: 679 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeConstraintsError', + loc: { start: 802, end: 830 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 832, end: 835 } + }, + loc: { start: 832, end: 835 } + }, + initializer: { + kind: 'number', + base: '10', + value: 131n, + loc: { start: 838, end: 841 } + } + }, + loc: { start: 796, end: 842 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeAccessDenied', + loc: { start: 1089, end: 1113 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1115, end: 1118 } + }, + loc: { start: 1115, end: 1118 } + }, + initializer: { + kind: 'number', + base: '10', + value: 132n, + loc: { start: 1121, end: 1124 } + } + }, + loc: { start: 1083, end: 1125 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeContractStopped', + loc: { start: 1335, end: 1362 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1364, end: 1367 } + }, + loc: { start: 1364, end: 1367 } + }, + initializer: { + kind: 'number', + base: '10', + value: 133n, + loc: { start: 1370, end: 1373 } + } + }, + loc: { start: 1329, end: 1374 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeInvalidArgument', + loc: { start: 1531, end: 1558 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1560, end: 1563 } + }, + loc: { start: 1560, end: 1563 } + }, + initializer: { + kind: 'number', + base: '10', + value: 134n, + loc: { start: 1566, end: 1569 } + } + }, + loc: { start: 1525, end: 1570 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeContractCodeNotFound', + loc: { start: 1688, end: 1720 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1722, end: 1725 } + }, + loc: { start: 1722, end: 1725 } + }, + initializer: { + kind: 'number', + base: '10', + value: 135n, + loc: { start: 1728, end: 1731 } + } + }, + loc: { start: 1682, end: 1732 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeInvalidStandardAddress', + loc: { start: 1881, end: 1915 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1917, end: 1920 } + }, + loc: { start: 1917, end: 1920 } + }, + initializer: { + kind: 'number', + base: '10', + value: 136n, + loc: { start: 1923, end: 1926 } + } + }, + loc: { start: 1875, end: 1927 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeNotBasechainAddress', + loc: { start: 2108, end: 2139 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2141, end: 2144 } + }, + loc: { start: 2141, end: 2144 } + }, + initializer: { + kind: 'number', + base: '10', + value: 138n, + loc: { start: 2147, end: 2150 } + } + }, + loc: { start: 2102, end: 2151 } + } + ] + }, + 'TactExitCodeContractStopped' => { + kind: 'tact', + path: 'std/internal/exit-codes.tact', + code: '/// Configurable since Tact 1.6.\n' + + '///\n' + + '/// Thrown when a null reference exception occurs during the compute phase.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#128\n' + + '///\n' + + 'const TactExitCodeNullReferenceException: Int = 128;\n' + + '\n' + + '/// Thrown when there is a failed deserialization attempt:\n' + + '/// a certain opcode prefix was expected, but a different one was parsed.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#129\n' + + '///\n' + + 'const TactExitCodeInvalidSerializationPrefix: Int = 129;\n' + + '\n' + + '/// Thrown when there is no receiver for the opcode of the received message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#130\n' + + '///\n' + + 'const TactExitCodeInvalidIncomingMessage: Int = 130;\n' + + '\n' + + '/// Constraints error. Reserved, but never thrown.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#131\n' + + '///\n' + + 'const TactExitCodeConstraintsError: Int = 131;\n' + + '\n' + + '/// Thrown when the sender is not the owner of the contract inheriting\n' + + '/// the `Ownable` trait and there has been a mismatch of the `self.owner`\n' + + "/// and the sender's address.\n" + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#132\n' + + '///\n' + + 'const TactExitCodeAccessDenied: Int = 132;\n' + + '\n' + + '/// Thrown when a message has been sent to a contract inheriting the `Stoppable`\n' + + '/// trait and has the `self.stopped` flag set to `true`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#133\n' + + '///\n' + + 'const TactExitCodeContractStopped: Int = 133;\n' + + '\n' + + '/// Thrown when an invalid or unexpected argument is passed to a function or method.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#134\n' + + '///\n' + + 'const TactExitCodeInvalidArgument: Int = 134;\n' + + '\n' + + "/// Thrown when a contract's code is missing.\n" + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#135\n' + + '///\n' + + 'const TactExitCodeContractCodeNotFound: Int = 135;\n' + + '\n' + + '/// Thrown when an address does not conform to the expected standard format.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#136\n' + + '///\n' + + 'const TactExitCodeInvalidStandardAddress: Int = 136;\n' + + '\n' + + '/// Available since Tact 1.6.3.\n' + + '///\n' + + '/// Thrown when the address does not belong to a basechain (chain ID 0).\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#138\n' + + '///\n' + + 'const TactExitCodeNotBasechainAddress: Int = 138;\n', + imports: [], + items: [ + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeNullReferenceException', + loc: { start: 183, end: 217 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 219, end: 222 } + }, + loc: { start: 219, end: 222 } + }, + initializer: { + kind: 'number', + base: '10', + value: 128n, + loc: { start: 225, end: 228 } + } + }, + loc: { start: 177, end: 229 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeInvalidSerializationPrefix', + loc: { start: 434, end: 472 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 474, end: 477 } + }, + loc: { start: 474, end: 477 } + }, + initializer: { + kind: 'number', + base: '10', + value: 129n, + loc: { start: 480, end: 483 } + } + }, + loc: { start: 428, end: 484 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeInvalidIncomingMessage', + loc: { start: 633, end: 667 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 669, end: 672 } + }, + loc: { start: 669, end: 672 } + }, + initializer: { + kind: 'number', + base: '10', + value: 130n, + loc: { start: 675, end: 678 } + } + }, + loc: { start: 627, end: 679 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeConstraintsError', + loc: { start: 802, end: 830 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 832, end: 835 } + }, + loc: { start: 832, end: 835 } + }, + initializer: { + kind: 'number', + base: '10', + value: 131n, + loc: { start: 838, end: 841 } + } + }, + loc: { start: 796, end: 842 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeAccessDenied', + loc: { start: 1089, end: 1113 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1115, end: 1118 } + }, + loc: { start: 1115, end: 1118 } + }, + initializer: { + kind: 'number', + base: '10', + value: 132n, + loc: { start: 1121, end: 1124 } + } + }, + loc: { start: 1083, end: 1125 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeContractStopped', + loc: { start: 1335, end: 1362 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1364, end: 1367 } + }, + loc: { start: 1364, end: 1367 } + }, + initializer: { + kind: 'number', + base: '10', + value: 133n, + loc: { start: 1370, end: 1373 } + } + }, + loc: { start: 1329, end: 1374 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeInvalidArgument', + loc: { start: 1531, end: 1558 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1560, end: 1563 } + }, + loc: { start: 1560, end: 1563 } + }, + initializer: { + kind: 'number', + base: '10', + value: 134n, + loc: { start: 1566, end: 1569 } + } + }, + loc: { start: 1525, end: 1570 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeContractCodeNotFound', + loc: { start: 1688, end: 1720 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1722, end: 1725 } + }, + loc: { start: 1722, end: 1725 } + }, + initializer: { + kind: 'number', + base: '10', + value: 135n, + loc: { start: 1728, end: 1731 } + } + }, + loc: { start: 1682, end: 1732 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeInvalidStandardAddress', + loc: { start: 1881, end: 1915 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1917, end: 1920 } + }, + loc: { start: 1917, end: 1920 } + }, + initializer: { + kind: 'number', + base: '10', + value: 136n, + loc: { start: 1923, end: 1926 } + } + }, + loc: { start: 1875, end: 1927 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeNotBasechainAddress', + loc: { start: 2108, end: 2139 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2141, end: 2144 } + }, + loc: { start: 2141, end: 2144 } + }, + initializer: { + kind: 'number', + base: '10', + value: 138n, + loc: { start: 2147, end: 2150 } + } + }, + loc: { start: 2102, end: 2151 } + } + ] + }, + 'TactExitCodeInvalidArgument' => { + kind: 'tact', + path: 'std/internal/exit-codes.tact', + code: '/// Configurable since Tact 1.6.\n' + + '///\n' + + '/// Thrown when a null reference exception occurs during the compute phase.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#128\n' + + '///\n' + + 'const TactExitCodeNullReferenceException: Int = 128;\n' + + '\n' + + '/// Thrown when there is a failed deserialization attempt:\n' + + '/// a certain opcode prefix was expected, but a different one was parsed.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#129\n' + + '///\n' + + 'const TactExitCodeInvalidSerializationPrefix: Int = 129;\n' + + '\n' + + '/// Thrown when there is no receiver for the opcode of the received message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#130\n' + + '///\n' + + 'const TactExitCodeInvalidIncomingMessage: Int = 130;\n' + + '\n' + + '/// Constraints error. Reserved, but never thrown.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#131\n' + + '///\n' + + 'const TactExitCodeConstraintsError: Int = 131;\n' + + '\n' + + '/// Thrown when the sender is not the owner of the contract inheriting\n' + + '/// the `Ownable` trait and there has been a mismatch of the `self.owner`\n' + + "/// and the sender's address.\n" + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#132\n' + + '///\n' + + 'const TactExitCodeAccessDenied: Int = 132;\n' + + '\n' + + '/// Thrown when a message has been sent to a contract inheriting the `Stoppable`\n' + + '/// trait and has the `self.stopped` flag set to `true`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#133\n' + + '///\n' + + 'const TactExitCodeContractStopped: Int = 133;\n' + + '\n' + + '/// Thrown when an invalid or unexpected argument is passed to a function or method.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#134\n' + + '///\n' + + 'const TactExitCodeInvalidArgument: Int = 134;\n' + + '\n' + + "/// Thrown when a contract's code is missing.\n" + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#135\n' + + '///\n' + + 'const TactExitCodeContractCodeNotFound: Int = 135;\n' + + '\n' + + '/// Thrown when an address does not conform to the expected standard format.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#136\n' + + '///\n' + + 'const TactExitCodeInvalidStandardAddress: Int = 136;\n' + + '\n' + + '/// Available since Tact 1.6.3.\n' + + '///\n' + + '/// Thrown when the address does not belong to a basechain (chain ID 0).\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#138\n' + + '///\n' + + 'const TactExitCodeNotBasechainAddress: Int = 138;\n', + imports: [], + items: [ + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeNullReferenceException', + loc: { start: 183, end: 217 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 219, end: 222 } + }, + loc: { start: 219, end: 222 } + }, + initializer: { + kind: 'number', + base: '10', + value: 128n, + loc: { start: 225, end: 228 } + } + }, + loc: { start: 177, end: 229 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeInvalidSerializationPrefix', + loc: { start: 434, end: 472 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 474, end: 477 } + }, + loc: { start: 474, end: 477 } + }, + initializer: { + kind: 'number', + base: '10', + value: 129n, + loc: { start: 480, end: 483 } + } + }, + loc: { start: 428, end: 484 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeInvalidIncomingMessage', + loc: { start: 633, end: 667 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 669, end: 672 } + }, + loc: { start: 669, end: 672 } + }, + initializer: { + kind: 'number', + base: '10', + value: 130n, + loc: { start: 675, end: 678 } + } + }, + loc: { start: 627, end: 679 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeConstraintsError', + loc: { start: 802, end: 830 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 832, end: 835 } + }, + loc: { start: 832, end: 835 } + }, + initializer: { + kind: 'number', + base: '10', + value: 131n, + loc: { start: 838, end: 841 } + } + }, + loc: { start: 796, end: 842 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeAccessDenied', + loc: { start: 1089, end: 1113 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1115, end: 1118 } + }, + loc: { start: 1115, end: 1118 } + }, + initializer: { + kind: 'number', + base: '10', + value: 132n, + loc: { start: 1121, end: 1124 } + } + }, + loc: { start: 1083, end: 1125 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeContractStopped', + loc: { start: 1335, end: 1362 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1364, end: 1367 } + }, + loc: { start: 1364, end: 1367 } + }, + initializer: { + kind: 'number', + base: '10', + value: 133n, + loc: { start: 1370, end: 1373 } + } + }, + loc: { start: 1329, end: 1374 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeInvalidArgument', + loc: { start: 1531, end: 1558 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1560, end: 1563 } + }, + loc: { start: 1560, end: 1563 } + }, + initializer: { + kind: 'number', + base: '10', + value: 134n, + loc: { start: 1566, end: 1569 } + } + }, + loc: { start: 1525, end: 1570 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeContractCodeNotFound', + loc: { start: 1688, end: 1720 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1722, end: 1725 } + }, + loc: { start: 1722, end: 1725 } + }, + initializer: { + kind: 'number', + base: '10', + value: 135n, + loc: { start: 1728, end: 1731 } + } + }, + loc: { start: 1682, end: 1732 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeInvalidStandardAddress', + loc: { start: 1881, end: 1915 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1917, end: 1920 } + }, + loc: { start: 1917, end: 1920 } + }, + initializer: { + kind: 'number', + base: '10', + value: 136n, + loc: { start: 1923, end: 1926 } + } + }, + loc: { start: 1875, end: 1927 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeNotBasechainAddress', + loc: { start: 2108, end: 2139 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2141, end: 2144 } + }, + loc: { start: 2141, end: 2144 } + }, + initializer: { + kind: 'number', + base: '10', + value: 138n, + loc: { start: 2147, end: 2150 } + } + }, + loc: { start: 2102, end: 2151 } + } + ] + }, + 'TactExitCodeContractCodeNotFound' => { + kind: 'tact', + path: 'std/internal/exit-codes.tact', + code: '/// Configurable since Tact 1.6.\n' + + '///\n' + + '/// Thrown when a null reference exception occurs during the compute phase.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#128\n' + + '///\n' + + 'const TactExitCodeNullReferenceException: Int = 128;\n' + + '\n' + + '/// Thrown when there is a failed deserialization attempt:\n' + + '/// a certain opcode prefix was expected, but a different one was parsed.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#129\n' + + '///\n' + + 'const TactExitCodeInvalidSerializationPrefix: Int = 129;\n' + + '\n' + + '/// Thrown when there is no receiver for the opcode of the received message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#130\n' + + '///\n' + + 'const TactExitCodeInvalidIncomingMessage: Int = 130;\n' + + '\n' + + '/// Constraints error. Reserved, but never thrown.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#131\n' + + '///\n' + + 'const TactExitCodeConstraintsError: Int = 131;\n' + + '\n' + + '/// Thrown when the sender is not the owner of the contract inheriting\n' + + '/// the `Ownable` trait and there has been a mismatch of the `self.owner`\n' + + "/// and the sender's address.\n" + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#132\n' + + '///\n' + + 'const TactExitCodeAccessDenied: Int = 132;\n' + + '\n' + + '/// Thrown when a message has been sent to a contract inheriting the `Stoppable`\n' + + '/// trait and has the `self.stopped` flag set to `true`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#133\n' + + '///\n' + + 'const TactExitCodeContractStopped: Int = 133;\n' + + '\n' + + '/// Thrown when an invalid or unexpected argument is passed to a function or method.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#134\n' + + '///\n' + + 'const TactExitCodeInvalidArgument: Int = 134;\n' + + '\n' + + "/// Thrown when a contract's code is missing.\n" + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#135\n' + + '///\n' + + 'const TactExitCodeContractCodeNotFound: Int = 135;\n' + + '\n' + + '/// Thrown when an address does not conform to the expected standard format.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#136\n' + + '///\n' + + 'const TactExitCodeInvalidStandardAddress: Int = 136;\n' + + '\n' + + '/// Available since Tact 1.6.3.\n' + + '///\n' + + '/// Thrown when the address does not belong to a basechain (chain ID 0).\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#138\n' + + '///\n' + + 'const TactExitCodeNotBasechainAddress: Int = 138;\n', + imports: [], + items: [ + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeNullReferenceException', + loc: { start: 183, end: 217 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 219, end: 222 } + }, + loc: { start: 219, end: 222 } + }, + initializer: { + kind: 'number', + base: '10', + value: 128n, + loc: { start: 225, end: 228 } + } + }, + loc: { start: 177, end: 229 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeInvalidSerializationPrefix', + loc: { start: 434, end: 472 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 474, end: 477 } + }, + loc: { start: 474, end: 477 } + }, + initializer: { + kind: 'number', + base: '10', + value: 129n, + loc: { start: 480, end: 483 } + } + }, + loc: { start: 428, end: 484 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeInvalidIncomingMessage', + loc: { start: 633, end: 667 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 669, end: 672 } + }, + loc: { start: 669, end: 672 } + }, + initializer: { + kind: 'number', + base: '10', + value: 130n, + loc: { start: 675, end: 678 } + } + }, + loc: { start: 627, end: 679 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeConstraintsError', + loc: { start: 802, end: 830 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 832, end: 835 } + }, + loc: { start: 832, end: 835 } + }, + initializer: { + kind: 'number', + base: '10', + value: 131n, + loc: { start: 838, end: 841 } + } + }, + loc: { start: 796, end: 842 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeAccessDenied', + loc: { start: 1089, end: 1113 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1115, end: 1118 } + }, + loc: { start: 1115, end: 1118 } + }, + initializer: { + kind: 'number', + base: '10', + value: 132n, + loc: { start: 1121, end: 1124 } + } + }, + loc: { start: 1083, end: 1125 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeContractStopped', + loc: { start: 1335, end: 1362 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1364, end: 1367 } + }, + loc: { start: 1364, end: 1367 } + }, + initializer: { + kind: 'number', + base: '10', + value: 133n, + loc: { start: 1370, end: 1373 } + } + }, + loc: { start: 1329, end: 1374 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeInvalidArgument', + loc: { start: 1531, end: 1558 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1560, end: 1563 } + }, + loc: { start: 1560, end: 1563 } + }, + initializer: { + kind: 'number', + base: '10', + value: 134n, + loc: { start: 1566, end: 1569 } + } + }, + loc: { start: 1525, end: 1570 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeContractCodeNotFound', + loc: { start: 1688, end: 1720 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1722, end: 1725 } + }, + loc: { start: 1722, end: 1725 } + }, + initializer: { + kind: 'number', + base: '10', + value: 135n, + loc: { start: 1728, end: 1731 } + } + }, + loc: { start: 1682, end: 1732 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeInvalidStandardAddress', + loc: { start: 1881, end: 1915 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1917, end: 1920 } + }, + loc: { start: 1917, end: 1920 } + }, + initializer: { + kind: 'number', + base: '10', + value: 136n, + loc: { start: 1923, end: 1926 } + } + }, + loc: { start: 1875, end: 1927 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeNotBasechainAddress', + loc: { start: 2108, end: 2139 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2141, end: 2144 } + }, + loc: { start: 2141, end: 2144 } + }, + initializer: { + kind: 'number', + base: '10', + value: 138n, + loc: { start: 2147, end: 2150 } + } + }, + loc: { start: 2102, end: 2151 } + } + ] + }, + 'TactExitCodeInvalidStandardAddress' => { + kind: 'tact', + path: 'std/internal/exit-codes.tact', + code: '/// Configurable since Tact 1.6.\n' + + '///\n' + + '/// Thrown when a null reference exception occurs during the compute phase.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#128\n' + + '///\n' + + 'const TactExitCodeNullReferenceException: Int = 128;\n' + + '\n' + + '/// Thrown when there is a failed deserialization attempt:\n' + + '/// a certain opcode prefix was expected, but a different one was parsed.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#129\n' + + '///\n' + + 'const TactExitCodeInvalidSerializationPrefix: Int = 129;\n' + + '\n' + + '/// Thrown when there is no receiver for the opcode of the received message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#130\n' + + '///\n' + + 'const TactExitCodeInvalidIncomingMessage: Int = 130;\n' + + '\n' + + '/// Constraints error. Reserved, but never thrown.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#131\n' + + '///\n' + + 'const TactExitCodeConstraintsError: Int = 131;\n' + + '\n' + + '/// Thrown when the sender is not the owner of the contract inheriting\n' + + '/// the `Ownable` trait and there has been a mismatch of the `self.owner`\n' + + "/// and the sender's address.\n" + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#132\n' + + '///\n' + + 'const TactExitCodeAccessDenied: Int = 132;\n' + + '\n' + + '/// Thrown when a message has been sent to a contract inheriting the `Stoppable`\n' + + '/// trait and has the `self.stopped` flag set to `true`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#133\n' + + '///\n' + + 'const TactExitCodeContractStopped: Int = 133;\n' + + '\n' + + '/// Thrown when an invalid or unexpected argument is passed to a function or method.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#134\n' + + '///\n' + + 'const TactExitCodeInvalidArgument: Int = 134;\n' + + '\n' + + "/// Thrown when a contract's code is missing.\n" + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#135\n' + + '///\n' + + 'const TactExitCodeContractCodeNotFound: Int = 135;\n' + + '\n' + + '/// Thrown when an address does not conform to the expected standard format.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#136\n' + + '///\n' + + 'const TactExitCodeInvalidStandardAddress: Int = 136;\n' + + '\n' + + '/// Available since Tact 1.6.3.\n' + + '///\n' + + '/// Thrown when the address does not belong to a basechain (chain ID 0).\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#138\n' + + '///\n' + + 'const TactExitCodeNotBasechainAddress: Int = 138;\n', + imports: [], + items: [ + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeNullReferenceException', + loc: { start: 183, end: 217 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 219, end: 222 } + }, + loc: { start: 219, end: 222 } + }, + initializer: { + kind: 'number', + base: '10', + value: 128n, + loc: { start: 225, end: 228 } + } + }, + loc: { start: 177, end: 229 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeInvalidSerializationPrefix', + loc: { start: 434, end: 472 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 474, end: 477 } + }, + loc: { start: 474, end: 477 } + }, + initializer: { + kind: 'number', + base: '10', + value: 129n, + loc: { start: 480, end: 483 } + } + }, + loc: { start: 428, end: 484 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeInvalidIncomingMessage', + loc: { start: 633, end: 667 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 669, end: 672 } + }, + loc: { start: 669, end: 672 } + }, + initializer: { + kind: 'number', + base: '10', + value: 130n, + loc: { start: 675, end: 678 } + } + }, + loc: { start: 627, end: 679 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeConstraintsError', + loc: { start: 802, end: 830 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 832, end: 835 } + }, + loc: { start: 832, end: 835 } + }, + initializer: { + kind: 'number', + base: '10', + value: 131n, + loc: { start: 838, end: 841 } + } + }, + loc: { start: 796, end: 842 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeAccessDenied', + loc: { start: 1089, end: 1113 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1115, end: 1118 } + }, + loc: { start: 1115, end: 1118 } + }, + initializer: { + kind: 'number', + base: '10', + value: 132n, + loc: { start: 1121, end: 1124 } + } + }, + loc: { start: 1083, end: 1125 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeContractStopped', + loc: { start: 1335, end: 1362 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1364, end: 1367 } + }, + loc: { start: 1364, end: 1367 } + }, + initializer: { + kind: 'number', + base: '10', + value: 133n, + loc: { start: 1370, end: 1373 } + } + }, + loc: { start: 1329, end: 1374 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeInvalidArgument', + loc: { start: 1531, end: 1558 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1560, end: 1563 } + }, + loc: { start: 1560, end: 1563 } + }, + initializer: { + kind: 'number', + base: '10', + value: 134n, + loc: { start: 1566, end: 1569 } + } + }, + loc: { start: 1525, end: 1570 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeContractCodeNotFound', + loc: { start: 1688, end: 1720 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1722, end: 1725 } + }, + loc: { start: 1722, end: 1725 } + }, + initializer: { + kind: 'number', + base: '10', + value: 135n, + loc: { start: 1728, end: 1731 } + } + }, + loc: { start: 1682, end: 1732 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeInvalidStandardAddress', + loc: { start: 1881, end: 1915 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1917, end: 1920 } + }, + loc: { start: 1917, end: 1920 } + }, + initializer: { + kind: 'number', + base: '10', + value: 136n, + loc: { start: 1923, end: 1926 } + } + }, + loc: { start: 1875, end: 1927 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeNotBasechainAddress', + loc: { start: 2108, end: 2139 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2141, end: 2144 } + }, + loc: { start: 2141, end: 2144 } + }, + initializer: { + kind: 'number', + base: '10', + value: 138n, + loc: { start: 2147, end: 2150 } + } + }, + loc: { start: 2102, end: 2151 } + } + ] + }, + 'TactExitCodeNotBasechainAddress' => { + kind: 'tact', + path: 'std/internal/exit-codes.tact', + code: '/// Configurable since Tact 1.6.\n' + + '///\n' + + '/// Thrown when a null reference exception occurs during the compute phase.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#128\n' + + '///\n' + + 'const TactExitCodeNullReferenceException: Int = 128;\n' + + '\n' + + '/// Thrown when there is a failed deserialization attempt:\n' + + '/// a certain opcode prefix was expected, but a different one was parsed.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#129\n' + + '///\n' + + 'const TactExitCodeInvalidSerializationPrefix: Int = 129;\n' + + '\n' + + '/// Thrown when there is no receiver for the opcode of the received message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#130\n' + + '///\n' + + 'const TactExitCodeInvalidIncomingMessage: Int = 130;\n' + + '\n' + + '/// Constraints error. Reserved, but never thrown.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#131\n' + + '///\n' + + 'const TactExitCodeConstraintsError: Int = 131;\n' + + '\n' + + '/// Thrown when the sender is not the owner of the contract inheriting\n' + + '/// the `Ownable` trait and there has been a mismatch of the `self.owner`\n' + + "/// and the sender's address.\n" + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#132\n' + + '///\n' + + 'const TactExitCodeAccessDenied: Int = 132;\n' + + '\n' + + '/// Thrown when a message has been sent to a contract inheriting the `Stoppable`\n' + + '/// trait and has the `self.stopped` flag set to `true`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#133\n' + + '///\n' + + 'const TactExitCodeContractStopped: Int = 133;\n' + + '\n' + + '/// Thrown when an invalid or unexpected argument is passed to a function or method.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#134\n' + + '///\n' + + 'const TactExitCodeInvalidArgument: Int = 134;\n' + + '\n' + + "/// Thrown when a contract's code is missing.\n" + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#135\n' + + '///\n' + + 'const TactExitCodeContractCodeNotFound: Int = 135;\n' + + '\n' + + '/// Thrown when an address does not conform to the expected standard format.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#136\n' + + '///\n' + + 'const TactExitCodeInvalidStandardAddress: Int = 136;\n' + + '\n' + + '/// Available since Tact 1.6.3.\n' + + '///\n' + + '/// Thrown when the address does not belong to a basechain (chain ID 0).\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/exit-codes#138\n' + + '///\n' + + 'const TactExitCodeNotBasechainAddress: Int = 138;\n', + imports: [], + items: [ + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeNullReferenceException', + loc: { start: 183, end: 217 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 219, end: 222 } + }, + loc: { start: 219, end: 222 } + }, + initializer: { + kind: 'number', + base: '10', + value: 128n, + loc: { start: 225, end: 228 } + } + }, + loc: { start: 177, end: 229 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeInvalidSerializationPrefix', + loc: { start: 434, end: 472 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 474, end: 477 } + }, + loc: { start: 474, end: 477 } + }, + initializer: { + kind: 'number', + base: '10', + value: 129n, + loc: { start: 480, end: 483 } + } + }, + loc: { start: 428, end: 484 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeInvalidIncomingMessage', + loc: { start: 633, end: 667 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 669, end: 672 } + }, + loc: { start: 669, end: 672 } + }, + initializer: { + kind: 'number', + base: '10', + value: 130n, + loc: { start: 675, end: 678 } + } + }, + loc: { start: 627, end: 679 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeConstraintsError', + loc: { start: 802, end: 830 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 832, end: 835 } + }, + loc: { start: 832, end: 835 } + }, + initializer: { + kind: 'number', + base: '10', + value: 131n, + loc: { start: 838, end: 841 } + } + }, + loc: { start: 796, end: 842 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeAccessDenied', + loc: { start: 1089, end: 1113 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1115, end: 1118 } + }, + loc: { start: 1115, end: 1118 } + }, + initializer: { + kind: 'number', + base: '10', + value: 132n, + loc: { start: 1121, end: 1124 } + } + }, + loc: { start: 1083, end: 1125 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeContractStopped', + loc: { start: 1335, end: 1362 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1364, end: 1367 } + }, + loc: { start: 1364, end: 1367 } + }, + initializer: { + kind: 'number', + base: '10', + value: 133n, + loc: { start: 1370, end: 1373 } + } + }, + loc: { start: 1329, end: 1374 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeInvalidArgument', + loc: { start: 1531, end: 1558 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1560, end: 1563 } + }, + loc: { start: 1560, end: 1563 } + }, + initializer: { + kind: 'number', + base: '10', + value: 134n, + loc: { start: 1566, end: 1569 } + } + }, + loc: { start: 1525, end: 1570 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeContractCodeNotFound', + loc: { start: 1688, end: 1720 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1722, end: 1725 } + }, + loc: { start: 1722, end: 1725 } + }, + initializer: { + kind: 'number', + base: '10', + value: 135n, + loc: { start: 1728, end: 1731 } + } + }, + loc: { start: 1682, end: 1732 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeInvalidStandardAddress', + loc: { start: 1881, end: 1915 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1917, end: 1920 } + }, + loc: { start: 1917, end: 1920 } + }, + initializer: { + kind: 'number', + base: '10', + value: 136n, + loc: { start: 1923, end: 1926 } + } + }, + loc: { start: 1875, end: 1927 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'TactExitCodeNotBasechainAddress', + loc: { start: 2108, end: 2139 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2141, end: 2144 } + }, + loc: { start: 2141, end: 2144 } + }, + initializer: { + kind: 'number', + base: '10', + value: 138n, + loc: { start: 2147, end: 2150 } + } + }, + loc: { start: 2102, end: 2151 } + } + ] + }, + 'ReserveExact' => { + kind: 'tact', + path: 'std/internal/reserve.tact', + code: '/// Executes the native `RAWRESERVE` instruction with the specified amount and mode.\n' + + '/// The `RAWRESERVE` instruction creates an output action to reserve a specific amount of\n' + + '/// [nanoToncoin] from the remaining balance of the account.\n' + + '///\n' + + '/// The `RAWRESERVE` instruction takes two arguments:\n' + + '/// * `amount`: The number of [nanoToncoin] to reserve.\n' + + '/// * `mode`: Determines the reservation behavior.\n' + + '///\n' + + '/// The `RAWRESERVE` instruction is roughly equivalent to creating an outbound message\n' + + '/// carrying the specified `amount` of [nanoToncoin] (or `b - amount` [nanoToncoin],\n' + + '/// where `b` is the remaining balance) to oneself.\n' + + '/// This ensures that subsequent output actions cannot spend more money than the remainder.\n' + + '///\n' + + '/// It is possible to use raw `Int` values and manually provide them for the `mode`,\n' + + "/// but for your convenience, there's a set of constants you may use to construct the\n" + + '/// compound `mode` with ease.\n' + + '///\n' + + '/// NOTE: Currently, `amount` must be a non-negative integer, and `mode` must be in the\n' + + '/// range `0..31`, inclusive.\n' + + '///\n' + + '/// Additionally, attempts to queue more than 255 reservations in one transaction throw an\n' + + '/// exception with [exit code 33]: `Action list is too long`.\n' + + '///\n' + + '/// NOTE: This function is gas-expensive and uses 500 gas units or more.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve\n' + + '///\n' + + '/// [exit code 33]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '/// [nanoToncoin]: https://docs.tact-lang.org/book/integers#nanotoncoin\n' + + 'asm fun nativeReserve(amount: Int, mode: Int) { RAWRESERVE }\n' + + '\n' + + '/// Reserves exactly the specified `amount` of\n' + + '/// [nanoToncoin](https://docs.tact-lang.org/book/integers#nanotoncoin).\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve-base-modes\n' + + '///\n' + + 'const ReserveExact: Int = 0;\n' + + '\n' + + '/// Reserves all but the specified `amount` of\n' + + '/// [nanoToncoin](https://docs.tact-lang.org/book/integers#nanotoncoin).\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve-base-modes\n' + + '///\n' + + 'const ReserveAllExcept: Int = 1;\n' + + '\n' + + '/// Reserves at most the specified `amount` of\n' + + '/// [nanoToncoin](https://docs.tact-lang.org/book/integers#nanotoncoin).\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve-base-modes\n' + + '///\n' + + 'const ReserveAtMost: Int = 2;\n' + + '\n' + + '/// Increases the `amount` by the original balance of the current account\n' + + '/// (before the compute phase), including all extra currencies.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve-optional-flags\n' + + '///\n' + + 'const ReserveAddOriginalBalance: Int = 4;\n' + + '\n' + + '/// Negates the `amount` value before performing the reservation.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve-optional-flags\n' + + '///\n' + + 'const ReserveInvertSign: Int = 8;\n' + + '\n' + + '/// Bounces the transaction if the reservation fails.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve-optional-flags\n' + + '///\n' + + 'const ReserveBounceIfActionFail: Int = 16;\n', + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeReserve', + loc: { start: 1509, end: 1522 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'amount', + loc: { start: 1523, end: 1529 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1531, end: 1534 } + }, + loc: { start: 1531, end: 1534 } + }, + loc: { start: 1523, end: 1534 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 1536, end: 1540 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1542, end: 1545 } + }, + loc: { start: 1542, end: 1545 } + }, + loc: { start: 1536, end: 1545 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RAWRESERVE' ] + }, + loc: { start: 1501, end: 1561 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'ReserveExact', + loc: { start: 1780, end: 1792 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1794, end: 1797 } + }, + loc: { start: 1794, end: 1797 } + }, + initializer: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 1800, end: 1801 } + } + }, + loc: { start: 1774, end: 1802 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'ReserveAllExcept', + loc: { start: 2021, end: 2037 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2039, end: 2042 } + }, + loc: { start: 2039, end: 2042 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 2045, end: 2046 } + } + }, + loc: { start: 2015, end: 2047 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'ReserveAtMost', + loc: { start: 2266, end: 2279 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2281, end: 2284 } + }, + loc: { start: 2281, end: 2284 } + }, + initializer: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 2287, end: 2288 } + } + }, + loc: { start: 2260, end: 2289 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'ReserveAddOriginalBalance', + loc: { start: 2530, end: 2555 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2557, end: 2560 } + }, + loc: { start: 2557, end: 2560 } + }, + initializer: { + kind: 'number', + base: '10', + value: 4n, + loc: { start: 2563, end: 2564 } + } + }, + loc: { start: 2524, end: 2565 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'ReserveInvertSign', + loc: { start: 2734, end: 2751 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2753, end: 2756 } + }, + loc: { start: 2753, end: 2756 } + }, + initializer: { + kind: 'number', + base: '10', + value: 8n, + loc: { start: 2759, end: 2760 } + } + }, + loc: { start: 2728, end: 2761 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'ReserveBounceIfActionFail', + loc: { start: 2918, end: 2943 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2945, end: 2948 } + }, + loc: { start: 2945, end: 2948 } + }, + initializer: { + kind: 'number', + base: '10', + value: 16n, + loc: { start: 2951, end: 2953 } + } + }, + loc: { start: 2912, end: 2954 } + } + ] + }, + 'ReserveAllExcept' => { + kind: 'tact', + path: 'std/internal/reserve.tact', + code: '/// Executes the native `RAWRESERVE` instruction with the specified amount and mode.\n' + + '/// The `RAWRESERVE` instruction creates an output action to reserve a specific amount of\n' + + '/// [nanoToncoin] from the remaining balance of the account.\n' + + '///\n' + + '/// The `RAWRESERVE` instruction takes two arguments:\n' + + '/// * `amount`: The number of [nanoToncoin] to reserve.\n' + + '/// * `mode`: Determines the reservation behavior.\n' + + '///\n' + + '/// The `RAWRESERVE` instruction is roughly equivalent to creating an outbound message\n' + + '/// carrying the specified `amount` of [nanoToncoin] (or `b - amount` [nanoToncoin],\n' + + '/// where `b` is the remaining balance) to oneself.\n' + + '/// This ensures that subsequent output actions cannot spend more money than the remainder.\n' + + '///\n' + + '/// It is possible to use raw `Int` values and manually provide them for the `mode`,\n' + + "/// but for your convenience, there's a set of constants you may use to construct the\n" + + '/// compound `mode` with ease.\n' + + '///\n' + + '/// NOTE: Currently, `amount` must be a non-negative integer, and `mode` must be in the\n' + + '/// range `0..31`, inclusive.\n' + + '///\n' + + '/// Additionally, attempts to queue more than 255 reservations in one transaction throw an\n' + + '/// exception with [exit code 33]: `Action list is too long`.\n' + + '///\n' + + '/// NOTE: This function is gas-expensive and uses 500 gas units or more.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve\n' + + '///\n' + + '/// [exit code 33]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '/// [nanoToncoin]: https://docs.tact-lang.org/book/integers#nanotoncoin\n' + + 'asm fun nativeReserve(amount: Int, mode: Int) { RAWRESERVE }\n' + + '\n' + + '/// Reserves exactly the specified `amount` of\n' + + '/// [nanoToncoin](https://docs.tact-lang.org/book/integers#nanotoncoin).\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve-base-modes\n' + + '///\n' + + 'const ReserveExact: Int = 0;\n' + + '\n' + + '/// Reserves all but the specified `amount` of\n' + + '/// [nanoToncoin](https://docs.tact-lang.org/book/integers#nanotoncoin).\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve-base-modes\n' + + '///\n' + + 'const ReserveAllExcept: Int = 1;\n' + + '\n' + + '/// Reserves at most the specified `amount` of\n' + + '/// [nanoToncoin](https://docs.tact-lang.org/book/integers#nanotoncoin).\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve-base-modes\n' + + '///\n' + + 'const ReserveAtMost: Int = 2;\n' + + '\n' + + '/// Increases the `amount` by the original balance of the current account\n' + + '/// (before the compute phase), including all extra currencies.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve-optional-flags\n' + + '///\n' + + 'const ReserveAddOriginalBalance: Int = 4;\n' + + '\n' + + '/// Negates the `amount` value before performing the reservation.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve-optional-flags\n' + + '///\n' + + 'const ReserveInvertSign: Int = 8;\n' + + '\n' + + '/// Bounces the transaction if the reservation fails.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve-optional-flags\n' + + '///\n' + + 'const ReserveBounceIfActionFail: Int = 16;\n', + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeReserve', + loc: { start: 1509, end: 1522 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'amount', + loc: { start: 1523, end: 1529 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1531, end: 1534 } + }, + loc: { start: 1531, end: 1534 } + }, + loc: { start: 1523, end: 1534 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 1536, end: 1540 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1542, end: 1545 } + }, + loc: { start: 1542, end: 1545 } + }, + loc: { start: 1536, end: 1545 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RAWRESERVE' ] + }, + loc: { start: 1501, end: 1561 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'ReserveExact', + loc: { start: 1780, end: 1792 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1794, end: 1797 } + }, + loc: { start: 1794, end: 1797 } + }, + initializer: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 1800, end: 1801 } + } + }, + loc: { start: 1774, end: 1802 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'ReserveAllExcept', + loc: { start: 2021, end: 2037 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2039, end: 2042 } + }, + loc: { start: 2039, end: 2042 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 2045, end: 2046 } + } + }, + loc: { start: 2015, end: 2047 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'ReserveAtMost', + loc: { start: 2266, end: 2279 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2281, end: 2284 } + }, + loc: { start: 2281, end: 2284 } + }, + initializer: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 2287, end: 2288 } + } + }, + loc: { start: 2260, end: 2289 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'ReserveAddOriginalBalance', + loc: { start: 2530, end: 2555 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2557, end: 2560 } + }, + loc: { start: 2557, end: 2560 } + }, + initializer: { + kind: 'number', + base: '10', + value: 4n, + loc: { start: 2563, end: 2564 } + } + }, + loc: { start: 2524, end: 2565 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'ReserveInvertSign', + loc: { start: 2734, end: 2751 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2753, end: 2756 } + }, + loc: { start: 2753, end: 2756 } + }, + initializer: { + kind: 'number', + base: '10', + value: 8n, + loc: { start: 2759, end: 2760 } + } + }, + loc: { start: 2728, end: 2761 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'ReserveBounceIfActionFail', + loc: { start: 2918, end: 2943 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2945, end: 2948 } + }, + loc: { start: 2945, end: 2948 } + }, + initializer: { + kind: 'number', + base: '10', + value: 16n, + loc: { start: 2951, end: 2953 } + } + }, + loc: { start: 2912, end: 2954 } + } + ] + }, + 'ReserveAtMost' => { + kind: 'tact', + path: 'std/internal/reserve.tact', + code: '/// Executes the native `RAWRESERVE` instruction with the specified amount and mode.\n' + + '/// The `RAWRESERVE` instruction creates an output action to reserve a specific amount of\n' + + '/// [nanoToncoin] from the remaining balance of the account.\n' + + '///\n' + + '/// The `RAWRESERVE` instruction takes two arguments:\n' + + '/// * `amount`: The number of [nanoToncoin] to reserve.\n' + + '/// * `mode`: Determines the reservation behavior.\n' + + '///\n' + + '/// The `RAWRESERVE` instruction is roughly equivalent to creating an outbound message\n' + + '/// carrying the specified `amount` of [nanoToncoin] (or `b - amount` [nanoToncoin],\n' + + '/// where `b` is the remaining balance) to oneself.\n' + + '/// This ensures that subsequent output actions cannot spend more money than the remainder.\n' + + '///\n' + + '/// It is possible to use raw `Int` values and manually provide them for the `mode`,\n' + + "/// but for your convenience, there's a set of constants you may use to construct the\n" + + '/// compound `mode` with ease.\n' + + '///\n' + + '/// NOTE: Currently, `amount` must be a non-negative integer, and `mode` must be in the\n' + + '/// range `0..31`, inclusive.\n' + + '///\n' + + '/// Additionally, attempts to queue more than 255 reservations in one transaction throw an\n' + + '/// exception with [exit code 33]: `Action list is too long`.\n' + + '///\n' + + '/// NOTE: This function is gas-expensive and uses 500 gas units or more.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve\n' + + '///\n' + + '/// [exit code 33]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '/// [nanoToncoin]: https://docs.tact-lang.org/book/integers#nanotoncoin\n' + + 'asm fun nativeReserve(amount: Int, mode: Int) { RAWRESERVE }\n' + + '\n' + + '/// Reserves exactly the specified `amount` of\n' + + '/// [nanoToncoin](https://docs.tact-lang.org/book/integers#nanotoncoin).\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve-base-modes\n' + + '///\n' + + 'const ReserveExact: Int = 0;\n' + + '\n' + + '/// Reserves all but the specified `amount` of\n' + + '/// [nanoToncoin](https://docs.tact-lang.org/book/integers#nanotoncoin).\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve-base-modes\n' + + '///\n' + + 'const ReserveAllExcept: Int = 1;\n' + + '\n' + + '/// Reserves at most the specified `amount` of\n' + + '/// [nanoToncoin](https://docs.tact-lang.org/book/integers#nanotoncoin).\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve-base-modes\n' + + '///\n' + + 'const ReserveAtMost: Int = 2;\n' + + '\n' + + '/// Increases the `amount` by the original balance of the current account\n' + + '/// (before the compute phase), including all extra currencies.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve-optional-flags\n' + + '///\n' + + 'const ReserveAddOriginalBalance: Int = 4;\n' + + '\n' + + '/// Negates the `amount` value before performing the reservation.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve-optional-flags\n' + + '///\n' + + 'const ReserveInvertSign: Int = 8;\n' + + '\n' + + '/// Bounces the transaction if the reservation fails.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve-optional-flags\n' + + '///\n' + + 'const ReserveBounceIfActionFail: Int = 16;\n', + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeReserve', + loc: { start: 1509, end: 1522 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'amount', + loc: { start: 1523, end: 1529 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1531, end: 1534 } + }, + loc: { start: 1531, end: 1534 } + }, + loc: { start: 1523, end: 1534 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 1536, end: 1540 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1542, end: 1545 } + }, + loc: { start: 1542, end: 1545 } + }, + loc: { start: 1536, end: 1545 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RAWRESERVE' ] + }, + loc: { start: 1501, end: 1561 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'ReserveExact', + loc: { start: 1780, end: 1792 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1794, end: 1797 } + }, + loc: { start: 1794, end: 1797 } + }, + initializer: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 1800, end: 1801 } + } + }, + loc: { start: 1774, end: 1802 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'ReserveAllExcept', + loc: { start: 2021, end: 2037 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2039, end: 2042 } + }, + loc: { start: 2039, end: 2042 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 2045, end: 2046 } + } + }, + loc: { start: 2015, end: 2047 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'ReserveAtMost', + loc: { start: 2266, end: 2279 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2281, end: 2284 } + }, + loc: { start: 2281, end: 2284 } + }, + initializer: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 2287, end: 2288 } + } + }, + loc: { start: 2260, end: 2289 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'ReserveAddOriginalBalance', + loc: { start: 2530, end: 2555 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2557, end: 2560 } + }, + loc: { start: 2557, end: 2560 } + }, + initializer: { + kind: 'number', + base: '10', + value: 4n, + loc: { start: 2563, end: 2564 } + } + }, + loc: { start: 2524, end: 2565 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'ReserveInvertSign', + loc: { start: 2734, end: 2751 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2753, end: 2756 } + }, + loc: { start: 2753, end: 2756 } + }, + initializer: { + kind: 'number', + base: '10', + value: 8n, + loc: { start: 2759, end: 2760 } + } + }, + loc: { start: 2728, end: 2761 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'ReserveBounceIfActionFail', + loc: { start: 2918, end: 2943 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2945, end: 2948 } + }, + loc: { start: 2945, end: 2948 } + }, + initializer: { + kind: 'number', + base: '10', + value: 16n, + loc: { start: 2951, end: 2953 } + } + }, + loc: { start: 2912, end: 2954 } + } + ] + }, + 'ReserveAddOriginalBalance' => { + kind: 'tact', + path: 'std/internal/reserve.tact', + code: '/// Executes the native `RAWRESERVE` instruction with the specified amount and mode.\n' + + '/// The `RAWRESERVE` instruction creates an output action to reserve a specific amount of\n' + + '/// [nanoToncoin] from the remaining balance of the account.\n' + + '///\n' + + '/// The `RAWRESERVE` instruction takes two arguments:\n' + + '/// * `amount`: The number of [nanoToncoin] to reserve.\n' + + '/// * `mode`: Determines the reservation behavior.\n' + + '///\n' + + '/// The `RAWRESERVE` instruction is roughly equivalent to creating an outbound message\n' + + '/// carrying the specified `amount` of [nanoToncoin] (or `b - amount` [nanoToncoin],\n' + + '/// where `b` is the remaining balance) to oneself.\n' + + '/// This ensures that subsequent output actions cannot spend more money than the remainder.\n' + + '///\n' + + '/// It is possible to use raw `Int` values and manually provide them for the `mode`,\n' + + "/// but for your convenience, there's a set of constants you may use to construct the\n" + + '/// compound `mode` with ease.\n' + + '///\n' + + '/// NOTE: Currently, `amount` must be a non-negative integer, and `mode` must be in the\n' + + '/// range `0..31`, inclusive.\n' + + '///\n' + + '/// Additionally, attempts to queue more than 255 reservations in one transaction throw an\n' + + '/// exception with [exit code 33]: `Action list is too long`.\n' + + '///\n' + + '/// NOTE: This function is gas-expensive and uses 500 gas units or more.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve\n' + + '///\n' + + '/// [exit code 33]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '/// [nanoToncoin]: https://docs.tact-lang.org/book/integers#nanotoncoin\n' + + 'asm fun nativeReserve(amount: Int, mode: Int) { RAWRESERVE }\n' + + '\n' + + '/// Reserves exactly the specified `amount` of\n' + + '/// [nanoToncoin](https://docs.tact-lang.org/book/integers#nanotoncoin).\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve-base-modes\n' + + '///\n' + + 'const ReserveExact: Int = 0;\n' + + '\n' + + '/// Reserves all but the specified `amount` of\n' + + '/// [nanoToncoin](https://docs.tact-lang.org/book/integers#nanotoncoin).\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve-base-modes\n' + + '///\n' + + 'const ReserveAllExcept: Int = 1;\n' + + '\n' + + '/// Reserves at most the specified `amount` of\n' + + '/// [nanoToncoin](https://docs.tact-lang.org/book/integers#nanotoncoin).\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve-base-modes\n' + + '///\n' + + 'const ReserveAtMost: Int = 2;\n' + + '\n' + + '/// Increases the `amount` by the original balance of the current account\n' + + '/// (before the compute phase), including all extra currencies.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve-optional-flags\n' + + '///\n' + + 'const ReserveAddOriginalBalance: Int = 4;\n' + + '\n' + + '/// Negates the `amount` value before performing the reservation.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve-optional-flags\n' + + '///\n' + + 'const ReserveInvertSign: Int = 8;\n' + + '\n' + + '/// Bounces the transaction if the reservation fails.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve-optional-flags\n' + + '///\n' + + 'const ReserveBounceIfActionFail: Int = 16;\n', + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeReserve', + loc: { start: 1509, end: 1522 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'amount', + loc: { start: 1523, end: 1529 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1531, end: 1534 } + }, + loc: { start: 1531, end: 1534 } + }, + loc: { start: 1523, end: 1534 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 1536, end: 1540 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1542, end: 1545 } + }, + loc: { start: 1542, end: 1545 } + }, + loc: { start: 1536, end: 1545 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RAWRESERVE' ] + }, + loc: { start: 1501, end: 1561 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'ReserveExact', + loc: { start: 1780, end: 1792 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1794, end: 1797 } + }, + loc: { start: 1794, end: 1797 } + }, + initializer: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 1800, end: 1801 } + } + }, + loc: { start: 1774, end: 1802 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'ReserveAllExcept', + loc: { start: 2021, end: 2037 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2039, end: 2042 } + }, + loc: { start: 2039, end: 2042 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 2045, end: 2046 } + } + }, + loc: { start: 2015, end: 2047 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'ReserveAtMost', + loc: { start: 2266, end: 2279 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2281, end: 2284 } + }, + loc: { start: 2281, end: 2284 } + }, + initializer: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 2287, end: 2288 } + } + }, + loc: { start: 2260, end: 2289 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'ReserveAddOriginalBalance', + loc: { start: 2530, end: 2555 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2557, end: 2560 } + }, + loc: { start: 2557, end: 2560 } + }, + initializer: { + kind: 'number', + base: '10', + value: 4n, + loc: { start: 2563, end: 2564 } + } + }, + loc: { start: 2524, end: 2565 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'ReserveInvertSign', + loc: { start: 2734, end: 2751 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2753, end: 2756 } + }, + loc: { start: 2753, end: 2756 } + }, + initializer: { + kind: 'number', + base: '10', + value: 8n, + loc: { start: 2759, end: 2760 } + } + }, + loc: { start: 2728, end: 2761 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'ReserveBounceIfActionFail', + loc: { start: 2918, end: 2943 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2945, end: 2948 } + }, + loc: { start: 2945, end: 2948 } + }, + initializer: { + kind: 'number', + base: '10', + value: 16n, + loc: { start: 2951, end: 2953 } + } + }, + loc: { start: 2912, end: 2954 } + } + ] + }, + 'ReserveInvertSign' => { + kind: 'tact', + path: 'std/internal/reserve.tact', + code: '/// Executes the native `RAWRESERVE` instruction with the specified amount and mode.\n' + + '/// The `RAWRESERVE` instruction creates an output action to reserve a specific amount of\n' + + '/// [nanoToncoin] from the remaining balance of the account.\n' + + '///\n' + + '/// The `RAWRESERVE` instruction takes two arguments:\n' + + '/// * `amount`: The number of [nanoToncoin] to reserve.\n' + + '/// * `mode`: Determines the reservation behavior.\n' + + '///\n' + + '/// The `RAWRESERVE` instruction is roughly equivalent to creating an outbound message\n' + + '/// carrying the specified `amount` of [nanoToncoin] (or `b - amount` [nanoToncoin],\n' + + '/// where `b` is the remaining balance) to oneself.\n' + + '/// This ensures that subsequent output actions cannot spend more money than the remainder.\n' + + '///\n' + + '/// It is possible to use raw `Int` values and manually provide them for the `mode`,\n' + + "/// but for your convenience, there's a set of constants you may use to construct the\n" + + '/// compound `mode` with ease.\n' + + '///\n' + + '/// NOTE: Currently, `amount` must be a non-negative integer, and `mode` must be in the\n' + + '/// range `0..31`, inclusive.\n' + + '///\n' + + '/// Additionally, attempts to queue more than 255 reservations in one transaction throw an\n' + + '/// exception with [exit code 33]: `Action list is too long`.\n' + + '///\n' + + '/// NOTE: This function is gas-expensive and uses 500 gas units or more.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve\n' + + '///\n' + + '/// [exit code 33]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '/// [nanoToncoin]: https://docs.tact-lang.org/book/integers#nanotoncoin\n' + + 'asm fun nativeReserve(amount: Int, mode: Int) { RAWRESERVE }\n' + + '\n' + + '/// Reserves exactly the specified `amount` of\n' + + '/// [nanoToncoin](https://docs.tact-lang.org/book/integers#nanotoncoin).\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve-base-modes\n' + + '///\n' + + 'const ReserveExact: Int = 0;\n' + + '\n' + + '/// Reserves all but the specified `amount` of\n' + + '/// [nanoToncoin](https://docs.tact-lang.org/book/integers#nanotoncoin).\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve-base-modes\n' + + '///\n' + + 'const ReserveAllExcept: Int = 1;\n' + + '\n' + + '/// Reserves at most the specified `amount` of\n' + + '/// [nanoToncoin](https://docs.tact-lang.org/book/integers#nanotoncoin).\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve-base-modes\n' + + '///\n' + + 'const ReserveAtMost: Int = 2;\n' + + '\n' + + '/// Increases the `amount` by the original balance of the current account\n' + + '/// (before the compute phase), including all extra currencies.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve-optional-flags\n' + + '///\n' + + 'const ReserveAddOriginalBalance: Int = 4;\n' + + '\n' + + '/// Negates the `amount` value before performing the reservation.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve-optional-flags\n' + + '///\n' + + 'const ReserveInvertSign: Int = 8;\n' + + '\n' + + '/// Bounces the transaction if the reservation fails.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve-optional-flags\n' + + '///\n' + + 'const ReserveBounceIfActionFail: Int = 16;\n', + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeReserve', + loc: { start: 1509, end: 1522 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'amount', + loc: { start: 1523, end: 1529 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1531, end: 1534 } + }, + loc: { start: 1531, end: 1534 } + }, + loc: { start: 1523, end: 1534 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 1536, end: 1540 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1542, end: 1545 } + }, + loc: { start: 1542, end: 1545 } + }, + loc: { start: 1536, end: 1545 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RAWRESERVE' ] + }, + loc: { start: 1501, end: 1561 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'ReserveExact', + loc: { start: 1780, end: 1792 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1794, end: 1797 } + }, + loc: { start: 1794, end: 1797 } + }, + initializer: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 1800, end: 1801 } + } + }, + loc: { start: 1774, end: 1802 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'ReserveAllExcept', + loc: { start: 2021, end: 2037 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2039, end: 2042 } + }, + loc: { start: 2039, end: 2042 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 2045, end: 2046 } + } + }, + loc: { start: 2015, end: 2047 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'ReserveAtMost', + loc: { start: 2266, end: 2279 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2281, end: 2284 } + }, + loc: { start: 2281, end: 2284 } + }, + initializer: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 2287, end: 2288 } + } + }, + loc: { start: 2260, end: 2289 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'ReserveAddOriginalBalance', + loc: { start: 2530, end: 2555 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2557, end: 2560 } + }, + loc: { start: 2557, end: 2560 } + }, + initializer: { + kind: 'number', + base: '10', + value: 4n, + loc: { start: 2563, end: 2564 } + } + }, + loc: { start: 2524, end: 2565 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'ReserveInvertSign', + loc: { start: 2734, end: 2751 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2753, end: 2756 } + }, + loc: { start: 2753, end: 2756 } + }, + initializer: { + kind: 'number', + base: '10', + value: 8n, + loc: { start: 2759, end: 2760 } + } + }, + loc: { start: 2728, end: 2761 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'ReserveBounceIfActionFail', + loc: { start: 2918, end: 2943 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2945, end: 2948 } + }, + loc: { start: 2945, end: 2948 } + }, + initializer: { + kind: 'number', + base: '10', + value: 16n, + loc: { start: 2951, end: 2953 } + } + }, + loc: { start: 2912, end: 2954 } + } + ] + }, + 'ReserveBounceIfActionFail' => { + kind: 'tact', + path: 'std/internal/reserve.tact', + code: '/// Executes the native `RAWRESERVE` instruction with the specified amount and mode.\n' + + '/// The `RAWRESERVE` instruction creates an output action to reserve a specific amount of\n' + + '/// [nanoToncoin] from the remaining balance of the account.\n' + + '///\n' + + '/// The `RAWRESERVE` instruction takes two arguments:\n' + + '/// * `amount`: The number of [nanoToncoin] to reserve.\n' + + '/// * `mode`: Determines the reservation behavior.\n' + + '///\n' + + '/// The `RAWRESERVE` instruction is roughly equivalent to creating an outbound message\n' + + '/// carrying the specified `amount` of [nanoToncoin] (or `b - amount` [nanoToncoin],\n' + + '/// where `b` is the remaining balance) to oneself.\n' + + '/// This ensures that subsequent output actions cannot spend more money than the remainder.\n' + + '///\n' + + '/// It is possible to use raw `Int` values and manually provide them for the `mode`,\n' + + "/// but for your convenience, there's a set of constants you may use to construct the\n" + + '/// compound `mode` with ease.\n' + + '///\n' + + '/// NOTE: Currently, `amount` must be a non-negative integer, and `mode` must be in the\n' + + '/// range `0..31`, inclusive.\n' + + '///\n' + + '/// Additionally, attempts to queue more than 255 reservations in one transaction throw an\n' + + '/// exception with [exit code 33]: `Action list is too long`.\n' + + '///\n' + + '/// NOTE: This function is gas-expensive and uses 500 gas units or more.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve\n' + + '///\n' + + '/// [exit code 33]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '/// [nanoToncoin]: https://docs.tact-lang.org/book/integers#nanotoncoin\n' + + 'asm fun nativeReserve(amount: Int, mode: Int) { RAWRESERVE }\n' + + '\n' + + '/// Reserves exactly the specified `amount` of\n' + + '/// [nanoToncoin](https://docs.tact-lang.org/book/integers#nanotoncoin).\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve-base-modes\n' + + '///\n' + + 'const ReserveExact: Int = 0;\n' + + '\n' + + '/// Reserves all but the specified `amount` of\n' + + '/// [nanoToncoin](https://docs.tact-lang.org/book/integers#nanotoncoin).\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve-base-modes\n' + + '///\n' + + 'const ReserveAllExcept: Int = 1;\n' + + '\n' + + '/// Reserves at most the specified `amount` of\n' + + '/// [nanoToncoin](https://docs.tact-lang.org/book/integers#nanotoncoin).\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve-base-modes\n' + + '///\n' + + 'const ReserveAtMost: Int = 2;\n' + + '\n' + + '/// Increases the `amount` by the original balance of the current account\n' + + '/// (before the compute phase), including all extra currencies.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve-optional-flags\n' + + '///\n' + + 'const ReserveAddOriginalBalance: Int = 4;\n' + + '\n' + + '/// Negates the `amount` value before performing the reservation.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve-optional-flags\n' + + '///\n' + + 'const ReserveInvertSign: Int = 8;\n' + + '\n' + + '/// Bounces the transaction if the reservation fails.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-contextstate#nativereserve-optional-flags\n' + + '///\n' + + 'const ReserveBounceIfActionFail: Int = 16;\n', + imports: [], + items: [ + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeReserve', + loc: { start: 1509, end: 1522 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'amount', + loc: { start: 1523, end: 1529 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1531, end: 1534 } + }, + loc: { start: 1531, end: 1534 } + }, + loc: { start: 1523, end: 1534 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 1536, end: 1540 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1542, end: 1545 } + }, + loc: { start: 1542, end: 1545 } + }, + loc: { start: 1536, end: 1545 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'RAWRESERVE' ] + }, + loc: { start: 1501, end: 1561 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'ReserveExact', + loc: { start: 1780, end: 1792 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1794, end: 1797 } + }, + loc: { start: 1794, end: 1797 } + }, + initializer: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 1800, end: 1801 } + } + }, + loc: { start: 1774, end: 1802 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'ReserveAllExcept', + loc: { start: 2021, end: 2037 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2039, end: 2042 } + }, + loc: { start: 2039, end: 2042 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 2045, end: 2046 } + } + }, + loc: { start: 2015, end: 2047 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'ReserveAtMost', + loc: { start: 2266, end: 2279 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2281, end: 2284 } + }, + loc: { start: 2281, end: 2284 } + }, + initializer: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 2287, end: 2288 } + } + }, + loc: { start: 2260, end: 2289 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'ReserveAddOriginalBalance', + loc: { start: 2530, end: 2555 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2557, end: 2560 } + }, + loc: { start: 2557, end: 2560 } + }, + initializer: { + kind: 'number', + base: '10', + value: 4n, + loc: { start: 2563, end: 2564 } + } + }, + loc: { start: 2524, end: 2565 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'ReserveInvertSign', + loc: { start: 2734, end: 2751 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2753, end: 2756 } + }, + loc: { start: 2753, end: 2756 } + }, + initializer: { + kind: 'number', + base: '10', + value: 8n, + loc: { start: 2759, end: 2760 } + } + }, + loc: { start: 2728, end: 2761 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'ReserveBounceIfActionFail', + loc: { start: 2918, end: 2943 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2945, end: 2948 } + }, + loc: { start: 2945, end: 2948 } + }, + initializer: { + kind: 'number', + base: '10', + value: 16n, + loc: { start: 2951, end: 2953 } + } + }, + loc: { start: 2912, end: 2954 } + } + ] + }, + 'SendDefaultMode' => { + kind: 'tact', + path: 'std/internal/send.tact', + code: '/// Ordinary message (default).\n' + + '///\n' + + '/// This constant is available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendDefaultMode: Int = 0;\n' + + '\n' + + '/// Carry all the remaining value of the inbound message in addition\n' + + '/// to the value initially indicated in the new message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendRemainingValue: Int = 64;\n' + + '\n' + + '/// Carry **all the remaining balance** of the current smart contract instead\n' + + '/// of the value originally indicated in the message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendRemainingBalance: Int = 128;\n' + + '\n' + + "/// Doesn't send the message, only estimates the forward fees\n" + + '/// if the message-sending function computes those.\n' + + '///\n' + + '/// This constant is available since Tact 1.5.0.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '/// * https://docs.tact-lang.org/book/send#message-sending-functions\n' + + '///\n' + + 'const SendOnlyEstimateFee: Int = 1024;\n' + + '\n' + + '/// **Deprecated** since Tact 1.6.5.\n' + + '///\n' + + '/// Pay forward fees separately from the message value.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendPayGasSeparately: Int = 1;\n' + + '\n' + + '/// Pay forward fees separately from the message value.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendPayFwdFeesSeparately: Int = 1;\n' + + '\n' + + '/// Ignore any errors arising while processing this message during the action phase.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendIgnoreErrors: Int = 2;\n' + + '\n' + + '/// Bounce transaction in case of any errors during action phase.\n' + + '/// Has no effect if flag +2, `SendIgnoreErrors` is used.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendBounceIfActionFail: Int = 16;\n' + + '\n' + + '/// Current account (contract) will be destroyed if its resulting balance is zero.\n' + + '/// This flag is often used with mode 128, `SendRemainingBalance`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendDestroyIfZero: Int = 32;\n' + + '\n' + + '/// Struct for specifying the message parameters of the `send()` function.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#send\n' + + '///\n' + + 'struct SendParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// Optional initial code of the contract (compiled bitcode).\n' + + ' code: Cell? = null;\n' + + '\n' + + ' /// Optional initial data of the contract (arguments of `init()` function or values of contract parameters).\n' + + ' data: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// Recipient internal `Address` on TON Blockchain.\n' + + ' to: Address;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '}\n' + + '\n' + + '/// Struct for specifying the message parameters of the `message()` function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#message\n' + + '///\n' + + 'struct MessageParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// Recipient internal `Address` on TON Blockchain.\n' + + ' to: Address;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Queues the message to be sent using the `MessageParameters` struct. Allows for cheaper non-deployment, regular messages compared to the `send()` function.\n' + + '///\n' + + '/// The `MessageParameters` struct is similar to `SendParameters` struct, but without the `code` and `data` fields.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// message(MessageParameters{\n' + + '/// to: sender(), // back to the sender,\n' + + '/// value: ton("1"), // with 1 Toncoin (1_000_000_000 nanoToncoin),\n' + + '/// // and no message body\n' + + '/// });\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 33: [Action list is too long] — Thrown when attempting to queue more than 255 messages.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-send#message\n' + + '/// * https://docs.tact-lang.org/book/message-mode\n' + + '///\n' + + '/// [Action list is too long]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '///\n' + + 'asm fun message(params: MessageParameters) {\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 106 PUSHINT // 1 + 4 + 4 + 64 + 32 + 1\n' + + ' STZEROES\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + ' STDICT\n' + + ' ENDC\n' + + ' SWAP\n' + + ' SENDRAWMSG\n' + + '}\n' + + '\n' + + '/// Global function. Queues the message to be sent using a `SendParameters` Struct.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// send(SendParameters{\n' + + '/// to: sender(), // back to the sender,\n' + + '/// value: ton("1"), // with 1 Toncoin (1_000_000_000 nanoToncoin),\n' + + '/// // and no message body\n' + + '/// });\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 33: [Action list is too long] — Thrown when attempting to queue more than 255 messages.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#send\n' + + '///\n' + + '/// [Action list is too long]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '///\n' + + 'asm fun send(params: SendParameters) {\n' + + ' // Instructions are grouped, and the stack states they produce as a group are shown right after.\n' + + ' // In the end, our message Cell should have the following TL-B structure:\n' + + ' // message$_ {X:Type}\n' + + ' // info:CommonMsgInfoRelaxed\n' + + ' // init:(Maybe (Either StateInit ^StateInit))\n' + + ' // body:(Either X ^X)\n' + + ' // = MessageRelaxed X;\n' + + '\n' + + ' // → Stack state\n' + + ' // s0: `params.bounce`\n' + + ' // s1: `params.to`\n' + + ' // s2: `params.value`\n' + + ' // s3: `params.data`\n' + + ' // s4: `params.code`\n' + + ' // s5: `params.body`\n' + + ' // s6: `params.mode`\n' + + ' // For brevity, the "params" prefix will be omitted from now on.\n' + + '\n' + + ' // Group 1: Storing the `bounce`, `to` and `value` into a Builder\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + '\n' + + ' // Group 2: Placing the Builder after code and data, then checking those for nullability\n' + + ' s2 XCHG0\n' + + ' DUP2\n' + + ' ISNULL\n' + + ' SWAP\n' + + ' ISNULL\n' + + ' AND\n' + + ' // → Stack state\n' + + ' // s0: -1 (true) if `data` and `code` are both null, 0 (false) otherwise\n' + + ' // s1: `code`\n' + + ' // s2: `data`\n' + + ' // s3: Builder\n' + + ' // s4: `body`\n' + + ' // s5: `mode`\n' + + '\n' + + ' // Group 3: Left branch of the IFELSE, executed if s0 is -1 (true)\n' + + ' <{\n' + + ' DROP2 // drop `data` and `code`, since either of those is null\n' + + ' b{0} STSLICECONST\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: Right branch of the IFELSE, executed if s0 is 0 (false)\n' + + ' <{\n' + + ' // _ split_depth:(Maybe (## 5))\n' + + ' // special:(Maybe TickTock)\n' + + ' // code:(Maybe ^Cell)\n' + + ' // data:(Maybe ^Cell)\n' + + ' // library:(Maybe ^Cell)\n' + + ' // = StateInit;\n' + + ' ROT // place message Builder on top\n' + + ' b{10} STSLICECONST // store Maybe = true, Either = false\n' + + ' // Start composing inlined StateInit\n' + + ' b{00} STSLICECONST // store split_depth and special first\n' + + ' STDICT // store code\n' + + ' STDICT // store data\n' + + ' b{0} STSLICECONST // store library\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: IFELSE that does the branching shown above\n' + + ' IFELSE\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: null or StateInit\n' + + ' // s2: `body`\n' + + ' // s3: `mode`\n' + + '\n' + + ' // Group 4: Finalizing the message\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: `mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG // https://github.com/tact-lang/tact/issues/1558\n' + + '}\n' + + '\n' + + '/// Struct for specifying the deployment message parameters of the `deploy()` function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#deploy\n' + + '///\n' + + 'struct DeployParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '\n' + + ' //'... 12658 more characters, + imports: [], + items: [ + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendDefaultMode', + loc: { start: 164, end: 179 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 181, end: 184 } + }, + loc: { start: 181, end: 184 } + }, + initializer: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 187, end: 188 } + } + }, + loc: { start: 158, end: 189 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendRemainingValue', + loc: { start: 396, end: 414 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 416, end: 419 } + }, + loc: { start: 416, end: 419 } + }, + initializer: { + kind: 'number', + base: '10', + value: 64n, + loc: { start: 422, end: 424 } + } + }, + loc: { start: 390, end: 425 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendRemainingBalance', + loc: { start: 638, end: 658 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 660, end: 663 } + }, + loc: { start: 660, end: 663 } + }, + initializer: { + kind: 'number', + base: '10', + value: 128n, + loc: { start: 666, end: 669 } + } + }, + loc: { start: 632, end: 670 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendOnlyEstimateFee', + loc: { start: 993, end: 1012 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1014, end: 1017 } + }, + loc: { start: 1014, end: 1017 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1024n, + loc: { start: 1020, end: 1024 } + } + }, + loc: { start: 987, end: 1025 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendPayGasSeparately', + loc: { start: 1207, end: 1227 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1229, end: 1232 } + }, + loc: { start: 1229, end: 1232 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1235, end: 1236 } + } + }, + loc: { start: 1201, end: 1237 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendPayFwdFeesSeparately', + loc: { start: 1378, end: 1402 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1404, end: 1407 } + }, + loc: { start: 1404, end: 1407 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1410, end: 1411 } + } + }, + loc: { start: 1372, end: 1412 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendIgnoreErrors', + loc: { start: 1582, end: 1598 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1600, end: 1603 } + }, + loc: { start: 1600, end: 1603 } + }, + initializer: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 1606, end: 1607 } + } + }, + loc: { start: 1576, end: 1608 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendBounceIfActionFail', + loc: { start: 1817, end: 1839 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1841, end: 1844 } + }, + loc: { start: 1841, end: 1844 } + }, + initializer: { + kind: 'number', + base: '10', + value: 16n, + loc: { start: 1847, end: 1849 } + } + }, + loc: { start: 1811, end: 1850 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendDestroyIfZero', + loc: { start: 2085, end: 2102 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2104, end: 2107 } + }, + loc: { start: 2104, end: 2107 } + }, + initializer: { + kind: 'number', + base: '10', + value: 32n, + loc: { start: 2110, end: 2112 } + } + }, + loc: { start: 2079, end: 2113 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'SendParameters', + loc: { start: 2260, end: 2274 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 2416, end: 2420 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2422, end: 2425 } + }, + loc: { start: 2422, end: 2425 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 2428, end: 2443 } + }, + loc: { start: 2416, end: 2443 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 2493, end: 2497 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2503, end: 2504 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2499, end: 2503 } + }, + loc: { start: 2499, end: 2503 } + } + ], + loc: { start: 2503, end: 2504 } + }, + initializer: { kind: 'null', loc: { start: 2507, end: 2511 } }, + loc: { start: 2493, end: 2511 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'code', + loc: { start: 2584, end: 2588 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2594, end: 2595 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2590, end: 2594 } + }, + loc: { start: 2590, end: 2594 } + } + ], + loc: { start: 2594, end: 2595 } + }, + initializer: { kind: 'null', loc: { start: 2598, end: 2602 } }, + loc: { start: 2584, end: 2602 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'data', + loc: { start: 2722, end: 2726 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2732, end: 2733 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2728, end: 2732 } + }, + loc: { start: 2728, end: 2732 } + } + ], + loc: { start: 2732, end: 2733 } + }, + initializer: { kind: 'null', loc: { start: 2736, end: 2740 } }, + loc: { start: 2722, end: 2740 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 2936, end: 2941 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2943, end: 2946 } + }, + loc: { start: 2943, end: 2946 } + }, + initializer: undefined, + loc: { start: 2936, end: 2946 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'to', + loc: { start: 3009, end: 3011 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3013, end: 3020 } + }, + typeArgs: [], + loc: { start: 3013, end: 3020 } + }, + initializer: undefined, + loc: { start: 3009, end: 3020 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 3186, end: 3192 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 3194, end: 3198 } + }, + typeArgs: [], + loc: { start: 3194, end: 3198 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 3201, end: 3205 } + }, + loc: { start: 3186, end: 3205 } + } + ], + loc: { start: 2253, end: 3208 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'MessageParameters', + loc: { start: 3389, end: 3406 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 3548, end: 3552 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3554, end: 3557 } + }, + loc: { start: 3554, end: 3557 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 3560, end: 3575 } + }, + loc: { start: 3548, end: 3575 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 3625, end: 3629 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 3635, end: 3636 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 3631, end: 3635 } + }, + loc: { start: 3631, end: 3635 } + } + ], + loc: { start: 3635, end: 3636 } + }, + initializer: { kind: 'null', loc: { start: 3639, end: 3643 } }, + loc: { start: 3625, end: 3643 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 3839, end: 3844 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3846, end: 3849 } + }, + loc: { start: 3846, end: 3849 } + }, + initializer: undefined, + loc: { start: 3839, end: 3849 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'to', + loc: { start: 3912, end: 3914 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3916, end: 3923 } + }, + typeArgs: [], + loc: { start: 3916, end: 3923 } + }, + initializer: undefined, + loc: { start: 3912, end: 3923 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 4089, end: 4095 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 4097, end: 4101 } + }, + typeArgs: [], + loc: { start: 4097, end: 4101 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 4104, end: 4108 } + }, + loc: { start: 4089, end: 4108 } + } + ], + loc: { start: 3382, end: 4111 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'message', + loc: { start: 5056, end: 5063 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 5064, end: 5070 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'MessageParameters', + loc: { start: 5072, end: 5089 } + }, + typeArgs: [], + loc: { start: 5072, end: 5089 } + }, + loc: { start: 5064, end: 5089 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 106 PUSHINT // 1 + 4 + 4 + 64 + 32 + 1\n' + + ' STZEROES\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + ' STDICT\n' + + ' ENDC\n' + + ' SWAP\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 5048, end: 5588 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'send', loc: { start: 6219, end: 6223 } }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 6224, end: 6230 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'SendParameters', + loc: { start: 6232, end: 6246 } + }, + typeArgs: [], + loc: { start: 6232, end: 6246 } + }, + loc: { start: 6224, end: 6246 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + '\n' + + ' // Group 2: Placing the Builder after code and data, then checking those for nullability\n' + + ' s2 XCHG0\n' + + ' DUP2\n' + + ' ISNULL\n' + + ' SWAP\n' + + ' ISNULL\n' + + ' AND\n' + + ' // → Stack state\n' + + ' // s0: -1 (true) if `data` and `code` are both null, 0 (false) otherwise\n' + + ' // s1: `code`\n' + + ' // s2: `data`\n' + + ' // s3: Builder\n' + + ' // s4: `body`\n' + + ' // s5: `mode`\n' + + '\n' + + ' // Group 3: Left branch of the IFELSE, executed if s0 is -1 (true)\n' + + ' <{\n' + + ' DROP2 // drop `data` and `code`, since either of those is null\n' + + ' b{0} STSLICECONST\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: Right branch of the IFELSE, executed if s0 is 0 (false)\n' + + ' <{\n' + + ' // _ split_depth:(Maybe (## 5))\n' + + ' // special:(Maybe TickTock)\n' + + ' // code:(Maybe ^Cell)\n' + + ' // data:(Maybe ^Cell)\n' + + ' // library:(Maybe ^Cell)\n' + + ' // = StateInit;\n' + + ' ROT // place message Builder on top\n' + + ' b{10} STSLICECONST // store Maybe = true, Either = false\n' + + ' // Start composing inlined StateInit\n' + + ' b{00} STSLICECONST // store split_depth and special first\n' + + ' STDICT // store code\n' + + ' STDICT // store data\n' + + ' b{0} STSLICECONST // store library\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: IFELSE that does the branching shown above\n' + + ' IFELSE\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: null or StateInit\n' + + ' // s2: `body`\n' + + ' // s3: `mode`\n' + + '\n' + + ' // Group 4: Finalizing the message\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: `mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG // https://github.com/tact-lang/tact/issues/1558' + ] + }, + loc: { start: 6211, end: 9157 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'DeployParameters', + loc: { start: 9347, end: 9363 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 9505, end: 9509 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9511, end: 9514 } + }, + loc: { start: 9511, end: 9514 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 9517, end: 9532 } + }, + loc: { start: 9505, end: 9532 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 9582, end: 9586 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 9592, end: 9593 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 9588, end: 9592 } + }, + loc: { start: 9588, end: 9592 } + } + ], + loc: { start: 9592, end: 9593 } + }, + initializer: { kind: 'null', loc: { start: 9596, end: 9600 } }, + loc: { start: 9582, end: 9600 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 9796, end: 9801 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9803, end: 9806 } + }, + loc: { start: 9803, end: 9806 } + }, + initializer: undefined, + loc: { start: 9796, end: 9806 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 9972, end: 9978 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 9980, end: 9984 } + }, + typeArgs: [], + loc: { start: 9980, end: 9984 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 9987, end: 9991 } + }, + loc: { start: 9972, end: 9991 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'init', + loc: { start: 10135, end: 10139 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 10141, end: 10150 } + }, + typeArgs: [], + loc: { start: 10141, end: 10150 } + }, + initializer: undefined, + loc: { start: 10135, end: 10150 } + } + ], + loc: { start: 9340, end: 10153 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'deploy', + loc: { start: 11796, end: 11802 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 11803, end: 11809 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'DeployParameters', + loc: { start: 11811, end: 11827 } + }, + typeArgs: [], + loc: { start: 11811, end: 11827 } + }, + loc: { start: 11803, end: 11827 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '4 1 BLKPUSH // pushes 2 copies of `init.code` and `init.data`\n' + + ' HASHCU // `init.data` hash\n' + + ' SWAP\n' + + ' HASHCU // `init.code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `init.data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `init.code` depth\n' + + '\n' + + ' // Group 2: Calculating destination address\n' + + ' // For almost identical logic and instructions,\n' + + ' // see comments inside `contractHash()` function in contract.tact\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + ' NEWC\n' + + ' 24 STU\n' + + ' 16 STU\n' + + ' 16 STU\n' + + ' 256 STU\n' + + ' 256 STU\n' + + ' ONE HASHEXT_SHA256 // obtains hash part (account id) of the address\n' + + ' // → Stack state\n' + + ' // s0: destAddr(hash part)\n' + + ' // s1: `init.data`\n' + + ' // s2: `init.code`\n' + + ' // s3 and below: `bounce`, `value`, `body`, `mode`\n' + + '\n' + + ' // Group 3: Building a message (CommonMsgInfoRelaxed)\n' + + ' s3 XCHG0 // swaps `bounce` with destAddr(hash part)\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' s1 s2 XCHG // swap `init.data` with `init.code`, placing code on s1\n' + + ' STREF // store `init.code`\n' + + ' STREF // store `init.data`\n' + + ' // Inline StateInit:\n' + + ' b{00010000000000} STSLICECONST\n' + + ' // 0 + 00 + 10 + 0 + 00000000\n' + + ' // 1) 0 - bounced = false\n' + + ' // 2) 00 - src = addr_none\n' + + ' // 3) 10 - tag of addr_std (part of dest)\n' + + ' // 4) 0 - Maybe Anycast = false\n' + + ' // 5) 00000000 - workchain_id (part of dest)\n' + + ' //\n' + + ' 256 STU // store destAddr(hash part)\n' + + ' SWAP // Builder on top, `value` below\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + '\n' + + ' // Group 4: Continue building a message (CommonMsgInfoRelaxed into MessageRelaxed)\n' + + ' // Remaining bits of MessageRelaxed:\n' + + ' b{1000110} STSLICECONST\n' + + ' // 10 + 0 + 0 + 1 + 1 + 0\n' + + ' // 10 - Maybe (Either StateInit ^StateInit) = true false\n' + + ' // 0 - split_depth:(Maybe (## 5)) = false\n' + + ' // 0 = special:(Maybe TickTock) = false\n' + + ' // 1 = code:(Maybe ^Cell) = true\n' + + ' // 1 = data:(Maybe ^Cell) = true\n' + + ' // 0 = library:(Maybe ^Cell) = false\n' + + ' //\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC // finalize the message\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: params.`mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 11788, end: 14770 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'cashback', + loc: { start: 15971, end: 15979 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'to', + loc: { start: 15980, end: 15982 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 15984, end: 15991 } + }, + typeArgs: [], + loc: { start: 15984, end: 15991 } + }, + loc: { start: 15980, end: 15991 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '16 PUSHINT // 0x10, i.e. 0x18 but with bounce = false\n' + + ' NEWC\n' + + ' 6 STU // .storeUint(0x10, 6)\n' + + ' STSLICE // .storeAddress(to)\n' + + ' 0 PUSHINT // 0\n' + + ' 111 STUR // .storeUint(0, 111)\n' + + ' // 4 zeros for coins and 107 zeros for lt, fees, etc.\n' + + ' ENDC\n' + + ' 66 PUSHINT // SendRemainingValue | SendIgnoreErrors\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 15963, end: 16385 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeSendMessage', + loc: { start: 16936, end: 16953 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 16954, end: 16957 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 16959, end: 16963 } + }, + loc: { start: 16959, end: 16963 } + }, + loc: { start: 16954, end: 16963 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 16965, end: 16969 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 16971, end: 16974 } + }, + loc: { start: 16971, end: 16974 } + }, + loc: { start: 16965, end: 16974 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDRAWMSG' ] + }, + loc: { start: 16928, end: 16990 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sendRawMessage', + loc: { start: 17751, end: 17765 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 17766, end: 17769 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 17771, end: 17775 } + }, + loc: { start: 17771, end: 17775 } + }, + loc: { start: 17766, end: 17775 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 17777, end: 17781 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 17783, end: 17786 } + }, + loc: { start: 17783, end: 17786 } + }, + loc: { start: 17777, end: 17786 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDRAWMSG' ] + }, + loc: { start: 17743, end: 17802 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeSendMessageReturnForwardFee', + loc: { start: 19063, end: 19096 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 19120, end: 19123 } + }, + loc: { start: 19120, end: 19123 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 19097, end: 19100 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 19102, end: 19106 } + }, + loc: { start: 19102, end: 19106 } + }, + loc: { start: 19097, end: 19106 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 19108, end: 19112 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 19114, end: 19117 } + }, + loc: { start: 19114, end: 19117 } + }, + loc: { start: 19108, end: 19117 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDMSG' ] + }, + loc: { start: 19055, end: 19135 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sendMessageReturnForwardFee', + loc: { start: 20186, end: 20213 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 20237, end: 20240 } + }, + loc: { start: 20237, end: 20240 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 20214, end: 20217 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 20219, end: 20223 } + }, + loc: { start: 20219, end: 20223 } + }, + loc: { start: 20214, end: 20223 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 20225, end: 20229 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 20231, end: 20234 } + }, + loc: { start: 20231, end: 20234 } + }, + loc: { start: 20225, end: 20234 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDMSG' ] + }, + loc: { start: 20178, end: 20252 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'emit', + loc: { start: 21033, end: 21037 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'body', + loc: { start: 21038, end: 21042 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 21044, end: 21048 } + }, + loc: { start: 21044, end: 21048 } + }, + loc: { start: 21038, end: 21048 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'c', + loc: { start: 21233, end: 21234 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 21236, end: 21240 } + }, + loc: { start: 21236, end: 21240 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'static_call', + function: { + kind: 'id', + text: 'beginCell', + loc: { start: 21243, end: 21252 } + }, + typeArgs: [], + args: [], + loc: { start: 21243, end: 21254 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 21264, end: 21273 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 15211807202738752817960438464513n, + loc: { start: 21274, end: 21306 } + }, + { + kind: 'number', + base: '10', + value: 104n, + loc: { start: 21308, end: 21311 } + } + ], + loc: { start: 21243, end: 21312 } + }, + method: { + kind: 'id', + text: 'storeRef', + loc: { start: 21322, end: 21330 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'body', + loc: { start: 21331, end: 21335 } + } + ], + loc: { start: 21243, end: 21336 } + }, + method: { + kind: 'id', + text: 'endCell', + loc: { start: 21346, end: 21353 } + }, + typeArgs: [], + args: [], + loc: { start: 21243, end: 21355 } + }, + loc: { start: 21229, end: 21356 } + }, + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'sendRawMessage', + loc: { start: 21361, end: 21375 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'c', + loc: { start: 21376, end: 21377 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 21379, end: 21380 } + } + ], + loc: { start: 21361, end: 21381 } + }, + loc: { start: 21361, end: 21382 } + } + ] + }, + loc: { start: 21022, end: 21384 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'acceptMessage', + loc: { start: 22124, end: 22137 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ACCEPT' ] + }, + loc: { start: 22116, end: 22150 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'commit', + loc: { start: 22638, end: 22644 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'COMMIT' ] + }, + loc: { start: 22630, end: 22657 } + } + ] + }, + 'SendRemainingValue' => { + kind: 'tact', + path: 'std/internal/send.tact', + code: '/// Ordinary message (default).\n' + + '///\n' + + '/// This constant is available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendDefaultMode: Int = 0;\n' + + '\n' + + '/// Carry all the remaining value of the inbound message in addition\n' + + '/// to the value initially indicated in the new message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendRemainingValue: Int = 64;\n' + + '\n' + + '/// Carry **all the remaining balance** of the current smart contract instead\n' + + '/// of the value originally indicated in the message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendRemainingBalance: Int = 128;\n' + + '\n' + + "/// Doesn't send the message, only estimates the forward fees\n" + + '/// if the message-sending function computes those.\n' + + '///\n' + + '/// This constant is available since Tact 1.5.0.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '/// * https://docs.tact-lang.org/book/send#message-sending-functions\n' + + '///\n' + + 'const SendOnlyEstimateFee: Int = 1024;\n' + + '\n' + + '/// **Deprecated** since Tact 1.6.5.\n' + + '///\n' + + '/// Pay forward fees separately from the message value.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendPayGasSeparately: Int = 1;\n' + + '\n' + + '/// Pay forward fees separately from the message value.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendPayFwdFeesSeparately: Int = 1;\n' + + '\n' + + '/// Ignore any errors arising while processing this message during the action phase.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendIgnoreErrors: Int = 2;\n' + + '\n' + + '/// Bounce transaction in case of any errors during action phase.\n' + + '/// Has no effect if flag +2, `SendIgnoreErrors` is used.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendBounceIfActionFail: Int = 16;\n' + + '\n' + + '/// Current account (contract) will be destroyed if its resulting balance is zero.\n' + + '/// This flag is often used with mode 128, `SendRemainingBalance`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendDestroyIfZero: Int = 32;\n' + + '\n' + + '/// Struct for specifying the message parameters of the `send()` function.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#send\n' + + '///\n' + + 'struct SendParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// Optional initial code of the contract (compiled bitcode).\n' + + ' code: Cell? = null;\n' + + '\n' + + ' /// Optional initial data of the contract (arguments of `init()` function or values of contract parameters).\n' + + ' data: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// Recipient internal `Address` on TON Blockchain.\n' + + ' to: Address;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '}\n' + + '\n' + + '/// Struct for specifying the message parameters of the `message()` function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#message\n' + + '///\n' + + 'struct MessageParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// Recipient internal `Address` on TON Blockchain.\n' + + ' to: Address;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Queues the message to be sent using the `MessageParameters` struct. Allows for cheaper non-deployment, regular messages compared to the `send()` function.\n' + + '///\n' + + '/// The `MessageParameters` struct is similar to `SendParameters` struct, but without the `code` and `data` fields.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// message(MessageParameters{\n' + + '/// to: sender(), // back to the sender,\n' + + '/// value: ton("1"), // with 1 Toncoin (1_000_000_000 nanoToncoin),\n' + + '/// // and no message body\n' + + '/// });\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 33: [Action list is too long] — Thrown when attempting to queue more than 255 messages.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-send#message\n' + + '/// * https://docs.tact-lang.org/book/message-mode\n' + + '///\n' + + '/// [Action list is too long]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '///\n' + + 'asm fun message(params: MessageParameters) {\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 106 PUSHINT // 1 + 4 + 4 + 64 + 32 + 1\n' + + ' STZEROES\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + ' STDICT\n' + + ' ENDC\n' + + ' SWAP\n' + + ' SENDRAWMSG\n' + + '}\n' + + '\n' + + '/// Global function. Queues the message to be sent using a `SendParameters` Struct.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// send(SendParameters{\n' + + '/// to: sender(), // back to the sender,\n' + + '/// value: ton("1"), // with 1 Toncoin (1_000_000_000 nanoToncoin),\n' + + '/// // and no message body\n' + + '/// });\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 33: [Action list is too long] — Thrown when attempting to queue more than 255 messages.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#send\n' + + '///\n' + + '/// [Action list is too long]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '///\n' + + 'asm fun send(params: SendParameters) {\n' + + ' // Instructions are grouped, and the stack states they produce as a group are shown right after.\n' + + ' // In the end, our message Cell should have the following TL-B structure:\n' + + ' // message$_ {X:Type}\n' + + ' // info:CommonMsgInfoRelaxed\n' + + ' // init:(Maybe (Either StateInit ^StateInit))\n' + + ' // body:(Either X ^X)\n' + + ' // = MessageRelaxed X;\n' + + '\n' + + ' // → Stack state\n' + + ' // s0: `params.bounce`\n' + + ' // s1: `params.to`\n' + + ' // s2: `params.value`\n' + + ' // s3: `params.data`\n' + + ' // s4: `params.code`\n' + + ' // s5: `params.body`\n' + + ' // s6: `params.mode`\n' + + ' // For brevity, the "params" prefix will be omitted from now on.\n' + + '\n' + + ' // Group 1: Storing the `bounce`, `to` and `value` into a Builder\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + '\n' + + ' // Group 2: Placing the Builder after code and data, then checking those for nullability\n' + + ' s2 XCHG0\n' + + ' DUP2\n' + + ' ISNULL\n' + + ' SWAP\n' + + ' ISNULL\n' + + ' AND\n' + + ' // → Stack state\n' + + ' // s0: -1 (true) if `data` and `code` are both null, 0 (false) otherwise\n' + + ' // s1: `code`\n' + + ' // s2: `data`\n' + + ' // s3: Builder\n' + + ' // s4: `body`\n' + + ' // s5: `mode`\n' + + '\n' + + ' // Group 3: Left branch of the IFELSE, executed if s0 is -1 (true)\n' + + ' <{\n' + + ' DROP2 // drop `data` and `code`, since either of those is null\n' + + ' b{0} STSLICECONST\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: Right branch of the IFELSE, executed if s0 is 0 (false)\n' + + ' <{\n' + + ' // _ split_depth:(Maybe (## 5))\n' + + ' // special:(Maybe TickTock)\n' + + ' // code:(Maybe ^Cell)\n' + + ' // data:(Maybe ^Cell)\n' + + ' // library:(Maybe ^Cell)\n' + + ' // = StateInit;\n' + + ' ROT // place message Builder on top\n' + + ' b{10} STSLICECONST // store Maybe = true, Either = false\n' + + ' // Start composing inlined StateInit\n' + + ' b{00} STSLICECONST // store split_depth and special first\n' + + ' STDICT // store code\n' + + ' STDICT // store data\n' + + ' b{0} STSLICECONST // store library\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: IFELSE that does the branching shown above\n' + + ' IFELSE\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: null or StateInit\n' + + ' // s2: `body`\n' + + ' // s3: `mode`\n' + + '\n' + + ' // Group 4: Finalizing the message\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: `mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG // https://github.com/tact-lang/tact/issues/1558\n' + + '}\n' + + '\n' + + '/// Struct for specifying the deployment message parameters of the `deploy()` function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#deploy\n' + + '///\n' + + 'struct DeployParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '\n' + + ' //'... 12658 more characters, + imports: [], + items: [ + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendDefaultMode', + loc: { start: 164, end: 179 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 181, end: 184 } + }, + loc: { start: 181, end: 184 } + }, + initializer: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 187, end: 188 } + } + }, + loc: { start: 158, end: 189 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendRemainingValue', + loc: { start: 396, end: 414 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 416, end: 419 } + }, + loc: { start: 416, end: 419 } + }, + initializer: { + kind: 'number', + base: '10', + value: 64n, + loc: { start: 422, end: 424 } + } + }, + loc: { start: 390, end: 425 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendRemainingBalance', + loc: { start: 638, end: 658 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 660, end: 663 } + }, + loc: { start: 660, end: 663 } + }, + initializer: { + kind: 'number', + base: '10', + value: 128n, + loc: { start: 666, end: 669 } + } + }, + loc: { start: 632, end: 670 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendOnlyEstimateFee', + loc: { start: 993, end: 1012 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1014, end: 1017 } + }, + loc: { start: 1014, end: 1017 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1024n, + loc: { start: 1020, end: 1024 } + } + }, + loc: { start: 987, end: 1025 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendPayGasSeparately', + loc: { start: 1207, end: 1227 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1229, end: 1232 } + }, + loc: { start: 1229, end: 1232 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1235, end: 1236 } + } + }, + loc: { start: 1201, end: 1237 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendPayFwdFeesSeparately', + loc: { start: 1378, end: 1402 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1404, end: 1407 } + }, + loc: { start: 1404, end: 1407 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1410, end: 1411 } + } + }, + loc: { start: 1372, end: 1412 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendIgnoreErrors', + loc: { start: 1582, end: 1598 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1600, end: 1603 } + }, + loc: { start: 1600, end: 1603 } + }, + initializer: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 1606, end: 1607 } + } + }, + loc: { start: 1576, end: 1608 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendBounceIfActionFail', + loc: { start: 1817, end: 1839 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1841, end: 1844 } + }, + loc: { start: 1841, end: 1844 } + }, + initializer: { + kind: 'number', + base: '10', + value: 16n, + loc: { start: 1847, end: 1849 } + } + }, + loc: { start: 1811, end: 1850 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendDestroyIfZero', + loc: { start: 2085, end: 2102 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2104, end: 2107 } + }, + loc: { start: 2104, end: 2107 } + }, + initializer: { + kind: 'number', + base: '10', + value: 32n, + loc: { start: 2110, end: 2112 } + } + }, + loc: { start: 2079, end: 2113 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'SendParameters', + loc: { start: 2260, end: 2274 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 2416, end: 2420 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2422, end: 2425 } + }, + loc: { start: 2422, end: 2425 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 2428, end: 2443 } + }, + loc: { start: 2416, end: 2443 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 2493, end: 2497 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2503, end: 2504 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2499, end: 2503 } + }, + loc: { start: 2499, end: 2503 } + } + ], + loc: { start: 2503, end: 2504 } + }, + initializer: { kind: 'null', loc: { start: 2507, end: 2511 } }, + loc: { start: 2493, end: 2511 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'code', + loc: { start: 2584, end: 2588 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2594, end: 2595 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2590, end: 2594 } + }, + loc: { start: 2590, end: 2594 } + } + ], + loc: { start: 2594, end: 2595 } + }, + initializer: { kind: 'null', loc: { start: 2598, end: 2602 } }, + loc: { start: 2584, end: 2602 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'data', + loc: { start: 2722, end: 2726 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2732, end: 2733 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2728, end: 2732 } + }, + loc: { start: 2728, end: 2732 } + } + ], + loc: { start: 2732, end: 2733 } + }, + initializer: { kind: 'null', loc: { start: 2736, end: 2740 } }, + loc: { start: 2722, end: 2740 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 2936, end: 2941 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2943, end: 2946 } + }, + loc: { start: 2943, end: 2946 } + }, + initializer: undefined, + loc: { start: 2936, end: 2946 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'to', + loc: { start: 3009, end: 3011 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3013, end: 3020 } + }, + typeArgs: [], + loc: { start: 3013, end: 3020 } + }, + initializer: undefined, + loc: { start: 3009, end: 3020 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 3186, end: 3192 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 3194, end: 3198 } + }, + typeArgs: [], + loc: { start: 3194, end: 3198 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 3201, end: 3205 } + }, + loc: { start: 3186, end: 3205 } + } + ], + loc: { start: 2253, end: 3208 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'MessageParameters', + loc: { start: 3389, end: 3406 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 3548, end: 3552 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3554, end: 3557 } + }, + loc: { start: 3554, end: 3557 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 3560, end: 3575 } + }, + loc: { start: 3548, end: 3575 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 3625, end: 3629 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 3635, end: 3636 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 3631, end: 3635 } + }, + loc: { start: 3631, end: 3635 } + } + ], + loc: { start: 3635, end: 3636 } + }, + initializer: { kind: 'null', loc: { start: 3639, end: 3643 } }, + loc: { start: 3625, end: 3643 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 3839, end: 3844 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3846, end: 3849 } + }, + loc: { start: 3846, end: 3849 } + }, + initializer: undefined, + loc: { start: 3839, end: 3849 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'to', + loc: { start: 3912, end: 3914 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3916, end: 3923 } + }, + typeArgs: [], + loc: { start: 3916, end: 3923 } + }, + initializer: undefined, + loc: { start: 3912, end: 3923 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 4089, end: 4095 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 4097, end: 4101 } + }, + typeArgs: [], + loc: { start: 4097, end: 4101 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 4104, end: 4108 } + }, + loc: { start: 4089, end: 4108 } + } + ], + loc: { start: 3382, end: 4111 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'message', + loc: { start: 5056, end: 5063 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 5064, end: 5070 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'MessageParameters', + loc: { start: 5072, end: 5089 } + }, + typeArgs: [], + loc: { start: 5072, end: 5089 } + }, + loc: { start: 5064, end: 5089 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 106 PUSHINT // 1 + 4 + 4 + 64 + 32 + 1\n' + + ' STZEROES\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + ' STDICT\n' + + ' ENDC\n' + + ' SWAP\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 5048, end: 5588 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'send', loc: { start: 6219, end: 6223 } }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 6224, end: 6230 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'SendParameters', + loc: { start: 6232, end: 6246 } + }, + typeArgs: [], + loc: { start: 6232, end: 6246 } + }, + loc: { start: 6224, end: 6246 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + '\n' + + ' // Group 2: Placing the Builder after code and data, then checking those for nullability\n' + + ' s2 XCHG0\n' + + ' DUP2\n' + + ' ISNULL\n' + + ' SWAP\n' + + ' ISNULL\n' + + ' AND\n' + + ' // → Stack state\n' + + ' // s0: -1 (true) if `data` and `code` are both null, 0 (false) otherwise\n' + + ' // s1: `code`\n' + + ' // s2: `data`\n' + + ' // s3: Builder\n' + + ' // s4: `body`\n' + + ' // s5: `mode`\n' + + '\n' + + ' // Group 3: Left branch of the IFELSE, executed if s0 is -1 (true)\n' + + ' <{\n' + + ' DROP2 // drop `data` and `code`, since either of those is null\n' + + ' b{0} STSLICECONST\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: Right branch of the IFELSE, executed if s0 is 0 (false)\n' + + ' <{\n' + + ' // _ split_depth:(Maybe (## 5))\n' + + ' // special:(Maybe TickTock)\n' + + ' // code:(Maybe ^Cell)\n' + + ' // data:(Maybe ^Cell)\n' + + ' // library:(Maybe ^Cell)\n' + + ' // = StateInit;\n' + + ' ROT // place message Builder on top\n' + + ' b{10} STSLICECONST // store Maybe = true, Either = false\n' + + ' // Start composing inlined StateInit\n' + + ' b{00} STSLICECONST // store split_depth and special first\n' + + ' STDICT // store code\n' + + ' STDICT // store data\n' + + ' b{0} STSLICECONST // store library\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: IFELSE that does the branching shown above\n' + + ' IFELSE\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: null or StateInit\n' + + ' // s2: `body`\n' + + ' // s3: `mode`\n' + + '\n' + + ' // Group 4: Finalizing the message\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: `mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG // https://github.com/tact-lang/tact/issues/1558' + ] + }, + loc: { start: 6211, end: 9157 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'DeployParameters', + loc: { start: 9347, end: 9363 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 9505, end: 9509 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9511, end: 9514 } + }, + loc: { start: 9511, end: 9514 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 9517, end: 9532 } + }, + loc: { start: 9505, end: 9532 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 9582, end: 9586 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 9592, end: 9593 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 9588, end: 9592 } + }, + loc: { start: 9588, end: 9592 } + } + ], + loc: { start: 9592, end: 9593 } + }, + initializer: { kind: 'null', loc: { start: 9596, end: 9600 } }, + loc: { start: 9582, end: 9600 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 9796, end: 9801 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9803, end: 9806 } + }, + loc: { start: 9803, end: 9806 } + }, + initializer: undefined, + loc: { start: 9796, end: 9806 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 9972, end: 9978 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 9980, end: 9984 } + }, + typeArgs: [], + loc: { start: 9980, end: 9984 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 9987, end: 9991 } + }, + loc: { start: 9972, end: 9991 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'init', + loc: { start: 10135, end: 10139 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 10141, end: 10150 } + }, + typeArgs: [], + loc: { start: 10141, end: 10150 } + }, + initializer: undefined, + loc: { start: 10135, end: 10150 } + } + ], + loc: { start: 9340, end: 10153 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'deploy', + loc: { start: 11796, end: 11802 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 11803, end: 11809 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'DeployParameters', + loc: { start: 11811, end: 11827 } + }, + typeArgs: [], + loc: { start: 11811, end: 11827 } + }, + loc: { start: 11803, end: 11827 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '4 1 BLKPUSH // pushes 2 copies of `init.code` and `init.data`\n' + + ' HASHCU // `init.data` hash\n' + + ' SWAP\n' + + ' HASHCU // `init.code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `init.data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `init.code` depth\n' + + '\n' + + ' // Group 2: Calculating destination address\n' + + ' // For almost identical logic and instructions,\n' + + ' // see comments inside `contractHash()` function in contract.tact\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + ' NEWC\n' + + ' 24 STU\n' + + ' 16 STU\n' + + ' 16 STU\n' + + ' 256 STU\n' + + ' 256 STU\n' + + ' ONE HASHEXT_SHA256 // obtains hash part (account id) of the address\n' + + ' // → Stack state\n' + + ' // s0: destAddr(hash part)\n' + + ' // s1: `init.data`\n' + + ' // s2: `init.code`\n' + + ' // s3 and below: `bounce`, `value`, `body`, `mode`\n' + + '\n' + + ' // Group 3: Building a message (CommonMsgInfoRelaxed)\n' + + ' s3 XCHG0 // swaps `bounce` with destAddr(hash part)\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' s1 s2 XCHG // swap `init.data` with `init.code`, placing code on s1\n' + + ' STREF // store `init.code`\n' + + ' STREF // store `init.data`\n' + + ' // Inline StateInit:\n' + + ' b{00010000000000} STSLICECONST\n' + + ' // 0 + 00 + 10 + 0 + 00000000\n' + + ' // 1) 0 - bounced = false\n' + + ' // 2) 00 - src = addr_none\n' + + ' // 3) 10 - tag of addr_std (part of dest)\n' + + ' // 4) 0 - Maybe Anycast = false\n' + + ' // 5) 00000000 - workchain_id (part of dest)\n' + + ' //\n' + + ' 256 STU // store destAddr(hash part)\n' + + ' SWAP // Builder on top, `value` below\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + '\n' + + ' // Group 4: Continue building a message (CommonMsgInfoRelaxed into MessageRelaxed)\n' + + ' // Remaining bits of MessageRelaxed:\n' + + ' b{1000110} STSLICECONST\n' + + ' // 10 + 0 + 0 + 1 + 1 + 0\n' + + ' // 10 - Maybe (Either StateInit ^StateInit) = true false\n' + + ' // 0 - split_depth:(Maybe (## 5)) = false\n' + + ' // 0 = special:(Maybe TickTock) = false\n' + + ' // 1 = code:(Maybe ^Cell) = true\n' + + ' // 1 = data:(Maybe ^Cell) = true\n' + + ' // 0 = library:(Maybe ^Cell) = false\n' + + ' //\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC // finalize the message\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: params.`mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 11788, end: 14770 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'cashback', + loc: { start: 15971, end: 15979 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'to', + loc: { start: 15980, end: 15982 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 15984, end: 15991 } + }, + typeArgs: [], + loc: { start: 15984, end: 15991 } + }, + loc: { start: 15980, end: 15991 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '16 PUSHINT // 0x10, i.e. 0x18 but with bounce = false\n' + + ' NEWC\n' + + ' 6 STU // .storeUint(0x10, 6)\n' + + ' STSLICE // .storeAddress(to)\n' + + ' 0 PUSHINT // 0\n' + + ' 111 STUR // .storeUint(0, 111)\n' + + ' // 4 zeros for coins and 107 zeros for lt, fees, etc.\n' + + ' ENDC\n' + + ' 66 PUSHINT // SendRemainingValue | SendIgnoreErrors\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 15963, end: 16385 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeSendMessage', + loc: { start: 16936, end: 16953 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 16954, end: 16957 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 16959, end: 16963 } + }, + loc: { start: 16959, end: 16963 } + }, + loc: { start: 16954, end: 16963 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 16965, end: 16969 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 16971, end: 16974 } + }, + loc: { start: 16971, end: 16974 } + }, + loc: { start: 16965, end: 16974 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDRAWMSG' ] + }, + loc: { start: 16928, end: 16990 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sendRawMessage', + loc: { start: 17751, end: 17765 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 17766, end: 17769 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 17771, end: 17775 } + }, + loc: { start: 17771, end: 17775 } + }, + loc: { start: 17766, end: 17775 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 17777, end: 17781 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 17783, end: 17786 } + }, + loc: { start: 17783, end: 17786 } + }, + loc: { start: 17777, end: 17786 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDRAWMSG' ] + }, + loc: { start: 17743, end: 17802 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeSendMessageReturnForwardFee', + loc: { start: 19063, end: 19096 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 19120, end: 19123 } + }, + loc: { start: 19120, end: 19123 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 19097, end: 19100 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 19102, end: 19106 } + }, + loc: { start: 19102, end: 19106 } + }, + loc: { start: 19097, end: 19106 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 19108, end: 19112 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 19114, end: 19117 } + }, + loc: { start: 19114, end: 19117 } + }, + loc: { start: 19108, end: 19117 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDMSG' ] + }, + loc: { start: 19055, end: 19135 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sendMessageReturnForwardFee', + loc: { start: 20186, end: 20213 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 20237, end: 20240 } + }, + loc: { start: 20237, end: 20240 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 20214, end: 20217 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 20219, end: 20223 } + }, + loc: { start: 20219, end: 20223 } + }, + loc: { start: 20214, end: 20223 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 20225, end: 20229 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 20231, end: 20234 } + }, + loc: { start: 20231, end: 20234 } + }, + loc: { start: 20225, end: 20234 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDMSG' ] + }, + loc: { start: 20178, end: 20252 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'emit', + loc: { start: 21033, end: 21037 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'body', + loc: { start: 21038, end: 21042 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 21044, end: 21048 } + }, + loc: { start: 21044, end: 21048 } + }, + loc: { start: 21038, end: 21048 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'c', + loc: { start: 21233, end: 21234 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 21236, end: 21240 } + }, + loc: { start: 21236, end: 21240 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'static_call', + function: { + kind: 'id', + text: 'beginCell', + loc: { start: 21243, end: 21252 } + }, + typeArgs: [], + args: [], + loc: { start: 21243, end: 21254 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 21264, end: 21273 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 15211807202738752817960438464513n, + loc: { start: 21274, end: 21306 } + }, + { + kind: 'number', + base: '10', + value: 104n, + loc: { start: 21308, end: 21311 } + } + ], + loc: { start: 21243, end: 21312 } + }, + method: { + kind: 'id', + text: 'storeRef', + loc: { start: 21322, end: 21330 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'body', + loc: { start: 21331, end: 21335 } + } + ], + loc: { start: 21243, end: 21336 } + }, + method: { + kind: 'id', + text: 'endCell', + loc: { start: 21346, end: 21353 } + }, + typeArgs: [], + args: [], + loc: { start: 21243, end: 21355 } + }, + loc: { start: 21229, end: 21356 } + }, + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'sendRawMessage', + loc: { start: 21361, end: 21375 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'c', + loc: { start: 21376, end: 21377 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 21379, end: 21380 } + } + ], + loc: { start: 21361, end: 21381 } + }, + loc: { start: 21361, end: 21382 } + } + ] + }, + loc: { start: 21022, end: 21384 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'acceptMessage', + loc: { start: 22124, end: 22137 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ACCEPT' ] + }, + loc: { start: 22116, end: 22150 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'commit', + loc: { start: 22638, end: 22644 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'COMMIT' ] + }, + loc: { start: 22630, end: 22657 } + } + ] + }, + 'SendRemainingBalance' => { + kind: 'tact', + path: 'std/internal/send.tact', + code: '/// Ordinary message (default).\n' + + '///\n' + + '/// This constant is available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendDefaultMode: Int = 0;\n' + + '\n' + + '/// Carry all the remaining value of the inbound message in addition\n' + + '/// to the value initially indicated in the new message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendRemainingValue: Int = 64;\n' + + '\n' + + '/// Carry **all the remaining balance** of the current smart contract instead\n' + + '/// of the value originally indicated in the message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendRemainingBalance: Int = 128;\n' + + '\n' + + "/// Doesn't send the message, only estimates the forward fees\n" + + '/// if the message-sending function computes those.\n' + + '///\n' + + '/// This constant is available since Tact 1.5.0.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '/// * https://docs.tact-lang.org/book/send#message-sending-functions\n' + + '///\n' + + 'const SendOnlyEstimateFee: Int = 1024;\n' + + '\n' + + '/// **Deprecated** since Tact 1.6.5.\n' + + '///\n' + + '/// Pay forward fees separately from the message value.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendPayGasSeparately: Int = 1;\n' + + '\n' + + '/// Pay forward fees separately from the message value.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendPayFwdFeesSeparately: Int = 1;\n' + + '\n' + + '/// Ignore any errors arising while processing this message during the action phase.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendIgnoreErrors: Int = 2;\n' + + '\n' + + '/// Bounce transaction in case of any errors during action phase.\n' + + '/// Has no effect if flag +2, `SendIgnoreErrors` is used.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendBounceIfActionFail: Int = 16;\n' + + '\n' + + '/// Current account (contract) will be destroyed if its resulting balance is zero.\n' + + '/// This flag is often used with mode 128, `SendRemainingBalance`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendDestroyIfZero: Int = 32;\n' + + '\n' + + '/// Struct for specifying the message parameters of the `send()` function.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#send\n' + + '///\n' + + 'struct SendParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// Optional initial code of the contract (compiled bitcode).\n' + + ' code: Cell? = null;\n' + + '\n' + + ' /// Optional initial data of the contract (arguments of `init()` function or values of contract parameters).\n' + + ' data: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// Recipient internal `Address` on TON Blockchain.\n' + + ' to: Address;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '}\n' + + '\n' + + '/// Struct for specifying the message parameters of the `message()` function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#message\n' + + '///\n' + + 'struct MessageParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// Recipient internal `Address` on TON Blockchain.\n' + + ' to: Address;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Queues the message to be sent using the `MessageParameters` struct. Allows for cheaper non-deployment, regular messages compared to the `send()` function.\n' + + '///\n' + + '/// The `MessageParameters` struct is similar to `SendParameters` struct, but without the `code` and `data` fields.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// message(MessageParameters{\n' + + '/// to: sender(), // back to the sender,\n' + + '/// value: ton("1"), // with 1 Toncoin (1_000_000_000 nanoToncoin),\n' + + '/// // and no message body\n' + + '/// });\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 33: [Action list is too long] — Thrown when attempting to queue more than 255 messages.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-send#message\n' + + '/// * https://docs.tact-lang.org/book/message-mode\n' + + '///\n' + + '/// [Action list is too long]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '///\n' + + 'asm fun message(params: MessageParameters) {\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 106 PUSHINT // 1 + 4 + 4 + 64 + 32 + 1\n' + + ' STZEROES\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + ' STDICT\n' + + ' ENDC\n' + + ' SWAP\n' + + ' SENDRAWMSG\n' + + '}\n' + + '\n' + + '/// Global function. Queues the message to be sent using a `SendParameters` Struct.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// send(SendParameters{\n' + + '/// to: sender(), // back to the sender,\n' + + '/// value: ton("1"), // with 1 Toncoin (1_000_000_000 nanoToncoin),\n' + + '/// // and no message body\n' + + '/// });\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 33: [Action list is too long] — Thrown when attempting to queue more than 255 messages.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#send\n' + + '///\n' + + '/// [Action list is too long]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '///\n' + + 'asm fun send(params: SendParameters) {\n' + + ' // Instructions are grouped, and the stack states they produce as a group are shown right after.\n' + + ' // In the end, our message Cell should have the following TL-B structure:\n' + + ' // message$_ {X:Type}\n' + + ' // info:CommonMsgInfoRelaxed\n' + + ' // init:(Maybe (Either StateInit ^StateInit))\n' + + ' // body:(Either X ^X)\n' + + ' // = MessageRelaxed X;\n' + + '\n' + + ' // → Stack state\n' + + ' // s0: `params.bounce`\n' + + ' // s1: `params.to`\n' + + ' // s2: `params.value`\n' + + ' // s3: `params.data`\n' + + ' // s4: `params.code`\n' + + ' // s5: `params.body`\n' + + ' // s6: `params.mode`\n' + + ' // For brevity, the "params" prefix will be omitted from now on.\n' + + '\n' + + ' // Group 1: Storing the `bounce`, `to` and `value` into a Builder\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + '\n' + + ' // Group 2: Placing the Builder after code and data, then checking those for nullability\n' + + ' s2 XCHG0\n' + + ' DUP2\n' + + ' ISNULL\n' + + ' SWAP\n' + + ' ISNULL\n' + + ' AND\n' + + ' // → Stack state\n' + + ' // s0: -1 (true) if `data` and `code` are both null, 0 (false) otherwise\n' + + ' // s1: `code`\n' + + ' // s2: `data`\n' + + ' // s3: Builder\n' + + ' // s4: `body`\n' + + ' // s5: `mode`\n' + + '\n' + + ' // Group 3: Left branch of the IFELSE, executed if s0 is -1 (true)\n' + + ' <{\n' + + ' DROP2 // drop `data` and `code`, since either of those is null\n' + + ' b{0} STSLICECONST\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: Right branch of the IFELSE, executed if s0 is 0 (false)\n' + + ' <{\n' + + ' // _ split_depth:(Maybe (## 5))\n' + + ' // special:(Maybe TickTock)\n' + + ' // code:(Maybe ^Cell)\n' + + ' // data:(Maybe ^Cell)\n' + + ' // library:(Maybe ^Cell)\n' + + ' // = StateInit;\n' + + ' ROT // place message Builder on top\n' + + ' b{10} STSLICECONST // store Maybe = true, Either = false\n' + + ' // Start composing inlined StateInit\n' + + ' b{00} STSLICECONST // store split_depth and special first\n' + + ' STDICT // store code\n' + + ' STDICT // store data\n' + + ' b{0} STSLICECONST // store library\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: IFELSE that does the branching shown above\n' + + ' IFELSE\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: null or StateInit\n' + + ' // s2: `body`\n' + + ' // s3: `mode`\n' + + '\n' + + ' // Group 4: Finalizing the message\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: `mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG // https://github.com/tact-lang/tact/issues/1558\n' + + '}\n' + + '\n' + + '/// Struct for specifying the deployment message parameters of the `deploy()` function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#deploy\n' + + '///\n' + + 'struct DeployParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '\n' + + ' //'... 12658 more characters, + imports: [], + items: [ + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendDefaultMode', + loc: { start: 164, end: 179 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 181, end: 184 } + }, + loc: { start: 181, end: 184 } + }, + initializer: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 187, end: 188 } + } + }, + loc: { start: 158, end: 189 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendRemainingValue', + loc: { start: 396, end: 414 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 416, end: 419 } + }, + loc: { start: 416, end: 419 } + }, + initializer: { + kind: 'number', + base: '10', + value: 64n, + loc: { start: 422, end: 424 } + } + }, + loc: { start: 390, end: 425 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendRemainingBalance', + loc: { start: 638, end: 658 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 660, end: 663 } + }, + loc: { start: 660, end: 663 } + }, + initializer: { + kind: 'number', + base: '10', + value: 128n, + loc: { start: 666, end: 669 } + } + }, + loc: { start: 632, end: 670 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendOnlyEstimateFee', + loc: { start: 993, end: 1012 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1014, end: 1017 } + }, + loc: { start: 1014, end: 1017 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1024n, + loc: { start: 1020, end: 1024 } + } + }, + loc: { start: 987, end: 1025 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendPayGasSeparately', + loc: { start: 1207, end: 1227 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1229, end: 1232 } + }, + loc: { start: 1229, end: 1232 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1235, end: 1236 } + } + }, + loc: { start: 1201, end: 1237 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendPayFwdFeesSeparately', + loc: { start: 1378, end: 1402 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1404, end: 1407 } + }, + loc: { start: 1404, end: 1407 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1410, end: 1411 } + } + }, + loc: { start: 1372, end: 1412 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendIgnoreErrors', + loc: { start: 1582, end: 1598 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1600, end: 1603 } + }, + loc: { start: 1600, end: 1603 } + }, + initializer: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 1606, end: 1607 } + } + }, + loc: { start: 1576, end: 1608 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendBounceIfActionFail', + loc: { start: 1817, end: 1839 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1841, end: 1844 } + }, + loc: { start: 1841, end: 1844 } + }, + initializer: { + kind: 'number', + base: '10', + value: 16n, + loc: { start: 1847, end: 1849 } + } + }, + loc: { start: 1811, end: 1850 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendDestroyIfZero', + loc: { start: 2085, end: 2102 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2104, end: 2107 } + }, + loc: { start: 2104, end: 2107 } + }, + initializer: { + kind: 'number', + base: '10', + value: 32n, + loc: { start: 2110, end: 2112 } + } + }, + loc: { start: 2079, end: 2113 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'SendParameters', + loc: { start: 2260, end: 2274 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 2416, end: 2420 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2422, end: 2425 } + }, + loc: { start: 2422, end: 2425 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 2428, end: 2443 } + }, + loc: { start: 2416, end: 2443 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 2493, end: 2497 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2503, end: 2504 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2499, end: 2503 } + }, + loc: { start: 2499, end: 2503 } + } + ], + loc: { start: 2503, end: 2504 } + }, + initializer: { kind: 'null', loc: { start: 2507, end: 2511 } }, + loc: { start: 2493, end: 2511 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'code', + loc: { start: 2584, end: 2588 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2594, end: 2595 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2590, end: 2594 } + }, + loc: { start: 2590, end: 2594 } + } + ], + loc: { start: 2594, end: 2595 } + }, + initializer: { kind: 'null', loc: { start: 2598, end: 2602 } }, + loc: { start: 2584, end: 2602 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'data', + loc: { start: 2722, end: 2726 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2732, end: 2733 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2728, end: 2732 } + }, + loc: { start: 2728, end: 2732 } + } + ], + loc: { start: 2732, end: 2733 } + }, + initializer: { kind: 'null', loc: { start: 2736, end: 2740 } }, + loc: { start: 2722, end: 2740 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 2936, end: 2941 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2943, end: 2946 } + }, + loc: { start: 2943, end: 2946 } + }, + initializer: undefined, + loc: { start: 2936, end: 2946 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'to', + loc: { start: 3009, end: 3011 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3013, end: 3020 } + }, + typeArgs: [], + loc: { start: 3013, end: 3020 } + }, + initializer: undefined, + loc: { start: 3009, end: 3020 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 3186, end: 3192 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 3194, end: 3198 } + }, + typeArgs: [], + loc: { start: 3194, end: 3198 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 3201, end: 3205 } + }, + loc: { start: 3186, end: 3205 } + } + ], + loc: { start: 2253, end: 3208 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'MessageParameters', + loc: { start: 3389, end: 3406 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 3548, end: 3552 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3554, end: 3557 } + }, + loc: { start: 3554, end: 3557 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 3560, end: 3575 } + }, + loc: { start: 3548, end: 3575 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 3625, end: 3629 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 3635, end: 3636 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 3631, end: 3635 } + }, + loc: { start: 3631, end: 3635 } + } + ], + loc: { start: 3635, end: 3636 } + }, + initializer: { kind: 'null', loc: { start: 3639, end: 3643 } }, + loc: { start: 3625, end: 3643 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 3839, end: 3844 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3846, end: 3849 } + }, + loc: { start: 3846, end: 3849 } + }, + initializer: undefined, + loc: { start: 3839, end: 3849 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'to', + loc: { start: 3912, end: 3914 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3916, end: 3923 } + }, + typeArgs: [], + loc: { start: 3916, end: 3923 } + }, + initializer: undefined, + loc: { start: 3912, end: 3923 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 4089, end: 4095 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 4097, end: 4101 } + }, + typeArgs: [], + loc: { start: 4097, end: 4101 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 4104, end: 4108 } + }, + loc: { start: 4089, end: 4108 } + } + ], + loc: { start: 3382, end: 4111 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'message', + loc: { start: 5056, end: 5063 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 5064, end: 5070 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'MessageParameters', + loc: { start: 5072, end: 5089 } + }, + typeArgs: [], + loc: { start: 5072, end: 5089 } + }, + loc: { start: 5064, end: 5089 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 106 PUSHINT // 1 + 4 + 4 + 64 + 32 + 1\n' + + ' STZEROES\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + ' STDICT\n' + + ' ENDC\n' + + ' SWAP\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 5048, end: 5588 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'send', loc: { start: 6219, end: 6223 } }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 6224, end: 6230 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'SendParameters', + loc: { start: 6232, end: 6246 } + }, + typeArgs: [], + loc: { start: 6232, end: 6246 } + }, + loc: { start: 6224, end: 6246 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + '\n' + + ' // Group 2: Placing the Builder after code and data, then checking those for nullability\n' + + ' s2 XCHG0\n' + + ' DUP2\n' + + ' ISNULL\n' + + ' SWAP\n' + + ' ISNULL\n' + + ' AND\n' + + ' // → Stack state\n' + + ' // s0: -1 (true) if `data` and `code` are both null, 0 (false) otherwise\n' + + ' // s1: `code`\n' + + ' // s2: `data`\n' + + ' // s3: Builder\n' + + ' // s4: `body`\n' + + ' // s5: `mode`\n' + + '\n' + + ' // Group 3: Left branch of the IFELSE, executed if s0 is -1 (true)\n' + + ' <{\n' + + ' DROP2 // drop `data` and `code`, since either of those is null\n' + + ' b{0} STSLICECONST\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: Right branch of the IFELSE, executed if s0 is 0 (false)\n' + + ' <{\n' + + ' // _ split_depth:(Maybe (## 5))\n' + + ' // special:(Maybe TickTock)\n' + + ' // code:(Maybe ^Cell)\n' + + ' // data:(Maybe ^Cell)\n' + + ' // library:(Maybe ^Cell)\n' + + ' // = StateInit;\n' + + ' ROT // place message Builder on top\n' + + ' b{10} STSLICECONST // store Maybe = true, Either = false\n' + + ' // Start composing inlined StateInit\n' + + ' b{00} STSLICECONST // store split_depth and special first\n' + + ' STDICT // store code\n' + + ' STDICT // store data\n' + + ' b{0} STSLICECONST // store library\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: IFELSE that does the branching shown above\n' + + ' IFELSE\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: null or StateInit\n' + + ' // s2: `body`\n' + + ' // s3: `mode`\n' + + '\n' + + ' // Group 4: Finalizing the message\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: `mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG // https://github.com/tact-lang/tact/issues/1558' + ] + }, + loc: { start: 6211, end: 9157 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'DeployParameters', + loc: { start: 9347, end: 9363 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 9505, end: 9509 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9511, end: 9514 } + }, + loc: { start: 9511, end: 9514 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 9517, end: 9532 } + }, + loc: { start: 9505, end: 9532 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 9582, end: 9586 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 9592, end: 9593 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 9588, end: 9592 } + }, + loc: { start: 9588, end: 9592 } + } + ], + loc: { start: 9592, end: 9593 } + }, + initializer: { kind: 'null', loc: { start: 9596, end: 9600 } }, + loc: { start: 9582, end: 9600 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 9796, end: 9801 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9803, end: 9806 } + }, + loc: { start: 9803, end: 9806 } + }, + initializer: undefined, + loc: { start: 9796, end: 9806 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 9972, end: 9978 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 9980, end: 9984 } + }, + typeArgs: [], + loc: { start: 9980, end: 9984 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 9987, end: 9991 } + }, + loc: { start: 9972, end: 9991 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'init', + loc: { start: 10135, end: 10139 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 10141, end: 10150 } + }, + typeArgs: [], + loc: { start: 10141, end: 10150 } + }, + initializer: undefined, + loc: { start: 10135, end: 10150 } + } + ], + loc: { start: 9340, end: 10153 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'deploy', + loc: { start: 11796, end: 11802 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 11803, end: 11809 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'DeployParameters', + loc: { start: 11811, end: 11827 } + }, + typeArgs: [], + loc: { start: 11811, end: 11827 } + }, + loc: { start: 11803, end: 11827 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '4 1 BLKPUSH // pushes 2 copies of `init.code` and `init.data`\n' + + ' HASHCU // `init.data` hash\n' + + ' SWAP\n' + + ' HASHCU // `init.code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `init.data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `init.code` depth\n' + + '\n' + + ' // Group 2: Calculating destination address\n' + + ' // For almost identical logic and instructions,\n' + + ' // see comments inside `contractHash()` function in contract.tact\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + ' NEWC\n' + + ' 24 STU\n' + + ' 16 STU\n' + + ' 16 STU\n' + + ' 256 STU\n' + + ' 256 STU\n' + + ' ONE HASHEXT_SHA256 // obtains hash part (account id) of the address\n' + + ' // → Stack state\n' + + ' // s0: destAddr(hash part)\n' + + ' // s1: `init.data`\n' + + ' // s2: `init.code`\n' + + ' // s3 and below: `bounce`, `value`, `body`, `mode`\n' + + '\n' + + ' // Group 3: Building a message (CommonMsgInfoRelaxed)\n' + + ' s3 XCHG0 // swaps `bounce` with destAddr(hash part)\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' s1 s2 XCHG // swap `init.data` with `init.code`, placing code on s1\n' + + ' STREF // store `init.code`\n' + + ' STREF // store `init.data`\n' + + ' // Inline StateInit:\n' + + ' b{00010000000000} STSLICECONST\n' + + ' // 0 + 00 + 10 + 0 + 00000000\n' + + ' // 1) 0 - bounced = false\n' + + ' // 2) 00 - src = addr_none\n' + + ' // 3) 10 - tag of addr_std (part of dest)\n' + + ' // 4) 0 - Maybe Anycast = false\n' + + ' // 5) 00000000 - workchain_id (part of dest)\n' + + ' //\n' + + ' 256 STU // store destAddr(hash part)\n' + + ' SWAP // Builder on top, `value` below\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + '\n' + + ' // Group 4: Continue building a message (CommonMsgInfoRelaxed into MessageRelaxed)\n' + + ' // Remaining bits of MessageRelaxed:\n' + + ' b{1000110} STSLICECONST\n' + + ' // 10 + 0 + 0 + 1 + 1 + 0\n' + + ' // 10 - Maybe (Either StateInit ^StateInit) = true false\n' + + ' // 0 - split_depth:(Maybe (## 5)) = false\n' + + ' // 0 = special:(Maybe TickTock) = false\n' + + ' // 1 = code:(Maybe ^Cell) = true\n' + + ' // 1 = data:(Maybe ^Cell) = true\n' + + ' // 0 = library:(Maybe ^Cell) = false\n' + + ' //\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC // finalize the message\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: params.`mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 11788, end: 14770 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'cashback', + loc: { start: 15971, end: 15979 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'to', + loc: { start: 15980, end: 15982 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 15984, end: 15991 } + }, + typeArgs: [], + loc: { start: 15984, end: 15991 } + }, + loc: { start: 15980, end: 15991 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '16 PUSHINT // 0x10, i.e. 0x18 but with bounce = false\n' + + ' NEWC\n' + + ' 6 STU // .storeUint(0x10, 6)\n' + + ' STSLICE // .storeAddress(to)\n' + + ' 0 PUSHINT // 0\n' + + ' 111 STUR // .storeUint(0, 111)\n' + + ' // 4 zeros for coins and 107 zeros for lt, fees, etc.\n' + + ' ENDC\n' + + ' 66 PUSHINT // SendRemainingValue | SendIgnoreErrors\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 15963, end: 16385 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeSendMessage', + loc: { start: 16936, end: 16953 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 16954, end: 16957 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 16959, end: 16963 } + }, + loc: { start: 16959, end: 16963 } + }, + loc: { start: 16954, end: 16963 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 16965, end: 16969 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 16971, end: 16974 } + }, + loc: { start: 16971, end: 16974 } + }, + loc: { start: 16965, end: 16974 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDRAWMSG' ] + }, + loc: { start: 16928, end: 16990 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sendRawMessage', + loc: { start: 17751, end: 17765 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 17766, end: 17769 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 17771, end: 17775 } + }, + loc: { start: 17771, end: 17775 } + }, + loc: { start: 17766, end: 17775 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 17777, end: 17781 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 17783, end: 17786 } + }, + loc: { start: 17783, end: 17786 } + }, + loc: { start: 17777, end: 17786 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDRAWMSG' ] + }, + loc: { start: 17743, end: 17802 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeSendMessageReturnForwardFee', + loc: { start: 19063, end: 19096 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 19120, end: 19123 } + }, + loc: { start: 19120, end: 19123 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 19097, end: 19100 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 19102, end: 19106 } + }, + loc: { start: 19102, end: 19106 } + }, + loc: { start: 19097, end: 19106 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 19108, end: 19112 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 19114, end: 19117 } + }, + loc: { start: 19114, end: 19117 } + }, + loc: { start: 19108, end: 19117 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDMSG' ] + }, + loc: { start: 19055, end: 19135 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sendMessageReturnForwardFee', + loc: { start: 20186, end: 20213 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 20237, end: 20240 } + }, + loc: { start: 20237, end: 20240 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 20214, end: 20217 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 20219, end: 20223 } + }, + loc: { start: 20219, end: 20223 } + }, + loc: { start: 20214, end: 20223 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 20225, end: 20229 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 20231, end: 20234 } + }, + loc: { start: 20231, end: 20234 } + }, + loc: { start: 20225, end: 20234 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDMSG' ] + }, + loc: { start: 20178, end: 20252 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'emit', + loc: { start: 21033, end: 21037 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'body', + loc: { start: 21038, end: 21042 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 21044, end: 21048 } + }, + loc: { start: 21044, end: 21048 } + }, + loc: { start: 21038, end: 21048 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'c', + loc: { start: 21233, end: 21234 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 21236, end: 21240 } + }, + loc: { start: 21236, end: 21240 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'static_call', + function: { + kind: 'id', + text: 'beginCell', + loc: { start: 21243, end: 21252 } + }, + typeArgs: [], + args: [], + loc: { start: 21243, end: 21254 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 21264, end: 21273 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 15211807202738752817960438464513n, + loc: { start: 21274, end: 21306 } + }, + { + kind: 'number', + base: '10', + value: 104n, + loc: { start: 21308, end: 21311 } + } + ], + loc: { start: 21243, end: 21312 } + }, + method: { + kind: 'id', + text: 'storeRef', + loc: { start: 21322, end: 21330 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'body', + loc: { start: 21331, end: 21335 } + } + ], + loc: { start: 21243, end: 21336 } + }, + method: { + kind: 'id', + text: 'endCell', + loc: { start: 21346, end: 21353 } + }, + typeArgs: [], + args: [], + loc: { start: 21243, end: 21355 } + }, + loc: { start: 21229, end: 21356 } + }, + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'sendRawMessage', + loc: { start: 21361, end: 21375 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'c', + loc: { start: 21376, end: 21377 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 21379, end: 21380 } + } + ], + loc: { start: 21361, end: 21381 } + }, + loc: { start: 21361, end: 21382 } + } + ] + }, + loc: { start: 21022, end: 21384 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'acceptMessage', + loc: { start: 22124, end: 22137 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ACCEPT' ] + }, + loc: { start: 22116, end: 22150 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'commit', + loc: { start: 22638, end: 22644 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'COMMIT' ] + }, + loc: { start: 22630, end: 22657 } + } + ] + }, + 'SendOnlyEstimateFee' => { + kind: 'tact', + path: 'std/internal/send.tact', + code: '/// Ordinary message (default).\n' + + '///\n' + + '/// This constant is available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendDefaultMode: Int = 0;\n' + + '\n' + + '/// Carry all the remaining value of the inbound message in addition\n' + + '/// to the value initially indicated in the new message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendRemainingValue: Int = 64;\n' + + '\n' + + '/// Carry **all the remaining balance** of the current smart contract instead\n' + + '/// of the value originally indicated in the message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendRemainingBalance: Int = 128;\n' + + '\n' + + "/// Doesn't send the message, only estimates the forward fees\n" + + '/// if the message-sending function computes those.\n' + + '///\n' + + '/// This constant is available since Tact 1.5.0.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '/// * https://docs.tact-lang.org/book/send#message-sending-functions\n' + + '///\n' + + 'const SendOnlyEstimateFee: Int = 1024;\n' + + '\n' + + '/// **Deprecated** since Tact 1.6.5.\n' + + '///\n' + + '/// Pay forward fees separately from the message value.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendPayGasSeparately: Int = 1;\n' + + '\n' + + '/// Pay forward fees separately from the message value.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendPayFwdFeesSeparately: Int = 1;\n' + + '\n' + + '/// Ignore any errors arising while processing this message during the action phase.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendIgnoreErrors: Int = 2;\n' + + '\n' + + '/// Bounce transaction in case of any errors during action phase.\n' + + '/// Has no effect if flag +2, `SendIgnoreErrors` is used.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendBounceIfActionFail: Int = 16;\n' + + '\n' + + '/// Current account (contract) will be destroyed if its resulting balance is zero.\n' + + '/// This flag is often used with mode 128, `SendRemainingBalance`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendDestroyIfZero: Int = 32;\n' + + '\n' + + '/// Struct for specifying the message parameters of the `send()` function.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#send\n' + + '///\n' + + 'struct SendParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// Optional initial code of the contract (compiled bitcode).\n' + + ' code: Cell? = null;\n' + + '\n' + + ' /// Optional initial data of the contract (arguments of `init()` function or values of contract parameters).\n' + + ' data: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// Recipient internal `Address` on TON Blockchain.\n' + + ' to: Address;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '}\n' + + '\n' + + '/// Struct for specifying the message parameters of the `message()` function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#message\n' + + '///\n' + + 'struct MessageParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// Recipient internal `Address` on TON Blockchain.\n' + + ' to: Address;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Queues the message to be sent using the `MessageParameters` struct. Allows for cheaper non-deployment, regular messages compared to the `send()` function.\n' + + '///\n' + + '/// The `MessageParameters` struct is similar to `SendParameters` struct, but without the `code` and `data` fields.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// message(MessageParameters{\n' + + '/// to: sender(), // back to the sender,\n' + + '/// value: ton("1"), // with 1 Toncoin (1_000_000_000 nanoToncoin),\n' + + '/// // and no message body\n' + + '/// });\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 33: [Action list is too long] — Thrown when attempting to queue more than 255 messages.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-send#message\n' + + '/// * https://docs.tact-lang.org/book/message-mode\n' + + '///\n' + + '/// [Action list is too long]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '///\n' + + 'asm fun message(params: MessageParameters) {\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 106 PUSHINT // 1 + 4 + 4 + 64 + 32 + 1\n' + + ' STZEROES\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + ' STDICT\n' + + ' ENDC\n' + + ' SWAP\n' + + ' SENDRAWMSG\n' + + '}\n' + + '\n' + + '/// Global function. Queues the message to be sent using a `SendParameters` Struct.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// send(SendParameters{\n' + + '/// to: sender(), // back to the sender,\n' + + '/// value: ton("1"), // with 1 Toncoin (1_000_000_000 nanoToncoin),\n' + + '/// // and no message body\n' + + '/// });\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 33: [Action list is too long] — Thrown when attempting to queue more than 255 messages.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#send\n' + + '///\n' + + '/// [Action list is too long]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '///\n' + + 'asm fun send(params: SendParameters) {\n' + + ' // Instructions are grouped, and the stack states they produce as a group are shown right after.\n' + + ' // In the end, our message Cell should have the following TL-B structure:\n' + + ' // message$_ {X:Type}\n' + + ' // info:CommonMsgInfoRelaxed\n' + + ' // init:(Maybe (Either StateInit ^StateInit))\n' + + ' // body:(Either X ^X)\n' + + ' // = MessageRelaxed X;\n' + + '\n' + + ' // → Stack state\n' + + ' // s0: `params.bounce`\n' + + ' // s1: `params.to`\n' + + ' // s2: `params.value`\n' + + ' // s3: `params.data`\n' + + ' // s4: `params.code`\n' + + ' // s5: `params.body`\n' + + ' // s6: `params.mode`\n' + + ' // For brevity, the "params" prefix will be omitted from now on.\n' + + '\n' + + ' // Group 1: Storing the `bounce`, `to` and `value` into a Builder\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + '\n' + + ' // Group 2: Placing the Builder after code and data, then checking those for nullability\n' + + ' s2 XCHG0\n' + + ' DUP2\n' + + ' ISNULL\n' + + ' SWAP\n' + + ' ISNULL\n' + + ' AND\n' + + ' // → Stack state\n' + + ' // s0: -1 (true) if `data` and `code` are both null, 0 (false) otherwise\n' + + ' // s1: `code`\n' + + ' // s2: `data`\n' + + ' // s3: Builder\n' + + ' // s4: `body`\n' + + ' // s5: `mode`\n' + + '\n' + + ' // Group 3: Left branch of the IFELSE, executed if s0 is -1 (true)\n' + + ' <{\n' + + ' DROP2 // drop `data` and `code`, since either of those is null\n' + + ' b{0} STSLICECONST\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: Right branch of the IFELSE, executed if s0 is 0 (false)\n' + + ' <{\n' + + ' // _ split_depth:(Maybe (## 5))\n' + + ' // special:(Maybe TickTock)\n' + + ' // code:(Maybe ^Cell)\n' + + ' // data:(Maybe ^Cell)\n' + + ' // library:(Maybe ^Cell)\n' + + ' // = StateInit;\n' + + ' ROT // place message Builder on top\n' + + ' b{10} STSLICECONST // store Maybe = true, Either = false\n' + + ' // Start composing inlined StateInit\n' + + ' b{00} STSLICECONST // store split_depth and special first\n' + + ' STDICT // store code\n' + + ' STDICT // store data\n' + + ' b{0} STSLICECONST // store library\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: IFELSE that does the branching shown above\n' + + ' IFELSE\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: null or StateInit\n' + + ' // s2: `body`\n' + + ' // s3: `mode`\n' + + '\n' + + ' // Group 4: Finalizing the message\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: `mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG // https://github.com/tact-lang/tact/issues/1558\n' + + '}\n' + + '\n' + + '/// Struct for specifying the deployment message parameters of the `deploy()` function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#deploy\n' + + '///\n' + + 'struct DeployParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '\n' + + ' //'... 12658 more characters, + imports: [], + items: [ + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendDefaultMode', + loc: { start: 164, end: 179 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 181, end: 184 } + }, + loc: { start: 181, end: 184 } + }, + initializer: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 187, end: 188 } + } + }, + loc: { start: 158, end: 189 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendRemainingValue', + loc: { start: 396, end: 414 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 416, end: 419 } + }, + loc: { start: 416, end: 419 } + }, + initializer: { + kind: 'number', + base: '10', + value: 64n, + loc: { start: 422, end: 424 } + } + }, + loc: { start: 390, end: 425 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendRemainingBalance', + loc: { start: 638, end: 658 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 660, end: 663 } + }, + loc: { start: 660, end: 663 } + }, + initializer: { + kind: 'number', + base: '10', + value: 128n, + loc: { start: 666, end: 669 } + } + }, + loc: { start: 632, end: 670 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendOnlyEstimateFee', + loc: { start: 993, end: 1012 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1014, end: 1017 } + }, + loc: { start: 1014, end: 1017 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1024n, + loc: { start: 1020, end: 1024 } + } + }, + loc: { start: 987, end: 1025 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendPayGasSeparately', + loc: { start: 1207, end: 1227 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1229, end: 1232 } + }, + loc: { start: 1229, end: 1232 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1235, end: 1236 } + } + }, + loc: { start: 1201, end: 1237 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendPayFwdFeesSeparately', + loc: { start: 1378, end: 1402 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1404, end: 1407 } + }, + loc: { start: 1404, end: 1407 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1410, end: 1411 } + } + }, + loc: { start: 1372, end: 1412 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendIgnoreErrors', + loc: { start: 1582, end: 1598 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1600, end: 1603 } + }, + loc: { start: 1600, end: 1603 } + }, + initializer: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 1606, end: 1607 } + } + }, + loc: { start: 1576, end: 1608 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendBounceIfActionFail', + loc: { start: 1817, end: 1839 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1841, end: 1844 } + }, + loc: { start: 1841, end: 1844 } + }, + initializer: { + kind: 'number', + base: '10', + value: 16n, + loc: { start: 1847, end: 1849 } + } + }, + loc: { start: 1811, end: 1850 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendDestroyIfZero', + loc: { start: 2085, end: 2102 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2104, end: 2107 } + }, + loc: { start: 2104, end: 2107 } + }, + initializer: { + kind: 'number', + base: '10', + value: 32n, + loc: { start: 2110, end: 2112 } + } + }, + loc: { start: 2079, end: 2113 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'SendParameters', + loc: { start: 2260, end: 2274 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 2416, end: 2420 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2422, end: 2425 } + }, + loc: { start: 2422, end: 2425 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 2428, end: 2443 } + }, + loc: { start: 2416, end: 2443 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 2493, end: 2497 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2503, end: 2504 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2499, end: 2503 } + }, + loc: { start: 2499, end: 2503 } + } + ], + loc: { start: 2503, end: 2504 } + }, + initializer: { kind: 'null', loc: { start: 2507, end: 2511 } }, + loc: { start: 2493, end: 2511 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'code', + loc: { start: 2584, end: 2588 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2594, end: 2595 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2590, end: 2594 } + }, + loc: { start: 2590, end: 2594 } + } + ], + loc: { start: 2594, end: 2595 } + }, + initializer: { kind: 'null', loc: { start: 2598, end: 2602 } }, + loc: { start: 2584, end: 2602 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'data', + loc: { start: 2722, end: 2726 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2732, end: 2733 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2728, end: 2732 } + }, + loc: { start: 2728, end: 2732 } + } + ], + loc: { start: 2732, end: 2733 } + }, + initializer: { kind: 'null', loc: { start: 2736, end: 2740 } }, + loc: { start: 2722, end: 2740 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 2936, end: 2941 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2943, end: 2946 } + }, + loc: { start: 2943, end: 2946 } + }, + initializer: undefined, + loc: { start: 2936, end: 2946 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'to', + loc: { start: 3009, end: 3011 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3013, end: 3020 } + }, + typeArgs: [], + loc: { start: 3013, end: 3020 } + }, + initializer: undefined, + loc: { start: 3009, end: 3020 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 3186, end: 3192 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 3194, end: 3198 } + }, + typeArgs: [], + loc: { start: 3194, end: 3198 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 3201, end: 3205 } + }, + loc: { start: 3186, end: 3205 } + } + ], + loc: { start: 2253, end: 3208 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'MessageParameters', + loc: { start: 3389, end: 3406 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 3548, end: 3552 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3554, end: 3557 } + }, + loc: { start: 3554, end: 3557 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 3560, end: 3575 } + }, + loc: { start: 3548, end: 3575 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 3625, end: 3629 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 3635, end: 3636 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 3631, end: 3635 } + }, + loc: { start: 3631, end: 3635 } + } + ], + loc: { start: 3635, end: 3636 } + }, + initializer: { kind: 'null', loc: { start: 3639, end: 3643 } }, + loc: { start: 3625, end: 3643 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 3839, end: 3844 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3846, end: 3849 } + }, + loc: { start: 3846, end: 3849 } + }, + initializer: undefined, + loc: { start: 3839, end: 3849 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'to', + loc: { start: 3912, end: 3914 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3916, end: 3923 } + }, + typeArgs: [], + loc: { start: 3916, end: 3923 } + }, + initializer: undefined, + loc: { start: 3912, end: 3923 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 4089, end: 4095 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 4097, end: 4101 } + }, + typeArgs: [], + loc: { start: 4097, end: 4101 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 4104, end: 4108 } + }, + loc: { start: 4089, end: 4108 } + } + ], + loc: { start: 3382, end: 4111 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'message', + loc: { start: 5056, end: 5063 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 5064, end: 5070 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'MessageParameters', + loc: { start: 5072, end: 5089 } + }, + typeArgs: [], + loc: { start: 5072, end: 5089 } + }, + loc: { start: 5064, end: 5089 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 106 PUSHINT // 1 + 4 + 4 + 64 + 32 + 1\n' + + ' STZEROES\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + ' STDICT\n' + + ' ENDC\n' + + ' SWAP\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 5048, end: 5588 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'send', loc: { start: 6219, end: 6223 } }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 6224, end: 6230 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'SendParameters', + loc: { start: 6232, end: 6246 } + }, + typeArgs: [], + loc: { start: 6232, end: 6246 } + }, + loc: { start: 6224, end: 6246 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + '\n' + + ' // Group 2: Placing the Builder after code and data, then checking those for nullability\n' + + ' s2 XCHG0\n' + + ' DUP2\n' + + ' ISNULL\n' + + ' SWAP\n' + + ' ISNULL\n' + + ' AND\n' + + ' // → Stack state\n' + + ' // s0: -1 (true) if `data` and `code` are both null, 0 (false) otherwise\n' + + ' // s1: `code`\n' + + ' // s2: `data`\n' + + ' // s3: Builder\n' + + ' // s4: `body`\n' + + ' // s5: `mode`\n' + + '\n' + + ' // Group 3: Left branch of the IFELSE, executed if s0 is -1 (true)\n' + + ' <{\n' + + ' DROP2 // drop `data` and `code`, since either of those is null\n' + + ' b{0} STSLICECONST\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: Right branch of the IFELSE, executed if s0 is 0 (false)\n' + + ' <{\n' + + ' // _ split_depth:(Maybe (## 5))\n' + + ' // special:(Maybe TickTock)\n' + + ' // code:(Maybe ^Cell)\n' + + ' // data:(Maybe ^Cell)\n' + + ' // library:(Maybe ^Cell)\n' + + ' // = StateInit;\n' + + ' ROT // place message Builder on top\n' + + ' b{10} STSLICECONST // store Maybe = true, Either = false\n' + + ' // Start composing inlined StateInit\n' + + ' b{00} STSLICECONST // store split_depth and special first\n' + + ' STDICT // store code\n' + + ' STDICT // store data\n' + + ' b{0} STSLICECONST // store library\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: IFELSE that does the branching shown above\n' + + ' IFELSE\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: null or StateInit\n' + + ' // s2: `body`\n' + + ' // s3: `mode`\n' + + '\n' + + ' // Group 4: Finalizing the message\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: `mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG // https://github.com/tact-lang/tact/issues/1558' + ] + }, + loc: { start: 6211, end: 9157 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'DeployParameters', + loc: { start: 9347, end: 9363 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 9505, end: 9509 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9511, end: 9514 } + }, + loc: { start: 9511, end: 9514 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 9517, end: 9532 } + }, + loc: { start: 9505, end: 9532 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 9582, end: 9586 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 9592, end: 9593 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 9588, end: 9592 } + }, + loc: { start: 9588, end: 9592 } + } + ], + loc: { start: 9592, end: 9593 } + }, + initializer: { kind: 'null', loc: { start: 9596, end: 9600 } }, + loc: { start: 9582, end: 9600 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 9796, end: 9801 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9803, end: 9806 } + }, + loc: { start: 9803, end: 9806 } + }, + initializer: undefined, + loc: { start: 9796, end: 9806 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 9972, end: 9978 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 9980, end: 9984 } + }, + typeArgs: [], + loc: { start: 9980, end: 9984 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 9987, end: 9991 } + }, + loc: { start: 9972, end: 9991 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'init', + loc: { start: 10135, end: 10139 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 10141, end: 10150 } + }, + typeArgs: [], + loc: { start: 10141, end: 10150 } + }, + initializer: undefined, + loc: { start: 10135, end: 10150 } + } + ], + loc: { start: 9340, end: 10153 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'deploy', + loc: { start: 11796, end: 11802 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 11803, end: 11809 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'DeployParameters', + loc: { start: 11811, end: 11827 } + }, + typeArgs: [], + loc: { start: 11811, end: 11827 } + }, + loc: { start: 11803, end: 11827 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '4 1 BLKPUSH // pushes 2 copies of `init.code` and `init.data`\n' + + ' HASHCU // `init.data` hash\n' + + ' SWAP\n' + + ' HASHCU // `init.code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `init.data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `init.code` depth\n' + + '\n' + + ' // Group 2: Calculating destination address\n' + + ' // For almost identical logic and instructions,\n' + + ' // see comments inside `contractHash()` function in contract.tact\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + ' NEWC\n' + + ' 24 STU\n' + + ' 16 STU\n' + + ' 16 STU\n' + + ' 256 STU\n' + + ' 256 STU\n' + + ' ONE HASHEXT_SHA256 // obtains hash part (account id) of the address\n' + + ' // → Stack state\n' + + ' // s0: destAddr(hash part)\n' + + ' // s1: `init.data`\n' + + ' // s2: `init.code`\n' + + ' // s3 and below: `bounce`, `value`, `body`, `mode`\n' + + '\n' + + ' // Group 3: Building a message (CommonMsgInfoRelaxed)\n' + + ' s3 XCHG0 // swaps `bounce` with destAddr(hash part)\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' s1 s2 XCHG // swap `init.data` with `init.code`, placing code on s1\n' + + ' STREF // store `init.code`\n' + + ' STREF // store `init.data`\n' + + ' // Inline StateInit:\n' + + ' b{00010000000000} STSLICECONST\n' + + ' // 0 + 00 + 10 + 0 + 00000000\n' + + ' // 1) 0 - bounced = false\n' + + ' // 2) 00 - src = addr_none\n' + + ' // 3) 10 - tag of addr_std (part of dest)\n' + + ' // 4) 0 - Maybe Anycast = false\n' + + ' // 5) 00000000 - workchain_id (part of dest)\n' + + ' //\n' + + ' 256 STU // store destAddr(hash part)\n' + + ' SWAP // Builder on top, `value` below\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + '\n' + + ' // Group 4: Continue building a message (CommonMsgInfoRelaxed into MessageRelaxed)\n' + + ' // Remaining bits of MessageRelaxed:\n' + + ' b{1000110} STSLICECONST\n' + + ' // 10 + 0 + 0 + 1 + 1 + 0\n' + + ' // 10 - Maybe (Either StateInit ^StateInit) = true false\n' + + ' // 0 - split_depth:(Maybe (## 5)) = false\n' + + ' // 0 = special:(Maybe TickTock) = false\n' + + ' // 1 = code:(Maybe ^Cell) = true\n' + + ' // 1 = data:(Maybe ^Cell) = true\n' + + ' // 0 = library:(Maybe ^Cell) = false\n' + + ' //\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC // finalize the message\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: params.`mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 11788, end: 14770 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'cashback', + loc: { start: 15971, end: 15979 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'to', + loc: { start: 15980, end: 15982 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 15984, end: 15991 } + }, + typeArgs: [], + loc: { start: 15984, end: 15991 } + }, + loc: { start: 15980, end: 15991 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '16 PUSHINT // 0x10, i.e. 0x18 but with bounce = false\n' + + ' NEWC\n' + + ' 6 STU // .storeUint(0x10, 6)\n' + + ' STSLICE // .storeAddress(to)\n' + + ' 0 PUSHINT // 0\n' + + ' 111 STUR // .storeUint(0, 111)\n' + + ' // 4 zeros for coins and 107 zeros for lt, fees, etc.\n' + + ' ENDC\n' + + ' 66 PUSHINT // SendRemainingValue | SendIgnoreErrors\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 15963, end: 16385 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeSendMessage', + loc: { start: 16936, end: 16953 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 16954, end: 16957 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 16959, end: 16963 } + }, + loc: { start: 16959, end: 16963 } + }, + loc: { start: 16954, end: 16963 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 16965, end: 16969 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 16971, end: 16974 } + }, + loc: { start: 16971, end: 16974 } + }, + loc: { start: 16965, end: 16974 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDRAWMSG' ] + }, + loc: { start: 16928, end: 16990 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sendRawMessage', + loc: { start: 17751, end: 17765 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 17766, end: 17769 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 17771, end: 17775 } + }, + loc: { start: 17771, end: 17775 } + }, + loc: { start: 17766, end: 17775 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 17777, end: 17781 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 17783, end: 17786 } + }, + loc: { start: 17783, end: 17786 } + }, + loc: { start: 17777, end: 17786 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDRAWMSG' ] + }, + loc: { start: 17743, end: 17802 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeSendMessageReturnForwardFee', + loc: { start: 19063, end: 19096 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 19120, end: 19123 } + }, + loc: { start: 19120, end: 19123 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 19097, end: 19100 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 19102, end: 19106 } + }, + loc: { start: 19102, end: 19106 } + }, + loc: { start: 19097, end: 19106 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 19108, end: 19112 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 19114, end: 19117 } + }, + loc: { start: 19114, end: 19117 } + }, + loc: { start: 19108, end: 19117 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDMSG' ] + }, + loc: { start: 19055, end: 19135 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sendMessageReturnForwardFee', + loc: { start: 20186, end: 20213 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 20237, end: 20240 } + }, + loc: { start: 20237, end: 20240 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 20214, end: 20217 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 20219, end: 20223 } + }, + loc: { start: 20219, end: 20223 } + }, + loc: { start: 20214, end: 20223 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 20225, end: 20229 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 20231, end: 20234 } + }, + loc: { start: 20231, end: 20234 } + }, + loc: { start: 20225, end: 20234 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDMSG' ] + }, + loc: { start: 20178, end: 20252 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'emit', + loc: { start: 21033, end: 21037 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'body', + loc: { start: 21038, end: 21042 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 21044, end: 21048 } + }, + loc: { start: 21044, end: 21048 } + }, + loc: { start: 21038, end: 21048 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'c', + loc: { start: 21233, end: 21234 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 21236, end: 21240 } + }, + loc: { start: 21236, end: 21240 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'static_call', + function: { + kind: 'id', + text: 'beginCell', + loc: { start: 21243, end: 21252 } + }, + typeArgs: [], + args: [], + loc: { start: 21243, end: 21254 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 21264, end: 21273 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 15211807202738752817960438464513n, + loc: { start: 21274, end: 21306 } + }, + { + kind: 'number', + base: '10', + value: 104n, + loc: { start: 21308, end: 21311 } + } + ], + loc: { start: 21243, end: 21312 } + }, + method: { + kind: 'id', + text: 'storeRef', + loc: { start: 21322, end: 21330 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'body', + loc: { start: 21331, end: 21335 } + } + ], + loc: { start: 21243, end: 21336 } + }, + method: { + kind: 'id', + text: 'endCell', + loc: { start: 21346, end: 21353 } + }, + typeArgs: [], + args: [], + loc: { start: 21243, end: 21355 } + }, + loc: { start: 21229, end: 21356 } + }, + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'sendRawMessage', + loc: { start: 21361, end: 21375 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'c', + loc: { start: 21376, end: 21377 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 21379, end: 21380 } + } + ], + loc: { start: 21361, end: 21381 } + }, + loc: { start: 21361, end: 21382 } + } + ] + }, + loc: { start: 21022, end: 21384 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'acceptMessage', + loc: { start: 22124, end: 22137 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ACCEPT' ] + }, + loc: { start: 22116, end: 22150 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'commit', + loc: { start: 22638, end: 22644 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'COMMIT' ] + }, + loc: { start: 22630, end: 22657 } + } + ] + }, + 'SendPayGasSeparately' => { + kind: 'tact', + path: 'std/internal/send.tact', + code: '/// Ordinary message (default).\n' + + '///\n' + + '/// This constant is available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendDefaultMode: Int = 0;\n' + + '\n' + + '/// Carry all the remaining value of the inbound message in addition\n' + + '/// to the value initially indicated in the new message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendRemainingValue: Int = 64;\n' + + '\n' + + '/// Carry **all the remaining balance** of the current smart contract instead\n' + + '/// of the value originally indicated in the message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendRemainingBalance: Int = 128;\n' + + '\n' + + "/// Doesn't send the message, only estimates the forward fees\n" + + '/// if the message-sending function computes those.\n' + + '///\n' + + '/// This constant is available since Tact 1.5.0.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '/// * https://docs.tact-lang.org/book/send#message-sending-functions\n' + + '///\n' + + 'const SendOnlyEstimateFee: Int = 1024;\n' + + '\n' + + '/// **Deprecated** since Tact 1.6.5.\n' + + '///\n' + + '/// Pay forward fees separately from the message value.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendPayGasSeparately: Int = 1;\n' + + '\n' + + '/// Pay forward fees separately from the message value.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendPayFwdFeesSeparately: Int = 1;\n' + + '\n' + + '/// Ignore any errors arising while processing this message during the action phase.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendIgnoreErrors: Int = 2;\n' + + '\n' + + '/// Bounce transaction in case of any errors during action phase.\n' + + '/// Has no effect if flag +2, `SendIgnoreErrors` is used.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendBounceIfActionFail: Int = 16;\n' + + '\n' + + '/// Current account (contract) will be destroyed if its resulting balance is zero.\n' + + '/// This flag is often used with mode 128, `SendRemainingBalance`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendDestroyIfZero: Int = 32;\n' + + '\n' + + '/// Struct for specifying the message parameters of the `send()` function.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#send\n' + + '///\n' + + 'struct SendParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// Optional initial code of the contract (compiled bitcode).\n' + + ' code: Cell? = null;\n' + + '\n' + + ' /// Optional initial data of the contract (arguments of `init()` function or values of contract parameters).\n' + + ' data: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// Recipient internal `Address` on TON Blockchain.\n' + + ' to: Address;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '}\n' + + '\n' + + '/// Struct for specifying the message parameters of the `message()` function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#message\n' + + '///\n' + + 'struct MessageParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// Recipient internal `Address` on TON Blockchain.\n' + + ' to: Address;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Queues the message to be sent using the `MessageParameters` struct. Allows for cheaper non-deployment, regular messages compared to the `send()` function.\n' + + '///\n' + + '/// The `MessageParameters` struct is similar to `SendParameters` struct, but without the `code` and `data` fields.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// message(MessageParameters{\n' + + '/// to: sender(), // back to the sender,\n' + + '/// value: ton("1"), // with 1 Toncoin (1_000_000_000 nanoToncoin),\n' + + '/// // and no message body\n' + + '/// });\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 33: [Action list is too long] — Thrown when attempting to queue more than 255 messages.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-send#message\n' + + '/// * https://docs.tact-lang.org/book/message-mode\n' + + '///\n' + + '/// [Action list is too long]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '///\n' + + 'asm fun message(params: MessageParameters) {\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 106 PUSHINT // 1 + 4 + 4 + 64 + 32 + 1\n' + + ' STZEROES\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + ' STDICT\n' + + ' ENDC\n' + + ' SWAP\n' + + ' SENDRAWMSG\n' + + '}\n' + + '\n' + + '/// Global function. Queues the message to be sent using a `SendParameters` Struct.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// send(SendParameters{\n' + + '/// to: sender(), // back to the sender,\n' + + '/// value: ton("1"), // with 1 Toncoin (1_000_000_000 nanoToncoin),\n' + + '/// // and no message body\n' + + '/// });\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 33: [Action list is too long] — Thrown when attempting to queue more than 255 messages.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#send\n' + + '///\n' + + '/// [Action list is too long]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '///\n' + + 'asm fun send(params: SendParameters) {\n' + + ' // Instructions are grouped, and the stack states they produce as a group are shown right after.\n' + + ' // In the end, our message Cell should have the following TL-B structure:\n' + + ' // message$_ {X:Type}\n' + + ' // info:CommonMsgInfoRelaxed\n' + + ' // init:(Maybe (Either StateInit ^StateInit))\n' + + ' // body:(Either X ^X)\n' + + ' // = MessageRelaxed X;\n' + + '\n' + + ' // → Stack state\n' + + ' // s0: `params.bounce`\n' + + ' // s1: `params.to`\n' + + ' // s2: `params.value`\n' + + ' // s3: `params.data`\n' + + ' // s4: `params.code`\n' + + ' // s5: `params.body`\n' + + ' // s6: `params.mode`\n' + + ' // For brevity, the "params" prefix will be omitted from now on.\n' + + '\n' + + ' // Group 1: Storing the `bounce`, `to` and `value` into a Builder\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + '\n' + + ' // Group 2: Placing the Builder after code and data, then checking those for nullability\n' + + ' s2 XCHG0\n' + + ' DUP2\n' + + ' ISNULL\n' + + ' SWAP\n' + + ' ISNULL\n' + + ' AND\n' + + ' // → Stack state\n' + + ' // s0: -1 (true) if `data` and `code` are both null, 0 (false) otherwise\n' + + ' // s1: `code`\n' + + ' // s2: `data`\n' + + ' // s3: Builder\n' + + ' // s4: `body`\n' + + ' // s5: `mode`\n' + + '\n' + + ' // Group 3: Left branch of the IFELSE, executed if s0 is -1 (true)\n' + + ' <{\n' + + ' DROP2 // drop `data` and `code`, since either of those is null\n' + + ' b{0} STSLICECONST\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: Right branch of the IFELSE, executed if s0 is 0 (false)\n' + + ' <{\n' + + ' // _ split_depth:(Maybe (## 5))\n' + + ' // special:(Maybe TickTock)\n' + + ' // code:(Maybe ^Cell)\n' + + ' // data:(Maybe ^Cell)\n' + + ' // library:(Maybe ^Cell)\n' + + ' // = StateInit;\n' + + ' ROT // place message Builder on top\n' + + ' b{10} STSLICECONST // store Maybe = true, Either = false\n' + + ' // Start composing inlined StateInit\n' + + ' b{00} STSLICECONST // store split_depth and special first\n' + + ' STDICT // store code\n' + + ' STDICT // store data\n' + + ' b{0} STSLICECONST // store library\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: IFELSE that does the branching shown above\n' + + ' IFELSE\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: null or StateInit\n' + + ' // s2: `body`\n' + + ' // s3: `mode`\n' + + '\n' + + ' // Group 4: Finalizing the message\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: `mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG // https://github.com/tact-lang/tact/issues/1558\n' + + '}\n' + + '\n' + + '/// Struct for specifying the deployment message parameters of the `deploy()` function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#deploy\n' + + '///\n' + + 'struct DeployParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '\n' + + ' //'... 12658 more characters, + imports: [], + items: [ + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendDefaultMode', + loc: { start: 164, end: 179 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 181, end: 184 } + }, + loc: { start: 181, end: 184 } + }, + initializer: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 187, end: 188 } + } + }, + loc: { start: 158, end: 189 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendRemainingValue', + loc: { start: 396, end: 414 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 416, end: 419 } + }, + loc: { start: 416, end: 419 } + }, + initializer: { + kind: 'number', + base: '10', + value: 64n, + loc: { start: 422, end: 424 } + } + }, + loc: { start: 390, end: 425 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendRemainingBalance', + loc: { start: 638, end: 658 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 660, end: 663 } + }, + loc: { start: 660, end: 663 } + }, + initializer: { + kind: 'number', + base: '10', + value: 128n, + loc: { start: 666, end: 669 } + } + }, + loc: { start: 632, end: 670 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendOnlyEstimateFee', + loc: { start: 993, end: 1012 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1014, end: 1017 } + }, + loc: { start: 1014, end: 1017 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1024n, + loc: { start: 1020, end: 1024 } + } + }, + loc: { start: 987, end: 1025 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendPayGasSeparately', + loc: { start: 1207, end: 1227 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1229, end: 1232 } + }, + loc: { start: 1229, end: 1232 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1235, end: 1236 } + } + }, + loc: { start: 1201, end: 1237 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendPayFwdFeesSeparately', + loc: { start: 1378, end: 1402 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1404, end: 1407 } + }, + loc: { start: 1404, end: 1407 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1410, end: 1411 } + } + }, + loc: { start: 1372, end: 1412 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendIgnoreErrors', + loc: { start: 1582, end: 1598 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1600, end: 1603 } + }, + loc: { start: 1600, end: 1603 } + }, + initializer: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 1606, end: 1607 } + } + }, + loc: { start: 1576, end: 1608 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendBounceIfActionFail', + loc: { start: 1817, end: 1839 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1841, end: 1844 } + }, + loc: { start: 1841, end: 1844 } + }, + initializer: { + kind: 'number', + base: '10', + value: 16n, + loc: { start: 1847, end: 1849 } + } + }, + loc: { start: 1811, end: 1850 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendDestroyIfZero', + loc: { start: 2085, end: 2102 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2104, end: 2107 } + }, + loc: { start: 2104, end: 2107 } + }, + initializer: { + kind: 'number', + base: '10', + value: 32n, + loc: { start: 2110, end: 2112 } + } + }, + loc: { start: 2079, end: 2113 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'SendParameters', + loc: { start: 2260, end: 2274 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 2416, end: 2420 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2422, end: 2425 } + }, + loc: { start: 2422, end: 2425 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 2428, end: 2443 } + }, + loc: { start: 2416, end: 2443 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 2493, end: 2497 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2503, end: 2504 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2499, end: 2503 } + }, + loc: { start: 2499, end: 2503 } + } + ], + loc: { start: 2503, end: 2504 } + }, + initializer: { kind: 'null', loc: { start: 2507, end: 2511 } }, + loc: { start: 2493, end: 2511 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'code', + loc: { start: 2584, end: 2588 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2594, end: 2595 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2590, end: 2594 } + }, + loc: { start: 2590, end: 2594 } + } + ], + loc: { start: 2594, end: 2595 } + }, + initializer: { kind: 'null', loc: { start: 2598, end: 2602 } }, + loc: { start: 2584, end: 2602 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'data', + loc: { start: 2722, end: 2726 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2732, end: 2733 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2728, end: 2732 } + }, + loc: { start: 2728, end: 2732 } + } + ], + loc: { start: 2732, end: 2733 } + }, + initializer: { kind: 'null', loc: { start: 2736, end: 2740 } }, + loc: { start: 2722, end: 2740 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 2936, end: 2941 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2943, end: 2946 } + }, + loc: { start: 2943, end: 2946 } + }, + initializer: undefined, + loc: { start: 2936, end: 2946 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'to', + loc: { start: 3009, end: 3011 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3013, end: 3020 } + }, + typeArgs: [], + loc: { start: 3013, end: 3020 } + }, + initializer: undefined, + loc: { start: 3009, end: 3020 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 3186, end: 3192 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 3194, end: 3198 } + }, + typeArgs: [], + loc: { start: 3194, end: 3198 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 3201, end: 3205 } + }, + loc: { start: 3186, end: 3205 } + } + ], + loc: { start: 2253, end: 3208 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'MessageParameters', + loc: { start: 3389, end: 3406 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 3548, end: 3552 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3554, end: 3557 } + }, + loc: { start: 3554, end: 3557 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 3560, end: 3575 } + }, + loc: { start: 3548, end: 3575 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 3625, end: 3629 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 3635, end: 3636 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 3631, end: 3635 } + }, + loc: { start: 3631, end: 3635 } + } + ], + loc: { start: 3635, end: 3636 } + }, + initializer: { kind: 'null', loc: { start: 3639, end: 3643 } }, + loc: { start: 3625, end: 3643 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 3839, end: 3844 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3846, end: 3849 } + }, + loc: { start: 3846, end: 3849 } + }, + initializer: undefined, + loc: { start: 3839, end: 3849 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'to', + loc: { start: 3912, end: 3914 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3916, end: 3923 } + }, + typeArgs: [], + loc: { start: 3916, end: 3923 } + }, + initializer: undefined, + loc: { start: 3912, end: 3923 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 4089, end: 4095 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 4097, end: 4101 } + }, + typeArgs: [], + loc: { start: 4097, end: 4101 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 4104, end: 4108 } + }, + loc: { start: 4089, end: 4108 } + } + ], + loc: { start: 3382, end: 4111 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'message', + loc: { start: 5056, end: 5063 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 5064, end: 5070 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'MessageParameters', + loc: { start: 5072, end: 5089 } + }, + typeArgs: [], + loc: { start: 5072, end: 5089 } + }, + loc: { start: 5064, end: 5089 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 106 PUSHINT // 1 + 4 + 4 + 64 + 32 + 1\n' + + ' STZEROES\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + ' STDICT\n' + + ' ENDC\n' + + ' SWAP\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 5048, end: 5588 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'send', loc: { start: 6219, end: 6223 } }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 6224, end: 6230 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'SendParameters', + loc: { start: 6232, end: 6246 } + }, + typeArgs: [], + loc: { start: 6232, end: 6246 } + }, + loc: { start: 6224, end: 6246 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + '\n' + + ' // Group 2: Placing the Builder after code and data, then checking those for nullability\n' + + ' s2 XCHG0\n' + + ' DUP2\n' + + ' ISNULL\n' + + ' SWAP\n' + + ' ISNULL\n' + + ' AND\n' + + ' // → Stack state\n' + + ' // s0: -1 (true) if `data` and `code` are both null, 0 (false) otherwise\n' + + ' // s1: `code`\n' + + ' // s2: `data`\n' + + ' // s3: Builder\n' + + ' // s4: `body`\n' + + ' // s5: `mode`\n' + + '\n' + + ' // Group 3: Left branch of the IFELSE, executed if s0 is -1 (true)\n' + + ' <{\n' + + ' DROP2 // drop `data` and `code`, since either of those is null\n' + + ' b{0} STSLICECONST\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: Right branch of the IFELSE, executed if s0 is 0 (false)\n' + + ' <{\n' + + ' // _ split_depth:(Maybe (## 5))\n' + + ' // special:(Maybe TickTock)\n' + + ' // code:(Maybe ^Cell)\n' + + ' // data:(Maybe ^Cell)\n' + + ' // library:(Maybe ^Cell)\n' + + ' // = StateInit;\n' + + ' ROT // place message Builder on top\n' + + ' b{10} STSLICECONST // store Maybe = true, Either = false\n' + + ' // Start composing inlined StateInit\n' + + ' b{00} STSLICECONST // store split_depth and special first\n' + + ' STDICT // store code\n' + + ' STDICT // store data\n' + + ' b{0} STSLICECONST // store library\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: IFELSE that does the branching shown above\n' + + ' IFELSE\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: null or StateInit\n' + + ' // s2: `body`\n' + + ' // s3: `mode`\n' + + '\n' + + ' // Group 4: Finalizing the message\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: `mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG // https://github.com/tact-lang/tact/issues/1558' + ] + }, + loc: { start: 6211, end: 9157 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'DeployParameters', + loc: { start: 9347, end: 9363 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 9505, end: 9509 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9511, end: 9514 } + }, + loc: { start: 9511, end: 9514 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 9517, end: 9532 } + }, + loc: { start: 9505, end: 9532 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 9582, end: 9586 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 9592, end: 9593 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 9588, end: 9592 } + }, + loc: { start: 9588, end: 9592 } + } + ], + loc: { start: 9592, end: 9593 } + }, + initializer: { kind: 'null', loc: { start: 9596, end: 9600 } }, + loc: { start: 9582, end: 9600 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 9796, end: 9801 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9803, end: 9806 } + }, + loc: { start: 9803, end: 9806 } + }, + initializer: undefined, + loc: { start: 9796, end: 9806 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 9972, end: 9978 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 9980, end: 9984 } + }, + typeArgs: [], + loc: { start: 9980, end: 9984 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 9987, end: 9991 } + }, + loc: { start: 9972, end: 9991 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'init', + loc: { start: 10135, end: 10139 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 10141, end: 10150 } + }, + typeArgs: [], + loc: { start: 10141, end: 10150 } + }, + initializer: undefined, + loc: { start: 10135, end: 10150 } + } + ], + loc: { start: 9340, end: 10153 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'deploy', + loc: { start: 11796, end: 11802 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 11803, end: 11809 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'DeployParameters', + loc: { start: 11811, end: 11827 } + }, + typeArgs: [], + loc: { start: 11811, end: 11827 } + }, + loc: { start: 11803, end: 11827 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '4 1 BLKPUSH // pushes 2 copies of `init.code` and `init.data`\n' + + ' HASHCU // `init.data` hash\n' + + ' SWAP\n' + + ' HASHCU // `init.code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `init.data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `init.code` depth\n' + + '\n' + + ' // Group 2: Calculating destination address\n' + + ' // For almost identical logic and instructions,\n' + + ' // see comments inside `contractHash()` function in contract.tact\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + ' NEWC\n' + + ' 24 STU\n' + + ' 16 STU\n' + + ' 16 STU\n' + + ' 256 STU\n' + + ' 256 STU\n' + + ' ONE HASHEXT_SHA256 // obtains hash part (account id) of the address\n' + + ' // → Stack state\n' + + ' // s0: destAddr(hash part)\n' + + ' // s1: `init.data`\n' + + ' // s2: `init.code`\n' + + ' // s3 and below: `bounce`, `value`, `body`, `mode`\n' + + '\n' + + ' // Group 3: Building a message (CommonMsgInfoRelaxed)\n' + + ' s3 XCHG0 // swaps `bounce` with destAddr(hash part)\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' s1 s2 XCHG // swap `init.data` with `init.code`, placing code on s1\n' + + ' STREF // store `init.code`\n' + + ' STREF // store `init.data`\n' + + ' // Inline StateInit:\n' + + ' b{00010000000000} STSLICECONST\n' + + ' // 0 + 00 + 10 + 0 + 00000000\n' + + ' // 1) 0 - bounced = false\n' + + ' // 2) 00 - src = addr_none\n' + + ' // 3) 10 - tag of addr_std (part of dest)\n' + + ' // 4) 0 - Maybe Anycast = false\n' + + ' // 5) 00000000 - workchain_id (part of dest)\n' + + ' //\n' + + ' 256 STU // store destAddr(hash part)\n' + + ' SWAP // Builder on top, `value` below\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + '\n' + + ' // Group 4: Continue building a message (CommonMsgInfoRelaxed into MessageRelaxed)\n' + + ' // Remaining bits of MessageRelaxed:\n' + + ' b{1000110} STSLICECONST\n' + + ' // 10 + 0 + 0 + 1 + 1 + 0\n' + + ' // 10 - Maybe (Either StateInit ^StateInit) = true false\n' + + ' // 0 - split_depth:(Maybe (## 5)) = false\n' + + ' // 0 = special:(Maybe TickTock) = false\n' + + ' // 1 = code:(Maybe ^Cell) = true\n' + + ' // 1 = data:(Maybe ^Cell) = true\n' + + ' // 0 = library:(Maybe ^Cell) = false\n' + + ' //\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC // finalize the message\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: params.`mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 11788, end: 14770 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'cashback', + loc: { start: 15971, end: 15979 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'to', + loc: { start: 15980, end: 15982 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 15984, end: 15991 } + }, + typeArgs: [], + loc: { start: 15984, end: 15991 } + }, + loc: { start: 15980, end: 15991 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '16 PUSHINT // 0x10, i.e. 0x18 but with bounce = false\n' + + ' NEWC\n' + + ' 6 STU // .storeUint(0x10, 6)\n' + + ' STSLICE // .storeAddress(to)\n' + + ' 0 PUSHINT // 0\n' + + ' 111 STUR // .storeUint(0, 111)\n' + + ' // 4 zeros for coins and 107 zeros for lt, fees, etc.\n' + + ' ENDC\n' + + ' 66 PUSHINT // SendRemainingValue | SendIgnoreErrors\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 15963, end: 16385 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeSendMessage', + loc: { start: 16936, end: 16953 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 16954, end: 16957 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 16959, end: 16963 } + }, + loc: { start: 16959, end: 16963 } + }, + loc: { start: 16954, end: 16963 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 16965, end: 16969 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 16971, end: 16974 } + }, + loc: { start: 16971, end: 16974 } + }, + loc: { start: 16965, end: 16974 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDRAWMSG' ] + }, + loc: { start: 16928, end: 16990 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sendRawMessage', + loc: { start: 17751, end: 17765 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 17766, end: 17769 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 17771, end: 17775 } + }, + loc: { start: 17771, end: 17775 } + }, + loc: { start: 17766, end: 17775 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 17777, end: 17781 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 17783, end: 17786 } + }, + loc: { start: 17783, end: 17786 } + }, + loc: { start: 17777, end: 17786 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDRAWMSG' ] + }, + loc: { start: 17743, end: 17802 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeSendMessageReturnForwardFee', + loc: { start: 19063, end: 19096 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 19120, end: 19123 } + }, + loc: { start: 19120, end: 19123 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 19097, end: 19100 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 19102, end: 19106 } + }, + loc: { start: 19102, end: 19106 } + }, + loc: { start: 19097, end: 19106 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 19108, end: 19112 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 19114, end: 19117 } + }, + loc: { start: 19114, end: 19117 } + }, + loc: { start: 19108, end: 19117 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDMSG' ] + }, + loc: { start: 19055, end: 19135 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sendMessageReturnForwardFee', + loc: { start: 20186, end: 20213 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 20237, end: 20240 } + }, + loc: { start: 20237, end: 20240 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 20214, end: 20217 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 20219, end: 20223 } + }, + loc: { start: 20219, end: 20223 } + }, + loc: { start: 20214, end: 20223 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 20225, end: 20229 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 20231, end: 20234 } + }, + loc: { start: 20231, end: 20234 } + }, + loc: { start: 20225, end: 20234 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDMSG' ] + }, + loc: { start: 20178, end: 20252 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'emit', + loc: { start: 21033, end: 21037 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'body', + loc: { start: 21038, end: 21042 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 21044, end: 21048 } + }, + loc: { start: 21044, end: 21048 } + }, + loc: { start: 21038, end: 21048 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'c', + loc: { start: 21233, end: 21234 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 21236, end: 21240 } + }, + loc: { start: 21236, end: 21240 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'static_call', + function: { + kind: 'id', + text: 'beginCell', + loc: { start: 21243, end: 21252 } + }, + typeArgs: [], + args: [], + loc: { start: 21243, end: 21254 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 21264, end: 21273 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 15211807202738752817960438464513n, + loc: { start: 21274, end: 21306 } + }, + { + kind: 'number', + base: '10', + value: 104n, + loc: { start: 21308, end: 21311 } + } + ], + loc: { start: 21243, end: 21312 } + }, + method: { + kind: 'id', + text: 'storeRef', + loc: { start: 21322, end: 21330 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'body', + loc: { start: 21331, end: 21335 } + } + ], + loc: { start: 21243, end: 21336 } + }, + method: { + kind: 'id', + text: 'endCell', + loc: { start: 21346, end: 21353 } + }, + typeArgs: [], + args: [], + loc: { start: 21243, end: 21355 } + }, + loc: { start: 21229, end: 21356 } + }, + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'sendRawMessage', + loc: { start: 21361, end: 21375 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'c', + loc: { start: 21376, end: 21377 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 21379, end: 21380 } + } + ], + loc: { start: 21361, end: 21381 } + }, + loc: { start: 21361, end: 21382 } + } + ] + }, + loc: { start: 21022, end: 21384 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'acceptMessage', + loc: { start: 22124, end: 22137 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ACCEPT' ] + }, + loc: { start: 22116, end: 22150 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'commit', + loc: { start: 22638, end: 22644 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'COMMIT' ] + }, + loc: { start: 22630, end: 22657 } + } + ] + }, + 'SendPayFwdFeesSeparately' => { + kind: 'tact', + path: 'std/internal/send.tact', + code: '/// Ordinary message (default).\n' + + '///\n' + + '/// This constant is available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendDefaultMode: Int = 0;\n' + + '\n' + + '/// Carry all the remaining value of the inbound message in addition\n' + + '/// to the value initially indicated in the new message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendRemainingValue: Int = 64;\n' + + '\n' + + '/// Carry **all the remaining balance** of the current smart contract instead\n' + + '/// of the value originally indicated in the message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendRemainingBalance: Int = 128;\n' + + '\n' + + "/// Doesn't send the message, only estimates the forward fees\n" + + '/// if the message-sending function computes those.\n' + + '///\n' + + '/// This constant is available since Tact 1.5.0.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '/// * https://docs.tact-lang.org/book/send#message-sending-functions\n' + + '///\n' + + 'const SendOnlyEstimateFee: Int = 1024;\n' + + '\n' + + '/// **Deprecated** since Tact 1.6.5.\n' + + '///\n' + + '/// Pay forward fees separately from the message value.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendPayGasSeparately: Int = 1;\n' + + '\n' + + '/// Pay forward fees separately from the message value.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendPayFwdFeesSeparately: Int = 1;\n' + + '\n' + + '/// Ignore any errors arising while processing this message during the action phase.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendIgnoreErrors: Int = 2;\n' + + '\n' + + '/// Bounce transaction in case of any errors during action phase.\n' + + '/// Has no effect if flag +2, `SendIgnoreErrors` is used.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendBounceIfActionFail: Int = 16;\n' + + '\n' + + '/// Current account (contract) will be destroyed if its resulting balance is zero.\n' + + '/// This flag is often used with mode 128, `SendRemainingBalance`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendDestroyIfZero: Int = 32;\n' + + '\n' + + '/// Struct for specifying the message parameters of the `send()` function.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#send\n' + + '///\n' + + 'struct SendParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// Optional initial code of the contract (compiled bitcode).\n' + + ' code: Cell? = null;\n' + + '\n' + + ' /// Optional initial data of the contract (arguments of `init()` function or values of contract parameters).\n' + + ' data: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// Recipient internal `Address` on TON Blockchain.\n' + + ' to: Address;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '}\n' + + '\n' + + '/// Struct for specifying the message parameters of the `message()` function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#message\n' + + '///\n' + + 'struct MessageParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// Recipient internal `Address` on TON Blockchain.\n' + + ' to: Address;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Queues the message to be sent using the `MessageParameters` struct. Allows for cheaper non-deployment, regular messages compared to the `send()` function.\n' + + '///\n' + + '/// The `MessageParameters` struct is similar to `SendParameters` struct, but without the `code` and `data` fields.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// message(MessageParameters{\n' + + '/// to: sender(), // back to the sender,\n' + + '/// value: ton("1"), // with 1 Toncoin (1_000_000_000 nanoToncoin),\n' + + '/// // and no message body\n' + + '/// });\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 33: [Action list is too long] — Thrown when attempting to queue more than 255 messages.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-send#message\n' + + '/// * https://docs.tact-lang.org/book/message-mode\n' + + '///\n' + + '/// [Action list is too long]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '///\n' + + 'asm fun message(params: MessageParameters) {\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 106 PUSHINT // 1 + 4 + 4 + 64 + 32 + 1\n' + + ' STZEROES\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + ' STDICT\n' + + ' ENDC\n' + + ' SWAP\n' + + ' SENDRAWMSG\n' + + '}\n' + + '\n' + + '/// Global function. Queues the message to be sent using a `SendParameters` Struct.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// send(SendParameters{\n' + + '/// to: sender(), // back to the sender,\n' + + '/// value: ton("1"), // with 1 Toncoin (1_000_000_000 nanoToncoin),\n' + + '/// // and no message body\n' + + '/// });\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 33: [Action list is too long] — Thrown when attempting to queue more than 255 messages.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#send\n' + + '///\n' + + '/// [Action list is too long]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '///\n' + + 'asm fun send(params: SendParameters) {\n' + + ' // Instructions are grouped, and the stack states they produce as a group are shown right after.\n' + + ' // In the end, our message Cell should have the following TL-B structure:\n' + + ' // message$_ {X:Type}\n' + + ' // info:CommonMsgInfoRelaxed\n' + + ' // init:(Maybe (Either StateInit ^StateInit))\n' + + ' // body:(Either X ^X)\n' + + ' // = MessageRelaxed X;\n' + + '\n' + + ' // → Stack state\n' + + ' // s0: `params.bounce`\n' + + ' // s1: `params.to`\n' + + ' // s2: `params.value`\n' + + ' // s3: `params.data`\n' + + ' // s4: `params.code`\n' + + ' // s5: `params.body`\n' + + ' // s6: `params.mode`\n' + + ' // For brevity, the "params" prefix will be omitted from now on.\n' + + '\n' + + ' // Group 1: Storing the `bounce`, `to` and `value` into a Builder\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + '\n' + + ' // Group 2: Placing the Builder after code and data, then checking those for nullability\n' + + ' s2 XCHG0\n' + + ' DUP2\n' + + ' ISNULL\n' + + ' SWAP\n' + + ' ISNULL\n' + + ' AND\n' + + ' // → Stack state\n' + + ' // s0: -1 (true) if `data` and `code` are both null, 0 (false) otherwise\n' + + ' // s1: `code`\n' + + ' // s2: `data`\n' + + ' // s3: Builder\n' + + ' // s4: `body`\n' + + ' // s5: `mode`\n' + + '\n' + + ' // Group 3: Left branch of the IFELSE, executed if s0 is -1 (true)\n' + + ' <{\n' + + ' DROP2 // drop `data` and `code`, since either of those is null\n' + + ' b{0} STSLICECONST\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: Right branch of the IFELSE, executed if s0 is 0 (false)\n' + + ' <{\n' + + ' // _ split_depth:(Maybe (## 5))\n' + + ' // special:(Maybe TickTock)\n' + + ' // code:(Maybe ^Cell)\n' + + ' // data:(Maybe ^Cell)\n' + + ' // library:(Maybe ^Cell)\n' + + ' // = StateInit;\n' + + ' ROT // place message Builder on top\n' + + ' b{10} STSLICECONST // store Maybe = true, Either = false\n' + + ' // Start composing inlined StateInit\n' + + ' b{00} STSLICECONST // store split_depth and special first\n' + + ' STDICT // store code\n' + + ' STDICT // store data\n' + + ' b{0} STSLICECONST // store library\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: IFELSE that does the branching shown above\n' + + ' IFELSE\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: null or StateInit\n' + + ' // s2: `body`\n' + + ' // s3: `mode`\n' + + '\n' + + ' // Group 4: Finalizing the message\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: `mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG // https://github.com/tact-lang/tact/issues/1558\n' + + '}\n' + + '\n' + + '/// Struct for specifying the deployment message parameters of the `deploy()` function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#deploy\n' + + '///\n' + + 'struct DeployParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '\n' + + ' //'... 12658 more characters, + imports: [], + items: [ + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendDefaultMode', + loc: { start: 164, end: 179 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 181, end: 184 } + }, + loc: { start: 181, end: 184 } + }, + initializer: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 187, end: 188 } + } + }, + loc: { start: 158, end: 189 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendRemainingValue', + loc: { start: 396, end: 414 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 416, end: 419 } + }, + loc: { start: 416, end: 419 } + }, + initializer: { + kind: 'number', + base: '10', + value: 64n, + loc: { start: 422, end: 424 } + } + }, + loc: { start: 390, end: 425 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendRemainingBalance', + loc: { start: 638, end: 658 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 660, end: 663 } + }, + loc: { start: 660, end: 663 } + }, + initializer: { + kind: 'number', + base: '10', + value: 128n, + loc: { start: 666, end: 669 } + } + }, + loc: { start: 632, end: 670 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendOnlyEstimateFee', + loc: { start: 993, end: 1012 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1014, end: 1017 } + }, + loc: { start: 1014, end: 1017 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1024n, + loc: { start: 1020, end: 1024 } + } + }, + loc: { start: 987, end: 1025 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendPayGasSeparately', + loc: { start: 1207, end: 1227 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1229, end: 1232 } + }, + loc: { start: 1229, end: 1232 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1235, end: 1236 } + } + }, + loc: { start: 1201, end: 1237 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendPayFwdFeesSeparately', + loc: { start: 1378, end: 1402 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1404, end: 1407 } + }, + loc: { start: 1404, end: 1407 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1410, end: 1411 } + } + }, + loc: { start: 1372, end: 1412 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendIgnoreErrors', + loc: { start: 1582, end: 1598 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1600, end: 1603 } + }, + loc: { start: 1600, end: 1603 } + }, + initializer: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 1606, end: 1607 } + } + }, + loc: { start: 1576, end: 1608 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendBounceIfActionFail', + loc: { start: 1817, end: 1839 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1841, end: 1844 } + }, + loc: { start: 1841, end: 1844 } + }, + initializer: { + kind: 'number', + base: '10', + value: 16n, + loc: { start: 1847, end: 1849 } + } + }, + loc: { start: 1811, end: 1850 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendDestroyIfZero', + loc: { start: 2085, end: 2102 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2104, end: 2107 } + }, + loc: { start: 2104, end: 2107 } + }, + initializer: { + kind: 'number', + base: '10', + value: 32n, + loc: { start: 2110, end: 2112 } + } + }, + loc: { start: 2079, end: 2113 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'SendParameters', + loc: { start: 2260, end: 2274 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 2416, end: 2420 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2422, end: 2425 } + }, + loc: { start: 2422, end: 2425 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 2428, end: 2443 } + }, + loc: { start: 2416, end: 2443 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 2493, end: 2497 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2503, end: 2504 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2499, end: 2503 } + }, + loc: { start: 2499, end: 2503 } + } + ], + loc: { start: 2503, end: 2504 } + }, + initializer: { kind: 'null', loc: { start: 2507, end: 2511 } }, + loc: { start: 2493, end: 2511 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'code', + loc: { start: 2584, end: 2588 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2594, end: 2595 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2590, end: 2594 } + }, + loc: { start: 2590, end: 2594 } + } + ], + loc: { start: 2594, end: 2595 } + }, + initializer: { kind: 'null', loc: { start: 2598, end: 2602 } }, + loc: { start: 2584, end: 2602 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'data', + loc: { start: 2722, end: 2726 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2732, end: 2733 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2728, end: 2732 } + }, + loc: { start: 2728, end: 2732 } + } + ], + loc: { start: 2732, end: 2733 } + }, + initializer: { kind: 'null', loc: { start: 2736, end: 2740 } }, + loc: { start: 2722, end: 2740 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 2936, end: 2941 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2943, end: 2946 } + }, + loc: { start: 2943, end: 2946 } + }, + initializer: undefined, + loc: { start: 2936, end: 2946 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'to', + loc: { start: 3009, end: 3011 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3013, end: 3020 } + }, + typeArgs: [], + loc: { start: 3013, end: 3020 } + }, + initializer: undefined, + loc: { start: 3009, end: 3020 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 3186, end: 3192 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 3194, end: 3198 } + }, + typeArgs: [], + loc: { start: 3194, end: 3198 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 3201, end: 3205 } + }, + loc: { start: 3186, end: 3205 } + } + ], + loc: { start: 2253, end: 3208 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'MessageParameters', + loc: { start: 3389, end: 3406 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 3548, end: 3552 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3554, end: 3557 } + }, + loc: { start: 3554, end: 3557 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 3560, end: 3575 } + }, + loc: { start: 3548, end: 3575 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 3625, end: 3629 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 3635, end: 3636 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 3631, end: 3635 } + }, + loc: { start: 3631, end: 3635 } + } + ], + loc: { start: 3635, end: 3636 } + }, + initializer: { kind: 'null', loc: { start: 3639, end: 3643 } }, + loc: { start: 3625, end: 3643 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 3839, end: 3844 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3846, end: 3849 } + }, + loc: { start: 3846, end: 3849 } + }, + initializer: undefined, + loc: { start: 3839, end: 3849 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'to', + loc: { start: 3912, end: 3914 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3916, end: 3923 } + }, + typeArgs: [], + loc: { start: 3916, end: 3923 } + }, + initializer: undefined, + loc: { start: 3912, end: 3923 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 4089, end: 4095 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 4097, end: 4101 } + }, + typeArgs: [], + loc: { start: 4097, end: 4101 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 4104, end: 4108 } + }, + loc: { start: 4089, end: 4108 } + } + ], + loc: { start: 3382, end: 4111 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'message', + loc: { start: 5056, end: 5063 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 5064, end: 5070 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'MessageParameters', + loc: { start: 5072, end: 5089 } + }, + typeArgs: [], + loc: { start: 5072, end: 5089 } + }, + loc: { start: 5064, end: 5089 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 106 PUSHINT // 1 + 4 + 4 + 64 + 32 + 1\n' + + ' STZEROES\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + ' STDICT\n' + + ' ENDC\n' + + ' SWAP\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 5048, end: 5588 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'send', loc: { start: 6219, end: 6223 } }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 6224, end: 6230 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'SendParameters', + loc: { start: 6232, end: 6246 } + }, + typeArgs: [], + loc: { start: 6232, end: 6246 } + }, + loc: { start: 6224, end: 6246 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + '\n' + + ' // Group 2: Placing the Builder after code and data, then checking those for nullability\n' + + ' s2 XCHG0\n' + + ' DUP2\n' + + ' ISNULL\n' + + ' SWAP\n' + + ' ISNULL\n' + + ' AND\n' + + ' // → Stack state\n' + + ' // s0: -1 (true) if `data` and `code` are both null, 0 (false) otherwise\n' + + ' // s1: `code`\n' + + ' // s2: `data`\n' + + ' // s3: Builder\n' + + ' // s4: `body`\n' + + ' // s5: `mode`\n' + + '\n' + + ' // Group 3: Left branch of the IFELSE, executed if s0 is -1 (true)\n' + + ' <{\n' + + ' DROP2 // drop `data` and `code`, since either of those is null\n' + + ' b{0} STSLICECONST\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: Right branch of the IFELSE, executed if s0 is 0 (false)\n' + + ' <{\n' + + ' // _ split_depth:(Maybe (## 5))\n' + + ' // special:(Maybe TickTock)\n' + + ' // code:(Maybe ^Cell)\n' + + ' // data:(Maybe ^Cell)\n' + + ' // library:(Maybe ^Cell)\n' + + ' // = StateInit;\n' + + ' ROT // place message Builder on top\n' + + ' b{10} STSLICECONST // store Maybe = true, Either = false\n' + + ' // Start composing inlined StateInit\n' + + ' b{00} STSLICECONST // store split_depth and special first\n' + + ' STDICT // store code\n' + + ' STDICT // store data\n' + + ' b{0} STSLICECONST // store library\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: IFELSE that does the branching shown above\n' + + ' IFELSE\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: null or StateInit\n' + + ' // s2: `body`\n' + + ' // s3: `mode`\n' + + '\n' + + ' // Group 4: Finalizing the message\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: `mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG // https://github.com/tact-lang/tact/issues/1558' + ] + }, + loc: { start: 6211, end: 9157 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'DeployParameters', + loc: { start: 9347, end: 9363 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 9505, end: 9509 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9511, end: 9514 } + }, + loc: { start: 9511, end: 9514 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 9517, end: 9532 } + }, + loc: { start: 9505, end: 9532 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 9582, end: 9586 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 9592, end: 9593 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 9588, end: 9592 } + }, + loc: { start: 9588, end: 9592 } + } + ], + loc: { start: 9592, end: 9593 } + }, + initializer: { kind: 'null', loc: { start: 9596, end: 9600 } }, + loc: { start: 9582, end: 9600 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 9796, end: 9801 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9803, end: 9806 } + }, + loc: { start: 9803, end: 9806 } + }, + initializer: undefined, + loc: { start: 9796, end: 9806 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 9972, end: 9978 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 9980, end: 9984 } + }, + typeArgs: [], + loc: { start: 9980, end: 9984 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 9987, end: 9991 } + }, + loc: { start: 9972, end: 9991 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'init', + loc: { start: 10135, end: 10139 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 10141, end: 10150 } + }, + typeArgs: [], + loc: { start: 10141, end: 10150 } + }, + initializer: undefined, + loc: { start: 10135, end: 10150 } + } + ], + loc: { start: 9340, end: 10153 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'deploy', + loc: { start: 11796, end: 11802 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 11803, end: 11809 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'DeployParameters', + loc: { start: 11811, end: 11827 } + }, + typeArgs: [], + loc: { start: 11811, end: 11827 } + }, + loc: { start: 11803, end: 11827 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '4 1 BLKPUSH // pushes 2 copies of `init.code` and `init.data`\n' + + ' HASHCU // `init.data` hash\n' + + ' SWAP\n' + + ' HASHCU // `init.code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `init.data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `init.code` depth\n' + + '\n' + + ' // Group 2: Calculating destination address\n' + + ' // For almost identical logic and instructions,\n' + + ' // see comments inside `contractHash()` function in contract.tact\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + ' NEWC\n' + + ' 24 STU\n' + + ' 16 STU\n' + + ' 16 STU\n' + + ' 256 STU\n' + + ' 256 STU\n' + + ' ONE HASHEXT_SHA256 // obtains hash part (account id) of the address\n' + + ' // → Stack state\n' + + ' // s0: destAddr(hash part)\n' + + ' // s1: `init.data`\n' + + ' // s2: `init.code`\n' + + ' // s3 and below: `bounce`, `value`, `body`, `mode`\n' + + '\n' + + ' // Group 3: Building a message (CommonMsgInfoRelaxed)\n' + + ' s3 XCHG0 // swaps `bounce` with destAddr(hash part)\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' s1 s2 XCHG // swap `init.data` with `init.code`, placing code on s1\n' + + ' STREF // store `init.code`\n' + + ' STREF // store `init.data`\n' + + ' // Inline StateInit:\n' + + ' b{00010000000000} STSLICECONST\n' + + ' // 0 + 00 + 10 + 0 + 00000000\n' + + ' // 1) 0 - bounced = false\n' + + ' // 2) 00 - src = addr_none\n' + + ' // 3) 10 - tag of addr_std (part of dest)\n' + + ' // 4) 0 - Maybe Anycast = false\n' + + ' // 5) 00000000 - workchain_id (part of dest)\n' + + ' //\n' + + ' 256 STU // store destAddr(hash part)\n' + + ' SWAP // Builder on top, `value` below\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + '\n' + + ' // Group 4: Continue building a message (CommonMsgInfoRelaxed into MessageRelaxed)\n' + + ' // Remaining bits of MessageRelaxed:\n' + + ' b{1000110} STSLICECONST\n' + + ' // 10 + 0 + 0 + 1 + 1 + 0\n' + + ' // 10 - Maybe (Either StateInit ^StateInit) = true false\n' + + ' // 0 - split_depth:(Maybe (## 5)) = false\n' + + ' // 0 = special:(Maybe TickTock) = false\n' + + ' // 1 = code:(Maybe ^Cell) = true\n' + + ' // 1 = data:(Maybe ^Cell) = true\n' + + ' // 0 = library:(Maybe ^Cell) = false\n' + + ' //\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC // finalize the message\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: params.`mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 11788, end: 14770 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'cashback', + loc: { start: 15971, end: 15979 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'to', + loc: { start: 15980, end: 15982 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 15984, end: 15991 } + }, + typeArgs: [], + loc: { start: 15984, end: 15991 } + }, + loc: { start: 15980, end: 15991 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '16 PUSHINT // 0x10, i.e. 0x18 but with bounce = false\n' + + ' NEWC\n' + + ' 6 STU // .storeUint(0x10, 6)\n' + + ' STSLICE // .storeAddress(to)\n' + + ' 0 PUSHINT // 0\n' + + ' 111 STUR // .storeUint(0, 111)\n' + + ' // 4 zeros for coins and 107 zeros for lt, fees, etc.\n' + + ' ENDC\n' + + ' 66 PUSHINT // SendRemainingValue | SendIgnoreErrors\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 15963, end: 16385 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeSendMessage', + loc: { start: 16936, end: 16953 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 16954, end: 16957 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 16959, end: 16963 } + }, + loc: { start: 16959, end: 16963 } + }, + loc: { start: 16954, end: 16963 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 16965, end: 16969 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 16971, end: 16974 } + }, + loc: { start: 16971, end: 16974 } + }, + loc: { start: 16965, end: 16974 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDRAWMSG' ] + }, + loc: { start: 16928, end: 16990 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sendRawMessage', + loc: { start: 17751, end: 17765 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 17766, end: 17769 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 17771, end: 17775 } + }, + loc: { start: 17771, end: 17775 } + }, + loc: { start: 17766, end: 17775 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 17777, end: 17781 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 17783, end: 17786 } + }, + loc: { start: 17783, end: 17786 } + }, + loc: { start: 17777, end: 17786 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDRAWMSG' ] + }, + loc: { start: 17743, end: 17802 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeSendMessageReturnForwardFee', + loc: { start: 19063, end: 19096 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 19120, end: 19123 } + }, + loc: { start: 19120, end: 19123 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 19097, end: 19100 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 19102, end: 19106 } + }, + loc: { start: 19102, end: 19106 } + }, + loc: { start: 19097, end: 19106 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 19108, end: 19112 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 19114, end: 19117 } + }, + loc: { start: 19114, end: 19117 } + }, + loc: { start: 19108, end: 19117 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDMSG' ] + }, + loc: { start: 19055, end: 19135 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sendMessageReturnForwardFee', + loc: { start: 20186, end: 20213 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 20237, end: 20240 } + }, + loc: { start: 20237, end: 20240 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 20214, end: 20217 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 20219, end: 20223 } + }, + loc: { start: 20219, end: 20223 } + }, + loc: { start: 20214, end: 20223 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 20225, end: 20229 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 20231, end: 20234 } + }, + loc: { start: 20231, end: 20234 } + }, + loc: { start: 20225, end: 20234 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDMSG' ] + }, + loc: { start: 20178, end: 20252 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'emit', + loc: { start: 21033, end: 21037 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'body', + loc: { start: 21038, end: 21042 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 21044, end: 21048 } + }, + loc: { start: 21044, end: 21048 } + }, + loc: { start: 21038, end: 21048 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'c', + loc: { start: 21233, end: 21234 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 21236, end: 21240 } + }, + loc: { start: 21236, end: 21240 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'static_call', + function: { + kind: 'id', + text: 'beginCell', + loc: { start: 21243, end: 21252 } + }, + typeArgs: [], + args: [], + loc: { start: 21243, end: 21254 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 21264, end: 21273 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 15211807202738752817960438464513n, + loc: { start: 21274, end: 21306 } + }, + { + kind: 'number', + base: '10', + value: 104n, + loc: { start: 21308, end: 21311 } + } + ], + loc: { start: 21243, end: 21312 } + }, + method: { + kind: 'id', + text: 'storeRef', + loc: { start: 21322, end: 21330 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'body', + loc: { start: 21331, end: 21335 } + } + ], + loc: { start: 21243, end: 21336 } + }, + method: { + kind: 'id', + text: 'endCell', + loc: { start: 21346, end: 21353 } + }, + typeArgs: [], + args: [], + loc: { start: 21243, end: 21355 } + }, + loc: { start: 21229, end: 21356 } + }, + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'sendRawMessage', + loc: { start: 21361, end: 21375 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'c', + loc: { start: 21376, end: 21377 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 21379, end: 21380 } + } + ], + loc: { start: 21361, end: 21381 } + }, + loc: { start: 21361, end: 21382 } + } + ] + }, + loc: { start: 21022, end: 21384 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'acceptMessage', + loc: { start: 22124, end: 22137 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ACCEPT' ] + }, + loc: { start: 22116, end: 22150 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'commit', + loc: { start: 22638, end: 22644 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'COMMIT' ] + }, + loc: { start: 22630, end: 22657 } + } + ] + }, + 'SendIgnoreErrors' => { + kind: 'tact', + path: 'std/internal/send.tact', + code: '/// Ordinary message (default).\n' + + '///\n' + + '/// This constant is available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendDefaultMode: Int = 0;\n' + + '\n' + + '/// Carry all the remaining value of the inbound message in addition\n' + + '/// to the value initially indicated in the new message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendRemainingValue: Int = 64;\n' + + '\n' + + '/// Carry **all the remaining balance** of the current smart contract instead\n' + + '/// of the value originally indicated in the message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendRemainingBalance: Int = 128;\n' + + '\n' + + "/// Doesn't send the message, only estimates the forward fees\n" + + '/// if the message-sending function computes those.\n' + + '///\n' + + '/// This constant is available since Tact 1.5.0.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '/// * https://docs.tact-lang.org/book/send#message-sending-functions\n' + + '///\n' + + 'const SendOnlyEstimateFee: Int = 1024;\n' + + '\n' + + '/// **Deprecated** since Tact 1.6.5.\n' + + '///\n' + + '/// Pay forward fees separately from the message value.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendPayGasSeparately: Int = 1;\n' + + '\n' + + '/// Pay forward fees separately from the message value.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendPayFwdFeesSeparately: Int = 1;\n' + + '\n' + + '/// Ignore any errors arising while processing this message during the action phase.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendIgnoreErrors: Int = 2;\n' + + '\n' + + '/// Bounce transaction in case of any errors during action phase.\n' + + '/// Has no effect if flag +2, `SendIgnoreErrors` is used.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendBounceIfActionFail: Int = 16;\n' + + '\n' + + '/// Current account (contract) will be destroyed if its resulting balance is zero.\n' + + '/// This flag is often used with mode 128, `SendRemainingBalance`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendDestroyIfZero: Int = 32;\n' + + '\n' + + '/// Struct for specifying the message parameters of the `send()` function.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#send\n' + + '///\n' + + 'struct SendParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// Optional initial code of the contract (compiled bitcode).\n' + + ' code: Cell? = null;\n' + + '\n' + + ' /// Optional initial data of the contract (arguments of `init()` function or values of contract parameters).\n' + + ' data: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// Recipient internal `Address` on TON Blockchain.\n' + + ' to: Address;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '}\n' + + '\n' + + '/// Struct for specifying the message parameters of the `message()` function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#message\n' + + '///\n' + + 'struct MessageParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// Recipient internal `Address` on TON Blockchain.\n' + + ' to: Address;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Queues the message to be sent using the `MessageParameters` struct. Allows for cheaper non-deployment, regular messages compared to the `send()` function.\n' + + '///\n' + + '/// The `MessageParameters` struct is similar to `SendParameters` struct, but without the `code` and `data` fields.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// message(MessageParameters{\n' + + '/// to: sender(), // back to the sender,\n' + + '/// value: ton("1"), // with 1 Toncoin (1_000_000_000 nanoToncoin),\n' + + '/// // and no message body\n' + + '/// });\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 33: [Action list is too long] — Thrown when attempting to queue more than 255 messages.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-send#message\n' + + '/// * https://docs.tact-lang.org/book/message-mode\n' + + '///\n' + + '/// [Action list is too long]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '///\n' + + 'asm fun message(params: MessageParameters) {\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 106 PUSHINT // 1 + 4 + 4 + 64 + 32 + 1\n' + + ' STZEROES\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + ' STDICT\n' + + ' ENDC\n' + + ' SWAP\n' + + ' SENDRAWMSG\n' + + '}\n' + + '\n' + + '/// Global function. Queues the message to be sent using a `SendParameters` Struct.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// send(SendParameters{\n' + + '/// to: sender(), // back to the sender,\n' + + '/// value: ton("1"), // with 1 Toncoin (1_000_000_000 nanoToncoin),\n' + + '/// // and no message body\n' + + '/// });\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 33: [Action list is too long] — Thrown when attempting to queue more than 255 messages.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#send\n' + + '///\n' + + '/// [Action list is too long]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '///\n' + + 'asm fun send(params: SendParameters) {\n' + + ' // Instructions are grouped, and the stack states they produce as a group are shown right after.\n' + + ' // In the end, our message Cell should have the following TL-B structure:\n' + + ' // message$_ {X:Type}\n' + + ' // info:CommonMsgInfoRelaxed\n' + + ' // init:(Maybe (Either StateInit ^StateInit))\n' + + ' // body:(Either X ^X)\n' + + ' // = MessageRelaxed X;\n' + + '\n' + + ' // → Stack state\n' + + ' // s0: `params.bounce`\n' + + ' // s1: `params.to`\n' + + ' // s2: `params.value`\n' + + ' // s3: `params.data`\n' + + ' // s4: `params.code`\n' + + ' // s5: `params.body`\n' + + ' // s6: `params.mode`\n' + + ' // For brevity, the "params" prefix will be omitted from now on.\n' + + '\n' + + ' // Group 1: Storing the `bounce`, `to` and `value` into a Builder\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + '\n' + + ' // Group 2: Placing the Builder after code and data, then checking those for nullability\n' + + ' s2 XCHG0\n' + + ' DUP2\n' + + ' ISNULL\n' + + ' SWAP\n' + + ' ISNULL\n' + + ' AND\n' + + ' // → Stack state\n' + + ' // s0: -1 (true) if `data` and `code` are both null, 0 (false) otherwise\n' + + ' // s1: `code`\n' + + ' // s2: `data`\n' + + ' // s3: Builder\n' + + ' // s4: `body`\n' + + ' // s5: `mode`\n' + + '\n' + + ' // Group 3: Left branch of the IFELSE, executed if s0 is -1 (true)\n' + + ' <{\n' + + ' DROP2 // drop `data` and `code`, since either of those is null\n' + + ' b{0} STSLICECONST\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: Right branch of the IFELSE, executed if s0 is 0 (false)\n' + + ' <{\n' + + ' // _ split_depth:(Maybe (## 5))\n' + + ' // special:(Maybe TickTock)\n' + + ' // code:(Maybe ^Cell)\n' + + ' // data:(Maybe ^Cell)\n' + + ' // library:(Maybe ^Cell)\n' + + ' // = StateInit;\n' + + ' ROT // place message Builder on top\n' + + ' b{10} STSLICECONST // store Maybe = true, Either = false\n' + + ' // Start composing inlined StateInit\n' + + ' b{00} STSLICECONST // store split_depth and special first\n' + + ' STDICT // store code\n' + + ' STDICT // store data\n' + + ' b{0} STSLICECONST // store library\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: IFELSE that does the branching shown above\n' + + ' IFELSE\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: null or StateInit\n' + + ' // s2: `body`\n' + + ' // s3: `mode`\n' + + '\n' + + ' // Group 4: Finalizing the message\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: `mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG // https://github.com/tact-lang/tact/issues/1558\n' + + '}\n' + + '\n' + + '/// Struct for specifying the deployment message parameters of the `deploy()` function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#deploy\n' + + '///\n' + + 'struct DeployParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '\n' + + ' //'... 12658 more characters, + imports: [], + items: [ + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendDefaultMode', + loc: { start: 164, end: 179 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 181, end: 184 } + }, + loc: { start: 181, end: 184 } + }, + initializer: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 187, end: 188 } + } + }, + loc: { start: 158, end: 189 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendRemainingValue', + loc: { start: 396, end: 414 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 416, end: 419 } + }, + loc: { start: 416, end: 419 } + }, + initializer: { + kind: 'number', + base: '10', + value: 64n, + loc: { start: 422, end: 424 } + } + }, + loc: { start: 390, end: 425 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendRemainingBalance', + loc: { start: 638, end: 658 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 660, end: 663 } + }, + loc: { start: 660, end: 663 } + }, + initializer: { + kind: 'number', + base: '10', + value: 128n, + loc: { start: 666, end: 669 } + } + }, + loc: { start: 632, end: 670 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendOnlyEstimateFee', + loc: { start: 993, end: 1012 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1014, end: 1017 } + }, + loc: { start: 1014, end: 1017 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1024n, + loc: { start: 1020, end: 1024 } + } + }, + loc: { start: 987, end: 1025 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendPayGasSeparately', + loc: { start: 1207, end: 1227 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1229, end: 1232 } + }, + loc: { start: 1229, end: 1232 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1235, end: 1236 } + } + }, + loc: { start: 1201, end: 1237 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendPayFwdFeesSeparately', + loc: { start: 1378, end: 1402 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1404, end: 1407 } + }, + loc: { start: 1404, end: 1407 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1410, end: 1411 } + } + }, + loc: { start: 1372, end: 1412 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendIgnoreErrors', + loc: { start: 1582, end: 1598 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1600, end: 1603 } + }, + loc: { start: 1600, end: 1603 } + }, + initializer: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 1606, end: 1607 } + } + }, + loc: { start: 1576, end: 1608 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendBounceIfActionFail', + loc: { start: 1817, end: 1839 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1841, end: 1844 } + }, + loc: { start: 1841, end: 1844 } + }, + initializer: { + kind: 'number', + base: '10', + value: 16n, + loc: { start: 1847, end: 1849 } + } + }, + loc: { start: 1811, end: 1850 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendDestroyIfZero', + loc: { start: 2085, end: 2102 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2104, end: 2107 } + }, + loc: { start: 2104, end: 2107 } + }, + initializer: { + kind: 'number', + base: '10', + value: 32n, + loc: { start: 2110, end: 2112 } + } + }, + loc: { start: 2079, end: 2113 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'SendParameters', + loc: { start: 2260, end: 2274 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 2416, end: 2420 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2422, end: 2425 } + }, + loc: { start: 2422, end: 2425 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 2428, end: 2443 } + }, + loc: { start: 2416, end: 2443 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 2493, end: 2497 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2503, end: 2504 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2499, end: 2503 } + }, + loc: { start: 2499, end: 2503 } + } + ], + loc: { start: 2503, end: 2504 } + }, + initializer: { kind: 'null', loc: { start: 2507, end: 2511 } }, + loc: { start: 2493, end: 2511 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'code', + loc: { start: 2584, end: 2588 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2594, end: 2595 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2590, end: 2594 } + }, + loc: { start: 2590, end: 2594 } + } + ], + loc: { start: 2594, end: 2595 } + }, + initializer: { kind: 'null', loc: { start: 2598, end: 2602 } }, + loc: { start: 2584, end: 2602 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'data', + loc: { start: 2722, end: 2726 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2732, end: 2733 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2728, end: 2732 } + }, + loc: { start: 2728, end: 2732 } + } + ], + loc: { start: 2732, end: 2733 } + }, + initializer: { kind: 'null', loc: { start: 2736, end: 2740 } }, + loc: { start: 2722, end: 2740 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 2936, end: 2941 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2943, end: 2946 } + }, + loc: { start: 2943, end: 2946 } + }, + initializer: undefined, + loc: { start: 2936, end: 2946 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'to', + loc: { start: 3009, end: 3011 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3013, end: 3020 } + }, + typeArgs: [], + loc: { start: 3013, end: 3020 } + }, + initializer: undefined, + loc: { start: 3009, end: 3020 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 3186, end: 3192 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 3194, end: 3198 } + }, + typeArgs: [], + loc: { start: 3194, end: 3198 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 3201, end: 3205 } + }, + loc: { start: 3186, end: 3205 } + } + ], + loc: { start: 2253, end: 3208 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'MessageParameters', + loc: { start: 3389, end: 3406 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 3548, end: 3552 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3554, end: 3557 } + }, + loc: { start: 3554, end: 3557 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 3560, end: 3575 } + }, + loc: { start: 3548, end: 3575 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 3625, end: 3629 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 3635, end: 3636 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 3631, end: 3635 } + }, + loc: { start: 3631, end: 3635 } + } + ], + loc: { start: 3635, end: 3636 } + }, + initializer: { kind: 'null', loc: { start: 3639, end: 3643 } }, + loc: { start: 3625, end: 3643 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 3839, end: 3844 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3846, end: 3849 } + }, + loc: { start: 3846, end: 3849 } + }, + initializer: undefined, + loc: { start: 3839, end: 3849 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'to', + loc: { start: 3912, end: 3914 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3916, end: 3923 } + }, + typeArgs: [], + loc: { start: 3916, end: 3923 } + }, + initializer: undefined, + loc: { start: 3912, end: 3923 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 4089, end: 4095 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 4097, end: 4101 } + }, + typeArgs: [], + loc: { start: 4097, end: 4101 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 4104, end: 4108 } + }, + loc: { start: 4089, end: 4108 } + } + ], + loc: { start: 3382, end: 4111 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'message', + loc: { start: 5056, end: 5063 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 5064, end: 5070 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'MessageParameters', + loc: { start: 5072, end: 5089 } + }, + typeArgs: [], + loc: { start: 5072, end: 5089 } + }, + loc: { start: 5064, end: 5089 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 106 PUSHINT // 1 + 4 + 4 + 64 + 32 + 1\n' + + ' STZEROES\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + ' STDICT\n' + + ' ENDC\n' + + ' SWAP\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 5048, end: 5588 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'send', loc: { start: 6219, end: 6223 } }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 6224, end: 6230 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'SendParameters', + loc: { start: 6232, end: 6246 } + }, + typeArgs: [], + loc: { start: 6232, end: 6246 } + }, + loc: { start: 6224, end: 6246 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + '\n' + + ' // Group 2: Placing the Builder after code and data, then checking those for nullability\n' + + ' s2 XCHG0\n' + + ' DUP2\n' + + ' ISNULL\n' + + ' SWAP\n' + + ' ISNULL\n' + + ' AND\n' + + ' // → Stack state\n' + + ' // s0: -1 (true) if `data` and `code` are both null, 0 (false) otherwise\n' + + ' // s1: `code`\n' + + ' // s2: `data`\n' + + ' // s3: Builder\n' + + ' // s4: `body`\n' + + ' // s5: `mode`\n' + + '\n' + + ' // Group 3: Left branch of the IFELSE, executed if s0 is -1 (true)\n' + + ' <{\n' + + ' DROP2 // drop `data` and `code`, since either of those is null\n' + + ' b{0} STSLICECONST\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: Right branch of the IFELSE, executed if s0 is 0 (false)\n' + + ' <{\n' + + ' // _ split_depth:(Maybe (## 5))\n' + + ' // special:(Maybe TickTock)\n' + + ' // code:(Maybe ^Cell)\n' + + ' // data:(Maybe ^Cell)\n' + + ' // library:(Maybe ^Cell)\n' + + ' // = StateInit;\n' + + ' ROT // place message Builder on top\n' + + ' b{10} STSLICECONST // store Maybe = true, Either = false\n' + + ' // Start composing inlined StateInit\n' + + ' b{00} STSLICECONST // store split_depth and special first\n' + + ' STDICT // store code\n' + + ' STDICT // store data\n' + + ' b{0} STSLICECONST // store library\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: IFELSE that does the branching shown above\n' + + ' IFELSE\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: null or StateInit\n' + + ' // s2: `body`\n' + + ' // s3: `mode`\n' + + '\n' + + ' // Group 4: Finalizing the message\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: `mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG // https://github.com/tact-lang/tact/issues/1558' + ] + }, + loc: { start: 6211, end: 9157 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'DeployParameters', + loc: { start: 9347, end: 9363 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 9505, end: 9509 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9511, end: 9514 } + }, + loc: { start: 9511, end: 9514 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 9517, end: 9532 } + }, + loc: { start: 9505, end: 9532 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 9582, end: 9586 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 9592, end: 9593 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 9588, end: 9592 } + }, + loc: { start: 9588, end: 9592 } + } + ], + loc: { start: 9592, end: 9593 } + }, + initializer: { kind: 'null', loc: { start: 9596, end: 9600 } }, + loc: { start: 9582, end: 9600 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 9796, end: 9801 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9803, end: 9806 } + }, + loc: { start: 9803, end: 9806 } + }, + initializer: undefined, + loc: { start: 9796, end: 9806 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 9972, end: 9978 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 9980, end: 9984 } + }, + typeArgs: [], + loc: { start: 9980, end: 9984 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 9987, end: 9991 } + }, + loc: { start: 9972, end: 9991 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'init', + loc: { start: 10135, end: 10139 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 10141, end: 10150 } + }, + typeArgs: [], + loc: { start: 10141, end: 10150 } + }, + initializer: undefined, + loc: { start: 10135, end: 10150 } + } + ], + loc: { start: 9340, end: 10153 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'deploy', + loc: { start: 11796, end: 11802 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 11803, end: 11809 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'DeployParameters', + loc: { start: 11811, end: 11827 } + }, + typeArgs: [], + loc: { start: 11811, end: 11827 } + }, + loc: { start: 11803, end: 11827 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '4 1 BLKPUSH // pushes 2 copies of `init.code` and `init.data`\n' + + ' HASHCU // `init.data` hash\n' + + ' SWAP\n' + + ' HASHCU // `init.code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `init.data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `init.code` depth\n' + + '\n' + + ' // Group 2: Calculating destination address\n' + + ' // For almost identical logic and instructions,\n' + + ' // see comments inside `contractHash()` function in contract.tact\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + ' NEWC\n' + + ' 24 STU\n' + + ' 16 STU\n' + + ' 16 STU\n' + + ' 256 STU\n' + + ' 256 STU\n' + + ' ONE HASHEXT_SHA256 // obtains hash part (account id) of the address\n' + + ' // → Stack state\n' + + ' // s0: destAddr(hash part)\n' + + ' // s1: `init.data`\n' + + ' // s2: `init.code`\n' + + ' // s3 and below: `bounce`, `value`, `body`, `mode`\n' + + '\n' + + ' // Group 3: Building a message (CommonMsgInfoRelaxed)\n' + + ' s3 XCHG0 // swaps `bounce` with destAddr(hash part)\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' s1 s2 XCHG // swap `init.data` with `init.code`, placing code on s1\n' + + ' STREF // store `init.code`\n' + + ' STREF // store `init.data`\n' + + ' // Inline StateInit:\n' + + ' b{00010000000000} STSLICECONST\n' + + ' // 0 + 00 + 10 + 0 + 00000000\n' + + ' // 1) 0 - bounced = false\n' + + ' // 2) 00 - src = addr_none\n' + + ' // 3) 10 - tag of addr_std (part of dest)\n' + + ' // 4) 0 - Maybe Anycast = false\n' + + ' // 5) 00000000 - workchain_id (part of dest)\n' + + ' //\n' + + ' 256 STU // store destAddr(hash part)\n' + + ' SWAP // Builder on top, `value` below\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + '\n' + + ' // Group 4: Continue building a message (CommonMsgInfoRelaxed into MessageRelaxed)\n' + + ' // Remaining bits of MessageRelaxed:\n' + + ' b{1000110} STSLICECONST\n' + + ' // 10 + 0 + 0 + 1 + 1 + 0\n' + + ' // 10 - Maybe (Either StateInit ^StateInit) = true false\n' + + ' // 0 - split_depth:(Maybe (## 5)) = false\n' + + ' // 0 = special:(Maybe TickTock) = false\n' + + ' // 1 = code:(Maybe ^Cell) = true\n' + + ' // 1 = data:(Maybe ^Cell) = true\n' + + ' // 0 = library:(Maybe ^Cell) = false\n' + + ' //\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC // finalize the message\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: params.`mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 11788, end: 14770 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'cashback', + loc: { start: 15971, end: 15979 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'to', + loc: { start: 15980, end: 15982 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 15984, end: 15991 } + }, + typeArgs: [], + loc: { start: 15984, end: 15991 } + }, + loc: { start: 15980, end: 15991 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '16 PUSHINT // 0x10, i.e. 0x18 but with bounce = false\n' + + ' NEWC\n' + + ' 6 STU // .storeUint(0x10, 6)\n' + + ' STSLICE // .storeAddress(to)\n' + + ' 0 PUSHINT // 0\n' + + ' 111 STUR // .storeUint(0, 111)\n' + + ' // 4 zeros for coins and 107 zeros for lt, fees, etc.\n' + + ' ENDC\n' + + ' 66 PUSHINT // SendRemainingValue | SendIgnoreErrors\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 15963, end: 16385 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeSendMessage', + loc: { start: 16936, end: 16953 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 16954, end: 16957 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 16959, end: 16963 } + }, + loc: { start: 16959, end: 16963 } + }, + loc: { start: 16954, end: 16963 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 16965, end: 16969 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 16971, end: 16974 } + }, + loc: { start: 16971, end: 16974 } + }, + loc: { start: 16965, end: 16974 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDRAWMSG' ] + }, + loc: { start: 16928, end: 16990 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sendRawMessage', + loc: { start: 17751, end: 17765 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 17766, end: 17769 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 17771, end: 17775 } + }, + loc: { start: 17771, end: 17775 } + }, + loc: { start: 17766, end: 17775 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 17777, end: 17781 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 17783, end: 17786 } + }, + loc: { start: 17783, end: 17786 } + }, + loc: { start: 17777, end: 17786 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDRAWMSG' ] + }, + loc: { start: 17743, end: 17802 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeSendMessageReturnForwardFee', + loc: { start: 19063, end: 19096 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 19120, end: 19123 } + }, + loc: { start: 19120, end: 19123 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 19097, end: 19100 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 19102, end: 19106 } + }, + loc: { start: 19102, end: 19106 } + }, + loc: { start: 19097, end: 19106 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 19108, end: 19112 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 19114, end: 19117 } + }, + loc: { start: 19114, end: 19117 } + }, + loc: { start: 19108, end: 19117 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDMSG' ] + }, + loc: { start: 19055, end: 19135 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sendMessageReturnForwardFee', + loc: { start: 20186, end: 20213 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 20237, end: 20240 } + }, + loc: { start: 20237, end: 20240 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 20214, end: 20217 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 20219, end: 20223 } + }, + loc: { start: 20219, end: 20223 } + }, + loc: { start: 20214, end: 20223 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 20225, end: 20229 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 20231, end: 20234 } + }, + loc: { start: 20231, end: 20234 } + }, + loc: { start: 20225, end: 20234 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDMSG' ] + }, + loc: { start: 20178, end: 20252 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'emit', + loc: { start: 21033, end: 21037 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'body', + loc: { start: 21038, end: 21042 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 21044, end: 21048 } + }, + loc: { start: 21044, end: 21048 } + }, + loc: { start: 21038, end: 21048 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'c', + loc: { start: 21233, end: 21234 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 21236, end: 21240 } + }, + loc: { start: 21236, end: 21240 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'static_call', + function: { + kind: 'id', + text: 'beginCell', + loc: { start: 21243, end: 21252 } + }, + typeArgs: [], + args: [], + loc: { start: 21243, end: 21254 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 21264, end: 21273 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 15211807202738752817960438464513n, + loc: { start: 21274, end: 21306 } + }, + { + kind: 'number', + base: '10', + value: 104n, + loc: { start: 21308, end: 21311 } + } + ], + loc: { start: 21243, end: 21312 } + }, + method: { + kind: 'id', + text: 'storeRef', + loc: { start: 21322, end: 21330 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'body', + loc: { start: 21331, end: 21335 } + } + ], + loc: { start: 21243, end: 21336 } + }, + method: { + kind: 'id', + text: 'endCell', + loc: { start: 21346, end: 21353 } + }, + typeArgs: [], + args: [], + loc: { start: 21243, end: 21355 } + }, + loc: { start: 21229, end: 21356 } + }, + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'sendRawMessage', + loc: { start: 21361, end: 21375 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'c', + loc: { start: 21376, end: 21377 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 21379, end: 21380 } + } + ], + loc: { start: 21361, end: 21381 } + }, + loc: { start: 21361, end: 21382 } + } + ] + }, + loc: { start: 21022, end: 21384 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'acceptMessage', + loc: { start: 22124, end: 22137 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ACCEPT' ] + }, + loc: { start: 22116, end: 22150 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'commit', + loc: { start: 22638, end: 22644 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'COMMIT' ] + }, + loc: { start: 22630, end: 22657 } + } + ] + }, + 'SendBounceIfActionFail' => { + kind: 'tact', + path: 'std/internal/send.tact', + code: '/// Ordinary message (default).\n' + + '///\n' + + '/// This constant is available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendDefaultMode: Int = 0;\n' + + '\n' + + '/// Carry all the remaining value of the inbound message in addition\n' + + '/// to the value initially indicated in the new message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendRemainingValue: Int = 64;\n' + + '\n' + + '/// Carry **all the remaining balance** of the current smart contract instead\n' + + '/// of the value originally indicated in the message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendRemainingBalance: Int = 128;\n' + + '\n' + + "/// Doesn't send the message, only estimates the forward fees\n" + + '/// if the message-sending function computes those.\n' + + '///\n' + + '/// This constant is available since Tact 1.5.0.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '/// * https://docs.tact-lang.org/book/send#message-sending-functions\n' + + '///\n' + + 'const SendOnlyEstimateFee: Int = 1024;\n' + + '\n' + + '/// **Deprecated** since Tact 1.6.5.\n' + + '///\n' + + '/// Pay forward fees separately from the message value.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendPayGasSeparately: Int = 1;\n' + + '\n' + + '/// Pay forward fees separately from the message value.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendPayFwdFeesSeparately: Int = 1;\n' + + '\n' + + '/// Ignore any errors arising while processing this message during the action phase.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendIgnoreErrors: Int = 2;\n' + + '\n' + + '/// Bounce transaction in case of any errors during action phase.\n' + + '/// Has no effect if flag +2, `SendIgnoreErrors` is used.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendBounceIfActionFail: Int = 16;\n' + + '\n' + + '/// Current account (contract) will be destroyed if its resulting balance is zero.\n' + + '/// This flag is often used with mode 128, `SendRemainingBalance`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendDestroyIfZero: Int = 32;\n' + + '\n' + + '/// Struct for specifying the message parameters of the `send()` function.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#send\n' + + '///\n' + + 'struct SendParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// Optional initial code of the contract (compiled bitcode).\n' + + ' code: Cell? = null;\n' + + '\n' + + ' /// Optional initial data of the contract (arguments of `init()` function or values of contract parameters).\n' + + ' data: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// Recipient internal `Address` on TON Blockchain.\n' + + ' to: Address;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '}\n' + + '\n' + + '/// Struct for specifying the message parameters of the `message()` function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#message\n' + + '///\n' + + 'struct MessageParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// Recipient internal `Address` on TON Blockchain.\n' + + ' to: Address;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Queues the message to be sent using the `MessageParameters` struct. Allows for cheaper non-deployment, regular messages compared to the `send()` function.\n' + + '///\n' + + '/// The `MessageParameters` struct is similar to `SendParameters` struct, but without the `code` and `data` fields.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// message(MessageParameters{\n' + + '/// to: sender(), // back to the sender,\n' + + '/// value: ton("1"), // with 1 Toncoin (1_000_000_000 nanoToncoin),\n' + + '/// // and no message body\n' + + '/// });\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 33: [Action list is too long] — Thrown when attempting to queue more than 255 messages.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-send#message\n' + + '/// * https://docs.tact-lang.org/book/message-mode\n' + + '///\n' + + '/// [Action list is too long]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '///\n' + + 'asm fun message(params: MessageParameters) {\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 106 PUSHINT // 1 + 4 + 4 + 64 + 32 + 1\n' + + ' STZEROES\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + ' STDICT\n' + + ' ENDC\n' + + ' SWAP\n' + + ' SENDRAWMSG\n' + + '}\n' + + '\n' + + '/// Global function. Queues the message to be sent using a `SendParameters` Struct.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// send(SendParameters{\n' + + '/// to: sender(), // back to the sender,\n' + + '/// value: ton("1"), // with 1 Toncoin (1_000_000_000 nanoToncoin),\n' + + '/// // and no message body\n' + + '/// });\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 33: [Action list is too long] — Thrown when attempting to queue more than 255 messages.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#send\n' + + '///\n' + + '/// [Action list is too long]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '///\n' + + 'asm fun send(params: SendParameters) {\n' + + ' // Instructions are grouped, and the stack states they produce as a group are shown right after.\n' + + ' // In the end, our message Cell should have the following TL-B structure:\n' + + ' // message$_ {X:Type}\n' + + ' // info:CommonMsgInfoRelaxed\n' + + ' // init:(Maybe (Either StateInit ^StateInit))\n' + + ' // body:(Either X ^X)\n' + + ' // = MessageRelaxed X;\n' + + '\n' + + ' // → Stack state\n' + + ' // s0: `params.bounce`\n' + + ' // s1: `params.to`\n' + + ' // s2: `params.value`\n' + + ' // s3: `params.data`\n' + + ' // s4: `params.code`\n' + + ' // s5: `params.body`\n' + + ' // s6: `params.mode`\n' + + ' // For brevity, the "params" prefix will be omitted from now on.\n' + + '\n' + + ' // Group 1: Storing the `bounce`, `to` and `value` into a Builder\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + '\n' + + ' // Group 2: Placing the Builder after code and data, then checking those for nullability\n' + + ' s2 XCHG0\n' + + ' DUP2\n' + + ' ISNULL\n' + + ' SWAP\n' + + ' ISNULL\n' + + ' AND\n' + + ' // → Stack state\n' + + ' // s0: -1 (true) if `data` and `code` are both null, 0 (false) otherwise\n' + + ' // s1: `code`\n' + + ' // s2: `data`\n' + + ' // s3: Builder\n' + + ' // s4: `body`\n' + + ' // s5: `mode`\n' + + '\n' + + ' // Group 3: Left branch of the IFELSE, executed if s0 is -1 (true)\n' + + ' <{\n' + + ' DROP2 // drop `data` and `code`, since either of those is null\n' + + ' b{0} STSLICECONST\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: Right branch of the IFELSE, executed if s0 is 0 (false)\n' + + ' <{\n' + + ' // _ split_depth:(Maybe (## 5))\n' + + ' // special:(Maybe TickTock)\n' + + ' // code:(Maybe ^Cell)\n' + + ' // data:(Maybe ^Cell)\n' + + ' // library:(Maybe ^Cell)\n' + + ' // = StateInit;\n' + + ' ROT // place message Builder on top\n' + + ' b{10} STSLICECONST // store Maybe = true, Either = false\n' + + ' // Start composing inlined StateInit\n' + + ' b{00} STSLICECONST // store split_depth and special first\n' + + ' STDICT // store code\n' + + ' STDICT // store data\n' + + ' b{0} STSLICECONST // store library\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: IFELSE that does the branching shown above\n' + + ' IFELSE\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: null or StateInit\n' + + ' // s2: `body`\n' + + ' // s3: `mode`\n' + + '\n' + + ' // Group 4: Finalizing the message\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: `mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG // https://github.com/tact-lang/tact/issues/1558\n' + + '}\n' + + '\n' + + '/// Struct for specifying the deployment message parameters of the `deploy()` function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#deploy\n' + + '///\n' + + 'struct DeployParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '\n' + + ' //'... 12658 more characters, + imports: [], + items: [ + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendDefaultMode', + loc: { start: 164, end: 179 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 181, end: 184 } + }, + loc: { start: 181, end: 184 } + }, + initializer: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 187, end: 188 } + } + }, + loc: { start: 158, end: 189 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendRemainingValue', + loc: { start: 396, end: 414 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 416, end: 419 } + }, + loc: { start: 416, end: 419 } + }, + initializer: { + kind: 'number', + base: '10', + value: 64n, + loc: { start: 422, end: 424 } + } + }, + loc: { start: 390, end: 425 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendRemainingBalance', + loc: { start: 638, end: 658 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 660, end: 663 } + }, + loc: { start: 660, end: 663 } + }, + initializer: { + kind: 'number', + base: '10', + value: 128n, + loc: { start: 666, end: 669 } + } + }, + loc: { start: 632, end: 670 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendOnlyEstimateFee', + loc: { start: 993, end: 1012 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1014, end: 1017 } + }, + loc: { start: 1014, end: 1017 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1024n, + loc: { start: 1020, end: 1024 } + } + }, + loc: { start: 987, end: 1025 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendPayGasSeparately', + loc: { start: 1207, end: 1227 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1229, end: 1232 } + }, + loc: { start: 1229, end: 1232 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1235, end: 1236 } + } + }, + loc: { start: 1201, end: 1237 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendPayFwdFeesSeparately', + loc: { start: 1378, end: 1402 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1404, end: 1407 } + }, + loc: { start: 1404, end: 1407 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1410, end: 1411 } + } + }, + loc: { start: 1372, end: 1412 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendIgnoreErrors', + loc: { start: 1582, end: 1598 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1600, end: 1603 } + }, + loc: { start: 1600, end: 1603 } + }, + initializer: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 1606, end: 1607 } + } + }, + loc: { start: 1576, end: 1608 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendBounceIfActionFail', + loc: { start: 1817, end: 1839 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1841, end: 1844 } + }, + loc: { start: 1841, end: 1844 } + }, + initializer: { + kind: 'number', + base: '10', + value: 16n, + loc: { start: 1847, end: 1849 } + } + }, + loc: { start: 1811, end: 1850 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendDestroyIfZero', + loc: { start: 2085, end: 2102 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2104, end: 2107 } + }, + loc: { start: 2104, end: 2107 } + }, + initializer: { + kind: 'number', + base: '10', + value: 32n, + loc: { start: 2110, end: 2112 } + } + }, + loc: { start: 2079, end: 2113 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'SendParameters', + loc: { start: 2260, end: 2274 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 2416, end: 2420 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2422, end: 2425 } + }, + loc: { start: 2422, end: 2425 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 2428, end: 2443 } + }, + loc: { start: 2416, end: 2443 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 2493, end: 2497 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2503, end: 2504 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2499, end: 2503 } + }, + loc: { start: 2499, end: 2503 } + } + ], + loc: { start: 2503, end: 2504 } + }, + initializer: { kind: 'null', loc: { start: 2507, end: 2511 } }, + loc: { start: 2493, end: 2511 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'code', + loc: { start: 2584, end: 2588 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2594, end: 2595 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2590, end: 2594 } + }, + loc: { start: 2590, end: 2594 } + } + ], + loc: { start: 2594, end: 2595 } + }, + initializer: { kind: 'null', loc: { start: 2598, end: 2602 } }, + loc: { start: 2584, end: 2602 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'data', + loc: { start: 2722, end: 2726 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2732, end: 2733 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2728, end: 2732 } + }, + loc: { start: 2728, end: 2732 } + } + ], + loc: { start: 2732, end: 2733 } + }, + initializer: { kind: 'null', loc: { start: 2736, end: 2740 } }, + loc: { start: 2722, end: 2740 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 2936, end: 2941 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2943, end: 2946 } + }, + loc: { start: 2943, end: 2946 } + }, + initializer: undefined, + loc: { start: 2936, end: 2946 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'to', + loc: { start: 3009, end: 3011 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3013, end: 3020 } + }, + typeArgs: [], + loc: { start: 3013, end: 3020 } + }, + initializer: undefined, + loc: { start: 3009, end: 3020 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 3186, end: 3192 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 3194, end: 3198 } + }, + typeArgs: [], + loc: { start: 3194, end: 3198 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 3201, end: 3205 } + }, + loc: { start: 3186, end: 3205 } + } + ], + loc: { start: 2253, end: 3208 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'MessageParameters', + loc: { start: 3389, end: 3406 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 3548, end: 3552 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3554, end: 3557 } + }, + loc: { start: 3554, end: 3557 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 3560, end: 3575 } + }, + loc: { start: 3548, end: 3575 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 3625, end: 3629 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 3635, end: 3636 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 3631, end: 3635 } + }, + loc: { start: 3631, end: 3635 } + } + ], + loc: { start: 3635, end: 3636 } + }, + initializer: { kind: 'null', loc: { start: 3639, end: 3643 } }, + loc: { start: 3625, end: 3643 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 3839, end: 3844 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3846, end: 3849 } + }, + loc: { start: 3846, end: 3849 } + }, + initializer: undefined, + loc: { start: 3839, end: 3849 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'to', + loc: { start: 3912, end: 3914 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3916, end: 3923 } + }, + typeArgs: [], + loc: { start: 3916, end: 3923 } + }, + initializer: undefined, + loc: { start: 3912, end: 3923 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 4089, end: 4095 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 4097, end: 4101 } + }, + typeArgs: [], + loc: { start: 4097, end: 4101 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 4104, end: 4108 } + }, + loc: { start: 4089, end: 4108 } + } + ], + loc: { start: 3382, end: 4111 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'message', + loc: { start: 5056, end: 5063 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 5064, end: 5070 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'MessageParameters', + loc: { start: 5072, end: 5089 } + }, + typeArgs: [], + loc: { start: 5072, end: 5089 } + }, + loc: { start: 5064, end: 5089 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 106 PUSHINT // 1 + 4 + 4 + 64 + 32 + 1\n' + + ' STZEROES\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + ' STDICT\n' + + ' ENDC\n' + + ' SWAP\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 5048, end: 5588 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'send', loc: { start: 6219, end: 6223 } }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 6224, end: 6230 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'SendParameters', + loc: { start: 6232, end: 6246 } + }, + typeArgs: [], + loc: { start: 6232, end: 6246 } + }, + loc: { start: 6224, end: 6246 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + '\n' + + ' // Group 2: Placing the Builder after code and data, then checking those for nullability\n' + + ' s2 XCHG0\n' + + ' DUP2\n' + + ' ISNULL\n' + + ' SWAP\n' + + ' ISNULL\n' + + ' AND\n' + + ' // → Stack state\n' + + ' // s0: -1 (true) if `data` and `code` are both null, 0 (false) otherwise\n' + + ' // s1: `code`\n' + + ' // s2: `data`\n' + + ' // s3: Builder\n' + + ' // s4: `body`\n' + + ' // s5: `mode`\n' + + '\n' + + ' // Group 3: Left branch of the IFELSE, executed if s0 is -1 (true)\n' + + ' <{\n' + + ' DROP2 // drop `data` and `code`, since either of those is null\n' + + ' b{0} STSLICECONST\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: Right branch of the IFELSE, executed if s0 is 0 (false)\n' + + ' <{\n' + + ' // _ split_depth:(Maybe (## 5))\n' + + ' // special:(Maybe TickTock)\n' + + ' // code:(Maybe ^Cell)\n' + + ' // data:(Maybe ^Cell)\n' + + ' // library:(Maybe ^Cell)\n' + + ' // = StateInit;\n' + + ' ROT // place message Builder on top\n' + + ' b{10} STSLICECONST // store Maybe = true, Either = false\n' + + ' // Start composing inlined StateInit\n' + + ' b{00} STSLICECONST // store split_depth and special first\n' + + ' STDICT // store code\n' + + ' STDICT // store data\n' + + ' b{0} STSLICECONST // store library\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: IFELSE that does the branching shown above\n' + + ' IFELSE\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: null or StateInit\n' + + ' // s2: `body`\n' + + ' // s3: `mode`\n' + + '\n' + + ' // Group 4: Finalizing the message\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: `mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG // https://github.com/tact-lang/tact/issues/1558' + ] + }, + loc: { start: 6211, end: 9157 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'DeployParameters', + loc: { start: 9347, end: 9363 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 9505, end: 9509 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9511, end: 9514 } + }, + loc: { start: 9511, end: 9514 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 9517, end: 9532 } + }, + loc: { start: 9505, end: 9532 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 9582, end: 9586 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 9592, end: 9593 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 9588, end: 9592 } + }, + loc: { start: 9588, end: 9592 } + } + ], + loc: { start: 9592, end: 9593 } + }, + initializer: { kind: 'null', loc: { start: 9596, end: 9600 } }, + loc: { start: 9582, end: 9600 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 9796, end: 9801 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9803, end: 9806 } + }, + loc: { start: 9803, end: 9806 } + }, + initializer: undefined, + loc: { start: 9796, end: 9806 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 9972, end: 9978 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 9980, end: 9984 } + }, + typeArgs: [], + loc: { start: 9980, end: 9984 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 9987, end: 9991 } + }, + loc: { start: 9972, end: 9991 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'init', + loc: { start: 10135, end: 10139 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 10141, end: 10150 } + }, + typeArgs: [], + loc: { start: 10141, end: 10150 } + }, + initializer: undefined, + loc: { start: 10135, end: 10150 } + } + ], + loc: { start: 9340, end: 10153 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'deploy', + loc: { start: 11796, end: 11802 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 11803, end: 11809 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'DeployParameters', + loc: { start: 11811, end: 11827 } + }, + typeArgs: [], + loc: { start: 11811, end: 11827 } + }, + loc: { start: 11803, end: 11827 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '4 1 BLKPUSH // pushes 2 copies of `init.code` and `init.data`\n' + + ' HASHCU // `init.data` hash\n' + + ' SWAP\n' + + ' HASHCU // `init.code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `init.data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `init.code` depth\n' + + '\n' + + ' // Group 2: Calculating destination address\n' + + ' // For almost identical logic and instructions,\n' + + ' // see comments inside `contractHash()` function in contract.tact\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + ' NEWC\n' + + ' 24 STU\n' + + ' 16 STU\n' + + ' 16 STU\n' + + ' 256 STU\n' + + ' 256 STU\n' + + ' ONE HASHEXT_SHA256 // obtains hash part (account id) of the address\n' + + ' // → Stack state\n' + + ' // s0: destAddr(hash part)\n' + + ' // s1: `init.data`\n' + + ' // s2: `init.code`\n' + + ' // s3 and below: `bounce`, `value`, `body`, `mode`\n' + + '\n' + + ' // Group 3: Building a message (CommonMsgInfoRelaxed)\n' + + ' s3 XCHG0 // swaps `bounce` with destAddr(hash part)\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' s1 s2 XCHG // swap `init.data` with `init.code`, placing code on s1\n' + + ' STREF // store `init.code`\n' + + ' STREF // store `init.data`\n' + + ' // Inline StateInit:\n' + + ' b{00010000000000} STSLICECONST\n' + + ' // 0 + 00 + 10 + 0 + 00000000\n' + + ' // 1) 0 - bounced = false\n' + + ' // 2) 00 - src = addr_none\n' + + ' // 3) 10 - tag of addr_std (part of dest)\n' + + ' // 4) 0 - Maybe Anycast = false\n' + + ' // 5) 00000000 - workchain_id (part of dest)\n' + + ' //\n' + + ' 256 STU // store destAddr(hash part)\n' + + ' SWAP // Builder on top, `value` below\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + '\n' + + ' // Group 4: Continue building a message (CommonMsgInfoRelaxed into MessageRelaxed)\n' + + ' // Remaining bits of MessageRelaxed:\n' + + ' b{1000110} STSLICECONST\n' + + ' // 10 + 0 + 0 + 1 + 1 + 0\n' + + ' // 10 - Maybe (Either StateInit ^StateInit) = true false\n' + + ' // 0 - split_depth:(Maybe (## 5)) = false\n' + + ' // 0 = special:(Maybe TickTock) = false\n' + + ' // 1 = code:(Maybe ^Cell) = true\n' + + ' // 1 = data:(Maybe ^Cell) = true\n' + + ' // 0 = library:(Maybe ^Cell) = false\n' + + ' //\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC // finalize the message\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: params.`mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 11788, end: 14770 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'cashback', + loc: { start: 15971, end: 15979 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'to', + loc: { start: 15980, end: 15982 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 15984, end: 15991 } + }, + typeArgs: [], + loc: { start: 15984, end: 15991 } + }, + loc: { start: 15980, end: 15991 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '16 PUSHINT // 0x10, i.e. 0x18 but with bounce = false\n' + + ' NEWC\n' + + ' 6 STU // .storeUint(0x10, 6)\n' + + ' STSLICE // .storeAddress(to)\n' + + ' 0 PUSHINT // 0\n' + + ' 111 STUR // .storeUint(0, 111)\n' + + ' // 4 zeros for coins and 107 zeros for lt, fees, etc.\n' + + ' ENDC\n' + + ' 66 PUSHINT // SendRemainingValue | SendIgnoreErrors\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 15963, end: 16385 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeSendMessage', + loc: { start: 16936, end: 16953 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 16954, end: 16957 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 16959, end: 16963 } + }, + loc: { start: 16959, end: 16963 } + }, + loc: { start: 16954, end: 16963 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 16965, end: 16969 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 16971, end: 16974 } + }, + loc: { start: 16971, end: 16974 } + }, + loc: { start: 16965, end: 16974 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDRAWMSG' ] + }, + loc: { start: 16928, end: 16990 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sendRawMessage', + loc: { start: 17751, end: 17765 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 17766, end: 17769 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 17771, end: 17775 } + }, + loc: { start: 17771, end: 17775 } + }, + loc: { start: 17766, end: 17775 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 17777, end: 17781 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 17783, end: 17786 } + }, + loc: { start: 17783, end: 17786 } + }, + loc: { start: 17777, end: 17786 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDRAWMSG' ] + }, + loc: { start: 17743, end: 17802 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeSendMessageReturnForwardFee', + loc: { start: 19063, end: 19096 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 19120, end: 19123 } + }, + loc: { start: 19120, end: 19123 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 19097, end: 19100 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 19102, end: 19106 } + }, + loc: { start: 19102, end: 19106 } + }, + loc: { start: 19097, end: 19106 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 19108, end: 19112 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 19114, end: 19117 } + }, + loc: { start: 19114, end: 19117 } + }, + loc: { start: 19108, end: 19117 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDMSG' ] + }, + loc: { start: 19055, end: 19135 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sendMessageReturnForwardFee', + loc: { start: 20186, end: 20213 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 20237, end: 20240 } + }, + loc: { start: 20237, end: 20240 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 20214, end: 20217 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 20219, end: 20223 } + }, + loc: { start: 20219, end: 20223 } + }, + loc: { start: 20214, end: 20223 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 20225, end: 20229 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 20231, end: 20234 } + }, + loc: { start: 20231, end: 20234 } + }, + loc: { start: 20225, end: 20234 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDMSG' ] + }, + loc: { start: 20178, end: 20252 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'emit', + loc: { start: 21033, end: 21037 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'body', + loc: { start: 21038, end: 21042 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 21044, end: 21048 } + }, + loc: { start: 21044, end: 21048 } + }, + loc: { start: 21038, end: 21048 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'c', + loc: { start: 21233, end: 21234 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 21236, end: 21240 } + }, + loc: { start: 21236, end: 21240 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'static_call', + function: { + kind: 'id', + text: 'beginCell', + loc: { start: 21243, end: 21252 } + }, + typeArgs: [], + args: [], + loc: { start: 21243, end: 21254 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 21264, end: 21273 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 15211807202738752817960438464513n, + loc: { start: 21274, end: 21306 } + }, + { + kind: 'number', + base: '10', + value: 104n, + loc: { start: 21308, end: 21311 } + } + ], + loc: { start: 21243, end: 21312 } + }, + method: { + kind: 'id', + text: 'storeRef', + loc: { start: 21322, end: 21330 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'body', + loc: { start: 21331, end: 21335 } + } + ], + loc: { start: 21243, end: 21336 } + }, + method: { + kind: 'id', + text: 'endCell', + loc: { start: 21346, end: 21353 } + }, + typeArgs: [], + args: [], + loc: { start: 21243, end: 21355 } + }, + loc: { start: 21229, end: 21356 } + }, + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'sendRawMessage', + loc: { start: 21361, end: 21375 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'c', + loc: { start: 21376, end: 21377 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 21379, end: 21380 } + } + ], + loc: { start: 21361, end: 21381 } + }, + loc: { start: 21361, end: 21382 } + } + ] + }, + loc: { start: 21022, end: 21384 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'acceptMessage', + loc: { start: 22124, end: 22137 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ACCEPT' ] + }, + loc: { start: 22116, end: 22150 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'commit', + loc: { start: 22638, end: 22644 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'COMMIT' ] + }, + loc: { start: 22630, end: 22657 } + } + ] + }, + 'SendDestroyIfZero' => { + kind: 'tact', + path: 'std/internal/send.tact', + code: '/// Ordinary message (default).\n' + + '///\n' + + '/// This constant is available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendDefaultMode: Int = 0;\n' + + '\n' + + '/// Carry all the remaining value of the inbound message in addition\n' + + '/// to the value initially indicated in the new message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendRemainingValue: Int = 64;\n' + + '\n' + + '/// Carry **all the remaining balance** of the current smart contract instead\n' + + '/// of the value originally indicated in the message.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '///\n' + + 'const SendRemainingBalance: Int = 128;\n' + + '\n' + + "/// Doesn't send the message, only estimates the forward fees\n" + + '/// if the message-sending function computes those.\n' + + '///\n' + + '/// This constant is available since Tact 1.5.0.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/book/message-mode#base-modes\n' + + '/// * https://docs.tact-lang.org/book/send#message-sending-functions\n' + + '///\n' + + 'const SendOnlyEstimateFee: Int = 1024;\n' + + '\n' + + '/// **Deprecated** since Tact 1.6.5.\n' + + '///\n' + + '/// Pay forward fees separately from the message value.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendPayGasSeparately: Int = 1;\n' + + '\n' + + '/// Pay forward fees separately from the message value.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendPayFwdFeesSeparately: Int = 1;\n' + + '\n' + + '/// Ignore any errors arising while processing this message during the action phase.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendIgnoreErrors: Int = 2;\n' + + '\n' + + '/// Bounce transaction in case of any errors during action phase.\n' + + '/// Has no effect if flag +2, `SendIgnoreErrors` is used.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendBounceIfActionFail: Int = 16;\n' + + '\n' + + '/// Current account (contract) will be destroyed if its resulting balance is zero.\n' + + '/// This flag is often used with mode 128, `SendRemainingBalance`.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/book/message-mode#optional-flags\n' + + '///\n' + + 'const SendDestroyIfZero: Int = 32;\n' + + '\n' + + '/// Struct for specifying the message parameters of the `send()` function.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#send\n' + + '///\n' + + 'struct SendParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// Optional initial code of the contract (compiled bitcode).\n' + + ' code: Cell? = null;\n' + + '\n' + + ' /// Optional initial data of the contract (arguments of `init()` function or values of contract parameters).\n' + + ' data: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// Recipient internal `Address` on TON Blockchain.\n' + + ' to: Address;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '}\n' + + '\n' + + '/// Struct for specifying the message parameters of the `message()` function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#message\n' + + '///\n' + + 'struct MessageParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// Recipient internal `Address` on TON Blockchain.\n' + + ' to: Address;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '}\n' + + '\n' + + '/// Global function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// Queues the message to be sent using the `MessageParameters` struct. Allows for cheaper non-deployment, regular messages compared to the `send()` function.\n' + + '///\n' + + '/// The `MessageParameters` struct is similar to `SendParameters` struct, but without the `code` and `data` fields.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// message(MessageParameters{\n' + + '/// to: sender(), // back to the sender,\n' + + '/// value: ton("1"), // with 1 Toncoin (1_000_000_000 nanoToncoin),\n' + + '/// // and no message body\n' + + '/// });\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 33: [Action list is too long] — Thrown when attempting to queue more than 255 messages.\n' + + '///\n' + + '/// See:\n' + + '/// * https://docs.tact-lang.org/ref/core-send#message\n' + + '/// * https://docs.tact-lang.org/book/message-mode\n' + + '///\n' + + '/// [Action list is too long]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '///\n' + + 'asm fun message(params: MessageParameters) {\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 106 PUSHINT // 1 + 4 + 4 + 64 + 32 + 1\n' + + ' STZEROES\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + ' STDICT\n' + + ' ENDC\n' + + ' SWAP\n' + + ' SENDRAWMSG\n' + + '}\n' + + '\n' + + '/// Global function. Queues the message to be sent using a `SendParameters` Struct.\n' + + '///\n' + + '/// ```tact\n' + + '/// fun example() {\n' + + '/// send(SendParameters{\n' + + '/// to: sender(), // back to the sender,\n' + + '/// value: ton("1"), // with 1 Toncoin (1_000_000_000 nanoToncoin),\n' + + '/// // and no message body\n' + + '/// });\n' + + '/// }\n' + + '/// ```\n' + + '///\n' + + '/// #### Exit codes\n' + + '///\n' + + '/// * 33: [Action list is too long] — Thrown when attempting to queue more than 255 messages.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#send\n' + + '///\n' + + '/// [Action list is too long]: https://docs.tact-lang.org/book/exit-codes#33\n' + + '///\n' + + 'asm fun send(params: SendParameters) {\n' + + ' // Instructions are grouped, and the stack states they produce as a group are shown right after.\n' + + ' // In the end, our message Cell should have the following TL-B structure:\n' + + ' // message$_ {X:Type}\n' + + ' // info:CommonMsgInfoRelaxed\n' + + ' // init:(Maybe (Either StateInit ^StateInit))\n' + + ' // body:(Either X ^X)\n' + + ' // = MessageRelaxed X;\n' + + '\n' + + ' // → Stack state\n' + + ' // s0: `params.bounce`\n' + + ' // s1: `params.to`\n' + + ' // s2: `params.value`\n' + + ' // s3: `params.data`\n' + + ' // s4: `params.code`\n' + + ' // s5: `params.body`\n' + + ' // s6: `params.mode`\n' + + ' // For brevity, the "params" prefix will be omitted from now on.\n' + + '\n' + + ' // Group 1: Storing the `bounce`, `to` and `value` into a Builder\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + '\n' + + ' // Group 2: Placing the Builder after code and data, then checking those for nullability\n' + + ' s2 XCHG0\n' + + ' DUP2\n' + + ' ISNULL\n' + + ' SWAP\n' + + ' ISNULL\n' + + ' AND\n' + + ' // → Stack state\n' + + ' // s0: -1 (true) if `data` and `code` are both null, 0 (false) otherwise\n' + + ' // s1: `code`\n' + + ' // s2: `data`\n' + + ' // s3: Builder\n' + + ' // s4: `body`\n' + + ' // s5: `mode`\n' + + '\n' + + ' // Group 3: Left branch of the IFELSE, executed if s0 is -1 (true)\n' + + ' <{\n' + + ' DROP2 // drop `data` and `code`, since either of those is null\n' + + ' b{0} STSLICECONST\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: Right branch of the IFELSE, executed if s0 is 0 (false)\n' + + ' <{\n' + + ' // _ split_depth:(Maybe (## 5))\n' + + ' // special:(Maybe TickTock)\n' + + ' // code:(Maybe ^Cell)\n' + + ' // data:(Maybe ^Cell)\n' + + ' // library:(Maybe ^Cell)\n' + + ' // = StateInit;\n' + + ' ROT // place message Builder on top\n' + + ' b{10} STSLICECONST // store Maybe = true, Either = false\n' + + ' // Start composing inlined StateInit\n' + + ' b{00} STSLICECONST // store split_depth and special first\n' + + ' STDICT // store code\n' + + ' STDICT // store data\n' + + ' b{0} STSLICECONST // store library\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: IFELSE that does the branching shown above\n' + + ' IFELSE\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: null or StateInit\n' + + ' // s2: `body`\n' + + ' // s3: `mode`\n' + + '\n' + + ' // Group 4: Finalizing the message\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: `mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG // https://github.com/tact-lang/tact/issues/1558\n' + + '}\n' + + '\n' + + '/// Struct for specifying the deployment message parameters of the `deploy()` function. Available since Tact 1.6.0.\n' + + '///\n' + + '/// See: https://docs.tact-lang.org/ref/core-send#deploy\n' + + '///\n' + + 'struct DeployParameters {\n' + + ' /// An 8-bit value that configures how to send a message, defaults to 0.\n' + + ' /// See: https://docs.tact-lang.org/book/message-mode\n' + + ' mode: Int = SendDefaultMode;\n' + + '\n' + + ' /// Optional message body as a `Cell`.\n' + + ' body: Cell? = null;\n' + + '\n' + + ' /// The amount of nanoToncoins you want to send with\n' + + ' /// the message. This value is used to cover forward fees,\n' + + ' /// unless the optional flag `SendPayFwdFeesSeparately` is used.\n' + + ' value: Int;\n' + + '\n' + + ' /// When set to `true` (default) message bounces back to the sender if\n' + + " /// the recipient contract doesn't exist or wasn't able to process the message.\n" + + ' bounce: Bool = true;\n' + + '\n' + + ' //'... 12658 more characters, + imports: [], + items: [ + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendDefaultMode', + loc: { start: 164, end: 179 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 181, end: 184 } + }, + loc: { start: 181, end: 184 } + }, + initializer: { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 187, end: 188 } + } + }, + loc: { start: 158, end: 189 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendRemainingValue', + loc: { start: 396, end: 414 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 416, end: 419 } + }, + loc: { start: 416, end: 419 } + }, + initializer: { + kind: 'number', + base: '10', + value: 64n, + loc: { start: 422, end: 424 } + } + }, + loc: { start: 390, end: 425 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendRemainingBalance', + loc: { start: 638, end: 658 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 660, end: 663 } + }, + loc: { start: 660, end: 663 } + }, + initializer: { + kind: 'number', + base: '10', + value: 128n, + loc: { start: 666, end: 669 } + } + }, + loc: { start: 632, end: 670 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendOnlyEstimateFee', + loc: { start: 993, end: 1012 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1014, end: 1017 } + }, + loc: { start: 1014, end: 1017 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1024n, + loc: { start: 1020, end: 1024 } + } + }, + loc: { start: 987, end: 1025 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendPayGasSeparately', + loc: { start: 1207, end: 1227 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1229, end: 1232 } + }, + loc: { start: 1229, end: 1232 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1235, end: 1236 } + } + }, + loc: { start: 1201, end: 1237 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendPayFwdFeesSeparately', + loc: { start: 1378, end: 1402 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1404, end: 1407 } + }, + loc: { start: 1404, end: 1407 } + }, + initializer: { + kind: 'number', + base: '10', + value: 1n, + loc: { start: 1410, end: 1411 } + } + }, + loc: { start: 1372, end: 1412 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendIgnoreErrors', + loc: { start: 1582, end: 1598 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1600, end: 1603 } + }, + loc: { start: 1600, end: 1603 } + }, + initializer: { + kind: 'number', + base: '10', + value: 2n, + loc: { start: 1606, end: 1607 } + } + }, + loc: { start: 1576, end: 1608 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendBounceIfActionFail', + loc: { start: 1817, end: 1839 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 1841, end: 1844 } + }, + loc: { start: 1841, end: 1844 } + }, + initializer: { + kind: 'number', + base: '10', + value: 16n, + loc: { start: 1847, end: 1849 } + } + }, + loc: { start: 1811, end: 1850 } + }, + { + kind: 'constant', + name: { + kind: 'id', + text: 'SendDestroyIfZero', + loc: { start: 2085, end: 2102 } + }, + init: { + kind: 'constant_def', + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2104, end: 2107 } + }, + loc: { start: 2104, end: 2107 } + }, + initializer: { + kind: 'number', + base: '10', + value: 32n, + loc: { start: 2110, end: 2112 } + } + }, + loc: { start: 2079, end: 2113 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'SendParameters', + loc: { start: 2260, end: 2274 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 2416, end: 2420 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2422, end: 2425 } + }, + loc: { start: 2422, end: 2425 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 2428, end: 2443 } + }, + loc: { start: 2416, end: 2443 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 2493, end: 2497 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2503, end: 2504 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2499, end: 2503 } + }, + loc: { start: 2499, end: 2503 } + } + ], + loc: { start: 2503, end: 2504 } + }, + initializer: { kind: 'null', loc: { start: 2507, end: 2511 } }, + loc: { start: 2493, end: 2511 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'code', + loc: { start: 2584, end: 2588 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2594, end: 2595 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2590, end: 2594 } + }, + loc: { start: 2590, end: 2594 } + } + ], + loc: { start: 2594, end: 2595 } + }, + initializer: { kind: 'null', loc: { start: 2598, end: 2602 } }, + loc: { start: 2584, end: 2602 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'data', + loc: { start: 2722, end: 2726 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 2732, end: 2733 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 2728, end: 2732 } + }, + loc: { start: 2728, end: 2732 } + } + ], + loc: { start: 2732, end: 2733 } + }, + initializer: { kind: 'null', loc: { start: 2736, end: 2740 } }, + loc: { start: 2722, end: 2740 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 2936, end: 2941 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 2943, end: 2946 } + }, + loc: { start: 2943, end: 2946 } + }, + initializer: undefined, + loc: { start: 2936, end: 2946 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'to', + loc: { start: 3009, end: 3011 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3013, end: 3020 } + }, + typeArgs: [], + loc: { start: 3013, end: 3020 } + }, + initializer: undefined, + loc: { start: 3009, end: 3020 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 3186, end: 3192 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 3194, end: 3198 } + }, + typeArgs: [], + loc: { start: 3194, end: 3198 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 3201, end: 3205 } + }, + loc: { start: 3186, end: 3205 } + } + ], + loc: { start: 2253, end: 3208 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'MessageParameters', + loc: { start: 3389, end: 3406 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 3548, end: 3552 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3554, end: 3557 } + }, + loc: { start: 3554, end: 3557 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 3560, end: 3575 } + }, + loc: { start: 3548, end: 3575 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 3625, end: 3629 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 3635, end: 3636 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 3631, end: 3635 } + }, + loc: { start: 3631, end: 3635 } + } + ], + loc: { start: 3635, end: 3636 } + }, + initializer: { kind: 'null', loc: { start: 3639, end: 3643 } }, + loc: { start: 3625, end: 3643 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 3839, end: 3844 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 3846, end: 3849 } + }, + loc: { start: 3846, end: 3849 } + }, + initializer: undefined, + loc: { start: 3839, end: 3849 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'to', + loc: { start: 3912, end: 3914 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 3916, end: 3923 } + }, + typeArgs: [], + loc: { start: 3916, end: 3923 } + }, + initializer: undefined, + loc: { start: 3912, end: 3923 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 4089, end: 4095 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 4097, end: 4101 } + }, + typeArgs: [], + loc: { start: 4097, end: 4101 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 4104, end: 4108 } + }, + loc: { start: 4089, end: 4108 } + } + ], + loc: { start: 3382, end: 4111 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'message', + loc: { start: 5056, end: 5063 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 5064, end: 5070 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'MessageParameters', + loc: { start: 5072, end: 5089 } + }, + typeArgs: [], + loc: { start: 5072, end: 5089 } + }, + loc: { start: 5064, end: 5089 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 106 PUSHINT // 1 + 4 + 4 + 64 + 32 + 1\n' + + ' STZEROES\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + ' STDICT\n' + + ' ENDC\n' + + ' SWAP\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 5048, end: 5588 } + }, + { + kind: 'function', + inline: false, + name: { kind: 'id', text: 'send', loc: { start: 6219, end: 6223 } }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 6224, end: 6230 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'SendParameters', + loc: { start: 6232, end: 6246 } + }, + typeArgs: [], + loc: { start: 6232, end: 6246 } + }, + loc: { start: 6224, end: 6246 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + 'NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' b{000} STSLICECONST // store bounced = false and src = addr_none\n' + + ' STSLICE // store `to`\n' + + ' SWAP\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: `data`\n' + + ' // s2: `code`\n' + + ' // s3: `body`\n' + + ' // s4: `mode`\n' + + '\n' + + ' // Group 2: Placing the Builder after code and data, then checking those for nullability\n' + + ' s2 XCHG0\n' + + ' DUP2\n' + + ' ISNULL\n' + + ' SWAP\n' + + ' ISNULL\n' + + ' AND\n' + + ' // → Stack state\n' + + ' // s0: -1 (true) if `data` and `code` are both null, 0 (false) otherwise\n' + + ' // s1: `code`\n' + + ' // s2: `data`\n' + + ' // s3: Builder\n' + + ' // s4: `body`\n' + + ' // s5: `mode`\n' + + '\n' + + ' // Group 3: Left branch of the IFELSE, executed if s0 is -1 (true)\n' + + ' <{\n' + + ' DROP2 // drop `data` and `code`, since either of those is null\n' + + ' b{0} STSLICECONST\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: Right branch of the IFELSE, executed if s0 is 0 (false)\n' + + ' <{\n' + + ' // _ split_depth:(Maybe (## 5))\n' + + ' // special:(Maybe TickTock)\n' + + ' // code:(Maybe ^Cell)\n' + + ' // data:(Maybe ^Cell)\n' + + ' // library:(Maybe ^Cell)\n' + + ' // = StateInit;\n' + + ' ROT // place message Builder on top\n' + + ' b{10} STSLICECONST // store Maybe = true, Either = false\n' + + ' // Start composing inlined StateInit\n' + + ' b{00} STSLICECONST // store split_depth and special first\n' + + ' STDICT // store code\n' + + ' STDICT // store data\n' + + ' b{0} STSLICECONST // store library\n' + + ' }> PUSHCONT\n' + + '\n' + + ' // Group 3: IFELSE that does the branching shown above\n' + + ' IFELSE\n' + + ' // → Stack state\n' + + ' // s0: Builder\n' + + ' // s1: null or StateInit\n' + + ' // s2: `body`\n' + + ' // s3: `mode`\n' + + '\n' + + ' // Group 4: Finalizing the message\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: `mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG // https://github.com/tact-lang/tact/issues/1558' + ] + }, + loc: { start: 6211, end: 9157 } + }, + { + kind: 'struct_decl', + name: { + kind: 'type_id', + text: 'DeployParameters', + loc: { start: 9347, end: 9363 } + }, + typeParams: [], + fields: [ + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'mode', + loc: { start: 9505, end: 9509 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9511, end: 9514 } + }, + loc: { start: 9511, end: 9514 } + }, + initializer: { + kind: 'var', + name: 'SendDefaultMode', + loc: { start: 9517, end: 9532 } + }, + loc: { start: 9505, end: 9532 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'body', + loc: { start: 9582, end: 9586 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Maybe', + loc: { start: 9592, end: 9593 } + }, + typeArgs: [ + { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 9588, end: 9592 } + }, + loc: { start: 9588, end: 9592 } + } + ], + loc: { start: 9592, end: 9593 } + }, + initializer: { kind: 'null', loc: { start: 9596, end: 9600 } }, + loc: { start: 9582, end: 9600 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'value', + loc: { start: 9796, end: 9801 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 9803, end: 9806 } + }, + loc: { start: 9803, end: 9806 } + }, + initializer: undefined, + loc: { start: 9796, end: 9806 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'bounce', + loc: { start: 9972, end: 9978 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Bool', + loc: { start: 9980, end: 9984 } + }, + typeArgs: [], + loc: { start: 9980, end: 9984 } + }, + initializer: { + kind: 'boolean', + value: true, + loc: { start: 9987, end: 9991 } + }, + loc: { start: 9972, end: 9991 } + }, + { + kind: 'field_decl', + name: { + kind: 'id', + text: 'init', + loc: { start: 10135, end: 10139 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'StateInit', + loc: { start: 10141, end: 10150 } + }, + typeArgs: [], + loc: { start: 10141, end: 10150 } + }, + initializer: undefined, + loc: { start: 10135, end: 10150 } + } + ], + loc: { start: 9340, end: 10153 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'deploy', + loc: { start: 11796, end: 11802 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'params', + loc: { start: 11803, end: 11809 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'DeployParameters', + loc: { start: 11811, end: 11827 } + }, + typeArgs: [], + loc: { start: 11811, end: 11827 } + }, + loc: { start: 11803, end: 11827 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '4 1 BLKPUSH // pushes 2 copies of `init.code` and `init.data`\n' + + ' HASHCU // `init.data` hash\n' + + ' SWAP\n' + + ' HASHCU // `init.code` hash\n' + + ' SWAP2\n' + + ' CDEPTH // `init.data` depth\n' + + ' SWAP\n' + + ' CDEPTH // `init.code` depth\n' + + '\n' + + ' // Group 2: Calculating destination address\n' + + ' // For almost identical logic and instructions,\n' + + ' // see comments inside `contractHash()` function in contract.tact\n' + + ' 131380 INT // (2 << 16) | (1 << 8) | 0x34\n' + + ' NEWC\n' + + ' 24 STU\n' + + ' 16 STU\n' + + ' 16 STU\n' + + ' 256 STU\n' + + ' 256 STU\n' + + ' ONE HASHEXT_SHA256 // obtains hash part (account id) of the address\n' + + ' // → Stack state\n' + + ' // s0: destAddr(hash part)\n' + + ' // s1: `init.data`\n' + + ' // s2: `init.code`\n' + + ' // s3 and below: `bounce`, `value`, `body`, `mode`\n' + + '\n' + + ' // Group 3: Building a message (CommonMsgInfoRelaxed)\n' + + ' s3 XCHG0 // swaps `bounce` with destAddr(hash part)\n' + + ' NEWC\n' + + ' b{01} STSLICECONST // store tag = $0 and ihr_disabled = true\n' + + ' 1 STI // store `bounce`\n' + + ' s1 s2 XCHG // swap `init.data` with `init.code`, placing code on s1\n' + + ' STREF // store `init.code`\n' + + ' STREF // store `init.data`\n' + + ' // Inline StateInit:\n' + + ' b{00010000000000} STSLICECONST\n' + + ' // 0 + 00 + 10 + 0 + 00000000\n' + + ' // 1) 0 - bounced = false\n' + + ' // 2) 00 - src = addr_none\n' + + ' // 3) 10 - tag of addr_std (part of dest)\n' + + ' // 4) 0 - Maybe Anycast = false\n' + + ' // 5) 00000000 - workchain_id (part of dest)\n' + + ' //\n' + + ' 256 STU // store destAddr(hash part)\n' + + ' SWAP // Builder on top, `value` below\n' + + ' STGRAMS // store `value`\n' + + ' 105 PUSHINT // 1 + 4 + 4 + 64 + 32\n' + + ' STZEROES // store currency_collection, ihr_fee, fwd_fee, created_lt and created_at\n' + + '\n' + + ' // Group 4: Continue building a message (CommonMsgInfoRelaxed into MessageRelaxed)\n' + + ' // Remaining bits of MessageRelaxed:\n' + + ' b{1000110} STSLICECONST\n' + + ' // 10 + 0 + 0 + 1 + 1 + 0\n' + + ' // 10 - Maybe (Either StateInit ^StateInit) = true false\n' + + ' // 0 - split_depth:(Maybe (## 5)) = false\n' + + ' // 0 = special:(Maybe TickTock) = false\n' + + ' // 1 = code:(Maybe ^Cell) = true\n' + + ' // 1 = data:(Maybe ^Cell) = true\n' + + ' // 0 = library:(Maybe ^Cell) = false\n' + + ' //\n' + + ' STDICT // store `body` as ref with an extra Maybe bit, since `body` might be null\n' + + ' ENDC // finalize the message\n' + + ' // → Stack state\n' + + ' // s0: Cell\n' + + ' // s1: params.`mode`\n' + + '\n' + + ' // Group 5: Sending the message, with `mode` on top\n' + + ' SWAP\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 11788, end: 14770 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'cashback', + loc: { start: 15971, end: 15979 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'to', + loc: { start: 15980, end: 15982 } + }, + type: { + kind: 'cons_type', + name: { + kind: 'type_id', + text: 'Address', + loc: { start: 15984, end: 15991 } + }, + typeArgs: [], + loc: { start: 15984, end: 15991 } + }, + loc: { start: 15980, end: 15991 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ + '16 PUSHINT // 0x10, i.e. 0x18 but with bounce = false\n' + + ' NEWC\n' + + ' 6 STU // .storeUint(0x10, 6)\n' + + ' STSLICE // .storeAddress(to)\n' + + ' 0 PUSHINT // 0\n' + + ' 111 STUR // .storeUint(0, 111)\n' + + ' // 4 zeros for coins and 107 zeros for lt, fees, etc.\n' + + ' ENDC\n' + + ' 66 PUSHINT // SendRemainingValue | SendIgnoreErrors\n' + + ' SENDRAWMSG' + ] + }, + loc: { start: 15963, end: 16385 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeSendMessage', + loc: { start: 16936, end: 16953 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 16954, end: 16957 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 16959, end: 16963 } + }, + loc: { start: 16959, end: 16963 } + }, + loc: { start: 16954, end: 16963 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 16965, end: 16969 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 16971, end: 16974 } + }, + loc: { start: 16971, end: 16974 } + }, + loc: { start: 16965, end: 16974 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDRAWMSG' ] + }, + loc: { start: 16928, end: 16990 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sendRawMessage', + loc: { start: 17751, end: 17765 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 17766, end: 17769 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 17771, end: 17775 } + }, + loc: { start: 17771, end: 17775 } + }, + loc: { start: 17766, end: 17775 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 17777, end: 17781 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 17783, end: 17786 } + }, + loc: { start: 17783, end: 17786 } + }, + loc: { start: 17777, end: 17786 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDRAWMSG' ] + }, + loc: { start: 17743, end: 17802 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'nativeSendMessageReturnForwardFee', + loc: { start: 19063, end: 19096 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 19120, end: 19123 } + }, + loc: { start: 19120, end: 19123 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 19097, end: 19100 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 19102, end: 19106 } + }, + loc: { start: 19102, end: 19106 } + }, + loc: { start: 19097, end: 19106 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 19108, end: 19112 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 19114, end: 19117 } + }, + loc: { start: 19114, end: 19117 } + }, + loc: { start: 19108, end: 19117 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDMSG' ] + }, + loc: { start: 19055, end: 19135 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'sendMessageReturnForwardFee', + loc: { start: 20186, end: 20213 } + }, + typeParams: [], + returnType: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 20237, end: 20240 } + }, + loc: { start: 20237, end: 20240 } + }, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'msg', + loc: { start: 20214, end: 20217 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 20219, end: 20223 } + }, + loc: { start: 20219, end: 20223 } + }, + loc: { start: 20214, end: 20223 } + }, + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'mode', + loc: { start: 20225, end: 20229 } + }, + type: { + kind: 'TyInt', + format: { + kind: 'FInt', + sign: 'signed', + width: 257, + loc: { start: 20231, end: 20234 } + }, + loc: { start: 20231, end: 20234 } + }, + loc: { start: 20225, end: 20234 } + } + ], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'SENDMSG' ] + }, + loc: { start: 20178, end: 20252 } + }, + { + kind: 'function', + inline: true, + name: { + kind: 'id', + text: 'emit', + loc: { start: 21033, end: 21037 } + }, + typeParams: [], + returnType: undefined, + params: [ + { + kind: 'typed_parameter', + name: { + kind: 'id', + text: 'body', + loc: { start: 21038, end: 21042 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 21044, end: 21048 } + }, + loc: { start: 21044, end: 21048 } + }, + loc: { start: 21038, end: 21048 } + } + ], + body: { + kind: 'regular_body', + statements: [ + { + kind: 'statement_let', + name: { + kind: 'id', + text: 'c', + loc: { start: 21233, end: 21234 } + }, + type: { + kind: 'TyCell', + format: { + kind: 'SFDefault', + loc: { start: 21236, end: 21240 } + }, + loc: { start: 21236, end: 21240 } + }, + expression: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'method_call', + self: { + kind: 'static_call', + function: { + kind: 'id', + text: 'beginCell', + loc: { start: 21243, end: 21252 } + }, + typeArgs: [], + args: [], + loc: { start: 21243, end: 21254 } + }, + method: { + kind: 'id', + text: 'storeUint', + loc: { start: 21264, end: 21273 } + }, + typeArgs: [], + args: [ + { + kind: 'number', + base: '10', + value: 15211807202738752817960438464513n, + loc: { start: 21274, end: 21306 } + }, + { + kind: 'number', + base: '10', + value: 104n, + loc: { start: 21308, end: 21311 } + } + ], + loc: { start: 21243, end: 21312 } + }, + method: { + kind: 'id', + text: 'storeRef', + loc: { start: 21322, end: 21330 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'body', + loc: { start: 21331, end: 21335 } + } + ], + loc: { start: 21243, end: 21336 } + }, + method: { + kind: 'id', + text: 'endCell', + loc: { start: 21346, end: 21353 } + }, + typeArgs: [], + args: [], + loc: { start: 21243, end: 21355 } + }, + loc: { start: 21229, end: 21356 } + }, + { + kind: 'statement_expression', + expression: { + kind: 'static_call', + function: { + kind: 'id', + text: 'sendRawMessage', + loc: { start: 21361, end: 21375 } + }, + typeArgs: [], + args: [ + { + kind: 'var', + name: 'c', + loc: { start: 21376, end: 21377 } + }, + { + kind: 'number', + base: '10', + value: 0n, + loc: { start: 21379, end: 21380 } + } + ], + loc: { start: 21361, end: 21381 } + }, + loc: { start: 21361, end: 21382 } + } + ] + }, + loc: { start: 21022, end: 21384 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'acceptMessage', + loc: { start: 22124, end: 22137 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'ACCEPT' ] + }, + loc: { start: 22116, end: 22150 } + }, + { + kind: 'function', + inline: false, + name: { + kind: 'id', + text: 'commit', + loc: { start: 22638, end: 22644 } + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: 'asm_body', + shuffle: { args: [], ret: [] }, + instructions: [ 'COMMIT' ] + }, + loc: { start: 22630, end: 22657 } + } + ] + } + } +} diff --git a/src/next/ast/generated/root.ts b/src/next/ast/generated/root.ts index b1a9b731bf..723a7487df 100644 --- a/src/next/ast/generated/root.ts +++ b/src/next/ast/generated/root.ts @@ -87,9 +87,9 @@ export const Method = (mutates: boolean, virtual: boolean, override: boolean, ge }); export const isMethod = ($value: Method) => $value.kind === "method"; export type Extension = $.Extension; -export const Extension = (fun: $.Method, selfType: $t.Type): $.Extension => Object.freeze({ +export const Extension = (method: $.Method, selfType: $t.Type): $.Extension => Object.freeze({ kind: "extension", - fun, + method, selfType }); export const isExtension = ($value: Extension) => $value.kind === "extension"; @@ -265,6 +265,7 @@ export const Trait = (name: $c.TypeId, traits: readonly $c.TypeId[], attributes: }); export const isTrait = ($value: Trait) => $value.kind === "trait"; export type ModuleItem = $.ModuleItem; +export type TypeDecl = $.TypeDecl; export type Module = $.Module; export const Module = (imports: readonly $.Import[], items: readonly $.ModuleItem[]): $.Module => Object.freeze({ kind: "module", diff --git a/src/next/ast/root.ts b/src/next/ast/root.ts index 40b056cf30..791062091f 100644 --- a/src/next/ast/root.ts +++ b/src/next/ast/root.ts @@ -32,6 +32,13 @@ export type ModuleItem = | AliasDecl | Contract | Trait; +export type TypeDecl = + | StructDecl + | MessageDecl + | UnionDecl + | AliasDecl + | Contract + | Trait; export type Import = { readonly kind: "import"; readonly importPath: ImportPath; @@ -92,7 +99,7 @@ export type ContractAttribute = { export type Extension = { readonly kind: "extension"; - readonly fun: Method; + readonly method: Method; readonly selfType: Type; }; diff --git a/src/next/index.ts b/src/next/index.ts index df5fc9ac5a..59cd2e489e 100644 --- a/src/next/index.ts +++ b/src/next/index.ts @@ -20,14 +20,14 @@ const main = async () => { const result = await reader.read( path.join(__dirname, "example"), // TODO: parseImportString(root, ImportErrors(log)) when there are CLI/config loggers - "scope2-a.tact", + "scope1-a.tact", ); if (!result) { return; } // dump(result.sources.length); // dump(result); - scope(log, result); + dump(scope(log, result).functions.keys()); }); }); }; diff --git a/src/next/scoping/tc2.ts b/src/next/scoping/tc2.ts index 47c3e91f31..34eaff4c9d 100644 --- a/src/next/scoping/tc2.ts +++ b/src/next/scoping/tc2.ts @@ -1,38 +1,11 @@ -import { entries, makeVisitor, memo } from "@/utils/tricks"; -import type { Range } from "@/next/ast"; +import { entries, memo } from "@/utils/tricks"; import type { Logger, SourceLogger } from "@/error/logger-util"; import type { TactImport, TactSource } from "@/next/imports/source"; import type * as Ast from "@/next/ast"; import { mapValues } from "@/utils/array"; +import type { Range } from "@/next/ast"; const TcErrors = (l: SourceLogger) => ({ - // FIXME - foo: () => (loc: Range) => { - return l.at(loc).error(l.text`Bar`); - }, - - attrNotAllowed: (name: string) => (loc: Range) => { - return l.at(loc).error(l.text`Attribute ${name} not allowed here`); - }, - duplicateParam: () => (loc: Range) => { - return l.at(loc).error(l.text`Duplicate parameter`); - }, - duplicateDecl: () => (loc: Range) => { - return l.at(loc).error(l.text`Duplicate declaration`); - }, - duplicateImport: () => (loc: Range) => { - return l.at(loc).error(l.text`Duplicate import`); - }, - selfImport: () => (loc: Range) => { - return l.at(loc).error(l.text`Cannot self-import`); - }, - mutatesWithoutExtends: () => (loc: Range) => { - return l - .at(loc) - .error( - l.text`Only a method can be mutating. Did you forget "extends"?`, - ); - }, shadowsImported: (name: string, prevPath: string, prevRange: Range) => (loc: Range) => { return l .at(loc) @@ -42,295 +15,127 @@ const TcErrors = (l: SourceLogger) => ({ type TcErrors = ReturnType>; -type SourceScope = Map +type Handler = (children: [T, TactImport][], source: TactSource) => T -export const scope = ( - log: Logger, - root: TactSource, -) => { - const rec = (source: TactSource): SourceScope => { - const logger = log.source(source.path, source.code, (logger) => logger); - const err = TcErrors(logger); - // map with all the currently available functions in current source - const functions: Map = new Map(); - // for every import of current source - for (const imp of source.imports) { - if (imp.kind !== 'tact') { - continue; - } - // get definitions along with the original source - const s = memoedRec(imp.source); - for (const [name, originalSource] of s) { - const prev = functions.get(name); - // prev.source -- original source of top import - // prev.place.loc -- place to complain (second arg) - // originalSource -- original source of bottom import - // imp.loc -- place to complain (first arg) - if (typeof prev === 'undefined') { - functions.set(name, { - source: originalSource, - place: imp, - }); - } else if (prev.source !== originalSource) { - err.shadowsImported( - name, - source.path, - prev.place.loc, - )(imp.loc); - } - } +const combine = (handlers: { [K in keyof O]: Handler }): Handler => { + return (children, source) => { + const result = {} as O; + for (const [key, handler] of entries(handlers)) { + result[key] = handler( + children.map(([o, imp]) => [o[key], imp] as const), + source, + ); } - for (const item of source.items) { - if (item.kind === 'function') { - const { text, loc } = item.name; - const prev = functions.get(text); - if (typeof prev === 'undefined') { - functions.set(text, { - source, - place: item.name, - }); - } else { - err.shadowsImported( - text, - source.path, - prev.place.loc, - )(loc); - } + return result; + }; +}; + +const foldSources = (root: TactSource, onSource: Handler): T => { + const rec = (source: TactSource): T => { + const children: [T, TactImport][] = []; + for (const imp of source.imports) { + if (imp.kind === 'tact') { + children.push([memoedRec(imp.source), imp]); } } - return mapValues(functions, ({ source }) => source); + return onSource(children, source); }; const memoedRec = memo(rec); - memoedRec(root); + return memoedRec(root); }; -// const addId = (set: Set, id: Ast.Id | Ast.TypeId, err: (loc: Range) => void) => { -// if (set.has(id.text)) { -// err(id.loc); -// } else { -// set.add(id.text); -// } -// }; - -// type SourceScope = { -// readonly functions: Map; -// readonly constants: Set; -// readonly types: Set; -// readonly traits: Map; -// readonly contracts: Map; -// } - -// const mergeSourceScope = (scopes: SourceScope[]): SourceScope => { -// const functions: Set = new Set(); -// const constants: Set = new Set(); -// const types: Set = new Set(); -// const traits: Map = new Map(); -// const contracts: Map = new Map(); -// for (const scope of scopes) { -// for (const fn of scope.functions) { -// addId(functions, fn, () => {}); -// } -// } -// return { -// functions, -// constants, -// types, -// traits, -// contracts, -// }; -// }; - -// type LocalScope = { -// readonly constants: Set; -// readonly fields: Set; -// readonly methods: Set; -// } +const getFunctions = (source: TactSource) => { + const ids: Ast.Id[] = []; + for (const item of source.items) { + if (item.kind === 'function') { + ids.push(item.name); + } + } + return ids; +}; -// const scopeAll = (root: TactSource) => { -// const rec = (source: TactSource) => { -// const scope = scopeSource(source); -// const scopes: SourceScope[] = []; -// for (const imp of source.imports) { -// if (imp.kind === 'tact') { -// scopes.push(rec(imp.source)); -// } -// } -// return mergeSourceScope([scope, ]); -// }; -// rec(root); -// }; +const getConstants = (source: TactSource) => { + const ids: Ast.Id[] = []; + for (const item of source.items) { + if (item.kind === 'constant') { + ids.push(item.name); + } + } + return ids; +}; -// const scopeSource = (source: TactSource): SourceScope => { -// const functions: Set = new Set(); -// const constants: Set = new Set(); -// const types: Set = new Set(); -// const traits: Map = new Map(); -// const contracts: Map = new Map(); +const getTypes = (source: TactSource) => { + const ids: Ast.TypeId[] = []; + for (const item of source.items) { + switch (item.kind) { + case "function": + case "extension": + case "constant": + continue; + case "struct_decl": + case "message_decl": + case "union_decl": + case "alias_decl": + case "contract": + case "trait": + ids.push(item.name); + } + } + return ids; +}; +// const getExtensions = (source: TactSource) => { +// const ids: Ast.Id[] = []; // for (const item of source.items) { -// switch (item.kind) { -// case "function": -// addId(functions, item.name, () => {}); -// continue; -// case "extension": -// // ???? -// continue; -// case "constant": -// addId(constants, item.name, () => {}); -// continue; -// case "struct_decl": -// case "message_decl": -// case "union_decl": -// case "alias_decl": -// addId(types, item.name, () => {}); -// continue; -// case "trait": { -// if (traits.has(item.name.text)) { -// // duplicate -// } else { -// traits.set(item.name.text, scopeLocal(item.declarations)); -// } -// continue; -// } -// case "contract": { -// if (contracts.has(item.name.text)) { -// // duplicate -// } else { -// contracts.set(item.name.text, scopeLocal(item.declarations)); -// } -// continue; -// } -// } -// } - -// return { -// functions, -// constants, -// types, -// traits, -// contracts, -// }; -// }; - -// export const scopeLocal = (declarations: readonly Ast.LocalItem[]): LocalScope => { -// const constants: Set = new Set(); -// const fields: Set = new Set(); -// const methods: Set = new Set(); -// for (const decl of declarations) { -// switch (decl.kind) { -// case "field_decl": { -// addId(fields, decl.name, () => {}); -// continue; -// } -// case "method": { -// addId(methods, decl.fun.name, () => {}); -// continue; -// } -// case "receiver": { -// // ??? -// continue; -// } -// case "field_const": { -// addId(constants, decl.body.name, () => {}); -// continue; -// } +// if (item.kind === 'extension') { +// ids.push(item.method.fun.name); // } // } -// return { -// constants, -// fields, -// methods, -// }; +// return ids; // }; -// export const typecheck = (log: Logger, source: TactSource) => { -// const logger = log.source(source.path, source.code, (logger) => logger); -// const err = TcErrors(logger); - -// // get list of all imported tact sources -// const sources: Set = new Set(); -// for (const imp of source.imports) { -// if (imp.kind === "tact") { -// sources.add(imp.source); -// } -// } - -// // combine all items from current source and imported sources -// const importedItems = [...sources].flatMap((source) => source.items); - -// // check imported function shadowing -// const importedFunctionNames: Set = new Set(); -// for (const item of importedItems) { -// if (item.kind === "function") { -// const name = item.name.text; -// if (importedFunctionNames.has(name)) { -// err.functionShadowsImported()(item.name.loc); -// } else { -// importedFunctionNames.add(name); -// } -// } -// } - -// for (const item of source.items) { -// switch (item.kind) { -// case "function": { -// const { -// body, -// name, -// params, -// returnType, -// typeParams -// } = item; -// } -// case "extension": -// case "constant_def": -// case "struct_decl": -// case "message_decl": -// case "union_decl": -// case "alias_decl": -// case "contract": -// case "trait": -// } -// } - -// // Duplicate function definition -// // (imports* AsmFunctionDef name) . size > 1 - -// // Duplicate parameter -// // asm fun f(x: Int, x: Foo) {} -// // (Source AsmFunctionDef params name) . size > 1 - -// // Type is not defined -// // asm fun f(x: Nonexist) {} -// // AsmFunctionDef (params type | retType) Type/TypeCons: -// // .name !in (imports* TypeDecl name | .typeParams) - -// // `F` expects 1 argument. Passed 2 arguments. -// // struct F {} asm fun f(x: F) {} -// // AsmFunctionDef (params type | retType) Type/TypeCons typeArgs length -// // != imports* TypeDecl typeParams length - -// // `F` type parameter is shadowing globally defined type -// // struct F {} asm fun f(x: F) {} -// // AsmFunctionDef typeParams name -// // in imports* TypeDecl name - -// // TypeDecl = StructDecl | MessageDecl | UnionDecl | AliasDecl | Contract | Trait - -// // Duplicate type parameter -// // (Source AsmFunctionDef typeParams name) . size > 1 +export type ResolvedSource = { + readonly path: string; + readonly code: string; + readonly imports: readonly ResolvedSource[]; + readonly functions: ReadonlyMap; + readonly extensions: ReadonlyMap; + readonly constants: ReadonlyMap; + readonly types: ReadonlyMap; +}; -// // Shuffle must be a permutation of all function parameters -// // asm(c c) extends fun f(self: Builder, c: Cell?) {} -// // AsmFunctionDef: (.shuffle args text).sort() = (.params name text).sort() +const scopeIds = ( + log: Logger, + getIds: (source: TactSource) => { text: string, loc: Ast.Range }[] +): Handler> => (children, source) => { + const err = log.source(source.path, source.code, (logger) => TcErrors(logger)); + const ids: Map = new Map(); + const addId = (name: string, nextSource: TactSource, loc: Range) => { + const prev = ids.get(name); + if (typeof prev === 'undefined') { + ids.set(name, { source: nextSource, loc }); + } else if (prev.source !== nextSource) { + err.shadowsImported(name, source.path, prev.loc)(loc); + } + }; + for (const [sources, imp] of children) { + for (const [name, source] of sources) { + addId(name, source, imp.loc); + } + } + for (const { text: name, loc } of getIds(source)) { + addId(name, source, loc); + } + return mapValues(ids, ({ source }) => source); +}; -// // extends fun попадают в скоуп self -// // trait A { abstract fun f(): Int; } -// // contract B {} -// // override extends asm fun f(self: B): Int {} -// }; +export const scope = ( + log: Logger, + root: TactSource, +) => { + return foldSources(root, combine({ + functions: scopeIds(log, getFunctions), + constants: scopeIds(log, getConstants), + types: scopeIds(log, getTypes), + })); +}; From 272b86f3716d3591af106be5e361d164570594dc Mon Sep 17 00:00:00 2001 From: verytactical <186486509+verytactical@users.noreply.github.com> Date: Thu, 8 May 2025 22:37:53 +0400 Subject: [PATCH 17/38] 1 --- find | 0 src/next/ast/common.ts | 3 + src/next/ast/generated/common.ts | 20 +- src/next/grammar/index.ts | 308 +++++------ src/next/imports/reader.ts | 6 +- src/next/imports/source.ts | 6 +- src/next/scoping/const.ts | 180 ------ src/next/scoping/errors.ts | 123 +++++ src/next/scoping/generated/type.ts | 189 +++++++ src/next/scoping/print-type.ts | 52 ++ src/next/scoping/scoped-ast.ts | 73 --- src/next/scoping/tc.ts | 179 ------ src/next/scoping/tc2.ts | 141 ----- src/next/scoping/type.ts | 155 ++++++ src/next/scoping/typecheck.ts | 851 +++++++++++++++++++++++++++++ src/utils/array.ts | 2 +- src/utils/tricks.ts | 67 ++- 17 files changed, 1587 insertions(+), 768 deletions(-) create mode 100644 find delete mode 100644 src/next/scoping/const.ts create mode 100644 src/next/scoping/errors.ts create mode 100644 src/next/scoping/generated/type.ts create mode 100644 src/next/scoping/print-type.ts delete mode 100644 src/next/scoping/scoped-ast.ts delete mode 100644 src/next/scoping/tc.ts delete mode 100644 src/next/scoping/tc2.ts create mode 100644 src/next/scoping/type.ts create mode 100644 src/next/scoping/typecheck.ts diff --git a/find b/find new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/next/ast/common.ts b/src/next/ast/common.ts index fc17fd28d8..391d829ef9 100644 --- a/src/next/ast/common.ts +++ b/src/next/ast/common.ts @@ -1,6 +1,9 @@ export type Range = { + readonly kind: "range"; readonly start: number; readonly end: number; + readonly path: string; + readonly code: string; }; export type OptionalId = Id | Wildcard; diff --git a/src/next/ast/generated/common.ts b/src/next/ast/generated/common.ts index 0f5e9479f5..f2e484f3d7 100644 --- a/src/next/ast/generated/common.ts +++ b/src/next/ast/generated/common.ts @@ -1,11 +1,27 @@ /* eslint-disable @typescript-eslint/no-unnecessary-condition */ import type * as $ from "@/next/ast/common"; export type Range = $.Range; -export const Range = (start: number, end: number): $.Range => - Object.freeze({ +export const Range = ( + start: number, + end: number, + path: string, + code: string, +): Range => { + const result: Range = { + kind: "range", start, end, + path, + code, + }; + Object.defineProperty(result, 'code', { + value: code, + writable: true, + configurable: true, + enumerable: false, }); + return Object.freeze(result); +}; export type Id = $.Id; export const Id = (text: string, loc: $.Range): $.Id => Object.freeze({ diff --git a/src/next/grammar/index.ts b/src/next/grammar/index.ts index 3fcfaffff5..08b5979b3c 100644 --- a/src/next/grammar/index.ts +++ b/src/next/grammar/index.ts @@ -11,23 +11,19 @@ import { parseImportString } from "@/next/grammar/import-parser"; const makeVisitor = makeMakeVisitor("$"); -const toRange = (loc: $.Loc): Ast.Range => { - if (loc.$ === "empty") { - return throwInternal("Lookahead at top level"); - } - const { start, end } = loc; - return { start, end }; -}; - const mergeRange = (left: Ast.Range, right: Ast.Range): Ast.Range => { if (left.start > right.end) { return throwInternal("Invalid range merge"); } - return { start: left.start, end: right.end }; + if (left.path !== right.path) { + return throwInternal("Merging ranges from different sources"); + } + return Ast.Range(left.start, right.end, left.path, left.code); }; type Context = { - err: SyntaxErrors; + readonly err: SyntaxErrors; + readonly toRange: (loc: $.Loc) => Ast.Range; }; type Handler = (ctx: Context) => T; @@ -50,45 +46,45 @@ const parseId = ({ name, loc }: $ast.Id | $ast.TypeId): Handler => (ctx) => { if (name.startsWith("__gen")) { - ctx.err.reservedVarPrefix("__gen")(toRange(loc)); + ctx.err.reservedVarPrefix("__gen")(ctx.toRange(loc)); } if (name.startsWith("__tact")) { - ctx.err.reservedVarPrefix("__tact")(toRange(loc)); + ctx.err.reservedVarPrefix("__tact")(ctx.toRange(loc)); } if (name === "_") { - ctx.err.noWildcard()(toRange(loc)); + ctx.err.noWildcard()(ctx.toRange(loc)); } - return Ast.Id(name, toRange(loc)); + return Ast.Id(name, ctx.toRange(loc)); }; const parseOptionalId = ({ name, loc }: $ast.Id | $ast.TypeId): Handler => (ctx) => { if (name.startsWith("__gen")) { - ctx.err.reservedVarPrefix("__gen")(toRange(loc)); + ctx.err.reservedVarPrefix("__gen")(ctx.toRange(loc)); } if (name.startsWith("__tact")) { - ctx.err.reservedVarPrefix("__tact")(toRange(loc)); + ctx.err.reservedVarPrefix("__tact")(ctx.toRange(loc)); } if (name === "_") { - return Ast.Wildcard(toRange(loc)); + return Ast.Wildcard(ctx.toRange(loc)); } - return Ast.Id(name, toRange(loc)); + return Ast.Id(name, ctx.toRange(loc)); }; const parseVar = ({ name, loc }: $ast.Id): Handler => (ctx) => { if (name.startsWith("__gen")) { - ctx.err.reservedVarPrefix("__gen")(toRange(loc)); + ctx.err.reservedVarPrefix("__gen")(ctx.toRange(loc)); } if (name.startsWith("__tact")) { - ctx.err.reservedVarPrefix("__tact")(toRange(loc)); + ctx.err.reservedVarPrefix("__tact")(ctx.toRange(loc)); } if (name === "_") { - ctx.err.noWildcard()(toRange(loc)); + ctx.err.noWildcard()(ctx.toRange(loc)); } - return Ast.Var(name, toRange(loc)); + return Ast.Var(name, ctx.toRange(loc)); }; /* @@ -194,15 +190,15 @@ const parseFuncId = ({ accessor, id, loc }: $ast.FuncId): Handler => (ctx) => { if (reservedFuncIds.has(id)) { - ctx.err.reservedFuncId()(toRange(loc)); + ctx.err.reservedFuncId()(ctx.toRange(loc)); } if (id.match(/^-?([0-9]+|0x[0-9a-fA-F]+)$/)) { - ctx.err.numericFuncId()(toRange(loc)); + ctx.err.numericFuncId()(ctx.toRange(loc)); } if (id.startsWith('"') || id.startsWith("{-")) { - ctx.err.invalidFuncId()(toRange(loc)); + ctx.err.invalidFuncId()(ctx.toRange(loc)); } - return Ast.FuncId((accessor ?? "") + id, toRange(loc)); + return Ast.FuncId((accessor ?? "") + id, ctx.toRange(loc)); }; const baseMap = { @@ -227,10 +223,10 @@ const parseIntegerLiteralValue = digits.startsWith("0") && digits.includes("_") ) { - ctx.err.leadingZeroUnderscore()(toRange(loc)); + ctx.err.leadingZeroUnderscore()(ctx.toRange(loc)); } const value = BigInt(prefixMap[$] + digits.replaceAll("_", "")); - return Ast.Number(baseMap[$], value, toRange(loc)); + return Ast.Number(baseMap[$], value, ctx.toRange(loc)); }; const parseIntegerLiteral = @@ -243,7 +239,7 @@ const parseStringLiteral = ({ value, loc }: $ast.StringLiteral): Handler => (ctx) => { const simplifiedValue = replaceEscapeSequences(value, loc, ctx); - return Ast.String(simplifiedValue, toRange(loc)); + return Ast.String(simplifiedValue, ctx.toRange(loc)); }; export function replaceEscapeSequences( @@ -276,7 +272,7 @@ export function replaceEscapeSequences( if (unicodeCodePoint) { const codePoint = parseInt(unicodeCodePoint, 16); if (codePoint > 0x10ffff) { - ctx.err.undefinedUnicodeCodepoint()(toRange(loc)); + ctx.err.undefinedUnicodeCodepoint()(ctx.toRange(loc)); return match; } return String.fromCodePoint(codePoint); @@ -299,14 +295,14 @@ export function replaceEscapeSequences( const parseBoolLiteral = ({ value, loc }: $ast.BoolLiteral): Handler => - (_ctx) => { - return Ast.Boolean(value === "true", toRange(loc)); + (ctx) => { + return Ast.Boolean(value === "true", ctx.toRange(loc)); }; const parseNull = ({ loc }: $ast.Null): Handler => - (_ctx) => { - return Ast.Null(toRange(loc)); + (ctx) => { + return Ast.Null(ctx.toRange(loc)); }; const parseStructFieldInitializer = @@ -322,7 +318,7 @@ const parseStructFieldInitializer = return Ast.StructFieldInitializer( fieldId, init ? parseExpression(init)(ctx) : parseVar(name)(ctx), - toRange(loc), + ctx.toRange(loc), ); }; @@ -338,7 +334,7 @@ const parseStructInstance = parseTypeId(type)(ctx), map(parseList(typeArgs), parseType)(ctx), map(parseList(fields), parseStructFieldInitializer)(ctx), - toRange(loc), + ctx.toRange(loc), ); }; @@ -366,7 +362,7 @@ const parseMapArgs = const parseMapLiteral = ({ typeArgs, fields, loc }: $ast.MapLiteral): Handler => (ctx) => { - const range = toRange(loc); + const range = ctx.toRange(loc); return Ast.MapLiteral( parseMapArgs(typeArgs, range)(ctx), map(parseList(fields), parseMapField)(ctx), @@ -407,7 +403,7 @@ const parseSetArgs = const parseSetLiteral = ({ typeArgs, fields, loc }: $ast.SetLiteral): Handler => (ctx) => { - const range = toRange(loc); + const range = ctx.toRange(loc); return Ast.SetLiteral( parseSetArgs(typeArgs, range)(ctx), map(parseList(fields), parseExpression)(ctx), @@ -421,14 +417,14 @@ const parseInitOf = return Ast.InitOf( parseTypeId(name)(ctx), map(parseList(params), parseExpression)(ctx), - toRange(loc), + ctx.toRange(loc), ); }; const parseCodeOf = ({ name, loc }: $ast.CodeOf): Handler => (ctx) => { - return Ast.CodeOf(parseTypeId(name)(ctx), toRange(loc)); + return Ast.CodeOf(parseTypeId(name)(ctx), ctx.toRange(loc)); }; const parseConditional = @@ -443,7 +439,7 @@ const parseConditional = condition, parseExpression(thenBranch)(ctx), parseExpression(elseBranch)(ctx), - toRange(loc), + ctx.toRange(loc), ); }; @@ -456,7 +452,7 @@ const parseBinary = ({ child, range }, { op, right }) => { const merged = mergeRange( range, - mergeRange(toRange(op.loc), toRange(right.loc)), + mergeRange(ctx.toRange(op.loc), ctx.toRange(right.loc)), ); return { child: Ast.OpBinary( @@ -468,7 +464,7 @@ const parseBinary = range: merged, }; }, - { child: parseExpression(head)(ctx), range: toRange(head.loc) }, + { child: parseExpression(head)(ctx), range: ctx.toRange(head.loc) }, ).child; }; @@ -477,7 +473,7 @@ const parseUnary = (ctx) => { return prefixes.reduceRight( ({ child, range }, { name, loc }) => { - const merged = mergeRange(toRange(loc), range); + const merged = mergeRange(ctx.toRange(loc), range); return { child: Ast.OpUnary(name, child, merged), range: merged, @@ -485,7 +481,7 @@ const parseUnary = }, { child: parseExpression(expression)(ctx), - range: toRange(expression.loc), + range: ctx.toRange(expression.loc), }, ).child; }; @@ -551,7 +547,7 @@ const parseSuffix = (ctx) => { return suffixes.reduce( ({ child, range }, suffix) => { - const merged = mergeRange(range, toRange(suffix.loc)); + const merged = mergeRange(range, ctx.toRange(suffix.loc)); return { child: suffixVisitor(suffix)(ctx)(child, merged), range: merged, @@ -559,15 +555,15 @@ const parseSuffix = }, { child: parseExpression(expression)(ctx), - range: toRange(expression.loc), + range: ctx.toRange(expression.loc), }, ).child; }; const parseUnit = ({ loc }: $ast.Unit): Handler => - (_ctx) => { - return Ast.Unit(toRange(loc)); + (ctx) => { + return Ast.Unit(ctx.toRange(loc)); }; const parseTensor = @@ -575,7 +571,7 @@ const parseTensor = (ctx) => { return Ast.Tensor( map([head, ...tail], parseExpression)(ctx), - toRange(loc), + ctx.toRange(loc), ); }; @@ -584,7 +580,7 @@ const parseTuple = (ctx) => { return Ast.Tuple( map(parseList(types), parseExpression)(ctx), - toRange(loc), + ctx.toRange(loc), ); }; @@ -645,7 +641,7 @@ const parseStatementLet = parseOptionalId(name)(ctx), type ? parseType(type)(ctx) : undefined, parseExpression(init)(ctx), - toRange(loc), + ctx.toRange(loc), ); }; @@ -686,7 +682,7 @@ const parseStatementDestruct = const [field] = pair; const name = field.text; if (ids.has(name)) { - ctx.err.duplicateField(name)(toRange(param.loc)); + ctx.err.duplicateField(name)(ctx.toRange(param.loc)); } ids.set(name, pair); } @@ -696,14 +692,14 @@ const parseStatementDestruct = ids, rest.$ === "RestArgument", parseExpression(init)(ctx), - toRange(loc), + ctx.toRange(loc), ); }; const parseStatementBlock = ({ body, loc }: $ast.StatementBlock): Handler => (ctx) => { - return Ast.StatementBlock(parseStatements(body)(ctx), toRange(loc)); + return Ast.StatementBlock(parseStatements(body)(ctx), ctx.toRange(loc)); }; const parseStatementReturn = @@ -711,7 +707,7 @@ const parseStatementReturn = (ctx) => { return Ast.StatementReturn( expression ? parseExpression(expression)(ctx) : undefined, - toRange(loc), + ctx.toRange(loc), ); }; @@ -728,21 +724,21 @@ const parseStatementCondition = parseExpression(condition)(ctx), parseStatements(trueBranch)(ctx), undefined, - toRange(loc), + ctx.toRange(loc), ); } else if (falseBranch.$ === "FalseBranch") { return Ast.StatementCondition( parseExpression(condition)(ctx), parseStatements(trueBranch)(ctx), parseStatements(falseBranch.body)(ctx), - toRange(loc), + ctx.toRange(loc), ); } else { return Ast.StatementCondition( parseExpression(condition)(ctx), parseStatements(trueBranch)(ctx), [parseStatementCondition(falseBranch)(ctx)], - toRange(loc), + ctx.toRange(loc), ); } }; @@ -757,7 +753,7 @@ const parseStatementWhile = return Ast.StatementWhile( parseExpression(condition)(ctx), parseStatements(body)(ctx), - toRange(loc), + ctx.toRange(loc), ); }; @@ -771,7 +767,7 @@ const parseStatementRepeat = return Ast.StatementRepeat( parseExpression(condition)(ctx), parseStatements(body)(ctx), - toRange(loc), + ctx.toRange(loc), ); }; @@ -785,7 +781,7 @@ const parseStatementUntil = return Ast.StatementUntil( parseExpression(condition)(ctx), parseStatements(body)(ctx), - toRange(loc), + ctx.toRange(loc), ); }; @@ -799,13 +795,13 @@ const parseStatementTry = catchName: parseOptionalId(handler.name)(ctx), catchStatements: parseStatements(handler.body)(ctx), }, - toRange(loc), + ctx.toRange(loc), ); } else { return Ast.StatementTry( parseStatements(body)(ctx), undefined, - toRange(loc), + ctx.toRange(loc), ); } }; @@ -824,7 +820,7 @@ const parseStatementForEach = parseOptionalId(value)(ctx), parseExpression(expression)(ctx), parseStatements(body)(ctx), - toRange(loc), + ctx.toRange(loc), ); }; @@ -836,7 +832,7 @@ const parseStatementExpression = (ctx) => { return Ast.StatementExpression( parseExpression(expression)(ctx), - toRange(loc), + ctx.toRange(loc), ); }; @@ -854,14 +850,14 @@ const parseStatementAssign = return Ast.StatementAssign( parseExpression(left)(ctx), parseExpression(right)(ctx), - toRange(loc), + ctx.toRange(loc), ); } else { return Ast.StatementAugmentedAssign( operator, parseExpression(left)(ctx), parseExpression(right)(ctx), - toRange(loc), + ctx.toRange(loc), ); } }; @@ -905,11 +901,11 @@ const parseGetAttribute = return undefined; } for (const attr of tail) { - ctx.err.function.duplicate("get")(toRange(attr.loc)); + ctx.err.function.duplicate("get")(ctx.toRange(attr.loc)); } return Ast.GetAttribute( head.methodId ? parseExpression(head.methodId)(ctx) : undefined, - toRange(head.loc), + ctx.toRange(head.loc), ); }; @@ -930,7 +926,7 @@ const parseNamedAttr = const attrs: Range[] = []; for (const node of nodes) { if (typeof node.name === "string" && node.name === key) { - attrs.push(toRange(node.loc)); + attrs.push(ctx.toRange(node.loc)); } } const [head, ...tail] = attrs; @@ -950,24 +946,24 @@ const parseParameter = return Ast.TypedParameter( parseOptionalId(name)(ctx), parseType(type)(ctx), - toRange(loc), + ctx.toRange(loc), ); }; const parseTypeId = ({ name, loc }: $ast.TypeId): Handler => - (_ctx) => { - return Ast.TypeId(name, toRange(loc)); + (ctx) => { + return Ast.TypeId(name, ctx.toRange(loc)); }; const parseTypeStorage = ({ child: storage, loc }: $ast.TypeStorage): Handler => (ctx) => { - const range = toRange(loc); + const range = ctx.toRange(loc); const fallback = Ast.TypeCons(Ast.TypeId("ERROR", range), [], range); if (storage.$ === "CoinsStorage") { return Ast.TypeInt( - Ast.IFVarInt("unsigned", "16", toRange(storage.loc)), + Ast.IFVarInt("unsigned", "16", ctx.toRange(storage.loc)), range, ); } else if (storage.$ === "IntStorage") { @@ -980,7 +976,7 @@ const parseTypeStorage = ? "signed" : "unsigned", "16", - toRange(storage.loc), + ctx.toRange(storage.loc), ), range, ); @@ -991,7 +987,7 @@ const parseTypeStorage = ? "signed" : "unsigned", "32", - toRange(storage.loc), + ctx.toRange(storage.loc), ), range, ); @@ -1045,7 +1041,7 @@ const applyFormat = if (type.kind === "TyInt") { if (storage.$ === "CoinsStorage") { return Ast.TypeInt( - Ast.IFVarInt("unsigned", "16", toRange(storage.loc)), + Ast.IFVarInt("unsigned", "16", ctx.toRange(storage.loc)), type.loc, ); } else if (storage.$ === "IntStorage") { @@ -1058,7 +1054,7 @@ const applyFormat = ? "signed" : "unsigned", "16", - toRange(storage.loc), + ctx.toRange(storage.loc), ), type.loc, ); @@ -1069,7 +1065,7 @@ const applyFormat = ? "signed" : "unsigned", "32", - toRange(storage.loc), + ctx.toRange(storage.loc), ), type.loc, ); @@ -1154,14 +1150,14 @@ const parseTypeAs = return parseType(type)(ctx); } if (as.length > 1) { - ctx.err.duplicateAs()(toRange(loc)); + ctx.err.duplicateAs()(ctx.toRange(loc)); return Ast.TypeCons( - Ast.TypeId("ERROR", toRange(loc)), + Ast.TypeId("ERROR", ctx.toRange(loc)), [], - toRange(loc), + ctx.toRange(loc), ); } - const asLoc = toRange(loc); + const asLoc = ctx.toRange(loc); const result = parseType(type)(ctx); return applyFormat(result, onlyAs, asLoc)(ctx); }; @@ -1180,9 +1176,9 @@ const parseTypeGeneric = ({ name, args, loc }: $ast.TypeGeneric): Handler => (ctx) => { return Ast.TypeCons( - Ast.TypeId(flattenName(name), toRange(name.loc)), + Ast.TypeId(flattenName(name), ctx.toRange(name.loc)), map(parseList(args), parseTypeAs)(ctx), - toRange(loc), + ctx.toRange(loc), ); }; @@ -1191,9 +1187,9 @@ const parseTypeOptional = (ctx) => { return optionals.reduce((acc, optional) => { return Ast.TypeCons( - Ast.TypeId("Maybe", toRange(optional.loc)), + Ast.TypeId("Maybe", ctx.toRange(optional.loc)), [acc], - toRange(optional.loc), + ctx.toRange(optional.loc), ); }, parseType(type)(ctx)); }; @@ -1201,7 +1197,7 @@ const parseTypeOptional = const parseTypeRegular = ({ child }: $ast.TypeRegular): Handler => (ctx) => { - const range = toRange(child.loc); + const range = ctx.toRange(child.loc); if (child.name === "Int") { return Ast.TypeInt(Ast.IFInt("signed", 257, range), range); } else if (child.name === "Slice") { @@ -1219,7 +1215,7 @@ const parseTypeTensor = (ctx) => { return Ast.TypeTensor( map([head, ...tail], parseType)(ctx), - toRange(loc), + ctx.toRange(loc), ); }; @@ -1228,14 +1224,14 @@ const parseTypeTuple = (ctx) => { return Ast.TypeTuple( map(parseList(types), parseType)(ctx), - toRange(loc), + ctx.toRange(loc), ); }; const parseTypeUnit = ({ loc }: $ast.TypeUnit): Handler => - (_ctx) => { - return Ast.TypeUnit(toRange(loc)); + (ctx) => { + return Ast.TypeUnit(ctx.toRange(loc)); }; type RawType = @@ -1266,7 +1262,7 @@ const parseFieldDecl = parseId(name)(ctx), parseType(type)(ctx), expression ? parseExpression(expression)(ctx) : undefined, - toRange(loc), + ctx.toRange(loc), ); }; @@ -1280,16 +1276,16 @@ const parseReceiverParam = : Ast.ReceiverComment(parseStringLiteral(param)(ctx)); }; -const parseReceiverReceive = +const parseReceiverInternal = ({ type, param, body, loc }: $ast.Receiver): Handler => (ctx) => { return Ast.Receiver( Ast.ReceiverInternal( parseReceiverParam(param)(ctx), - toRange(type.loc), + ctx.toRange(type.loc), ), map(body, parseStatement)(ctx), - toRange(loc), + ctx.toRange(loc), ); }; @@ -1299,10 +1295,10 @@ const parseReceiverExternal = return Ast.Receiver( Ast.ReceiverExternal( parseReceiverParam(param)(ctx), - toRange(type.loc), + ctx.toRange(type.loc), ), map(body, parseStatement)(ctx), - toRange(loc), + ctx.toRange(loc), ); }; @@ -1340,19 +1336,19 @@ const parseReceiverBounced = ({ type, param, body, loc }: $ast.Receiver): Handler => (ctx) => { if (typeof param === "undefined") { - ctx.err.noBouncedWithoutArg()(toRange(loc)); + ctx.err.noBouncedWithoutArg()(ctx.toRange(loc)); param = repairParam; } if (param.$ === "StringLiteral") { - ctx.err.noBouncedWithString()(toRange(loc)); + ctx.err.noBouncedWithString()(ctx.toRange(loc)); param = repairParam; } return Ast.Receiver( - Ast.ReceiverBounce(parseParameter(param)(ctx), toRange(type.loc)), + Ast.ReceiverBounce(parseParameter(param)(ctx), ctx.toRange(type.loc)), map(body, parseStatement)(ctx), - toRange(loc), + ctx.toRange(loc), ); }; @@ -1361,7 +1357,7 @@ const parserByReceiverType: Record< (node: $ast.Receiver) => Handler > = { bounced: parseReceiverBounced, - receive: parseReceiverReceive, + receive: parseReceiverInternal, external: parseReceiverExternal, }; @@ -1399,7 +1395,7 @@ const parseAsmFunctionRaw = Ast.AsmBody(parseAsmShuffle(node.shuffle)(ctx), [ node.instructions.trim(), ]), - toRange(node.loc), + ctx.toRange(node.loc), ); }; @@ -1448,7 +1444,7 @@ const parseConstant = (node: $ast.Constant): Handler => (ctx) => { const name = parseId(node.name)(ctx); - const range = toRange(node.loc); + const range = ctx.toRange(node.loc); const type = (() => { if (node.body.$ === "ConstantDefinition") { return Ast.ConstantDef( @@ -1468,7 +1464,7 @@ const parseConstant = const parseConstantGlobal = (node: $ast.Constant): Handler => (ctx) => { - checkNoGlobalAttrs(node.attributes, toRange(node.loc))(ctx); + checkNoGlobalAttrs(node.attributes, ctx.toRange(node.loc))(ctx); return parseConstant(node)(ctx); }; @@ -1479,7 +1475,7 @@ const parseFieldConstant = const inh = parseInheritance( body.init.kind === 'constant_def', node.attributes, - toRange(node.loc), + ctx.toRange(node.loc), )(ctx); return Ast.FieldConstant(inh.virtual, inh.override, body); }; @@ -1517,14 +1513,14 @@ const parseContract = } const [initFn, ...restInitFns] = initFns; for (const fn of restInitFns) { - ctx.err.tooMuchInit()(toRange(fn.loc)); + ctx.err.tooMuchInit()(ctx.toRange(fn.loc)); } const init = (() => { if (typeof parameters !== "undefined") { // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (initFn) { - ctx.err.initFnAndParams()(toRange(initFn.loc)); + ctx.err.initFnAndParams()(ctx.toRange(initFn.loc)); } return Ast.InitParams(params); // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition @@ -1532,7 +1528,7 @@ const parseContract = return Ast.InitFunction( map(parseList(initFn.parameters), parseParameter)(ctx), map(initFn.body, parseStatement)(ctx), - toRange(loc), + ctx.toRange(loc), ); } else { return undefined; @@ -1545,44 +1541,26 @@ const parseContract = map(attributes, parseContractAttribute)(ctx), init, map(locals, parseLocalItem)(ctx), - toRange(loc), + ctx.toRange(loc), ); }; const parseFunctionRaw = (node: $ast.$Function): Handler => (ctx) => { - const name = parseId(node.name)(ctx); - const returnType = node.returnType - ? parseType(node.returnType)(ctx) - : undefined; - const typeParams = map(parseList(node.typeParams), parseTypeId)(ctx); - const parameters = map(parseList(node.parameters), parseParameter)(ctx); - - if (node.body.$ === "FunctionDeclaration") { - const inline = !!parseNamedAttr("inline")(node.attributes)(ctx); - return Ast.Function( - inline, - name, - typeParams, - returnType, - parameters, - Ast.AbstractBody(), - toRange(node.loc), - ); - } else { - const inline = !!parseNamedAttr("inline")(node.attributes)(ctx); - const statements = map(node.body.body, parseStatement)(ctx); - return Ast.Function( - inline, - name, - typeParams, - returnType, - parameters, - Ast.RegularBody(statements), - toRange(node.loc), - ); - } + return Ast.Function( + !!parseNamedAttr("inline")(node.attributes)(ctx), + parseId(node.name)(ctx), + map(parseList(node.typeParams), parseTypeId)(ctx), + node.returnType + ? parseType(node.returnType)(ctx) + : undefined, + map(parseList(node.parameters), parseParameter)(ctx), + node.body.$ === "FunctionDeclaration" + ? Ast.AbstractBody() + : Ast.RegularBody(map(node.body.body, parseStatement)(ctx)), + ctx.toRange(node.loc), + ); }; const parseExtension = @@ -1596,7 +1574,7 @@ const parseExtension = if (get) { ctx.err.globalGetter()(get.loc); } - checkNoGlobalAttrs(node.attributes, toRange(node.loc))(ctx); + checkNoGlobalAttrs(node.attributes, ctx.toRange(node.loc))(ctx); const isMutates = parseNamedAttr("mutates")(node.attributes)(ctx); const isExtends = parseNamedAttr("extends")(node.attributes)(ctx); if (!isExtends) { @@ -1613,7 +1591,7 @@ const parseExtension = first.name.kind !== "id" || first.name.text !== "self" ) { - const range = toRange(node.loc); + const range = ctx.toRange(node.loc); ctx.err.extendsSelf()(range); return Ast.TypeCons(Ast.TypeId("ERROR", range), [], range); } @@ -1642,12 +1620,12 @@ const parseMethod = const inh = parseInheritance( fn.body.kind !== 'abstract_body', node.attributes, - toRange(node.loc), + ctx.toRange(node.loc), )(ctx); const isMutates = parseNamedAttr("mutates")(node.attributes)(ctx); const isExtends = parseNamedAttr("extends")(node.attributes)(ctx); if (isExtends) { - ctx.err.localExtends()(toRange(node.loc)); + ctx.err.localExtends()(ctx.toRange(node.loc)); } return Ast.Method( !!isMutates, @@ -1670,7 +1648,7 @@ const parseMessageDecl = parseTypeId(name)(ctx), opcode ? parseExpression(opcode)(ctx) : undefined, map(parseList(fields), parseFieldDecl)(ctx), - toRange(loc), + ctx.toRange(loc), ); }; @@ -1692,7 +1670,7 @@ const parseNativeFunctionDecl = returnType ? parseType(returnType)(ctx) : undefined, map(parseList(parameters), parseParameter)(ctx), Ast.NativeBody(parseFuncId(nativeName)(ctx)), - toRange(loc), + ctx.toRange(loc), ); }; @@ -1703,7 +1681,7 @@ const parseAlias = parseTypeId(name)(ctx), map(parseList(typeParams), parseTypeId)(ctx), parseType(type)(ctx), - toRange(loc), + ctx.toRange(loc), ); }; @@ -1719,7 +1697,7 @@ const parseUnion = parseTypeId(name)(ctx), map(parseList(typeParams), parseTypeId)(ctx), map(cases, parseUnionCase)(ctx), - toRange(loc), + ctx.toRange(loc), ); }; @@ -1744,7 +1722,7 @@ const parseStructDecl = parseTypeId(name)(ctx), map(parseList(typeParams), parseTypeId)(ctx), map(parseList(fields), parseFieldDecl)(ctx), - toRange(loc), + ctx.toRange(loc), ); }; @@ -1753,7 +1731,7 @@ const parseContractAttribute = (ctx) => { return Ast.ContractAttribute( parseStringLiteral(name)(ctx).value, - toRange(loc), + ctx.toRange(loc), ); }; @@ -1771,7 +1749,7 @@ const parseTrait = traits ? map(parseList(traits), parseTypeId)(ctx) : [], map(attributes, parseContractAttribute)(ctx), map(declarations, parseLocalItem)(ctx), - toRange(loc), + ctx.toRange(loc), ); }; const parseLocalItem: ( @@ -1804,7 +1782,7 @@ const parseModuleItem = (node: $ast.moduleItem): Handler => (ctx) => { if (node.$ === "PrimitiveTypeDecl") { - ctx.err.deprecatedPrimitiveDecl()(toRange(node.loc)); + ctx.err.deprecatedPrimitiveDecl()(ctx.toRange(node.loc)); return []; } return [parseModuleItemAux(node)(ctx)]; @@ -1816,8 +1794,8 @@ const parseImport = const stringLiteral = parseStringLiteral(path)(ctx); const parsedString: string = JSON.parse(`"${stringLiteral.value}"`); return Ast.Import( - parseImportString(parsedString, toRange(loc), ctx.err.imports), - toRange(loc), + parseImportString(parsedString, ctx.toRange(loc), ctx.err.imports), + ctx.toRange(loc), ); }; @@ -1832,14 +1810,15 @@ const parseModule = export const parse = ( log: SourceLogger, - text: string, + code: string, + path: string, ): Ast.Module => { const err = SyntaxErrors(log); const result = $.parse({ grammar: G.Module, space: G.space, - text, + text: code, }); if (result.$ === "error") { @@ -1851,7 +1830,16 @@ export const parse = ( return Ast.Module([], []); } + const toRange = (loc: $.Loc): Ast.Range => { + if (loc.$ === "empty") { + return throwInternal("Lookahead at top level"); + } + const { start, end } = loc; + return Ast.Range(start, end, path, code); + }; + return parseModule(result.value)({ err, + toRange, }); }; diff --git a/src/next/imports/reader.ts b/src/next/imports/reader.ts index 2da8bf2d88..48ce26be97 100644 --- a/src/next/imports/reader.ts +++ b/src/next/imports/reader.ts @@ -42,7 +42,7 @@ const readSource = async ({ file: Cursor, code: string, ): Promise => { - const { imports: rawImports, items } = parse(log, code); + const { imports: rawImports, items } = parse(log, code, path); const imports: ResolvedImport[] = [...implicits]; for (const { importPath, loc } of rawImports) { const { language, path, type } = importPath; @@ -129,7 +129,9 @@ export const ProjectReader = async (log: Logger) => { { kind: "tact", source: stdStd, - loc: { start: 0, end: 0 }, + loc: { + kind: 'implicit', + }, }, ]; return await readSource({ diff --git a/src/next/imports/source.ts b/src/next/imports/source.ts index cd7f229857..be2aa727a1 100644 --- a/src/next/imports/source.ts +++ b/src/next/imports/source.ts @@ -12,10 +12,14 @@ export type ResolvedImport = TactImport | FuncImport; export type TactImport = { readonly kind: "tact"; readonly source: TactSource; - readonly loc: Range; + readonly loc: Range | Implicit; }; export type FuncImport = { readonly kind: "func"; readonly code: string; readonly loc: Range; }; + +export type Implicit = { + readonly kind: "implicit"; +} diff --git a/src/next/scoping/const.ts b/src/next/scoping/const.ts deleted file mode 100644 index 3b274cd087..0000000000 --- a/src/next/scoping/const.ts +++ /dev/null @@ -1,180 +0,0 @@ -import type { ConstantDecl, ConstantDef, Expression } from "@/next/ast"; -import type { Id } from "@/next/ast/common"; -import type { Var } from "@/next/ast/expression"; -import type { TactSource } from "@/next/imports/source"; - -const ensureMap = (m: Map, k: K, v: V): V => { - const prev = m.get(k); - if (prev) { - return prev; - } else { - const x = {...v}; - m.set(k, x); - return x; - } -}; - -// constDefs: Map -// freeVars: Map -// varsInConst: Map - -// TactSource . items . ConstantDef . Expr/Var . name . !(TactSource . items . ConstantDef . name) -// TactSource . items . ConstantDef . name . !(TactSource . items . ConstantDef . name) -// TactSource . items . ConstantDef . (Expr/Var . name . !(ConstantDef . name))* . name - -type GlobalEnv = { - readonly freeVars: Map>; - readonly definedConsts: Set; - readonly constDefByName: Map; - readonly transitiveUse: Map; -} - -// const x = (Foo {}).y; -// struct Foo { -// y: Int as int32 = x; -// } - - -type Env = Map; - readonly usedBy: Set; -}> -const empty = { - definedBy: new Set(), - usedBy: new Set(), -} as const; -const define = (env: Env, id: Id) => ensureMap(env, id.text, empty).definedBy.add(id); -const use = (env: Env, id: Id) => ensureMap(env, id.text, empty).usedBy.add(id); - -// const c1 = 42; -// const c2 = c1 + 5; - -type Name = string; -interface Scope { - readonly constants: Env; - readonly children: Scope[]; -} -const Scope = (parent?: Scope): Scope => { - const scope: Scope = { constants: new Map(), children: [] }; - parent?.children.push(scope); - return scope; -}; - -export const resolve = (node: TactSource) => { - const global = Scope() - resolveTop(node, global); - // TODO: flatten scope - const flatGlobal = global; - checkDefinedOnce(flatGlobal); - checkSortable(flatGlobal); -}; - -const checkDefinedOnce = (scope: Scope) => { - for (const { definedBy, usedBy } of scope.constants.values()) { - if (definedBy.size === 0) { - for (const use of usedBy) { - console.error(`Constant was not defined ${use.loc.start}`); - } - } else if (definedBy.size > 1) { - for (const def of definedBy) { - console.error(`Constant was already defined ${def.loc.start}`); - } - } - } -} - -const checkSortable = (scope: Scope) => { - scope.constants -}; - -const resolveTop = ({ items }: TactSource, scope: Scope) => { - for (const item of items) { - switch (item.kind) { - case "constant_def": { - const { attributes: _a, initializer, name, type } = item; - define(scope.constants, name); - const child = resolveExpr(initializer, scope); - return; - } - case "function_def": - case "asm_function_def": - case "native_function_decl": - return; - case "struct_decl": - case "message_decl": - case "union_decl": - case "alias_decl": - case "contract": - case "trait": - return; - } - } -}; - -const resolveExpr = (root: Expression, parentScope: Scope) => { - const scope = Scope(parentScope); - const recAll = (nodes: readonly Expression[]) => { - for (const node of nodes) { - rec(node); - } - }; - const rec = (node: Expression) => { - switch (node.kind) { - case "var": - use(scope.constants, node.name); - return; - case "string": - case "number": - case "boolean": - return; - case "op_binary": - rec(node.left); - rec(node.right); - return; - case "op_unary": - rec(node.operand); - return; - case "conditional": - rec(node.condition); - rec(node.thenBranch); - rec(node.elseBranch); - return; - case "method_call": - rec(node.self); - recAll(node.args); - return; - case "field_access": - rec(node.aggregate); - return; - case "static_call": - recAll(node.args); - return; - case "struct_instance": - recAll(node.args.map(x => x.initializer)); - return; - case "init_of": - recAll(node.args); - return; - case "code_of": - return; - case "null": - return; - case "unit": - return; - case "tuple": - recAll(node.children); - return; - case "tensor": - recAll(node.children); - return; - case "map_literal": - recAll(node.fields.flatMap(({ key, value }) => [key, value])); - return; - case "set_literal": - recAll(node.fields); - return; - } - }; - rec(root); - return scope; -}; \ No newline at end of file diff --git a/src/next/scoping/errors.ts b/src/next/scoping/errors.ts new file mode 100644 index 0000000000..d44f7a8635 --- /dev/null +++ b/src/next/scoping/errors.ts @@ -0,0 +1,123 @@ +import type { SourceLogger } from "@/error/logger-util"; +import type { Implicit } from "@/next/imports/source"; +import type { Range } from "@/next/ast"; +import type * as Ty from "@/next/scoping/generated/type"; +import { printType } from "@/next/scoping/print-type"; + +export type MismatchTree = { + readonly to: Ty.LocType; + readonly from: Ty.LocType; + readonly children: MismatchTree[]; +} + +export const TcErrors = (l: SourceLogger) => ({ + shadowsImported: (name: string, prevPath: string, prevRange: Range | Implicit) => (loc: Range | Implicit) => { + if (loc.kind !== 'range') { + return l.internal(l.text`Import from standard library cannot shadow anything`); + } + const id = prevRange.kind === 'range' + ? l.text`"${l.locatedId(name, prevPath, prevRange)}"` + : l.text`from standard library`; + return l.at(loc).error(l.text`Declaration of "${name}" shadows previous declaration ${id}`); + }, + shadowsBuiltin: (name: string) => (loc: Range | Implicit) => { + if (loc.kind !== 'range') { + return l.internal(l.text`Import from standard library cannot shadow anything`); + } + return l.at(loc).error(l.text`"${name}" is primitive and cannot be redefined`); + }, + typeNotDefined: (name: string) => (loc: Ty.Loc) => { + if (loc.kind !== 'range') { + return l.internal(l.text`${loc.kind} type is not defined`); + } + return l.at(loc).error(l.text`Type "${name}" is not defined`); + }, + typeArity: (name: string, factualLen: number, expectedLen: number) => (loc: Ty.Loc) => { + if (loc.kind !== 'range') { + return l.internal(l.text`${loc.kind} type arity mismatch`); + } + return l.at(loc).error(l.text`Generic type "${name}" expected ${expectedLen.toString()} parameters, but got ${factualLen.toString()}`); + }, + fnArity: (name: string, factualLen: number, expectedLen: number) => (loc: Ty.Loc) => { + if (loc.kind !== 'range') { + return l.internal(l.text`${loc.kind} arity mismatch`); + } + return l.at(loc).error(l.text`"${name}" expected ${expectedLen.toString()} parameters, but got ${factualLen.toString()}`); + }, + noHkt: (name: string) => (loc: Ty.Loc) => { + if (loc.kind !== 'range') { + return l.internal(l.text`${loc.kind} is a hkt`); + } + return l.at(loc).error(l.text`Type variable "${name}" is not a type constructor`); + }, + instantiationLimit: () => (loc: Ty.Loc) => { + if (loc.kind !== 'range') { + return l.internal(l.text`${loc.kind} too deep`); + } + return l.at(loc).error(l.text`Instantiation is excessively deep`); + }, + typeMismatch: (root: MismatchTree) => (loc: Ty.Loc) => { + if (loc.kind !== 'range') { + return l.internal(l.text`${loc.kind} mismatch`); + } + const rec = ({ to, from, children }: MismatchTree, prefix: M, depth: number): M => { + const padding = new Array(depth + 1).join(' '); + const row = l.text`${padding}${printType(from)} is not assignable to ${printType(to)}`; + return children.reduce((message, child) => { + return rec(child, message, depth + 1); + }, l.text`${prefix}\n${row}`); + }; + return l.at(loc).error(rec(root, l.text``, 0)); + }, + danglingTypeParam: () => (loc: Ty.Loc) => { + if (loc.kind !== 'range') { + return l.internal(l.text`${loc.kind} mismatch`); + } + // def fun(/* T unused */) { } + return l.at(loc).error(l.text`Cannot infer type parameter`); + }, + contractNotDefined: () => (loc: Ty.Loc) => { + if (loc.kind !== 'range') { + return l.internal(l.text`${loc.kind} mismatch`); + } + return l.at(loc).error(l.text`No such contract`); + }, + typeNotContract: () => (loc: Ty.Loc) => { + if (loc.kind !== 'range') { + return l.internal(l.text`${loc.kind} mismatch`); + } + return l.at(loc).error(l.text`Type is not a contract`); + }, + structNotDefined: () => (loc: Ty.Loc) => { + if (loc.kind !== 'range') { + return l.internal(l.text`${loc.kind} mismatch`); + } + return l.at(loc).error(l.text`No such struct or message`); + }, + typeNotStruct: () => (loc: Ty.Loc) => { + if (loc.kind !== 'range') { + return l.internal(l.text`${loc.kind} mismatch`); + } + return l.at(loc).error(l.text`Type is not a struct or message`); + }, + noInit: () => (loc: Ty.Loc) => { + if (loc.kind !== 'range') { + return l.internal(l.text`${loc.kind} mismatch`); + } + return l.at(loc).error(l.text`Contract has neither init() nor parameters`); + }, + duplicateField: () => (loc: Ty.Loc) => { + if (loc.kind !== 'range') { + return l.internal(l.text`${loc.kind} mismatch`); + } + return l.at(loc).error(l.text`Duplicate field in struct instance`); + }, + fieldNotDefined: () => (loc: Ty.Loc) => { + if (loc.kind !== 'range') { + return l.internal(l.text`${loc.kind} mismatch`); + } + return l.at(loc).error(l.text`No such field`); + }, +}); + +export type TcErrors = ReturnType>; \ No newline at end of file diff --git a/src/next/scoping/generated/type.ts b/src/next/scoping/generated/type.ts new file mode 100644 index 0000000000..4f052b0153 --- /dev/null +++ b/src/next/scoping/generated/type.ts @@ -0,0 +1,189 @@ +/* eslint-disable @typescript-eslint/no-unnecessary-condition */ +import type * as $ from "@/next/scoping/type"; + +export type Inferred = $.Inferred; +export const Inferred = (range: $.Loc, readableName: string): $.Inferred => Object.freeze({ + kind: "inferred", + range, + readableName +}); +export const isInferred = ($value: Inferred) => $value.kind === "inferred"; +export type Loc = $.Loc; + +export type Signedness = $.Signedness; +export const allSignedness: readonly $.Signedness[] = ["signed", "unsigned"]; +export type IFInt = $.IFInt; +export const IFInt = ( + sign: $.Signedness, + width: number, + loc: $.Loc, +): $.IFInt => + Object.freeze({ + kind: "FInt", + sign, + width, + loc, + }); +export const isIFInt = ($value: IFInt) => $value.kind === "FInt"; +export type VarIntWidth = $.VarIntWidth; +export const allVarIntWidth: readonly $.VarIntWidth[] = ["16", "32"]; +export type IFVarInt = $.IFVarInt; +export const IFVarInt = ( + sign: $.Signedness, + width: $.VarIntWidth, + loc: $.Loc, +): $.IFVarInt => + Object.freeze({ + kind: "FVarInt", + sign, + width, + loc, + }); +export const isIFVarInt = ($value: IFVarInt) => $value.kind === "FVarInt"; +export type IntFormat = $.IntFormat; +export type TypeInt = $.TypeInt; +export const TypeInt = (format: $.IntFormat, loc: $.Loc): $.TypeInt => + Object.freeze({ + kind: "TyInt", + format, + loc, + }); +export const isTypeInt = ($value: TypeInt) => $value.kind === "TyInt"; +export type SFBits = $.SFBits; +export const SFBits = (bits: number, loc: $.Loc): $.SFBits => + Object.freeze({ + kind: "SFBits", + bits, + loc, + }); +export const isSFBits = ($value: SFBits) => $value.kind === "SFBits"; +export type SFRemaining = $.SFRemaining; +export const SFRemaining = (loc: $.Loc): $.SFRemaining => + Object.freeze({ + kind: "SFRemaining", + loc, + }); +export const isSFRemaining = ($value: SFRemaining) => + $value.kind === "SFRemaining"; +export type SFDefault = $.SFDefault; +export const SFDefault = (loc: $.Loc): $.SFDefault => + Object.freeze({ + kind: "SFDefault", + loc, + }); +export const isSFDefault = ($value: SFDefault) => $value.kind === "SFDefault"; +export type SliceFormat = $.SliceFormat; +export type TypeSlice = $.TypeSlice; +export const TypeSlice = (format: $.SliceFormat, loc: $.Loc): $.TypeSlice => + Object.freeze({ + kind: "TySlice", + format, + loc, + }); +export const isTypeSlice = ($value: TypeSlice) => $value.kind === "TySlice"; +export type RemFormat = $.RemFormat; +export type TypeCell = $.TypeCell; +export const TypeCell = (format: $.RemFormat, loc: $.Loc): $.TypeCell => + Object.freeze({ + kind: "TyCell", + format, + loc, + }); +export const isTypeCell = ($value: TypeCell) => $value.kind === "TyCell"; +export type TypeBuilder = $.TypeBuilder; +export const TypeBuilder = ( + format: $.RemFormat, + loc: $.Loc, +): $.TypeBuilder => + Object.freeze({ + kind: "TyBuilder", + format, + loc, + }); +export const isTypeBuilder = ($value: TypeBuilder) => + $value.kind === "TyBuilder"; +export type TypeUnit = $.TypeUnit; +export const TypeUnit = (loc: $.Loc): $.TypeUnit => + Object.freeze({ + kind: "unit_type", + loc, + }); +export const isTypeUnit = ($value: TypeUnit) => $value.kind === "unit_type"; +export type TypeTensor = $.TypeTensor; +export const TypeTensor = ( + typeArgs: readonly $.Type[], + loc: $.Loc, +): $.TypeTensor => + Object.freeze({ + kind: "tensor_type", + typeArgs, + loc, + }); +export const isTypeTensor = ($value: TypeTensor) => + $value.kind === "tensor_type"; +export type TypeTuple = $.TypeTuple; +export const TypeTuple = ( + typeArgs: readonly $.Type[], + loc: $.Loc, +): $.TypeTuple => + Object.freeze({ + kind: "tuple_type", + typeArgs, + loc, + }); +export const isTypeTuple = ($value: TypeTuple) => $value.kind === "tuple_type"; +export type TypeCons = $.TypeCons; +export const TypeCons = ( + name: $.TypeId, + typeArgs: readonly $.Type[], + loc: $.Loc, +): $.TypeCons => + Object.freeze({ + kind: "cons_type", + name, + typeArgs, + loc, + }); +export const isTypeCons = ($value: TypeCons) => $value.kind === "cons_type"; +export type LocType = $.LocType; +export type Type = $.Type; +export type TypeMap = $.TypeMap; +export const TypeMap = (key: $.Type, value: $.Type, loc: $.Loc): $.TypeMap => + Object.freeze({ + kind: "map_type", + key, + value, + loc, + }); +export const isTypeMap = ($value: TypeMap) => $value.kind === "map_type"; +export type TypeFunction = $.TypeFunction; +export const TypeFunction = (params: readonly $.Type[], returnType: $.Type | undefined): $.TypeFunction => Object.freeze({ + kind: "function", + params, + returnType +}); +export const isTypeFunction = ($value: TypeFunction) => $value.kind === "function"; +export type Builtin = $.Builtin; +export const Builtin = (readableName: string): $.Builtin => Object.freeze({ + kind: "builtin", + readableName +}); +export const isBuiltin = ($value: Builtin) => $value.kind === "builtin"; +export type TypeVar = $.TypeVar; +export const TypeVar = (id: number): $.TypeVar => Object.freeze({ + kind: "type_var", + id +}); +export const isTypeVar = ($value: TypeVar) => $value.kind === "type_var"; +export type TypeId = $.TypeId; +export const TypeId = (text: string, loc: $.Loc): $.TypeId => Object.freeze({ + kind: "type_id", + text, + loc +}); +export const isTypeId = ($value: TypeId) => $value.kind === "type_id"; +export type TypeErrorRecovered = $.TypeErrorRecovered; +export const TypeErrorRecovered = (): $.TypeErrorRecovered => Object.freeze({ + kind: "ERROR" +}); +export const isTypeErrorRecovered = ($value: TypeErrorRecovered) => $value.kind === "ERROR"; diff --git a/src/next/scoping/print-type.ts b/src/next/scoping/print-type.ts new file mode 100644 index 0000000000..4ff37afed4 --- /dev/null +++ b/src/next/scoping/print-type.ts @@ -0,0 +1,52 @@ +import type * as Ty from "@/next/scoping/generated/type"; + +export const printType = (type: Ty.Type): string => { + switch (type.kind) { + case "ERROR": return `_`; + case "type_var": return `#${type.id}`; + case "unit_type": return `()`; + case "TyInt": return `Int${printIntFormat(type.format)}` + case "TySlice": return `Slice${printSliceFormat(type.format)}`; + case "TyCell": return `Cell${printRemFormat(type.format)}`; + case "TyBuilder": return `Builder${printRemFormat(type.format)}`; + case "tuple_type": return `[${printTypeList(type.typeArgs)}]`; + case "tensor_type": return `(${printTypeList(type.typeArgs)})`; + case "map_type": return `map<${printType(type.key)}, ${printType(type.value)}>` + case "cons_type": { + return type.name.text + ( + type.typeArgs.length === 0 + ? '' + : `<${printTypeList(type.typeArgs)}>` + ); + } + } +}; + +const printTypeList = (types: readonly Ty.Type[]): string => { + return types.map(type => printType(type)).join(', '); +}; + +const printIntFormat = (format: Ty.IntFormat): string => { + if (format.kind === 'FInt' && format.sign === 'signed' && format.width === 257) { + return ''; + } + return " as " + (format.kind === 'FVarInt' ? "var" : "") + + (format.sign === 'unsigned' ? 'uint' : 'int') + + (format.kind === 'FVarInt' ? format.width : format.width.toString()); +}; + +const printSliceFormat = (format: Ty.SliceFormat): string => { + if (format.kind === 'SFBits') { + // FIXME: bits not divisible by 8 + return ` as bytes${format.bits >> 3}`; + } else { + return printRemFormat(format); + } +}; + +const printRemFormat = (format: Ty.RemFormat): string => { + switch (format.kind) { + case "SFRemaining": return ` as remaining`; + case "SFDefault": return ``; + } +}; diff --git a/src/next/scoping/scoped-ast.ts b/src/next/scoping/scoped-ast.ts deleted file mode 100644 index f913768e63..0000000000 --- a/src/next/scoping/scoped-ast.ts +++ /dev/null @@ -1,73 +0,0 @@ -export type ScopeId = string; - -export type Constraint = - | Define - | Use - | Child - -export type Define = { - readonly kind: 'define'; - readonly name: string; - readonly scope: ScopeId; -} - -export type Use = { - readonly kind: 'use'; - readonly name: string; - readonly scope: ScopeId; -} - -type Name = string -export type Scope = StmtScope - -type StmtScope = { - readonly kind: 'stmt_scope'; - readonly parent: Scope | undefined; - readonly vars: Map; - definedBy: Set; - }>; - readonly types: Map; - readonly functions: Map; -} - -fun f(y: Int) { - let x = y + 1; - { - let z = 0; - } - let z = 0; - return x + z; -} - -ensureMap(s.vars, "y", def) - -getVar(s, "y").definedBy.add(f) - -for (const s of scopes) { - for (const [k, { usedBy, definedBy }] of s.vars) { - if (definedBy.size === 0) { - for (const usage of usedBy) { - error(`Variable ${k} was not defined`, usage.loc); - } - } else if (definedBy.size > 1) { - const [head, ...tail] = definedBy; - for (const def of tail) { - error(`Variable ${k} is already defined`, def.loc); - } - } else { - - } - } -} - -const ensureMap = (m: Map, k: K, v: V): V => { - const prev = m.get(k); - if (prev) { - return prev; - } else { - const x = {...v}; - m.set(k, x); - return x; - } -}; diff --git a/src/next/scoping/tc.ts b/src/next/scoping/tc.ts deleted file mode 100644 index 97fc4bfea9..0000000000 --- a/src/next/scoping/tc.ts +++ /dev/null @@ -1,179 +0,0 @@ -import { makeVisitor } from "@/utils/tricks"; -import type { Range } from "@/next/ast"; -import type { Logger, SourceLogger } from "@/error/logger-util"; -import type { TactSource } from "@/next/imports/source"; -import type * as Ast from "@/next/ast/root"; - -const TcErrors = (l: SourceLogger) => ({ - // FIXME - foo: () => (loc: Range) => { - return l.at(loc).error(l.text`Bar`); - }, - - duplicateParam: () => (loc: Range) => { - return l.at(loc).error(l.text`Duplicate parameter`); - }, - duplicateDecl: () => (loc: Range) => { - return l.at(loc).error(l.text`Duplicate declaration`); - }, -}); - -type TcErrors = ReturnType>; - -type Name = string; -type Context = { - log: Logger; - err: TcErrors; - - typeNames: Map; -}; -type Tc = (ctx: Context) => void; - -const tcDummy = (): Tc => () => {}; - -const map = - (ts: readonly T[], handler: (t: T) => Tc): Tc => - (ctx) => { - for (const t of ts) { - handler(t)(ctx); - } - }; - -export const tcSource = - ({ path, code, imports, items }: TactSource): Tc => - (ctx) => { - ctx.log.source(path, code, (log) => { - const newCtx: Context = { - log: ctx.log, - err: TcErrors(log), - typeNames: new Map(), - }; - map(items, collectTypeEnv)(newCtx); - map(items, tcModuleItem)(newCtx); - }); - }; - -type TypeDecls = - | Ast.StructDecl - | Ast.MessageDecl - | Ast.UnionDecl - | Ast.AliasDecl - | Ast.Contract - | Ast.Trait; - -const collectTypeEnvStruct = - (node: TypeDecls): Tc => - (ctx) => { - const prev = ctx.typeNames.get(node.name.text); - if (typeof prev !== "undefined") { - ctx.err.duplicateDecl()(node.loc); - } else { - ctx.typeNames.set(node.name.text, node); - } - }; - -const collectTypeEnv = makeVisitor()({ - function_def: tcDummy, - asm_function_def: tcDummy, - native_function_decl: tcDummy, - constant_def: tcDummy, - - struct_decl: collectTypeEnvStruct, - message_decl: collectTypeEnvStruct, - union_decl: collectTypeEnvStruct, - alias_decl: collectTypeEnvStruct, - contract: collectTypeEnvStruct, - trait: collectTypeEnvStruct, -}); - -const checkParamDuplicates = - (params: readonly Ast.AsmTypedParameter[]): Tc => - (ctx) => { - const names: Set = new Set(); - for (const { - name: { text }, - loc, - } of params) { - if (names.has(text)) { - ctx.err.duplicateParam()(loc); - } else { - names.add(text); - } - } - }; - -// AsmFunctionDef: -// Cannot use ... attrubute on global assembly functions -// attributes kind == "get" -// attributes kind == "virtual" | "abstract" | "override" | "inline" - -// Only a method can be mutating. Did you forget "extends"? -// attributes kind has "mutates", doesn't have "extends" - -// Duplicate function definition -// (imports* AsmFunctionDef name) . size > 1 - -// Duplicate parameter -// asm fun f(x: Int, x: Foo) {} -// (Source AsmFunctionDef params name) . size > 1 - -// Type is not defined -// asm fun f(x: Nonexist) {} -// AsmFunctionDef (params type | retType) Type/TypeCons: -// .name !in (imports* TypeDecl name | .typeParams) - -// `F` expects 1 argument. Passed 2 arguments. -// struct F {} asm fun f(x: F) {} -// AsmFunctionDef (params type | retType) Type/TypeCons typeArgs length -// != imports* TypeDecl typeParams length - -// `F` type parameter is shadowing globally defined type -// struct F {} asm fun f(x: F) {} -// AsmFunctionDef typeParams name -// in imports* TypeDecl name - -// TypeDecl = StructDecl | MessageDecl | UnionDecl | AliasDecl | Contract | Trait - -// Duplicate type parameter -// (Source AsmFunctionDef typeParams name) . size > 1 - -// Shuffle must be a permutation of all function parameters -// asm(c c) extends fun f(self: Builder, c: Cell?) {} -// AsmFunctionDef: (.shuffle args text).sort() = (.params name text).sort() - -// extends fun попадают в скоуп self -// trait A { abstract fun f(): Int; } -// contract B {} -// override extends asm fun f(self: B): Int {} - -const tcAsmFunction = - ({ - attributes, - name, - params, - return: retType, - shuffle, - typeParams, - loc, - }: Ast.AsmFunctionDef): Tc => - (ctx) => { - checkParamDuplicates(params)(ctx); - - for (const arg of shuffle.args) { - arg.text; - } - }; - -const tcModuleItem = makeVisitor()({ - function_def: tcDummy, - asm_function_def: tcAsmFunction, - native_function_decl: tcDummy, - constant_def: tcDummy, - - struct_decl: tcDummy, - message_decl: tcDummy, - union_decl: tcDummy, - alias_decl: tcDummy, - contract: tcDummy, - trait: tcDummy, -}); diff --git a/src/next/scoping/tc2.ts b/src/next/scoping/tc2.ts deleted file mode 100644 index 34eaff4c9d..0000000000 --- a/src/next/scoping/tc2.ts +++ /dev/null @@ -1,141 +0,0 @@ -import { entries, memo } from "@/utils/tricks"; -import type { Logger, SourceLogger } from "@/error/logger-util"; -import type { TactImport, TactSource } from "@/next/imports/source"; -import type * as Ast from "@/next/ast"; -import { mapValues } from "@/utils/array"; -import type { Range } from "@/next/ast"; - -const TcErrors = (l: SourceLogger) => ({ - shadowsImported: (name: string, prevPath: string, prevRange: Range) => (loc: Range) => { - return l - .at(loc) - .error(l.text`Declaration of "${name}" shadows previous declaration "${l.locatedId(name, prevPath, prevRange)}"`); - }, -}); - -type TcErrors = ReturnType>; - -type Handler = (children: [T, TactImport][], source: TactSource) => T - -const combine = (handlers: { [K in keyof O]: Handler }): Handler => { - return (children, source) => { - const result = {} as O; - for (const [key, handler] of entries(handlers)) { - result[key] = handler( - children.map(([o, imp]) => [o[key], imp] as const), - source, - ); - } - return result; - }; -}; - -const foldSources = (root: TactSource, onSource: Handler): T => { - const rec = (source: TactSource): T => { - const children: [T, TactImport][] = []; - for (const imp of source.imports) { - if (imp.kind === 'tact') { - children.push([memoedRec(imp.source), imp]); - } - } - return onSource(children, source); - }; - const memoedRec = memo(rec); - return memoedRec(root); -}; - -const getFunctions = (source: TactSource) => { - const ids: Ast.Id[] = []; - for (const item of source.items) { - if (item.kind === 'function') { - ids.push(item.name); - } - } - return ids; -}; - -const getConstants = (source: TactSource) => { - const ids: Ast.Id[] = []; - for (const item of source.items) { - if (item.kind === 'constant') { - ids.push(item.name); - } - } - return ids; -}; - -const getTypes = (source: TactSource) => { - const ids: Ast.TypeId[] = []; - for (const item of source.items) { - switch (item.kind) { - case "function": - case "extension": - case "constant": - continue; - case "struct_decl": - case "message_decl": - case "union_decl": - case "alias_decl": - case "contract": - case "trait": - ids.push(item.name); - } - } - return ids; -}; - -// const getExtensions = (source: TactSource) => { -// const ids: Ast.Id[] = []; -// for (const item of source.items) { -// if (item.kind === 'extension') { -// ids.push(item.method.fun.name); -// } -// } -// return ids; -// }; - -export type ResolvedSource = { - readonly path: string; - readonly code: string; - readonly imports: readonly ResolvedSource[]; - readonly functions: ReadonlyMap; - readonly extensions: ReadonlyMap; - readonly constants: ReadonlyMap; - readonly types: ReadonlyMap; -}; - -const scopeIds = ( - log: Logger, - getIds: (source: TactSource) => { text: string, loc: Ast.Range }[] -): Handler> => (children, source) => { - const err = log.source(source.path, source.code, (logger) => TcErrors(logger)); - const ids: Map = new Map(); - const addId = (name: string, nextSource: TactSource, loc: Range) => { - const prev = ids.get(name); - if (typeof prev === 'undefined') { - ids.set(name, { source: nextSource, loc }); - } else if (prev.source !== nextSource) { - err.shadowsImported(name, source.path, prev.loc)(loc); - } - }; - for (const [sources, imp] of children) { - for (const [name, source] of sources) { - addId(name, source, imp.loc); - } - } - for (const { text: name, loc } of getIds(source)) { - addId(name, source, loc); - } - return mapValues(ids, ({ source }) => source); -}; - -export const scope = ( - log: Logger, - root: TactSource, -) => { - return foldSources(root, combine({ - functions: scopeIds(log, getFunctions), - constants: scopeIds(log, getConstants), - types: scopeIds(log, getTypes), - })); -}; diff --git a/src/next/scoping/type.ts b/src/next/scoping/type.ts new file mode 100644 index 0000000000..9cf4f026ff --- /dev/null +++ b/src/next/scoping/type.ts @@ -0,0 +1,155 @@ +import type { Range } from "@/next/ast"; + +export type TypeId = { + readonly kind: "type_id"; + readonly text: string; + readonly loc: Loc; +}; + +export type Loc = Range | Inferred | Builtin; + +/** + * Type that was computed from AST + */ +export type Inferred = { + readonly kind: "inferred"; + readonly range: Loc; + readonly readableName: string; +} + +/** + * Type that came from builtins, where we don't have location at all + */ +export type Builtin = { + readonly kind: "builtin"; + readonly readableName: string; +} + +export type TypeFunction = { + readonly kind: "function"; + // readonly typeParams: readonly string[]; + readonly params: readonly Type[]; + readonly returnType: undefined | Type; +} + +export type Type = + | TypeErrorRecovered + | TypeVar + | TypeMap + | TypeCons + | TypeInt + | TypeSlice + | TypeCell + | TypeBuilder + | TypeTuple + | TypeUnit + | TypeTensor; + +export type LocType = + | TypeMap + | TypeCons + | TypeInt + | TypeSlice + | TypeCell + | TypeBuilder + | TypeTuple + | TypeUnit + | TypeTensor + +export type TypeErrorRecovered = { + readonly kind: "ERROR"; +}; + +export type TypeVar = { + readonly kind: "type_var"; + readonly id: number; +}; + +export type TypeCons = { + readonly kind: "cons_type"; + readonly name: TypeId; + readonly typeArgs: readonly Type[]; + readonly loc: Loc; +}; + +export type TypeBool = { + readonly kind: "TyBool"; + readonly loc: Loc; +}; + +export type TypeInt = { + readonly kind: "TyInt"; + readonly format: IntFormat; + readonly loc: Loc; +}; +export type IntFormat = IFInt | IFVarInt; +export type IFInt = { + readonly kind: "FInt"; + readonly sign: Signedness; + readonly width: number; + readonly loc: Loc; +}; +export type IFVarInt = { + readonly kind: "FVarInt"; + readonly sign: Signedness; + readonly width: VarIntWidth; + readonly loc: Loc; +}; +export type VarIntWidth = "16" | "32"; +export type Signedness = "signed" | "unsigned"; + +export type TypeSlice = { + readonly kind: "TySlice"; + readonly format: SliceFormat; + readonly loc: Loc; +}; +export type SliceFormat = SFBits | SFRemaining | SFDefault; +export type SFBits = { + readonly kind: "SFBits"; + readonly bits: number; + readonly loc: Loc; +}; +export type SFRemaining = { + readonly kind: "SFRemaining"; + readonly loc: Loc; +}; +export type SFDefault = { + readonly kind: "SFDefault"; + readonly loc: Loc; +}; + +export type TypeCell = { + readonly kind: "TyCell"; + readonly format: RemFormat; + readonly loc: Loc; +}; +export type TypeBuilder = { + readonly kind: "TyBuilder"; + readonly format: RemFormat; + readonly loc: Loc; +}; +export type RemFormat = SFRemaining | SFDefault; + +export type TypeTuple = { + readonly kind: "tuple_type"; + readonly typeArgs: readonly Type[]; + readonly loc: Loc; +}; + +export type TypeUnit = { + readonly kind: "unit_type"; + readonly loc: Loc; +}; + +export type TypeTensor = { + readonly kind: "tensor_type"; + readonly typeArgs: readonly Type[]; + readonly loc: Loc; +}; + +export type TypeMap = { + readonly kind: "map_type"; + readonly key: Type; // any type except tensor + readonly value: Type; // any type except tensor + readonly loc: Loc; +}; diff --git a/src/next/scoping/typecheck.ts b/src/next/scoping/typecheck.ts new file mode 100644 index 0000000000..d0013f0680 --- /dev/null +++ b/src/next/scoping/typecheck.ts @@ -0,0 +1,851 @@ +/* eslint-disable @typescript-eslint/no-base-to-string */ +import { makeVisitor, memo } from "@/utils/tricks"; +import type { Logger } from "@/error/logger-util"; +import type { Implicit, TactImport, TactSource } from "@/next/imports/source"; +import type * as Ast from "@/next/ast"; +import type { Range } from "@/next/ast"; +import * as Ty from "@/next/scoping/generated/type"; +import { zip } from "@/utils/array"; +import { throwInternal } from "@/error/errors"; +import { type MismatchTree, TcErrors } from "@/next/scoping/errors"; + +export const scope = ( + log: Logger, + root: TactSource, +) => { + return foldSources(root, scopeIds(log)); +}; + +type Handler = (children: [T, TactImport][], source: TactSource) => T + +const foldSources = (root: TactSource, onSource: Handler): T => { + const rec = (source: TactSource): T => { + const children: [T, TactImport][] = []; + for (const imp of source.imports) { + if (imp.kind === 'tact') { + children.push([memoedRec(imp.source), imp]); + } + } + return onSource(children, source); + }; + const memoedRec = memo(rec); + return memoedRec(root); +}; + +type Result = { + // readonly source: TactSource; + // readonly imports: readonly Result[]; + readonly functions: ReadonlyMap; + readonly extensions: ReadonlyMap; + readonly constants: ReadonlyMap; + readonly types: ReadonlyMap; +}; + +type DeclMap = Map; + +type Registry = { + readonly get: (key: string) => T | undefined; + readonly add: ( + name: string, + entry: T, + nextSource: TactSource, + loc: Range | Implicit, + ) => void; +} + +const scopeIds = (log: Logger) => + (children: [Result, TactImport][], source: TactSource): Result => { + const err = log.source(source.path, source.code, (logger) => TcErrors(logger)); + + const makeRegistry = (builtins: Set): Registry => { + const ids: DeclMap = new Map(); + return { + get: (key) => ids.get(key)?.entry, + add: (name, entry, nextSource, loc) => { + const prev = ids.get(name); + if (builtins.has(name)) { + err.shadowsBuiltin(name)(loc); + } else if (typeof prev === 'undefined') { + ids.set(name, { source: nextSource, entry, loc }); + } else if (prev.source !== nextSource) { + err.shadowsImported(name, source.path, prev.loc)(loc); + } + }, + }; + }; + + const functions = makeRegistry(new Set()); + const extensions = makeRegistry(new Set()); + const constants = makeRegistry(new Set()); + const types = makeRegistry(new Set([ + "void", + "bounced", + "Null", + "Maybe", + "Int", + "Bool", + "Builder", + "Slice", + "Cell", + "Address", + "String", + "StringBuilder", + ])); + + for (const [sources, imp] of children) { + for (const [name, [entry, source]] of sources.functions) { + functions.add(name, entry, source, imp.loc); + } + // for (const [name, [entry, source]] of sources.extensions) { + // extensions.add(name, entry, source, imp.loc); + // } + for (const [name, [entry, source]] of sources.constants) { + constants.add(name, entry, source, imp.loc); + } + for (const [name, [entry, source]] of sources.types) { + types.add(name, entry, source, imp.loc); + } + } + + for (const item of source.items) { + switch (item.kind) { + case "function": { + functions.add(item.name.text, item, source, item.name.loc); + continue; + } + case "constant": { + constants.add(item.name.text, item, source, item.name.loc); + continue; + } + case "extension": { + const id = item.method.fun.name; + extensions.add(id.text, item, source, id.loc); + continue; + } + case "struct_decl": + case "message_decl": + case "union_decl": + case "alias_decl": + case "contract": + case "trait": { + types.add(item.name.text, item, source, item.name.loc); + continue; + } + } + } + + for (const item of source.items) { + checkItem(types.get, err, item); + } + + return { + functions: functions.get(), + constants: constants.get(), + types: types.get(), + extensions: extensions.get(), + }; + }; + +const noTypeParams = () => false; + +const checkItem = ( + getType: (key: string) => Ast.TypeDecl | undefined, + err: TcErrors, + node: Ast.ModuleItem, +) => { + // TODO: check kinds + // TODO: Check if self is initialized + switch (node.kind) { + case "constant": { + const { init } = node; + if (init.kind === 'constant_def') { + const { checkExpr, assignTo } = getExprChecker( + getType, + noTypeParams, + err, + ); + const exprType = checkExpr(init.initializer); + if (init.type) { + const res = assignTo(init.type, exprType); + } + return; + } else { + // ... + return; + } + } + case "function": { + return; + } + case "extension": { + return; + } + case "struct_decl": { + return; + } + case "message_decl": { + return; + } + case "union_decl": { + return; + } + case "alias_decl": { + return; + } + case "contract": { + return; + } + case "trait": { + return; + } + } +}; + +const Int257 = (loc: Ty.Loc) => Ty.TypeInt(Ty.IFInt("signed", 257, loc), loc); +const String = (loc: Ty.Loc) => Ty.TypeCons(Ty.TypeId("String", loc), [], loc); +const Bool = (loc: Ty.Loc) => Ty.TypeCons(Ty.TypeId("Bool", loc), [], loc); +const Cell = (loc: Ty.Loc) => Ty.TypeCons(Ty.TypeId("Cell", loc), [], loc); +const StateInit = (loc: Ty.Loc) => Ty.TypeCons(Ty.TypeId("StateInit", loc), [], loc); +const Maybe = (param: Ty.Type, loc: Ty.Loc) => Ty.TypeCons(Ty.TypeId("Maybe", loc), [param], loc); +const Null = (loc: Ty.Loc) => Ty.TypeCons(Ty.TypeId("Null", loc), [], loc); +const Unit = (loc: Ty.Loc) => Ty.TypeTensor([], loc); + +const isNull = (type: Ty.LocType) => type.kind === 'cons_type' && type.name.text === 'Null'; + +const getExprChecker = ( + getType: (key: string) => Ast.TypeDecl | undefined, + hasTypeParam: (key: string) => boolean, + err: TcErrors, +) => { + const typeVars: Map = new Map(); + + const simplifyHead = (type: Ty.Type): Ty.Type => simplifyHeadAux(type, 0); + const simplifyHeadAux = (type: Ty.Type, depth: number): Ty.Type => { + switch (type.kind) { + case "type_var": return simplifyVar(type, depth); + case "cons_type": return simplifyAlias(type, depth); + default: return type; + } + }; + const simplifyVar = (type: Ty.TypeVar, depth: number): Ty.Type => { + const foundType = typeVars.get(type.id); + return foundType ? simplifyHeadAux(foundType, depth + 1) : type; + }; + const simplifyAlias = (type: Ty.TypeCons, depth: number): Ty.Type => { + if (depth >= 100) { + err.instantiationLimit()(type.loc); + return Ty.TypeErrorRecovered(); + } + const name = type.name.text; + const maybeAlias = getType(name); + if (!maybeAlias) { + err.typeNotDefined(name)(type.name.loc); + return Ty.TypeErrorRecovered(); + } + if (maybeAlias.kind !== 'alias_decl') { + return type; + } + const factualLen = type.typeArgs.length; + const expectedLen = maybeAlias.typeParams.length; + if (factualLen !== expectedLen) { + err.typeArity(name, factualLen, expectedLen)(type.loc); + } + return simplifyHeadAux( + substParams( + maybeAlias.type, + maybeAlias.typeParams, + type.typeArgs, + ), + depth + 1, + ); + }; + + const assignTo = (to: Ty.Type, from: Ty.Type): boolean => { + if (from.kind === 'ERROR') { + return false; + } + if (from.kind === 'type_var') { + return throwInternal("Type variable on top level of assignment"); + } + const children: MismatchTree[] = []; + const result = assignToAux1(to, from, children); + if (!result) { + for (const tree of children) { + err.typeMismatch(tree)(from.loc); + } + } + return result; + }; + const assignAll = ( + to: readonly Ty.Type[], + from: readonly Ty.Type[], + parent: MismatchTree[] + ): boolean => { + if (to.length !== from.length) { + return throwInternal("Arity check failed after kind checks"); + } + return zip(to, from) + .map(([elemTo, elemFrom]) => assignToAux1(elemTo, elemFrom, parent)) + // eslint-disable-next-line @typescript-eslint/no-unnecessary-boolean-literal-compare + .every(x => x === true) + }; + const assignToAux1 = ( + to: Ty.Type, + from: Ty.Type, + parent: MismatchTree[] + ) => { + // Substitute type variables and aliases + to = simplifyHead(to); + from = simplifyHead(from); + // If either argument is already a recovery, no more + // error messages should be emitted + if (to.kind === 'ERROR' || from.kind === 'ERROR') { + return false; + } + // If we're assigning something with type variables in it, + // the global invariant of type synthesis was violated + if (from.kind === 'type_var') { + return throwInternal("Type variable on right side of assignment"); + } + if (to.kind === 'type_var') { + typeVars.set(to.id, from); + return true; + } + const children: MismatchTree[] = []; + const result = assignToAux2(to, from, children); + if (!result) { + parent.push({ to, from, children }); + } + return result; + }; + const assignToAux2 = ( + to: Ty.LocType, + from: Ty.LocType, + tree: MismatchTree[], + ): boolean => { + switch (to.kind) { + case 'TyBuilder': + case 'TyCell': + case 'TyInt': + case 'TySlice': + case "unit_type": { + return from.kind === to.kind; + } + case "tuple_type": + case "tensor_type": { + return from.kind === to.kind && assignAll(to.typeArgs, from.typeArgs, tree); + } + case "map_type": { + return isNull(from) + || from.kind === 'map_type' && assignToAux1(to.key, from.key, tree) && assignToAux1(to.value, from.value, tree); + } + case 'cons_type': { + return hasTypeParam(to.name.text) && to.typeArgs.length === 0 + || to.name.text === 'Maybe' && isNull(from) + || from.kind === 'cons_type' && to.name.text === from.name.text && assignAll(to.typeArgs, from.typeArgs, tree); + } + } + }; + + const mgu = (left: Ty.Type, right: Ty.Type): Ty.Type => { + if (left.kind === 'ERROR' || right.kind === 'ERROR') { + return Ty.TypeErrorRecovered(); + } + if (left.kind === 'type_var' || right.kind === 'type_var') { + return throwInternal("Trying to unify type variable"); + } + const children1: MismatchTree[] = []; + const children2: MismatchTree[] = []; + if (assignToAux1(left, right, children1)) { + return left; + } + if (assignToAux1(right, left, children2)) { + return right; + } + // TODO + }; + + let nextId = 0; + const freshTVar = () => { + const id = nextId++; + + const resolve = (loc: Ty.Loc) => { + const type = typeVars.get(id); + if (!type) { + // TODO: think if it should be check at declaration + // time and `throwInternal` here + err.danglingTypeParam()(loc); + return Ty.TypeErrorRecovered(); + } + return type; + }; + + return { + type: Ty.TypeVar(id), + resolve, + }; + }; + + const checkNull = (node: Ast.Null): Ty.Type => { + return Null(Ty.Inferred(node.loc, "null literal")); + }; + + const checkUnit = (node: Ast.Unit): Ty.Type => { + return Unit(Ty.Inferred(node.loc, "unit literal")); + }; + + const checkString = (node: Ast.String): Ty.Type => { + return String(Ty.Inferred(node.loc, "string literal")); + }; + + const checkNumber = (node: Ast.Number): Ty.Type => { + return Int257(Ty.Inferred(node.loc, "numeric literal")); + }; + + const checkBoolean = (node: Ast.Boolean): Ty.Type => { + return Bool(Ty.Inferred(node.loc, "boolean literal")); + }; + + const checkUnaryExpr = (node: Ast.OpUnary): Ty.Type => { + const resultLoc = Ty.Inferred(node.loc, `result of ${node.op} operator`); + const paramLoc = Ty.Builtin(`parameter of "${node.op}" operator`); + const argType = checkExpr(node.operand); + switch (node.op) { + case "+": + case "-": + case "~": { + if (!assignTo(Int257(paramLoc), argType)) { + return Ty.TypeErrorRecovered(); + } + return Int257(resultLoc); + } + case "!": { + if (!assignTo(Bool(paramLoc), argType)) { + return Ty.TypeErrorRecovered(); + } + return Bool(resultLoc); + } + case "!!": { + // fun !!_(x: T?): T; + const tv = freshTVar(); + if (!assignTo(Maybe(tv.type, paramLoc), argType)) { + return Ty.TypeErrorRecovered(); + } + return tv.resolve(Ty.Builtin(`type argument of optional type`)); + } + } + }; + + const checkBinaryExpr = (node: Ast.OpBinary): Ty.Type => { + const resultLoc = Ty.Inferred(node.loc, `result of ${node.op} operator`); + const leftLoc = Ty.Builtin(`left parameter of "${node.op}" operator`); + const rightLoc = Ty.Builtin(`right parameter of "${node.op}" operator`); + const leftType = checkExpr(node.left); + const rightType = checkExpr(node.right); + + switch (node.op) { + case "+": + case "-": + case "*": + case "/": + case "%": + case "<<": + case ">>": + case "&": + case "|": + case "^": { + if ( + !assignTo(Int257(leftLoc), leftType) + || !assignTo(Int257(rightLoc), rightType) + ) { + return Ty.TypeErrorRecovered(); + } + return Int257(resultLoc); + } + case ">": + case "<": + case ">=": + case "<=": { + if ( + !assignTo(Int257(leftLoc), leftType) + || !assignTo(Int257(rightLoc), rightType) + ) { + return Ty.TypeErrorRecovered(); + } + return Bool(resultLoc); + } + case "!=": + case "==": { + // TODO: + // Maybe ? Null + // Null ? Maybe + // map<> ? Null + // Null ? map<> + // "Int" + // "Bool" + // "Address" + // "Cell" + // "Slice" + // "String" + return Bool(resultLoc); + } + case "&&": + case "||": { + if ( + !assignTo(Bool(leftLoc), leftType) + || !assignTo(Bool(rightLoc), rightType) + ) { + return Ty.TypeErrorRecovered(); + } + return Bool(resultLoc); + } + } + }; + + const checkTernary = (node: Ast.Conditional): Ty.Type => { + const resultLoc = Ty.Inferred(node.loc, `result of ternary operator`); + const condLoc = Ty.Builtin(`condition of ternary operator`); + const thenLoc = Ty.Builtin(`"then" of ternary operator`); + const elseLoc = Ty.Builtin(`"else" of ternary operator`); + const condType = checkExpr(node.condition); + const commonType = mgu( + checkExpr(node.thenBranch), + checkExpr(node.elseBranch), + ); + if ( + !assignTo(Bool(condLoc), condType) + || commonType.kind === 'ERROR' + ) { + return Ty.TypeErrorRecovered(); + } + return commonType; + }; + + const getContract = (id: Ty.TypeId): undefined | Ast.Contract => { + const contract = getType(id.text); + if (typeof contract === 'undefined') { + err.contractNotDefined()(id.loc); + return undefined; + } + if (contract.kind !== 'contract') { + err.typeNotContract()(id.loc); + return undefined; + } + return contract; + }; + + const getStruct = (id: Ty.TypeId): undefined | Ast.StructDecl | Ast.MessageDecl => { + const struct = getType(id.text); + if (typeof struct === 'undefined') { + err.structNotDefined()(id.loc); + return undefined; + } + if (struct.kind !== 'struct_decl' && struct.kind !== 'message_decl') { + err.typeNotStruct()(id.loc); + return undefined; + } + return struct; + }; + + const checkCodeOf = (node: Ast.CodeOf): Ty.Type => { + if (!getContract(node.contract)) { + return Ty.TypeErrorRecovered(); + } + return Cell(Ty.Inferred(node.loc, "return value of codeOf operator")); + }; + + const checkInitOf = (node: Ast.InitOf): Ty.Type => { + // resolveInitOf + const contract = getContract(node.contract); + if (!contract) { + return Ty.TypeErrorRecovered(); + } + + const { init } = contract; + if (!init) { + err.noInit()(node.loc) + return Ty.TypeErrorRecovered(); + } + + const paramCount = init.params.length; + const argCount = node.args.length; + if (paramCount < argCount) { + err.fnArity(`Contract ${contract.name.text}`, argCount, paramCount)(node.loc); + } + + for (const [index, param] of init.params.entries()) { + const arg = node.args[index]; + // const paramName = param.name.kind === 'id' ? param.name.text : `number ${index + 1}`; + // const argType = arg ? : Null(Ty.Inferred(node.loc, `omitted parameter ${paramName}`)); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + if (arg) { + const children: MismatchTree[] = []; + if (!assignToAux1(param.type, checkExpr(arg), children)) { + for (const tree of children) { + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + err.typeMismatch(tree)(arg ? arg.loc : node.loc); + } + } + } else if (param.kind !== 'field_decl' || !param.initializer) { + err.fnArity(`Contract ${contract.name.text}`, argCount, paramCount)(node.loc); + } + } + + return StateInit(Ty.Inferred(node.loc, "result of initOf operator")); + }; + + type Substitutor = { + readonly subst: (type: Ty.Type) => Ty.Type; + readonly getArgs: () => readonly Ty.Type[]; + } + const substTypeParams = ( + struct: Ast.StructDecl | Ast.MessageDecl, + node: Ast.StructInstance, + ): Substitutor => { + if (struct.kind === 'message_decl') { + if (node.typeArgs.length > 0) { + err.typeArity(struct.name.text, node.typeArgs.length, 0)(node.loc); + } + // messages do not have type parameters + return { + subst: (type) => type, + getArgs: () => [], + }; + } + if (struct.typeParams.length !== 0 && node.typeArgs.length === 0) { + // struct F { x: Int; } + // let a = F { x: 1 }; + const vars = struct.typeParams.map(param => ({ + ...freshTVar(), + name: param.text, + })); + return { + subst: (type) => { + // substitute type variables + return substParams( + type, + struct.typeParams, + vars.map(v => v.type), + ); + }, + getArgs: () => vars.map(v => { + // resolve type variables after all the fields + // are assigned + return v.resolve(Ty.Inferred( + node.loc, + `inferred type parameter ${v.name}`, + )); + }), + }; + } + if (struct.typeParams.length !== node.typeArgs.length) { + err.typeArity(struct.name.text, node.typeArgs.length, 0)(node.loc); + } + // struct F { x: Int; } + // let a = F { x: 1 }; + return { + subst: (type: Ty.Type) => { + // substitute passed args + return substParams( + type, + struct.typeParams, + node.typeArgs, + ); + }, + getArgs: () => { + return [ + // cut extraneous arguments + ...node.typeArgs.slice(0, struct.typeParams.length), + // pad with missing arguments + ...new Array(Math.max(0, struct.typeParams.length - node.typeArgs.length)) + .fill(0).map(() => Ty.TypeErrorRecovered()) + ]; + }, + }; + }; + const checkStructInstance = (node: Ast.StructInstance): Ty.Type => { + const struct = getStruct(node.type); + if (!struct) { + return Ty.TypeErrorRecovered(); + } + const { subst, getArgs } = substTypeParams(struct, node); + const defined: Set = new Set(); + for (const { field: { text, loc }, initializer } of node.args) { + if (defined.has(text)) { + err.duplicateField()(loc); + } + const field = struct.fields.find(field => field.name.text === text); + if (field) { + assignTo(subst(field.type), checkExpr(initializer)); + } else { + err.fieldNotDefined()(loc); + } + } + for (const field of struct.fields) { + if (!defined.has(field.name.text) && !field.initializer) { + assignTo(field.type, Null(Ty.Inferred(node.loc, `omitted field "${field.name.text}"`))); + } + } + const loc = Ty.Inferred(node.loc, "struct literal"); + return Ty.TypeCons( + Ty.TypeId(node.type.text, loc), + getArgs(), + loc, + ); + }; + + const checkFunctionCall = (node: Ast.StaticCall): Ty.Type => { + // dump: checkDump, // (ref | void | null | map | Cell | Slice | Builder | Address | String | Bool | Int) -> void + + // ton: checkTon, // (String) -> Int, строка должна быть конст + // require: checkRequire, // (Bool, String) -> void + // address: checkAddress, // (String) -> Address + // cell: checkCell, // (String) -> Cell + // dumpStack: checkDumpStack, // () -> void + // emptyMap: checkEmptyMap, // () -> Null + // sha256: checkSha256, // (String | Slice) -> Int + // slice: checkSlice, // (String) -> Slice + // rawSlice: checkRawSlice, // (String) -> Slice + // ascii: checkAscii, // (String) -> Int + // crc32: checkCrc32, // (String) -> Int + const resultLoc = Ty.Inferred(node.loc, `result of ${node.op} operator`); + const leftLoc = Ty.Builtin(`left parameter of "${node.op}" operator`); + const rightLoc = Ty.Builtin(`right parameter of "${node.op}" operator`); + const leftType = checkExpr(node.left); + const rightType = checkExpr(node.right); + if ( + !assignTo(Int257(leftLoc), leftType) + || !assignTo(Int257(rightLoc), rightType) + ) { + return Ty.TypeErrorRecovered(); + } + return Int257(resultLoc); + }; + + const checkMethodCall = (node: Ast.MethodCall): Ty.Type => { + // toCell : struct.() -> Cell + // toSlice: struct.() -> Slice + + // K = Int|Address + // set: map.(key: K, value: V) -> void + // get: map.(key: K) -> Maybe + // del: map.(key: K) -> Bool + // asCell: map.() -> Maybe + // isEmpty: map.() -> Bool + // exists: map.(key: K) -> Bool + // deepEquals: map.(other: map) -> Bool // mgu + // replace: map.(key: K, value: V) -> Bool + // replaceGet: map.(key: K, value: V) -> map + + // bounced<> не переносит методы + // null -- Maybe<>, map<>, Null; может быть >1 кандидата + }; + + const checkField = (node: Ast.FieldAccess): Ty.Type => { + // resolveFieldAccess + // только struct или Maybe или bounced + // обрезать bounced поля (см. partialFieldCount) + // ищем в полях и константах + }; + + const checkVariable = (node: Ast.Var): Ty.Type => { + // 1. константы + // 2. Type.foo() + // fromCell: Struct.(Cell) -> struct + // fromSlice: Struct.(Slice) -> struct + // FIXME!!! + // 3. переменные + // 4. кастомная ошибка, когда foo, но нужен self.foo + }; + + const checkTuple = (node: Ast.Tuple): Ty.Type => { + // + }; + + const checkTensor = (node: Ast.Tensor): Ty.Type => { + // + }; + + const checkMapLiteral = (node: Ast.MapLiteral): Ty.Type => { + // + }; + + const checkSetLiteral = (node: Ast.SetLiteral): Ty.Type => { + // + }; + + const checkExpr = makeVisitor()({ + null: checkNull, + unit: checkUnit, + string: checkString, + number: checkNumber, + boolean: checkBoolean, + op_unary: checkUnaryExpr, + op_binary: checkBinaryExpr, + conditional: checkTernary, + init_of: checkInitOf, + code_of: checkCodeOf, + struct_instance: checkStructInstance, + static_call: checkFunctionCall, + method_call: checkMethodCall, + field_access: checkField, + var: checkVariable, + tuple: checkTuple, + tensor: checkTensor, + map_literal: checkMapLiteral, + set_literal: checkSetLiteral, + }); + + return { + assignTo, + freshTVar, + checkExpr, + }; +}; + +const substParams = (into: Ty.Type, params: readonly Ty.TypeId[], args: readonly Ty.Type[]) => { + return zip(params, args) + .reduce((type, [param, arg]) => { + return substParam(type, param.text, arg); + }, into); +}; + +const substParam = (into: Ty.Type, param: string, value: Ty.Type): Ty.Type => { + const rec = (into: Ty.Type): Ty.Type => { + switch (into.kind) { + case "ERROR": + case "type_var": + case "TyInt": + case "TySlice": + case "TyCell": + case "TyBuilder": + case "unit_type": { + return into; + } + case "cons_type": { + if (into.name.text !== param) { + return Ty.TypeCons(into.name, into.typeArgs.map(arg => rec(arg)), into.loc); + } + if (into.typeArgs.length !== 0) { + // err.noHkt(param)(into.loc); + } + return value; + } + case "map_type": { + return Ty.TypeMap(rec(into.key), rec(into.value), into.loc); + } + case "tuple_type": { + return Ty.TypeTuple(into.typeArgs.map(arg => rec(arg)), into.loc); + } + case "tensor_type": { + return Ty.TypeTensor(into.typeArgs.map(arg => rec(arg)), into.loc); + } + } + }; + + return rec(into); +}; \ No newline at end of file diff --git a/src/utils/array.ts b/src/utils/array.ts index f8d440d967..50a25d1a89 100644 --- a/src/utils/array.ts +++ b/src/utils/array.ts @@ -6,7 +6,7 @@ export const mapValues = (map: Map, f: (a: A) => B): Map => return new Map(result); }; -export const zip = (arr1: T[], arr2: U[]): [T, U][] => { +export const zip = (arr1: readonly T[], arr2: readonly U[]): [T, U][] => { const length = Math.min(arr1.length, arr2.length); return arr1.slice(0, length).flatMap((item1, index) => { const item2 = arr2[index]; diff --git a/src/utils/tricks.ts b/src/utils/tricks.ts index 2a5663ee67..29ab566d6f 100644 --- a/src/utils/tricks.ts +++ b/src/utils/tricks.ts @@ -26,9 +26,9 @@ interface NonExhaustiveBug { type End = [I] extends [never] ? EndInternal : { - otherwise: (handle: (...input: I) => DO) => O | DO; - end: NonExhaustiveBug; - }; + otherwise: (handle: (...input: I) => DO) => O | DO; + end: NonExhaustiveBug; + }; type MV = End & On; type OnInternal = { @@ -75,14 +75,14 @@ export const match = ( otherwise: (handler) => handler(...(args as unknown as I)), on: (...match: DI) => - (handler: (...args: Extract>) => DO) => - rec>, O | DO>(() => - deepMatch(args, match) - ? handler( - ...(args as unknown as Extract>), - ) - : end(), - ), + (handler: (...args: Extract>) => DO) => + rec>, O | DO>(() => + deepMatch(args, match) + ? handler( + ...(args as unknown as Extract>), + ) + : end(), + ), }); return rec, never>(() => { throw new Error("Not exhaustive"); @@ -108,8 +108,8 @@ export type Unwrap = T extends infer R ? { [K in keyof R]: R[K] } : never; type Inputs = I extends { [Z in T]: infer K } ? K extends string - ? Record unknown> - : never + ? Record unknown> + : never : never; type Outputs = { [K in keyof O]: (input: never) => O[K] }; type Handlers = Unwrap>> & @@ -117,22 +117,22 @@ type Handlers = Unwrap>> & export const makeMakeVisitor = (tag: T) => - () => - (handlers: Handlers) => - (input: Extract): O[keyof O] => { - const handler = (handlers as Record O[keyof O]>)[ - input[tag] - ]; - - // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition - if (handler) { - return handler(input); - } else { - throwInternalCompilerError( - `Reached impossible case: ${input[tag]}`, - ); - } - }; + () => + (handlers: Handlers) => + (input: Extract): O[keyof O] => { + const handler = (handlers as Record O[keyof O]>)[ + input[tag] + ]; + + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + if (handler) { + return handler(input); + } else { + throwInternalCompilerError( + `Reached impossible case: ${input[tag]}`, + ); + } + }; /** * Make visitor for disjoint union (tagged union, discriminated union) @@ -161,3 +161,12 @@ export const memo = (f: (a: A) => B) => { return b; }; }; + +export const includes = ( + keys: readonly K[], + key: string, +): key is K => { + // we have to do this, otherwise, the next line will complain that `key` isn't `K` + const keys1: readonly string[] = keys; + return keys1.includes(key); +}; \ No newline at end of file From d1e3ebba85e7f32d94f0e2bef7f1e0dfb79d26cc Mon Sep 17 00:00:00 2001 From: verytactical <186486509+verytactical@users.noreply.github.com> Date: Tue, 13 May 2025 09:35:47 +0400 Subject: [PATCH 18/38] 1 --- src/next/ast/expression.ts | 12 +- src/next/ast/generated/expression.ts | 10 + src/next/ast/generated/root.ts | 8 +- src/next/ast/root.ts | 8 +- src/next/grammar/grammar.peggy | 8 + src/next/grammar/grammar.ts | 3535 +++++--------------------- src/next/grammar/index.ts | 22 +- src/next/index.ts | 2 +- src/next/scoping/errors.ts | 6 + src/next/scoping/typecheck.ts | 308 ++- 10 files changed, 946 insertions(+), 2973 deletions(-) diff --git a/src/next/ast/expression.ts b/src/next/ast/expression.ts index 844ea0201a..189eba7396 100644 --- a/src/next/ast/expression.ts +++ b/src/next/ast/expression.ts @@ -6,8 +6,9 @@ export type Expression = | OpUnary | Conditional | MethodCall - | FieldAccess | StaticCall + | StaticMethodCall + | FieldAccess | StructInstance | InitOf | CodeOf @@ -120,6 +121,15 @@ export type StaticCall = { readonly loc: Range; }; +export type StaticMethodCall = { + readonly kind: "static_method_call"; + readonly self: TypeId; + readonly typeArgs: readonly Type[]; + readonly function: Id; + readonly args: readonly Expression[]; + readonly loc: Range; +}; + export type StructInstance = { readonly kind: "struct_instance"; readonly type: TypeId; diff --git a/src/next/ast/generated/expression.ts b/src/next/ast/generated/expression.ts index f426b34922..bd51dad71c 100644 --- a/src/next/ast/generated/expression.ts +++ b/src/next/ast/generated/expression.ts @@ -285,3 +285,13 @@ export const SetLiteral = ( }); export const isSetLiteral = ($value: SetLiteral) => $value.kind === "set_literal"; +export type StaticMethodCall = $.StaticMethodCall; +export const StaticMethodCall = (self: $c.TypeId, typeArgs: readonly $t.Type[], function_: $c.Id, args: readonly $.Expression[], loc: $c.Range): $.StaticMethodCall => Object.freeze({ + kind: "static_method_call", + self, + typeArgs, + function: function_, + args, + loc +}); +export const isStaticMethodCall = ($value: StaticMethodCall) => $value.kind === "static_method_call"; diff --git a/src/next/ast/generated/root.ts b/src/next/ast/generated/root.ts index 723a7487df..f3a1e9d8a5 100644 --- a/src/next/ast/generated/root.ts +++ b/src/next/ast/generated/root.ts @@ -77,10 +77,10 @@ export const GetAttribute = (methodId: $e.Expression | undefined, loc: $c.Range) loc }); export type Method = $.Method; -export const Method = (mutates: boolean, virtual: boolean, override: boolean, get: $.GetAttribute | undefined, fun: $.Function): $.Method => Object.freeze({ +export const Method = (mutates: boolean, overridable: boolean, override: boolean, get: $.GetAttribute | undefined, fun: $.Function): $.Method => Object.freeze({ kind: "method", mutates, - virtual, + overridable, override, get, fun @@ -235,9 +235,9 @@ export const Receiver = (selector: $.ReceiverKind, statements: readonly $s.State }); export const isReceiver = ($value: Receiver) => $value.kind === "receiver"; export type FieldConstant = $.FieldConstant; -export const FieldConstant = (virtual: boolean, override: boolean, body: $.Constant): $.FieldConstant => Object.freeze({ +export const FieldConstant = (overridable: boolean, override: boolean, body: $.Constant): $.FieldConstant => Object.freeze({ kind: "field_const", - virtual, + overridable, override, body }); diff --git a/src/next/ast/root.ts b/src/next/ast/root.ts index 791062091f..dc29a88841 100644 --- a/src/next/ast/root.ts +++ b/src/next/ast/root.ts @@ -56,10 +56,11 @@ export type ImportType = "stdlib" | "relative"; export type Contract = { readonly kind: "contract"; + readonly init: undefined | Init; + readonly name: TypeId; readonly traits: readonly TypeId[]; readonly attributes: readonly ContractAttribute[]; - readonly init: undefined | Init; readonly declarations: readonly LocalItem[]; readonly loc: Range; }; @@ -78,6 +79,7 @@ export type InitParams = { export type Trait = { readonly kind: "trait"; + readonly name: TypeId; readonly traits: readonly TypeId[]; readonly attributes: readonly ContractAttribute[]; @@ -106,7 +108,7 @@ export type Extension = { export type Method = { readonly kind: "method"; readonly mutates: boolean; - readonly virtual: boolean; + readonly overridable: boolean; readonly override: boolean; readonly get: undefined | GetAttribute; readonly fun: Function; @@ -160,7 +162,7 @@ export type TypedParameter = { export type FieldConstant = { readonly kind: "field_const"; - readonly virtual: boolean; + readonly overridable: boolean; readonly override: boolean; readonly body: Constant; } diff --git a/src/next/grammar/grammar.peggy b/src/next/grammar/grammar.peggy index 3468f9fcca..4b096326ac 100644 --- a/src/next/grammar/grammar.peggy +++ b/src/next/grammar/grammar.peggy @@ -325,6 +325,7 @@ primary / MapLiteral / SetLiteral / StructInstance + / StaticCall / IntegerLiteral / BoolLiteral / InitOf @@ -342,6 +343,13 @@ Unit = "(" ")"; Tensor = "(" head:expression tail:("," @expression)+ ","? ")"; Tuple = "[" types:commaList? "]"; +StaticCall = + type:TypeId + typeArgs:typeArgs? + "." + name:Id + args:parameterList; + StructInstance = type:TypeId typeArgs:typeArgs? diff --git a/src/next/grammar/grammar.ts b/src/next/grammar/grammar.ts index f2a6f24fb0..90b2cdc2f2 100644 --- a/src/next/grammar/grammar.ts +++ b/src/next/grammar/grammar.ts @@ -6,2905 +6,652 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ import * as $ from "@tonstudio/parser-runtime"; export namespace $ast { - export type Module = $.Located<{ - readonly $: "Module"; - readonly imports: readonly Import[]; - readonly items: readonly moduleItem[]; - }>; - export type Import = $.Located<{ - readonly $: "Import"; - readonly path: StringLiteral; - }>; - export type PrimitiveTypeDecl = $.Located<{ - readonly $: "PrimitiveTypeDecl"; - readonly name: TypeId; - }>; - export type $Function = $.Located<{ - readonly $: "Function"; - readonly attributes: readonly FunctionAttribute[]; - readonly name: Id; - readonly typeParams: typeParams | undefined; - readonly parameters: parameterList; - readonly returnType: ascription | undefined; - readonly body: FunctionDefinition | FunctionDeclaration; - }>; - export type AsmFunction = $.Located<{ - readonly $: "AsmFunction"; - readonly shuffle: shuffle | undefined; - readonly attributes: readonly FunctionAttribute[]; - readonly name: Id; - readonly typeParams: typeParams | undefined; - readonly parameters: parameterList; - readonly returnType: ascription | undefined; - readonly instructions: assembly; - }>; - export type NativeFunctionDecl = $.Located<{ - readonly $: "NativeFunctionDecl"; - readonly nativeName: FuncId; - readonly attributes: readonly FunctionAttribute[]; - readonly name: Id; - readonly typeParams: typeParams | undefined; - readonly parameters: parameterList; - readonly returnType: ascription | undefined; - }>; - export type Constant = $.Located<{ - readonly $: "Constant"; - readonly attributes: readonly ConstantAttribute[]; - readonly name: Id; - readonly type: ascription | undefined; - readonly body: ConstantDefinition | ConstantDeclaration; - }>; - export type StructDecl = $.Located<{ - readonly $: "StructDecl"; - readonly name: TypeId; - readonly typeParams: typeParams | undefined; - readonly fields: structFields; - }>; - export type MessageDecl = $.Located<{ - readonly $: "MessageDecl"; - readonly opcode: expression | undefined; - readonly name: TypeId; - readonly fields: structFields; - }>; - export type UnionDecl = $.Located<{ - readonly $: "UnionDecl"; - readonly name: TypeId; - readonly typeParams: typeParams | undefined; - readonly cases: readonly Case[]; - }>; - export type AliasDecl = $.Located<{ - readonly $: "AliasDecl"; - readonly name: TypeId; - readonly typeParams: typeParams | undefined; - readonly type: $type; - }>; - export type Contract = $.Located<{ - readonly $: "Contract"; - readonly attributes: readonly ContractAttribute[]; - readonly name: TypeId; - readonly parameters: ParameterList | undefined; - readonly traits: inheritedTraits | undefined; - readonly declarations: readonly contractItemDecl[]; - }>; - export type Trait = $.Located<{ - readonly $: "Trait"; - readonly attributes: readonly ContractAttribute[]; - readonly name: TypeId; - readonly traits: inheritedTraits | undefined; - readonly declarations: readonly traitItemDecl[]; - }>; - export type moduleItem = - | PrimitiveTypeDecl - | $Function - | AsmFunction - | NativeFunctionDecl - | Constant - | StructDecl - | MessageDecl - | UnionDecl - | AliasDecl - | Contract - | Trait; - export type ContractInit = $.Located<{ - readonly $: "ContractInit"; - readonly parameters: parameterList; - readonly body: statements; - }>; - export type Receiver = $.Located<{ - readonly $: "Receiver"; - readonly type: ReceiverType; - readonly param: receiverParam; - readonly body: statements; - }>; - export type FieldDecl = $.Located<{ - readonly $: "FieldDecl"; - readonly name: Id; - readonly type: ascription; - readonly expression: expression | undefined; - }>; - export type semicolon = ";" | "}"; - export type storageVar = FieldDecl; - export type contractItemDecl = - | ContractInit - | Receiver - | $Function - | AsmFunction - | Constant - | storageVar; - export type traitItemDecl = - | Receiver - | $Function - | AsmFunction - | Constant - | storageVar; - export type FunctionDefinition = $.Located<{ - readonly $: "FunctionDefinition"; - readonly body: statements; - }>; - export type FunctionDeclaration = $.Located<{ - readonly $: "FunctionDeclaration"; - }>; - export type Id = $.Located<{ - readonly $: "Id"; - readonly name: string; - }>; - export type IntegerLiteralDec = $.Located<{ - readonly $: "IntegerLiteralDec"; - readonly digits: underscored; - }>; - export type shuffle = { - readonly ids: readonly Id[]; - readonly to: readonly IntegerLiteralDec[] | undefined; - }; - export type ConstantAttribute = $.Located<{ - readonly $: "ConstantAttribute"; - readonly name: - | keyword<"virtual"> - | keyword<"override"> - | keyword<"abstract">; - }>; - export type ConstantDefinition = $.Located<{ - readonly $: "ConstantDefinition"; - readonly expression: expression; - }>; - export type ConstantDeclaration = $.Located<{ - readonly $: "ConstantDeclaration"; - }>; - export type Case = $.Located<{ - readonly $: "Case"; - readonly name: TypeId; - readonly fields: structFields; - }>; - export type inter = { - readonly head: A; - readonly tail: readonly { - readonly op: B; - readonly right: A; - }[]; - }; - export type structFields = inter | undefined; - export type keyword = T; - export type commaList = inter; - export type TypeId = $.Located<{ - readonly $: "TypeId"; - readonly name: string; - }>; - export type inheritedTraits = commaList; - export type ContractAttribute = $.Located<{ - readonly $: "ContractAttribute"; - readonly name: StringLiteral; - }>; - export type FunctionAttribute = $.Located<{ - readonly $: "FunctionAttribute"; - readonly name: - | GetAttribute - | keyword<"mutates"> - | keyword<"extends"> - | keyword<"virtual"> - | keyword<"override"> - | keyword<"inline"> - | keyword<"abstract">; - }>; - export type GetAttribute = $.Located<{ - readonly $: "GetAttribute"; - readonly methodId: expression | undefined; - }>; - export type ReceiverType = $.Located<{ - readonly $: "ReceiverType"; - readonly name: "bounced" | keyword<"receive"> | keyword<"external">; - }>; - export type Parameter = $.Located<{ - readonly $: "Parameter"; - readonly name: Id; - readonly type: ascription; - }>; - export type StringLiteral = $.Located<{ - readonly $: "StringLiteral"; - readonly value: string; - }>; - export type receiverParam = Parameter | StringLiteral | undefined; - export type assembly = string; - export type multiLineComment = string; - export type singleLineComment = string; - export type comment = multiLineComment | singleLineComment; - export type assemblyItem = {} | comment | {} | readonly {}[]; - export type assemblySequence = readonly assemblyItem[]; - export type TypeAs = $.Located<{ - readonly $: "TypeAs"; - readonly type: TypeOptional; - readonly as: readonly storage[]; - }>; - export type $type = TypeAs; - export type ascription = $type; - export type TypeOptional = $.Located<{ - readonly $: "TypeOptional"; - readonly type: typePrimary; - readonly optionals: readonly Optional[]; - }>; - export type Optional = $.Located<{ - readonly $: "Optional"; - }>; - export type TypeGeneric = $.Located<{ - readonly $: "TypeGeneric"; - readonly name: MapKeyword | Bounced | TypeId; - readonly args: typeArgs; - }>; - export type TypeRegular = $.Located<{ - readonly $: "TypeRegular"; - readonly child: TypeId; - }>; - export type TypeStorage = $.Located<{ - readonly $: "TypeStorage"; - readonly child: storage; - }>; - export type TypeTuple = $.Located<{ - readonly $: "TypeTuple"; - readonly types: commaList<$type> | undefined; - }>; - export type TypeTensor = $.Located<{ - readonly $: "TypeTensor"; - readonly head: $type; - readonly tail: readonly $type[]; - }>; - export type TypeUnit = $.Located<{ - readonly $: "TypeUnit"; - }>; - export type typeParens = $type; - export type typePrimary = - | TypeGeneric - | TypeRegular - | TypeStorage - | TypeTuple - | TypeTensor - | TypeUnit - | typeParens; - export type MapKeyword = $.Located<{ - readonly $: "MapKeyword"; - }>; - export type Bounced = $.Located<{ - readonly $: "Bounced"; - }>; - export type IntStorage = $.Located<{ - readonly $: "IntStorage"; - readonly isVar: "var" | undefined; - readonly isUnsigned: "u" | undefined; - readonly width: string; - }>; - export type CoinsStorage = $.Located<{ - readonly $: "CoinsStorage"; - }>; - export type RemainingStorage = $.Located<{ - readonly $: "RemainingStorage"; - }>; - export type BytesStorage = $.Located<{ - readonly $: "BytesStorage"; - readonly width: string; - }>; - export type storage = - | IntStorage - | CoinsStorage - | RemainingStorage - | BytesStorage; - export type generic = commaList | undefined; - export type typeParams = generic; - export type typeArgs = generic<$type>; - export type StatementLet = $.Located<{ - readonly $: "StatementLet"; - readonly name: Id; - readonly type: ascription | undefined; - readonly init: expression; - }>; - export type StatementDestruct = $.Located<{ - readonly $: "StatementDestruct"; - readonly type: TypeId; - readonly fields: inter; - readonly rest: optionalRest; - readonly init: expression; - }>; - export type StatementBlock = $.Located<{ - readonly $: "StatementBlock"; - readonly body: statements; - }>; - export type StatementReturn = $.Located<{ - readonly $: "StatementReturn"; - readonly expression: expression | undefined; - }>; - export type StatementCondition = $.Located<{ - readonly $: "StatementCondition"; - readonly condition: expression; - readonly trueBranch: statements; - readonly falseBranch: FalseBranch | StatementCondition | undefined; - }>; - export type StatementWhile = $.Located<{ - readonly $: "StatementWhile"; - readonly condition: parens; - readonly body: statements; - }>; - export type StatementRepeat = $.Located<{ - readonly $: "StatementRepeat"; - readonly condition: parens; - readonly body: statements; - }>; - export type StatementUntil = $.Located<{ - readonly $: "StatementUntil"; - readonly body: statements; - readonly condition: parens; - }>; - export type StatementTry = $.Located<{ - readonly $: "StatementTry"; - readonly body: statements; - readonly handler: - | { - readonly name: Id; - readonly body: statements; - } - | undefined; - }>; - export type StatementForEach = $.Located<{ - readonly $: "StatementForEach"; - readonly key: Id; - readonly value: Id; - readonly expression: expression; - readonly body: statements; - }>; - export type StatementExpression = $.Located<{ - readonly $: "StatementExpression"; - readonly expression: expression; - }>; - export type StatementAssign = $.Located<{ - readonly $: "StatementAssign"; - readonly left: expression; - readonly operator: augmentedOp | "="; - readonly right: expression; - }>; - export type statement = - | StatementLet - | StatementDestruct - | StatementBlock - | StatementReturn - | StatementCondition - | StatementWhile - | StatementRepeat - | StatementUntil - | StatementTry - | StatementForEach - | StatementExpression - | StatementAssign; - export type statements = readonly statement[]; - export type augmentedOp = - | "||=" - | "&&=" - | ">>=" - | "<<=" - | "-=" - | "+=" - | "*=" - | "/=" - | "%=" - | "|=" - | "&=" - | "^="; - export type FalseBranch = $.Located<{ - readonly $: "FalseBranch"; - readonly body: statements; - }>; - export type RegularField = $.Located<{ - readonly $: "RegularField"; - readonly fieldName: Id; - readonly varName: Id; - }>; - export type PunnedField = $.Located<{ - readonly $: "PunnedField"; - readonly name: Id; - }>; - export type destructItem = RegularField | PunnedField; - export type RestArgument = $.Located<{ - readonly $: "RestArgument"; - }>; - export type NoRestArgument = $.Located<{ - readonly $: "NoRestArgument"; - }>; - export type optionalRest = RestArgument | NoRestArgument; - export type Conditional = $.Located<{ - readonly $: "Conditional"; - readonly head: or; - readonly tail: - | { - readonly thenBranch: or; - readonly elseBranch: Conditional; - } - | undefined; - }>; - export type expression = Conditional; - export type Binary = $.Located<{ - readonly $: "Binary"; - readonly exprs: inter>; - }>; - export type Unary = $.Located<{ - readonly $: "Unary"; - readonly prefixes: readonly Operator<"-" | "+" | "!" | "~">[]; - readonly expression: Suffix; - }>; - export type mul = Binary; - export type add = Binary; - export type bitwiseShift = Binary>">; - export type compare = Binary=" | ">">; - export type equality = Binary; - export type bitwiseXor = Binary; - export type bitwiseOr = Binary; - export type and = Binary; - export type or = Binary; - export type Suffix = $.Located<{ - readonly $: "Suffix"; - readonly expression: primary; - readonly suffixes: readonly suffix[]; - }>; - export type Operator = $.Located<{ - readonly $: "Operator"; - readonly name: U; - }>; - export type SuffixUnboxNotNull = $.Located<{ - readonly $: "SuffixUnboxNotNull"; - }>; - export type SuffixCall = $.Located<{ - readonly $: "SuffixCall"; - readonly typeArgs: typeArgs | undefined; - readonly params: parameterList; - }>; - export type SuffixFieldAccess = $.Located<{ - readonly $: "SuffixFieldAccess"; - readonly name: Id; - }>; - export type suffix = SuffixUnboxNotNull | SuffixCall | SuffixFieldAccess; - export type Unit = $.Located<{ - readonly $: "Unit"; - }>; - export type Tensor = $.Located<{ - readonly $: "Tensor"; - readonly head: expression; - readonly tail: readonly expression[]; - }>; - export type Tuple = $.Located<{ - readonly $: "Tuple"; - readonly types: commaList | undefined; - }>; - export type Parens = $.Located<{ - readonly $: "Parens"; - readonly child: parens; - }>; - export type MapLiteral = $.Located<{ - readonly $: "MapLiteral"; - readonly typeArgs: typeArgs; - readonly fields: commaList | undefined; - }>; - export type SetLiteral = $.Located<{ - readonly $: "SetLiteral"; - readonly typeArgs: typeArgs; - readonly fields: commaList | undefined; - }>; - export type StructInstance = $.Located<{ - readonly $: "StructInstance"; - readonly type: TypeId; - readonly typeArgs: typeArgs | undefined; - readonly fields: commaList | undefined; - }>; - export type IntegerLiteral = $.Located<{ - readonly $: "IntegerLiteral"; - readonly value: - | IntegerLiteralHex - | IntegerLiteralBin - | IntegerLiteralOct - | IntegerLiteralDec; - }>; - export type BoolLiteral = $.Located<{ - readonly $: "BoolLiteral"; - readonly value: "true" | "false"; - }>; - export type InitOf = $.Located<{ - readonly $: "InitOf"; - readonly name: TypeId; - readonly params: parameterList; - }>; - export type CodeOf = $.Located<{ - readonly $: "CodeOf"; - readonly name: TypeId; - }>; - export type Null = $.Located<{ - readonly $: "Null"; - }>; - export type primary = - | Unit - | Tensor - | Tuple - | Parens - | MapLiteral - | SetLiteral - | StructInstance - | IntegerLiteral - | BoolLiteral - | InitOf - | CodeOf - | Null - | StringLiteral - | Id; - export type parens = expression; - export type StructFieldInitializer = $.Located<{ - readonly $: "StructFieldInitializer"; - readonly name: Id; - readonly init: expression | undefined; - }>; - export type mapField = { - readonly key: expression; - readonly value: expression; - }; - export type ParameterList = $.Located<{ - readonly $: "ParameterList"; - readonly values: commaList | undefined; - }>; - export type parameterList = commaList | undefined; - export type IntegerLiteralHex = $.Located<{ - readonly $: "IntegerLiteralHex"; - readonly digits: underscored; - }>; - export type IntegerLiteralBin = $.Located<{ - readonly $: "IntegerLiteralBin"; - readonly digits: underscored<"0" | "1">; - }>; - export type IntegerLiteralOct = $.Located<{ - readonly $: "IntegerLiteralOct"; - readonly digits: underscored; - }>; - export type underscored = string; - export type digit = string; - export type idPart = string | string | string | "_"; - export type FuncId = $.Located<{ - readonly $: "FuncId"; - readonly accessor: "." | "~" | undefined; - readonly id: string; - }>; - export type hexDigit = string | string | string; - export type escapeChar = - | "\\" - | '"' - | "n" - | "r" - | "t" - | "v" - | "b" - | "f" - | string - | string - | string; - export type reservedWord = keyword< - | "extend" - | "public" - | "fun" - | "let" - | "return" - | "receive" - | "native" - | "primitive" - | "null" - | "if" - | "else" - | "while" - | "repeat" - | "do" - | "until" - | "try" - | "catch" - | "foreach" - | "as" - | "map" - | "mutates" - | "extends" - | "external" - | "import" - | "with" - | "trait" - | "initOf" - | "override" - | "abstract" - | "virtual" - | "inline" - | "const" - >; - export type space = " " | "\t" | "\r" | "\n" | comment; - export type JustImports = $.Located<{ - readonly $: "JustImports"; - readonly imports: readonly Import[]; - }>; + export type Module = $.Located<{ + readonly $: "Module"; + readonly imports: readonly Import[]; + readonly items: readonly moduleItem[]; + }>; + export type Import = $.Located<{ + readonly $: "Import"; + readonly path: StringLiteral; + }>; + export type PrimitiveTypeDecl = $.Located<{ + readonly $: "PrimitiveTypeDecl"; + readonly name: TypeId; + }>; + export type $Function = $.Located<{ + readonly $: "Function"; + readonly attributes: readonly FunctionAttribute[]; + readonly name: Id; + readonly typeParams: typeParams | undefined; + readonly parameters: parameterList; + readonly returnType: ascription | undefined; + readonly body: FunctionDefinition | FunctionDeclaration; + }>; + export type AsmFunction = $.Located<{ + readonly $: "AsmFunction"; + readonly shuffle: shuffle | undefined; + readonly attributes: readonly FunctionAttribute[]; + readonly name: Id; + readonly typeParams: typeParams | undefined; + readonly parameters: parameterList; + readonly returnType: ascription | undefined; + readonly instructions: assembly; + }>; + export type NativeFunctionDecl = $.Located<{ + readonly $: "NativeFunctionDecl"; + readonly nativeName: FuncId; + readonly attributes: readonly FunctionAttribute[]; + readonly name: Id; + readonly typeParams: typeParams | undefined; + readonly parameters: parameterList; + readonly returnType: ascription | undefined; + }>; + export type Constant = $.Located<{ + readonly $: "Constant"; + readonly attributes: readonly ConstantAttribute[]; + readonly name: Id; + readonly type: ascription | undefined; + readonly body: ConstantDefinition | ConstantDeclaration; + }>; + export type StructDecl = $.Located<{ + readonly $: "StructDecl"; + readonly name: TypeId; + readonly typeParams: typeParams | undefined; + readonly fields: structFields; + }>; + export type MessageDecl = $.Located<{ + readonly $: "MessageDecl"; + readonly opcode: expression | undefined; + readonly name: TypeId; + readonly fields: structFields; + }>; + export type UnionDecl = $.Located<{ + readonly $: "UnionDecl"; + readonly name: TypeId; + readonly typeParams: typeParams | undefined; + readonly cases: readonly Case[]; + }>; + export type AliasDecl = $.Located<{ + readonly $: "AliasDecl"; + readonly name: TypeId; + readonly typeParams: typeParams | undefined; + readonly type: $type; + }>; + export type Contract = $.Located<{ + readonly $: "Contract"; + readonly attributes: readonly ContractAttribute[]; + readonly name: TypeId; + readonly parameters: ParameterList | undefined; + readonly traits: inheritedTraits | undefined; + readonly declarations: readonly contractItemDecl[]; + }>; + export type Trait = $.Located<{ + readonly $: "Trait"; + readonly attributes: readonly ContractAttribute[]; + readonly name: TypeId; + readonly traits: inheritedTraits | undefined; + readonly declarations: readonly traitItemDecl[]; + }>; + export type moduleItem = PrimitiveTypeDecl | $Function | AsmFunction | NativeFunctionDecl | Constant | StructDecl | MessageDecl | UnionDecl | AliasDecl | Contract | Trait; + export type ContractInit = $.Located<{ + readonly $: "ContractInit"; + readonly parameters: parameterList; + readonly body: statements; + }>; + export type Receiver = $.Located<{ + readonly $: "Receiver"; + readonly type: ReceiverType; + readonly param: receiverParam; + readonly body: statements; + }>; + export type FieldDecl = $.Located<{ + readonly $: "FieldDecl"; + readonly name: Id; + readonly type: ascription; + readonly expression: expression | undefined; + }>; + export type semicolon = ";" | "}"; + export type storageVar = FieldDecl; + export type contractItemDecl = ContractInit | Receiver | $Function | AsmFunction | Constant | storageVar; + export type traitItemDecl = Receiver | $Function | AsmFunction | Constant | storageVar; + export type FunctionDefinition = $.Located<{ + readonly $: "FunctionDefinition"; + readonly body: statements; + }>; + export type FunctionDeclaration = $.Located<{ + readonly $: "FunctionDeclaration"; + }>; + export type Id = $.Located<{ + readonly $: "Id"; + readonly name: string; + }>; + export type IntegerLiteralDec = $.Located<{ + readonly $: "IntegerLiteralDec"; + readonly digits: underscored; + }>; + export type shuffle = { + readonly ids: readonly Id[]; + readonly to: readonly IntegerLiteralDec[] | undefined; + }; + export type ConstantAttribute = $.Located<{ + readonly $: "ConstantAttribute"; + readonly name: keyword<"virtual"> | keyword<"override"> | keyword<"abstract">; + }>; + export type ConstantDefinition = $.Located<{ + readonly $: "ConstantDefinition"; + readonly expression: expression; + }>; + export type ConstantDeclaration = $.Located<{ + readonly $: "ConstantDeclaration"; + }>; + export type Case = $.Located<{ + readonly $: "Case"; + readonly name: TypeId; + readonly fields: structFields; + }>; + export type inter = { + readonly head: A; + readonly tail: readonly { + readonly op: B; + readonly right: A; + }[]; + }; + export type structFields = inter | undefined; + export type keyword = T; + export type commaList = inter; + export type TypeId = $.Located<{ + readonly $: "TypeId"; + readonly name: string; + }>; + export type inheritedTraits = commaList; + export type ContractAttribute = $.Located<{ + readonly $: "ContractAttribute"; + readonly name: StringLiteral; + }>; + export type FunctionAttribute = $.Located<{ + readonly $: "FunctionAttribute"; + readonly name: GetAttribute | keyword<"mutates"> | keyword<"extends"> | keyword<"virtual"> | keyword<"override"> | keyword<"inline"> | keyword<"abstract">; + }>; + export type GetAttribute = $.Located<{ + readonly $: "GetAttribute"; + readonly methodId: expression | undefined; + }>; + export type ReceiverType = $.Located<{ + readonly $: "ReceiverType"; + readonly name: "bounced" | keyword<"receive"> | keyword<"external">; + }>; + export type Parameter = $.Located<{ + readonly $: "Parameter"; + readonly name: Id; + readonly type: ascription; + }>; + export type StringLiteral = $.Located<{ + readonly $: "StringLiteral"; + readonly value: string; + }>; + export type receiverParam = Parameter | StringLiteral | undefined; + export type assembly = string; + export type multiLineComment = string; + export type singleLineComment = string; + export type comment = multiLineComment | singleLineComment; + export type assemblyItem = {} | comment | {} | readonly {}[]; + export type assemblySequence = readonly assemblyItem[]; + export type TypeAs = $.Located<{ + readonly $: "TypeAs"; + readonly type: TypeOptional; + readonly as: readonly storage[]; + }>; + export type $type = TypeAs; + export type ascription = $type; + export type TypeOptional = $.Located<{ + readonly $: "TypeOptional"; + readonly type: typePrimary; + readonly optionals: readonly Optional[]; + }>; + export type Optional = $.Located<{ + readonly $: "Optional"; + }>; + export type TypeGeneric = $.Located<{ + readonly $: "TypeGeneric"; + readonly name: MapKeyword | Bounced | TypeId; + readonly args: typeArgs; + }>; + export type TypeRegular = $.Located<{ + readonly $: "TypeRegular"; + readonly child: TypeId; + }>; + export type TypeStorage = $.Located<{ + readonly $: "TypeStorage"; + readonly child: storage; + }>; + export type TypeTuple = $.Located<{ + readonly $: "TypeTuple"; + readonly types: commaList<$type> | undefined; + }>; + export type TypeTensor = $.Located<{ + readonly $: "TypeTensor"; + readonly head: $type; + readonly tail: readonly $type[]; + }>; + export type TypeUnit = $.Located<{ + readonly $: "TypeUnit"; + }>; + export type typeParens = $type; + export type typePrimary = TypeGeneric | TypeRegular | TypeStorage | TypeTuple | TypeTensor | TypeUnit | typeParens; + export type MapKeyword = $.Located<{ + readonly $: "MapKeyword"; + }>; + export type Bounced = $.Located<{ + readonly $: "Bounced"; + }>; + export type IntStorage = $.Located<{ + readonly $: "IntStorage"; + readonly isVar: "var" | undefined; + readonly isUnsigned: "u" | undefined; + readonly width: string; + }>; + export type CoinsStorage = $.Located<{ + readonly $: "CoinsStorage"; + }>; + export type RemainingStorage = $.Located<{ + readonly $: "RemainingStorage"; + }>; + export type BytesStorage = $.Located<{ + readonly $: "BytesStorage"; + readonly width: string; + }>; + export type storage = IntStorage | CoinsStorage | RemainingStorage | BytesStorage; + export type generic = commaList | undefined; + export type typeParams = generic; + export type typeArgs = generic<$type>; + export type StatementLet = $.Located<{ + readonly $: "StatementLet"; + readonly name: Id; + readonly type: ascription | undefined; + readonly init: expression; + }>; + export type StatementDestruct = $.Located<{ + readonly $: "StatementDestruct"; + readonly type: TypeId; + readonly fields: inter; + readonly rest: optionalRest; + readonly init: expression; + }>; + export type StatementBlock = $.Located<{ + readonly $: "StatementBlock"; + readonly body: statements; + }>; + export type StatementReturn = $.Located<{ + readonly $: "StatementReturn"; + readonly expression: expression | undefined; + }>; + export type StatementCondition = $.Located<{ + readonly $: "StatementCondition"; + readonly condition: expression; + readonly trueBranch: statements; + readonly falseBranch: FalseBranch | StatementCondition | undefined; + }>; + export type StatementWhile = $.Located<{ + readonly $: "StatementWhile"; + readonly condition: parens; + readonly body: statements; + }>; + export type StatementRepeat = $.Located<{ + readonly $: "StatementRepeat"; + readonly condition: parens; + readonly body: statements; + }>; + export type StatementUntil = $.Located<{ + readonly $: "StatementUntil"; + readonly body: statements; + readonly condition: parens; + }>; + export type StatementTry = $.Located<{ + readonly $: "StatementTry"; + readonly body: statements; + readonly handler: { + readonly name: Id; + readonly body: statements; + } | undefined; + }>; + export type StatementForEach = $.Located<{ + readonly $: "StatementForEach"; + readonly key: Id; + readonly value: Id; + readonly expression: expression; + readonly body: statements; + }>; + export type StatementExpression = $.Located<{ + readonly $: "StatementExpression"; + readonly expression: expression; + }>; + export type StatementAssign = $.Located<{ + readonly $: "StatementAssign"; + readonly left: expression; + readonly operator: augmentedOp | "="; + readonly right: expression; + }>; + export type statement = StatementLet | StatementDestruct | StatementBlock | StatementReturn | StatementCondition | StatementWhile | StatementRepeat | StatementUntil | StatementTry | StatementForEach | StatementExpression | StatementAssign; + export type statements = readonly statement[]; + export type augmentedOp = "||=" | "&&=" | ">>=" | "<<=" | "-=" | "+=" | "*=" | "/=" | "%=" | "|=" | "&=" | "^="; + export type FalseBranch = $.Located<{ + readonly $: "FalseBranch"; + readonly body: statements; + }>; + export type RegularField = $.Located<{ + readonly $: "RegularField"; + readonly fieldName: Id; + readonly varName: Id; + }>; + export type PunnedField = $.Located<{ + readonly $: "PunnedField"; + readonly name: Id; + }>; + export type destructItem = RegularField | PunnedField; + export type RestArgument = $.Located<{ + readonly $: "RestArgument"; + }>; + export type NoRestArgument = $.Located<{ + readonly $: "NoRestArgument"; + }>; + export type optionalRest = RestArgument | NoRestArgument; + export type Conditional = $.Located<{ + readonly $: "Conditional"; + readonly head: or; + readonly tail: { + readonly thenBranch: or; + readonly elseBranch: Conditional; + } | undefined; + }>; + export type expression = Conditional; + export type Binary = $.Located<{ + readonly $: "Binary"; + readonly exprs: inter>; + }>; + export type Unary = $.Located<{ + readonly $: "Unary"; + readonly prefixes: readonly Operator<"-" | "+" | "!" | "~">[]; + readonly expression: Suffix; + }>; + export type mul = Binary; + export type add = Binary; + export type bitwiseShift = Binary>">; + export type compare = Binary=" | ">">; + export type equality = Binary; + export type bitwiseXor = Binary; + export type bitwiseOr = Binary; + export type and = Binary; + export type or = Binary; + export type Suffix = $.Located<{ + readonly $: "Suffix"; + readonly expression: primary; + readonly suffixes: readonly suffix[]; + }>; + export type Operator = $.Located<{ + readonly $: "Operator"; + readonly name: U; + }>; + export type SuffixUnboxNotNull = $.Located<{ + readonly $: "SuffixUnboxNotNull"; + }>; + export type SuffixCall = $.Located<{ + readonly $: "SuffixCall"; + readonly typeArgs: typeArgs | undefined; + readonly params: parameterList; + }>; + export type SuffixFieldAccess = $.Located<{ + readonly $: "SuffixFieldAccess"; + readonly name: Id; + }>; + export type suffix = SuffixUnboxNotNull | SuffixCall | SuffixFieldAccess; + export type Unit = $.Located<{ + readonly $: "Unit"; + }>; + export type Tensor = $.Located<{ + readonly $: "Tensor"; + readonly head: expression; + readonly tail: readonly expression[]; + }>; + export type Tuple = $.Located<{ + readonly $: "Tuple"; + readonly types: commaList | undefined; + }>; + export type Parens = $.Located<{ + readonly $: "Parens"; + readonly child: parens; + }>; + export type MapLiteral = $.Located<{ + readonly $: "MapLiteral"; + readonly typeArgs: typeArgs; + readonly fields: commaList | undefined; + }>; + export type SetLiteral = $.Located<{ + readonly $: "SetLiteral"; + readonly typeArgs: typeArgs; + readonly fields: commaList | undefined; + }>; + export type StructInstance = $.Located<{ + readonly $: "StructInstance"; + readonly type: TypeId; + readonly typeArgs: typeArgs | undefined; + readonly fields: commaList | undefined; + }>; + export type StaticCall = $.Located<{ + readonly $: "StaticCall"; + readonly type: TypeId; + readonly typeArgs: typeArgs | undefined; + readonly name: Id; + readonly args: parameterList; + }>; + export type IntegerLiteral = $.Located<{ + readonly $: "IntegerLiteral"; + readonly value: IntegerLiteralHex | IntegerLiteralBin | IntegerLiteralOct | IntegerLiteralDec; + }>; + export type BoolLiteral = $.Located<{ + readonly $: "BoolLiteral"; + readonly value: "true" | "false"; + }>; + export type InitOf = $.Located<{ + readonly $: "InitOf"; + readonly name: TypeId; + readonly params: parameterList; + }>; + export type CodeOf = $.Located<{ + readonly $: "CodeOf"; + readonly name: TypeId; + }>; + export type Null = $.Located<{ + readonly $: "Null"; + }>; + export type primary = Unit | Tensor | Tuple | Parens | MapLiteral | SetLiteral | StructInstance | StaticCall | IntegerLiteral | BoolLiteral | InitOf | CodeOf | Null | StringLiteral | Id; + export type parens = expression; + export type StructFieldInitializer = $.Located<{ + readonly $: "StructFieldInitializer"; + readonly name: Id; + readonly init: expression | undefined; + }>; + export type mapField = { + readonly key: expression; + readonly value: expression; + }; + export type ParameterList = $.Located<{ + readonly $: "ParameterList"; + readonly values: commaList | undefined; + }>; + export type parameterList = commaList | undefined; + export type IntegerLiteralHex = $.Located<{ + readonly $: "IntegerLiteralHex"; + readonly digits: underscored; + }>; + export type IntegerLiteralBin = $.Located<{ + readonly $: "IntegerLiteralBin"; + readonly digits: underscored<"0" | "1">; + }>; + export type IntegerLiteralOct = $.Located<{ + readonly $: "IntegerLiteralOct"; + readonly digits: underscored; + }>; + export type underscored = string; + export type digit = string; + export type idPart = string | string | string | "_"; + export type FuncId = $.Located<{ + readonly $: "FuncId"; + readonly accessor: "." | "~" | undefined; + readonly id: string; + }>; + export type hexDigit = string | string | string; + export type escapeChar = "\\" | "\"" | "n" | "r" | "t" | "v" | "b" | "f" | string | string | string; + export type reservedWord = keyword<"extend" | "public" | "fun" | "let" | "return" | "receive" | "native" | "primitive" | "null" | "if" | "else" | "while" | "repeat" | "do" | "until" | "try" | "catch" | "foreach" | "as" | "map" | "mutates" | "extends" | "external" | "import" | "with" | "trait" | "initOf" | "override" | "abstract" | "virtual" | "inline" | "const">; + export type space = " " | "\t" | "\r" | "\n" | comment; + export type JustImports = $.Located<{ + readonly $: "JustImports"; + readonly imports: readonly Import[]; + }>; } -export const Module: $.Parser<$ast.Module> = $.loc( - $.field( - $.pure("Module"), - "$", - $.field( - $.star($.lazy(() => Import)), - "imports", - $.field($.star($.lazy(() => moduleItem)), "items", $.eps), - ), - ), -); -export const Import: $.Parser<$ast.Import> = $.loc( - $.field( - $.pure("Import"), - "$", - $.right( - $.lazy(() => keyword($.str("import"))), - $.field( - $.lazy(() => StringLiteral), - "path", - $.right($.str(";"), $.eps), - ), - ), - ), -); -export const PrimitiveTypeDecl: $.Parser<$ast.PrimitiveTypeDecl> = $.loc( - $.field( - $.pure("PrimitiveTypeDecl"), - "$", - $.right( - $.lazy(() => keyword($.str("primitive"))), - $.field( - $.lazy(() => TypeId), - "name", - $.right($.str(";"), $.eps), - ), - ), - ), -); -export const $Function: $.Parser<$ast.$Function> = $.loc( - $.field( - $.pure("Function"), - "$", - $.field( - $.star($.lazy(() => FunctionAttribute)), - "attributes", - $.right( - $.lazy(() => keyword($.str("fun"))), - $.field( - $.lazy(() => Id), - "name", - $.field( - $.opt($.lazy(() => typeParams)), - "typeParams", - $.field( - $.lazy(() => - parameterList($.lazy(() => Parameter)), - ), - "parameters", - $.field( - $.opt($.lazy(() => ascription)), - "returnType", - $.field( - $.alt( - $.lazy(() => FunctionDefinition), - $.lazy(() => FunctionDeclaration), - ), - "body", - $.eps, - ), - ), - ), - ), - ), - ), - ), - ), -); -export const AsmFunction: $.Parser<$ast.AsmFunction> = $.loc( - $.field( - $.pure("AsmFunction"), - "$", - $.right( - $.str("asm"), - $.field( - $.opt($.lazy(() => shuffle)), - "shuffle", - $.field( - $.star($.lazy(() => FunctionAttribute)), - "attributes", - $.right( - $.lazy(() => keyword($.str("fun"))), - $.field( - $.lazy(() => Id), - "name", - $.field( - $.opt($.lazy(() => typeParams)), - "typeParams", - $.field( - $.lazy(() => - parameterList($.lazy(() => Parameter)), - ), - "parameters", - $.field( - $.opt($.lazy(() => ascription)), - "returnType", - $.right( - $.str("{"), - $.field( - $.lazy(() => assembly), - "instructions", - $.right($.str("}"), $.eps), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), -); -export const NativeFunctionDecl: $.Parser<$ast.NativeFunctionDecl> = $.loc( - $.field( - $.pure("NativeFunctionDecl"), - "$", - $.right( - $.str("@name"), - $.right( - $.str("("), - $.field( - $.lex($.lazy(() => FuncId)), - "nativeName", - $.right( - $.str(")"), - $.field( - $.star($.lazy(() => FunctionAttribute)), - "attributes", - $.right( - $.lazy(() => keyword($.str("native"))), - $.field( - $.lazy(() => Id), - "name", - $.field( - $.opt($.lazy(() => typeParams)), - "typeParams", - $.field( - $.lazy(() => - parameterList( - $.lazy(() => Parameter), - ), - ), - "parameters", - $.field( - $.opt($.lazy(() => ascription)), - "returnType", - $.right($.str(";"), $.eps), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), -); -export const Constant: $.Parser<$ast.Constant> = $.loc( - $.field( - $.pure("Constant"), - "$", - $.field( - $.star($.lazy(() => ConstantAttribute)), - "attributes", - $.right( - $.lazy(() => keyword($.str("const"))), - $.field( - $.lazy(() => Id), - "name", - $.field( - $.opt($.lazy(() => ascription)), - "type", - $.field( - $.alt( - $.lazy(() => ConstantDefinition), - $.lazy(() => ConstantDeclaration), - ), - "body", - $.eps, - ), - ), - ), - ), - ), - ), -); -export const StructDecl: $.Parser<$ast.StructDecl> = $.loc( - $.field( - $.pure("StructDecl"), - "$", - $.right( - $.str("struct"), - $.field( - $.lazy(() => TypeId), - "name", - $.field( - $.opt($.lazy(() => typeParams)), - "typeParams", - $.right( - $.str("{"), - $.field( - $.lazy(() => structFields), - "fields", - $.right($.str("}"), $.eps), - ), - ), - ), - ), - ), - ), -); -export const MessageDecl: $.Parser<$ast.MessageDecl> = $.loc( - $.field( - $.pure("MessageDecl"), - "$", - $.right( - $.str("message"), - $.field( - $.opt( - $.right( - $.str("("), - $.left( - $.lazy(() => expression), - $.str(")"), - ), - ), - ), - "opcode", - $.field( - $.lazy(() => TypeId), - "name", - $.right( - $.str("{"), - $.field( - $.lazy(() => structFields), - "fields", - $.right($.str("}"), $.eps), - ), - ), - ), - ), - ), - ), -); -export const UnionDecl: $.Parser<$ast.UnionDecl> = $.loc( - $.field( - $.pure("UnionDecl"), - "$", - $.right( - $.str("union"), - $.field( - $.lazy(() => TypeId), - "name", - $.field( - $.opt($.lazy(() => typeParams)), - "typeParams", - $.right( - $.str("{"), - $.field( - $.star($.lazy(() => Case)), - "cases", - $.right($.str("}"), $.eps), - ), - ), - ), - ), - ), - ), -); -export const AliasDecl: $.Parser<$ast.AliasDecl> = $.loc( - $.field( - $.pure("AliasDecl"), - "$", - $.right( - $.str("type"), - $.field( - $.lazy(() => TypeId), - "name", - $.field( - $.opt($.lazy(() => typeParams)), - "typeParams", - $.right( - $.str("="), - $.field( - $.lazy(() => $type), - "type", - $.right($.str(";"), $.eps), - ), - ), - ), - ), - ), - ), -); -export const Contract: $.Parser<$ast.Contract> = $.loc( - $.field( - $.pure("Contract"), - "$", - $.field( - $.star($.lazy(() => ContractAttribute)), - "attributes", - $.right( - $.lazy(() => keyword($.str("contract"))), - $.field( - $.lazy(() => TypeId), - "name", - $.field( - $.opt( - $.lazy(() => - ParameterList($.lazy(() => Parameter)), - ), - ), - "parameters", - $.field( - $.opt($.lazy(() => inheritedTraits)), - "traits", - $.right( - $.str("{"), - $.field( - $.star($.lazy(() => contractItemDecl)), - "declarations", - $.right($.str("}"), $.eps), - ), - ), - ), - ), - ), - ), - ), - ), -); -export const Trait: $.Parser<$ast.Trait> = $.loc( - $.field( - $.pure("Trait"), - "$", - $.field( - $.star($.lazy(() => ContractAttribute)), - "attributes", - $.right( - $.lazy(() => keyword($.str("trait"))), - $.field( - $.lazy(() => TypeId), - "name", - $.field( - $.opt($.lazy(() => inheritedTraits)), - "traits", - $.right( - $.str("{"), - $.field( - $.star($.lazy(() => traitItemDecl)), - "declarations", - $.right($.str("}"), $.eps), - ), - ), - ), - ), - ), - ), - ), -); -export const moduleItem: $.Parser<$ast.moduleItem> = $.alt( - PrimitiveTypeDecl, - $.alt( - $Function, - $.alt( - AsmFunction, - $.alt( - NativeFunctionDecl, - $.alt( - Constant, - $.alt( - StructDecl, - $.alt( - MessageDecl, - $.alt( - UnionDecl, - $.alt(AliasDecl, $.alt(Contract, Trait)), - ), - ), - ), - ), - ), - ), - ), -); -export const ContractInit: $.Parser<$ast.ContractInit> = $.loc( - $.field( - $.pure("ContractInit"), - "$", - $.right( - $.str("init"), - $.field( - $.lazy(() => parameterList($.lazy(() => Parameter))), - "parameters", - $.field( - $.lazy(() => statements), - "body", - $.eps, - ), - ), - ), - ), -); -export const Receiver: $.Parser<$ast.Receiver> = $.loc( - $.field( - $.pure("Receiver"), - "$", - $.field( - $.lazy(() => ReceiverType), - "type", - $.right( - $.str("("), - $.field( - $.lazy(() => receiverParam), - "param", - $.right( - $.str(")"), - $.field( - $.lazy(() => statements), - "body", - $.eps, - ), - ), - ), - ), - ), - ), -); -export const FieldDecl: $.Parser<$ast.FieldDecl> = $.loc( - $.field( - $.pure("FieldDecl"), - "$", - $.field( - $.lazy(() => Id), - "name", - $.field( - $.lazy(() => ascription), - "type", - $.field( - $.opt( - $.right( - $.str("="), - $.lazy(() => expression), - ), - ), - "expression", - $.eps, - ), - ), - ), - ), -); -export const semicolon: $.Parser<$ast.semicolon> = $.alt( - $.str(";"), - $.lookPos($.str("}")), -); -export const storageVar: $.Parser<$ast.storageVar> = $.left( - FieldDecl, - semicolon, -); -export const contractItemDecl: $.Parser<$ast.contractItemDecl> = $.alt( - ContractInit, - $.alt( - Receiver, - $.alt($Function, $.alt(AsmFunction, $.alt(Constant, storageVar))), - ), -); -export const traitItemDecl: $.Parser<$ast.traitItemDecl> = $.alt( - Receiver, - $.alt($Function, $.alt(AsmFunction, $.alt(Constant, storageVar))), -); -export const FunctionDefinition: $.Parser<$ast.FunctionDefinition> = $.loc( - $.field( - $.pure("FunctionDefinition"), - "$", - $.field( - $.lazy(() => statements), - "body", - $.eps, - ), - ), -); -export const FunctionDeclaration: $.Parser<$ast.FunctionDeclaration> = $.loc( - $.field($.pure("FunctionDeclaration"), "$", $.right(semicolon, $.eps)), -); -export const Id: $.Parser<$ast.Id> = $.named( - "identifier", - $.loc( - $.field( - $.pure("Id"), - "$", - $.field( - $.lex( - $.stry( - $.right( - $.lookNeg($.lazy(() => reservedWord)), - $.right( - $.alt( - $.right( - $.regex( - "a-zA-Z_", - [ - $.ExpRange("a", "z"), - $.ExpRange("A", "Z"), - $.ExpString("_"), - ], - ), - $.right( - $.star($.lazy(() => idPart)), - $.eps, - ), - ), - $.str("$"), - ), - $.eps, - ), - ), - ), - ), - "name", - $.eps, - ), - ), - ), -); -export const IntegerLiteralDec: $.Parser<$ast.IntegerLiteralDec> = $.loc( - $.field( - $.pure("IntegerLiteralDec"), - "$", - $.field( - $.lex($.lazy(() => underscored($.lazy(() => digit)))), - "digits", - $.eps, - ), - ), -); -export const shuffle: $.Parser<$ast.shuffle> = $.right( - $.str("("), - $.field( - $.star(Id), - "ids", - $.field( - $.opt($.right($.str("->"), $.plus(IntegerLiteralDec))), - "to", - $.right($.str(")"), $.eps), - ), - ), -); -export const ConstantAttribute: $.Parser<$ast.ConstantAttribute> = $.loc( - $.field( - $.pure("ConstantAttribute"), - "$", - $.field( - $.alt( - $.lazy(() => keyword($.str("virtual"))), - $.alt( - $.lazy(() => keyword($.str("override"))), - $.lazy(() => keyword($.str("abstract"))), - ), - ), - "name", - $.eps, - ), - ), -); -export const ConstantDefinition: $.Parser<$ast.ConstantDefinition> = $.loc( - $.field( - $.pure("ConstantDefinition"), - "$", - $.right( - $.str("="), - $.field( - $.lazy(() => expression), - "expression", - $.right(semicolon, $.eps), - ), - ), - ), -); -export const ConstantDeclaration: $.Parser<$ast.ConstantDeclaration> = $.loc( - $.field($.pure("ConstantDeclaration"), "$", $.right(semicolon, $.eps)), -); -export const Case: $.Parser<$ast.Case> = $.loc( - $.field( - $.pure("Case"), - "$", - $.field( - $.lazy(() => TypeId), - "name", - $.right( - $.str("{"), - $.field( - $.lazy(() => structFields), - "fields", - $.right($.str("}"), $.eps), - ), - ), - ), - ), -); -export const inter = ( - A: $.Parser, - B: $.Parser, -): $.Parser<$ast.inter> => - $.field( - $.lazy(() => A), - "head", - $.field( - $.star( - $.field( - $.lazy(() => B), - "op", - $.field( - $.lazy(() => A), - "right", - $.eps, - ), - ), - ), - "tail", - $.eps, - ), - ); -export const structFields: $.Parser<$ast.structFields> = $.left( - $.opt(inter(FieldDecl, $.str(";"))), - $.opt($.str(";")), -); -export const keyword = (T: $.Parser): $.Parser<$ast.keyword> => - $.lex( - $.left( - $.lazy(() => T), - $.lookNeg($.lazy(() => idPart)), - ), - ); -export const commaList = (T: $.Parser): $.Parser<$ast.commaList> => - $.left( - inter( - $.lazy(() => T), - $.str(","), - ), - $.opt($.str(",")), - ); -export const TypeId: $.Parser<$ast.TypeId> = $.named( - "capitalized identifier", - $.loc( - $.field( - $.pure("TypeId"), - "$", - $.field( - $.lex( - $.stry( - $.right( - $.regex("A-Z", [$.ExpRange("A", "Z")]), - $.right( - $.star( - $.regex( - "a-zA-Z0-9_", - [ - $.ExpRange("a", "z"), - $.ExpRange("A", "Z"), - $.ExpRange("0", "9"), - $.ExpString("_"), - ], - ), - ), - $.eps, - ), - ), - ), - ), - "name", - $.eps, - ), - ), - ), -); -export const inheritedTraits: $.Parser<$ast.inheritedTraits> = $.right( - keyword($.str("with")), - commaList(TypeId), -); -export const ContractAttribute: $.Parser<$ast.ContractAttribute> = $.loc( - $.field( - $.pure("ContractAttribute"), - "$", - $.right( - $.str("@interface"), - $.right( - $.str("("), - $.field( - $.lazy(() => StringLiteral), - "name", - $.right($.str(")"), $.eps), - ), - ), - ), - ), -); -export const FunctionAttribute: $.Parser<$ast.FunctionAttribute> = $.loc( - $.field( - $.pure("FunctionAttribute"), - "$", - $.field( - $.alt( - $.lazy(() => GetAttribute), - $.alt( - keyword($.str("mutates")), - $.alt( - keyword($.str("extends")), - $.alt( - keyword($.str("virtual")), - $.alt( - keyword($.str("override")), - $.alt( - keyword($.str("inline")), - keyword($.str("abstract")), - ), - ), - ), - ), - ), - ), - "name", - $.eps, - ), - ), -); -export const GetAttribute: $.Parser<$ast.GetAttribute> = $.loc( - $.field( - $.pure("GetAttribute"), - "$", - $.right( - $.str("get"), - $.field( - $.opt( - $.right( - $.str("("), - $.left( - $.lazy(() => expression), - $.str(")"), - ), - ), - ), - "methodId", - $.eps, - ), - ), - ), -); -export const ReceiverType: $.Parser<$ast.ReceiverType> = $.loc( - $.field( - $.pure("ReceiverType"), - "$", - $.field( - $.alt( - $.str("bounced"), - $.alt(keyword($.str("receive")), keyword($.str("external"))), - ), - "name", - $.eps, - ), - ), -); -export const Parameter: $.Parser<$ast.Parameter> = $.loc( - $.field( - $.pure("Parameter"), - "$", - $.field( - Id, - "name", - $.field( - $.lazy(() => ascription), - "type", - $.eps, - ), - ), - ), -); -export const StringLiteral: $.Parser<$ast.StringLiteral> = $.loc( - $.field( - $.pure("StringLiteral"), - "$", - $.field( - $.lex( - $.right( - $.str('"'), - $.left( - $.stry( - $.star( - $.alt( - $.regex<'"' | "\\">( - '^"\\\\', - $.negateExps([ - $.ExpString('"'), - $.ExpString("\\"), - ]), - ), - $.right( - $.str("\\"), - $.lazy(() => escapeChar), - ), - ), - ), - ), - $.str('"'), - ), - ), - ), - "value", - $.eps, - ), - ), -); -export const receiverParam: $.Parser<$ast.receiverParam> = $.opt( - $.alt(Parameter, StringLiteral), -); -export const assembly: $.Parser<$ast.assembly> = $.lex( - $.stry($.lazy(() => assemblySequence)), -); -export const multiLineComment: $.Parser<$ast.multiLineComment> = $.right( - $.str("/*"), - $.left( - $.stry($.star($.right($.lookNeg($.str("*/")), $.right($.any, $.eps)))), - $.str("*/"), - ), -); -export const singleLineComment: $.Parser<$ast.singleLineComment> = $.right( - $.str("//"), - $.stry( - $.star( - $.regex<"\r" | "\n">( - "^\\r\\n", - $.negateExps([$.ExpString("\r"), $.ExpString("\n")]), - ), - ), - ), -); -export const comment: $.Parser<$ast.comment> = $.alt( - multiLineComment, - singleLineComment, -); -export const assemblyItem: $.Parser<$ast.assemblyItem> = $.alt( - $.right( - $.str("{"), - $.right( - $.lazy(() => assemblySequence), - $.right($.str("}"), $.eps), - ), - ), - $.alt( - comment, - $.alt( - $.right( - $.str('"'), - $.right( - $.star( - $.regex<'"'>('^"', $.negateExps([$.ExpString('"')])), - ), - $.right($.str('"'), $.eps), - ), - ), - $.plus( - $.right( - $.lookNeg( - $.alt( - $.regex<'"' | "{" | "}">('"{}', [ - $.ExpString('"'), - $.ExpString("{"), - $.ExpString("}"), - ]), - $.alt($.str("//"), $.str("/*")), - ), - ), - $.right($.any, $.eps), - ), - ), - ), - ), -); -export const assemblySequence: $.Parser<$ast.assemblySequence> = - $.star(assemblyItem); -export const TypeAs: $.Parser<$ast.TypeAs> = $.loc( - $.field( - $.pure("TypeAs"), - "$", - $.field( - $.lazy(() => TypeOptional), - "type", - $.field( - $.star( - $.right(keyword($.str("as")), $.lex($.lazy(() => storage))), - ), - "as", - $.eps, - ), - ), - ), -); +export const Module: $.Parser<$ast.Module> = $.loc($.field($.pure("Module"), "$", $.field($.star($.lazy(() => Import)), "imports", $.field($.star($.lazy(() => moduleItem)), "items", $.eps)))); +export const Import: $.Parser<$ast.Import> = $.loc($.field($.pure("Import"), "$", $.right($.lazy(() => keyword($.str("import"))), $.field($.lazy(() => StringLiteral), "path", $.right($.str(";"), $.eps))))); +export const PrimitiveTypeDecl: $.Parser<$ast.PrimitiveTypeDecl> = $.loc($.field($.pure("PrimitiveTypeDecl"), "$", $.right($.lazy(() => keyword($.str("primitive"))), $.field($.lazy(() => TypeId), "name", $.right($.str(";"), $.eps))))); +export const $Function: $.Parser<$ast.$Function> = $.loc($.field($.pure("Function"), "$", $.field($.star($.lazy(() => FunctionAttribute)), "attributes", $.right($.lazy(() => keyword($.str("fun"))), $.field($.lazy(() => Id), "name", $.field($.opt($.lazy(() => typeParams)), "typeParams", $.field($.lazy(() => parameterList($.lazy(() => Parameter))), "parameters", $.field($.opt($.lazy(() => ascription)), "returnType", $.field($.alt($.lazy(() => FunctionDefinition), $.lazy(() => FunctionDeclaration)), "body", $.eps))))))))); +export const AsmFunction: $.Parser<$ast.AsmFunction> = $.loc($.field($.pure("AsmFunction"), "$", $.right($.str("asm"), $.field($.opt($.lazy(() => shuffle)), "shuffle", $.field($.star($.lazy(() => FunctionAttribute)), "attributes", $.right($.lazy(() => keyword($.str("fun"))), $.field($.lazy(() => Id), "name", $.field($.opt($.lazy(() => typeParams)), "typeParams", $.field($.lazy(() => parameterList($.lazy(() => Parameter))), "parameters", $.field($.opt($.lazy(() => ascription)), "returnType", $.right($.str("{"), $.field($.lazy(() => assembly), "instructions", $.right($.str("}"), $.eps))))))))))))); +export const NativeFunctionDecl: $.Parser<$ast.NativeFunctionDecl> = $.loc($.field($.pure("NativeFunctionDecl"), "$", $.right($.str("@name"), $.right($.str("("), $.field($.lex($.lazy(() => FuncId)), "nativeName", $.right($.str(")"), $.field($.star($.lazy(() => FunctionAttribute)), "attributes", $.right($.lazy(() => keyword($.str("native"))), $.field($.lazy(() => Id), "name", $.field($.opt($.lazy(() => typeParams)), "typeParams", $.field($.lazy(() => parameterList($.lazy(() => Parameter))), "parameters", $.field($.opt($.lazy(() => ascription)), "returnType", $.right($.str(";"), $.eps))))))))))))); +export const Constant: $.Parser<$ast.Constant> = $.loc($.field($.pure("Constant"), "$", $.field($.star($.lazy(() => ConstantAttribute)), "attributes", $.right($.lazy(() => keyword($.str("const"))), $.field($.lazy(() => Id), "name", $.field($.opt($.lazy(() => ascription)), "type", $.field($.alt($.lazy(() => ConstantDefinition), $.lazy(() => ConstantDeclaration)), "body", $.eps))))))); +export const StructDecl: $.Parser<$ast.StructDecl> = $.loc($.field($.pure("StructDecl"), "$", $.right($.str("struct"), $.field($.lazy(() => TypeId), "name", $.field($.opt($.lazy(() => typeParams)), "typeParams", $.right($.str("{"), $.field($.lazy(() => structFields), "fields", $.right($.str("}"), $.eps)))))))); +export const MessageDecl: $.Parser<$ast.MessageDecl> = $.loc($.field($.pure("MessageDecl"), "$", $.right($.str("message"), $.field($.opt($.right($.str("("), $.left($.lazy(() => expression), $.str(")")))), "opcode", $.field($.lazy(() => TypeId), "name", $.right($.str("{"), $.field($.lazy(() => structFields), "fields", $.right($.str("}"), $.eps)))))))); +export const UnionDecl: $.Parser<$ast.UnionDecl> = $.loc($.field($.pure("UnionDecl"), "$", $.right($.str("union"), $.field($.lazy(() => TypeId), "name", $.field($.opt($.lazy(() => typeParams)), "typeParams", $.right($.str("{"), $.field($.star($.lazy(() => Case)), "cases", $.right($.str("}"), $.eps)))))))); +export const AliasDecl: $.Parser<$ast.AliasDecl> = $.loc($.field($.pure("AliasDecl"), "$", $.right($.str("type"), $.field($.lazy(() => TypeId), "name", $.field($.opt($.lazy(() => typeParams)), "typeParams", $.right($.str("="), $.field($.lazy(() => $type), "type", $.right($.str(";"), $.eps)))))))); +export const Contract: $.Parser<$ast.Contract> = $.loc($.field($.pure("Contract"), "$", $.field($.star($.lazy(() => ContractAttribute)), "attributes", $.right($.lazy(() => keyword($.str("contract"))), $.field($.lazy(() => TypeId), "name", $.field($.opt($.lazy(() => ParameterList($.lazy(() => Parameter)))), "parameters", $.field($.opt($.lazy(() => inheritedTraits)), "traits", $.right($.str("{"), $.field($.star($.lazy(() => contractItemDecl)), "declarations", $.right($.str("}"), $.eps)))))))))); +export const Trait: $.Parser<$ast.Trait> = $.loc($.field($.pure("Trait"), "$", $.field($.star($.lazy(() => ContractAttribute)), "attributes", $.right($.lazy(() => keyword($.str("trait"))), $.field($.lazy(() => TypeId), "name", $.field($.opt($.lazy(() => inheritedTraits)), "traits", $.right($.str("{"), $.field($.star($.lazy(() => traitItemDecl)), "declarations", $.right($.str("}"), $.eps))))))))); +export const moduleItem: $.Parser<$ast.moduleItem> = $.alt(PrimitiveTypeDecl, $.alt($Function, $.alt(AsmFunction, $.alt(NativeFunctionDecl, $.alt(Constant, $.alt(StructDecl, $.alt(MessageDecl, $.alt(UnionDecl, $.alt(AliasDecl, $.alt(Contract, Trait)))))))))); +export const ContractInit: $.Parser<$ast.ContractInit> = $.loc($.field($.pure("ContractInit"), "$", $.right($.str("init"), $.field($.lazy(() => parameterList($.lazy(() => Parameter))), "parameters", $.field($.lazy(() => statements), "body", $.eps))))); +export const Receiver: $.Parser<$ast.Receiver> = $.loc($.field($.pure("Receiver"), "$", $.field($.lazy(() => ReceiverType), "type", $.right($.str("("), $.field($.lazy(() => receiverParam), "param", $.right($.str(")"), $.field($.lazy(() => statements), "body", $.eps))))))); +export const FieldDecl: $.Parser<$ast.FieldDecl> = $.loc($.field($.pure("FieldDecl"), "$", $.field($.lazy(() => Id), "name", $.field($.lazy(() => ascription), "type", $.field($.opt($.right($.str("="), $.lazy(() => expression))), "expression", $.eps))))); +export const semicolon: $.Parser<$ast.semicolon> = $.alt($.str(";"), $.lookPos($.str("}"))); +export const storageVar: $.Parser<$ast.storageVar> = $.left(FieldDecl, semicolon); +export const contractItemDecl: $.Parser<$ast.contractItemDecl> = $.alt(ContractInit, $.alt(Receiver, $.alt($Function, $.alt(AsmFunction, $.alt(Constant, storageVar))))); +export const traitItemDecl: $.Parser<$ast.traitItemDecl> = $.alt(Receiver, $.alt($Function, $.alt(AsmFunction, $.alt(Constant, storageVar)))); +export const FunctionDefinition: $.Parser<$ast.FunctionDefinition> = $.loc($.field($.pure("FunctionDefinition"), "$", $.field($.lazy(() => statements), "body", $.eps))); +export const FunctionDeclaration: $.Parser<$ast.FunctionDeclaration> = $.loc($.field($.pure("FunctionDeclaration"), "$", $.right(semicolon, $.eps))); +export const Id: $.Parser<$ast.Id> = $.named("identifier", $.loc($.field($.pure("Id"), "$", $.field($.lex($.stry($.right($.lookNeg($.lazy(() => reservedWord)), $.right($.alt($.right($.regex("a-zA-Z_", [$.ExpRange("a", "z"), $.ExpRange("A", "Z"), $.ExpString("_")]), $.right($.star($.lazy(() => idPart)), $.eps)), $.str("$")), $.eps)))), "name", $.eps)))); +export const IntegerLiteralDec: $.Parser<$ast.IntegerLiteralDec> = $.loc($.field($.pure("IntegerLiteralDec"), "$", $.field($.lex($.lazy(() => underscored($.lazy(() => digit)))), "digits", $.eps))); +export const shuffle: $.Parser<$ast.shuffle> = $.right($.str("("), $.field($.star(Id), "ids", $.field($.opt($.right($.str("->"), $.plus(IntegerLiteralDec))), "to", $.right($.str(")"), $.eps)))); +export const ConstantAttribute: $.Parser<$ast.ConstantAttribute> = $.loc($.field($.pure("ConstantAttribute"), "$", $.field($.alt($.lazy(() => keyword($.str("virtual"))), $.alt($.lazy(() => keyword($.str("override"))), $.lazy(() => keyword($.str("abstract"))))), "name", $.eps))); +export const ConstantDefinition: $.Parser<$ast.ConstantDefinition> = $.loc($.field($.pure("ConstantDefinition"), "$", $.right($.str("="), $.field($.lazy(() => expression), "expression", $.right(semicolon, $.eps))))); +export const ConstantDeclaration: $.Parser<$ast.ConstantDeclaration> = $.loc($.field($.pure("ConstantDeclaration"), "$", $.right(semicolon, $.eps))); +export const Case: $.Parser<$ast.Case> = $.loc($.field($.pure("Case"), "$", $.field($.lazy(() => TypeId), "name", $.right($.str("{"), $.field($.lazy(() => structFields), "fields", $.right($.str("}"), $.eps)))))); +export const inter = (A: $.Parser, B: $.Parser): $.Parser<$ast.inter> => $.field($.lazy(() => A), "head", $.field($.star($.field($.lazy(() => B), "op", $.field($.lazy(() => A), "right", $.eps))), "tail", $.eps)); +export const structFields: $.Parser<$ast.structFields> = $.left($.opt(inter(FieldDecl, $.str(";"))), $.opt($.str(";"))); +export const keyword = (T: $.Parser): $.Parser<$ast.keyword> => $.lex($.left($.lazy(() => T), $.lookNeg($.lazy(() => idPart)))); +export const commaList = (T: $.Parser): $.Parser<$ast.commaList> => $.left(inter($.lazy(() => T), $.str(",")), $.opt($.str(","))); +export const TypeId: $.Parser<$ast.TypeId> = $.named("capitalized identifier", $.loc($.field($.pure("TypeId"), "$", $.field($.lex($.stry($.right($.regex("A-Z", [$.ExpRange("A", "Z")]), $.right($.star($.regex("a-zA-Z0-9_", [$.ExpRange("a", "z"), $.ExpRange("A", "Z"), $.ExpRange("0", "9"), $.ExpString("_")])), $.eps)))), "name", $.eps)))); +export const inheritedTraits: $.Parser<$ast.inheritedTraits> = $.right(keyword($.str("with")), commaList(TypeId)); +export const ContractAttribute: $.Parser<$ast.ContractAttribute> = $.loc($.field($.pure("ContractAttribute"), "$", $.right($.str("@interface"), $.right($.str("("), $.field($.lazy(() => StringLiteral), "name", $.right($.str(")"), $.eps)))))); +export const FunctionAttribute: $.Parser<$ast.FunctionAttribute> = $.loc($.field($.pure("FunctionAttribute"), "$", $.field($.alt($.lazy(() => GetAttribute), $.alt(keyword($.str("mutates")), $.alt(keyword($.str("extends")), $.alt(keyword($.str("virtual")), $.alt(keyword($.str("override")), $.alt(keyword($.str("inline")), keyword($.str("abstract")))))))), "name", $.eps))); +export const GetAttribute: $.Parser<$ast.GetAttribute> = $.loc($.field($.pure("GetAttribute"), "$", $.right($.str("get"), $.field($.opt($.right($.str("("), $.left($.lazy(() => expression), $.str(")")))), "methodId", $.eps)))); +export const ReceiverType: $.Parser<$ast.ReceiverType> = $.loc($.field($.pure("ReceiverType"), "$", $.field($.alt($.str("bounced"), $.alt(keyword($.str("receive")), keyword($.str("external")))), "name", $.eps))); +export const Parameter: $.Parser<$ast.Parameter> = $.loc($.field($.pure("Parameter"), "$", $.field(Id, "name", $.field($.lazy(() => ascription), "type", $.eps)))); +export const StringLiteral: $.Parser<$ast.StringLiteral> = $.loc($.field($.pure("StringLiteral"), "$", $.field($.lex($.right($.str("\""), $.left($.stry($.star($.alt($.regex<"\"" | "\\">("^\"\\\\", $.negateExps([$.ExpString("\""), $.ExpString("\\")])), $.right($.str("\\"), $.lazy(() => escapeChar))))), $.str("\"")))), "value", $.eps))); +export const receiverParam: $.Parser<$ast.receiverParam> = $.opt($.alt(Parameter, StringLiteral)); +export const assembly: $.Parser<$ast.assembly> = $.lex($.stry($.lazy(() => assemblySequence))); +export const multiLineComment: $.Parser<$ast.multiLineComment> = $.right($.str("/*"), $.left($.stry($.star($.right($.lookNeg($.str("*/")), $.right($.any, $.eps)))), $.str("*/"))); +export const singleLineComment: $.Parser<$ast.singleLineComment> = $.right($.str("//"), $.stry($.star($.regex<"\r" | "\n">("^\\r\\n", $.negateExps([$.ExpString("\r"), $.ExpString("\n")]))))); +export const comment: $.Parser<$ast.comment> = $.alt(multiLineComment, singleLineComment); +export const assemblyItem: $.Parser<$ast.assemblyItem> = $.alt($.right($.str("{"), $.right($.lazy(() => assemblySequence), $.right($.str("}"), $.eps))), $.alt(comment, $.alt($.right($.str("\""), $.right($.star($.regex<"\"">("^\"", $.negateExps([$.ExpString("\"")]))), $.right($.str("\""), $.eps))), $.plus($.right($.lookNeg($.alt($.regex<"\"" | "{" | "}">("\"{}", [$.ExpString("\""), $.ExpString("{"), $.ExpString("}")]), $.alt($.str("//"), $.str("/*")))), $.right($.any, $.eps)))))); +export const assemblySequence: $.Parser<$ast.assemblySequence> = $.star(assemblyItem); +export const TypeAs: $.Parser<$ast.TypeAs> = $.loc($.field($.pure("TypeAs"), "$", $.field($.lazy(() => TypeOptional), "type", $.field($.star($.right(keyword($.str("as")), $.lex($.lazy(() => storage)))), "as", $.eps)))); export const $type: $.Parser<$ast.$type> = TypeAs; export const ascription: $.Parser<$ast.ascription> = $.right($.str(":"), $type); -export const TypeOptional: $.Parser<$ast.TypeOptional> = $.loc( - $.field( - $.pure("TypeOptional"), - "$", - $.field( - $.lazy(() => typePrimary), - "type", - $.field($.star($.lazy(() => Optional)), "optionals", $.eps), - ), - ), -); -export const Optional: $.Parser<$ast.Optional> = $.loc( - $.field($.pure("Optional"), "$", $.right($.str("?"), $.eps)), -); -export const TypeGeneric: $.Parser<$ast.TypeGeneric> = $.loc( - $.field( - $.pure("TypeGeneric"), - "$", - $.field( - $.alt( - $.lazy(() => MapKeyword), - $.alt( - $.lazy(() => Bounced), - TypeId, - ), - ), - "name", - $.field( - $.lazy(() => typeArgs), - "args", - $.eps, - ), - ), - ), -); -export const TypeRegular: $.Parser<$ast.TypeRegular> = $.loc( - $.field($.pure("TypeRegular"), "$", $.field(TypeId, "child", $.eps)), -); -export const TypeStorage: $.Parser<$ast.TypeStorage> = $.loc( - $.field( - $.pure("TypeStorage"), - "$", - $.field( - $.lazy(() => storage), - "child", - $.eps, - ), - ), -); -export const TypeTuple: $.Parser<$ast.TypeTuple> = $.loc( - $.field( - $.pure("TypeTuple"), - "$", - $.right( - $.str("["), - $.field( - $.opt(commaList($type)), - "types", - $.right($.str("]"), $.eps), - ), - ), - ), -); -export const TypeTensor: $.Parser<$ast.TypeTensor> = $.loc( - $.field( - $.pure("TypeTensor"), - "$", - $.right( - $.str("("), - $.field( - $type, - "head", - $.field( - $.plus($.right($.str(","), $type)), - "tail", - $.right($.opt($.str(",")), $.right($.str(")"), $.eps)), - ), - ), - ), - ), -); -export const TypeUnit: $.Parser<$ast.TypeUnit> = $.loc( - $.field( - $.pure("TypeUnit"), - "$", - $.right($.right($.str("("), $.right($.str(")"), $.eps)), $.eps), - ), -); -export const typeParens: $.Parser<$ast.typeParens> = $.right( - $.str("("), - $.left($type, $.str(")")), -); -export const typePrimary: $.Parser<$ast.typePrimary> = $.alt( - TypeGeneric, - $.alt( - TypeRegular, - $.alt( - TypeStorage, - $.alt(TypeTuple, $.alt(TypeTensor, $.alt(TypeUnit, typeParens))), - ), - ), -); -export const MapKeyword: $.Parser<$ast.MapKeyword> = $.loc( - $.field($.pure("MapKeyword"), "$", $.right(keyword($.str("map")), $.eps)), -); -export const Bounced: $.Parser<$ast.Bounced> = $.loc( - $.field($.pure("Bounced"), "$", $.right($.str("bounced"), $.eps)), -); -export const IntStorage: $.Parser<$ast.IntStorage> = $.loc( - $.field( - $.pure("IntStorage"), - "$", - $.field( - $.opt($.str("var")), - "isVar", - $.field( - $.opt($.str("u")), - "isUnsigned", - $.right( - $.str("int"), - $.field( - $.stry($.plus($.lazy(() => digit))), - "width", - $.eps, - ), - ), - ), - ), - ), -); -export const CoinsStorage: $.Parser<$ast.CoinsStorage> = $.loc( - $.field($.pure("CoinsStorage"), "$", $.right($.str("coins"), $.eps)), -); -export const RemainingStorage: $.Parser<$ast.RemainingStorage> = $.loc( - $.field( - $.pure("RemainingStorage"), - "$", - $.right($.str("remaining"), $.eps), - ), -); -export const BytesStorage: $.Parser<$ast.BytesStorage> = $.loc( - $.field( - $.pure("BytesStorage"), - "$", - $.right( - $.str("bytes"), - $.field($.stry($.plus($.lazy(() => digit))), "width", $.eps), - ), - ), -); -export const storage: $.Parser<$ast.storage> = $.alt( - IntStorage, - $.alt(CoinsStorage, $.alt(RemainingStorage, BytesStorage)), -); -export const generic = (T: $.Parser): $.Parser<$ast.generic> => - $.right($.str("<"), $.left($.opt(commaList($.lazy(() => T))), $.str(">"))); +export const TypeOptional: $.Parser<$ast.TypeOptional> = $.loc($.field($.pure("TypeOptional"), "$", $.field($.lazy(() => typePrimary), "type", $.field($.star($.lazy(() => Optional)), "optionals", $.eps)))); +export const Optional: $.Parser<$ast.Optional> = $.loc($.field($.pure("Optional"), "$", $.right($.str("?"), $.eps))); +export const TypeGeneric: $.Parser<$ast.TypeGeneric> = $.loc($.field($.pure("TypeGeneric"), "$", $.field($.alt($.lazy(() => MapKeyword), $.alt($.lazy(() => Bounced), TypeId)), "name", $.field($.lazy(() => typeArgs), "args", $.eps)))); +export const TypeRegular: $.Parser<$ast.TypeRegular> = $.loc($.field($.pure("TypeRegular"), "$", $.field(TypeId, "child", $.eps))); +export const TypeStorage: $.Parser<$ast.TypeStorage> = $.loc($.field($.pure("TypeStorage"), "$", $.field($.lazy(() => storage), "child", $.eps))); +export const TypeTuple: $.Parser<$ast.TypeTuple> = $.loc($.field($.pure("TypeTuple"), "$", $.right($.str("["), $.field($.opt(commaList($type)), "types", $.right($.str("]"), $.eps))))); +export const TypeTensor: $.Parser<$ast.TypeTensor> = $.loc($.field($.pure("TypeTensor"), "$", $.right($.str("("), $.field($type, "head", $.field($.plus($.right($.str(","), $type)), "tail", $.right($.opt($.str(",")), $.right($.str(")"), $.eps))))))); +export const TypeUnit: $.Parser<$ast.TypeUnit> = $.loc($.field($.pure("TypeUnit"), "$", $.right($.right($.str("("), $.right($.str(")"), $.eps)), $.eps))); +export const typeParens: $.Parser<$ast.typeParens> = $.right($.str("("), $.left($type, $.str(")"))); +export const typePrimary: $.Parser<$ast.typePrimary> = $.alt(TypeGeneric, $.alt(TypeRegular, $.alt(TypeStorage, $.alt(TypeTuple, $.alt(TypeTensor, $.alt(TypeUnit, typeParens)))))); +export const MapKeyword: $.Parser<$ast.MapKeyword> = $.loc($.field($.pure("MapKeyword"), "$", $.right(keyword($.str("map")), $.eps))); +export const Bounced: $.Parser<$ast.Bounced> = $.loc($.field($.pure("Bounced"), "$", $.right($.str("bounced"), $.eps))); +export const IntStorage: $.Parser<$ast.IntStorage> = $.loc($.field($.pure("IntStorage"), "$", $.field($.opt($.str("var")), "isVar", $.field($.opt($.str("u")), "isUnsigned", $.right($.str("int"), $.field($.stry($.plus($.lazy(() => digit))), "width", $.eps)))))); +export const CoinsStorage: $.Parser<$ast.CoinsStorage> = $.loc($.field($.pure("CoinsStorage"), "$", $.right($.str("coins"), $.eps))); +export const RemainingStorage: $.Parser<$ast.RemainingStorage> = $.loc($.field($.pure("RemainingStorage"), "$", $.right($.str("remaining"), $.eps))); +export const BytesStorage: $.Parser<$ast.BytesStorage> = $.loc($.field($.pure("BytesStorage"), "$", $.right($.str("bytes"), $.field($.stry($.plus($.lazy(() => digit))), "width", $.eps)))); +export const storage: $.Parser<$ast.storage> = $.alt(IntStorage, $.alt(CoinsStorage, $.alt(RemainingStorage, BytesStorage))); +export const generic = (T: $.Parser): $.Parser<$ast.generic> => $.right($.str("<"), $.left($.opt(commaList($.lazy(() => T))), $.str(">"))); export const typeParams: $.Parser<$ast.typeParams> = generic(TypeId); export const typeArgs: $.Parser<$ast.typeArgs> = generic($type); -export const StatementLet: $.Parser<$ast.StatementLet> = $.loc( - $.field( - $.pure("StatementLet"), - "$", - $.right( - keyword($.str("let")), - $.field( - Id, - "name", - $.field( - $.opt(ascription), - "type", - $.right( - $.str("="), - $.field( - $.lazy(() => expression), - "init", - $.right(semicolon, $.eps), - ), - ), - ), - ), - ), - ), -); -export const StatementDestruct: $.Parser<$ast.StatementDestruct> = $.loc( - $.field( - $.pure("StatementDestruct"), - "$", - $.right( - keyword($.str("let")), - $.field( - TypeId, - "type", - $.right( - $.str("{"), - $.field( - inter( - $.lazy(() => destructItem), - $.str(","), - ), - "fields", - $.field( - $.lazy(() => optionalRest), - "rest", - $.right( - $.str("}"), - $.right( - $.str("="), - $.field( - $.lazy(() => expression), - "init", - $.right(semicolon, $.eps), - ), - ), - ), - ), - ), - ), - ), - ), - ), -); -export const StatementBlock: $.Parser<$ast.StatementBlock> = $.loc( - $.field( - $.pure("StatementBlock"), - "$", - $.field( - $.lazy(() => statements), - "body", - $.eps, - ), - ), -); -export const StatementReturn: $.Parser<$ast.StatementReturn> = $.loc( - $.field( - $.pure("StatementReturn"), - "$", - $.right( - keyword($.str("return")), - $.field( - $.opt($.lazy(() => expression)), - "expression", - $.right(semicolon, $.eps), - ), - ), - ), -); -export const StatementCondition: $.Parser<$ast.StatementCondition> = $.loc( - $.field( - $.pure("StatementCondition"), - "$", - $.right( - keyword($.str("if")), - $.field( - $.lazy(() => expression), - "condition", - $.field( - $.lazy(() => statements), - "trueBranch", - $.field( - $.opt( - $.right( - keyword($.str("else")), - $.alt( - $.lazy(() => FalseBranch), - $.lazy(() => StatementCondition), - ), - ), - ), - "falseBranch", - $.eps, - ), - ), - ), - ), - ), -); -export const StatementWhile: $.Parser<$ast.StatementWhile> = $.loc( - $.field( - $.pure("StatementWhile"), - "$", - $.right( - keyword($.str("while")), - $.field( - $.lazy(() => parens), - "condition", - $.field( - $.lazy(() => statements), - "body", - $.eps, - ), - ), - ), - ), -); -export const StatementRepeat: $.Parser<$ast.StatementRepeat> = $.loc( - $.field( - $.pure("StatementRepeat"), - "$", - $.right( - keyword($.str("repeat")), - $.field( - $.lazy(() => parens), - "condition", - $.field( - $.lazy(() => statements), - "body", - $.eps, - ), - ), - ), - ), -); -export const StatementUntil: $.Parser<$ast.StatementUntil> = $.loc( - $.field( - $.pure("StatementUntil"), - "$", - $.right( - keyword($.str("do")), - $.field( - $.lazy(() => statements), - "body", - $.right( - keyword($.str("until")), - $.field( - $.lazy(() => parens), - "condition", - $.right(semicolon, $.eps), - ), - ), - ), - ), - ), -); -export const StatementTry: $.Parser<$ast.StatementTry> = $.loc( - $.field( - $.pure("StatementTry"), - "$", - $.right( - keyword($.str("try")), - $.field( - $.lazy(() => statements), - "body", - $.field( - $.opt( - $.right( - keyword($.str("catch")), - $.right( - $.str("("), - $.field( - Id, - "name", - $.right( - $.str(")"), - $.field( - $.lazy(() => statements), - "body", - $.eps, - ), - ), - ), - ), - ), - ), - "handler", - $.eps, - ), - ), - ), - ), -); -export const StatementForEach: $.Parser<$ast.StatementForEach> = $.loc( - $.field( - $.pure("StatementForEach"), - "$", - $.right( - keyword($.str("foreach")), - $.right( - $.str("("), - $.field( - Id, - "key", - $.right( - $.str(","), - $.field( - Id, - "value", - $.right( - $.str("in"), - $.field( - $.lazy(() => expression), - "expression", - $.right( - $.str(")"), - $.field( - $.lazy(() => statements), - "body", - $.eps, - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), -); -export const StatementExpression: $.Parser<$ast.StatementExpression> = $.loc( - $.field( - $.pure("StatementExpression"), - "$", - $.field( - $.lazy(() => expression), - "expression", - $.right(semicolon, $.eps), - ), - ), -); -export const StatementAssign: $.Parser<$ast.StatementAssign> = $.loc( - $.field( - $.pure("StatementAssign"), - "$", - $.field( - $.lazy(() => expression), - "left", - $.field( - $.alt( - $.lazy(() => augmentedOp), - $.str("="), - ), - "operator", - $.field( - $.lazy(() => expression), - "right", - $.right(semicolon, $.eps), - ), - ), - ), - ), -); -export const statement: $.Parser<$ast.statement> = $.alt( - StatementLet, - $.alt( - StatementDestruct, - $.alt( - StatementBlock, - $.alt( - StatementReturn, - $.alt( - StatementCondition, - $.alt( - StatementWhile, - $.alt( - StatementRepeat, - $.alt( - StatementUntil, - $.alt( - StatementTry, - $.alt( - StatementForEach, - $.alt( - StatementExpression, - StatementAssign, - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), -); -export const statements: $.Parser<$ast.statements> = $.right( - $.str("{"), - $.left($.star(statement), $.str("}")), -); -export const augmentedOp: $.Parser<$ast.augmentedOp> = $.alt( - $.str("||="), - $.alt( - $.str("&&="), - $.alt( - $.str(">>="), - $.alt( - $.str("<<="), - $.alt( - $.str("-="), - $.alt( - $.str("+="), - $.alt( - $.str("*="), - $.alt( - $.str("/="), - $.alt( - $.str("%="), - $.alt( - $.str("|="), - $.alt($.str("&="), $.str("^=")), - ), - ), - ), - ), - ), - ), - ), - ), - ), -); -export const FalseBranch: $.Parser<$ast.FalseBranch> = $.loc( - $.field($.pure("FalseBranch"), "$", $.field(statements, "body", $.eps)), -); -export const RegularField: $.Parser<$ast.RegularField> = $.loc( - $.field( - $.pure("RegularField"), - "$", - $.field( - Id, - "fieldName", - $.right($.str(":"), $.field(Id, "varName", $.eps)), - ), - ), -); -export const PunnedField: $.Parser<$ast.PunnedField> = $.loc( - $.field($.pure("PunnedField"), "$", $.field(Id, "name", $.eps)), -); -export const destructItem: $.Parser<$ast.destructItem> = $.alt( - RegularField, - PunnedField, -); -export const RestArgument: $.Parser<$ast.RestArgument> = $.loc( - $.field($.pure("RestArgument"), "$", $.right($.str(".."), $.eps)), -); -export const NoRestArgument: $.Parser<$ast.NoRestArgument> = $.loc( - $.field($.pure("NoRestArgument"), "$", $.right($.opt($.str(",")), $.eps)), -); -export const optionalRest: $.Parser<$ast.optionalRest> = $.alt( - $.right($.str(","), RestArgument), - NoRestArgument, -); -export const Conditional: $.Parser<$ast.Conditional> = $.loc( - $.field( - $.pure("Conditional"), - "$", - $.field( - $.lazy(() => or), - "head", - $.field( - $.opt( - $.right( - $.str("?"), - $.field( - $.lazy(() => or), - "thenBranch", - $.right( - $.str(":"), - $.field( - $.lazy(() => Conditional), - "elseBranch", - $.eps, - ), - ), - ), - ), - ), - "tail", - $.eps, - ), - ), - ), -); +export const StatementLet: $.Parser<$ast.StatementLet> = $.loc($.field($.pure("StatementLet"), "$", $.right(keyword($.str("let")), $.field(Id, "name", $.field($.opt(ascription), "type", $.right($.str("="), $.field($.lazy(() => expression), "init", $.right(semicolon, $.eps)))))))); +export const StatementDestruct: $.Parser<$ast.StatementDestruct> = $.loc($.field($.pure("StatementDestruct"), "$", $.right(keyword($.str("let")), $.field(TypeId, "type", $.right($.str("{"), $.field(inter($.lazy(() => destructItem), $.str(",")), "fields", $.field($.lazy(() => optionalRest), "rest", $.right($.str("}"), $.right($.str("="), $.field($.lazy(() => expression), "init", $.right(semicolon, $.eps))))))))))); +export const StatementBlock: $.Parser<$ast.StatementBlock> = $.loc($.field($.pure("StatementBlock"), "$", $.field($.lazy(() => statements), "body", $.eps))); +export const StatementReturn: $.Parser<$ast.StatementReturn> = $.loc($.field($.pure("StatementReturn"), "$", $.right(keyword($.str("return")), $.field($.opt($.lazy(() => expression)), "expression", $.right(semicolon, $.eps))))); +export const StatementCondition: $.Parser<$ast.StatementCondition> = $.loc($.field($.pure("StatementCondition"), "$", $.right(keyword($.str("if")), $.field($.lazy(() => expression), "condition", $.field($.lazy(() => statements), "trueBranch", $.field($.opt($.right(keyword($.str("else")), $.alt($.lazy(() => FalseBranch), $.lazy(() => StatementCondition)))), "falseBranch", $.eps)))))); +export const StatementWhile: $.Parser<$ast.StatementWhile> = $.loc($.field($.pure("StatementWhile"), "$", $.right(keyword($.str("while")), $.field($.lazy(() => parens), "condition", $.field($.lazy(() => statements), "body", $.eps))))); +export const StatementRepeat: $.Parser<$ast.StatementRepeat> = $.loc($.field($.pure("StatementRepeat"), "$", $.right(keyword($.str("repeat")), $.field($.lazy(() => parens), "condition", $.field($.lazy(() => statements), "body", $.eps))))); +export const StatementUntil: $.Parser<$ast.StatementUntil> = $.loc($.field($.pure("StatementUntil"), "$", $.right(keyword($.str("do")), $.field($.lazy(() => statements), "body", $.right(keyword($.str("until")), $.field($.lazy(() => parens), "condition", $.right(semicolon, $.eps))))))); +export const StatementTry: $.Parser<$ast.StatementTry> = $.loc($.field($.pure("StatementTry"), "$", $.right(keyword($.str("try")), $.field($.lazy(() => statements), "body", $.field($.opt($.right(keyword($.str("catch")), $.right($.str("("), $.field(Id, "name", $.right($.str(")"), $.field($.lazy(() => statements), "body", $.eps)))))), "handler", $.eps))))); +export const StatementForEach: $.Parser<$ast.StatementForEach> = $.loc($.field($.pure("StatementForEach"), "$", $.right(keyword($.str("foreach")), $.right($.str("("), $.field(Id, "key", $.right($.str(","), $.field(Id, "value", $.right($.str("in"), $.field($.lazy(() => expression), "expression", $.right($.str(")"), $.field($.lazy(() => statements), "body", $.eps))))))))))); +export const StatementExpression: $.Parser<$ast.StatementExpression> = $.loc($.field($.pure("StatementExpression"), "$", $.field($.lazy(() => expression), "expression", $.right(semicolon, $.eps)))); +export const StatementAssign: $.Parser<$ast.StatementAssign> = $.loc($.field($.pure("StatementAssign"), "$", $.field($.lazy(() => expression), "left", $.field($.alt($.lazy(() => augmentedOp), $.str("=")), "operator", $.field($.lazy(() => expression), "right", $.right(semicolon, $.eps)))))); +export const statement: $.Parser<$ast.statement> = $.alt(StatementLet, $.alt(StatementDestruct, $.alt(StatementBlock, $.alt(StatementReturn, $.alt(StatementCondition, $.alt(StatementWhile, $.alt(StatementRepeat, $.alt(StatementUntil, $.alt(StatementTry, $.alt(StatementForEach, $.alt(StatementExpression, StatementAssign))))))))))); +export const statements: $.Parser<$ast.statements> = $.right($.str("{"), $.left($.star(statement), $.str("}"))); +export const augmentedOp: $.Parser<$ast.augmentedOp> = $.alt($.str("||="), $.alt($.str("&&="), $.alt($.str(">>="), $.alt($.str("<<="), $.alt($.str("-="), $.alt($.str("+="), $.alt($.str("*="), $.alt($.str("/="), $.alt($.str("%="), $.alt($.str("|="), $.alt($.str("&="), $.str("^=")))))))))))); +export const FalseBranch: $.Parser<$ast.FalseBranch> = $.loc($.field($.pure("FalseBranch"), "$", $.field(statements, "body", $.eps))); +export const RegularField: $.Parser<$ast.RegularField> = $.loc($.field($.pure("RegularField"), "$", $.field(Id, "fieldName", $.right($.str(":"), $.field(Id, "varName", $.eps))))); +export const PunnedField: $.Parser<$ast.PunnedField> = $.loc($.field($.pure("PunnedField"), "$", $.field(Id, "name", $.eps))); +export const destructItem: $.Parser<$ast.destructItem> = $.alt(RegularField, PunnedField); +export const RestArgument: $.Parser<$ast.RestArgument> = $.loc($.field($.pure("RestArgument"), "$", $.right($.str(".."), $.eps))); +export const NoRestArgument: $.Parser<$ast.NoRestArgument> = $.loc($.field($.pure("NoRestArgument"), "$", $.right($.opt($.str(",")), $.eps))); +export const optionalRest: $.Parser<$ast.optionalRest> = $.alt($.right($.str(","), RestArgument), NoRestArgument); +export const Conditional: $.Parser<$ast.Conditional> = $.loc($.field($.pure("Conditional"), "$", $.field($.lazy(() => or), "head", $.field($.opt($.right($.str("?"), $.field($.lazy(() => or), "thenBranch", $.right($.str(":"), $.field($.lazy(() => Conditional), "elseBranch", $.eps))))), "tail", $.eps)))); export const expression: $.Parser<$ast.expression> = Conditional; -export const Binary = ( - T: $.Parser, - U: $.Parser, -): $.Parser<$ast.Binary> => - $.loc( - $.field( - $.pure("Binary"), - "$", - $.field( - inter( - $.lazy(() => T), - $.lazy(() => Operator($.lazy(() => U))), - ), - "exprs", - $.eps, - ), - ), - ); -export const Unary: $.Parser<$ast.Unary> = $.loc( - $.field( - $.pure("Unary"), - "$", - $.field( - $.star( - $.lazy(() => - Operator( - $.regex<"-" | "+" | "!" | "~">("-+!~", [ - $.ExpString("-"), - $.ExpString("+"), - $.ExpString("!"), - $.ExpString("~"), - ]), - ), - ), - ), - "prefixes", - $.field( - $.lazy(() => Suffix), - "expression", - $.eps, - ), - ), - ), -); -export const mul: $.Parser<$ast.mul> = Binary( - Unary, - $.regex<"*" | "/" | "%">("*/%", [ - $.ExpString("*"), - $.ExpString("/"), - $.ExpString("%"), - ]), -); -export const add: $.Parser<$ast.add> = Binary( - mul, - $.alt($.str("+"), $.str("-")), -); -export const bitwiseShift: $.Parser<$ast.bitwiseShift> = Binary( - add, - $.alt($.str("<<"), $.str(">>")), -); -export const compare: $.Parser<$ast.compare> = Binary( - bitwiseShift, - $.alt($.str("<="), $.alt($.str("<"), $.alt($.str(">="), $.str(">")))), -); -export const equality: $.Parser<$ast.equality> = Binary( - compare, - $.alt($.str("!="), $.str("==")), -); -export const bitwiseAnd: $.Parser<$ast.bitwiseAnd> = Binary( - equality, - $.str("&"), -); -export const bitwiseXor: $.Parser<$ast.bitwiseXor> = Binary( - bitwiseAnd, - $.str("^"), -); -export const bitwiseOr: $.Parser<$ast.bitwiseOr> = Binary( - bitwiseXor, - $.str("|"), -); +export const Binary = (T: $.Parser, U: $.Parser): $.Parser<$ast.Binary> => $.loc($.field($.pure("Binary"), "$", $.field(inter($.lazy(() => T), $.lazy(() => Operator($.lazy(() => U)))), "exprs", $.eps))); +export const Unary: $.Parser<$ast.Unary> = $.loc($.field($.pure("Unary"), "$", $.field($.star($.lazy(() => Operator($.regex<"-" | "+" | "!" | "~">("-+!~", [$.ExpString("-"), $.ExpString("+"), $.ExpString("!"), $.ExpString("~")])))), "prefixes", $.field($.lazy(() => Suffix), "expression", $.eps)))); +export const mul: $.Parser<$ast.mul> = Binary(Unary, $.regex<"*" | "/" | "%">("*/%", [$.ExpString("*"), $.ExpString("/"), $.ExpString("%")])); +export const add: $.Parser<$ast.add> = Binary(mul, $.alt($.str("+"), $.str("-"))); +export const bitwiseShift: $.Parser<$ast.bitwiseShift> = Binary(add, $.alt($.str("<<"), $.str(">>"))); +export const compare: $.Parser<$ast.compare> = Binary(bitwiseShift, $.alt($.str("<="), $.alt($.str("<"), $.alt($.str(">="), $.str(">"))))); +export const equality: $.Parser<$ast.equality> = Binary(compare, $.alt($.str("!="), $.str("=="))); +export const bitwiseAnd: $.Parser<$ast.bitwiseAnd> = Binary(equality, $.str("&")); +export const bitwiseXor: $.Parser<$ast.bitwiseXor> = Binary(bitwiseAnd, $.str("^")); +export const bitwiseOr: $.Parser<$ast.bitwiseOr> = Binary(bitwiseXor, $.str("|")); export const and: $.Parser<$ast.and> = Binary(bitwiseOr, $.str("&&")); export const or: $.Parser<$ast.or> = Binary(and, $.str("||")); -export const Suffix: $.Parser<$ast.Suffix> = $.loc( - $.field( - $.pure("Suffix"), - "$", - $.field( - $.lazy(() => primary), - "expression", - $.field($.star($.lazy(() => suffix)), "suffixes", $.eps), - ), - ), -); -export const Operator = (U: $.Parser): $.Parser<$ast.Operator> => - $.loc( - $.field( - $.pure("Operator"), - "$", - $.field( - $.lazy(() => U), - "name", - $.eps, - ), - ), - ); -export const SuffixUnboxNotNull: $.Parser<$ast.SuffixUnboxNotNull> = $.loc( - $.field($.pure("SuffixUnboxNotNull"), "$", $.right($.str("!!"), $.eps)), -); -export const SuffixCall: $.Parser<$ast.SuffixCall> = $.loc( - $.field( - $.pure("SuffixCall"), - "$", - $.field( - $.opt(typeArgs), - "typeArgs", - $.field( - $.lazy(() => parameterList(expression)), - "params", - $.eps, - ), - ), - ), -); -export const SuffixFieldAccess: $.Parser<$ast.SuffixFieldAccess> = $.loc( - $.field( - $.pure("SuffixFieldAccess"), - "$", - $.right($.str("."), $.field(Id, "name", $.eps)), - ), -); -export const suffix: $.Parser<$ast.suffix> = $.alt( - SuffixUnboxNotNull, - $.alt(SuffixCall, SuffixFieldAccess), -); -export const Unit: $.Parser<$ast.Unit> = $.loc( - $.field( - $.pure("Unit"), - "$", - $.right($.right($.str("("), $.right($.str(")"), $.eps)), $.eps), - ), -); -export const Tensor: $.Parser<$ast.Tensor> = $.loc( - $.field( - $.pure("Tensor"), - "$", - $.right( - $.str("("), - $.field( - expression, - "head", - $.field( - $.plus($.right($.str(","), expression)), - "tail", - $.right($.opt($.str(",")), $.right($.str(")"), $.eps)), - ), - ), - ), - ), -); -export const Tuple: $.Parser<$ast.Tuple> = $.loc( - $.field( - $.pure("Tuple"), - "$", - $.right( - $.str("["), - $.field( - $.opt(commaList(expression)), - "types", - $.right($.str("]"), $.eps), - ), - ), - ), -); -export const Parens: $.Parser<$ast.Parens> = $.loc( - $.field( - $.pure("Parens"), - "$", - $.field( - $.lazy(() => parens), - "child", - $.eps, - ), - ), -); -export const MapLiteral: $.Parser<$ast.MapLiteral> = $.loc( - $.field( - $.pure("MapLiteral"), - "$", - $.right( - keyword($.str("map")), - $.field( - typeArgs, - "typeArgs", - $.right( - $.str("{"), - $.field( - $.opt(commaList($.lazy(() => mapField))), - "fields", - $.right($.str("}"), $.eps), - ), - ), - ), - ), - ), -); -export const SetLiteral: $.Parser<$ast.SetLiteral> = $.loc( - $.field( - $.pure("SetLiteral"), - "$", - $.right( - $.str("set"), - $.field( - typeArgs, - "typeArgs", - $.right( - $.str("{"), - $.field( - $.opt(commaList(expression)), - "fields", - $.right($.str("}"), $.eps), - ), - ), - ), - ), - ), -); -export const StructInstance: $.Parser<$ast.StructInstance> = $.loc( - $.field( - $.pure("StructInstance"), - "$", - $.field( - TypeId, - "type", - $.field( - $.opt(typeArgs), - "typeArgs", - $.right( - $.str("{"), - $.field( - $.opt(commaList($.lazy(() => StructFieldInitializer))), - "fields", - $.right($.str("}"), $.eps), - ), - ), - ), - ), - ), -); -export const IntegerLiteral: $.Parser<$ast.IntegerLiteral> = $.loc( - $.field( - $.pure("IntegerLiteral"), - "$", - $.field( - $.alt( - $.lazy(() => IntegerLiteralHex), - $.alt( - $.lazy(() => IntegerLiteralBin), - $.alt( - $.lazy(() => IntegerLiteralOct), - IntegerLiteralDec, - ), - ), - ), - "value", - $.eps, - ), - ), -); -export const BoolLiteral: $.Parser<$ast.BoolLiteral> = $.loc( - $.field( - $.pure("BoolLiteral"), - "$", - $.field( - $.alt($.str("true"), $.str("false")), - "value", - $.right($.lookNeg($.lazy(() => idPart)), $.eps), - ), - ), -); -export const InitOf: $.Parser<$ast.InitOf> = $.loc( - $.field( - $.pure("InitOf"), - "$", - $.right( - keyword($.str("initOf")), - $.field( - TypeId, - "name", - $.field( - $.lazy(() => parameterList(expression)), - "params", - $.eps, - ), - ), - ), - ), -); -export const CodeOf: $.Parser<$ast.CodeOf> = $.loc( - $.field( - $.pure("CodeOf"), - "$", - $.right($.str("codeOf"), $.field(TypeId, "name", $.eps)), - ), -); -export const Null: $.Parser<$ast.Null> = $.loc( - $.field($.pure("Null"), "$", $.right(keyword($.str("null")), $.eps)), -); -export const primary: $.Parser<$ast.primary> = $.alt( - Unit, - $.alt( - Tensor, - $.alt( - Tuple, - $.alt( - Parens, - $.alt( - MapLiteral, - $.alt( - SetLiteral, - $.alt( - StructInstance, - $.alt( - IntegerLiteral, - $.alt( - BoolLiteral, - $.alt( - InitOf, - $.alt( - CodeOf, - $.alt( - Null, - $.alt(StringLiteral, Id), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), -); -export const parens: $.Parser<$ast.parens> = $.right( - $.str("("), - $.left(expression, $.str(")")), -); -export const StructFieldInitializer: $.Parser<$ast.StructFieldInitializer> = - $.loc( - $.field( - $.pure("StructFieldInitializer"), - "$", - $.field( - Id, - "name", - $.field($.opt($.right($.str(":"), expression)), "init", $.eps), - ), - ), - ); -export const mapField: $.Parser<$ast.mapField> = $.field( - expression, - "key", - $.right($.str(":"), $.field(expression, "value", $.eps)), -); -export const ParameterList = ( - T: $.Parser, -): $.Parser<$ast.ParameterList> => - $.loc( - $.field( - $.pure("ParameterList"), - "$", - $.right( - $.str("("), - $.field( - $.opt(commaList($.lazy(() => T))), - "values", - $.right($.str(")"), $.eps), - ), - ), - ), - ); -export const parameterList = ( - T: $.Parser, -): $.Parser<$ast.parameterList> => - $.right($.str("("), $.left($.opt(commaList($.lazy(() => T))), $.str(")"))); -export const IntegerLiteralHex: $.Parser<$ast.IntegerLiteralHex> = $.loc( - $.field( - $.pure("IntegerLiteralHex"), - "$", - $.field( - $.lex( - $.right( - $.str("0"), - $.right( - $.regex<"x" | "X">("xX", [ - $.ExpString("x"), - $.ExpString("X"), - ]), - $.lazy(() => underscored($.lazy(() => hexDigit))), - ), - ), - ), - "digits", - $.eps, - ), - ), -); -export const IntegerLiteralBin: $.Parser<$ast.IntegerLiteralBin> = $.loc( - $.field( - $.pure("IntegerLiteralBin"), - "$", - $.field( - $.lex( - $.right( - $.str("0"), - $.right( - $.regex<"b" | "B">("bB", [ - $.ExpString("b"), - $.ExpString("B"), - ]), - $.lazy(() => - underscored( - $.regex<"0" | "1">("01", [ - $.ExpString("0"), - $.ExpString("1"), - ]), - ), - ), - ), - ), - ), - "digits", - $.eps, - ), - ), -); -export const IntegerLiteralOct: $.Parser<$ast.IntegerLiteralOct> = $.loc( - $.field( - $.pure("IntegerLiteralOct"), - "$", - $.field( - $.lex( - $.right( - $.str("0"), - $.right( - $.regex<"o" | "O">("oO", [ - $.ExpString("o"), - $.ExpString("O"), - ]), - $.lazy(() => - underscored( - $.regex("0-7", [$.ExpRange("0", "7")]), - ), - ), - ), - ), - ), - "digits", - $.eps, - ), - ), -); -export const underscored = (T: $.Parser): $.Parser<$ast.underscored> => - $.stry( - $.right( - $.lazy(() => T), - $.right( - $.star( - $.right( - $.opt($.str("_")), - $.right( - $.lazy(() => T), - $.eps, - ), - ), - ), - $.eps, - ), - ), - ); -export const digit: $.Parser<$ast.digit> = $.named( - "digit", - $.regex("0-9", [$.ExpRange("0", "9")]), -); -export const idPart: $.Parser<$ast.idPart> = $.named( - "identifier character", - $.regex("a-zA-Z0-9_", [ - $.ExpRange("a", "z"), - $.ExpRange("A", "Z"), - $.ExpRange("0", "9"), - $.ExpString("_"), - ]), -); -export const FuncId: $.Parser<$ast.FuncId> = $.named( - "FunC identifier", - $.loc( - $.field( - $.pure("FuncId"), - "$", - $.field( - $.opt( - $.regex<"." | "~">(".~", [ - $.ExpString("."), - $.ExpString("~"), - ]), - ), - "accessor", - $.field( - $.stry( - $.alt( - $.right( - $.str("`"), - $.right( - $.plus( - $.regex<"`" | "\r" | "\n">( - "^`\\r\\n", - $.negateExps([ - $.ExpString("`"), - $.ExpString("\r"), - $.ExpString("\n"), - ]), - ), - ), - $.right($.str("`"), $.eps), - ), - ), - $.plus( - $.regex< - | " " - | "\t" - | "\r" - | "\n" - | "(" - | ")" - | "[" - | string - | "," - | "." - | ";" - | "~" - >( - "^ \\t\\r\\n()[\\],.;~", - $.negateExps([ - $.ExpString(" "), - $.ExpString("\t"), - $.ExpString("\r"), - $.ExpString("\n"), - $.ExpString("("), - $.ExpString(")"), - $.ExpString("["), - $.ExpString('"\\]"'), - $.ExpString(","), - $.ExpString("."), - $.ExpString(";"), - $.ExpString("~"), - ]), - ), - ), - ), - ), - "id", - $.eps, - ), - ), - ), - ), -); -export const hexDigit: $.Parser<$ast.hexDigit> = $.named( - "hexadecimal digit", - $.regex("0-9a-fA-F", [ - $.ExpRange("0", "9"), - $.ExpRange("a", "f"), - $.ExpRange("A", "F"), - ]), -); -export const escapeChar: $.Parser<$ast.escapeChar> = $.alt( - $.regex<"\\" | '"' | "n" | "r" | "t" | "v" | "b" | "f">('\\\\"nrtvbf', [ - $.ExpString("\\"), - $.ExpString('"'), - $.ExpString("n"), - $.ExpString("r"), - $.ExpString("t"), - $.ExpString("v"), - $.ExpString("b"), - $.ExpString("f"), - ]), - $.alt( - $.right( - $.str("u{"), - $.left( - $.stry( - $.right( - hexDigit, - $.right( - $.opt(hexDigit), - $.right( - $.opt(hexDigit), - $.right( - $.opt(hexDigit), - $.right( - $.opt(hexDigit), - $.right($.opt(hexDigit), $.eps), - ), - ), - ), - ), - ), - ), - $.str("}"), - ), - ), - $.alt( - $.right( - $.str("u"), - $.stry( - $.right( - hexDigit, - $.right( - hexDigit, - $.right(hexDigit, $.right(hexDigit, $.eps)), - ), - ), - ), - ), - $.right( - $.str("x"), - $.stry($.right(hexDigit, $.right(hexDigit, $.eps))), - ), - ), - ), -); -export const reservedWord: $.Parser<$ast.reservedWord> = $.named( - "reserved word", - keyword( - $.alt( - $.str("extend"), - $.alt( - $.str("public"), - $.alt( - $.str("fun"), - $.alt( - $.str("let"), - $.alt( - $.str("return"), - $.alt( - $.str("receive"), - $.alt( - $.str("native"), - $.alt( - $.str("primitive"), - $.alt( - $.str("null"), - $.alt( - $.str("if"), - $.alt( - $.str("else"), - $.alt( - $.str("while"), - $.alt( - $.str("repeat"), - $.alt( - $.str("do"), - $.alt( - $.str( - "until", - ), - $.alt( - $.str( - "try", - ), - $.alt( - $.str( - "catch", - ), - $.alt( - $.str( - "foreach", - ), - $.alt( - $.str( - "as", - ), - $.alt( - $.str( - "map", - ), - $.alt( - $.str( - "mutates", - ), - $.alt( - $.str( - "extends", - ), - $.alt( - $.str( - "external", - ), - $.alt( - $.str( - "import", - ), - $.alt( - $.str( - "with", - ), - $.alt( - $.str( - "trait", - ), - $.alt( - $.str( - "initOf", - ), - $.alt( - $.str( - "override", - ), - $.alt( - $.str( - "abstract", - ), - $.alt( - $.str( - "virtual", - ), - $.alt( - $.str( - "inline", - ), - $.str( - "const", - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), - ), -); -export const space: $.Parser<$ast.space> = $.named( - "space", - $.alt( - $.regex<" " | "\t" | "\r" | "\n">(" \\t\\r\\n", [ - $.ExpString(" "), - $.ExpString("\t"), - $.ExpString("\r"), - $.ExpString("\n"), - ]), - comment, - ), -); -export const JustImports: $.Parser<$ast.JustImports> = $.loc( - $.field( - $.pure("JustImports"), - "$", - $.field($.star(Import), "imports", $.right($.star($.any), $.eps)), - ), -); +export const Suffix: $.Parser<$ast.Suffix> = $.loc($.field($.pure("Suffix"), "$", $.field($.lazy(() => primary), "expression", $.field($.star($.lazy(() => suffix)), "suffixes", $.eps)))); +export const Operator = (U: $.Parser): $.Parser<$ast.Operator> => $.loc($.field($.pure("Operator"), "$", $.field($.lazy(() => U), "name", $.eps))); +export const SuffixUnboxNotNull: $.Parser<$ast.SuffixUnboxNotNull> = $.loc($.field($.pure("SuffixUnboxNotNull"), "$", $.right($.str("!!"), $.eps))); +export const SuffixCall: $.Parser<$ast.SuffixCall> = $.loc($.field($.pure("SuffixCall"), "$", $.field($.opt(typeArgs), "typeArgs", $.field($.lazy(() => parameterList(expression)), "params", $.eps)))); +export const SuffixFieldAccess: $.Parser<$ast.SuffixFieldAccess> = $.loc($.field($.pure("SuffixFieldAccess"), "$", $.right($.str("."), $.field(Id, "name", $.eps)))); +export const suffix: $.Parser<$ast.suffix> = $.alt(SuffixUnboxNotNull, $.alt(SuffixCall, SuffixFieldAccess)); +export const Unit: $.Parser<$ast.Unit> = $.loc($.field($.pure("Unit"), "$", $.right($.right($.str("("), $.right($.str(")"), $.eps)), $.eps))); +export const Tensor: $.Parser<$ast.Tensor> = $.loc($.field($.pure("Tensor"), "$", $.right($.str("("), $.field(expression, "head", $.field($.plus($.right($.str(","), expression)), "tail", $.right($.opt($.str(",")), $.right($.str(")"), $.eps))))))); +export const Tuple: $.Parser<$ast.Tuple> = $.loc($.field($.pure("Tuple"), "$", $.right($.str("["), $.field($.opt(commaList(expression)), "types", $.right($.str("]"), $.eps))))); +export const Parens: $.Parser<$ast.Parens> = $.loc($.field($.pure("Parens"), "$", $.field($.lazy(() => parens), "child", $.eps))); +export const MapLiteral: $.Parser<$ast.MapLiteral> = $.loc($.field($.pure("MapLiteral"), "$", $.right(keyword($.str("map")), $.field(typeArgs, "typeArgs", $.right($.str("{"), $.field($.opt(commaList($.lazy(() => mapField))), "fields", $.right($.str("}"), $.eps))))))); +export const SetLiteral: $.Parser<$ast.SetLiteral> = $.loc($.field($.pure("SetLiteral"), "$", $.right($.str("set"), $.field(typeArgs, "typeArgs", $.right($.str("{"), $.field($.opt(commaList(expression)), "fields", $.right($.str("}"), $.eps))))))); +export const StructInstance: $.Parser<$ast.StructInstance> = $.loc($.field($.pure("StructInstance"), "$", $.field(TypeId, "type", $.field($.opt(typeArgs), "typeArgs", $.right($.str("{"), $.field($.opt(commaList($.lazy(() => StructFieldInitializer))), "fields", $.right($.str("}"), $.eps))))))); +export const StaticCall: $.Parser<$ast.StaticCall> = $.loc($.field($.pure("StaticCall"), "$", $.field(TypeId, "type", $.field($.opt(typeArgs), "typeArgs", $.right($.str("."), $.field(Id, "name", $.field($.lazy(() => parameterList(expression)), "args", $.eps))))))); +export const IntegerLiteral: $.Parser<$ast.IntegerLiteral> = $.loc($.field($.pure("IntegerLiteral"), "$", $.field($.alt($.lazy(() => IntegerLiteralHex), $.alt($.lazy(() => IntegerLiteralBin), $.alt($.lazy(() => IntegerLiteralOct), IntegerLiteralDec))), "value", $.eps))); +export const BoolLiteral: $.Parser<$ast.BoolLiteral> = $.loc($.field($.pure("BoolLiteral"), "$", $.field($.alt($.str("true"), $.str("false")), "value", $.right($.lookNeg($.lazy(() => idPart)), $.eps)))); +export const InitOf: $.Parser<$ast.InitOf> = $.loc($.field($.pure("InitOf"), "$", $.right(keyword($.str("initOf")), $.field(TypeId, "name", $.field($.lazy(() => parameterList(expression)), "params", $.eps))))); +export const CodeOf: $.Parser<$ast.CodeOf> = $.loc($.field($.pure("CodeOf"), "$", $.right($.str("codeOf"), $.field(TypeId, "name", $.eps)))); +export const Null: $.Parser<$ast.Null> = $.loc($.field($.pure("Null"), "$", $.right(keyword($.str("null")), $.eps))); +export const primary: $.Parser<$ast.primary> = $.alt(Unit, $.alt(Tensor, $.alt(Tuple, $.alt(Parens, $.alt(MapLiteral, $.alt(SetLiteral, $.alt(StructInstance, $.alt(StaticCall, $.alt(IntegerLiteral, $.alt(BoolLiteral, $.alt(InitOf, $.alt(CodeOf, $.alt(Null, $.alt(StringLiteral, Id)))))))))))))); +export const parens: $.Parser<$ast.parens> = $.right($.str("("), $.left(expression, $.str(")"))); +export const StructFieldInitializer: $.Parser<$ast.StructFieldInitializer> = $.loc($.field($.pure("StructFieldInitializer"), "$", $.field(Id, "name", $.field($.opt($.right($.str(":"), expression)), "init", $.eps)))); +export const mapField: $.Parser<$ast.mapField> = $.field(expression, "key", $.right($.str(":"), $.field(expression, "value", $.eps))); +export const ParameterList = (T: $.Parser): $.Parser<$ast.ParameterList> => $.loc($.field($.pure("ParameterList"), "$", $.right($.str("("), $.field($.opt(commaList($.lazy(() => T))), "values", $.right($.str(")"), $.eps))))); +export const parameterList = (T: $.Parser): $.Parser<$ast.parameterList> => $.right($.str("("), $.left($.opt(commaList($.lazy(() => T))), $.str(")"))); +export const IntegerLiteralHex: $.Parser<$ast.IntegerLiteralHex> = $.loc($.field($.pure("IntegerLiteralHex"), "$", $.field($.lex($.right($.str("0"), $.right($.regex<"x" | "X">("xX", [$.ExpString("x"), $.ExpString("X")]), $.lazy(() => underscored($.lazy(() => hexDigit)))))), "digits", $.eps))); +export const IntegerLiteralBin: $.Parser<$ast.IntegerLiteralBin> = $.loc($.field($.pure("IntegerLiteralBin"), "$", $.field($.lex($.right($.str("0"), $.right($.regex<"b" | "B">("bB", [$.ExpString("b"), $.ExpString("B")]), $.lazy(() => underscored($.regex<"0" | "1">("01", [$.ExpString("0"), $.ExpString("1")])))))), "digits", $.eps))); +export const IntegerLiteralOct: $.Parser<$ast.IntegerLiteralOct> = $.loc($.field($.pure("IntegerLiteralOct"), "$", $.field($.lex($.right($.str("0"), $.right($.regex<"o" | "O">("oO", [$.ExpString("o"), $.ExpString("O")]), $.lazy(() => underscored($.regex("0-7", [$.ExpRange("0", "7")])))))), "digits", $.eps))); +export const underscored = (T: $.Parser): $.Parser<$ast.underscored> => $.stry($.right($.lazy(() => T), $.right($.star($.right($.opt($.str("_")), $.right($.lazy(() => T), $.eps))), $.eps))); +export const digit: $.Parser<$ast.digit> = $.named("digit", $.regex("0-9", [$.ExpRange("0", "9")])); +export const idPart: $.Parser<$ast.idPart> = $.named("identifier character", $.regex("a-zA-Z0-9_", [$.ExpRange("a", "z"), $.ExpRange("A", "Z"), $.ExpRange("0", "9"), $.ExpString("_")])); +export const FuncId: $.Parser<$ast.FuncId> = $.named("FunC identifier", $.loc($.field($.pure("FuncId"), "$", $.field($.opt($.regex<"." | "~">(".~", [$.ExpString("."), $.ExpString("~")])), "accessor", $.field($.stry($.alt($.right($.str("`"), $.right($.plus($.regex<"`" | "\r" | "\n">("^`\\r\\n", $.negateExps([$.ExpString("`"), $.ExpString("\r"), $.ExpString("\n")]))), $.right($.str("`"), $.eps))), $.plus($.regex<" " | "\t" | "\r" | "\n" | "(" | ")" | "[" | string | "," | "." | ";" | "~">("^ \\t\\r\\n()[\\],.;~", $.negateExps([$.ExpString(" "), $.ExpString("\t"), $.ExpString("\r"), $.ExpString("\n"), $.ExpString("("), $.ExpString(")"), $.ExpString("["), $.ExpString("\"\\]\""), $.ExpString(","), $.ExpString("."), $.ExpString(";"), $.ExpString("~")]))))), "id", $.eps))))); +export const hexDigit: $.Parser<$ast.hexDigit> = $.named("hexadecimal digit", $.regex("0-9a-fA-F", [$.ExpRange("0", "9"), $.ExpRange("a", "f"), $.ExpRange("A", "F")])); +export const escapeChar: $.Parser<$ast.escapeChar> = $.alt($.regex<"\\" | "\"" | "n" | "r" | "t" | "v" | "b" | "f">("\\\\\"nrtvbf", [$.ExpString("\\"), $.ExpString("\""), $.ExpString("n"), $.ExpString("r"), $.ExpString("t"), $.ExpString("v"), $.ExpString("b"), $.ExpString("f")]), $.alt($.right($.str("u{"), $.left($.stry($.right(hexDigit, $.right($.opt(hexDigit), $.right($.opt(hexDigit), $.right($.opt(hexDigit), $.right($.opt(hexDigit), $.right($.opt(hexDigit), $.eps))))))), $.str("}"))), $.alt($.right($.str("u"), $.stry($.right(hexDigit, $.right(hexDigit, $.right(hexDigit, $.right(hexDigit, $.eps)))))), $.right($.str("x"), $.stry($.right(hexDigit, $.right(hexDigit, $.eps))))))); +export const reservedWord: $.Parser<$ast.reservedWord> = $.named("reserved word", keyword($.alt($.str("extend"), $.alt($.str("public"), $.alt($.str("fun"), $.alt($.str("let"), $.alt($.str("return"), $.alt($.str("receive"), $.alt($.str("native"), $.alt($.str("primitive"), $.alt($.str("null"), $.alt($.str("if"), $.alt($.str("else"), $.alt($.str("while"), $.alt($.str("repeat"), $.alt($.str("do"), $.alt($.str("until"), $.alt($.str("try"), $.alt($.str("catch"), $.alt($.str("foreach"), $.alt($.str("as"), $.alt($.str("map"), $.alt($.str("mutates"), $.alt($.str("extends"), $.alt($.str("external"), $.alt($.str("import"), $.alt($.str("with"), $.alt($.str("trait"), $.alt($.str("initOf"), $.alt($.str("override"), $.alt($.str("abstract"), $.alt($.str("virtual"), $.alt($.str("inline"), $.str("const")))))))))))))))))))))))))))))))))); +export const space: $.Parser<$ast.space> = $.named("space", $.alt($.regex<" " | "\t" | "\r" | "\n">(" \\t\\r\\n", [$.ExpString(" "), $.ExpString("\t"), $.ExpString("\r"), $.ExpString("\n")]), comment)); +export const JustImports: $.Parser<$ast.JustImports> = $.loc($.field($.pure("JustImports"), "$", $.field($.star(Import), "imports", $.right($.star($.any), $.eps)))); \ No newline at end of file diff --git a/src/next/grammar/index.ts b/src/next/grammar/index.ts index 08b5979b3c..9afc8c4c83 100644 --- a/src/next/grammar/index.ts +++ b/src/next/grammar/index.ts @@ -584,6 +584,16 @@ const parseTuple = ); }; +const parseStaticCall = ({ type, name, typeArgs, args, loc }: $ast.StaticCall): Handler => ctx => { + return Ast.StaticMethodCall( + parseTypeId(type)(ctx), + map(parseList(typeArgs), parseType)(ctx), + parseId(name)(ctx), + map(parseList(args), parseExpression)(ctx), + ctx.toRange(loc), + ); +}; + const parseParens = ({ child }: $ast.Parens): Handler => { return parseExpression(child); }; @@ -610,7 +620,8 @@ type Expression = | $ast.Tensor | $ast.Tuple | $ast.MapLiteral - | $ast.SetLiteral; + | $ast.SetLiteral + | $ast.StaticCall; const parseExpression: (input: Expression) => Handler = makeVisitor()({ @@ -632,6 +643,7 @@ const parseExpression: (input: Expression) => Handler = Tuple: parseTuple, MapLiteral: parseMapLiteral, SetLiteral: parseSetLiteral, + StaticCall: parseStaticCall, }); const parseStatementLet = @@ -1415,7 +1427,7 @@ const parseInheritance = ( hasBody: boolean, attrs: readonly ($ast.FunctionAttribute | $ast.ConstantAttribute)[], range: Range, -): Handler<{ override: boolean, virtual: boolean }> => ctx => { +): Handler<{ override: boolean, overridable: boolean }> => ctx => { const isVirtual = parseNamedAttr("virtual")(attrs)(ctx); const isOverride = parseNamedAttr("override")(attrs)(ctx); const isAbstract = parseNamedAttr("abstract")(attrs)(ctx); @@ -1436,7 +1448,7 @@ const parseInheritance = ( } return { override: !!isOverride, - virtual: !!isVirtual, + overridable: !!isVirtual || !!isAbstract, }; }; @@ -1477,7 +1489,7 @@ const parseFieldConstant = node.attributes, ctx.toRange(node.loc), )(ctx); - return Ast.FieldConstant(inh.virtual, inh.override, body); + return Ast.FieldConstant(inh.overridable, inh.override, body); }; const parseContract = @@ -1629,7 +1641,7 @@ const parseMethod = } return Ast.Method( !!isMutates, - inh.virtual, + inh.overridable, inh.override, get, fn, diff --git a/src/next/index.ts b/src/next/index.ts index 59cd2e489e..4142ce691d 100644 --- a/src/next/index.ts +++ b/src/next/index.ts @@ -3,7 +3,7 @@ import { TerminalLogger } from "@/cli/logger"; import { getAnsiMarkup, isColorSupported } from "@/cli/colors"; import { ProjectReader } from "@/next/imports/reader"; import { inspect } from "util"; -import { scope } from "@/next/scoping/tc2"; +import { scope } from "@/next/scoping/typecheck"; // eslint-disable-next-line @typescript-eslint/no-unused-vars const dump = (obj: unknown) => diff --git a/src/next/scoping/errors.ts b/src/next/scoping/errors.ts index d44f7a8635..0b52436b7e 100644 --- a/src/next/scoping/errors.ts +++ b/src/next/scoping/errors.ts @@ -100,6 +100,12 @@ export const TcErrors = (l: SourceLogger) => ({ } return l.at(loc).error(l.text`Type is not a struct or message`); }, + staticMethodNotDefined: () => (loc: Ty.Loc) => { + if (loc.kind !== 'range') { + return l.internal(l.text`${loc.kind} mismatch`); + } + return l.at(loc).error(l.text`Only fromCell and fromSlice static methods are supported`); + }, noInit: () => (loc: Ty.Loc) => { if (loc.kind !== 'range') { return l.internal(l.text`${loc.kind} mismatch`); diff --git a/src/next/scoping/typecheck.ts b/src/next/scoping/typecheck.ts index d0013f0680..743d9988f7 100644 --- a/src/next/scoping/typecheck.ts +++ b/src/next/scoping/typecheck.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-unnecessary-condition */ /* eslint-disable @typescript-eslint/no-base-to-string */ import { makeVisitor, memo } from "@/utils/tricks"; import type { Logger } from "@/error/logger-util"; @@ -41,11 +42,13 @@ type Result = { readonly types: ReadonlyMap; }; -type DeclMap = Map = { readonly source: TactSource; readonly entry: T; readonly loc: Range | Implicit; -}>; +} + +type DeclMap = Map>; type Registry = { readonly get: (key: string) => T | undefined; @@ -57,6 +60,23 @@ type Registry = { ) => void; } +type TypeExtensionRecord = { + readonly source: TactSource; + readonly self: Ty.LocType; + + readonly mutates: boolean; + readonly fun: Ast.Function; + readonly loc: Range | Implicit; +} + +// type ContractExtensionRecord = { +// readonly source: TactSource; +// readonly self: Ast.Trait | Ast.Contract; + +// readonly fun: Ast.Method; +// readonly loc: Range | Implicit; +// } + const scopeIds = (log: Logger) => (children: [Result, TactImport][], source: TactSource): Result => { const err = log.source(source.path, source.code, (logger) => TcErrors(logger)); @@ -78,8 +98,30 @@ const scopeIds = (log: Logger) => }; }; + // method name -> (type -> method) + const typeExt: Map = new Map(); + const findTypeMethod = ( + methodName: string, + selfType: Ty.LocType, + ): undefined | TypeExtensionRecord => { + const methodReg = typeExt.get(methodName); + if (typeof methodReg === 'undefined') { + return undefined; + } + for (const reg of methodReg) { + resolveOverload(reg.self, selfType) + } + }; + + // extends fun foo(self: T); + // extends fun foo(self: Either); + // let x: Either; + // x.foo(); + // findTypeMethod("foo", Either); + + // const contractExt: Map = new Map(); + const functions = makeRegistry(new Set()); - const extensions = makeRegistry(new Set()); const constants = makeRegistry(new Set()); const types = makeRegistry(new Set([ "void", @@ -122,8 +164,7 @@ const scopeIds = (log: Logger) => continue; } case "extension": { - const id = item.method.fun.name; - extensions.add(id.text, item, source, id.loc); + // handled below continue; } case "struct_decl": @@ -138,18 +179,87 @@ const scopeIds = (log: Logger) => } } + for (const item of source.items) { + switch (item.kind) { + case "extension": { + const id = item.method.fun.name; + extensions.add(id.text, item, source, id.loc); + continue; + } + case "contract": + case "trait": { + continue; + } + case "function": + case "constant": + case "struct_decl": + case "message_decl": + case "union_decl": + case "alias_decl": { + continue; + } + } + } + for (const item of source.items) { checkItem(types.get, err, item); } return { functions: functions.get(), - constants: constants.get(), + constants: constants.get(), types: types.get(), extensions: extensions.get(), }; }; +type Spine = SpineCons | SpineVar +type SpineCons = { + readonly kind: 'cons'; + readonly name: string; + readonly children: readonly Spine[]; +} +const SpineCons = (name: string, children: readonly Spine[]): SpineCons => ({ kind: 'cons', name, children }); +type SpineVar = { + readonly kind: 'var'; + readonly id: number; +} +const SpineVar = (id: number): SpineVar => ({ kind: 'var', id }); + +const getSpine = (type: Ty.Type): undefined | Spine => { + switch (type.kind) { + case "map_type": { + const key = getSpine(type.key); + const value = getSpine(type.value); + if (!key || !value) return undefined; + return SpineCons("map", [key, value]); + } + case "cons_type": { + const children: Spine[] = []; + for (const arg of type.typeArgs) { + const spine = getSpine(arg); + if (spine) { + children.push(spine); + } else { + return undefined; + } + } + return SpineCons(type.name.text, children); + } + case "TyInt": return SpineCons("Int", []); + case "TySlice": return SpineCons("Slice", []); + case "TyCell": return SpineCons("Cell", []); + case "TyBuilder": return SpineCons("Builder", []); + case "type_var": return SpineVar(type.id); + case "tuple_type": + case "unit_type": + case "tensor_type": + case "ERROR": { + return undefined; + } + } +}; + const noTypeParams = () => false; const checkItem = ( @@ -159,6 +269,7 @@ const checkItem = ( ) => { // TODO: check kinds // TODO: Check if self is initialized + // TODO: map key should be serializable without refs switch (node.kind) { case "constant": { const { init } = node; @@ -179,6 +290,8 @@ const checkItem = ( } } case "function": { + // TODO: check return value + // foo(x: Int): Int { if (x == 42) return 43; } return; } case "extension": { @@ -197,6 +310,7 @@ const checkItem = ( return; } case "contract": { + // check all contract fields are initialized return; } case "trait": { @@ -209,6 +323,7 @@ const Int257 = (loc: Ty.Loc) => Ty.TypeInt(Ty.IFInt("signed", 257, loc), loc); const String = (loc: Ty.Loc) => Ty.TypeCons(Ty.TypeId("String", loc), [], loc); const Bool = (loc: Ty.Loc) => Ty.TypeCons(Ty.TypeId("Bool", loc), [], loc); const Cell = (loc: Ty.Loc) => Ty.TypeCons(Ty.TypeId("Cell", loc), [], loc); +const Slice = (loc: Ty.Loc) => Ty.TypeCons(Ty.TypeId("Slice", loc), [], loc); const StateInit = (loc: Ty.Loc) => Ty.TypeCons(Ty.TypeId("StateInit", loc), [], loc); const Maybe = (param: Ty.Type, loc: Ty.Loc) => Ty.TypeCons(Ty.TypeId("Maybe", loc), [param], loc); const Null = (loc: Ty.Loc) => Ty.TypeCons(Ty.TypeId("Null", loc), [], loc); @@ -351,22 +466,32 @@ const getExprChecker = ( } }; - const mgu = (left: Ty.Type, right: Ty.Type): Ty.Type => { + const mgu = (left: Ty.Type, right: Ty.Type, loc: Ty.Loc): Ty.Type => { + left = simplifyHead(left); + right = simplifyHead(right); if (left.kind === 'ERROR' || right.kind === 'ERROR') { return Ty.TypeErrorRecovered(); } if (left.kind === 'type_var' || right.kind === 'type_var') { return throwInternal("Trying to unify type variable"); } - const children1: MismatchTree[] = []; - const children2: MismatchTree[] = []; - if (assignToAux1(left, right, children1)) { + const children: MismatchTree[] = []; + if (assignToAux1(left, right, children)) { return left; } - if (assignToAux1(right, left, children2)) { + if (assignToAux1(right, left, children)) { return right; } - // TODO + if (isNull(right)) { + return Maybe(left, loc); + } + if (isNull(left)) { + return Maybe(right, loc); + } + for (const tree of children) { + err.typeMismatch(tree)(loc); + } + return Ty.TypeErrorRecovered(); }; let nextId = 0; @@ -446,7 +571,7 @@ const getExprChecker = ( const rightLoc = Ty.Builtin(`right parameter of "${node.op}" operator`); const leftType = checkExpr(node.left); const rightType = checkExpr(node.right); - + switch (node.op) { case "+": case "-": @@ -480,18 +605,14 @@ const getExprChecker = ( } case "!=": case "==": { - // TODO: - // Maybe ? Null - // Null ? Maybe - // map<> ? Null - // Null ? map<> - // "Int" - // "Bool" - // "Address" - // "Cell" - // "Slice" - // "String" - return Bool(resultLoc); + const common = mgu(leftType, rightType, resultLoc); + if (common.kind === 'ERROR') { + return common; + } + if (supportsEquality(common)) { + return Bool(resultLoc); + } + return Ty.TypeErrorRecovered(); } case "&&": case "||": { @@ -509,15 +630,13 @@ const getExprChecker = ( const checkTernary = (node: Ast.Conditional): Ty.Type => { const resultLoc = Ty.Inferred(node.loc, `result of ternary operator`); const condLoc = Ty.Builtin(`condition of ternary operator`); - const thenLoc = Ty.Builtin(`"then" of ternary operator`); - const elseLoc = Ty.Builtin(`"else" of ternary operator`); - const condType = checkExpr(node.condition); const commonType = mgu( checkExpr(node.thenBranch), checkExpr(node.elseBranch), + resultLoc, ); if ( - !assignTo(Bool(condLoc), condType) + !assignTo(Bool(condLoc), checkExpr(node.condition)) || commonType.kind === 'ERROR' ) { return Ty.TypeErrorRecovered(); @@ -559,12 +678,11 @@ const getExprChecker = ( }; const checkInitOf = (node: Ast.InitOf): Ty.Type => { - // resolveInitOf const contract = getContract(node.contract); if (!contract) { return Ty.TypeErrorRecovered(); } - + const { init } = contract; if (!init) { err.noInit()(node.loc) @@ -579,8 +697,6 @@ const getExprChecker = ( for (const [index, param] of init.params.entries()) { const arg = node.args[index]; - // const paramName = param.name.kind === 'id' ? param.name.text : `number ${index + 1}`; - // const argType = arg ? : Null(Ty.Inferred(node.loc, `omitted parameter ${paramName}`)); // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (arg) { const children: MismatchTree[] = []; @@ -602,9 +718,20 @@ const getExprChecker = ( readonly subst: (type: Ty.Type) => Ty.Type; readonly getArgs: () => readonly Ty.Type[]; } + + const fillUpTypeArgs = (args: readonly Ty.Type[], params: readonly Ty.TypeId[]): readonly Ty.Type[] => [ + // cut extraneous arguments + ...args.slice(0, params.length), + // pad with missing arguments + ...new Array(Math.max(0, params.length - args.length)) + .fill(0).map(() => Ty.TypeErrorRecovered()) + ]; const substTypeParams = ( struct: Ast.StructDecl | Ast.MessageDecl, - node: Ast.StructInstance, + node: { + readonly typeArgs: readonly Ty.Type[], + readonly loc: Ty.Loc, + }, ): Substitutor => { if (struct.kind === 'message_decl') { if (node.typeArgs.length > 0) { @@ -656,15 +783,7 @@ const getExprChecker = ( node.typeArgs, ); }, - getArgs: () => { - return [ - // cut extraneous arguments - ...node.typeArgs.slice(0, struct.typeParams.length), - // pad with missing arguments - ...new Array(Math.max(0, struct.typeParams.length - node.typeArgs.length)) - .fill(0).map(() => Ty.TypeErrorRecovered()) - ]; - }, + getArgs: () => fillUpTypeArgs(node.typeArgs, struct.typeParams), }; }; const checkStructInstance = (node: Ast.StructInstance): Ty.Type => { @@ -698,6 +817,40 @@ const getExprChecker = ( ); }; + const checkStaticMethodCall = (node: Ast.StaticMethodCall): Ty.Type => { + const struct = getStruct(node.self); + if (!struct) { + return Ty.TypeErrorRecovered(); + } + const name = node.function.text; + if (name !== "fromSlice" && name !== "fromCell") { + err.staticMethodNotDefined()(node.function.loc); + return Ty.TypeErrorRecovered(); + } + const paramLoc = Ty.Builtin(`parameter of .${name}()`); + const [arg] = node.args; + if (node.args.length !== 1 || !arg) { + err.fnArity(name, node.args.length, 1)(node.loc); + } else if (name === 'fromSlice') { + // fromSlice: Struct.(Slice) -> struct + assignTo(Slice(paramLoc), checkExpr(arg)); + } else if (name === 'fromCell') { + // fromCell: Struct.(Cell) -> struct + assignTo(Cell(paramLoc), checkExpr(arg)); + } + if (struct.kind === 'struct_decl' && struct.typeParams.length !== node.typeArgs.length) { + err.typeArity(struct.name.text, node.typeArgs.length, 0)(node.loc); + } + const resultLoc = Ty.Inferred(node.loc, `result of .${name}()`); + return Ty.TypeCons( + Ty.TypeId(node.self.text, resultLoc), + struct.kind === 'struct_decl' + ? fillUpTypeArgs(node.typeArgs, struct.typeParams) + : [], + resultLoc, + ); + }; + const checkFunctionCall = (node: Ast.StaticCall): Ty.Type => { // dump: checkDump, // (ref | void | null | map | Cell | Slice | Builder | Address | String | Bool | Int) -> void @@ -727,22 +880,42 @@ const getExprChecker = ( }; const checkMethodCall = (node: Ast.MethodCall): Ty.Type => { - // toCell : struct.() -> Cell - // toSlice: struct.() -> Slice + const self = checkExpr(node.self); + switch (self.kind) { + case "cons_type": { + // struct + // toCell : struct.() -> Cell + // toSlice: struct.() -> Slice - // K = Int|Address - // set: map.(key: K, value: V) -> void - // get: map.(key: K) -> Maybe - // del: map.(key: K) -> Bool - // asCell: map.() -> Maybe - // isEmpty: map.() -> Bool - // exists: map.(key: K) -> Bool - // deepEquals: map.(other: map) -> Bool // mgu - // replace: map.(key: K, value: V) -> Bool - // replaceGet: map.(key: K, value: V) -> map + // bounced<> не переносит методы - // bounced<> не переносит методы - // null -- Maybe<>, map<>, Null; может быть >1 кандидата + // null + // Maybe<>, map<>, Null; может быть >1 кандидата + return; + } + case "map_type": { + // set: map.(key: K, value: V) -> void + // get: map.(key: K) -> Maybe + // del: map.(key: K) -> Bool + // asCell: map.() -> Maybe + // isEmpty: map.() -> Bool + // exists: map.(key: K) -> Bool + // deepEquals: map.(other: map) -> Bool // mgu + // replace: map.(key: K, value: V) -> Bool + // replaceGet: map.(key: K, value: V) -> map + } + case "ERROR": + case "type_var": { + return; + } + case "TyInt": + case "TySlice": + case "TyCell": + case "TyBuilder": + case "tuple_type": + case "unit_type": + case "tensor_type": + } }; const checkField = (node: Ast.FieldAccess): Ty.Type => { @@ -754,26 +927,22 @@ const getExprChecker = ( const checkVariable = (node: Ast.Var): Ty.Type => { // 1. константы - // 2. Type.foo() - // fromCell: Struct.(Cell) -> struct - // fromSlice: Struct.(Slice) -> struct - // FIXME!!! // 3. переменные // 4. кастомная ошибка, когда foo, но нужен self.foo }; - + const checkTuple = (node: Ast.Tuple): Ty.Type => { // }; - + const checkTensor = (node: Ast.Tensor): Ty.Type => { // }; - + const checkMapLiteral = (node: Ast.MapLiteral): Ty.Type => { // }; - + const checkSetLiteral = (node: Ast.SetLiteral): Ty.Type => { // }; @@ -798,6 +967,7 @@ const getExprChecker = ( tensor: checkTensor, map_literal: checkMapLiteral, set_literal: checkSetLiteral, + static_method_call: checkStaticMethodCall, }); return { @@ -807,6 +977,14 @@ const getExprChecker = ( }; }; +const supportsEquality = (common: Ty.Type): boolean => { + return common.kind === 'cons_type' && common.name.text === 'Maybe' && common.typeArgs.every(arg => supportsEquality(arg)) + || common.kind === 'map_type' + || common.kind === 'cons_type' && [ + "Int", "Bool", "Address", "Cell", "Slice", "String" + ].includes(common.name.text) +}; + const substParams = (into: Ty.Type, params: readonly Ty.TypeId[], args: readonly Ty.Type[]) => { return zip(params, args) .reduce((type, [param, arg]) => { From 25bc51032096321309868d70b7bb9d9645fee024 Mon Sep 17 00:00:00 2001 From: verytactical <186486509+verytactical@users.noreply.github.com> Date: Thu, 15 May 2025 19:20:08 +0400 Subject: [PATCH 19/38] debugging --- .vscode/launch.json | 18 ++ package.json | 2 + src/next/ast/generated/common.ts | 9 +- src/next/fs/memory-fs.ts | 8 +- src/next/fs/proxy-fs.ts | 6 +- src/next/grammar/index.ts | 4 +- src/next/imports/reader.ts | 40 +++-- src/next/scoping/typecheck.ts | 44 +++-- src/next/test/_cli.build.ts | 9 + src/next/test/_run.test.ts | 36 ++++ src/next/test/_test.build.ts | 65 +++++++ src/next/test/fun-shadow-1.snap.js | 43 +++++ src/next/test/fun-shadow-1.tact | 3 + src/next/test/fun-shadow-2.snap.js | 41 +++++ src/next/test/fun-shadow-2.tact | 5 + src/next/test/fun-shadow-3.snap.js | 8 + src/next/test/fun-shadow-3.tact | 3 + src/next/test/fun-shadow-4.snap.js | 8 + src/next/test/fun-shadow-4.tact | 5 + src/next/test/fun-shadow-5.snap.js | 43 +++++ src/next/test/fun-shadow-5.tact | 7 + src/next/test/to-code.ts | 137 +++++++++++++++ src/next/types/typecheck.ts | 261 +++++++++++++++++++++++++++++ src/next/types/via.ts | 47 ++++++ src/next/types/writer.ts | 70 ++++++++ src/utils/tricks.ts | 12 +- yarn.lock | 21 ++- 27 files changed, 914 insertions(+), 41 deletions(-) create mode 100644 .vscode/launch.json create mode 100644 src/next/test/_cli.build.ts create mode 100644 src/next/test/_run.test.ts create mode 100644 src/next/test/_test.build.ts create mode 100644 src/next/test/fun-shadow-1.snap.js create mode 100644 src/next/test/fun-shadow-1.tact create mode 100644 src/next/test/fun-shadow-2.snap.js create mode 100644 src/next/test/fun-shadow-2.tact create mode 100644 src/next/test/fun-shadow-3.snap.js create mode 100644 src/next/test/fun-shadow-3.tact create mode 100644 src/next/test/fun-shadow-4.snap.js create mode 100644 src/next/test/fun-shadow-4.tact create mode 100644 src/next/test/fun-shadow-5.snap.js create mode 100644 src/next/test/fun-shadow-5.tact create mode 100644 src/next/test/to-code.ts create mode 100644 src/next/types/typecheck.ts create mode 100644 src/next/types/via.ts create mode 100644 src/next/types/writer.ts diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000000..ebd943eb57 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,18 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Run _cli.build.ts", + "type": "node", + "request": "launch", + "program": "${workspaceFolder}/src/next/test/_cli.build.ts", + "args": [ + "${file}" + ], + "runtimeExecutable": "ts-node", + "cwd": "${workspaceFolder}", + "console": "integratedTerminal", + "internalConsoleOptions": "neverOpen" + } + ] +} \ No newline at end of file diff --git a/package.json b/package.json index b53b856988..9cab754664 100644 --- a/package.json +++ b/package.json @@ -109,6 +109,7 @@ "@types/glob": "^8.1.0", "@types/jest": "^29.5.12", "@types/node": "^22.5.0", + "@types/serialize-javascript": "^5.0.4", "@typescript-eslint/eslint-plugin": "^8.21.0", "@typescript-eslint/parser": "^8.21.0", "chalk": "4.1.2", @@ -127,6 +128,7 @@ "knip": "^5.24.1", "prando": "^6.0.1", "prettier": "^3.2.5", + "serialize-javascript": "^6.0.2", "ts-jest": "^29.0.3", "ts-node": "^10.9.1", "ts-to-zod": "^3.15.0", diff --git a/src/next/ast/generated/common.ts b/src/next/ast/generated/common.ts index f2e484f3d7..c504c58c12 100644 --- a/src/next/ast/generated/common.ts +++ b/src/next/ast/generated/common.ts @@ -1,5 +1,6 @@ /* eslint-disable @typescript-eslint/no-unnecessary-condition */ import type * as $ from "@/next/ast/common"; +import { hideProperty } from "@/utils/tricks"; export type Range = $.Range; export const Range = ( start: number, @@ -14,12 +15,8 @@ export const Range = ( path, code, }; - Object.defineProperty(result, 'code', { - value: code, - writable: true, - configurable: true, - enumerable: false, - }); + hideProperty(result, 'code'); + hideProperty(result, 'path'); return Object.freeze(result); }; export type Id = $.Id; diff --git a/src/next/fs/memory-fs.ts b/src/next/fs/memory-fs.ts index ac977075e6..a94fb9fa9c 100644 --- a/src/next/fs/memory-fs.ts +++ b/src/next/fs/memory-fs.ts @@ -5,9 +5,9 @@ import type { RelativePath } from "@/next/fs/path"; import type { Cursor } from "@/next/fs/cursor"; import type { Logger } from "@/error/logger-util"; -type Options = { +type Options = { // FIXME: should we pass log here, or into functions? - readonly log: Logger; + readonly log: Logger; /** * Files present in memory file system at creation time @@ -33,12 +33,12 @@ export const emptyFiles: Map = new Map(); /** * Create in-memory file system */ -export function createMemoryFs({ +export function createMemoryFs({ log, files, root, isReadonly, -}: Options): Cursor { +}: Options): Cursor { const errors = FsErrors(log); function builder(currPath: RelativePath): Cursor { diff --git a/src/next/fs/proxy-fs.ts b/src/next/fs/proxy-fs.ts index fdc8f46343..e39f9e396b 100644 --- a/src/next/fs/proxy-fs.ts +++ b/src/next/fs/proxy-fs.ts @@ -10,8 +10,8 @@ import type { Logger } from "@/error/logger-util"; const asRecord = (t: Record) => t; -type Options = { - readonly log: Logger; +type Options = { + readonly log: Logger; readonly root: string; readonly isReadonly: boolean; }; @@ -19,7 +19,7 @@ type Options = { /** * Create file system that proxies requests to real file system */ -export function createProxyFs({ log, root, isReadonly }: Options): Cursor { +export function createProxyFs({ log, root, isReadonly }: Options): Cursor { const errors = FsErrors(log); function builder(currPath: RelativePath): Cursor { diff --git a/src/next/grammar/index.ts b/src/next/grammar/index.ts index 9afc8c4c83..16a3c88e4d 100644 --- a/src/next/grammar/index.ts +++ b/src/next/grammar/index.ts @@ -1820,8 +1820,8 @@ const parseModule = ); }; -export const parse = ( - log: SourceLogger, +export const parse = ( + log: SourceLogger, code: string, path: string, ): Ast.Module => { diff --git a/src/next/imports/reader.ts b/src/next/imports/reader.ts index 48ce26be97..c45ba53aa2 100644 --- a/src/next/imports/reader.ts +++ b/src/next/imports/reader.ts @@ -4,10 +4,12 @@ import { parentPath, createMemoryFs, createProxyFs } from "@/next/fs"; import { getFiles } from "@/next/stdlib"; import type { Cursor } from "@/next/fs"; import type { AnyLogger, Logger, SourceLogger } from "@/error/logger-util"; -import type { ResolvedImport, TactSource } from "@/next/imports/source"; +import type { FuncImport, Implicit, ResolvedImport, TactImport, TactSource } from "@/next/imports/source"; +import type { ModuleItem, Range } from "@/next/ast"; +import { hideProperty } from "@/utils/tricks"; -type Options = { - readonly log: Logger; +type Options = { + readonly log: Logger; /** * Cursor to root of file system with project files */ @@ -27,18 +29,18 @@ type Options = { readonly root: string; }; -const readSource = async ({ +export const readSource = async ({ log, project, stdlib, implicits, root, -}: Options): Promise => { +}: Options): Promise => { const status: Map = new Map(); const resolveImports = async ( path: string, - log: SourceLogger, + log: SourceLogger, file: Cursor, code: string, ): Promise => { @@ -53,10 +55,10 @@ const readSource = async ({ if (language === "tact") { const source = await resolveSource(importedFile, log); if (source) { - imports.push({ kind: "tact", source, loc }); + imports.push(TactImport(source, loc)); } } else { - imports.push({ kind: "func", code, loc }); + imports.push(FuncImport(code, loc)); } } return { kind: 'tact', path, code, imports, items }; @@ -64,7 +66,7 @@ const readSource = async ({ const resolveSource = async ( file: Cursor, - parentLog: AnyLogger, + parentLog: AnyLogger, ): Promise => { const path = file.getAbsolutePathForLog(); const res = status.get(path); @@ -95,7 +97,7 @@ const readSource = async ({ /** * Read standard library and prepare for reading projects */ -export const ProjectReader = async (log: Logger) => { +export const ProjectReader = async (log: Logger) => { const stdRoot = createMemoryFs({ log, files: getFiles(), @@ -145,3 +147,21 @@ export const ProjectReader = async (log: Logger) => { return { read }; }; + +const TactImport = (source: TactSource, loc: Range | Implicit) => { + const result: TactImport = { kind: "tact", source, loc }; + hideProperty(result, 'source'); + return result; +}; + +const FuncImport = (code: string, loc: Range) => { + const result: FuncImport = { kind: "func", code, loc }; + hideProperty(result, 'code'); + return result; +}; + +const TactSource = (path: string, code: string, imports: readonly ResolvedImport[], items: readonly ModuleItem[]) => { + const result: TactSource = { kind: 'tact', path, code, imports, items }; + hideProperty(result, 'code'); + return result; +}; diff --git a/src/next/scoping/typecheck.ts b/src/next/scoping/typecheck.ts index 743d9988f7..373aa66bf2 100644 --- a/src/next/scoping/typecheck.ts +++ b/src/next/scoping/typecheck.ts @@ -99,7 +99,9 @@ const scopeIds = (log: Logger) => }; // method name -> (type -> method) - const typeExt: Map = new Map(); + const typeExt: Map = new Map(); const findTypeMethod = ( methodName: string, selfType: Ty.LocType, @@ -113,6 +115,18 @@ const scopeIds = (log: Logger) => } }; + // left: Either + // left: Int + // left: Maybe + // left: Slice + + // isGround = нет типовых переменных: Either + // isSimple = Cons : Either + // isGround || isSimple + // extends fun foo(self: Either) {} + // extends fun foo(self: Either) {} + // fun bar() { let e: Either = ...; e.foo() } + // extends fun foo(self: T); // extends fun foo(self: Either); // let x: Either; @@ -838,6 +852,7 @@ const getExprChecker = ( // fromCell: Struct.(Cell) -> struct assignTo(Cell(paramLoc), checkExpr(arg)); } + // Message.opcode() if (struct.kind === 'struct_decl' && struct.typeParams.length !== node.typeArgs.length) { err.typeArity(struct.name.text, node.typeArgs.length, 0)(node.loc); } @@ -852,7 +867,7 @@ const getExprChecker = ( }; const checkFunctionCall = (node: Ast.StaticCall): Ty.Type => { - // dump: checkDump, // (ref | void | null | map | Cell | Slice | Builder | Address | String | Bool | Int) -> void + // dump: checkDump, // (T) -> void // ton: checkTon, // (String) -> Int, строка должна быть конст // require: checkRequire, // (Bool, String) -> void @@ -860,7 +875,8 @@ const getExprChecker = ( // cell: checkCell, // (String) -> Cell // dumpStack: checkDumpStack, // () -> void // emptyMap: checkEmptyMap, // () -> Null - // sha256: checkSha256, // (String | Slice) -> Int + // sha256: checkSha256, // (String) -> Int + // sha256: checkSha256, // (Slice) -> Int // slice: checkSlice, // (String) -> Slice // rawSlice: checkRawSlice, // (String) -> Slice // ascii: checkAscii, // (String) -> Int @@ -884,8 +900,8 @@ const getExprChecker = ( switch (self.kind) { case "cons_type": { // struct - // toCell : struct.() -> Cell - // toSlice: struct.() -> Slice + // extends fun toCell(self: Struct): Cell + // extends fun toSlice(self: Struct): Slice // bounced<> не переносит методы @@ -894,15 +910,15 @@ const getExprChecker = ( return; } case "map_type": { - // set: map.(key: K, value: V) -> void - // get: map.(key: K) -> Maybe - // del: map.(key: K) -> Bool - // asCell: map.() -> Maybe - // isEmpty: map.() -> Bool - // exists: map.(key: K) -> Bool - // deepEquals: map.(other: map) -> Bool // mgu - // replace: map.(key: K, value: V) -> Bool - // replaceGet: map.(key: K, value: V) -> map + // extends fun set(self: map, key: K, value: V) -> void + // extends fun get(self: map, key: K) -> Maybe + // extends fun del(self: map, key: K) -> Bool + // extends fun asCell(self: map, ) -> Maybe + // extends fun isEmpty(self: map, ) -> Bool + // extends fun exists(self: map, key: K) -> Bool + // extends fun deepEquals(self: map, other: map) -> Bool // mgu + // extends fun replace(self: map, key: K, value: V) -> Bool + // extends fun replaceGet(self: map, key: K, value: V) -> map } case "ERROR": case "type_var": { diff --git a/src/next/test/_cli.build.ts b/src/next/test/_cli.build.ts new file mode 100644 index 0000000000..507d079706 --- /dev/null +++ b/src/next/test/_cli.build.ts @@ -0,0 +1,9 @@ +import { resolve } from "path"; +import { runTest } from "@/next/test/_test.build"; + +const main = async () => { + const path = resolve(process.argv[2] ?? ''); + console.log(await runTest(path)); +}; + +void main(); diff --git a/src/next/test/_run.test.ts b/src/next/test/_run.test.ts new file mode 100644 index 0000000000..f39344e6ff --- /dev/null +++ b/src/next/test/_run.test.ts @@ -0,0 +1,36 @@ +import fs from "fs"; +import { readFile, writeFile } from "fs/promises"; +import { basename, dirname, extname, join } from "path"; +import { runTest } from "@/next/test/_test.build"; + +const root = __dirname; + +const listCases = (): readonly string[] => { + return fs.readdirSync(root) + .filter(file => file.endsWith(".tact")) + .map(file => join(root, file)); +}; + +const readFileOpt = async (path: string): Promise => { + try { + return await readFile(path, 'utf8'); + } catch (err) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + if (err && (err as any).code === 'ENOENT') return undefined; + throw err; + } +}; + +it.each(listCases())("%s", async (path) => { + const newText = await runTest(path); + const snapPath = join(dirname(path), basename(path, extname(path)) + '.snap.js'); + const isUpdate = expect.getState().snapshotState._updateSnapshot === 'all'; + const oldText = await readFileOpt(snapPath); + if (isUpdate || typeof oldText === 'undefined') { + await writeFile(snapPath, newText, 'utf-8'); + expect(newText).toBe(newText); + } else { + expect(newText).toBe(oldText); + } +}); + diff --git a/src/next/test/_test.build.ts b/src/next/test/_test.build.ts new file mode 100644 index 0000000000..103d290a0a --- /dev/null +++ b/src/next/test/_test.build.ts @@ -0,0 +1,65 @@ +import { createMemoryFs, createProxyFs, fromString } from "@/next/fs"; +import { ProjectReader, readSource } from "@/next/imports/reader"; +import { toJs } from "@/next/test/to-code"; +import { typecheck } from "@/next/types/typecheck"; +import { runServer } from "@/server/run-server"; +import { basename, dirname } from "path"; +import type { Logger } from "@/error/logger-util"; +import type { ResolvedImport } from "@/next/imports/source"; + +export const runTest = async (path: string): Promise => { + let types: unknown; + const result = await runServer(async (log) => { + await log.recover(async (log) => { + const result = await buildNoStdlib(log, path); + + if (!result) { + return; + } + + const tcResult = typecheck(result); + types = tcResult.errors.length + ? { errors: tcResult.errors } + : { scope: tcResult.value }; + }); + }); + return toJs({ types, result }); +}; + +export const buildE2E = async ( + log: Logger, + path: string, +) => { + const reader = await ProjectReader(log); + if (!reader) { + return; + } + return await reader.read( + dirname(path), + basename(path), + ); +} + +export const buildNoStdlib = async ( + log: Logger, + path: string, +) => { + const project = createProxyFs({ + log, + root: dirname(path), + isReadonly: false, + }); + const implicits: ResolvedImport[] = []; + return await readSource({ + log, + project, + stdlib: createMemoryFs({ + log, + files: new Map(), + isReadonly: true, + root: fromString('.'), + }), + implicits, + root: basename(path), + }); +}; \ No newline at end of file diff --git a/src/next/test/fun-shadow-1.snap.js b/src/next/test/fun-shadow-1.snap.js new file mode 100644 index 0000000000..bd2ea137dc --- /dev/null +++ b/src/next/test/fun-shadow-1.snap.js @@ -0,0 +1,43 @@ +const x1 = { + kind: "range", + start: 32, + end: 44, +}; + +export default { + types: { + scope: { + functions: new Map([ + ["foo", { + value: { + kind: "function", + inline: false, + name: { + kind: "id", + text: "foo", + loc: { + kind: "range", + start: 36, + end: 39, + }, + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: "regular_body", + statements: [], + }, + loc: x1, + }, + via: { + kind: "user", + imports: [], + defLoc: x1, + }, + }], + ]), + }, + }, + result: [], +}; diff --git a/src/next/test/fun-shadow-1.tact b/src/next/test/fun-shadow-1.tact new file mode 100644 index 0000000000..e1c3ac1f1f --- /dev/null +++ b/src/next/test/fun-shadow-1.tact @@ -0,0 +1,3 @@ +// regular function definition + +fun foo() {} diff --git a/src/next/test/fun-shadow-2.snap.js b/src/next/test/fun-shadow-2.snap.js new file mode 100644 index 0000000000..1ef9a5432c --- /dev/null +++ b/src/next/test/fun-shadow-2.snap.js @@ -0,0 +1,41 @@ +export default { + types: { + errors: [ + { + loc: { + kind: "range", + start: 82, + end: 94, + }, + descr: [ + { + kind: "text", + text: "There already is a function \"foo\" from", + }, + { + kind: "via", + via: { + kind: "user", + imports: [ + { + kind: "tact", + loc: { + kind: "range", + start: 56, + end: 80, + }, + }, + ], + defLoc: { + kind: "range", + start: 32, + end: 44, + }, + }, + }, + ], + }, + ], + }, + result: [], +}; diff --git a/src/next/test/fun-shadow-2.tact b/src/next/test/fun-shadow-2.tact new file mode 100644 index 0000000000..cfd7a03be7 --- /dev/null +++ b/src/next/test/fun-shadow-2.tact @@ -0,0 +1,5 @@ +// Fails, because fun-shadow-1 already has foo defined + +import "./fun-shadow-1"; + +fun foo() {} diff --git a/src/next/test/fun-shadow-3.snap.js b/src/next/test/fun-shadow-3.snap.js new file mode 100644 index 0000000000..0c54538ba6 --- /dev/null +++ b/src/next/test/fun-shadow-3.snap.js @@ -0,0 +1,8 @@ +export default { + types: { + scope: { + functions: undefined, + }, + }, + result: [], +}; diff --git a/src/next/test/fun-shadow-3.tact b/src/next/test/fun-shadow-3.tact new file mode 100644 index 0000000000..bf14ace51b --- /dev/null +++ b/src/next/test/fun-shadow-3.tact @@ -0,0 +1,3 @@ +// reexporting the function from fun-shadow-1 + +import "./fun-shadow-1"; diff --git a/src/next/test/fun-shadow-4.snap.js b/src/next/test/fun-shadow-4.snap.js new file mode 100644 index 0000000000..0c54538ba6 --- /dev/null +++ b/src/next/test/fun-shadow-4.snap.js @@ -0,0 +1,8 @@ +export default { + types: { + scope: { + functions: undefined, + }, + }, + result: [], +}; diff --git a/src/next/test/fun-shadow-4.tact b/src/next/test/fun-shadow-4.tact new file mode 100644 index 0000000000..4dda7369f6 --- /dev/null +++ b/src/next/test/fun-shadow-4.tact @@ -0,0 +1,5 @@ +// fun-shadow-3 reexports the same functions +// as fun-shadow-1, and it should not clash + +import "./fun-shadow-1"; +import "./fun-shadow-3"; diff --git a/src/next/test/fun-shadow-5.snap.js b/src/next/test/fun-shadow-5.snap.js new file mode 100644 index 0000000000..ee6fb3d10e --- /dev/null +++ b/src/next/test/fun-shadow-5.snap.js @@ -0,0 +1,43 @@ +const x1 = { + kind: "range", + start: 136, + end: 148, +}; + +export default { + types: { + scope: { + functions: new Map([ + ["foo", { + value: { + kind: "function", + inline: false, + name: { + kind: "id", + text: "foo", + loc: { + kind: "range", + start: 140, + end: 143, + }, + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: "regular_body", + statements: [], + }, + loc: x1, + }, + via: { + kind: "user", + imports: [], + defLoc: x1, + }, + }], + ]), + }, + }, + result: [], +}; diff --git a/src/next/test/fun-shadow-5.tact b/src/next/test/fun-shadow-5.tact new file mode 100644 index 0000000000..46390d0c0b --- /dev/null +++ b/src/next/test/fun-shadow-5.tact @@ -0,0 +1,7 @@ +// fails: we're redefining a function from fun-shadow-1 +// must have only one error + +import "./fun-shadow-1"; +import "./fun-shadow-3"; + +fun foo() {} diff --git a/src/next/test/to-code.ts b/src/next/test/to-code.ts new file mode 100644 index 0000000000..1e8f16efe4 --- /dev/null +++ b/src/next/test/to-code.ts @@ -0,0 +1,137 @@ +function isValidId(key: string) { + return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(key); +} + +const pad = (s: readonly string[]) => s.map(s => " " + s); + +function concat(s: readonly string[], t: readonly string[]): readonly string[] { + const [last, ...init] = [...s].reverse(); + const [head, ...tail] = t; + if (typeof last === 'undefined') { + return t; + } else if (typeof head === 'undefined') { + return s; + } else { + return [...init.reverse(), last + head, ...tail]; + } +} + +function concatAll(s: readonly (readonly string[])[]): readonly string[] { + return s.reduce((acc, next) => concat(acc, next), []); +} + +const braced = (l: string, code: readonly string[], r: string) => { + const m = pad(code); + return m.length === 0 ? [l + r] : [l, ...m, r]; +}; + +export function toJs(value: unknown): string { + const counts: Map = new Map(); + const order: Map = new Map(); + let nextId = 0; + function countUsages(val: unknown) { + if (typeof val !== 'object' || val === null || val instanceof Date || val instanceof RegExp) { + return; + } + const newCount = counts.get(val); + if (!newCount) { + counts.set(val, 'exists'); + const items = + Array.isArray(val) ? val : + val instanceof Map ? val.entries().flatMap((kv) => kv) : + val instanceof Set ? [...val] : + Object.entries(val) + + for (const item of items) { + countUsages(item); + } + } else if (newCount === 'exists') { + const name = `x${++nextId}`; + counts.set(val, { name }); + } + } + + function show(val: unknown): readonly string[] { + const count = counts.get(val); + if (typeof count !== 'object') { + return showAny(val); + } + if (!order.has(count.name)) { + // set as being prepared + order.set(count.name, []); + const res = showAny(val); + order.set(count.name, res); + } + return [count.name]; + } + + function showAny(val: unknown): readonly string[] { + switch (typeof val) { + case "string": return [JSON.stringify(val)]; + case "number": return [String(val)]; + case "boolean": return [String(val)]; + case "bigint": return [val.toString() + 'n']; + case "symbol": return [val.description ? `Symbol(${JSON.stringify(val.description)})` : 'Symbol()']; + case "undefined": return ['undefined']; + case "object": return val === null ? ["null"] : showObject(val); + case "function": return [`new Function(${val.toString()})`]; + } + } + + const showObject = (val: object): readonly string[] => { + if (val instanceof Date) { + return [`new Date(${val.getTime()})`]; + } + if (val instanceof RegExp) { + return [val.toString()]; // sus + } + if (Array.isArray(val)) { + return braced( + '[', + val.flatMap((item) => { + return concat(show(item), [","]); + }), + ']', + ); + } + if (val instanceof Map) { + return braced( + 'new Map([', + [...val.entries()].flatMap(([k, v]) => { + return concatAll([["["], show(k), [", "], show(v), ["],"]]); + }), + '])', + ); + } + if (val instanceof Set) { + return braced( + 'new Set([', + [...val].flatMap((k) => { + return concat(show(k), [","]); + }), + '])', + ); + } + return braced( + '{', + Object.entries(val).flatMap(([k, v]) => { + const keyRep = isValidId(k) ? k : JSON.stringify(k); + return concatAll([[keyRep], [": "], show(v), [","]]); + }), + '}', + ); + }; + + countUsages(value); + const res = show(value); + + const code = [...order.entries()].flatMap(([varName, code]) => { + return concatAll([ + [`const ${varName} = `], + code, + [";"], + ]); + }).join('\n'); + + return `${code ? `${code}\n\n` : ''}export default ${res.join('\n')};\n`; +} diff --git a/src/next/types/typecheck.ts b/src/next/types/typecheck.ts new file mode 100644 index 0000000000..12696de74e --- /dev/null +++ b/src/next/types/typecheck.ts @@ -0,0 +1,261 @@ +import type { ResolvedImport, TactImport, TactSource } from "@/next/imports/source"; +import { memo } from "@/utils/tricks"; +import type * as Ast from "@/next/ast"; +import * as W from "@/next/types/writer"; +import * as V from "@/next/types/via"; +import { throwInternal } from "@/error/errors"; + +export const typecheck = (root: TactSource): WithLog => { + const errors: TcError[] = []; + const recur = (source: TactSource): Scope => { + const result = tcSource( + // leave only imports of .tact + onlyTactImports(source.imports) + .map(importedBy => ({ + globals: memoedRec(importedBy.source), + importedBy, + })), + source, + ); + // `recur` is called only once on every source + // this ensures errors from every source get counted + // only once + errors.push(...result.errors); + return result.value + }; + const memoedRec = memo(recur); + return { errors, value: memoedRec(root) }; +}; +const onlyTactImports = (imports: readonly ResolvedImport[]): readonly TactImport[] => { + // typescript narrowing doesn't properly apply to filter, + // so we need this helper + const result: TactImport[] = []; + for (const imp of imports) { + if (imp.kind === 'tact') { + result.push(imp); + } + } + return result; +}; + +type SourceCheckResult = { + // import that lead to reading this file + readonly importedBy: TactImport; + // scopes that were computed from this file + readonly globals: Scope; +} + +const tcSource = ( + // list of import+source pairs for every of file's imports + imported: readonly SourceCheckResult[], + // source for current file + currSource: TactSource, +): WithLog => { + // for each of the imports + const importGlobals = imported.map(({ globals, importedBy }) => { + // in each of its definitions + return updateVias(globals, (via) => { + // tell that it came from that import + return V.ViaImport(via, importedBy); + }); + }); + return W.flatMapLog( + // append local definitions to the end of the list + tcBody(currSource), + // reduce list of sets of definitions into single set + local => concatScopes([...importGlobals, local]) + ); +}; + +// convert source to a list of its definitions +const tcBody = (source: TactSource): WithLog => { + return W.flatMapLog( + // for every item, extract globals + W.traverseLog( + source.items, + item => scopeItem(item, source), + ), + // then concat them + concatScopes, + ); +}; + +type Stmt = (item: T, source: TactSource) => WithLog; + +const scopeItem: Stmt = (item, source) => { + switch (item.kind) { + case "function": + return scopeFunction(item, source); + case "constant": + return scopeConstant(item, source); + case "extension": + // cannot scope until we know types + return W.pureLog(emptyScope()); + case "struct_decl": + case "message_decl": + case "union_decl": + case "alias_decl": + case "contract": + case "trait": + return scopeType(item, source); + } +}; + +const scopeFunction: Stmt = (item, source) => { + return W.pureLog(defineFunction( + item.name.text, + item, + V.ViaOrigin(item.loc, source), + )); +}; + +const scopeConstant: Stmt = (item, source) => { + // TODO + return W.pureLog(emptyScope()); +}; + +const scopeType: Stmt = (item, source) => { + // TODO + return W.pureLog(emptyScope()); +}; + +// set of definitions (transitively) from a source file +type Scope = { + // global function definitions + functions: Functions; +} +const emptyScope = (): Scope => ({ + functions: emptyFunctions() +}); +// sequence multiple definition sets +const concatScopes = (globals: readonly Scope[]): WithLog => { + return W.reduceLog(globals, appendScopes, emptyScope()); +}; +// define global function +const defineFunction = (name: string, value: Ast.Function, via: V.ViaUser): Scope => { + return { + ...emptyScope(), + functions: pureFunctions(name, value, via), + }; +}; +// sequence two definition sets: define all the `right` after `left` +const appendScopes = (left: Scope, right: Scope): WithLog => { + return W.combineLog({ + functions: appendFunctions(left.functions, right.functions), + }); +}; +// update all the `via` fields with information about new import +const updateVias = (globals: Scope, cb: (via: V.ViaUser) => V.ViaUser): Scope => { + return { + functions: mapViaFunctions(globals.functions, cb), + }; +}; + + +const Fn = (xs: 1[], x: 1) => 1; +const TVar = (x: string) => 1 as const; +const String = 1; +const Void = 1; +const Int = 1; +const Bool = 1; +const Address = 1; +const Cell = 1; +const Null = 1; +const Slice = 1; + +const builtinFunctions = new Map([ + ["dump", Fn([TVar("T")], Void)], + ["ton", Fn([String], Int)], + ["require", Fn([Bool, String], Void)], + ["address", Fn([String], Address)], + ["cell", Fn([String], Cell)], + ["dumpStack", Fn([], Void)], + ["emptyMap", Fn([], Null)], + // ["sha256", Overload([ + // Fn([String], Int), + // Fn([Slice], Int), + // ])], + ["slice", Fn([String], Slice)], + ["rawSlice", Fn([String], Slice)], + ["ascii", Fn([String], Int)], + ["crc32", Fn([String], Int)], +]); +type Functions = undefined | ReadonlyMap; +const emptyFunctions = (): Functions => undefined; +const pureFunctions = (name: string, value: Ast.Function, via: V.ViaUser): Functions => { + // if (name === 'foo') debugger; + return new Map([[name, { value, via }]]); +}; +const mapViaFunctions = (fns: Functions, cb: (via: V.ViaUser) => V.ViaUser): Functions => { + if (!fns) return; + return new Map(fns.entries().map(([k, v]) => { + return [k, { value: v.value, via: cb(v.via) }]; + })); +}; +const appendFunctions = (prev: Functions, next: Functions): WithLog => { + // console.log({ prev, next }); + if (!prev || !next) return W.pureLog(next); + const value = new Map(prev.entries()); + const errors: TcError[] = []; + for (const [name, nextItem] of next) { + const prevItem = value.get(name); + if (builtinFunctions.has(name)) { + // defined in compiler + errors.push(ERedefineFn(name, V.ViaBuiltin(), nextItem.via)); + } else if (typeof prevItem === 'undefined') { + // not defined yet; define it now + value.set(name, nextItem); + } else if (prevItem.via.source !== nextItem.via.source) { + // already defined, and it's not a diamond-situation + errors.push(ERedefineFn(name, prevItem.via, nextItem.via)); + } + } + return { value, errors }; +}; + + +// typechecking errors +type WithLog = W.Writer; +export const ERedefineFn = (name: string, prev: V.Via, next: V.ViaUser): TcError => ({ + loc: viaToRange(next), + descr: [ + TEText(`There already is a function "${name}" from`), + TEVia(prev), + ], +}); + + +// error DSL +type TcError = { + // location where IDE should show this error + readonly loc: Ast.Range; + // text description + readonly descr: readonly TELine[]; +} +type TELine = TEText | TEVia; +type TEText = { + readonly kind: 'text'; + readonly text: string; +} +const TEText = (text: string): TEText => ({ kind: 'text', text }); +type TEVia = { + readonly kind: 'via'; + readonly via: V.Via; +} +const TEVia = (via: V.Via): TEVia => ({ kind: 'via', via }); +const viaToRange = ({ imports, defLoc: definedAt }: V.ViaUser): Ast.Range => { + const [head] = imports; + if (typeof head === 'undefined') { + return definedAt; + } + const { loc } = head; + if (loc.kind === 'range') { + return loc; + } + return throwInternal("Implicit import shadows something. Duplicates in stdlib?"); +}; diff --git a/src/next/types/via.ts b/src/next/types/via.ts new file mode 100644 index 0000000000..f54fe51783 --- /dev/null +++ b/src/next/types/via.ts @@ -0,0 +1,47 @@ +import type { TactImport, TactSource } from "@/next/imports/source"; +import { hideProperty } from "@/utils/tricks"; +import type * as Ast from "@/next/ast"; + +// provenance for definition: where did it come from +export type Via = ViaUser | ViaBuiltin + +// is defined in compiler, always was there +export type ViaBuiltin = { + readonly kind: 'builtin'; +} + +export const ViaBuiltin = (): ViaBuiltin => ({ kind: 'builtin' }); + +export type ViaUser = { + readonly kind: 'user'; + // which imports it came through + readonly imports: readonly TactImport[]; + // where in the code it was defined + readonly defLoc: Ast.Range; + // in which source + readonly source: TactSource; +} + +// when something was just defined +export const ViaOrigin = (defLoc: Ast.Range, source: TactSource): ViaUser => { + const result: ViaUser = { + kind: 'user', + imports: [], + defLoc, + source, + }; + hideProperty(result, 'source'); + return result; +}; + +// when it came through an import +export const ViaImport = (via: ViaUser, throughImport: TactImport): ViaUser => { + const result: ViaUser = { + kind: 'user', + imports: [throughImport, ...via.imports], + defLoc: via.defLoc, + source: via.source, + }; + hideProperty(result, 'source'); + return result; +}; \ No newline at end of file diff --git a/src/next/types/writer.ts b/src/next/types/writer.ts new file mode 100644 index 0000000000..6920ab7685 --- /dev/null +++ b/src/next/types/writer.ts @@ -0,0 +1,70 @@ +import { throwInternal } from "@/error/errors"; +import { entries } from "@/utils/tricks"; + +export type Writer = { + errors: C[]; + value: T; +} + +export const pureLog = (value: T): Writer => ({ + errors: [], + value, +}); + +export const makeLog = (value: T, errors: C[]): Writer => ({ value, errors }); + +export const mapLog = (x: Writer, f: (t: T) => U): Writer => { + return { + errors: x.errors, + value: f(x.value), + }; +}; + +export const flatMapLog = (x: Writer, f: (t: T) => Writer): Writer => { + const res = f(x.value); + return { + errors: [...x.errors, ...res.errors], + value: res.value, + }; +}; + +export const combineLog = (children: { [K in keyof O]: Writer }): Writer => { + const value = {} as O; + const errors: C[] = []; + for (const [k, v] of entries(children)) { + value[k] = v.value; + errors.push(...v.errors); + } + return { errors, value }; +}; + +export const traverseLog = (xs: readonly T[], cb: (t: T) => Writer): Writer => { + const value: U[] = []; + const errors: C[] = []; + for (const x of xs) { + const v = cb(x); + value.push(v.value); + errors.push(...v.errors); + } + return { errors, value }; +}; + +export const reduceLog = ( + xs: readonly T[], cb: (a: A, t: T) => Writer, init: A, +): Writer => { + let acc: Writer = pureLog(init); + for (const x of xs) { + acc = flatMapLog(acc, acc => cb(acc, x)); + } + return acc; +}; + +export const reduce1Log = ( + xs: readonly T[], cb: (a: T, t: T) => Writer, +): Writer => { + const [head, ...tail] = xs; + if (typeof head === 'undefined') { + return throwInternal("Reducing empty list"); + } + return reduceLog(tail, cb, head); +}; diff --git a/src/utils/tricks.ts b/src/utils/tricks.ts index 29ab566d6f..ea43b6d97c 100644 --- a/src/utils/tricks.ts +++ b/src/utils/tricks.ts @@ -169,4 +169,14 @@ export const includes = ( // we have to do this, otherwise, the next line will complain that `key` isn't `K` const keys1: readonly string[] = keys; return keys1.includes(key); -}; \ No newline at end of file +}; + +export const hideProperty = (o: T, k: K): T => { + Object.defineProperty(o, k, { + value: o[k], + writable: true, + configurable: true, + enumerable: false, + }); + return o; +}; diff --git a/yarn.lock b/yarn.lock index 666c690b0a..f4a71d4d6d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1483,6 +1483,11 @@ dependencies: undici-types "~6.20.0" +"@types/serialize-javascript@^5.0.4": + version "5.0.4" + resolved "https://npm.dev-internal.org/@types/serialize-javascript/-/serialize-javascript-5.0.4.tgz#7a7c32248e207a0d29afed88e5ee3e921999c73d" + integrity sha512-Z2R7UKFuNWCP8eoa2o9e5rkD3hmWxx/1L0CYz0k2BZzGh0PhEVMp9kfGiqEml/0IglwNERXZ2hwNzIrSz/KHTA== + "@types/stack-utils@^2.0.0": version "2.0.3" resolved "https://npm.dev-internal.org/@types/stack-utils/-/stack-utils-2.0.3.tgz#6209321eb2c1712a7e7466422b8cb1fc0d9dd5d8" @@ -4812,6 +4817,13 @@ rabin-wasm@^0.1.4: node-fetch "^2.6.1" readable-stream "^3.6.0" +randombytes@^2.1.0: + version "2.1.0" + resolved "https://npm.dev-internal.org/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + react-is@^18.0.0: version "18.3.1" resolved "https://npm.dev-internal.org/react-is/-/react-is-18.3.1.tgz#e83557dc12eae63a99e003a46388b1dcbb44db7e" @@ -4950,7 +4962,7 @@ safe-array-concat@^1.1.3: has-symbols "^1.1.0" isarray "^2.0.5" -safe-buffer@~5.2.0: +safe-buffer@^5.1.0, safe-buffer@~5.2.0: version "5.2.1" resolved "https://npm.dev-internal.org/safe-buffer/-/safe-buffer-5.2.1.tgz" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -4987,6 +4999,13 @@ semver@^7.5.3, semver@^7.5.4, semver@^7.6.0, semver@^7.6.3, semver@^7.7.1: resolved "https://npm.dev-internal.org/semver/-/semver-7.7.1.tgz#abd5098d82b18c6c81f6074ff2647fd3e7220c9f" integrity sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA== +serialize-javascript@^6.0.2: + version "6.0.2" + resolved "https://npm.dev-internal.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz#defa1e055c83bf6d59ea805d8da862254eb6a6c2" + integrity sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g== + dependencies: + randombytes "^2.1.0" + set-function-length@^1.2.2: version "1.2.2" resolved "https://npm.dev-internal.org/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" From 8607ec887b95e669e4a36d9d7fe86bccdc1dc1ff Mon Sep 17 00:00:00 2001 From: verytactical <186486509+verytactical@users.noreply.github.com> Date: Thu, 15 May 2025 19:46:52 +0400 Subject: [PATCH 20/38] debugging --- .vscode/launch.json | 6 +-- src/next/test/fun-shadow-3.snap.js | 46 ++++++++++++++++++++- src/next/test/fun-shadow-4.snap.js | 46 ++++++++++++++++++++- src/next/test/fun-shadow-5.snap.js | 66 +++++++++++++++--------------- src/next/types/typecheck.ts | 45 ++++++++++---------- src/next/types/writer.ts | 25 ++++------- src/utils/log-deep.build.ts | 9 ++++ 7 files changed, 165 insertions(+), 78 deletions(-) create mode 100644 src/utils/log-deep.build.ts diff --git a/.vscode/launch.json b/.vscode/launch.json index ebd943eb57..dfca9f8616 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -5,11 +5,11 @@ "name": "Run _cli.build.ts", "type": "node", "request": "launch", - "program": "${workspaceFolder}/src/next/test/_cli.build.ts", + "runtimeExecutable": "bash", "args": [ - "${file}" + "-lc", + "clear; ts-node ${workspaceFolder}/src/next/test/_cli.build.ts ${file}" ], - "runtimeExecutable": "ts-node", "cwd": "${workspaceFolder}", "console": "integratedTerminal", "internalConsoleOptions": "neverOpen" diff --git a/src/next/test/fun-shadow-3.snap.js b/src/next/test/fun-shadow-3.snap.js index 0c54538ba6..c0c5f152ff 100644 --- a/src/next/test/fun-shadow-3.snap.js +++ b/src/next/test/fun-shadow-3.snap.js @@ -1,7 +1,51 @@ +const x1 = { + kind: "range", + start: 32, + end: 44, +}; + export default { types: { scope: { - functions: undefined, + functions: new Map([ + ["foo", { + value: { + kind: "function", + inline: false, + name: { + kind: "id", + text: "foo", + loc: { + kind: "range", + start: 36, + end: 39, + }, + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: "regular_body", + statements: [], + }, + loc: x1, + }, + via: { + kind: "user", + imports: [ + { + kind: "tact", + loc: { + kind: "range", + start: 47, + end: 71, + }, + }, + ], + defLoc: x1, + }, + }], + ]), }, }, result: [], diff --git a/src/next/test/fun-shadow-4.snap.js b/src/next/test/fun-shadow-4.snap.js index 0c54538ba6..a76fab8e70 100644 --- a/src/next/test/fun-shadow-4.snap.js +++ b/src/next/test/fun-shadow-4.snap.js @@ -1,7 +1,51 @@ +const x1 = { + kind: "range", + start: 32, + end: 44, +}; + export default { types: { scope: { - functions: undefined, + functions: new Map([ + ["foo", { + value: { + kind: "function", + inline: false, + name: { + kind: "id", + text: "foo", + loc: { + kind: "range", + start: 36, + end: 39, + }, + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: "regular_body", + statements: [], + }, + loc: x1, + }, + via: { + kind: "user", + imports: [ + { + kind: "tact", + loc: { + kind: "range", + start: 90, + end: 114, + }, + }, + ], + defLoc: x1, + }, + }], + ]), }, }, result: [], diff --git a/src/next/test/fun-shadow-5.snap.js b/src/next/test/fun-shadow-5.snap.js index ee6fb3d10e..e62c55d34a 100644 --- a/src/next/test/fun-shadow-5.snap.js +++ b/src/next/test/fun-shadow-5.snap.js @@ -1,43 +1,41 @@ -const x1 = { - kind: "range", - start: 136, - end: 148, -}; - export default { types: { - scope: { - functions: new Map([ - ["foo", { - value: { - kind: "function", - inline: false, - name: { - kind: "id", - text: "foo", - loc: { + errors: [ + { + loc: { + kind: "range", + start: 136, + end: 148, + }, + descr: [ + { + kind: "text", + text: "There already is a function \"foo\" from", + }, + { + kind: "via", + via: { + kind: "user", + imports: [ + { + kind: "tact", + loc: { + kind: "range", + start: 85, + end: 109, + }, + }, + ], + defLoc: { kind: "range", - start: 140, - end: 143, + start: 32, + end: 44, }, }, - typeParams: [], - returnType: undefined, - params: [], - body: { - kind: "regular_body", - statements: [], - }, - loc: x1, - }, - via: { - kind: "user", - imports: [], - defLoc: x1, }, - }], - ]), - }, + ], + }, + ], }, result: [], }; diff --git a/src/next/types/typecheck.ts b/src/next/types/typecheck.ts index 12696de74e..96d71a9dd9 100644 --- a/src/next/types/typecheck.ts +++ b/src/next/types/typecheck.ts @@ -1,9 +1,11 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ import type { ResolvedImport, TactImport, TactSource } from "@/next/imports/source"; import { memo } from "@/utils/tricks"; import type * as Ast from "@/next/ast"; import * as W from "@/next/types/writer"; import * as V from "@/next/types/via"; import { throwInternal } from "@/error/errors"; +import { logDeep } from "@/utils/log-deep.build"; export const typecheck = (root: TactSource): WithLog => { const errors: TcError[] = []; @@ -24,7 +26,7 @@ export const typecheck = (root: TactSource): WithLog => { return result.value }; const memoedRec = memo(recur); - return { errors, value: memoedRec(root) }; + return W.makeLog(memoedRec(root), errors); }; const onlyTactImports = (imports: readonly ResolvedImport[]): readonly TactImport[] => { // typescript narrowing doesn't properly apply to filter, @@ -61,22 +63,18 @@ const tcSource = ( }); return W.flatMapLog( // append local definitions to the end of the list - tcBody(currSource), - // reduce list of sets of definitions into single set - local => concatScopes([...importGlobals, local]) - ); -}; - -// convert source to a list of its definitions -const tcBody = (source: TactSource): WithLog => { - return W.flatMapLog( - // for every item, extract globals W.traverseLog( - source.items, - item => scopeItem(item, source), + currSource.items, + item => scopeItem(item, currSource), ), - // then concat them - concatScopes, + // reduce list of sets of definitions into single set + local => { + const allScopes = [...importGlobals, ...local]; + // if (currSource.path.includes("5")) { + // logDeep(allScopes); + // } + return concatScopes(allScopes); + } ); }; @@ -198,24 +196,27 @@ const mapViaFunctions = (fns: Functions, cb: (via: V.ViaUser) => V.ViaUser): Fun })); }; const appendFunctions = (prev: Functions, next: Functions): WithLog => { - // console.log({ prev, next }); if (!prev || !next) return W.pureLog(next); const value = new Map(prev.entries()); const errors: TcError[] = []; for (const [name, nextItem] of next) { const prevItem = value.get(name); + // defined in compiler if (builtinFunctions.has(name)) { - // defined in compiler errors.push(ERedefineFn(name, V.ViaBuiltin(), nextItem.via)); - } else if (typeof prevItem === 'undefined') { - // not defined yet; define it now + continue; + } + // not defined yet; define it now + if (typeof prevItem === 'undefined') { value.set(name, nextItem); - } else if (prevItem.via.source !== nextItem.via.source) { - // already defined, and it's not a diamond-situation + continue; + } + // already defined, and it's not a diamond situation + if (prevItem.via.source !== nextItem.via.source) { errors.push(ERedefineFn(name, prevItem.via, nextItem.via)); } } - return { value, errors }; + return W.makeLog(value, errors); }; diff --git a/src/next/types/writer.ts b/src/next/types/writer.ts index 6920ab7685..3791a553c7 100644 --- a/src/next/types/writer.ts +++ b/src/next/types/writer.ts @@ -2,30 +2,21 @@ import { throwInternal } from "@/error/errors"; import { entries } from "@/utils/tricks"; export type Writer = { - errors: C[]; - value: T; + readonly errors: C[]; + readonly value: T; } -export const pureLog = (value: T): Writer => ({ - errors: [], - value, -}); +export const makeLog = (value: T, errors: C[]): Writer => ({ errors, value }); -export const makeLog = (value: T, errors: C[]): Writer => ({ value, errors }); +export const pureLog = (value: T): Writer => makeLog(value, []); export const mapLog = (x: Writer, f: (t: T) => U): Writer => { - return { - errors: x.errors, - value: f(x.value), - }; + return makeLog(f(x.value), x.errors); }; export const flatMapLog = (x: Writer, f: (t: T) => Writer): Writer => { const res = f(x.value); - return { - errors: [...x.errors, ...res.errors], - value: res.value, - }; + return makeLog(res.value, [...x.errors, ...res.errors]); }; export const combineLog = (children: { [K in keyof O]: Writer }): Writer => { @@ -35,7 +26,7 @@ export const combineLog = (children: { [K in keyof O]: Writer }): value[k] = v.value; errors.push(...v.errors); } - return { errors, value }; + return makeLog(value, errors); }; export const traverseLog = (xs: readonly T[], cb: (t: T) => Writer): Writer => { @@ -46,7 +37,7 @@ export const traverseLog = (xs: readonly T[], cb: (t: T) => Writer( diff --git a/src/utils/log-deep.build.ts b/src/utils/log-deep.build.ts new file mode 100644 index 0000000000..1b2fd9900b --- /dev/null +++ b/src/utils/log-deep.build.ts @@ -0,0 +1,9 @@ +import { inspect } from "util"; + +// log json to terminal without shortening +export const logDeep = (obj: unknown, colors = true) => { + console.log(inspect(obj, { + colors, + depth: Infinity, + })); +}; From 9dd7523a5e7eb5ebb254755e751aa760901f3b7b Mon Sep 17 00:00:00 2001 From: verytactical <186486509+verytactical@users.noreply.github.com> Date: Thu, 15 May 2025 20:31:26 +0400 Subject: [PATCH 21/38] 1 --- src/next/test/_test.build.ts | 3 +- src/next/types/error-dsl.ts | 38 +++++++ src/next/types/errors.ts | 15 +++ src/next/types/functions.ts | 87 ++++++++++++++++ src/next/types/registry.ts | 9 ++ src/next/types/type-decls.ts | 72 +++++++++++++ src/next/types/typecheck.ts | 192 ++++++++++------------------------- 7 files changed, 277 insertions(+), 139 deletions(-) create mode 100644 src/next/types/error-dsl.ts create mode 100644 src/next/types/errors.ts create mode 100644 src/next/types/functions.ts create mode 100644 src/next/types/registry.ts create mode 100644 src/next/types/type-decls.ts diff --git a/src/next/test/_test.build.ts b/src/next/test/_test.build.ts index 103d290a0a..0b7714856d 100644 --- a/src/next/test/_test.build.ts +++ b/src/next/test/_test.build.ts @@ -11,7 +11,8 @@ export const runTest = async (path: string): Promise => { let types: unknown; const result = await runServer(async (log) => { await log.recover(async (log) => { - const result = await buildNoStdlib(log, path); + // const result = await buildNoStdlib(log, path); + const result = await buildE2E(log, path); if (!result) { return; diff --git a/src/next/types/error-dsl.ts b/src/next/types/error-dsl.ts new file mode 100644 index 0000000000..547b80033b --- /dev/null +++ b/src/next/types/error-dsl.ts @@ -0,0 +1,38 @@ +import { throwInternal } from "@/error/errors"; +import type { Range } from "@/next/ast"; +import type * as V from "@/next/types/via"; + +export type TcError = { + // location where IDE should show this error + readonly loc: Range; + // text description + readonly descr: readonly TELine[]; +} + +export type TELine = TEText | TEVia; + +export type TEText = { + readonly kind: 'text'; + readonly text: string; +} + +export const TEText = (text: string): TEText => ({ kind: 'text', text }); + +export type TEVia = { + readonly kind: 'via'; + readonly via: V.Via; +} + +export const TEVia = (via: V.Via): TEVia => ({ kind: 'via', via }); + +export const viaToRange = ({ imports, defLoc: definedAt }: V.ViaUser): Range => { + const [head] = imports; + if (typeof head === 'undefined') { + return definedAt; + } + const { loc } = head; + if (loc.kind === 'range') { + return loc; + } + return throwInternal("Implicit import shadows something. Duplicates in stdlib?"); +}; diff --git a/src/next/types/errors.ts b/src/next/types/errors.ts new file mode 100644 index 0000000000..99e2692cd2 --- /dev/null +++ b/src/next/types/errors.ts @@ -0,0 +1,15 @@ +import * as E from "@/next/types/error-dsl"; +import type * as W from "@/next/types/writer"; +import type * as V from "@/next/types/via"; + +export * from "@/next/types/error-dsl"; + +export type WithLog = W.Writer; + +export const ERedefineFn = (name: string, prev: V.Via, next: V.ViaUser): E.TcError => ({ + loc: E.viaToRange(next), + descr: [ + E.TEText(`There already is a function "${name}" from`), + E.TEVia(prev), + ], +}); \ No newline at end of file diff --git a/src/next/types/functions.ts b/src/next/types/functions.ts new file mode 100644 index 0000000000..fbfbada0eb --- /dev/null +++ b/src/next/types/functions.ts @@ -0,0 +1,87 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import * as W from "@/next/types/writer"; +import * as V from "@/next/types/via"; +import * as E from "@/next/types/errors"; +import type * as Ast from "@/next/ast"; +import type { Registry } from "@/next/types/registry"; + +// FIXME +const Fn = (xs: 1[], x: 1) => 1; +const TVar = (x: string) => 1 as const; +const String = 1; +const Void = 1; +const Int = 1; +const Bool = 1; +const Address = 1; +const Cell = 1; +const Null = 1; +const Slice = 1; + +const builtins = new Map([ + ["dump", Fn([TVar("T")], Void)], + ["ton", Fn([String], Int)], + ["require", Fn([Bool, String], Void)], + ["address", Fn([String], Address)], + ["cell", Fn([String], Cell)], + ["dumpStack", Fn([], Void)], + ["emptyMap", Fn([], Null)], + // ["sha256", Overload([ + // Fn([String], Int), + // Fn([Slice], Int), + // ])], + ["slice", Fn([String], Slice)], + ["rawSlice", Fn([String], Slice)], + ["ascii", Fn([String], Int)], + ["crc32", Fn([String], Int)], +]); + +export type Functions = undefined | ReadonlyMap; + +const empty = (): Functions => undefined; + +const create = (name: string, value: Ast.Function, via: V.ViaUser): Functions => { + return new Map([[name, { value, via }]]); +}; + +const mapVia = (fns: Functions, cb: (via: V.ViaUser) => V.ViaUser): Functions => { + if (!fns) return; + return new Map(fns.entries().map(([k, v]) => { + return [k, { value: v.value, via: cb(v.via) }]; + })); +}; + +const append = (prev: Functions, next: Functions): E.WithLog => { + if (!prev || !next) return W.pureLog(next); + const value = new Map(prev.entries()); + const errors: E.TcError[] = []; + for (const [name, nextItem] of next) { + const prevItem = value.get(name); + // defined in compiler + if (builtins.has(name)) { + errors.push(E.ERedefineFn(name, V.ViaBuiltin(), nextItem.via)); + continue; + } + // not defined yet; define it now + if (typeof prevItem === 'undefined') { + value.set(name, nextItem); + continue; + } + // already defined, and it's not a diamond situation + if (prevItem.via.source !== nextItem.via.source) { + errors.push(E.ERedefineFn(name, prevItem.via, nextItem.via)); + } + } + return W.makeLog(value, errors); +}; + +export const Functions: Registry = { + empty, + create, + mapVia, + append, +}; \ No newline at end of file diff --git a/src/next/types/registry.ts b/src/next/types/registry.ts new file mode 100644 index 0000000000..c5e1dd61e7 --- /dev/null +++ b/src/next/types/registry.ts @@ -0,0 +1,9 @@ +import type * as V from "@/next/types/via"; +import type * as E from "@/next/types/errors"; + +export interface Registry { + empty(): Reg; + create(key: Key, value: Val, via: V.ViaUser): Reg; + mapVia(fns: Reg, cb: (via: V.ViaUser) => V.ViaUser): Reg; + append(prev: Reg, next: Reg): E.WithLog; +} diff --git a/src/next/types/type-decls.ts b/src/next/types/type-decls.ts new file mode 100644 index 0000000000..327e71cab0 --- /dev/null +++ b/src/next/types/type-decls.ts @@ -0,0 +1,72 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import * as W from "@/next/types/writer"; +import * as V from "@/next/types/via"; +import * as E from "@/next/types/errors"; +import type * as Ast from "@/next/ast"; +import type { Registry } from "@/next/types/registry"; + +const builtins = new Map([ + ["void", 1], + ["bounced", 1], + ["Null", 1], + ["Maybe", 1], + ["Int", 1], + ["Bool", 1], + ["Builder", 1], + ["Slice", 1], + ["Cell", 1], + ["Address", 1], + ["String", 1], + ["StringBuilder", 1], +]); + +export type TypeDecls = undefined | ReadonlyMap; + +const empty = (): TypeDecls => undefined; + +const create = (name: string, value: Ast.TypeDecl, via: V.ViaUser): TypeDecls => { + return new Map([[name, { value, via }]]); +}; + +const mapVia = (fns: TypeDecls, cb: (via: V.ViaUser) => V.ViaUser): TypeDecls => { + if (!fns) return; + return new Map(fns.entries().map(([k, v]) => { + return [k, { value: v.value, via: cb(v.via) }]; + })); +}; + +const append = (prev: TypeDecls, next: TypeDecls): E.WithLog => { + if (!prev || !next) return W.pureLog(next); + const value = new Map(prev.entries()); + const errors: E.TcError[] = []; + for (const [name, nextItem] of next) { + const prevItem = value.get(name); + // defined in compiler + if (builtins.has(name)) { + errors.push(E.ERedefineFn(name, V.ViaBuiltin(), nextItem.via)); + continue; + } + // not defined yet; define it now + if (typeof prevItem === 'undefined') { + value.set(name, nextItem); + continue; + } + // already defined, and it's not a diamond situation + if (prevItem.via.source !== nextItem.via.source) { + errors.push(E.ERedefineFn(name, prevItem.via, nextItem.via)); + } + } + return W.makeLog(value, errors); +}; + +export const TypeDecls: Registry = { + empty, + create, + mapVia, + append, +}; \ No newline at end of file diff --git a/src/next/types/typecheck.ts b/src/next/types/typecheck.ts index 96d71a9dd9..0c245ee2a9 100644 --- a/src/next/types/typecheck.ts +++ b/src/next/types/typecheck.ts @@ -4,11 +4,14 @@ import { memo } from "@/utils/tricks"; import type * as Ast from "@/next/ast"; import * as W from "@/next/types/writer"; import * as V from "@/next/types/via"; +import type * as E from "@/next/types/errors"; import { throwInternal } from "@/error/errors"; import { logDeep } from "@/utils/log-deep.build"; +import { Functions } from "@/next/types/functions"; +import { TypeDecls } from "@/next/types/type-decls"; -export const typecheck = (root: TactSource): WithLog => { - const errors: TcError[] = []; +export const typecheck = (root: TactSource): E.WithLog => { + const errors: E.TcError[] = []; const recur = (source: TactSource): Scope => { const result = tcSource( // leave only imports of .tact @@ -51,8 +54,8 @@ const tcSource = ( // list of import+source pairs for every of file's imports imported: readonly SourceCheckResult[], // source for current file - currSource: TactSource, -): WithLog => { + source: TactSource, +): E.WithLog => { // for each of the imports const importGlobals = imported.map(({ globals, importedBy }) => { // in each of its definitions @@ -61,24 +64,28 @@ const tcSource = ( return V.ViaImport(via, importedBy); }); }); - return W.flatMapLog( - // append local definitions to the end of the list + + // get local definitions + const locals = W.flatMapLog( W.traverseLog( - currSource.items, - item => scopeItem(item, currSource), + source.items, + item => scopeItem(item, source), ), - // reduce list of sets of definitions into single set - local => { - const allScopes = [...importGlobals, ...local]; - // if (currSource.path.includes("5")) { - // logDeep(allScopes); - // } - return concatScopes(allScopes); - } + concatScopes, + ); + + // reduce list of sets of definitions into single set + const all = W.flatMapLog( + locals, + locals => concatScopes([...importGlobals, locals]), ); + + const typeErr = W.flatMapLog(all, checkTypes); + + return typeErr; }; -type Stmt = (item: T, source: TactSource) => WithLog; +type Stmt = (item: T, source: TactSource) => E.WithLog; const scopeItem: Stmt = (item, source) => { switch (item.kind) { @@ -113,150 +120,59 @@ const scopeConstant: Stmt = (item, source) => { }; const scopeType: Stmt = (item, source) => { - // TODO - return W.pureLog(emptyScope()); + return W.pureLog(defineType( + item.name.text, + item, + V.ViaOrigin(item.loc, source), + )); }; // set of definitions (transitively) from a source file type Scope = { // global function definitions - functions: Functions; + readonly functions: Functions; + // global type definitons + readonly types: TypeDecls; } + const emptyScope = (): Scope => ({ - functions: emptyFunctions() + functions: Functions.empty(), + types: TypeDecls.empty(), }); + // sequence multiple definition sets -const concatScopes = (globals: readonly Scope[]): WithLog => { +const concatScopes = (globals: readonly Scope[]): E.WithLog => { return W.reduceLog(globals, appendScopes, emptyScope()); }; + // define global function const defineFunction = (name: string, value: Ast.Function, via: V.ViaUser): Scope => { return { ...emptyScope(), - functions: pureFunctions(name, value, via), + functions: Functions.create(name, value, via), }; }; + +// define type +const defineType = (name: string, value: Ast.TypeDecl, via: V.ViaUser): Scope => { + return { + ...emptyScope(), + types: TypeDecls.create(name, value, via), + }; +}; + // sequence two definition sets: define all the `right` after `left` -const appendScopes = (left: Scope, right: Scope): WithLog => { +const appendScopes = (left: Scope, right: Scope): E.WithLog => { return W.combineLog({ - functions: appendFunctions(left.functions, right.functions), + functions: Functions.append(left.functions, right.functions), + types: TypeDecls.append(left.types, right.types), }); }; + // update all the `via` fields with information about new import const updateVias = (globals: Scope, cb: (via: V.ViaUser) => V.ViaUser): Scope => { return { - functions: mapViaFunctions(globals.functions, cb), + functions: Functions.mapVia(globals.functions, cb), + types: TypeDecls.mapVia(globals.types, cb), }; }; - - -const Fn = (xs: 1[], x: 1) => 1; -const TVar = (x: string) => 1 as const; -const String = 1; -const Void = 1; -const Int = 1; -const Bool = 1; -const Address = 1; -const Cell = 1; -const Null = 1; -const Slice = 1; - -const builtinFunctions = new Map([ - ["dump", Fn([TVar("T")], Void)], - ["ton", Fn([String], Int)], - ["require", Fn([Bool, String], Void)], - ["address", Fn([String], Address)], - ["cell", Fn([String], Cell)], - ["dumpStack", Fn([], Void)], - ["emptyMap", Fn([], Null)], - // ["sha256", Overload([ - // Fn([String], Int), - // Fn([Slice], Int), - // ])], - ["slice", Fn([String], Slice)], - ["rawSlice", Fn([String], Slice)], - ["ascii", Fn([String], Int)], - ["crc32", Fn([String], Int)], -]); -type Functions = undefined | ReadonlyMap; -const emptyFunctions = (): Functions => undefined; -const pureFunctions = (name: string, value: Ast.Function, via: V.ViaUser): Functions => { - // if (name === 'foo') debugger; - return new Map([[name, { value, via }]]); -}; -const mapViaFunctions = (fns: Functions, cb: (via: V.ViaUser) => V.ViaUser): Functions => { - if (!fns) return; - return new Map(fns.entries().map(([k, v]) => { - return [k, { value: v.value, via: cb(v.via) }]; - })); -}; -const appendFunctions = (prev: Functions, next: Functions): WithLog => { - if (!prev || !next) return W.pureLog(next); - const value = new Map(prev.entries()); - const errors: TcError[] = []; - for (const [name, nextItem] of next) { - const prevItem = value.get(name); - // defined in compiler - if (builtinFunctions.has(name)) { - errors.push(ERedefineFn(name, V.ViaBuiltin(), nextItem.via)); - continue; - } - // not defined yet; define it now - if (typeof prevItem === 'undefined') { - value.set(name, nextItem); - continue; - } - // already defined, and it's not a diamond situation - if (prevItem.via.source !== nextItem.via.source) { - errors.push(ERedefineFn(name, prevItem.via, nextItem.via)); - } - } - return W.makeLog(value, errors); -}; - - -// typechecking errors -type WithLog = W.Writer; -export const ERedefineFn = (name: string, prev: V.Via, next: V.ViaUser): TcError => ({ - loc: viaToRange(next), - descr: [ - TEText(`There already is a function "${name}" from`), - TEVia(prev), - ], -}); - - -// error DSL -type TcError = { - // location where IDE should show this error - readonly loc: Ast.Range; - // text description - readonly descr: readonly TELine[]; -} -type TELine = TEText | TEVia; -type TEText = { - readonly kind: 'text'; - readonly text: string; -} -const TEText = (text: string): TEText => ({ kind: 'text', text }); -type TEVia = { - readonly kind: 'via'; - readonly via: V.Via; -} -const TEVia = (via: V.Via): TEVia => ({ kind: 'via', via }); -const viaToRange = ({ imports, defLoc: definedAt }: V.ViaUser): Ast.Range => { - const [head] = imports; - if (typeof head === 'undefined') { - return definedAt; - } - const { loc } = head; - if (loc.kind === 'range') { - return loc; - } - return throwInternal("Implicit import shadows something. Duplicates in stdlib?"); -}; From bc3860f837655881ff8c8d2baeeb13945d32e7df Mon Sep 17 00:00:00 2001 From: verytactical <186486509+verytactical@users.noreply.github.com> Date: Mon, 26 May 2025 03:28:10 +0400 Subject: [PATCH 22/38] 1 --- spell/cspell-list.txt | 3 + src/next/ast/common.ts | 16 +- src/next/ast/dtype.ts | 86 ++ src/next/ast/expression.ts | 44 +- src/next/ast/generated/common.ts | 18 +- src/next/ast/generated/dtype.ts | 64 ++ src/next/ast/generated/expression.ts | 42 +- src/next/ast/generated/mtype.ts | 122 +++ src/next/ast/generated/root.ts | 123 +-- src/next/ast/generated/statement.ts | 26 +- src/next/ast/generated/type.ts | 98 ++- src/next/ast/generated/vtype.ts | 74 ++ src/next/ast/index.ts | 3 + src/next/ast/mtype.ts | 137 +++ src/next/ast/root.ts | 88 +- src/next/ast/statement.ts | 28 +- src/next/ast/type.ts | 101 ++- src/next/ast/vtype.ts | 85 ++ src/next/grammar/errors.ts | 10 + src/next/grammar/import-parser.ts | 12 +- src/next/grammar/index.ts | 255 ++++-- src/next/imports/reader.ts | 8 +- src/next/imports/source.ts | 8 +- src/next/scoping/errors.ts | 6 +- src/next/scoping/type.ts | 4 +- src/next/scoping/typecheck.ts | 729 +++++++++------- src/next/types/builtins.ts | 180 ++++ src/next/types/error-dsl.ts | 38 - src/next/types/errors.ts | 66 +- src/next/types/flat.ts | 124 +++ src/next/types/functions.ts | 87 -- src/next/types/registry.ts | 9 - src/next/types/type-decls.ts | 72 -- src/next/types/typecheck.ts | 1206 +++++++++++++++++++++++--- src/next/types/via.ts | 6 +- src/next/types/writer.ts | 61 -- 36 files changed, 3008 insertions(+), 1031 deletions(-) create mode 100644 src/next/ast/dtype.ts create mode 100644 src/next/ast/generated/dtype.ts create mode 100644 src/next/ast/generated/mtype.ts create mode 100644 src/next/ast/generated/vtype.ts create mode 100644 src/next/ast/mtype.ts create mode 100644 src/next/ast/vtype.ts create mode 100644 src/next/types/builtins.ts delete mode 100644 src/next/types/error-dsl.ts create mode 100644 src/next/types/flat.ts delete mode 100644 src/next/types/functions.ts delete mode 100644 src/next/types/registry.ts delete mode 100644 src/next/types/type-decls.ts delete mode 100644 src/next/types/writer.ts diff --git a/spell/cspell-list.txt b/spell/cspell-list.txt index cc331c2a8a..3f1f0f3b19 100644 --- a/spell/cspell-list.txt +++ b/spell/cspell-list.txt @@ -120,12 +120,14 @@ mintable misparse misparsed mktemp +Monoid multiformats nanoton nanotons Nemo Neovim nextra +nexts nobounce nocheck noexcept @@ -144,6 +146,7 @@ pinst POSIX postpack prando +prevs quadtree quadtrees RANDU diff --git a/src/next/ast/common.ts b/src/next/ast/common.ts index 391d829ef9..5fd8dbb8f6 100644 --- a/src/next/ast/common.ts +++ b/src/next/ast/common.ts @@ -1,34 +1,40 @@ +export type Loc = Range | Builtin; + +export type Builtin = { + readonly kind: "builtin"; +}; + export type Range = { readonly kind: "range"; readonly start: number; readonly end: number; readonly path: string; readonly code: string; -}; +} export type OptionalId = Id | Wildcard; export type Id = { readonly kind: "id"; readonly text: string; - readonly loc: Range; + readonly loc: Loc; }; export type Wildcard = { readonly kind: "wildcard"; - readonly loc: Range; + readonly loc: Loc; }; export type FuncId = { readonly kind: "func_id"; readonly text: string; - readonly loc: Range; + readonly loc: Loc; }; export type TypeId = { readonly kind: "type_id"; readonly text: string; - readonly loc: Range; + readonly loc: Loc; }; export type Language = "func" | "tact"; diff --git a/src/next/ast/dtype.ts b/src/next/ast/dtype.ts new file mode 100644 index 0000000000..7644d695fd --- /dev/null +++ b/src/next/ast/dtype.ts @@ -0,0 +1,86 @@ +import type { Loc, TypeId } from "@/next/ast/common"; +import type * as Ast from "@/next/ast/type"; + +export type DecodedType = + | DTypeRef + | DTypeAliasRef + | DTypeParamRef + | DTypeMap + | DTypeBounced + | DTypeMaybe + | DTypeTuple + | DTypeTensor + | DTypeInt + | DTypeSlice + | DTypeCell + | DTypeBuilder + | DTypeUnit + | DTypeVoid + | DTypeNull + | DTypeBool + | DTypeAddress + | DTypeString + | DTypeStringBuilder; + +export type DTypeInt = Ast.TypeInt +export type DTypeSlice = Ast.TypeSlice +export type DTypeCell = Ast.TypeCell +export type DTypeBuilder = Ast.TypeBuilder +export type DTypeUnit = Ast.TypeUnit +export type DTypeVoid = Ast.TypeVoid +export type DTypeNull = Ast.TypeNull +export type DTypeBool = Ast.TypeBool +export type DTypeAddress = Ast.TypeAddress +export type DTypeString = Ast.TypeString +export type DTypeStringBuilder = Ast.TypeStringBuilder + +export type DTypeRef = { + readonly kind: "type_ref"; + readonly name: TypeId; + readonly typeArgs: readonly DecodedType[]; + readonly loc: Loc; +}; + +export type DTypeAliasRef = { + readonly kind: "TypeAlias" + readonly name: TypeId; + readonly typeArgs: readonly DecodedType[]; + readonly loc: Loc; +} + +export type DTypeParamRef = { + readonly kind: "TypeParam" + readonly name: TypeId; + readonly loc: Loc; +} + +export type DTypeBounced = { + readonly kind: "TypeBounced" + readonly type: DecodedType; + readonly loc: Loc; +} + +export type DTypeMaybe = { + readonly kind: "TypeMaybe" + readonly type: DecodedType; + readonly loc: Loc; +} + +export type DTypeMap = { + readonly kind: "map_type"; + readonly key: DecodedType; + readonly value: DecodedType; + readonly loc: Loc; +}; + +export type DTypeTuple = { + readonly kind: "tuple_type"; + readonly typeArgs: readonly DecodedType[]; + readonly loc: Loc; +}; + +export type DTypeTensor = { + readonly kind: "tensor_type"; + readonly typeArgs: readonly DecodedType[]; + readonly loc: Loc; +}; diff --git a/src/next/ast/expression.ts b/src/next/ast/expression.ts index 189eba7396..2eb0ff0b9e 100644 --- a/src/next/ast/expression.ts +++ b/src/next/ast/expression.ts @@ -1,4 +1,4 @@ -import type { Id, Range, TypeId } from "@/next/ast/common"; +import type { Id, Loc, TypeId } from "@/next/ast/common"; import type { Type, TypeMap } from "@/next/ast/type"; export type Expression = @@ -26,14 +26,14 @@ export type Expression = export type Var = { readonly kind: "var"; readonly name: string; - readonly loc: Range; + readonly loc: Loc; }; export type Number = { readonly kind: "number"; readonly base: NumberBase; readonly value: bigint; - readonly loc: Range; + readonly loc: Loc; }; export type NumberBase = "2" | "8" | "10" | "16"; @@ -41,14 +41,14 @@ export type NumberBase = "2" | "8" | "10" | "16"; export type Boolean = { readonly kind: "boolean"; readonly value: boolean; - readonly loc: Range; + readonly loc: Loc; }; // A String is a string in which escaping characters, like '\\' has been simplified, e.g., '\\' simplified to '\'. export type String = { readonly kind: "string"; readonly value: string; - readonly loc: Range; + readonly loc: Loc; }; // `null` value is an inhabitant of several types: @@ -56,7 +56,7 @@ export type String = { // or empty map of any key and value types export type Null = { readonly kind: "null"; - readonly loc: Range; + readonly loc: Loc; }; export type BinaryOperation = @@ -84,7 +84,7 @@ export type OpBinary = { readonly op: BinaryOperation; readonly left: Expression; readonly right: Expression; - readonly loc: Range; + readonly loc: Loc; }; export type UnaryOperation = "+" | "-" | "!" | "!!" | "~"; @@ -93,14 +93,14 @@ export type OpUnary = { readonly kind: "op_unary"; readonly op: UnaryOperation; readonly operand: Expression; - readonly loc: Range; + readonly loc: Loc; }; export type FieldAccess = { readonly kind: "field_access"; readonly aggregate: Expression; // contract, trait, struct, message readonly field: Id; - readonly loc: Range; + readonly loc: Loc; }; export type MethodCall = { @@ -109,7 +109,7 @@ export type MethodCall = { readonly method: Id; readonly typeArgs: readonly Type[]; readonly args: readonly Expression[]; - readonly loc: Range; + readonly loc: Loc; }; // builtins or top-level (module) functions @@ -118,7 +118,7 @@ export type StaticCall = { readonly function: Id; readonly typeArgs: readonly Type[]; readonly args: readonly Expression[]; - readonly loc: Range; + readonly loc: Loc; }; export type StaticMethodCall = { @@ -127,7 +127,7 @@ export type StaticMethodCall = { readonly typeArgs: readonly Type[]; readonly function: Id; readonly args: readonly Expression[]; - readonly loc: Range; + readonly loc: Loc; }; export type StructInstance = { @@ -135,21 +135,21 @@ export type StructInstance = { readonly type: TypeId; readonly typeArgs: readonly Type[]; readonly args: readonly StructFieldInitializer[]; - readonly loc: Range; + readonly loc: Loc; }; export type StructFieldInitializer = { readonly kind: "struct_field_initializer"; readonly field: Id; readonly initializer: Expression; - readonly loc: Range; + readonly loc: Loc; }; export type MapLiteral = { readonly kind: "map_literal"; readonly type: TypeMap; readonly fields: readonly MapField[]; - readonly loc: Range; + readonly loc: Loc; }; export type MapField = { @@ -161,20 +161,20 @@ export type SetLiteral = { readonly kind: "set_literal"; readonly valueType: Type; readonly fields: readonly Expression[]; - readonly loc: Range; + readonly loc: Loc; }; export type InitOf = { readonly kind: "init_of"; readonly contract: TypeId; readonly args: readonly Expression[]; - readonly loc: Range; + readonly loc: Loc; }; export type CodeOf = { readonly kind: "code_of"; readonly contract: TypeId; - readonly loc: Range; + readonly loc: Loc; }; export type Conditional = { @@ -182,22 +182,22 @@ export type Conditional = { readonly condition: Expression; readonly thenBranch: Expression; readonly elseBranch: Expression; - readonly loc: Range; + readonly loc: Loc; }; export type Unit = { readonly kind: "unit"; - readonly loc: Range; + readonly loc: Loc; }; export type Tuple = { readonly kind: "tuple"; readonly children: readonly Expression[]; - readonly loc: Range; + readonly loc: Loc; }; export type Tensor = { readonly kind: "tensor"; readonly children: readonly Expression[]; - readonly loc: Range; + readonly loc: Loc; }; diff --git a/src/next/ast/generated/common.ts b/src/next/ast/generated/common.ts index c504c58c12..d47e5f94e9 100644 --- a/src/next/ast/generated/common.ts +++ b/src/next/ast/generated/common.ts @@ -1,14 +1,20 @@ /* eslint-disable @typescript-eslint/no-unnecessary-condition */ import type * as $ from "@/next/ast/common"; import { hideProperty } from "@/utils/tricks"; +export type Loc = $.Loc; +export type Builtin = $.Builtin; +export const Builtin = (): $.Builtin => Object.freeze({ + kind: "builtin" +}); +export const isBuiltin = ($value: Builtin) => $value.kind === "builtin"; export type Range = $.Range; export const Range = ( start: number, end: number, path: string, code: string, -): Range => { - const result: Range = { +): $.Range => { + const result: $.Range = { kind: "range", start, end, @@ -20,7 +26,7 @@ export const Range = ( return Object.freeze(result); }; export type Id = $.Id; -export const Id = (text: string, loc: $.Range): $.Id => +export const Id = (text: string, loc: $.Loc): $.Id => Object.freeze({ kind: "id", text, @@ -28,7 +34,7 @@ export const Id = (text: string, loc: $.Range): $.Id => }); export const isId = ($value: Id) => $value.kind === "id"; export type Wildcard = $.Wildcard; -export const Wildcard = (loc: $.Range): $.Wildcard => +export const Wildcard = (loc: $.Loc): $.Wildcard => Object.freeze({ kind: "wildcard", loc, @@ -36,7 +42,7 @@ export const Wildcard = (loc: $.Range): $.Wildcard => export const isWildcard = ($value: Wildcard) => $value.kind === "wildcard"; export type OptionalId = $.OptionalId; export type FuncId = $.FuncId; -export const FuncId = (text: string, loc: $.Range): $.FuncId => +export const FuncId = (text: string, loc: $.Loc): $.FuncId => Object.freeze({ kind: "func_id", text, @@ -44,7 +50,7 @@ export const FuncId = (text: string, loc: $.Range): $.FuncId => }); export const isFuncId = ($value: FuncId) => $value.kind === "func_id"; export type TypeId = $.TypeId; -export const TypeId = (text: string, loc: $.Range): $.TypeId => +export const TypeId = (text: string, loc: $.Loc): $.TypeId => Object.freeze({ kind: "type_id", text, diff --git a/src/next/ast/generated/dtype.ts b/src/next/ast/generated/dtype.ts new file mode 100644 index 0000000000..a8ee1f40c9 --- /dev/null +++ b/src/next/ast/generated/dtype.ts @@ -0,0 +1,64 @@ +/* eslint-disable @typescript-eslint/no-unnecessary-condition */ +import type * as $ from "@/next/ast/dtype"; +import type * as $c from "@/next/ast/common"; + +export type DTypeParamRef = $.DTypeParamRef; +export const DTypeParamRef = (name: $c.TypeId, loc: $c.Loc): $.DTypeParamRef => Object.freeze({ + kind: "TypeParam", + name, + loc +}); +export const isDTypeParamRef = ($value: DTypeParamRef) => $value.kind === "TypeParam"; +export type DTypeTensor = $.DTypeTensor; +export const DTypeTensor = (typeArgs: readonly $.DecodedType[], loc: $c.Loc): $.DTypeTensor => Object.freeze({ + kind: "tensor_type", + typeArgs, + loc +}); +export const isDTypeTensor = ($value: DTypeTensor) => $value.kind === "tensor_type"; +export type DTypeTuple = $.DTypeTuple; +export const DTypeTuple = (typeArgs: readonly $.DecodedType[], loc: $c.Loc): $.DTypeTuple => Object.freeze({ + kind: "tuple_type", + typeArgs, + loc +}); +export const isDTypeTuple = ($value: DTypeTuple) => $value.kind === "tuple_type"; +export type DTypeMaybe = $.DTypeMaybe; +export const DTypeMaybe = (type_: $.DecodedType, loc: $c.Loc): $.DTypeMaybe => Object.freeze({ + kind: "TypeMaybe", + type: type_, + loc +}); +export const isDTypeMaybe = ($value: DTypeMaybe) => $value.kind === "TypeMaybe"; +export type DTypeBounced = $.DTypeBounced; +export const DTypeBounced = (type_: $.DecodedType, loc: $c.Loc): $.DTypeBounced => Object.freeze({ + kind: "TypeBounced", + type: type_, + loc +}); +export const isDTypeBounced = ($value: DTypeBounced) => $value.kind === "TypeBounced"; +export type DTypeMap = $.DTypeMap; +export const DTypeMap = (key: $.DecodedType, value: $.DecodedType, loc: $c.Loc): $.DTypeMap => Object.freeze({ + kind: "map_type", + key, + value, + loc +}); +export const isDTypeMap = ($value: DTypeMap) => $value.kind === "map_type"; +export type DTypeAliasRef = $.DTypeAliasRef; +export const DTypeAliasRef = (name: $c.TypeId, typeArgs: readonly $.DecodedType[], loc: $c.Loc): $.DTypeAliasRef => Object.freeze({ + kind: "TypeAlias", + name, + typeArgs, + loc +}); +export const isDTypeAliasRef = ($value: DTypeAliasRef) => $value.kind === "TypeAlias"; +export type DTypeRef = $.DTypeRef; +export const DTypeRef = (name: $c.TypeId, typeArgs: readonly $.DecodedType[], loc: $c.Loc): $.DTypeRef => Object.freeze({ + kind: "type_ref", + name, + typeArgs, + loc +}); +export const isDTypeRef = ($value: DTypeRef) => $value.kind === "type_ref"; +export type DecodedType = $.DecodedType; \ No newline at end of file diff --git a/src/next/ast/generated/expression.ts b/src/next/ast/generated/expression.ts index bd51dad71c..a54d4763bc 100644 --- a/src/next/ast/generated/expression.ts +++ b/src/next/ast/generated/expression.ts @@ -33,7 +33,7 @@ export const allUnaryOperation: readonly $.UnaryOperation[] = [ "~", ]; export type CodeOf = $.CodeOf; -export const CodeOf = (contract: $c.TypeId, loc: $c.Range): $.CodeOf => +export const CodeOf = (contract: $c.TypeId, loc: $c.Loc): $.CodeOf => Object.freeze({ kind: "code_of", contract, @@ -46,7 +46,7 @@ export type Number = $.Number; export const Number = ( base: $.NumberBase, value: bigint, - loc: $c.Range, + loc: $c.Loc, ): $.Number => Object.freeze({ kind: "number", @@ -56,7 +56,7 @@ export const Number = ( }); export const isNumber = ($value: Number) => $value.kind === "number"; export type Boolean = $.Boolean; -export const Boolean = (value: boolean, loc: $c.Range): $.Boolean => +export const Boolean = (value: boolean, loc: $c.Loc): $.Boolean => Object.freeze({ kind: "boolean", value, @@ -64,14 +64,14 @@ export const Boolean = (value: boolean, loc: $c.Range): $.Boolean => }); export const isBoolean = ($value: Boolean) => $value.kind === "boolean"; export type Null = $.Null; -export const Null = (loc: $c.Range): $.Null => +export const Null = (loc: $c.Loc): $.Null => Object.freeze({ kind: "null", loc, }); export const isNull = ($value: Null) => $value.kind === "null"; export type String = $.String; -export const String = (value: string, loc: $c.Range): $.String => +export const String = (value: string, loc: $c.Loc): $.String => Object.freeze({ kind: "string", value, @@ -79,7 +79,7 @@ export const String = (value: string, loc: $c.Range): $.String => }); export const isString = ($value: String) => $value.kind === "string"; export type Var = $.Var; -export const Var = (name: string, loc: $c.Range): $.Var => +export const Var = (name: string, loc: $c.Loc): $.Var => Object.freeze({ kind: "var", name, @@ -87,7 +87,7 @@ export const Var = (name: string, loc: $c.Range): $.Var => }); export const isVar = ($value: Var) => $value.kind === "var"; export type Unit = $.Unit; -export const Unit = (loc: $c.Range): $.Unit => +export const Unit = (loc: $c.Loc): $.Unit => Object.freeze({ kind: "unit", loc, @@ -96,7 +96,7 @@ export const isUnit = ($value: Unit) => $value.kind === "unit"; export type Tensor = $.Tensor; export const Tensor = ( children: readonly $.Expression[], - loc: $c.Range, + loc: $c.Loc, ): $.Tensor => Object.freeze({ kind: "tensor", @@ -107,7 +107,7 @@ export const isTensor = ($value: Tensor) => $value.kind === "tensor"; export type Tuple = $.Tuple; export const Tuple = ( children: readonly $.Expression[], - loc: $c.Range, + loc: $c.Loc, ): $.Tuple => Object.freeze({ kind: "tuple", @@ -119,7 +119,7 @@ export type InitOf = $.InitOf; export const InitOf = ( contract: $c.TypeId, args: readonly $.Expression[], - loc: $c.Range, + loc: $c.Loc, ): $.InitOf => Object.freeze({ kind: "init_of", @@ -132,7 +132,7 @@ export type StructFieldInitializer = $.StructFieldInitializer; export const StructFieldInitializer = ( field: $c.Id, initializer: $.Expression, - loc: $c.Range, + loc: $c.Loc, ): $.StructFieldInitializer => Object.freeze({ kind: "struct_field_initializer", @@ -147,7 +147,7 @@ export const StructInstance = ( type_: $c.TypeId, typeArgs: readonly $t.Type[], args: readonly $.StructFieldInitializer[], - loc: $c.Range, + loc: $c.Loc, ): $.StructInstance => Object.freeze({ kind: "struct_instance", @@ -163,7 +163,7 @@ export const StaticCall = ( function_: $c.Id, typeArgs: readonly $t.Type[], args: readonly $.Expression[], - loc: $c.Range, + loc: $c.Loc, ): $.StaticCall => Object.freeze({ kind: "static_call", @@ -178,7 +178,7 @@ export type FieldAccess = $.FieldAccess; export const FieldAccess = ( aggregate: $.Expression, field: $c.Id, - loc: $c.Range, + loc: $c.Loc, ): $.FieldAccess => Object.freeze({ kind: "field_access", @@ -194,7 +194,7 @@ export const MethodCall = ( method: $c.Id, typeArgs: readonly $t.Type[], args: readonly $.Expression[], - loc: $c.Range, + loc: $c.Loc, ): $.MethodCall => Object.freeze({ kind: "method_call", @@ -211,7 +211,7 @@ export const Conditional = ( condition: $.Expression, thenBranch: $.Expression, elseBranch: $.Expression, - loc: $c.Range, + loc: $c.Loc, ): $.Conditional => Object.freeze({ kind: "conditional", @@ -226,7 +226,7 @@ export type OpUnary = $.OpUnary; export const OpUnary = ( op: $.UnaryOperation, operand: $.Expression, - loc: $c.Range, + loc: $c.Loc, ): $.OpUnary => Object.freeze({ kind: "op_unary", @@ -240,7 +240,7 @@ export const OpBinary = ( op: $.BinaryOperation, left: $.Expression, right: $.Expression, - loc: $c.Range, + loc: $c.Loc, ): $.OpBinary => Object.freeze({ kind: "op_binary", @@ -261,7 +261,7 @@ export type MapLiteral = $.MapLiteral; export const MapLiteral = ( type_: $t.TypeMap, fields: readonly $.MapField[], - loc: $c.Range, + loc: $c.Loc, ): $.MapLiteral => Object.freeze({ kind: "map_literal", @@ -275,7 +275,7 @@ export type SetLiteral = $.SetLiteral; export const SetLiteral = ( valueType: $t.Type, fields: readonly $.Expression[], - loc: $c.Range, + loc: $c.Loc, ): $.SetLiteral => Object.freeze({ kind: "set_literal", @@ -286,7 +286,7 @@ export const SetLiteral = ( export const isSetLiteral = ($value: SetLiteral) => $value.kind === "set_literal"; export type StaticMethodCall = $.StaticMethodCall; -export const StaticMethodCall = (self: $c.TypeId, typeArgs: readonly $t.Type[], function_: $c.Id, args: readonly $.Expression[], loc: $c.Range): $.StaticMethodCall => Object.freeze({ +export const StaticMethodCall = (self: $c.TypeId, typeArgs: readonly $t.Type[], function_: $c.Id, args: readonly $.Expression[], loc: $c.Loc): $.StaticMethodCall => Object.freeze({ kind: "static_method_call", self, typeArgs, diff --git a/src/next/ast/generated/mtype.ts b/src/next/ast/generated/mtype.ts new file mode 100644 index 0000000000..cce2ef4a10 --- /dev/null +++ b/src/next/ast/generated/mtype.ts @@ -0,0 +1,122 @@ +/* eslint-disable @typescript-eslint/no-unnecessary-condition */ +import type * as $ from "@/next/ast/mtype"; +import type * as $c from "@/next/ast/common"; +import type * as $d from "@/next/ast/dtype"; + +export type MGTypeInt = $.MGTypeInt; +export type MGTypeSlice = $.MGTypeSlice; +export type MGTypeCell = $.MGTypeCell; +export type MGTypeBuilder = $.MGTypeBuilder; +export type MGTypeUnit = $.MGTypeUnit; +export type MGTypeVoid = $.MGTypeVoid; +export type MGTypeNull = $.MGTypeNull; +export type MGTypeBool = $.MGTypeBool; +export type MGTypeAddress = $.MGTypeAddress; +export type MGTypeString = $.MGTypeString; +export type MGTypeStringBuilder = $.MGTypeStringBuilder; +export type MGTypeRef = $.MGTypeRef; +export const MGTypeRef = (name: $c.TypeId, typeArgs: readonly $.MethodGroundType[], loc: $c.Loc): $.MGTypeRef => Object.freeze({ + ground: "yes", + kind: "type_ref", + name, + typeArgs, + loc +}); +export const isMGTypeRef = ($value: MGTypeRef) => $value.kind === "type_ref"; +export type MGTypeMaybe = $.MGTypeMaybe; +export const MGTypeMaybe = (type_: $.MethodGroundType, loc: $c.Loc): $.MGTypeMaybe => Object.freeze({ + ground: "yes", + kind: "TypeMaybe", + type: type_, + loc +}); +export const isMGTypeMaybe = ($value: MGTypeMaybe) => $value.kind === "TypeMaybe"; +export type MGTypeMap = $.MGTypeMap; +export const MGTypeMap = (key: $.MethodGroundType, value: $.MethodGroundType, loc: $c.Loc): $.MGTypeMap => Object.freeze({ + ground: "yes", + kind: "map_type", + key, + value, + loc +}); +export const isMGTypeMap = ($value: MGTypeMap) => $value.kind === "map_type"; +export type MGTypeTuple = $.MGTypeTuple; +export const MGTypeTuple = (typeArgs: readonly $.MethodGroundType[], loc: $c.Loc): $.MGTypeTuple => Object.freeze({ + ground: "yes", + kind: "tuple_type", + typeArgs, + loc +}); +export const isMGTypeTuple = ($value: MGTypeTuple) => $value.kind === "tuple_type"; +export type MGTypeTensor = $.MGTypeTensor; +export const MGTypeTensor = (typeArgs: readonly $.MethodGroundType[], loc: $c.Loc): $.MGTypeTensor => Object.freeze({ + ground: "yes", + kind: "tensor_type", + typeArgs, + loc +}); +export const isMGTypeTensor = ($value: MGTypeTensor) => $value.kind === "tensor_type"; +export type MVTypeRef = $.MVTypeRef; +export const MVTypeRef = (name: $c.TypeId, typeArgs: readonly $d.DTypeParamRef[], loc: $c.Loc): $.MVTypeRef => Object.freeze({ + ground: "no", + kind: "type_ref", + name, + typeArgs, + loc +}); +export const isMVTypeRef = ($value: MVTypeRef) => $value.kind === "type_ref"; +export type MVTypeMaybe = $.MVTypeMaybe; +export const MVTypeMaybe = (type_: $d.DTypeParamRef, loc: $c.Loc): $.MVTypeMaybe => Object.freeze({ + ground: "no", + kind: "TypeMaybe", + type: type_, + loc +}); +export const isMVTypeMaybe = ($value: MVTypeMaybe) => $value.kind === "TypeMaybe"; +export type MVTypeMap = $.MVTypeMap; +export const MVTypeMap = (key: $d.DTypeParamRef, value: $d.DTypeParamRef, loc: $c.Loc): $.MVTypeMap => Object.freeze({ + ground: "no", + kind: "map_type", + key, + value, + loc +}); +export const isMVTypeMap = ($value: MVTypeMap) => $value.kind === "map_type"; +export type MVTypeTuple = $.MVTypeTuple; +export const MVTypeTuple = (typeArgs: readonly $d.DTypeParamRef[], loc: $c.Loc): $.MVTypeTuple => Object.freeze({ + ground: "no", + kind: "tuple_type", + typeArgs, + loc +}); +export const isMVTypeTuple = ($value: MVTypeTuple) => $value.kind === "tuple_type"; +export type MVTypeTensor = $.MVTypeTensor; +export const MVTypeTensor = (typeArgs: readonly $d.DTypeParamRef[], loc: $c.Loc): $.MVTypeTensor => Object.freeze({ + ground: "no", + kind: "tensor_type", + typeArgs, + loc +}); +export const isMVTypeTensor = ($value: MVTypeTensor) => $value.kind === "tensor_type"; +export type SelfType = $.SelfType; +export type MethodGroundType = $.MethodGroundType; +export type MMethodFnType = $.MMethodFnType; +export const MMethodFnType = (typeParams: readonly $c.TypeId[], self: $.SelfType, args: readonly $.MTypedParameter[], returnType: $d.DecodedType): $.MMethodFnType => Object.freeze({ + typeParams, + self, + args, + returnType +}); +export type MTypedParameter = $.MTypedParameter; +export const MTypedParameter = (name: $c.OptionalId, type_: $d.DecodedType, loc: $c.Loc): $.MTypedParameter => Object.freeze({ + kind: "typed_parameter", + name, + type: type_, + loc +}); +export type MFnType = $.MFnType; +export const MFnType = (typeParams: readonly $c.TypeId[], args: readonly $.MTypedParameter[], returnType: $d.DecodedType): $.MFnType => Object.freeze({ + typeParams, + args, + returnType +}); \ No newline at end of file diff --git a/src/next/ast/generated/root.ts b/src/next/ast/generated/root.ts index f3a1e9d8a5..e979fba306 100644 --- a/src/next/ast/generated/root.ts +++ b/src/next/ast/generated/root.ts @@ -14,20 +14,12 @@ export const ImportPath = (path: $f.RelativePath, type_: $.ImportType, language: language }); export type Import = $.Import; -export const Import = (importPath: $.ImportPath, loc: $c.Range): $.Import => Object.freeze({ +export const Import = (importPath: $.ImportPath, loc: $c.Loc): $.Import => Object.freeze({ kind: "import", importPath, loc }); export const isImport = ($value: Import) => $value.kind === "import"; -export type TypedParameter = $.TypedParameter; -export const TypedParameter = (name: $c.OptionalId, type_: $t.Type, loc: $c.Range): $.TypedParameter => Object.freeze({ - kind: "typed_parameter", - name, - type: type_, - loc -}); -export const isTypedParameter = ($value: TypedParameter) => $value.kind === "typed_parameter"; export type RegularBody = $.RegularBody; export const RegularBody = (statements: readonly $s.Statement[]): $.RegularBody => Object.freeze({ kind: "regular_body", @@ -60,39 +52,15 @@ export const AbstractBody = (): $.AbstractBody => Object.freeze({ export const isAbstractBody = ($value: AbstractBody) => $value.kind === "abstract_body"; export type FunctionalBody = $.FunctionalBody; export type Function = $.Function; -export const Function = (inline: boolean, name: $c.Id, typeParams: readonly $c.TypeId[], returnType: $t.Type | undefined, params: readonly $.TypedParameter[], body: $.FunctionalBody, loc: $c.Range): $.Function => Object.freeze({ +export const Function = (inline: boolean, name: $c.Id, type_: $t.FnType, body: $.FunctionalBody, loc: $c.Loc): $.Function => Object.freeze({ kind: "function", inline, name, - typeParams, - returnType, - params, + type: type_, body, loc }); export const isFunction = ($value: Function) => $value.kind === "function"; -export type GetAttribute = $.GetAttribute; -export const GetAttribute = (methodId: $e.Expression | undefined, loc: $c.Range): $.GetAttribute => Object.freeze({ - methodId, - loc -}); -export type Method = $.Method; -export const Method = (mutates: boolean, overridable: boolean, override: boolean, get: $.GetAttribute | undefined, fun: $.Function): $.Method => Object.freeze({ - kind: "method", - mutates, - overridable, - override, - get, - fun -}); -export const isMethod = ($value: Method) => $value.kind === "method"; -export type Extension = $.Extension; -export const Extension = (method: $.Method, selfType: $t.Type): $.Extension => Object.freeze({ - kind: "extension", - method, - selfType -}); -export const isExtension = ($value: Extension) => $value.kind === "extension"; export type ConstantDef = $.ConstantDef; export const ConstantDef = (type_: $t.Type | undefined, initializer: $e.Expression): $.ConstantDef => Object.freeze({ kind: "constant_def", @@ -108,15 +76,23 @@ export const ConstantDecl = (type_: $t.Type): $.ConstantDecl => Object.freeze({ export const isConstantDecl = ($value: ConstantDecl) => $value.kind === "constant_decl"; export type ConstantInit = $.ConstantInit; export type Constant = $.Constant; -export const Constant = (name: $c.Id, init: $.ConstantInit, loc: $c.Range): $.Constant => Object.freeze({ +export const Constant = (name: $c.Id, init: $.ConstantInit, loc: $c.Loc): $.Constant => Object.freeze({ kind: "constant", name, init, loc }); export const isConstant = ($value: Constant) => $value.kind === "constant"; +export type Extension = $.Extension; +export const Extension = (mutates: boolean, fun: $.Function, selfType: $t.Type): $.Extension => Object.freeze({ + kind: "extension", + mutates, + fun, + selfType +}); +export const isExtension = ($value: Extension) => $value.kind === "extension"; export type FieldDecl = $.FieldDecl; -export const FieldDecl = (name: $c.Id, type_: $t.Type, initializer: $e.Expression | undefined, loc: $c.Range): $.FieldDecl => Object.freeze({ +export const FieldDecl = (name: $c.Id, type_: $t.Type, initializer: $e.Expression | undefined, loc: $c.Loc): $.FieldDecl => Object.freeze({ kind: "field_decl", name, type: type_, @@ -125,7 +101,7 @@ export const FieldDecl = (name: $c.Id, type_: $t.Type, initializer: $e.Expressio }); export const isFieldDecl = ($value: FieldDecl) => $value.kind === "field_decl"; export type StructDecl = $.StructDecl; -export const StructDecl = (name: $c.TypeId, typeParams: readonly $c.TypeId[], fields: readonly $.FieldDecl[], loc: $c.Range): $.StructDecl => Object.freeze({ +export const StructDecl = (name: $c.TypeId, typeParams: readonly $c.TypeId[], fields: readonly $.FieldDecl[], loc: $c.Loc): $.StructDecl => Object.freeze({ kind: "struct_decl", name, typeParams, @@ -134,7 +110,7 @@ export const StructDecl = (name: $c.TypeId, typeParams: readonly $c.TypeId[], fi }); export const isStructDecl = ($value: StructDecl) => $value.kind === "struct_decl"; export type MessageDecl = $.MessageDecl; -export const MessageDecl = (name: $c.TypeId, opcode: $e.Expression | undefined, fields: readonly $.FieldDecl[], loc: $c.Range): $.MessageDecl => Object.freeze({ +export const MessageDecl = (name: $c.TypeId, opcode: $e.Expression | undefined, fields: readonly $.FieldDecl[], loc: $c.Loc): $.MessageDecl => Object.freeze({ kind: "message_decl", name, opcode, @@ -148,7 +124,7 @@ export const UnionCase = (name: $c.TypeId, fields: readonly $.FieldDecl[]): $.Un fields }); export type UnionDecl = $.UnionDecl; -export const UnionDecl = (name: $c.TypeId, typeParams: readonly $c.TypeId[], cases: readonly $.UnionCase[], loc: $c.Range): $.UnionDecl => Object.freeze({ +export const UnionDecl = (name: $c.TypeId, typeParams: readonly $c.TypeId[], cases: readonly $.UnionCase[], loc: $c.Loc): $.UnionDecl => Object.freeze({ kind: "union_decl", name, typeParams, @@ -157,7 +133,7 @@ export const UnionDecl = (name: $c.TypeId, typeParams: readonly $c.TypeId[], cas }); export const isUnionDecl = ($value: UnionDecl) => $value.kind === "union_decl"; export type AliasDecl = $.AliasDecl; -export const AliasDecl = (name: $c.TypeId, typeParams: readonly $c.TypeId[], type_: $t.Type, loc: $c.Range): $.AliasDecl => Object.freeze({ +export const AliasDecl = (name: $c.TypeId, typeParams: readonly $c.TypeId[], type_: $t.Type, loc: $c.Loc): $.AliasDecl => Object.freeze({ kind: "alias_decl", name, typeParams, @@ -165,16 +141,10 @@ export const AliasDecl = (name: $c.TypeId, typeParams: readonly $c.TypeId[], typ loc }); export const isAliasDecl = ($value: AliasDecl) => $value.kind === "alias_decl"; -export type ContractAttribute = $.ContractAttribute; -export const ContractAttribute = (name: string, loc: $c.Range): $.ContractAttribute => Object.freeze({ - type: "interface", - name, - loc -}); export type InitFunction = $.InitFunction; -export const InitFunction = (params: readonly $.TypedParameter[], statements: readonly $s.Statement[], loc: $c.Range): $.InitFunction => Object.freeze({ +export const InitFunction = (args: readonly $t.TypedParameter[], statements: readonly $s.Statement[], loc: $c.Loc): $.InitFunction => Object.freeze({ kind: "init_function", - params, + args, statements, loc }); @@ -186,8 +156,29 @@ export const InitParams = (params: readonly $.FieldDecl[]): $.InitParams => Obje }); export const isInitParams = ($value: InitParams) => $value.kind === "init_params"; export type Init = $.Init; +export type ContractAttribute = $.ContractAttribute; +export const ContractAttribute = (name: string, loc: $c.Loc): $.ContractAttribute => Object.freeze({ + type: "interface", + name, + loc +}); +export type GetAttribute = $.GetAttribute; +export const GetAttribute = (methodId: $e.Expression | undefined, loc: $c.Loc): $.GetAttribute => Object.freeze({ + methodId, + loc +}); +export type Method = $.Method; +export const Method = (mutates: boolean, overridable: boolean, override: boolean, get: $.GetAttribute | undefined, fun: $.Function): $.Method => Object.freeze({ + kind: "method", + mutates, + overridable, + override, + get, + fun +}); +export const isMethod = ($value: Method) => $value.kind === "method"; export type ReceiverSimple = $.ReceiverSimple; -export const ReceiverSimple = (param: $.TypedParameter): $.ReceiverSimple => Object.freeze({ +export const ReceiverSimple = (param: $t.TypedParameter): $.ReceiverSimple => Object.freeze({ kind: "simple", param }); @@ -205,21 +196,21 @@ export const ReceiverComment = (comment: $e.String): $.ReceiverComment => Object export const isReceiverComment = ($value: ReceiverComment) => $value.kind === "comment"; export type ReceiverSubKind = $.ReceiverSubKind; export type ReceiverInternal = $.ReceiverInternal; -export const ReceiverInternal = (subKind: $.ReceiverSubKind, loc: $c.Range): $.ReceiverInternal => Object.freeze({ +export const ReceiverInternal = (subKind: $.ReceiverSubKind, loc: $c.Loc): $.ReceiverInternal => Object.freeze({ kind: "internal", subKind, loc }); export const isReceiverInternal = ($value: ReceiverInternal) => $value.kind === "internal"; export type ReceiverExternal = $.ReceiverExternal; -export const ReceiverExternal = (subKind: $.ReceiverSubKind, loc: $c.Range): $.ReceiverExternal => Object.freeze({ +export const ReceiverExternal = (subKind: $.ReceiverSubKind, loc: $c.Loc): $.ReceiverExternal => Object.freeze({ kind: "external", subKind, loc }); export const isReceiverExternal = ($value: ReceiverExternal) => $value.kind === "external"; export type ReceiverBounce = $.ReceiverBounce; -export const ReceiverBounce = (param: $.TypedParameter, loc: $c.Range): $.ReceiverBounce => Object.freeze({ +export const ReceiverBounce = (param: $t.TypedParameter, loc: $c.Loc): $.ReceiverBounce => Object.freeze({ kind: "bounce", param, loc @@ -227,7 +218,7 @@ export const ReceiverBounce = (param: $.TypedParameter, loc: $c.Range): $.Receiv export const isReceiverBounce = ($value: ReceiverBounce) => $value.kind === "bounce"; export type ReceiverKind = $.ReceiverKind; export type Receiver = $.Receiver; -export const Receiver = (selector: $.ReceiverKind, statements: readonly $s.Statement[], loc: $c.Range): $.Receiver => Object.freeze({ +export const Receiver = (selector: $.ReceiverKind, statements: readonly $s.Statement[], loc: $c.Loc): $.Receiver => Object.freeze({ kind: "receiver", selector, statements, @@ -242,20 +233,26 @@ export const FieldConstant = (overridable: boolean, override: boolean, body: $.C body }); export const isFieldConstant = ($value: FieldConstant) => $value.kind === "field_const"; -export type LocalItem = $.LocalItem; +export type LocalItems = $.LocalItems; +export const LocalItems = (fields: readonly $.FieldDecl[], methods: readonly $.Method[], receivers: readonly $.Receiver[], constants: readonly $.FieldConstant[]): $.LocalItems => Object.freeze({ + fields, + methods, + receivers, + constants +}); export type Contract = $.Contract; -export const Contract = (name: $c.TypeId, traits: readonly $c.TypeId[], attributes: readonly $.ContractAttribute[], init: $.Init | undefined, declarations: readonly $.LocalItem[], loc: $c.Range): $.Contract => Object.freeze({ +export const Contract = (init: $.Init | undefined, name: $c.TypeId, traits: readonly $c.TypeId[], attributes: readonly $.ContractAttribute[], declarations: $.LocalItems, loc: $c.Loc): $.Contract => Object.freeze({ kind: "contract", + init, name, traits, attributes, - init, declarations, loc }); export const isContract = ($value: Contract) => $value.kind === "contract"; export type Trait = $.Trait; -export const Trait = (name: $c.TypeId, traits: readonly $c.TypeId[], attributes: readonly $.ContractAttribute[], declarations: readonly $.LocalItem[], loc: $c.Range): $.Trait => Object.freeze({ +export const Trait = (name: $c.TypeId, traits: readonly $c.TypeId[], attributes: readonly $.ContractAttribute[], declarations: $.LocalItems, loc: $c.Loc): $.Trait => Object.freeze({ kind: "trait", name, traits, @@ -264,10 +261,16 @@ export const Trait = (name: $c.TypeId, traits: readonly $c.TypeId[], attributes: loc }); export const isTrait = ($value: Trait) => $value.kind === "trait"; -export type ModuleItem = $.ModuleItem; export type TypeDecl = $.TypeDecl; +export type ModuleItems = $.ModuleItems; +export const ModuleItems = (functions: readonly $.Function[], constants: readonly $.Constant[], extensions: readonly $.Extension[], types: readonly $.TypeDecl[]): $.ModuleItems => Object.freeze({ + functions, + constants, + extensions, + types +}); export type Module = $.Module; -export const Module = (imports: readonly $.Import[], items: readonly $.ModuleItem[]): $.Module => Object.freeze({ +export const Module = (imports: readonly $.Import[], items: $.ModuleItems): $.Module => Object.freeze({ kind: "module", imports, items diff --git a/src/next/ast/generated/statement.ts b/src/next/ast/generated/statement.ts index e08108fec2..b36ecbe6db 100644 --- a/src/next/ast/generated/statement.ts +++ b/src/next/ast/generated/statement.ts @@ -9,7 +9,7 @@ export const StatementLet = ( name: $c.OptionalId, type_: $t.Type | undefined, expression: $e.Expression, - loc: $c.Range, + loc: $c.Loc, ): $.StatementLet => Object.freeze({ kind: "statement_let", @@ -23,7 +23,7 @@ export const isStatementLet = ($value: StatementLet) => export type StatementReturn = $.StatementReturn; export const StatementReturn = ( expression: $e.Expression | undefined, - loc: $c.Range, + loc: $c.Loc, ): $.StatementReturn => Object.freeze({ kind: "statement_return", @@ -35,7 +35,7 @@ export const isStatementReturn = ($value: StatementReturn) => export type StatementExpression = $.StatementExpression; export const StatementExpression = ( expression: $e.Expression, - loc: $c.Range, + loc: $c.Loc, ): $.StatementExpression => Object.freeze({ kind: "statement_expression", @@ -48,7 +48,7 @@ export type StatementAssign = $.StatementAssign; export const StatementAssign = ( path: $e.Expression, expression: $e.Expression, - loc: $c.Range, + loc: $c.Loc, ): $.StatementAssign => Object.freeze({ kind: "statement_assign", @@ -79,7 +79,7 @@ export const StatementAugmentedAssign = ( op: $.AugmentedAssignOperation, path: $e.Expression, expression: $e.Expression, - loc: $c.Range, + loc: $c.Loc, ): $.StatementAugmentedAssign => Object.freeze({ kind: "statement_augmentedassign", @@ -96,7 +96,7 @@ export const StatementDestruct = ( identifiers: ReadonlyMap, ignoreUnspecifiedFields: boolean, expression: $e.Expression, - loc: $c.Range, + loc: $c.Loc, ): $.StatementDestruct => Object.freeze({ kind: "statement_destruct", @@ -111,7 +111,7 @@ export const isStatementDestruct = ($value: StatementDestruct) => export type StatementBlock = $.StatementBlock; export const StatementBlock = ( statements: readonly $.Statement[], - loc: $c.Range, + loc: $c.Loc, ): $.StatementBlock => Object.freeze({ kind: "statement_block", @@ -126,7 +126,7 @@ export const StatementForEach = ( valueName: $c.OptionalId, map: $e.Expression, statements: readonly $.Statement[], - loc: $c.Range, + loc: $c.Loc, ): $.StatementForEach => Object.freeze({ kind: "statement_foreach", @@ -151,7 +151,7 @@ export type StatementTry = $.StatementTry; export const StatementTry = ( statements: readonly $.Statement[], catchBlock: $.CatchBlock | undefined, - loc: $c.Range, + loc: $c.Loc, ): $.StatementTry => Object.freeze({ kind: "statement_try", @@ -165,7 +165,7 @@ export type StatementRepeat = $.StatementRepeat; export const StatementRepeat = ( iterations: $e.Expression, statements: readonly $.Statement[], - loc: $c.Range, + loc: $c.Loc, ): $.StatementRepeat => Object.freeze({ kind: "statement_repeat", @@ -179,7 +179,7 @@ export type StatementUntil = $.StatementUntil; export const StatementUntil = ( condition: $e.Expression, statements: readonly $.Statement[], - loc: $c.Range, + loc: $c.Loc, ): $.StatementUntil => Object.freeze({ kind: "statement_until", @@ -193,7 +193,7 @@ export type StatementWhile = $.StatementWhile; export const StatementWhile = ( condition: $e.Expression, statements: readonly $.Statement[], - loc: $c.Range, + loc: $c.Loc, ): $.StatementWhile => Object.freeze({ kind: "statement_while", @@ -208,7 +208,7 @@ export const StatementCondition = ( condition: $e.Expression, trueStatements: readonly $.Statement[], falseStatements: readonly $.Statement[] | undefined, - loc: $c.Range, + loc: $c.Loc, ): $.StatementCondition => Object.freeze({ kind: "statement_condition", diff --git a/src/next/ast/generated/type.ts b/src/next/ast/generated/type.ts index 14a69f30e7..6c25d2c9c4 100644 --- a/src/next/ast/generated/type.ts +++ b/src/next/ast/generated/type.ts @@ -8,7 +8,7 @@ export type IFInt = $.IFInt; export const IFInt = ( sign: $.Signedness, width: number, - loc: $c.Range, + loc: $c.Loc, ): $.IFInt => Object.freeze({ kind: "FInt", @@ -23,7 +23,7 @@ export type IFVarInt = $.IFVarInt; export const IFVarInt = ( sign: $.Signedness, width: $.VarIntWidth, - loc: $c.Range, + loc: $c.Loc, ): $.IFVarInt => Object.freeze({ kind: "FVarInt", @@ -34,7 +34,7 @@ export const IFVarInt = ( export const isIFVarInt = ($value: IFVarInt) => $value.kind === "FVarInt"; export type IntFormat = $.IntFormat; export type TypeInt = $.TypeInt; -export const TypeInt = (format: $.IntFormat, loc: $c.Range): $.TypeInt => +export const TypeInt = (format: $.IntFormat, loc: $c.Loc): $.TypeInt => Object.freeze({ kind: "TyInt", format, @@ -42,7 +42,7 @@ export const TypeInt = (format: $.IntFormat, loc: $c.Range): $.TypeInt => }); export const isTypeInt = ($value: TypeInt) => $value.kind === "TyInt"; export type SFBits = $.SFBits; -export const SFBits = (bits: number, loc: $c.Range): $.SFBits => +export const SFBits = (bits: number, loc: $c.Loc): $.SFBits => Object.freeze({ kind: "SFBits", bits, @@ -50,7 +50,7 @@ export const SFBits = (bits: number, loc: $c.Range): $.SFBits => }); export const isSFBits = ($value: SFBits) => $value.kind === "SFBits"; export type SFRemaining = $.SFRemaining; -export const SFRemaining = (loc: $c.Range): $.SFRemaining => +export const SFRemaining = (loc: $c.Loc): $.SFRemaining => Object.freeze({ kind: "SFRemaining", loc, @@ -58,7 +58,7 @@ export const SFRemaining = (loc: $c.Range): $.SFRemaining => export const isSFRemaining = ($value: SFRemaining) => $value.kind === "SFRemaining"; export type SFDefault = $.SFDefault; -export const SFDefault = (loc: $c.Range): $.SFDefault => +export const SFDefault = (loc: $c.Loc): $.SFDefault => Object.freeze({ kind: "SFDefault", loc, @@ -66,7 +66,7 @@ export const SFDefault = (loc: $c.Range): $.SFDefault => export const isSFDefault = ($value: SFDefault) => $value.kind === "SFDefault"; export type SliceFormat = $.SliceFormat; export type TypeSlice = $.TypeSlice; -export const TypeSlice = (format: $.SliceFormat, loc: $c.Range): $.TypeSlice => +export const TypeSlice = (format: $.SliceFormat, loc: $c.Loc): $.TypeSlice => Object.freeze({ kind: "TySlice", format, @@ -75,7 +75,7 @@ export const TypeSlice = (format: $.SliceFormat, loc: $c.Range): $.TypeSlice => export const isTypeSlice = ($value: TypeSlice) => $value.kind === "TySlice"; export type RemFormat = $.RemFormat; export type TypeCell = $.TypeCell; -export const TypeCell = (format: $.RemFormat, loc: $c.Range): $.TypeCell => +export const TypeCell = (format: $.RemFormat, loc: $c.Loc): $.TypeCell => Object.freeze({ kind: "TyCell", format, @@ -85,7 +85,7 @@ export const isTypeCell = ($value: TypeCell) => $value.kind === "TyCell"; export type TypeBuilder = $.TypeBuilder; export const TypeBuilder = ( format: $.RemFormat, - loc: $c.Range, + loc: $c.Loc, ): $.TypeBuilder => Object.freeze({ kind: "TyBuilder", @@ -95,7 +95,7 @@ export const TypeBuilder = ( export const isTypeBuilder = ($value: TypeBuilder) => $value.kind === "TyBuilder"; export type TypeUnit = $.TypeUnit; -export const TypeUnit = (loc: $c.Range): $.TypeUnit => +export const TypeUnit = (loc: $c.Loc): $.TypeUnit => Object.freeze({ kind: "unit_type", loc, @@ -104,7 +104,7 @@ export const isTypeUnit = ($value: TypeUnit) => $value.kind === "unit_type"; export type TypeTensor = $.TypeTensor; export const TypeTensor = ( typeArgs: readonly $.Type[], - loc: $c.Range, + loc: $c.Loc, ): $.TypeTensor => Object.freeze({ kind: "tensor_type", @@ -116,7 +116,7 @@ export const isTypeTensor = ($value: TypeTensor) => export type TypeTuple = $.TypeTuple; export const TypeTuple = ( typeArgs: readonly $.Type[], - loc: $c.Range, + loc: $c.Loc, ): $.TypeTuple => Object.freeze({ kind: "tuple_type", @@ -128,7 +128,7 @@ export type TypeCons = $.TypeCons; export const TypeCons = ( name: $c.TypeId, typeArgs: readonly $.Type[], - loc: $c.Range, + loc: $c.Loc, ): $.TypeCons => Object.freeze({ kind: "cons_type", @@ -139,7 +139,7 @@ export const TypeCons = ( export const isTypeCons = ($value: TypeCons) => $value.kind === "cons_type"; export type Type = $.Type; export type TypeMap = $.TypeMap; -export const TypeMap = (key: $.Type, value: $.Type, loc: $c.Range): $.TypeMap => +export const TypeMap = (key: $.Type, value: $.Type, loc: $c.Loc): $.TypeMap => Object.freeze({ kind: "map_type", key, @@ -147,3 +147,73 @@ export const TypeMap = (key: $.Type, value: $.Type, loc: $c.Range): $.TypeMap => loc, }); export const isTypeMap = ($value: TypeMap) => $value.kind === "map_type"; + +export type TypeVoid = $.TypeVoid; +export const TypeVoid = (loc: $c.Loc): $.TypeVoid => Object.freeze({ + kind: "TypeVoid", + loc +}); +export const isTypeVoid = ($value: TypeVoid) => $value.kind === "TypeVoid"; +export type TypeNull = $.TypeNull; +export const TypeNull = (loc: $c.Loc): $.TypeNull => Object.freeze({ + kind: "TypeNull", + loc +}); +export const isTypeNull = ($value: TypeNull) => $value.kind === "TypeNull"; +export type TypeBool = $.TypeBool; +export const TypeBool = (loc: $c.Loc): $.TypeBool => Object.freeze({ + kind: "TypeBool", + loc +}); +export const isTypeBool = ($value: TypeBool) => $value.kind === "TypeBool"; +export type TypeAddress = $.TypeAddress; +export const TypeAddress = (loc: $c.Loc): $.TypeAddress => Object.freeze({ + kind: "TypeAddress", + loc +}); +export const isTypeAddress = ($value: TypeAddress) => $value.kind === "TypeAddress"; +export type TypeString = $.TypeString; +export const TypeString = (loc: $c.Loc): $.TypeString => Object.freeze({ + kind: "TypeString", + loc +}); +export const isTypeString = ($value: TypeString) => $value.kind === "TypeString"; +export type TypeStringBuilder = $.TypeStringBuilder; +export const TypeStringBuilder = (loc: $c.Loc): $.TypeStringBuilder => Object.freeze({ + kind: "TypeStringBuilder", + loc +}); +export const isTypeStringBuilder = ($value: TypeStringBuilder) => $value.kind === "TypeStringBuilder"; +export type TypeBounced = $.TypeBounced; +export const TypeBounced = (type_: $.Type, loc: $c.Loc): $.TypeBounced => Object.freeze({ + kind: "TypeBounced", + type: type_, + loc +}); +export const isTypeBounced = ($value: TypeBounced) => $value.kind === "TypeBounced"; +export type TypeMaybe = $.TypeMaybe; +export const TypeMaybe = (type_: $.Type, loc: $c.Loc): $.TypeMaybe => Object.freeze({ + kind: "TypeMaybe", + type: type_, + loc +}); +export const isTypeMaybe = ($value: TypeMaybe) => $value.kind === "TypeMaybe"; +export type TypedParameter = $.TypedParameter; +export const TypedParameter = (name: $c.OptionalId, type_: $.Type, loc: $c.Loc): $.TypedParameter => Object.freeze({ + name, + type: type_, + loc +}); +export type FnType = $.FnType; +export const FnType = (typeParams: readonly $c.TypeId[], params: readonly $.TypedParameter[], returnType: $.Type | undefined): $.FnType => Object.freeze({ + typeParams, + params, + returnType +}); +export type MethodFnType = $.MethodFnType; +export const MethodFnType = (typeParams: readonly $c.TypeId[], self: $.Type, args: readonly $.TypedParameter[], returnType: $.Type): $.MethodFnType => Object.freeze({ + typeParams, + self, + args, + returnType +}); \ No newline at end of file diff --git a/src/next/ast/generated/vtype.ts b/src/next/ast/generated/vtype.ts new file mode 100644 index 0000000000..33d7a4fcdd --- /dev/null +++ b/src/next/ast/generated/vtype.ts @@ -0,0 +1,74 @@ +/* eslint-disable @typescript-eslint/no-unnecessary-condition */ +import type * as $ from "@/next/ast/vtype"; +import type * as $c from "@/next/ast/common"; + +export type VTypeVar = $.VTypeVar; +export const VTypeVar = (id: number): $.VTypeVar => Object.freeze({ + kind: "type_var", + id +}); +export const isVTypeVar = ($value: VTypeVar) => $value.kind === "type_var"; +export type VTypeInt = $.VTypeInt; +export type VTypeSlice = $.VTypeSlice; +export type VTypeCell = $.VTypeCell; +export type VTypeBuilder = $.VTypeBuilder; +export type VTypeUnit = $.VTypeUnit; +export type VTypeVoid = $.VTypeVoid; +export type VTypeNull = $.VTypeNull; +export type VTypeBool = $.VTypeBool; +export type VTypeAddress = $.VTypeAddress; +export type VTypeString = $.VTypeString; +export type VTypeStringBuilder = $.VTypeStringBuilder; +export type VTypeMaybe = $.VTypeMaybe; +export const VTypeMaybe = (type_: $.VType, loc: $c.Loc): $.VTypeMaybe => Object.freeze({ + kind: "TypeMaybe", + type: type_, + loc +}); +export const isVTypeMaybe = ($value: VTypeMaybe) => $value.kind === "TypeMaybe"; +export type VTypeBounced = $.VTypeBounced; +export const VTypeBounced = (type_: $.VType, loc: $c.Loc): $.VTypeBounced => Object.freeze({ + kind: "TypeBounced", + type: type_, + loc +}); +export const isVTypeBounced = ($value: VTypeBounced) => $value.kind === "TypeBounced"; +export type VTypeTensor = $.VTypeTensor; +export const VTypeTensor = (typeArgs: readonly $.VType[], loc: $c.Loc): $.VTypeTensor => Object.freeze({ + kind: "tensor_type", + typeArgs, + loc +}); +export const isVTypeTensor = ($value: VTypeTensor) => $value.kind === "tensor_type"; +export type VTypeTuple = $.VTypeTuple; +export const VTypeTuple = (typeArgs: readonly $.VType[], loc: $c.Loc): $.VTypeTuple => Object.freeze({ + kind: "tuple_type", + typeArgs, + loc +}); +export const isVTypeTuple = ($value: VTypeTuple) => $value.kind === "tuple_type"; +export type VTypeCons = $.VTypeCons; +export const VTypeCons = (name: $c.TypeId, typeArgs: readonly $.VType[], loc: $c.Loc): $.VTypeCons => Object.freeze({ + kind: "cons_type", + name, + typeArgs, + loc +}); +export const isVTypeCons = ($value: VTypeCons) => $value.kind === "cons_type"; +export type VTypeMap = $.VTypeMap; +export const VTypeMap = (key: $.VType, value: $.VType, loc: $c.Loc): $.VTypeMap => Object.freeze({ + kind: "map_type", + key, + value, + loc +}); +export const isVTypeMap = ($value: VTypeMap) => $value.kind === "map_type"; +export type VType = $.VType; +export type VTypeAlias = $.VTypeAlias; +export const VTypeAlias = (cons: $.VTypeCons, type_: $.VType, loc: $c.Loc): $.VTypeAlias => Object.freeze({ + kind: "TypeAlias", + cons, + type: type_, + loc +}); +export const isVTypeAlias = ($value: VTypeAlias) => $value.kind === "TypeAlias"; diff --git a/src/next/ast/index.ts b/src/next/ast/index.ts index ba26755dcf..fafe6213a2 100644 --- a/src/next/ast/index.ts +++ b/src/next/ast/index.ts @@ -2,4 +2,7 @@ export * from "@/next/ast/generated/common"; export * from "@/next/ast/generated/expression"; export * from "@/next/ast/generated/statement"; export * from "@/next/ast/generated/type"; +export * from "@/next/ast/generated/vtype"; +export * from "@/next/ast/generated/dtype"; +export * from "@/next/ast/generated/mtype"; export * from "@/next/ast/generated/root"; diff --git a/src/next/ast/mtype.ts b/src/next/ast/mtype.ts new file mode 100644 index 0000000000..d491c3d554 --- /dev/null +++ b/src/next/ast/mtype.ts @@ -0,0 +1,137 @@ +import type { OptionalId, Loc, TypeId } from "@/next/ast/common"; +import type { DecodedType, DTypeParamRef } from "@/next/ast/dtype"; +import type * as Ast from "@/next/ast/type"; + +export type MFnType = { + readonly typeParams: readonly TypeId[]; + readonly args: readonly MTypedParameter[]; + readonly returnType: DecodedType, +} + +export type MMethodFnType = { + readonly typeParams: readonly TypeId[]; + readonly self: SelfType; + readonly args: readonly MTypedParameter[]; + readonly returnType: DecodedType, +} + +export type MTypedParameter = { + readonly kind: "typed_parameter"; + readonly name: OptionalId; + readonly type: DecodedType; + readonly loc: Loc; +}; + +export type SelfType = + | MethodGroundType + | MVTypeRef + | MVTypeMap + | MVTypeMaybe + | MVTypeTuple + | MVTypeTensor; + +export type MethodGroundType = + | MGTypeRef + | MGTypeInt + | MGTypeSlice + | MGTypeCell + | MGTypeBuilder + | MGTypeUnit + | MGTypeVoid + | MGTypeNull + | MGTypeBool + | MGTypeAddress + | MGTypeString + | MGTypeStringBuilder + | MGTypeMap + | MGTypeMaybe + | MGTypeTuple + | MGTypeTensor; + +export type MGTypeInt = Ast.TypeInt +export type MGTypeSlice = Ast.TypeSlice +export type MGTypeCell = Ast.TypeCell +export type MGTypeBuilder = Ast.TypeBuilder +export type MGTypeUnit = Ast.TypeUnit +export type MGTypeVoid = Ast.TypeVoid +export type MGTypeNull = Ast.TypeNull +export type MGTypeBool = Ast.TypeBool +export type MGTypeAddress = Ast.TypeAddress +export type MGTypeString = Ast.TypeString +export type MGTypeStringBuilder = Ast.TypeStringBuilder + +export type MGTypeRef = { + readonly ground: "yes", + readonly kind: "type_ref"; + readonly name: TypeId; + readonly typeArgs: readonly MethodGroundType[]; + readonly loc: Loc; +}; + +export type MGTypeMaybe = { + readonly ground: "yes"; + readonly kind: "TypeMaybe" + readonly type: MethodGroundType; + readonly loc: Loc; +} + +export type MGTypeMap = { + readonly ground: "yes"; + readonly kind: "map_type"; + readonly key: MethodGroundType; + readonly value: MethodGroundType; + readonly loc: Loc; +}; + +export type MGTypeTuple = { + readonly ground: "yes"; + readonly kind: "tuple_type"; + readonly typeArgs: readonly MethodGroundType[]; + readonly loc: Loc; +}; + +export type MGTypeTensor = { + readonly ground: "yes"; + readonly kind: "tensor_type"; + readonly typeArgs: readonly MethodGroundType[]; + readonly loc: Loc; +}; + + + +export type MVTypeRef = { + readonly ground: "no", + readonly kind: "type_ref"; + readonly name: TypeId; + readonly typeArgs: readonly DTypeParamRef[]; + readonly loc: Loc; +}; + +export type MVTypeMaybe = { + readonly ground: "no", + readonly kind: "TypeMaybe" + readonly type: DTypeParamRef; + readonly loc: Loc; +} + +export type MVTypeMap = { + readonly ground: "no", + readonly kind: "map_type"; + readonly key: DTypeParamRef; + readonly value: DTypeParamRef; + readonly loc: Loc; +}; + +export type MVTypeTuple = { + readonly ground: "no", + readonly kind: "tuple_type"; + readonly typeArgs: readonly DTypeParamRef[]; + readonly loc: Loc; +}; + +export type MVTypeTensor = { + readonly ground: "no", + readonly kind: "tensor_type"; + readonly typeArgs: readonly DTypeParamRef[]; + readonly loc: Loc; +}; diff --git a/src/next/ast/root.ts b/src/next/ast/root.ts index dc29a88841..e962b74742 100644 --- a/src/next/ast/root.ts +++ b/src/next/ast/root.ts @@ -1,14 +1,13 @@ import type { FuncId, Id, - Range, - OptionalId, + Loc, TypeId, Language, } from "@/next/ast/common"; import type { Expression, Number, String } from "@/next/ast/expression"; import type { Statement } from "@/next/ast/statement"; -import type { Type } from "@/next/ast/type"; +import type { FnType, Type, TypedParameter } from "@/next/ast/type"; import type { RelativePath } from "@/next/fs"; export type Source = { @@ -20,18 +19,14 @@ export type Source = { export type Module = { readonly kind: "module"; readonly imports: readonly Import[]; - readonly items: readonly ModuleItem[]; + readonly items: ModuleItems; }; -export type ModuleItem = - | Function - | Extension - | Constant - | StructDecl - | MessageDecl - | UnionDecl - | AliasDecl - | Contract - | Trait; +export type ModuleItems = { + readonly functions: readonly Function[]; + readonly constants: readonly Constant[]; + readonly extensions: readonly Extension[]; + readonly types: readonly TypeDecl[]; +} export type TypeDecl = | StructDecl | MessageDecl @@ -42,7 +37,7 @@ export type TypeDecl = export type Import = { readonly kind: "import"; readonly importPath: ImportPath; - readonly loc: Range; + readonly loc: Loc; }; // Reference to source file export type ImportPath = { @@ -61,16 +56,16 @@ export type Contract = { readonly name: TypeId; readonly traits: readonly TypeId[]; readonly attributes: readonly ContractAttribute[]; - readonly declarations: readonly LocalItem[]; - readonly loc: Range; + readonly declarations: LocalItems; + readonly loc: Loc; }; export type Init = InitFunction | InitParams; export type InitFunction = { readonly kind: "init_function"; - readonly params: readonly TypedParameter[]; + readonly args: readonly TypedParameter[]; readonly statements: readonly Statement[]; - readonly loc: Range; + readonly loc: Loc; }; export type InitParams = { readonly kind: "init_params"; @@ -83,25 +78,27 @@ export type Trait = { readonly name: TypeId; readonly traits: readonly TypeId[]; readonly attributes: readonly ContractAttribute[]; - readonly declarations: readonly LocalItem[]; - readonly loc: Range; + readonly declarations: LocalItems; + readonly loc: Loc; }; -export type LocalItem = - | FieldDecl - | Method - | Receiver - | FieldConstant; +export type LocalItems = { + readonly fields: readonly FieldDecl[]; + readonly methods: readonly Method[]; + readonly receivers: readonly Receiver[]; + readonly constants: readonly FieldConstant[]; +}; export type ContractAttribute = { readonly type: "interface"; readonly name: string; - readonly loc: Range; + readonly loc: Loc; }; export type Extension = { readonly kind: "extension"; - readonly method: Method; + readonly mutates: boolean; + readonly fun: Function; readonly selfType: Type; }; @@ -116,18 +113,16 @@ export type Method = { export type GetAttribute = { readonly methodId: Expression | undefined; - readonly loc: Range; + readonly loc: Loc; }; export type Function = { readonly kind: "function"; readonly inline: boolean; readonly name: Id; - readonly typeParams: readonly TypeId[]; - readonly returnType: Type | undefined; - readonly params: readonly TypedParameter[]; + readonly type: FnType; readonly body: FunctionalBody; - readonly loc: Range; + readonly loc: Loc; }; export type FunctionalBody = RegularBody | AsmBody | NativeBody | AbstractBody; @@ -153,13 +148,6 @@ export type AsmShuffle = { readonly ret: readonly Number[]; }; -export type TypedParameter = { - readonly kind: "typed_parameter"; - readonly name: OptionalId; - readonly type: Type; - readonly loc: Range; -}; - export type FieldConstant = { readonly kind: "field_const"; readonly overridable: boolean; @@ -170,7 +158,7 @@ export type Constant = { readonly kind: "constant"; readonly name: Id; readonly init: ConstantInit; - readonly loc: Range; + readonly loc: Loc; }; export type ConstantInit = ConstantDef | ConstantDecl; export type ConstantDef = { @@ -188,7 +176,7 @@ export type StructDecl = { readonly name: TypeId; readonly typeParams: readonly TypeId[]; readonly fields: readonly FieldDecl[]; - readonly loc: Range; + readonly loc: Loc; }; export type MessageDecl = { @@ -196,7 +184,7 @@ export type MessageDecl = { readonly name: TypeId; readonly opcode: Expression | undefined; readonly fields: readonly FieldDecl[]; - readonly loc: Range; + readonly loc: Loc; }; export type UnionDecl = { @@ -204,7 +192,7 @@ export type UnionDecl = { readonly name: TypeId; readonly typeParams: readonly TypeId[]; readonly cases: readonly UnionCase[]; - readonly loc: Range; + readonly loc: Loc; }; export type UnionCase = { readonly name: TypeId; @@ -216,7 +204,7 @@ export type AliasDecl = { readonly name: TypeId; readonly typeParams: readonly TypeId[]; readonly type: Type; - readonly loc: Range; + readonly loc: Loc; }; export type FieldDecl = { @@ -224,14 +212,14 @@ export type FieldDecl = { readonly name: Id; readonly type: Type; readonly initializer: Expression | undefined; - readonly loc: Range; + readonly loc: Loc; }; export type Receiver = { readonly kind: "receiver"; readonly selector: ReceiverKind; readonly statements: readonly Statement[]; - readonly loc: Range; + readonly loc: Loc; }; export type ReceiverSimple = { readonly kind: "simple"; @@ -251,16 +239,16 @@ export type ReceiverSubKind = export type ReceiverInternal = { readonly kind: "internal"; readonly subKind: ReceiverSubKind; - readonly loc: Range; + readonly loc: Loc; }; export type ReceiverExternal = { readonly kind: "external"; readonly subKind: ReceiverSubKind; - readonly loc: Range; + readonly loc: Loc; }; export type ReceiverBounce = { readonly kind: "bounce"; readonly param: TypedParameter; - readonly loc: Range; + readonly loc: Loc; }; export type ReceiverKind = ReceiverInternal | ReceiverExternal | ReceiverBounce; diff --git a/src/next/ast/statement.ts b/src/next/ast/statement.ts index 5baa797bf1..39230b1aaf 100644 --- a/src/next/ast/statement.ts +++ b/src/next/ast/statement.ts @@ -1,4 +1,4 @@ -import type { Id, Range, OptionalId, TypeId } from "@/next/ast/common"; +import type { Id, Loc, OptionalId, TypeId } from "@/next/ast/common"; import type { Expression } from "@/next/ast/expression"; import type { Type } from "@/next/ast/type"; @@ -22,26 +22,26 @@ export type StatementLet = { readonly name: OptionalId; readonly type: Type | undefined; readonly expression: Expression; - readonly loc: Range; + readonly loc: Loc; }; export type StatementReturn = { readonly kind: "statement_return"; readonly expression: Expression | undefined; - readonly loc: Range; + readonly loc: Loc; }; export type StatementExpression = { readonly kind: "statement_expression"; readonly expression: Expression; - readonly loc: Range; + readonly loc: Loc; }; export type StatementAssign = { readonly kind: "statement_assign"; readonly path: Expression; // left-hand side of `=` readonly expression: Expression; - readonly loc: Range; + readonly loc: Loc; }; export type AugmentedAssignOperation = @@ -63,7 +63,7 @@ export type StatementAugmentedAssign = { readonly op: AugmentedAssignOperation; readonly path: Expression; readonly expression: Expression; - readonly loc: Range; + readonly loc: Loc; }; export type StatementCondition = { @@ -71,35 +71,35 @@ export type StatementCondition = { readonly condition: Expression; readonly trueStatements: readonly Statement[]; readonly falseStatements: readonly Statement[] | undefined; - readonly loc: Range; + readonly loc: Loc; }; export type StatementWhile = { readonly kind: "statement_while"; readonly condition: Expression; readonly statements: readonly Statement[]; - readonly loc: Range; + readonly loc: Loc; }; export type StatementUntil = { readonly kind: "statement_until"; readonly condition: Expression; readonly statements: readonly Statement[]; - readonly loc: Range; + readonly loc: Loc; }; export type StatementRepeat = { readonly kind: "statement_repeat"; readonly iterations: Expression; readonly statements: readonly Statement[]; - readonly loc: Range; + readonly loc: Loc; }; export type StatementTry = { readonly kind: "statement_try"; readonly statements: readonly Statement[]; readonly catchBlock: CatchBlock | undefined; - readonly loc: Range; + readonly loc: Loc; }; export type CatchBlock = { @@ -113,7 +113,7 @@ export type StatementForEach = { readonly valueName: OptionalId; readonly map: Expression; readonly statements: readonly Statement[]; - readonly loc: Range; + readonly loc: Loc; }; export type StatementDestruct = { @@ -123,11 +123,11 @@ export type StatementDestruct = { readonly identifiers: ReadonlyMap; readonly ignoreUnspecifiedFields: boolean; readonly expression: Expression; - readonly loc: Range; + readonly loc: Loc; }; export type StatementBlock = { readonly kind: "statement_block"; readonly statements: readonly Statement[]; - readonly loc: Range; + readonly loc: Loc; }; diff --git a/src/next/ast/type.ts b/src/next/ast/type.ts index ea5d89438c..e2cd3f66a2 100644 --- a/src/next/ast/type.ts +++ b/src/next/ast/type.ts @@ -1,4 +1,23 @@ -import type { Range, TypeId } from "@/next/ast/common"; +import type { Loc, OptionalId, TypeId } from "@/next/ast/common"; + +export type FnType = { + readonly typeParams: readonly TypeId[]; + readonly params: readonly TypedParameter[]; + readonly returnType: Type | undefined, +} + +export type MethodFnType = { + readonly typeParams: readonly TypeId[]; + readonly self: Type; + readonly args: readonly TypedParameter[]; + readonly returnType: Type, +} + +export type TypedParameter = { + readonly name: OptionalId; + readonly type: Type; + readonly loc: Loc; +}; export type Type = | TypeMap @@ -9,32 +28,82 @@ export type Type = | TypeBuilder | TypeTuple | TypeUnit - | TypeTensor; + | TypeTensor + | TypeVoid + | TypeNull + | TypeBool + | TypeAddress + | TypeString + | TypeStringBuilder + | TypeBounced + | TypeMaybe; export type TypeCons = { readonly kind: "cons_type"; readonly name: TypeId; readonly typeArgs: readonly Type[]; - readonly loc: Range; + readonly loc: Loc; }; +export type TypeVoid = { + readonly kind: "TypeVoid" + readonly loc: Loc; +} + +export type TypeNull = { + readonly kind: "TypeNull" + readonly loc: Loc; +} + +export type TypeBool = { + readonly kind: "TypeBool" + readonly loc: Loc; +} + +export type TypeAddress = { + readonly kind: "TypeAddress" + readonly loc: Loc; +} + +export type TypeString = { + readonly kind: "TypeString" + readonly loc: Loc; +} + +export type TypeStringBuilder = { + readonly kind: "TypeStringBuilder" + readonly loc: Loc; +} + +export type TypeBounced = { + readonly kind: "TypeBounced" + readonly type: Type; + readonly loc: Loc; +} + +export type TypeMaybe = { + readonly kind: "TypeMaybe" + readonly type: Type; + readonly loc: Loc; +} + export type TypeInt = { readonly kind: "TyInt"; readonly format: IntFormat; - readonly loc: Range; + readonly loc: Loc; }; export type IntFormat = IFInt | IFVarInt; export type IFInt = { readonly kind: "FInt"; readonly sign: Signedness; readonly width: number; - readonly loc: Range; + readonly loc: Loc; }; export type IFVarInt = { readonly kind: "FVarInt"; readonly sign: Signedness; readonly width: VarIntWidth; - readonly loc: Range; + readonly loc: Loc; }; export type VarIntWidth = "16" | "32"; export type Signedness = "signed" | "unsigned"; @@ -42,55 +111,55 @@ export type Signedness = "signed" | "unsigned"; export type TypeSlice = { readonly kind: "TySlice"; readonly format: SliceFormat; - readonly loc: Range; + readonly loc: Loc; }; export type SliceFormat = SFBits | SFRemaining | SFDefault; export type SFBits = { readonly kind: "SFBits"; readonly bits: number; - readonly loc: Range; + readonly loc: Loc; }; export type SFRemaining = { readonly kind: "SFRemaining"; - readonly loc: Range; + readonly loc: Loc; }; export type SFDefault = { readonly kind: "SFDefault"; - readonly loc: Range; + readonly loc: Loc; }; export type TypeCell = { readonly kind: "TyCell"; readonly format: RemFormat; - readonly loc: Range; + readonly loc: Loc; }; export type TypeBuilder = { readonly kind: "TyBuilder"; readonly format: RemFormat; - readonly loc: Range; + readonly loc: Loc; }; export type RemFormat = SFRemaining | SFDefault; export type TypeTuple = { readonly kind: "tuple_type"; readonly typeArgs: readonly Type[]; - readonly loc: Range; + readonly loc: Loc; }; export type TypeUnit = { readonly kind: "unit_type"; - readonly loc: Range; + readonly loc: Loc; }; export type TypeTensor = { readonly kind: "tensor_type"; readonly typeArgs: readonly Type[]; - readonly loc: Range; + readonly loc: Loc; }; export type TypeMap = { readonly kind: "map_type"; readonly key: Type; // any type except tensor readonly value: Type; // any type except tensor - readonly loc: Range; + readonly loc: Loc; }; diff --git a/src/next/ast/vtype.ts b/src/next/ast/vtype.ts new file mode 100644 index 0000000000..f7cb414cf9 --- /dev/null +++ b/src/next/ast/vtype.ts @@ -0,0 +1,85 @@ +import type { Loc, TypeId } from "@/next/ast/common"; +import type * as Ast from "@/next/ast/type"; + +export type VType = + | VTypeVar + | VTypeMap + | VTypeCons + | VTypeTuple + | VTypeTensor + | VTypeAlias + | VTypeInt + | VTypeSlice + | VTypeCell + | VTypeBuilder + | VTypeUnit + | VTypeVoid + | VTypeNull + | VTypeBool + | VTypeAddress + | VTypeString + | VTypeStringBuilder + | VTypeBounced + | VTypeMaybe; + +export type VTypeInt = Ast.TypeInt; +export type VTypeSlice = Ast.TypeSlice; +export type VTypeCell = Ast.TypeCell; +export type VTypeBuilder = Ast.TypeBuilder; +export type VTypeUnit = Ast.TypeUnit; +export type VTypeVoid = Ast.TypeVoid; +export type VTypeNull = Ast.TypeNull; +export type VTypeBool = Ast.TypeBool; +export type VTypeAddress = Ast.TypeAddress; +export type VTypeString = Ast.TypeString; +export type VTypeStringBuilder = Ast.TypeStringBuilder; + +export type VTypeVar = { + readonly kind: "type_var"; + readonly id: number; +} + +export type VTypeAlias = { + readonly kind: "TypeAlias" + readonly cons: VTypeCons; + readonly type: VType; + readonly loc: Loc; +} + +export type VTypeCons = { + readonly kind: "cons_type"; + readonly name: TypeId; + readonly typeArgs: readonly VType[]; + readonly loc: Loc; +}; + +export type VTypeTuple = { + readonly kind: "tuple_type"; + readonly typeArgs: readonly VType[]; + readonly loc: Loc; +}; + +export type VTypeTensor = { + readonly kind: "tensor_type"; + readonly typeArgs: readonly VType[]; + readonly loc: Loc; +}; + +export type VTypeMap = { + readonly kind: "map_type"; + readonly key: VType; + readonly value: VType; + readonly loc: Loc; +}; + +export type VTypeBounced = { + readonly kind: "TypeBounced" + readonly type: VType; + readonly loc: Loc; +} + +export type VTypeMaybe = { + readonly kind: "TypeMaybe" + readonly type: VType; + readonly loc: Loc; +} diff --git a/src/next/grammar/errors.ts b/src/next/grammar/errors.ts index 367b5a7267..6f9c512c5f 100644 --- a/src/next/grammar/errors.ts +++ b/src/next/grammar/errors.ts @@ -164,6 +164,9 @@ export const SyntaxErrors = (l: SourceLogger) => ({ duplicateAs: () => (loc: Range) => { return l.at(loc).error(l.text`"as" cannot be nested`); }, + typeArity: (name: string, expected: number) => (loc: Range) => { + return l.at(loc).error(l.text`${name}<> expects ${String(expected)} arguments`); + }, wrongVarIntSize: () => (loc: Range) => { return l.at(loc).error(l.text`Varint can only be 16 or 32 bits wide`); }, @@ -284,6 +287,13 @@ export const SyntaxErrors = (l: SourceLogger) => ({ l.text`Declaration without a body must be abstract`, ); }, + mustBeGeneric: () => (loc: Range) => { + return l + .at(loc) + .error( + l.text`This type must be generic`, + ); + }, }); export type SyntaxErrors = ReturnType>; diff --git a/src/next/grammar/import-parser.ts b/src/next/grammar/import-parser.ts index f92963fcec..c52ac3e595 100644 --- a/src/next/grammar/import-parser.ts +++ b/src/next/grammar/import-parser.ts @@ -1,6 +1,6 @@ import type * as Ast from "@/next/ast"; import { emptyPath, fromString } from "@/next/fs"; -import type { Language, Range } from "@/next/ast/common"; +import type { Language, Loc } from "@/next/ast/common"; import type { SourceLogger } from "@/error/logger-util"; const detectLanguage = (path: string): Language | undefined => { @@ -29,18 +29,18 @@ const guessExtension = ( const stdlibPrefix = "@stdlib/"; export const ImportErrors = (l: SourceLogger) => ({ - importWithBackslash: () => (loc: Range) => { + importWithBackslash: () => (loc: Loc) => { return l.at(loc).error(l.text`Import path can't contain "\\"`); }, - noFolderImports: () => (loc: Range) => { + noFolderImports: () => (loc: Loc) => { return l.at(loc).error(l.text`Cannot import a folder`); }, - invalidImport: () => (loc: Range) => { + invalidImport: () => (loc: Loc) => { return l .at(loc) .error(l.text`Import must start with ./, ../ or @stdlib/`); }, - escapingImport: () => (loc: Range) => { + escapingImport: () => (loc: Loc) => { return l .at(loc) .error(l.text`Standard library imports should be inside its root`); @@ -51,7 +51,7 @@ export type ImportErrors = ReturnType>; export function parseImportString( importText: string, - range: Range, + range: Loc, err: ImportErrors, ): Ast.ImportPath { if (importText.endsWith("/")) { diff --git a/src/next/grammar/index.ts b/src/next/grammar/index.ts index 16a3c88e4d..f04e2dc2b2 100644 --- a/src/next/grammar/index.ts +++ b/src/next/grammar/index.ts @@ -4,10 +4,11 @@ import type { $ast } from "@/next/grammar/grammar"; import * as G from "@/next/grammar/grammar"; import { SyntaxErrors } from "@/next/grammar/errors"; import { makeMakeVisitor } from "@/utils/tricks"; -import type { Range } from "@/next/ast/common"; +import type { Loc } from "@/next/ast/common"; import { throwInternal } from "@/error/errors"; import type { SourceLogger } from "@/error/logger-util"; import { parseImportString } from "@/next/grammar/import-parser"; +import { builtinTypes } from "@/next/types/builtins"; const makeVisitor = makeMakeVisitor("$"); @@ -338,8 +339,40 @@ const parseStructInstance = ); }; +const parseBouncedArgs = + (typeArgs: $ast.typeArgs, range: Ast.Range): Handler => + (ctx) => { + const args = parseList(typeArgs); + const [head] = args; + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + if (args.length !== 1 || !head) { + ctx.err.typeArity('bounced', 1)(range); + return Ast.TypeBounced( + Ast.TypeCons(Ast.TypeId("ERROR", range), [], range), + range, + ); + } + return Ast.TypeBounced(parseType(head)(ctx), range); + }; + +const parseMaybeArgs = + (typeArgs: $ast.typeArgs, range: Ast.Range): Handler => + (ctx) => { + const args = parseList(typeArgs); + const [head] = args; + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + if (args.length !== 1 || !head) { + ctx.err.typeArity('Maybe', 1)(range); + return Ast.TypeMaybe( + Ast.TypeCons(Ast.TypeId("ERROR", range), [], range), + range, + ); + } + return Ast.TypeMaybe(parseType(head)(ctx), range); + }; + const parseMapArgs = - (typeArgs: $ast.typeArgs, range: Range): Handler => + (typeArgs: $ast.typeArgs, range: Ast.Range): Handler => (ctx) => { const args = parseList(typeArgs); const [keyType, valueType] = args; @@ -380,7 +413,7 @@ const parseMapField = }; const parseSetArgs = - (typeArgs: $ast.typeArgs, range: Range): Handler => + (typeArgs: $ast.typeArgs, range: Ast.Range): Handler => (ctx) => { const args = parseList(typeArgs); const [valueType] = args; @@ -933,9 +966,9 @@ const parseNamedAttr = (key: K) => ( nodes: readonly ($ast.FunctionAttribute | $ast.ConstantAttribute)[], - ): Handler => + ): Handler => (ctx) => { - const attrs: Range[] = []; + const attrs: Ast.Range[] = []; for (const node of nodes) { if (typeof node.name === "string" && node.name === key) { attrs.push(ctx.toRange(node.loc)); @@ -1047,7 +1080,7 @@ const parseTypeStorage = }; const applyFormat = - (type: Ast.Type, storage: $ast.storage, asLoc: Range): Handler => + (type: Ast.Type, storage: $ast.storage, asLoc: Ast.Range): Handler => (ctx) => { const fallback = Ast.TypeCons(Ast.TypeId("ERROR", asLoc), [], asLoc); if (type.kind === "TyInt") { @@ -1149,6 +1182,10 @@ const applyFormat = const result = applyFormat(arg, storage, asLoc)(ctx); return Ast.TypeCons(type.name, [result], type.loc); } else { + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + if (type.loc.kind !== 'range') { + return throwInternal("Non-range in parser") + } ctx.err.cannotHaveFormat()(type.loc); return fallback; } @@ -1174,24 +1211,26 @@ const parseTypeAs = return applyFormat(result, onlyAs, asLoc)(ctx); }; -const flattenName = (name: $ast.TypeId | $ast.MapKeyword | $ast.Bounced) => { - if (name.$ === "MapKeyword") { - return "map"; - } else if (name.$ === "Bounced") { - return "bounced"; - } else { - return name.name; - } -}; - const parseTypeGeneric = ({ name, args, loc }: $ast.TypeGeneric): Handler => (ctx) => { - return Ast.TypeCons( - Ast.TypeId(flattenName(name), ctx.toRange(name.loc)), - map(parseList(args), parseTypeAs)(ctx), - ctx.toRange(loc), - ); + const range = ctx.toRange(loc); + if (name.$ === "Bounced") { + return parseBouncedArgs(args, range)(ctx); + } else if (name.$ === "MapKeyword" || name.name === 'Map') { + return parseMapArgs(args, range)(ctx); + } else if (name.name === 'Maybe') { + return parseMaybeArgs(args, range)(ctx); + } else if (builtinTypes.has(name.name)) { + ctx.err.typeArity(name.name, 0)(range); + return Ast.TypeCons(Ast.TypeId("ERROR", range), [], range); + } else { + return Ast.TypeCons( + Ast.TypeId(name.name, ctx.toRange(name.loc)), + map(parseList(args), parseTypeAs)(ctx), + range, + ); + } }; const parseTypeOptional = @@ -1210,16 +1249,36 @@ const parseTypeRegular = ({ child }: $ast.TypeRegular): Handler => (ctx) => { const range = ctx.toRange(child.loc); - if (child.name === "Int") { - return Ast.TypeInt(Ast.IFInt("signed", 257, range), range); - } else if (child.name === "Slice") { - return Ast.TypeSlice(Ast.SFDefault(range), range); - } else if (child.name === "Cell") { - return Ast.TypeCell(Ast.SFDefault(range), range); - } else if (child.name === "Builder") { - return Ast.TypeBuilder(Ast.SFDefault(range), range); + switch (child.name) { + case "Int": + return Ast.TypeInt(Ast.IFInt("signed", 257, range), range); + case "Slice": + return Ast.TypeSlice(Ast.SFDefault(range), range); + case "Cell": + return Ast.TypeCell(Ast.SFDefault(range), range); + case "Builder": + return Ast.TypeBuilder(Ast.SFDefault(range), range); + case "Void": + return Ast.TypeVoid(range); + case "Null": + return Ast.TypeNull(range); + case "Bool": + return Ast.TypeBool(range); + case "Address": + return Ast.TypeAddress(range); + case "String": + return Ast.TypeString(range); + case "StringBuilder": + return Ast.TypeStringBuilder(range); + case "Bounced": + ctx.err.mustBeGeneric()(range); + return Ast.TypeCons(Ast.TypeId("ERROR", range), [], range); + case "Maybe": + ctx.err.mustBeGeneric()(range); + return Ast.TypeCons(Ast.TypeId("ERROR", range), [], range); + default: + return Ast.TypeCons(parseTypeId(child)(ctx), [], range); } - return Ast.TypeCons(parseTypeId(child)(ctx), [], range); }; const parseTypeTensor = @@ -1401,9 +1460,11 @@ const parseAsmFunctionRaw = return Ast.Function( !!parseNamedAttr("inline")(node.attributes)(ctx), parseId(node.name)(ctx), - map(parseList(node.typeParams), parseTypeId)(ctx), - node.returnType ? parseType(node.returnType)(ctx) : undefined, - map(parseList(node.parameters), parseParameter)(ctx), + Ast.FnType( + map(parseList(node.typeParams), parseTypeId)(ctx), + map(parseList(node.parameters), parseParameter)(ctx), + node.returnType ? parseType(node.returnType)(ctx) : undefined, + ), Ast.AsmBody(parseAsmShuffle(node.shuffle)(ctx), [ node.instructions.trim(), ]), @@ -1413,7 +1474,7 @@ const parseAsmFunctionRaw = const checkNoGlobalAttrs = ( attrs: readonly ($ast.FunctionAttribute | $ast.ConstantAttribute)[], - range: Range, + range: Ast.Range, ): Handler => ctx => { const isVirtual = parseNamedAttr("virtual")(attrs)(ctx); const isOverride = parseNamedAttr("override")(attrs)(ctx); @@ -1426,7 +1487,7 @@ const checkNoGlobalAttrs = ( const parseInheritance = ( hasBody: boolean, attrs: readonly ($ast.FunctionAttribute | $ast.ConstantAttribute)[], - range: Range, + range: Ast.Range, ): Handler<{ override: boolean, overridable: boolean }> => ctx => { const isVirtual = parseNamedAttr("virtual")(attrs)(ctx); const isOverride = parseNamedAttr("override")(attrs)(ctx); @@ -1548,11 +1609,11 @@ const parseContract = })(); return Ast.Contract( + init, parseTypeId(name)(ctx), map(parseList(traits), parseTypeId)(ctx), map(attributes, parseContractAttribute)(ctx), - init, - map(locals, parseLocalItem)(ctx), + parseLocalItems(locals)(ctx), ctx.toRange(loc), ); }; @@ -1563,11 +1624,13 @@ const parseFunctionRaw = return Ast.Function( !!parseNamedAttr("inline")(node.attributes)(ctx), parseId(node.name)(ctx), - map(parseList(node.typeParams), parseTypeId)(ctx), - node.returnType - ? parseType(node.returnType)(ctx) - : undefined, - map(parseList(node.parameters), parseParameter)(ctx), + Ast.FnType( + map(parseList(node.typeParams), parseTypeId)(ctx), + map(parseList(node.parameters), parseParameter)(ctx), + node.returnType + ? parseType(node.returnType)(ctx) + : undefined, + ), node.body.$ === "FunctionDeclaration" ? Ast.AbstractBody() : Ast.RegularBody(map(node.body.body, parseStatement)(ctx)), @@ -1584,6 +1647,10 @@ const parseExtension = const fn = parseFunction(node)(ctx); const get = parseGetAttribute(node.attributes)(ctx); if (get) { + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + if (get.loc.kind !== 'range') { + return throwInternal("Non-range in parser"); + } ctx.err.globalGetter()(get.loc); } checkNoGlobalAttrs(node.attributes, ctx.toRange(node.loc))(ctx); @@ -1595,7 +1662,7 @@ const parseExtension = } return fn; } - const [first, ...rest] = fn.params; + const [first, ...rest] = fn.type.params; const selfType = (() => { if ( // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition @@ -1610,13 +1677,8 @@ const parseExtension = return first.type; })(); return Ast.Extension( - Ast.Method( - !!isMutates, - false, - false, - undefined, - { ...fn, params: rest } - ), + !!isMutates, + { ...fn, type: { ...fn.type, params: rest } }, selfType, ); }; @@ -1678,9 +1740,11 @@ const parseNativeFunctionDecl = return Ast.Function( !!parseNamedAttr("inline")(attributes)(ctx), parseId(name)(ctx), - map(parseList(typeParams), parseTypeId)(ctx), - returnType ? parseType(returnType)(ctx) : undefined, - map(parseList(parameters), parseParameter)(ctx), + Ast.FnType( + map(parseList(typeParams), parseTypeId)(ctx), + map(parseList(parameters), parseParameter)(ctx), + returnType ? parseType(returnType)(ctx) : undefined, + ), Ast.NativeBody(parseFuncId(nativeName)(ctx)), ctx.toRange(loc), ); @@ -1760,13 +1824,15 @@ const parseTrait = parseTypeId(name)(ctx), traits ? map(parseList(traits), parseTypeId)(ctx) : [], map(attributes, parseContractAttribute)(ctx), - map(declarations, parseLocalItem)(ctx), + parseLocalItems(declarations)(ctx), ctx.toRange(loc), ); }; + +type LocalItem = Ast.FieldDecl | Ast.Receiver | Ast.Method | Ast.FieldConstant const parseLocalItem: ( input: $ast.traitItemDecl, -) => Handler = makeVisitor<$ast.traitItemDecl>()({ +) => Handler = makeVisitor<$ast.traitItemDecl>()({ FieldDecl: parseFieldDecl, Receiver: parseReceiver, Function: parseMethod(parseFunctionRaw), @@ -1774,9 +1840,40 @@ const parseLocalItem: ( Constant: parseFieldConstant, }); +const parseLocalItems = (items: readonly $ast.traitItemDecl[]): Handler => ctx => { + const locals = map(items, parseLocalItem)(ctx); + + const fields: Ast.FieldDecl[] = []; + const methods: Ast.Method[] = []; + const receivers: Ast.Receiver[] = []; + const constants: Ast.FieldConstant[] = []; + + for (const item of locals) { + switch (item.kind) { + case "field_decl": { + fields.push(item); + continue; + } + case "receiver": { + receivers.push(item); + continue; + } + case "method": { + methods.push(item); + continue; + } + case "field_const": { + constants.push(item); + continue; + } + } + } + return { fields, methods, receivers, constants }; +}; + type ModuleItemAux = Exclude<$ast.moduleItem, $ast.PrimitiveTypeDecl>; -const parseModuleItemAux: (input: ModuleItemAux) => Handler = +const parseModuleItemAux: (input: ModuleItemAux) => Handler = makeVisitor()({ Function: parseExtension(parseFunctionRaw), AsmFunction: parseExtension(parseAsmFunctionRaw), @@ -1790,8 +1887,14 @@ const parseModuleItemAux: (input: ModuleItemAux) => Handler = AliasDecl: parseAlias, }); +type ModuleItem = + | Ast.Function + | Ast.Extension + | Ast.Constant + | Ast.TypeDecl + const parseModuleItem = - (node: $ast.moduleItem): Handler => + (node: $ast.moduleItem): Handler => (ctx) => { if (node.$ === "PrimitiveTypeDecl") { ctx.err.deprecatedPrimitiveDecl()(ctx.toRange(node.loc)); @@ -1811,12 +1914,41 @@ const parseImport = ); }; +const splitItems = (items: readonly ModuleItem[]): Ast.ModuleItems => { + const functions: Ast.Function[] = []; + const constants: Ast.Constant[] = []; + const extensions: Ast.Extension[] = []; + const types: Ast.TypeDecl[] = []; + for (const item of items) { + switch (item.kind) { + case "function": + functions.push(item); + continue; + case "extension": + extensions.push(item); + continue; + case "constant": + constants.push(item); + continue; + case "struct_decl": + case "message_decl": + case "union_decl": + case "alias_decl": + case "contract": + case "trait": + types.push(item); + continue; + } + } + return { functions, constants, extensions, types }; +}; + const parseModule = ({ imports, items }: $ast.Module): Handler => (ctx) => { return Ast.Module( map(imports, parseImport)(ctx), - map(items, parseModuleItem)(ctx).flat(), + splitItems(map(items, parseModuleItem)(ctx).flat()), ); }; @@ -1839,7 +1971,12 @@ export const parse = ( start: position, end: position, }); - return Ast.Module([], []); + return Ast.Module([], { + constants: [], + extensions: [], + functions: [], + types: [], + }); } const toRange = (loc: $.Loc): Ast.Range => { diff --git a/src/next/imports/reader.ts b/src/next/imports/reader.ts index c45ba53aa2..bbb4c7902a 100644 --- a/src/next/imports/reader.ts +++ b/src/next/imports/reader.ts @@ -5,7 +5,7 @@ import { getFiles } from "@/next/stdlib"; import type { Cursor } from "@/next/fs"; import type { AnyLogger, Logger, SourceLogger } from "@/error/logger-util"; import type { FuncImport, Implicit, ResolvedImport, TactImport, TactSource } from "@/next/imports/source"; -import type { ModuleItem, Range } from "@/next/ast"; +import type { ModuleItems, Loc } from "@/next/ast"; import { hideProperty } from "@/utils/tricks"; type Options = { @@ -148,19 +148,19 @@ export const ProjectReader = async (log: Logger) => { return { read }; }; -const TactImport = (source: TactSource, loc: Range | Implicit) => { +const TactImport = (source: TactSource, loc: Loc | Implicit) => { const result: TactImport = { kind: "tact", source, loc }; hideProperty(result, 'source'); return result; }; -const FuncImport = (code: string, loc: Range) => { +const FuncImport = (code: string, loc: Loc) => { const result: FuncImport = { kind: "func", code, loc }; hideProperty(result, 'code'); return result; }; -const TactSource = (path: string, code: string, imports: readonly ResolvedImport[], items: readonly ModuleItem[]) => { +const TactSource = (path: string, code: string, imports: readonly ResolvedImport[], items: ModuleItems) => { const result: TactSource = { kind: 'tact', path, code, imports, items }; hideProperty(result, 'code'); return result; diff --git a/src/next/imports/source.ts b/src/next/imports/source.ts index be2aa727a1..e96af2067d 100644 --- a/src/next/imports/source.ts +++ b/src/next/imports/source.ts @@ -1,23 +1,23 @@ -import type { ModuleItem, Range } from "@/next/ast"; +import type { ModuleItems, Loc } from "@/next/ast"; export type TactSource = { readonly kind: "tact"; readonly path: string; readonly code: string; readonly imports: readonly ResolvedImport[]; - readonly items: readonly ModuleItem[]; + readonly items: ModuleItems; }; export type ResolvedImport = TactImport | FuncImport; export type TactImport = { readonly kind: "tact"; readonly source: TactSource; - readonly loc: Range | Implicit; + readonly loc: Loc | Implicit; }; export type FuncImport = { readonly kind: "func"; readonly code: string; - readonly loc: Range; + readonly loc: Loc; }; export type Implicit = { diff --git a/src/next/scoping/errors.ts b/src/next/scoping/errors.ts index 0b52436b7e..af0ff5bb02 100644 --- a/src/next/scoping/errors.ts +++ b/src/next/scoping/errors.ts @@ -1,6 +1,6 @@ import type { SourceLogger } from "@/error/logger-util"; import type { Implicit } from "@/next/imports/source"; -import type { Range } from "@/next/ast"; +import type { Loc } from "@/next/ast"; import type * as Ty from "@/next/scoping/generated/type"; import { printType } from "@/next/scoping/print-type"; @@ -11,7 +11,7 @@ export type MismatchTree = { } export const TcErrors = (l: SourceLogger) => ({ - shadowsImported: (name: string, prevPath: string, prevRange: Range | Implicit) => (loc: Range | Implicit) => { + shadowsImported: (name: string, prevPath: string, prevRange: Loc | Implicit) => (loc: Loc | Implicit) => { if (loc.kind !== 'range') { return l.internal(l.text`Import from standard library cannot shadow anything`); } @@ -20,7 +20,7 @@ export const TcErrors = (l: SourceLogger) => ({ : l.text`from standard library`; return l.at(loc).error(l.text`Declaration of "${name}" shadows previous declaration ${id}`); }, - shadowsBuiltin: (name: string) => (loc: Range | Implicit) => { + shadowsBuiltin: (name: string) => (loc: Loc | Implicit) => { if (loc.kind !== 'range') { return l.internal(l.text`Import from standard library cannot shadow anything`); } diff --git a/src/next/scoping/type.ts b/src/next/scoping/type.ts index 9cf4f026ff..e3d6847ccb 100644 --- a/src/next/scoping/type.ts +++ b/src/next/scoping/type.ts @@ -1,4 +1,4 @@ -import type { Range } from "@/next/ast"; +import type { Loc } from "@/next/ast"; export type TypeId = { readonly kind: "type_id"; @@ -6,7 +6,7 @@ export type TypeId = { readonly loc: Loc; }; -export type Loc = Range | Inferred | Builtin; +export type Loc = Loc | Inferred | Builtin; /** * Type that was computed from AST diff --git a/src/next/scoping/typecheck.ts b/src/next/scoping/typecheck.ts index 373aa66bf2..b1fc0ff402 100644 --- a/src/next/scoping/typecheck.ts +++ b/src/next/scoping/typecheck.ts @@ -1,347 +1,39 @@ +() => E.WithLog + +export type Unifier = ReturnType +export type LocalUnifier = ReturnType + /* eslint-disable @typescript-eslint/no-unnecessary-condition */ /* eslint-disable @typescript-eslint/no-base-to-string */ import { makeVisitor, memo } from "@/utils/tricks"; import type { Logger } from "@/error/logger-util"; import type { Implicit, TactImport, TactSource } from "@/next/imports/source"; import type * as Ast from "@/next/ast"; -import type { Range } from "@/next/ast"; +import type { Loc } from "@/next/ast"; import * as Ty from "@/next/scoping/generated/type"; import { zip } from "@/utils/array"; import { throwInternal } from "@/error/errors"; import { type MismatchTree, TcErrors } from "@/next/scoping/errors"; -export const scope = ( - log: Logger, - root: TactSource, -) => { - return foldSources(root, scopeIds(log)); -}; - -type Handler = (children: [T, TactImport][], source: TactSource) => T - -const foldSources = (root: TactSource, onSource: Handler): T => { - const rec = (source: TactSource): T => { - const children: [T, TactImport][] = []; - for (const imp of source.imports) { - if (imp.kind === 'tact') { - children.push([memoedRec(imp.source), imp]); - } - } - return onSource(children, source); - }; - const memoedRec = memo(rec); - return memoedRec(root); -}; - -type Result = { - // readonly source: TactSource; - // readonly imports: readonly Result[]; - readonly functions: ReadonlyMap; - readonly extensions: ReadonlyMap; - readonly constants: ReadonlyMap; - readonly types: ReadonlyMap; -}; - -type DeclRecord = { - readonly source: TactSource; - readonly entry: T; - readonly loc: Range | Implicit; -} - -type DeclMap = Map>; - -type Registry = { - readonly get: (key: string) => T | undefined; - readonly add: ( - name: string, - entry: T, - nextSource: TactSource, - loc: Range | Implicit, - ) => void; -} - -type TypeExtensionRecord = { - readonly source: TactSource; - readonly self: Ty.LocType; - - readonly mutates: boolean; - readonly fun: Ast.Function; - readonly loc: Range | Implicit; -} - -// type ContractExtensionRecord = { -// readonly source: TactSource; -// readonly self: Ast.Trait | Ast.Contract; - -// readonly fun: Ast.Method; -// readonly loc: Range | Implicit; -// } - -const scopeIds = (log: Logger) => - (children: [Result, TactImport][], source: TactSource): Result => { - const err = log.source(source.path, source.code, (logger) => TcErrors(logger)); - - const makeRegistry = (builtins: Set): Registry => { - const ids: DeclMap = new Map(); - return { - get: (key) => ids.get(key)?.entry, - add: (name, entry, nextSource, loc) => { - const prev = ids.get(name); - if (builtins.has(name)) { - err.shadowsBuiltin(name)(loc); - } else if (typeof prev === 'undefined') { - ids.set(name, { source: nextSource, entry, loc }); - } else if (prev.source !== nextSource) { - err.shadowsImported(name, source.path, prev.loc)(loc); - } - }, - }; - }; - - // method name -> (type -> method) - const typeExt: Map = new Map(); - const findTypeMethod = ( - methodName: string, - selfType: Ty.LocType, - ): undefined | TypeExtensionRecord => { - const methodReg = typeExt.get(methodName); - if (typeof methodReg === 'undefined') { - return undefined; - } - for (const reg of methodReg) { - resolveOverload(reg.self, selfType) - } - }; - - // left: Either - // left: Int - // left: Maybe - // left: Slice - - // isGround = нет типовых переменных: Either - // isSimple = Cons : Either - // isGround || isSimple - // extends fun foo(self: Either) {} - // extends fun foo(self: Either) {} - // fun bar() { let e: Either = ...; e.foo() } - - // extends fun foo(self: T); - // extends fun foo(self: Either); - // let x: Either; - // x.foo(); - // findTypeMethod("foo", Either); - - // const contractExt: Map = new Map(); - - const functions = makeRegistry(new Set()); - const constants = makeRegistry(new Set()); - const types = makeRegistry(new Set([ - "void", - "bounced", - "Null", - "Maybe", - "Int", - "Bool", - "Builder", - "Slice", - "Cell", - "Address", - "String", - "StringBuilder", - ])); - - for (const [sources, imp] of children) { - for (const [name, [entry, source]] of sources.functions) { - functions.add(name, entry, source, imp.loc); - } - // for (const [name, [entry, source]] of sources.extensions) { - // extensions.add(name, entry, source, imp.loc); - // } - for (const [name, [entry, source]] of sources.constants) { - constants.add(name, entry, source, imp.loc); - } - for (const [name, [entry, source]] of sources.types) { - types.add(name, entry, source, imp.loc); - } - } +// left: Either +// left: Int +// left: Maybe +// left: Slice - for (const item of source.items) { - switch (item.kind) { - case "function": { - functions.add(item.name.text, item, source, item.name.loc); - continue; - } - case "constant": { - constants.add(item.name.text, item, source, item.name.loc); - continue; - } - case "extension": { - // handled below - continue; - } - case "struct_decl": - case "message_decl": - case "union_decl": - case "alias_decl": - case "contract": - case "trait": { - types.add(item.name.text, item, source, item.name.loc); - continue; - } - } - } +// isGround = нет типовых переменных: Either +// isSimple = Cons : Either +// isGround || isSimple +// extends fun foo(self: Either) {} +// extends fun foo(self: Either) {} +// fun bar() { let e: Either = ...; e.foo() } - for (const item of source.items) { - switch (item.kind) { - case "extension": { - const id = item.method.fun.name; - extensions.add(id.text, item, source, id.loc); - continue; - } - case "contract": - case "trait": { - continue; - } - case "function": - case "constant": - case "struct_decl": - case "message_decl": - case "union_decl": - case "alias_decl": { - continue; - } - } - } +// extends fun foo(self: T); +// extends fun foo(self: Either); +// let x: Either; +// x.foo(); +// findTypeMethod("foo", Either); - for (const item of source.items) { - checkItem(types.get, err, item); - } - - return { - functions: functions.get(), - constants: constants.get(), - types: types.get(), - extensions: extensions.get(), - }; - }; - -type Spine = SpineCons | SpineVar -type SpineCons = { - readonly kind: 'cons'; - readonly name: string; - readonly children: readonly Spine[]; -} -const SpineCons = (name: string, children: readonly Spine[]): SpineCons => ({ kind: 'cons', name, children }); -type SpineVar = { - readonly kind: 'var'; - readonly id: number; -} -const SpineVar = (id: number): SpineVar => ({ kind: 'var', id }); - -const getSpine = (type: Ty.Type): undefined | Spine => { - switch (type.kind) { - case "map_type": { - const key = getSpine(type.key); - const value = getSpine(type.value); - if (!key || !value) return undefined; - return SpineCons("map", [key, value]); - } - case "cons_type": { - const children: Spine[] = []; - for (const arg of type.typeArgs) { - const spine = getSpine(arg); - if (spine) { - children.push(spine); - } else { - return undefined; - } - } - return SpineCons(type.name.text, children); - } - case "TyInt": return SpineCons("Int", []); - case "TySlice": return SpineCons("Slice", []); - case "TyCell": return SpineCons("Cell", []); - case "TyBuilder": return SpineCons("Builder", []); - case "type_var": return SpineVar(type.id); - case "tuple_type": - case "unit_type": - case "tensor_type": - case "ERROR": { - return undefined; - } - } -}; - -const noTypeParams = () => false; - -const checkItem = ( - getType: (key: string) => Ast.TypeDecl | undefined, - err: TcErrors, - node: Ast.ModuleItem, -) => { - // TODO: check kinds - // TODO: Check if self is initialized - // TODO: map key should be serializable without refs - switch (node.kind) { - case "constant": { - const { init } = node; - if (init.kind === 'constant_def') { - const { checkExpr, assignTo } = getExprChecker( - getType, - noTypeParams, - err, - ); - const exprType = checkExpr(init.initializer); - if (init.type) { - const res = assignTo(init.type, exprType); - } - return; - } else { - // ... - return; - } - } - case "function": { - // TODO: check return value - // foo(x: Int): Int { if (x == 42) return 43; } - return; - } - case "extension": { - return; - } - case "struct_decl": { - return; - } - case "message_decl": { - return; - } - case "union_decl": { - return; - } - case "alias_decl": { - return; - } - case "contract": { - // check all contract fields are initialized - return; - } - case "trait": { - return; - } - } -}; - -const Int257 = (loc: Ty.Loc) => Ty.TypeInt(Ty.IFInt("signed", 257, loc), loc); -const String = (loc: Ty.Loc) => Ty.TypeCons(Ty.TypeId("String", loc), [], loc); -const Bool = (loc: Ty.Loc) => Ty.TypeCons(Ty.TypeId("Bool", loc), [], loc); -const Cell = (loc: Ty.Loc) => Ty.TypeCons(Ty.TypeId("Cell", loc), [], loc); -const Slice = (loc: Ty.Loc) => Ty.TypeCons(Ty.TypeId("Slice", loc), [], loc); -const StateInit = (loc: Ty.Loc) => Ty.TypeCons(Ty.TypeId("StateInit", loc), [], loc); -const Maybe = (param: Ty.Type, loc: Ty.Loc) => Ty.TypeCons(Ty.TypeId("Maybe", loc), [param], loc); -const Null = (loc: Ty.Loc) => Ty.TypeCons(Ty.TypeId("Null", loc), [], loc); -const Unit = (loc: Ty.Loc) => Ty.TypeTensor([], loc); +// const contractExt: Map = new Map(); const isNull = (type: Ty.LocType) => type.kind === 'cons_type' && type.name.text === 'Null'; @@ -1042,4 +734,379 @@ const substParam = (into: Ty.Type, param: string, value: Ty.Type): Ty.Type => { }; return rec(into); -}; \ No newline at end of file +}; + +// import { throwInternal } from "@/error/errors"; +// import * as Ast from "@/next/ast"; +// import * as E from "@/next/types/errors"; +// import type { Registry } from "@/next/types/merger"; +// import type { TypeEntry } from "@/next/types/typecheck"; + +// export const decodeType = ( +// userTypes: Registry, +// typeParams: readonly Ast.TypeId[], +// type: Ast.Type, +// ): E.WithLog => { +// function* recN( +// types: readonly Ast.Type[], +// ): E.WithLog { +// const results: Ast.Type[] = []; +// for (const type of types) { +// const result = yield* rec(type); +// if (result) { +// results.push(result); +// } else { +// return undefined +// } +// } +// return results; +// } + +// function* rec( +// type: Ast.Type, +// ): E.WithLog { +// switch (type.kind) { +// case "unit_type": +// case "TyInt": +// case "TySlice": +// case "TyCell": +// case "TyBuilder": +// case "TypeVoid": +// case "TypeNull": +// case "TypeBool": +// case "TypeAddress": +// case "TypeString": +// case "TypeStringBuilder": +// case "TypeParam": { +// return type; +// } +// case "tuple_type": { +// const result = yield* recN(type.typeArgs); +// return result && Ast.TypeTuple(result, type.loc); +// } +// case "tensor_type": { +// const result = yield* recN(type.typeArgs); +// return result && Ast.TypeTensor(result, type.loc); +// } +// case "map_type": { +// const key = yield* rec(type.key); +// const value = yield* rec(type.value); +// if (!key || !value) { +// return undefined; +// } +// return Ast.TypeMap(key, value, type.loc); +// } +// case "TypeBounced": { +// const child = yield* rec(type.type); +// if (!child) { +// return undefined; +// } +// return Ast.TypeBounced(child, type.loc); +// } +// case "TypeMaybe": { +// const child = yield* rec(type.type); +// if (!child) { +// return undefined; +// } +// return Ast.TypeMaybe(child, type.loc); +// } +// case "TypeAlias": { +// return throwInternal("Alias references are never generated in parser"); +// } +// case "cons_type": { +// const name = type.name.text; +// const arity = type.typeArgs.length; + +// const args = yield* recN(type.typeArgs); + +// const param = typeParams.find(p => p.text); +// if (param) { +// if (!(yield* matchArity(name, arity, 0, type.loc))) { +// return undefined; +// } +// return Ast.TypeParam( +// type.name, +// type.loc, +// ); +// } + +// if (!args) { +// return undefined; +// } + +// const typeEntry = userTypes.get(name); +// if (typeEntry) { +// if (!(yield* matchArity( +// name, +// arity, +// typeEntry.value.arity, +// type.loc, +// ))) { +// return undefined; +// } +// const decl = typeEntry.value.type; +// switch (decl.kind) { +// case "FlatAlias": { +// return ; +// } +// case "alias_decl": { +// return; +// } +// case "FlatContract": +// case "FlatTrait": +// case "struct_decl": +// case "message_decl": +// case "union_decl": +// case "contract": +// case "trait": { +// return Ast.TypeCons(type.name, args, type.loc); +// } +// } +// } + +// yield ETypeNotFound(name, type.loc); +// return undefined; +// } +// } +// } + +// return rec(type); +// } + +// export const ETypeNotFound = ( +// name: string, +// loc: Ast.Range, +// ): E.TcError => ({ +// loc, +// descr: [ +// E.TEText(`Type "${name}" is not defined`), +// ], +// }); +// export const EContractTraitType = ( +// kind: string, +// name: string, +// loc: Ast.Range, +// ): E.TcError => ({ +// loc, +// descr: [ +// E.TEText(`Cannot use ${kind} ${name} as a type`), +// ], +// }); + + +// export function* matchArity( +// name: string, +// got: number, +// expected: number, +// loc: Ast.Range, +// ): E.WithLog { +// const result = got === expected; +// if (!result) { +// yield EArity(name, expected, got, loc); +// } +// return result; +// } +// export const EArity = ( +// name: string, +// expected: number, +// got: number, +// loc: Ast.Range, +// ): E.TcError => ({ +// loc, +// descr: [ +// E.TEText(`Type "${name}" is expected to have ${expected} type arguments, got ${got}`), +// ], +// }); + +// import * as V from "@/next/types/via"; +// import * as E from "@/next/types/errors"; +// import type * as Ast from "@/next/ast"; +// import type { TactImport, TactSource } from "@/next/imports/source"; +// import type { FlatDecl, Schema } from "@/next/types/flat"; + +// export type Def = { +// // the definition +// readonly value: T; +// // where it was defined +// readonly via: V.ViaUser; +// } +// export const Def = (value: T, via: V.ViaUser): Def => ({ value, via }); +// export const importDef = (importedBy: TactImport, { value, via }: Def): Def => Def(value, V.ViaImport(importedBy, via)); + +// export type Registry = Map>; + +// export type StructMethod = { +// readonly mutates: boolean; +// readonly fun: Ast.Function; +// } + +// export type TypeMap = readonly (readonly [Schema, Def])[] + +// export type ExtRegistry = Map + +// export type Scope = { +// readonly types: Registry; +// readonly functions: Registry; +// readonly constants: Registry; +// readonly extensions: ExtRegistry; +// } + +// export type SourceCheckResult = { +// // import that lead to reading this file +// readonly importedBy: TactImport; +// // scopes that were computed from this file +// readonly globals: Scope; +// } + +// export function* mergeExt( +// results: readonly SourceCheckResult[], +// source: TactSource, +// items: Ast.Extension[], +// builtins: ReadonlyMap, +// ): E.WithLog { +// const EMethodOverlap = ( +// name: string, +// prev: V.Via, +// next: V.ViaUser, +// ): E.TcError => ({ +// loc: E.viaToRange(next), +// descr: [ +// E.TEText(`Method "${name}" overlaps previously defined method`), +// E.TEVia(prev), +// ], +// }); + +// const imported: ExtRegistry[] = results.map(({ globals, importedBy }) => { +// const exts = globals.extensions; +// return new Map(exts.entries().map(([k, v]) => { +// return [k, v.map(([k, v]) => [k, { +// value: v.value, +// via: V.ViaImport(importedBy, v.via), +// }])]; +// })); +// }); + +// const local: ExtRegistry[] = []; +// for (const item of items) { +// const fun = item.method.fun; +// const schema = { +// typeArgs: fun.typeParams, +// type: item.selfType, +// }; +// const def = { +// value: item.method, +// via: V.ViaOrigin(fun.loc, source), +// }; +// const { canExtend } = unifier.withParams(fun.typeParams); +// if (yield* canExtend(item.selfType)) { +// local.push(new Map([[fun.name.text, [[schema, def]]]])); +// } +// } + +// const all = [...imported, ...local]; + +// const prev: Map])[]> = new Map(); +// for (const next of all) { +// for (const [name, nextMap] of next) { +// const prevMap = [...prev.get(name) ?? []]; +// const builtin = builtins.get(name) ?? []; +// for (const [nextSchema, nextDef] of nextMap) { +// // defined in compiler +// const prevBuiltin = builtin.find(prevSchema => !unifier.areOrdered( +// prevSchema, nextSchema +// )); +// if (prevBuiltin) { +// yield EMethodOverlap(name, V.ViaBuiltin(), nextDef.via); +// continue; +// } +// const prevEntry = prevMap.find(([prevSchema]) => !unifier.areOrdered( +// prevSchema, nextSchema +// )); +// // not defined yet; define it now +// if (!prevEntry) { +// prevMap.push([nextSchema, nextDef]); +// continue; +// } +// const [, prevDef] = prevEntry; +// // already defined, and it's not a diamond situation +// if (prevDef.via.source !== nextDef.via.source) { +// yield EMethodOverlap(name, prevDef.via, nextDef.via); +// } +// } +// prev.set(name, prevMap); +// } +// } +// return prev; +// } + +// export function* merge( +// results: readonly SourceCheckResult[], +// source: TactSource, +// kind: string, +// get1: (s: Scope) => Registry, +// items: T[], +// builtin: Map, +// ): E.WithLog> { +// const imported = results.map(({ globals, importedBy }) => ( +// mapRegVia(get1(globals), importedBy) +// )); +// const local = items.map((item) => createRef( +// item.name.text, +// item, +// V.ViaOrigin(item.loc, source), +// )); +// return yield* concatReg( +// builtin, +// kind, +// [...imported, ...local], +// ) +// } + +// export const createRef = (name: string, value: V, via: V.ViaUser): Registry => { +// return new Map([[name, { value, via }]]); +// }; + +// export const mapRegVia = (fns: Registry, importedBy: TactImport): Registry => { +// return new Map(fns.entries().map(([k, v]) => { +// return [k, { +// value: v.value, +// via: V.ViaImport(importedBy, v.via), +// }]; +// })); +// }; + +// export function* concatReg( +// builtins: Map, +// kind: string, +// all: readonly Registry[] +// ): E.WithLog> { +// const ERedefine = (kind: string, name: string, prev: V.Via, next: V.ViaUser): E.TcError => ({ +// loc: E.viaToRange(next), +// descr: [ +// E.TEText(`There already is a ${kind} "${name}" from`), +// E.TEVia(prev), +// ], +// }); + +// const prev: Map> = new Map(); +// for (const next of all) { +// for (const [name, nextItem] of next) { +// const prevItem = prev.get(name); +// // defined in compiler +// if (builtins.has(name)) { +// yield ERedefine(kind, name, V.ViaBuiltin(), nextItem.via); +// continue; +// } +// // not defined yet; define it now +// if (typeof prevItem === 'undefined') { +// prev.set(name, nextItem); +// continue; +// } +// // already defined, and it's not a diamond situation +// if (prevItem.via.source !== nextItem.via.source) { +// yield ERedefine(kind, name, prevItem.via, nextItem.via); +// } +// } +// } +// return prev; +// } diff --git a/src/next/types/builtins.ts b/src/next/types/builtins.ts new file mode 100644 index 0000000000..2d03e01342 --- /dev/null +++ b/src/next/types/builtins.ts @@ -0,0 +1,180 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ + +import * as Ast from "@/next/ast"; + +const r = Ast.Builtin(); + +const Param = (name: string, type: Ast.DecodedType) => { + return Ast.MTypedParameter( + Ast.Id(name, r), + type, + r, + ); +}; + +const t = Ast.TypeId("T", r); +const tParam = Ast.DTypeParamRef(t, r); + +const k = Ast.TypeId("K", r); +const kParam = Ast.DTypeParamRef(k, r); +const key = Param("key", kParam); + +const v = Ast.TypeId("V", r); +const vParam = Ast.DTypeParamRef(v, r); +const value = Param("value", vParam); + +const mapType = Ast.MVTypeMap(kParam, vParam, r); + +const GenericFn = (name: string, typeParams: readonly Ast.TypeId[], args: readonly Ast.MTypedParameter[], returnType: Ast.DecodedType): [string, Ast.MFnType] => { + return [name, Ast.MFnType(typeParams, args, returnType)]; +}; +const Fn = (name: string, args: readonly Ast.MTypedParameter[], returnType: Ast.DecodedType): [string, Ast.MFnType] => { + return [name, Ast.MFnType([], args, returnType)]; +}; +const MapMethod = (name: string, args: readonly Ast.MTypedParameter[], returnType: Ast.DecodedType): [string, Ast.MMethodFnType] => { + return [name, Ast.MMethodFnType( + [k, v], + mapType, + args, + returnType, + )]; +}; + +export const Int = Ast.TypeInt(Ast.IFInt("signed", 257, r), r); +export const Slice = Ast.TypeSlice(Ast.SFDefault(r), r); +export const Cell = Ast.TypeCell(Ast.SFDefault(r), r); +export const Builder = Ast.TypeBuilder(Ast.SFDefault(r), r); +export const Void = Ast.TypeVoid(r); +export const Null = Ast.TypeNull(r); +export const Bool = Ast.TypeBool(r); +export const Address = Ast.TypeAddress(r); +export const String = Ast.TypeString(r); +export const StringBuilder = Ast.TypeStringBuilder(r); +export const MapType = (k: Ast.DecodedType, v: Ast.DecodedType) => Ast.DTypeMap(k, v, r); +export const Maybe = (t: Ast.DecodedType) => Ast.DTypeMaybe(t, r) +export const Unit = Ast.TypeUnit(r); +export const StateInit = Ast.TypeCons(Ast.TypeId("StateInit", r), [], r); + +export const builtinTypes = new Map([ + "Int", "Slice", "Cell", "Builder", "Void", "Null", "Bool", + "Address", "String", "StringBuilder", "Map", "Maybe" +].map(s => [s, s])); + +const ArithBin = (name: string) => { + return Fn(name, [Param("left", Int), Param("right", Int)], Int); +}; +const CompBin = (name: string) => { + return Fn(name, [Param("left", Int), Param("right", Int)], Bool); +}; +const BoolBin = (name: string) => { + return Fn(name, [Param("left", Bool), Param("right", Bool)], Bool); +}; +const EqBin = (name: string) => { + return GenericFn(name, [t], [Param("left", tParam), Param("right", tParam)], Bool); +}; + +export const builtinFunctions: Map = new Map([ + // dump(arg: T): Void + GenericFn("dump", [t], [Param("data", tParam)], Void), + // ton(value: String): Int + Fn("ton", [Param("value", String)], Int), + // require(that: Bool, msg: String): Void + Fn("require", [Param("that", Bool), Param("msg", String)], Void), + // address(s: String): Address + Fn("address", [Param("s", String)], Address), + // cell(bocBase64: String): Cell + Fn("cell", [Param("bocBase64", String)], Cell), + // dumpStack(): Void + Fn("dumpStack", [], Void), + // emptyMap(): map + GenericFn("emptyMap", [k, v], [], mapType), + // slice(bocBase64: String): Slice + Fn("slice", [Param("bocBase64", String)], Slice), + // rawSlice(hex: String): Slice + Fn("rawSlice", [Param("hex", String)], Slice), + // ascii(str: String): Int + Fn("ascii", [Param("str", String)], Int), + // crc32(str: String): Int + Fn("crc32", [Param("str", String)], Int), + // sha256(data: Slice): Int + Fn("sha256", [Param("str", Slice)], Int), +]); + +export const builtinMethods: Map = new Map([ + // set(key: K, value: V): void + MapMethod("set", [key, value], Void), + // get(key: K): Maybe + MapMethod("get", [key], Maybe(vParam)), + // del(key: K): Bool + MapMethod("del", [key], Bool), + // asCell(): Maybe + MapMethod("asCell", [], Maybe(Cell)), + // isEmpty(): Bool + MapMethod("isEmpty", [], Bool), + // exists(key: K): Bool + MapMethod("exists", [key], Bool), + // deepEquals(other: map): Bool + MapMethod("deepEquals", [Param("other", mapType)], Bool), + // replace(key: K, value: V): Bool + MapMethod("replace", [key, value], Bool), + // replaceGet(key: K, value: V): map + MapMethod("replaceGet", [key, value], mapType), +]); + +export const builtinUnary: Map = new Map([ + Fn("+", [Param("arg", Int)], Int), + Fn("-", [Param("arg", Int)], Int), + Fn("~", [Param("arg", Int)], Int), + Fn("!", [Param("arg", Bool)], Bool), + GenericFn("!!", [t], [Param("arg", Maybe(tParam))], tParam), +]); + +export const builtinBinary: Map = new Map([ + // (left: Int, right: Int): Int + ArithBin("+"), + ArithBin("-"), + ArithBin("*"), + ArithBin("/"), + ArithBin("%"), + ArithBin("<<"), + ArithBin(">>"), + ArithBin("&"), + ArithBin("|"), + ArithBin("^"), + // (left: Int, right: Int): Bool + CompBin(">"), + CompBin("<"), + CompBin(">="), + CompBin("<="), + // (left: T, right: T): Bool + EqBin("=="), + EqBin("!="), + // (left: Bool, right: Bool): Bool + BoolBin("&&"), + BoolBin("||"), +]); + +export const getStaticBuiltin = (type: Ast.DecodedType): Map => { + return new Map([ + // Foo.fromSlice(slice: Slice) + Fn("fromSlice", [Param("slice", Slice)], type), + // Foo.fromSlice(cell: Cell) + Fn("fromCell", [Param("cell", Cell)], type), + ]) +}; + +export const structBuiltin = new Map([ + // Foo.toSlice(): Slice + Fn("toSlice", [], Slice), + // Foo.toCell(): Cell + Fn("toCell", [], Cell), +]); + +export const messageBuiltin = new Map([ + // Foo.toSlice(): Slice + Fn("toSlice", [], Slice), + // Foo.toCell(): Cell + Fn("toCell", [], Cell), + // Foo.opcode(): Int + Fn("opcode", [], Int) +]); diff --git a/src/next/types/error-dsl.ts b/src/next/types/error-dsl.ts deleted file mode 100644 index 547b80033b..0000000000 --- a/src/next/types/error-dsl.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { throwInternal } from "@/error/errors"; -import type { Range } from "@/next/ast"; -import type * as V from "@/next/types/via"; - -export type TcError = { - // location where IDE should show this error - readonly loc: Range; - // text description - readonly descr: readonly TELine[]; -} - -export type TELine = TEText | TEVia; - -export type TEText = { - readonly kind: 'text'; - readonly text: string; -} - -export const TEText = (text: string): TEText => ({ kind: 'text', text }); - -export type TEVia = { - readonly kind: 'via'; - readonly via: V.Via; -} - -export const TEVia = (via: V.Via): TEVia => ({ kind: 'via', via }); - -export const viaToRange = ({ imports, defLoc: definedAt }: V.ViaUser): Range => { - const [head] = imports; - if (typeof head === 'undefined') { - return definedAt; - } - const { loc } = head; - if (loc.kind === 'range') { - return loc; - } - return throwInternal("Implicit import shadows something. Duplicates in stdlib?"); -}; diff --git a/src/next/types/errors.ts b/src/next/types/errors.ts index 99e2692cd2..5128ee1557 100644 --- a/src/next/types/errors.ts +++ b/src/next/types/errors.ts @@ -1,15 +1,59 @@ -import * as E from "@/next/types/error-dsl"; -import type * as W from "@/next/types/writer"; +import { throwInternal } from "@/error/errors"; +import type { Loc } from "@/next/ast"; import type * as V from "@/next/types/via"; -export * from "@/next/types/error-dsl"; +export type WithLog = Generator -export type WithLog = W.Writer; +export function runLog(gen: Generator): readonly [R, readonly T[]] { + const yields: T[] = []; + for (;;) { + const result = gen.next(); + if (result.done) { + return [result.value, yields]; + } else { + yields.push(result.value); + } + } +} -export const ERedefineFn = (name: string, prev: V.Via, next: V.ViaUser): E.TcError => ({ - loc: E.viaToRange(next), - descr: [ - E.TEText(`There already is a function "${name}" from`), - E.TEVia(prev), - ], -}); \ No newline at end of file +export type TcError = { + // location where IDE should show this error + readonly loc: Loc; + // text description + readonly descr: readonly TELine[]; +} + +export type TELine = TEText | TEVia | TECode; + +export type TEText = { + readonly kind: 'text'; + readonly text: string; +} + +export const TEText = (text: string): TEText => ({ kind: 'text', text }); + +export type TEVia = { + readonly kind: 'via'; + readonly via: V.Via; +} + +export const TEVia = (via: V.Via): TEVia => ({ kind: 'via', via }); + +export type TECode = { + readonly kind: 'code'; + readonly loc: Loc; +} + +export const TECode = (loc: Loc): TECode => ({ kind: 'code', loc }); + +export const viaToRange = ({ imports, defLoc: definedAt }: V.ViaUser): Loc => { + const [head] = imports; + if (typeof head === 'undefined') { + return definedAt; + } + const { loc } = head; + if (loc.kind === 'range') { + return loc; + } + return throwInternal("Implicit import shadows something. Duplicates in stdlib?"); +}; diff --git a/src/next/types/flat.ts b/src/next/types/flat.ts new file mode 100644 index 0000000000..f1df87aed2 --- /dev/null +++ b/src/next/types/flat.ts @@ -0,0 +1,124 @@ +import type * as Ast from "@/next/ast"; +import type { TactImport } from "@/next/imports/source"; +import * as V from "@/next/types/via"; + +export type Scope = { + readonly types: Registry; + readonly functions: Registry; + readonly constants: Registry; + readonly extensions: ExtRegistry; +} + +export type Registry = Map>; + +export type Def = { + // the definition + readonly value: T; + // where it was defined + readonly via: V.ViaUser; +} +export const Def = (value: T, via: V.ViaUser): Def => ({ value, via }); +export const importDef = (importedBy: TactImport, { value, via }: Def): Def => Def(value, V.ViaImport(importedBy, via)); + +export type ExtRegistry = Map + +export type ExtEntry = { + readonly self: Ast.SelfType; + readonly typeParams: readonly Ast.TypeId[]; + readonly mutates: boolean; + readonly fun: Ast.Function; + readonly via: V.ViaUser; +} + +export type FlatDecl = + | InvalidDecl + | FlatAlias + | FlatContract + | FlatTrait + | Ast.StructDecl + | Ast.MessageDecl + | Ast.UnionDecl; + +export type InvalidDecl = { + readonly kind: 'InvalidDecl'; + readonly name: Ast.TypeId; + readonly arity: number; + readonly loc: Ast.Loc; +} +export const InvalidDecl = ( + name: Ast.TypeId, + arity: number, + loc: Ast.Loc, +): InvalidDecl => ({ kind: 'InvalidDecl', name, arity, loc }); + +export type FlatAlias = { + readonly kind: 'FlatAlias'; + readonly name: Ast.TypeId; + readonly typeParams: readonly Ast.TypeId[]; + readonly type: Ast.DecodedType; + readonly loc: Ast.Loc; +} +export const FlatAlias = ( + name: Ast.TypeId, + typeParams: readonly Ast.TypeId[], + type: Ast.DecodedType, + loc: Ast.Loc, +): FlatAlias => ({ kind: 'FlatAlias', name, type, typeParams, loc }); + +export type Schema = { + readonly typeArgs: readonly Ast.TypeId[]; + readonly type: Ast.DecodedType; +} + +export type FlatContent = { + readonly name: Ast.TypeId; + readonly attributes: readonly Ast.ContractAttribute[]; + readonly declarations: Ast.LocalItems; + readonly loc: Ast.Loc; +}; +export const FlatContent = ( + name: Ast.TypeId, + attributes: readonly Ast.ContractAttribute[], + declarations: Ast.LocalItems, + loc: Ast.Loc, +): FlatContent => ({ attributes, declarations, name, loc }); + +export type FlatContract = { + readonly kind: 'FlatContract'; + readonly init: undefined | Ast.Init; + readonly content: FlatContent; +}; +export const FlatContract = ( + init: undefined | Ast.Init, + content: FlatContent, +): FlatContract => ({ kind: 'FlatContract', content, init }); + +export type FlatTrait = { + readonly kind: 'FlatTrait'; + readonly content: FlatContent; +}; +export const FlatTrait = (content: FlatContent): FlatTrait => ({ kind: 'FlatTrait', content }); + +export type FlatItems = { + readonly fields: readonly Ast.FieldDecl[]; + readonly methods: readonly FlatMethod[]; + readonly receivers: readonly Ast.Receiver[]; + readonly constants: readonly Ast.Constant[]; +}; +export const FlatItems = ( + fields: readonly Ast.FieldDecl[], + methods: readonly FlatMethod[], + receivers: readonly Ast.Receiver[], + constants: readonly Ast.Constant[], +): FlatItems => ({ constants, fields, methods, receivers }); + +export type FlatMethod = { + readonly mutates: boolean; + readonly fun: Ast.Function; + readonly get: undefined | Ast.GetAttribute; +}; +export const FlatMethod = ( + mutates: boolean, + fun: Ast.Function, + get: undefined | Ast.GetAttribute, +): FlatMethod => ({ fun, get, mutates }); diff --git a/src/next/types/functions.ts b/src/next/types/functions.ts deleted file mode 100644 index fbfbada0eb..0000000000 --- a/src/next/types/functions.ts +++ /dev/null @@ -1,87 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unused-vars */ -import * as W from "@/next/types/writer"; -import * as V from "@/next/types/via"; -import * as E from "@/next/types/errors"; -import type * as Ast from "@/next/ast"; -import type { Registry } from "@/next/types/registry"; - -// FIXME -const Fn = (xs: 1[], x: 1) => 1; -const TVar = (x: string) => 1 as const; -const String = 1; -const Void = 1; -const Int = 1; -const Bool = 1; -const Address = 1; -const Cell = 1; -const Null = 1; -const Slice = 1; - -const builtins = new Map([ - ["dump", Fn([TVar("T")], Void)], - ["ton", Fn([String], Int)], - ["require", Fn([Bool, String], Void)], - ["address", Fn([String], Address)], - ["cell", Fn([String], Cell)], - ["dumpStack", Fn([], Void)], - ["emptyMap", Fn([], Null)], - // ["sha256", Overload([ - // Fn([String], Int), - // Fn([Slice], Int), - // ])], - ["slice", Fn([String], Slice)], - ["rawSlice", Fn([String], Slice)], - ["ascii", Fn([String], Int)], - ["crc32", Fn([String], Int)], -]); - -export type Functions = undefined | ReadonlyMap; - -const empty = (): Functions => undefined; - -const create = (name: string, value: Ast.Function, via: V.ViaUser): Functions => { - return new Map([[name, { value, via }]]); -}; - -const mapVia = (fns: Functions, cb: (via: V.ViaUser) => V.ViaUser): Functions => { - if (!fns) return; - return new Map(fns.entries().map(([k, v]) => { - return [k, { value: v.value, via: cb(v.via) }]; - })); -}; - -const append = (prev: Functions, next: Functions): E.WithLog => { - if (!prev || !next) return W.pureLog(next); - const value = new Map(prev.entries()); - const errors: E.TcError[] = []; - for (const [name, nextItem] of next) { - const prevItem = value.get(name); - // defined in compiler - if (builtins.has(name)) { - errors.push(E.ERedefineFn(name, V.ViaBuiltin(), nextItem.via)); - continue; - } - // not defined yet; define it now - if (typeof prevItem === 'undefined') { - value.set(name, nextItem); - continue; - } - // already defined, and it's not a diamond situation - if (prevItem.via.source !== nextItem.via.source) { - errors.push(E.ERedefineFn(name, prevItem.via, nextItem.via)); - } - } - return W.makeLog(value, errors); -}; - -export const Functions: Registry = { - empty, - create, - mapVia, - append, -}; \ No newline at end of file diff --git a/src/next/types/registry.ts b/src/next/types/registry.ts deleted file mode 100644 index c5e1dd61e7..0000000000 --- a/src/next/types/registry.ts +++ /dev/null @@ -1,9 +0,0 @@ -import type * as V from "@/next/types/via"; -import type * as E from "@/next/types/errors"; - -export interface Registry { - empty(): Reg; - create(key: Key, value: Val, via: V.ViaUser): Reg; - mapVia(fns: Reg, cb: (via: V.ViaUser) => V.ViaUser): Reg; - append(prev: Reg, next: Reg): E.WithLog; -} diff --git a/src/next/types/type-decls.ts b/src/next/types/type-decls.ts deleted file mode 100644 index 327e71cab0..0000000000 --- a/src/next/types/type-decls.ts +++ /dev/null @@ -1,72 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unused-vars */ -import * as W from "@/next/types/writer"; -import * as V from "@/next/types/via"; -import * as E from "@/next/types/errors"; -import type * as Ast from "@/next/ast"; -import type { Registry } from "@/next/types/registry"; - -const builtins = new Map([ - ["void", 1], - ["bounced", 1], - ["Null", 1], - ["Maybe", 1], - ["Int", 1], - ["Bool", 1], - ["Builder", 1], - ["Slice", 1], - ["Cell", 1], - ["Address", 1], - ["String", 1], - ["StringBuilder", 1], -]); - -export type TypeDecls = undefined | ReadonlyMap; - -const empty = (): TypeDecls => undefined; - -const create = (name: string, value: Ast.TypeDecl, via: V.ViaUser): TypeDecls => { - return new Map([[name, { value, via }]]); -}; - -const mapVia = (fns: TypeDecls, cb: (via: V.ViaUser) => V.ViaUser): TypeDecls => { - if (!fns) return; - return new Map(fns.entries().map(([k, v]) => { - return [k, { value: v.value, via: cb(v.via) }]; - })); -}; - -const append = (prev: TypeDecls, next: TypeDecls): E.WithLog => { - if (!prev || !next) return W.pureLog(next); - const value = new Map(prev.entries()); - const errors: E.TcError[] = []; - for (const [name, nextItem] of next) { - const prevItem = value.get(name); - // defined in compiler - if (builtins.has(name)) { - errors.push(E.ERedefineFn(name, V.ViaBuiltin(), nextItem.via)); - continue; - } - // not defined yet; define it now - if (typeof prevItem === 'undefined') { - value.set(name, nextItem); - continue; - } - // already defined, and it's not a diamond situation - if (prevItem.via.source !== nextItem.via.source) { - errors.push(E.ERedefineFn(name, prevItem.via, nextItem.via)); - } - } - return W.makeLog(value, errors); -}; - -export const TypeDecls: Registry = { - empty, - create, - mapVia, - append, -}; \ No newline at end of file diff --git a/src/next/types/typecheck.ts b/src/next/types/typecheck.ts index 0c245ee2a9..00317fdce3 100644 --- a/src/next/types/typecheck.ts +++ b/src/next/types/typecheck.ts @@ -1,36 +1,56 @@ +/* eslint-disable @typescript-eslint/consistent-type-imports */ /* eslint-disable @typescript-eslint/no-unused-vars */ -import type { ResolvedImport, TactImport, TactSource } from "@/next/imports/source"; -import { memo } from "@/utils/tricks"; -import type * as Ast from "@/next/ast"; -import * as W from "@/next/types/writer"; +/* eslint-disable require-yield */ import * as V from "@/next/types/via"; -import type * as E from "@/next/types/errors"; +import * as E from "@/next/types/errors"; +import * as Ast from "@/next/ast"; +import { memo } from "@/utils/tricks"; +import type { ResolvedImport, TactImport, TactSource } from "@/next/imports/source"; +// import { logDeep } from "@/utils/log-deep.build"; +import { builtinFunctions, builtinMethods, builtinTypes } from "@/next/types/builtins"; +import { Def, ExtEntry, ExtRegistry, FlatAlias, FlatDecl, InvalidDecl, Registry, Scope } from "@/next/types/flat"; import { throwInternal } from "@/error/errors"; -import { logDeep } from "@/utils/log-deep.build"; -import { Functions } from "@/next/types/functions"; -import { TypeDecls } from "@/next/types/type-decls"; - -export const typecheck = (root: TactSource): E.WithLog => { - const errors: E.TcError[] = []; - const recur = (source: TactSource): Scope => { - const result = tcSource( +import { zip } from "@/utils/array"; + +export type SourceCheckResult = { + // import that lead to reading this file + readonly importedBy: TactImport; + // scopes that were computed from this file + readonly globals: Scope; +} + +export type TypeEntry = { + readonly arity: number; + readonly decl: T +} +export const TypeEntry = ( + arity: number, + decl: T, +): TypeEntry => ({ arity, decl }); + +export const typecheck = (root: TactSource): [Scope, E.TcError[]] => { + const allErrors: E.TcError[] = []; + + const recur = memo((source: TactSource): Scope => { + const [value, errors] = E.runLog(tcSource( // leave only imports of .tact onlyTactImports(source.imports) .map(importedBy => ({ - globals: memoedRec(importedBy.source), + globals: recur(importedBy.source), importedBy, })), source, - ); + )); // `recur` is called only once on every source // this ensures errors from every source get counted // only once - errors.push(...result.errors); - return result.value - }; - const memoedRec = memo(recur); - return W.makeLog(memoedRec(root), errors); + allErrors.push(...errors); + return value; + }); + + return [recur(root), allErrors]; }; + const onlyTactImports = (imports: readonly ResolvedImport[]): readonly TactImport[] => { // typescript narrowing doesn't properly apply to filter, // so we need this helper @@ -43,136 +63,1082 @@ const onlyTactImports = (imports: readonly ResolvedImport[]): readonly TactImpor return result; }; -type SourceCheckResult = { - // import that lead to reading this file - readonly importedBy: TactImport; - // scopes that were computed from this file - readonly globals: Scope; -} - -const tcSource = ( +function* tcSource( // list of import+source pairs for every of file's imports imported: readonly SourceCheckResult[], // source for current file source: TactSource, -): E.WithLog => { - // for each of the imports - const importGlobals = imported.map(({ globals, importedBy }) => { - // in each of its definitions - return updateVias(globals, (via) => { - // tell that it came from that import - return V.ViaImport(via, importedBy); - }); - }); +): E.WithLog { + const importedTypes = imported.map(({ globals, importedBy }) => ( + mapRegVia>(new Map( + globals.types.entries().map(([name, { value, via }]) => [ + name, { value: TypeEntry(getArity(value), value), via } + ]) + ), importedBy) + )); + const localTypes = source.items.types.map((item) => createRef( + item.name.text, + TypeEntry(getArity(item), item), + V.ViaOrigin(item.loc, source), + )); + const undecodedTypes = yield* concatReg( + builtinTypes, + 'type', + [...importedTypes, ...localTypes], + ); + const aliasDecodedTypes = yield* decodeAliases(undecodedTypes); - // get local definitions - const locals = W.flatMapLog( - W.traverseLog( - source.items, - item => scopeItem(item, source), - ), - concatScopes, + const functions = yield* mergeReg( + imported, source, + 'function', + (s) => s.functions, + source.items.functions, + builtinFunctions, ); - // reduce list of sets of definitions into single set - const all = W.flatMapLog( - locals, - locals => concatScopes([...importGlobals, locals]), + const constants = yield* mergeReg( + imported, source, + 'constant', + (s) => s.constants, + source.items.constants, + new Map([]), ); - const typeErr = W.flatMapLog(all, checkTypes); + const extensions = yield* mergeExt( + imported, + source, + source.items.extensions, + builtinMethods, + aliasDecodedTypes, + ) - return typeErr; -}; + // for (const t of source.items.types) { + // yield* checkTypeDecl(t, unifier, all); + // } -type Stmt = (item: T, source: TactSource) => E.WithLog; - -const scopeItem: Stmt = (item, source) => { - switch (item.kind) { - case "function": - return scopeFunction(item, source); - case "constant": - return scopeConstant(item, source); - case "extension": - // cannot scope until we know types - return W.pureLog(emptyScope()); - case "struct_decl": - case "message_decl": - case "union_decl": - case "alias_decl": + // for (const c of source.items.constants) { + // yield* checkConstant(c, unifier.withParams([]), all); + // } + + // for (const f of source.items.functions) { + // yield* checkFunction(f, all); + // } + + // check aliases (no recursion) + // scope extensions + // check functions/extension/constant/method body + // source.items.constants.map(node => checkConstant(node)) + // check type uses (all types should be defined) + // check kinds (all uses of types are correct) + // get() opcode + // message opcode `Expression | undefined`, can only be done after types are checked + // TODO: constant/function/extension loops + + return { + types, + functions, + constants, + extensions, + }; +} +const getArity = (type: Ast.TypeDecl | FlatDecl): number => { + switch (type.kind) { + case "FlatContract": + case "FlatTrait": case "contract": case "trait": - return scopeType(item, source); + case "message_decl": { + return 0; + } + case 'InvalidDecl': { + return type.arity; + } + case "struct_decl": + case "union_decl": + case "FlatAlias": + case "alias_decl": { + return type.typeParams.length; + } } }; -const scopeFunction: Stmt = (item, source) => { - return W.pureLog(defineFunction( - item.name.text, - item, - V.ViaOrigin(item.loc, source), - )); -}; +type AliasDecodedDecl = + | FlatDecl + | Ast.Contract + | Ast.Trait +const decodeAliases = ( + userTypes: Registry>, +): E.WithLog>> => { + const EAliasOccurs = ( + name: string, + loc: Ast.Loc, + ): E.TcError => ({ + loc, + descr: [ + E.TEText(`Alias "${name}" was expanded inside itself`), + ], + }); -const scopeConstant: Stmt = (item, source) => { - // TODO - return W.pureLog(emptyScope()); -}; + type Status = Success | Failure | Visiting + // alias was already decoded + type Success = { + readonly kind: 'success'; + readonly alias: FlatAlias; + } + // failed at decoding the alias + type Failure = { + readonly kind: 'failure'; + } + // we're decoding it right now + type Visiting = { + readonly kind: 'visiting'; + } -const scopeType: Stmt = (item, source) => { - return W.pureLog(defineType( - item.name.text, - item, - V.ViaOrigin(item.loc, source), - )); + // status of checking alias bodies + const status: Map = new Map(); + + // check that neither of the types have cyclic alias references + function* checkTypes(types: readonly Ast.DecodedType[]): E.WithLog { + let result = true; + for (const type of types) { + const partialResult = yield* checkType(type); + // NB: separate from previous line to avoid short-circuiting + // we want to give ALL error message + result &&= partialResult; + } + return result; + } + + // check decoded type has no cyclic alias references + function* checkType(type: Ast.DecodedType): E.WithLog { + switch (type.kind) { + case "TyInt": + case "TySlice": + case "TyCell": + case "TyBuilder": + case "unit_type": + case "TypeVoid": + case "TypeNull": + case "TypeBool": + case "TypeAddress": + case "TypeString": + case "TypeParam": + case "TypeStringBuilder": { + return true; + } + case "TypeBounced": + case "TypeMaybe": { + return yield* checkType(type.type); + } + case "map_type": { + return (yield* checkType(type.key)) && (yield* checkType(type.value)); + } + case "type_ref": + case "tuple_type": + case "tensor_type": { + return yield* checkTypes(type.typeArgs); + } + case "TypeAlias": { + // check alias reference's arguments + const result = yield* checkTypes(type.typeArgs); + const alias = userTypes.get(type.name.text); + if (!alias) { + return throwInternal("Alias reference was decoded, but doesn't exist"); + } + const decl = alias.value.decl + if (decl.kind === 'alias_decl') { + return Boolean(yield* decodeAlias(decl)) && result; + } + if (decl.kind === 'FlatAlias') { + // we don't need to check FlatAlias, because it + // was already checked in one of the previous sources + return result; + } + return throwInternal("Alias reference was decoded, but does not reference alias"); + } + } + } + + // convert alias into better representation + function* decodeAlias(decl: Ast.AliasDecl): E.WithLog { + const name = decl.name.text; + const s = status.get(name); + if (!s) { + // remember we're trying to do it right now, + // so that we can throw occurs check for cyclic aliases + status.set(name, { kind: 'visiting' }); + + // decode type of the alias body + const type = yield* decodeType( + userTypes, + decl.typeParams, + decl.type, + ); + + // something went wrong trying to decode alias body + if (!type) { + status.set(name, { kind: 'failure' }); + return undefined; + } + + const alias = FlatAlias( + decl.name, + decl.typeParams, + type, + decl.loc, + ); + yield* checkType(type); + + // remember that we're done with this alias + status.set(name, { kind: 'success', alias }); + return alias; + } else if (s.kind === 'failure') { + return undefined; + } else if (s.kind === 'success') { + return s.alias; + } else { + yield EAliasOccurs(name, decl.loc); + return undefined; + } + } + function* root(): E.WithLog>> { + const result: [string, Def>][] = []; + // for every type declaration + for (const [name, def] of userTypes) { + const decl = def.value.decl; + // if it's not an alias, return it unchanged + // cannot decode it yet + if (decl.kind !== 'alias_decl') { + result.push([name, { value: { + arity: def.value.arity, + decl: decl, + }, via: def.via }]); + continue; + } + // decode the alias + const res = yield* decodeAlias(decl); + if (!res) { + // if decoding failed, store it as invalid type declaration + result.push([name, { value: { + arity: def.value.arity, + decl: InvalidDecl(decl.name, def.value.arity, decl.loc), + }, via: def.via }]); + continue; + } + // we've actually manage to decode the alias + // and it has neither broken types, nor loops + result.push([name, { value: { + arity: def.value.arity, + decl: res, + }, via: def.via }]); + } + return new Map(result); + } + return root(); }; -// set of definitions (transitively) from a source file -type Scope = { - // global function definitions - readonly functions: Functions; - // global type definitons - readonly types: TypeDecls; +const decodeType = ( + userTypes: Registry>, + typeParams: readonly Ast.TypeId[], + type: Ast.Type, +): E.WithLog => { + const ETypeNotFound = ( + name: string, + loc: Ast.Loc, + ): E.TcError => ({ + loc, + descr: [ + E.TEText(`Type "${name}" is not defined`), + ], + }); + function* matchArity( + name: string, + got: number, + expected: number, + loc: Ast.Loc, + ): E.WithLog { + const result = got === expected; + if (!result) { + yield EArity(name, expected, got, loc); + } + return result; + } + const EArity = ( + name: string, + expected: number, + got: number, + loc: Ast.Loc, + ): E.TcError => ({ + loc, + descr: [ + E.TEText(`Type "${name}" is expected to have ${expected} type arguments, got ${got}`), + ], + }); + + // decode all the types in an array + function* recN( + types: readonly Ast.Type[], + ): E.WithLog { + const results: Ast.DecodedType[] = []; + for (const type of types) { + const result = yield* rec(type); + if (result) { + results.push(result); + } else { + return undefined + } + } + return results; + } + + // decode a type + function* rec( + type: Ast.Type, + ): E.WithLog { + switch (type.kind) { + case "unit_type": + case "TyInt": + case "TySlice": + case "TyCell": + case "TyBuilder": + case "TypeVoid": + case "TypeNull": + case "TypeBool": + case "TypeAddress": + case "TypeString": + case "TypeStringBuilder": { + return type; + } + case "tuple_type": { + const result = yield* recN(type.typeArgs); + return result && Ast.DTypeTuple(result, type.loc); + } + case "tensor_type": { + const result = yield* recN(type.typeArgs); + return result && Ast.DTypeTensor(result, type.loc); + } + case "map_type": { + const key = yield* rec(type.key); + const value = yield* rec(type.value); + if (!key || !value) { + return undefined; + } + return Ast.DTypeMap(key, value, type.loc); + } + case "TypeBounced": { + const child = yield* rec(type.type); + if (!child) { + return undefined; + } + return Ast.DTypeBounced(child, type.loc); + } + case "TypeMaybe": { + const child = yield* rec(type.type); + if (!child) { + return undefined; + } + return Ast.DTypeMaybe(child, type.loc); + } + case "cons_type": { + // this is where the meat of the procedure is + // cons can be either parameter, type reference, + // alias reference, or reference to undefined type + const name = type.name.text; + const arity = type.typeArgs.length; + + const args = yield* recN(type.typeArgs); + + // if it's in a list of type parameters, this + // is a parameter + const param = typeParams.find(p => p.text); + if (param) { + // if we used type parameter generically, throw error + // because we do not support HKT + if (!(yield* matchArity(name, arity, 0, type.loc))) { + return undefined; + } + return Ast.DTypeParamRef( + type.name, + type.loc, + ); + } + + const typeEntry = userTypes.get(name); + + // there is no such type at all! + if (!typeEntry) { + yield ETypeNotFound(name, type.loc); + return undefined; + } + + // check number of type arguments does match + if (!(yield* matchArity( + name, + arity, + typeEntry.value.arity, + type.loc, + ))) { + return undefined; + } + + // arguments did match, but something is wrong with them + if (!args) { + return undefined; + } + + const decl = typeEntry.value.decl; + switch (decl.kind) { + case "InvalidDecl": { + // something went wrong with the declaration we refer to + // so this cannot be a valid type + return undefined; + } + case "FlatAlias": + case "alias_decl": { + // this is an alias reference + return Ast.DTypeAliasRef(type.name, args, type.loc); + } + case "FlatContract": + case "FlatTrait": + case "struct_decl": + case "message_decl": + case "union_decl": + case "contract": + case "trait": { + // this is a ground type reference + return Ast.DTypeRef(type.name, args, type.loc); + } + } + } + } + } + + return rec(type); } -const emptyScope = (): Scope => ({ - functions: Functions.empty(), - types: TypeDecls.empty(), -}); +function* mergeExt( + results: readonly SourceCheckResult[], + source: TactSource, + items: readonly Ast.Extension[], + builtins: ReadonlyMap, + userTypes: Registry>, +): E.WithLog { + const EMethodOverlap = ( + name: string, + prev: V.Via, + next: V.ViaUser, + ): E.TcError => ({ + loc: E.viaToRange(next), + descr: [ + E.TEText(`Method "${name}" overlaps previously defined method`), + E.TEVia(prev), + ], + }); -// sequence multiple definition sets -const concatScopes = (globals: readonly Scope[]): E.WithLog => { - return W.reduceLog(globals, appendScopes, emptyScope()); -}; + const imported: ExtRegistry[] = results.map(({ globals, importedBy }) => { + return new Map(globals.extensions.entries().map(([k, v]) => { + return [k, v.map((e) => ({ + via: V.ViaImport(importedBy, e.via), + self: e.self, + typeParams: e.typeParams, + mutates: e.mutates, + fun: e.fun, + }))]; + })); + }); -// define global function -const defineFunction = (name: string, value: Ast.Function, via: V.ViaUser): Scope => { - return { - ...emptyScope(), - functions: Functions.create(name, value, via), + const local: ExtRegistry[] = []; + for (const item of items) { + const fun = item.fun; + const type = yield* decodeType( + userTypes, + fun.type.typeParams, + item.selfType + ); + + if (!type) { + // self type is wrong + continue; + } + + // type without any aliases + const methodType = yield* toSelfType( + userTypes, + resolveAliases(userTypes, type) + ); + if (!methodType) { + continue; + } + + local.push(new Map([[fun.name.text, [{ + via: V.ViaOrigin(fun.loc, source), + self: methodType, + typeParams: fun.type.typeParams, + mutates: item.mutates, + fun: item.fun, + }]]])); + } + + const all = [...imported, ...local]; + + const prev: Map = new Map(); + for (const next of all) { + for (const [name, nextMap] of next) { + const prevMap = [...prev.get(name) ?? []]; + const builtin = builtins.get(name); + for (const entry of nextMap) { + const { typeParams, self } = entry + // defined in compiler + const prevBuiltin = !areOrdered(builtin, nextSchema); + if (prevBuiltin) { + yield EMethodOverlap(name, V.ViaBuiltin(), nextDef.via); + continue; + } + const prevEntry = prevMap.find(([prevSchema]) => !unifier.areOrdered( + prevSchema, nextSchema + )); + // not defined yet; define it now + if (!prevEntry) { + prevMap.push([nextSchema, nextDef]); + continue; + } + const [, prevDef] = prevEntry; + // already defined, and it's not a diamond situation + if (prevDef.via.source !== nextDef.via.source) { + yield EMethodOverlap(name, prevDef.via, nextDef.via); + } + } + prev.set(name, prevMap); + } + } + return prev; +} + +const resolveAliases = ( + userTypes: Registry>, + type: Ast.DecodedType, +) => { + const recN = (types: readonly Ast.DecodedType[]): readonly Ast.DecodedType[] => { + return types.map(type => rec(type)); + }; + const rec = (type: Ast.DecodedType): Ast.DecodedType => { + switch (type.kind) { + case "type_ref": { + return Ast.DTypeRef( + type.name, + recN(type.typeArgs), + type.loc, + ); + } + case "TypeAlias": { + const def = userTypes.get(type.name.text); + if (!def) { + return throwInternal("Decoder returned broken reference"); + } + const decl = def.value.decl; + if (decl.kind !== 'FlatAlias') { + return throwInternal("Decoder returned broken reference"); + } + // NB! if we could decode alias once, there might be + // a nested one too + return rec(substitute( + decl.type, + decl.typeParams, + recN(type.typeArgs), + )); + } + case "TypeParam": { + return type; + } + case "map_type": { + return Ast.DTypeMap( + rec(type.key), + rec(type.value), + type.loc, + ); + } + case "TypeBounced": { + return Ast.DTypeBounced( + rec(type.type), + type.loc, + ); + } + case "TypeMaybe": { + return Ast.DTypeMaybe( + rec(type.type), + type.loc, + ); + } + case "tuple_type": { + return Ast.DTypeTuple( + recN(type.typeArgs), + type.loc, + ); + } + case "tensor_type": { + return Ast.DTypeTensor( + recN(type.typeArgs), + type.loc, + ); + } + case "TyInt": + case "TySlice": + case "TyCell": + case "TyBuilder": + case "unit_type": + case "TypeVoid": + case "TypeNull": + case "TypeBool": + case "TypeAddress": + case "TypeString": + case "TypeStringBuilder": { + return type; + } + } }; + return rec(type); }; -// define type -const defineType = (name: string, value: Ast.TypeDecl, via: V.ViaUser): Scope => { - return { - ...emptyScope(), - types: TypeDecls.create(name, value, via), +const substitute = ( + type: Ast.DecodedType, + params: readonly Ast.TypeId[], + args: readonly Ast.DecodedType[], +): Ast.DecodedType => { + if (params.length !== args.length) { + return throwInternal("Decoder didn't check alias arity"); + } + + const substMap = new Map(zip(params, args).map(([param, arg]) => { + return [param.text, arg]; + })) + + const recN = (types: readonly Ast.DecodedType[]): readonly Ast.DecodedType[] => { + return types.map(type => rec(type)); }; + + const rec = (type: Ast.DecodedType): Ast.DecodedType => { + switch (type.kind) { + case "TypeParam": { + const arg = substMap.get(type.name.text); + if (!arg) { + return throwInternal("Decoder didn't scope alias's type args"); + } + return arg; + } + case "type_ref": { + return Ast.DTypeRef( + type.name, + recN(type.typeArgs), + type.loc, + ); + } + case "TypeAlias": { + return Ast.DTypeAliasRef( + type.name, + recN(type.typeArgs), + type.loc, + ); + } + case "map_type": { + return Ast.DTypeMap( + rec(type.key), + rec(type.value), + type.loc, + ); + } + case "TypeBounced": { + return Ast.DTypeBounced( + rec(type.type), + type.loc, + ); + } + case "TypeMaybe": { + return Ast.DTypeMaybe( + rec(type.type), + type.loc, + ); + } + case "tuple_type": { + return Ast.DTypeTuple( + recN(type.typeArgs), + type.loc, + ); + } + case "tensor_type": { + return Ast.DTypeTensor( + recN(type.typeArgs), + type.loc, + ); + } + case "TyInt": + case "TySlice": + case "TyCell": + case "TyBuilder": + case "unit_type": + case "TypeVoid": + case "TypeNull": + case "TypeBool": + case "TypeAddress": + case "TypeString": + case "TypeStringBuilder": { + return type; + } + } + }; + + return rec(type); }; -// sequence two definition sets: define all the `right` after `left` -const appendScopes = (left: Scope, right: Scope): E.WithLog => { - return W.combineLog({ - functions: Functions.append(left.functions, right.functions), - types: TypeDecls.append(left.types, right.types), - }); +function* toSelfType( + userTypes: Registry>, + type: Ast.DecodedType, +): E.WithLog { + switch (type.kind) { + case "type_ref": { + const def = userTypes.get(type.name.text); + if (!def) { + return throwInternal("Decoder returned broken reference") + } + const decl = def.value.decl; + switch (decl.kind) { + case "InvalidDecl": { + return undefined; + } + case "FlatAlias": { + return throwInternal("Decoder returned broken reference") + } + case "FlatContract": + case "contract": { + yield ENoMethods("contract", type.loc); + return undefined; + } + case "FlatTrait": + case "trait": { + yield ENoMethods("trait", type.loc); + return undefined; + } + case "struct_decl": + case "message_decl": + case "union_decl": { + const allVars = type.typeArgs.filter(arg => { + return arg.kind === 'TypeParam'; + }); + if (type.typeArgs.length === allVars.length) { + const argNames = new Set(allVars.map(v => v.name.text)); + if (argNames.size !== allVars.length) { + // type variables are not distinct + yield EBadMethodType(type.loc); + return undefined; + } + return Ast.MVTypeRef( + type.name, + allVars, + type.loc, + ); + } + if (type.typeArgs.length > 0 && allVars.length > 0) { + // has vars, but it's not all the parameters + yield EBadMethodType(type.loc); + return undefined; + } + const ground: Ast.MethodGroundType[] = []; + for (const arg of type.typeArgs) { + const result = yield* toGroundType(userTypes, arg); + if (!result) { + yield EBadMethodType(type.loc); + return undefined; + } + ground.push(result); + } + return Ast.MGTypeRef( + type.name, + ground, + type.loc, + ); + } + } + // somehow typescript wants this + return throwInternal("Unknown declaration type"); + } + case "TypeAlias": { + return throwInternal("resolveAliases didn't resolve them"); + } + case "TypeParam": { + yield EBadMethodType(type.loc); + return undefined; + } + case "map_type": { + if (type.key.kind === 'TypeParam' && type.value.kind === 'TypeParam') { + return Ast.MVTypeMap( + type.key, + type.value, + type.loc, + ); + } + const ground = yield* toGroundType(userTypes, type); + if (!ground) { + yield EBadMethodType(type.loc); + return undefined; + } + return ground; + } + case "TypeBounced": { + yield EBadMethodType(type.loc); + return undefined; + } + case "TypeMaybe": { + if (type.type.kind === 'TypeParam') { + return Ast.MVTypeMaybe( + type.type, + type.loc, + ); + } + const ground = yield* toGroundType(userTypes, type); + if (!ground) { + yield EBadMethodType(type.loc); + return undefined; + } + return ground; + } + case "tensor_type": + case "tuple_type": { + const mvCons = type.kind === 'tuple_type' + ? Ast.MVTypeTuple + : Ast.MVTypeTensor; + const allVars = type.typeArgs.filter(arg => { + return arg.kind === 'TypeParam'; + }); + if (type.typeArgs.length === allVars.length) { + const argNames = new Set(allVars.map(v => v.name.text)); + if (argNames.size !== allVars.length) { + // type variables are not distinct + yield EBadMethodType(type.loc); + return undefined; + } + return mvCons( + allVars, + type.loc, + ); + } + const ground = yield* toGroundType(userTypes, type); + if (!ground) { + yield EBadMethodType(type.loc); + return undefined; + } + return ground; + } + case "TyInt": + case "TySlice": + case "TyCell": + case "TyBuilder": + case "unit_type": + case "TypeVoid": + case "TypeNull": + case "TypeBool": + case "TypeAddress": + case "TypeString": + case "TypeStringBuilder": { + return type; + } + } +} +const EBadMethodType = ( + loc: Ast.Loc, +): E.TcError => ({ + loc, + descr: [ + E.TEText(`Type of self must either have no type parameters, or be a generic type with distinct type parameters`), + ], +}); +const ENoMethods = ( + kind: string, + loc: Ast.Loc, +): E.TcError => ({ + loc, + descr: [ + E.TEText(`Cannot define methods on ${kind}`), + ], +}); + +function* toGroundType( + userTypes: Registry>, + type: Ast.DecodedType +): E.WithLog { + switch (type.kind) { + case "type_ref": { + const def = userTypes.get(type.name.text); + if (!def) { + return throwInternal("Decoder returned broken reference") + } + const decl = def.value.decl; + switch (decl.kind) { + case "InvalidDecl": { + return undefined; + } + case "FlatAlias": { + return throwInternal("Decoder returned broken reference") + } + case "FlatContract": + case "contract": { + yield ENoMethods("contract", type.loc); + return undefined; + } + case "FlatTrait": + case "trait": { + yield ENoMethods("trait", type.loc); + return undefined; + } + case "struct_decl": + case "message_decl": + case "union_decl": { + const ground: Ast.MethodGroundType[] = []; + for (const arg of type.typeArgs) { + const result = yield* toGroundType(userTypes, arg); + if (!result) { + return undefined; + } + ground.push(result); + } + return Ast.MGTypeRef( + type.name, + ground, + type.loc, + ); + } + } + // somehow typescript wants this + return throwInternal("Unknown declaration type"); + } + case "TypeAlias": { + return throwInternal("resolveAliases didn't resolve them"); + } + case "TypeParam": { + return undefined; + } + case "map_type": { + const key = yield* toGroundType(userTypes, type.key); + const value = yield* toGroundType(userTypes, type.value); + if (!key || !value) { + return undefined; + } + return Ast.MGTypeMap(key, value, type.loc); + } + case "TypeBounced": { + return undefined; + } + case "TypeMaybe": { + const child = yield* toGroundType(userTypes, type.type); + if (!child) { + return undefined; + } + return Ast.MGTypeMaybe(child, type.loc); + } + case "tuple_type": { + const children: Ast.MethodGroundType[] = []; + for (const child of type.typeArgs) { + const result = yield* toGroundType(userTypes, child); + if (!result) { + return undefined; + } + children.push(result); + } + return Ast.MGTypeTuple(children, type.loc); + } + case "tensor_type": { + const children: Ast.MethodGroundType[] = []; + for (const child of type.typeArgs) { + const result = yield* toGroundType(userTypes, child); + if (!result) { + return undefined; + } + children.push(result); + } + return Ast.MGTypeTensor(children, type.loc); + } + case "TyInt": + case "TySlice": + case "TyCell": + case "TyBuilder": + case "unit_type": + case "TypeVoid": + case "TypeNull": + case "TypeBool": + case "TypeAddress": + case "TypeString": + case "TypeStringBuilder": { + return type; + } + } +} + +function* mergeReg( + results: readonly SourceCheckResult[], + source: TactSource, + kind: string, + get1: (s: Scope) => Registry, + items: readonly T[], + builtin: Map, +): E.WithLog> { + const imported = results.map(({ globals, importedBy }) => ( + mapRegVia(get1(globals), importedBy) + )); + const local = items.map((item) => createRef( + item.name.text, + item, + V.ViaOrigin(item.loc, source), + )); + return yield* concatReg( + builtin, + kind, + [...imported, ...local], + ) +} + +const createRef = (name: string, value: V, via: V.ViaUser): Registry => { + return new Map([[name, { value, via }]]); }; -// update all the `via` fields with information about new import -const updateVias = (globals: Scope, cb: (via: V.ViaUser) => V.ViaUser): Scope => { - return { - functions: Functions.mapVia(globals.functions, cb), - types: TypeDecls.mapVia(globals.types, cb), - }; +const mapRegVia = (fns: Registry, importedBy: TactImport): Registry => { + return new Map(fns.entries().map(([k, v]) => { + return [k, { + value: v.value, + via: V.ViaImport(importedBy, v.via), + }]; + })); }; + +function* concatReg( + builtins: Map, + kind: string, + all: readonly Registry[] +): E.WithLog> { + const ERedefine = (kind: string, name: string, prev: V.Via, next: V.ViaUser): E.TcError => ({ + loc: E.viaToRange(next), + descr: [ + E.TEText(`There already is a ${kind} "${name}" from`), + E.TEVia(prev), + ], + }); + + const prev: Map> = new Map(); + for (const next of all) { + for (const [name, nextItem] of next) { + const prevItem = prev.get(name); + // defined in compiler + if (builtins.has(name)) { + yield ERedefine(kind, name, V.ViaBuiltin(), nextItem.via); + continue; + } + // not defined yet; define it now + if (typeof prevItem === 'undefined') { + prev.set(name, nextItem); + continue; + } + // already defined, and it's not a diamond situation + if (prevItem.via.source !== nextItem.via.source) { + yield ERedefine(kind, name, prevItem.via, nextItem.via); + } + } + } + return prev; +} diff --git a/src/next/types/via.ts b/src/next/types/via.ts index f54fe51783..2cecae7aca 100644 --- a/src/next/types/via.ts +++ b/src/next/types/via.ts @@ -17,13 +17,13 @@ export type ViaUser = { // which imports it came through readonly imports: readonly TactImport[]; // where in the code it was defined - readonly defLoc: Ast.Range; + readonly defLoc: Ast.Loc; // in which source readonly source: TactSource; } // when something was just defined -export const ViaOrigin = (defLoc: Ast.Range, source: TactSource): ViaUser => { +export const ViaOrigin = (defLoc: Ast.Loc, source: TactSource): ViaUser => { const result: ViaUser = { kind: 'user', imports: [], @@ -35,7 +35,7 @@ export const ViaOrigin = (defLoc: Ast.Range, source: TactSource): ViaUser => { }; // when it came through an import -export const ViaImport = (via: ViaUser, throughImport: TactImport): ViaUser => { +export const ViaImport = (throughImport: TactImport, via: ViaUser): ViaUser => { const result: ViaUser = { kind: 'user', imports: [throughImport, ...via.imports], diff --git a/src/next/types/writer.ts b/src/next/types/writer.ts deleted file mode 100644 index 3791a553c7..0000000000 --- a/src/next/types/writer.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { throwInternal } from "@/error/errors"; -import { entries } from "@/utils/tricks"; - -export type Writer = { - readonly errors: C[]; - readonly value: T; -} - -export const makeLog = (value: T, errors: C[]): Writer => ({ errors, value }); - -export const pureLog = (value: T): Writer => makeLog(value, []); - -export const mapLog = (x: Writer, f: (t: T) => U): Writer => { - return makeLog(f(x.value), x.errors); -}; - -export const flatMapLog = (x: Writer, f: (t: T) => Writer): Writer => { - const res = f(x.value); - return makeLog(res.value, [...x.errors, ...res.errors]); -}; - -export const combineLog = (children: { [K in keyof O]: Writer }): Writer => { - const value = {} as O; - const errors: C[] = []; - for (const [k, v] of entries(children)) { - value[k] = v.value; - errors.push(...v.errors); - } - return makeLog(value, errors); -}; - -export const traverseLog = (xs: readonly T[], cb: (t: T) => Writer): Writer => { - const value: U[] = []; - const errors: C[] = []; - for (const x of xs) { - const v = cb(x); - value.push(v.value); - errors.push(...v.errors); - } - return makeLog(value, errors); -}; - -export const reduceLog = ( - xs: readonly T[], cb: (a: A, t: T) => Writer, init: A, -): Writer => { - let acc: Writer = pureLog(init); - for (const x of xs) { - acc = flatMapLog(acc, acc => cb(acc, x)); - } - return acc; -}; - -export const reduce1Log = ( - xs: readonly T[], cb: (a: T, t: T) => Writer, -): Writer => { - const [head, ...tail] = xs; - if (typeof head === 'undefined') { - return throwInternal("Reducing empty list"); - } - return reduceLog(tail, cb, head); -}; From 0e334555a7fd0f2cda1d0d696ea80fd10e199251 Mon Sep 17 00:00:00 2001 From: verytactical <186486509+verytactical@users.noreply.github.com> Date: Mon, 26 May 2025 14:38:21 +0400 Subject: [PATCH 23/38] 1 --- src/next/ast/checked.ts | 207 ++++++ src/next/ast/dtype.ts | 5 + src/next/ast/generated/checked.ts | 211 ++++++ src/next/ast/generated/dtype.ts | 7 +- src/next/ast/generated/mtype.ts | 20 - src/next/ast/generated/via.ts | 39 + src/next/ast/index.ts | 2 + src/next/ast/mtype.ts | 50 +- src/next/ast/via.ts | 25 + src/next/types/aliases.ts | 302 ++++++++ src/next/types/builtins.ts | 136 ++-- src/next/types/constants.ts | 78 ++ src/next/types/errors.ts | 47 +- src/next/types/expression.ts | 12 + src/next/types/extensions.ts | 420 +++++++++++ src/next/types/flat.ts | 124 ---- src/next/types/functions.ts | 53 ++ src/next/types/reg.ts | 30 + src/next/types/traits.ts | 36 + src/next/types/type-params.ts | 30 + src/next/types/typecheck.ts | 1135 ++--------------------------- src/next/types/types.ts | 226 ++++++ src/next/types/util.ts | 74 ++ src/next/types/via.ts | 47 -- 24 files changed, 1943 insertions(+), 1373 deletions(-) create mode 100644 src/next/ast/checked.ts create mode 100644 src/next/ast/generated/checked.ts create mode 100644 src/next/ast/generated/via.ts create mode 100644 src/next/ast/via.ts create mode 100644 src/next/types/aliases.ts create mode 100644 src/next/types/constants.ts create mode 100644 src/next/types/expression.ts create mode 100644 src/next/types/extensions.ts delete mode 100644 src/next/types/flat.ts create mode 100644 src/next/types/functions.ts create mode 100644 src/next/types/reg.ts create mode 100644 src/next/types/traits.ts create mode 100644 src/next/types/type-params.ts create mode 100644 src/next/types/types.ts create mode 100644 src/next/types/util.ts delete mode 100644 src/next/types/via.ts diff --git a/src/next/ast/checked.ts b/src/next/ast/checked.ts new file mode 100644 index 0000000000..5bffe5da1f --- /dev/null +++ b/src/next/ast/checked.ts @@ -0,0 +1,207 @@ +import type { Loc, OptionalId, TypeId } from "@/next/ast/common"; +import type { DecodedType, DTypeRef } from "@/next/ast/dtype"; +import type { SelfType } from "@/next/ast/mtype"; +import type { ViaMember, ViaUser } from "@/next/ast/via"; +import type { TactImport } from "@/next/imports/source"; + +export type SourceCheckResult = { + // import that lead to reading this file + readonly importedBy: TactImport; + // scopes that were computed from this file + readonly globals: Scope; +} + +export type DeclSigs = ReadonlyMap + +export type Scope = { + readonly typeDecls: ReadonlyMap; + readonly fnSigs: ReadonlyMap; + readonly constSigs: ReadonlyMap; + readonly extSigs: ReadonlyMap; +} + +export type TypeDeclSig = + | BadSig + | AliasSig + | ContractSig + | TraitSig + | StructSig + | MessageSig + | UnionSig + +export type DeclSig = { + readonly use: TypeUse; + readonly arity: number; + readonly via: ViaUser; +} +export type TypeUse = "usual" | "alias" | "contract" | "forbidden" + +export type ConstSig = { + readonly type: DecodedType; + readonly via: ViaUser; +} + +export type FnSig = { + readonly type: DecodedFnType; + readonly via: ViaUser; +} + +export type ExtSig = { + readonly type: DecodedMethodType; + readonly via: ViaUser; +} + +export type BadSig = { + readonly kind: 'bad'; + readonly arity: number; + readonly via: ViaUser; +} + +export type AliasSig = { + readonly kind: 'alias'; + readonly typeParams: TypeParams; + readonly type: DecodedType; + readonly via: ViaUser; +} + +export type ContractSig = { + readonly kind: 'contract'; + readonly init: Parameters; + readonly content: CommonSig; + readonly via: ViaUser; +} +export type TraitSig = { + readonly kind: 'trait'; + readonly content: CommonSig; + readonly via: ViaUser; +} +export type CommonSig = { + readonly name: TypeId; + readonly fields: Ordered; + readonly constants: ReadonlyMap; + readonly methods: ReadonlyMap; + readonly bounce: BounceSig; + readonly internal: RecvSig; + readonly external: RecvSig; +} + +export type InhFieldSig = { + readonly type: DecodedType + readonly via: ViaMember; +} + +export type FieldConstSig = { + readonly overridable: boolean; + readonly override: boolean; + readonly type: DecodedType; + readonly via: ViaMember; +} + +export type MethodSig = { + readonly overridable: boolean; + readonly override: boolean; + readonly type: DecodedFnType; + readonly via: ViaMember; +} + +export type BounceSig = { + readonly message: ReadonlyMap; + readonly messageAny: undefined | MessageAnyRecv; +} + +export type RecvSig = { + readonly message: ReadonlyMap; + readonly messageAny: undefined | MessageAnyRecv; + readonly string: ReadonlyMap; + readonly stringAny: undefined | StringAnyRecv; + readonly empty: undefined | EmptyRecv; +} + +export type MessageRecv = { + readonly name: OptionalId; + readonly type: DTypeRef; + readonly via: ViaMember; +} +export type MessageAnyRecv = { + readonly name: OptionalId; + readonly via: ViaMember; +} +export type StringRecv = { + readonly comment: string; + readonly via: ViaMember; +} +export type StringAnyRecv = { + readonly name: OptionalId; + readonly via: ViaMember; +} +export type EmptyRecv = { + readonly via: ViaMember; +} + +export type StructSig = { + readonly kind: "struct"; + readonly typeParams: TypeParams; + readonly fields: Ordered; + readonly via: ViaUser; +} + +export type MessageSig = { + readonly kind: "message"; + readonly typeParams: TypeParams; + readonly fields: Ordered; + readonly via: ViaUser; +} + +export type UnionSig = { + readonly kind: "union"; + readonly typeParams: TypeParams; + readonly cases: ReadonlyMap>; + readonly via: ViaUser; +} + +export type FieldSig = { + readonly type: DecodedType; + readonly via: ViaUser; +} + +export type DecodedFnType = { + readonly typeParams: TypeParams; + readonly params: Parameters; + readonly returnType: DecodedType, +} + +export type DecodedMethodType = { + readonly typeParams: TypeParams; + readonly self: SelfType; + readonly params: Parameters; + readonly returnType: DecodedType, +} + +export type DecodedParameter = { + readonly name: OptionalId; + readonly type: DecodedType; + readonly loc: Loc; +}; + +export type Ordered = { + readonly order: readonly string[]; + readonly map: ReadonlyMap; +} + +export type Parameters = { + readonly order: readonly Parameter[]; + readonly set: ReadonlySet; +} + +export type Parameter = { + readonly name: OptionalId; + readonly type: DecodedType; + readonly loc: Loc; +}; + +export type TypeParams = { + readonly order: readonly TypeId[]; + readonly set: ReadonlySet; +} + + diff --git a/src/next/ast/dtype.ts b/src/next/ast/dtype.ts index 7644d695fd..24761d8974 100644 --- a/src/next/ast/dtype.ts +++ b/src/next/ast/dtype.ts @@ -2,6 +2,7 @@ import type { Loc, TypeId } from "@/next/ast/common"; import type * as Ast from "@/next/ast/type"; export type DecodedType = + | DTypeRecover | DTypeRef | DTypeAliasRef | DTypeParamRef @@ -34,6 +35,10 @@ export type DTypeAddress = Ast.TypeAddress export type DTypeString = Ast.TypeString export type DTypeStringBuilder = Ast.TypeStringBuilder +export type DTypeRecover = { + readonly kind: "recover"; +} + export type DTypeRef = { readonly kind: "type_ref"; readonly name: TypeId; diff --git a/src/next/ast/generated/checked.ts b/src/next/ast/generated/checked.ts new file mode 100644 index 0000000000..9de5f5e346 --- /dev/null +++ b/src/next/ast/generated/checked.ts @@ -0,0 +1,211 @@ +/* eslint-disable @typescript-eslint/no-unnecessary-condition */ +import type * as $c from "@/next/ast/common"; +import type * as $d from "@/next/ast/dtype"; +import type * as $m from "@/next/ast/mtype"; +import type * as $v from "@/next/ast/via"; +import type * as $ from "@/next/ast/checked"; +import type { TactImport } from "@/next/imports/source"; + +export type TypeUse = $.TypeUse; +export const allTypeUse: readonly $.TypeUse[] = ["usual", "alias", "forbidden"]; +export type DeclSig = $.DeclSig; +export const DeclSig = (use: $.TypeUse, arity: number, via: $v.ViaUser): $.DeclSig => Object.freeze({ + use, + arity, + via +}); +export type DeclSigs = $.DeclSigs; +export type TypeParams = $.TypeParams; +export const TypeParams = (order: readonly $c.TypeId[], set: ReadonlySet): TypeParams => Object.freeze({ + order, + set, +}); +export type AliasSig = $.AliasSig; +export const AliasSig = (typeParams: $.TypeParams, type_: $d.DecodedType, via: $v.ViaUser): $.AliasSig => Object.freeze({ + kind: 'alias', + typeParams, + type: type_, + via +}); +export type Ordered = $.Ordered; +export const Ordered = (order: readonly string[], map: ReadonlyMap): $.Ordered => Object.freeze({ + order, + map +}); +export type InhFieldSig = $.InhFieldSig; +export const InhFieldSig = (type_: $d.DecodedType, via: $v.ViaMember): $.InhFieldSig => Object.freeze({ + type: type_, + via +}); +export type FieldConstSig = $.FieldConstSig; +export const FieldConstSig = (overridable: boolean, override: boolean, type_: $d.DecodedType, via: $v.ViaMember): $.FieldConstSig => Object.freeze({ + overridable, + override, + type: type_, + via +}); +export type DecodedFnType = $.DecodedFnType; +export const DecodedFnType = (typeParams: $.TypeParams, params: $.Parameters, returnType: $d.DecodedType): $.DecodedFnType => Object.freeze({ + typeParams, + params, + returnType +}); +export type MethodSig = $.MethodSig; +export const MethodSig = (overridable: boolean, override: boolean, type_: $.DecodedFnType, via: $v.ViaMember): $.MethodSig => Object.freeze({ + overridable, + override, + type: type_, + via +}); +export type MessageRecv = $.MessageRecv; +export const MessageRecv = (name: $c.OptionalId, type_: $d.DTypeRef, via: $v.ViaMember): $.MessageRecv => Object.freeze({ + name, + type: type_, + via +}); +export type MessageAnyRecv = $.MessageAnyRecv; +export const MessageAnyRecv = (name: $c.OptionalId, via: $v.ViaMember): $.MessageAnyRecv => Object.freeze({ + name, + via +}); +export type BounceSig = $.BounceSig; +export const BounceSig = (message: ReadonlyMap, messageAny: $.MessageAnyRecv | undefined): $.BounceSig => Object.freeze({ + message, + messageAny +}); +export type StringRecv = $.StringRecv; +export const StringRecv = (comment: string, via: $v.ViaMember): $.StringRecv => Object.freeze({ + comment, + via +}); +export type StringAnyRecv = $.StringAnyRecv; +export const StringAnyRecv = (name: $c.OptionalId, via: $v.ViaMember): $.StringAnyRecv => Object.freeze({ + name, + via +}); +export type EmptyRecv = $.EmptyRecv; +export const EmptyRecv = (via: $v.ViaMember): $.EmptyRecv => Object.freeze({ + via +}); +export type RecvSig = $.RecvSig; +export const RecvSig = (message: ReadonlyMap, messageAny: $.MessageAnyRecv | undefined, string_: ReadonlyMap, stringAny: $.StringAnyRecv | undefined, empty: $.EmptyRecv | undefined): $.RecvSig => Object.freeze({ + message, + messageAny, + string: string_, + stringAny, + empty +}); +export type CommonSig = $.CommonSig; +export const CommonSig = (name: $c.TypeId, fields: $.Ordered<$.InhFieldSig>, constants: ReadonlyMap, methods: ReadonlyMap, bounce: $.BounceSig, internal: $.RecvSig, external: $.RecvSig): $.CommonSig => Object.freeze({ + name, + fields, + constants, + methods, + bounce, + internal, + external +}); +export type ContractSig = $.ContractSig; +export const ContractSig = (init: $.Parameters, content: $.CommonSig, via: $v.ViaUser): $.ContractSig => Object.freeze({ + kind: 'contract', + init, + content, + via, +}); +export type TraitSig = $.TraitSig; +export const TraitSig = (content: $.CommonSig, via: $v.ViaUser): $.TraitSig => Object.freeze({ + kind: 'trait', + content, + via +}); +export type FieldSig = $.FieldSig; +export const FieldSig = (type_: $d.DecodedType, via: $v.ViaUser): $.FieldSig => Object.freeze({ + type: type_, + via +}); +export type StructSig = $.StructSig; +export const StructSig = (typeParams: $.TypeParams, fields: $.Ordered<$.FieldSig>, via: $v.ViaUser): $.StructSig => Object.freeze({ + kind: "struct", + typeParams, + fields, + via +}); +export const isStructSig = ($value: StructSig) => $value.kind === "struct"; +export type MessageSig = $.MessageSig; +export const MessageSig = (typeParams: $.TypeParams, fields: $.Ordered<$.FieldSig>, via: $v.ViaUser): $.MessageSig => Object.freeze({ + kind: "message", + typeParams, + fields, + via +}); +export const isMessageSig = ($value: MessageSig) => $value.kind === "message"; +export type UnionSig = $.UnionSig; +export const UnionSig = (typeParams: $.TypeParams, cases: ReadonlyMap>, via: $v.ViaUser): $.UnionSig => Object.freeze({ + kind: "union", + typeParams, + cases, + via +}); +export const isUnionSig = ($value: UnionSig) => $value.kind === "union"; +export type TypeDeclSig = $.TypeDeclSig; +export type FnSig = $.FnSig; +export const FnSig = (type_: $.DecodedFnType, via: $v.ViaUser): $.FnSig => Object.freeze({ + type: type_, + via +}); +export type ConstSig = $.ConstSig; +export const ConstSig = (type_: $d.DecodedType, via: $v.ViaUser): $.ConstSig => Object.freeze({ + type: type_, + via +}); +export type ExtSig = $.ExtSig; +export const ExtSig = (type: $.DecodedMethodType, via: $v.ViaUser): $.ExtSig => Object.freeze({ + type, + via +}); +export type Scope = $.Scope; +export const Scope = (typeDecls: ReadonlyMap, fnSigs: ReadonlyMap, constSigs: ReadonlyMap, extSigs: ReadonlyMap): $.Scope => Object.freeze({ + typeDecls, + fnSigs, + constSigs, + extSigs +}); +export type DecodedMethodType = $.DecodedMethodType; +export const DecodedMethodType = (typeParams: $.TypeParams, self: $m.SelfType, params: $.Parameters, returnType: $d.DecodedType): $.DecodedMethodType => Object.freeze({ + typeParams, + self, + params, + returnType +}); +export type DecodedParameter = $.DecodedParameter; +export const DecodedParameter = (name: $c.OptionalId, type_: $d.DecodedType, loc: $c.Loc): $.DecodedParameter => Object.freeze({ + name, + type: type_, + loc +}); +export type SourceCheckResult = $.SourceCheckResult; +export const SourceCheckResult = (importedBy: TactImport, globals: $.Scope): $.SourceCheckResult => Object.freeze({ + importedBy, + globals +}); +export type BadSig = $.BadSig; +export const BadSig = ( + arity: number, + via: $v.ViaUser, +): $.BadSig => Object.freeze({ + kind: "bad", + arity, + via, +}); +export const isBadSig = ($value: BadSig) => $value.kind === "bad"; +export type Parameter = $.Parameter; +export const Parameter = (name: $c.OptionalId, type_: $d.DecodedType, loc: $c.Loc): $.Parameter => Object.freeze({ + name, + type: type_, + loc +}); +export type Parameters = $.Parameters; +export const Parameters = (order: readonly $.Parameter[], set: ReadonlySet): $.Parameters => Object.freeze({ + order, + set +}); \ No newline at end of file diff --git a/src/next/ast/generated/dtype.ts b/src/next/ast/generated/dtype.ts index a8ee1f40c9..59299428c5 100644 --- a/src/next/ast/generated/dtype.ts +++ b/src/next/ast/generated/dtype.ts @@ -61,4 +61,9 @@ export const DTypeRef = (name: $c.TypeId, typeArgs: readonly $.DecodedType[], lo loc }); export const isDTypeRef = ($value: DTypeRef) => $value.kind === "type_ref"; -export type DecodedType = $.DecodedType; \ No newline at end of file +export type DecodedType = $.DecodedType; +export type DTypeRecover = $.DTypeRecover; +export const DTypeRecover = (): $.DTypeRecover => Object.freeze({ + kind: "recover" +}); +export const isDTypeRecover = ($value: DTypeRecover) => $value.kind === "recover"; diff --git a/src/next/ast/generated/mtype.ts b/src/next/ast/generated/mtype.ts index cce2ef4a10..986ba5214d 100644 --- a/src/next/ast/generated/mtype.ts +++ b/src/next/ast/generated/mtype.ts @@ -100,23 +100,3 @@ export const MVTypeTensor = (typeArgs: readonly $d.DTypeParamRef[], loc: $c.Loc) export const isMVTypeTensor = ($value: MVTypeTensor) => $value.kind === "tensor_type"; export type SelfType = $.SelfType; export type MethodGroundType = $.MethodGroundType; -export type MMethodFnType = $.MMethodFnType; -export const MMethodFnType = (typeParams: readonly $c.TypeId[], self: $.SelfType, args: readonly $.MTypedParameter[], returnType: $d.DecodedType): $.MMethodFnType => Object.freeze({ - typeParams, - self, - args, - returnType -}); -export type MTypedParameter = $.MTypedParameter; -export const MTypedParameter = (name: $c.OptionalId, type_: $d.DecodedType, loc: $c.Loc): $.MTypedParameter => Object.freeze({ - kind: "typed_parameter", - name, - type: type_, - loc -}); -export type MFnType = $.MFnType; -export const MFnType = (typeParams: readonly $c.TypeId[], args: readonly $.MTypedParameter[], returnType: $d.DecodedType): $.MFnType => Object.freeze({ - typeParams, - args, - returnType -}); \ No newline at end of file diff --git a/src/next/ast/generated/via.ts b/src/next/ast/generated/via.ts new file mode 100644 index 0000000000..85d23beb56 --- /dev/null +++ b/src/next/ast/generated/via.ts @@ -0,0 +1,39 @@ +import type * as $ from "@/next/ast/via"; +import type * as $c from "@/next/ast/common"; +import type { TactImport, TactSource } from "@/next/imports/source"; +import { hideProperty } from "@/utils/tricks"; + +export type Via = $.Via; +export type ViaBuiltin = $.ViaBuiltin; +export type ViaUser = $.ViaUser; +export type ViaMember = $.ViaMember; + +export const ViaBuiltin = (): $.ViaBuiltin => ({ kind: 'builtin' }); + +// when something was just defined +export const ViaOrigin = (defLoc: $c.Loc, source: TactSource): $.ViaUser => { + const result: $.ViaUser = { + kind: 'user', + imports: [], + defLoc, + source, + }; + hideProperty(result, 'source'); + return result; +}; + +// when it came through an import +export const ViaImport = (throughImport: TactImport, via: $.ViaUser): $.ViaUser => { + const result: $.ViaUser = { + kind: 'user', + imports: [throughImport, ...via.imports], + defLoc: via.defLoc, + source: via.source, + }; + hideProperty(result, 'source'); + return result; +}; + +export const ViaMember = ( + inheritance: readonly $.ViaUser[] +): $.ViaMember => ({ inheritance }); \ No newline at end of file diff --git a/src/next/ast/index.ts b/src/next/ast/index.ts index fafe6213a2..3e487640e5 100644 --- a/src/next/ast/index.ts +++ b/src/next/ast/index.ts @@ -5,4 +5,6 @@ export * from "@/next/ast/generated/type"; export * from "@/next/ast/generated/vtype"; export * from "@/next/ast/generated/dtype"; export * from "@/next/ast/generated/mtype"; +export * from "@/next/ast/generated/via"; +export * from "@/next/ast/generated/checked"; export * from "@/next/ast/generated/root"; diff --git a/src/next/ast/mtype.ts b/src/next/ast/mtype.ts index d491c3d554..29de0edbe7 100644 --- a/src/next/ast/mtype.ts +++ b/src/next/ast/mtype.ts @@ -1,27 +1,7 @@ -import type { OptionalId, Loc, TypeId } from "@/next/ast/common"; -import type { DecodedType, DTypeParamRef } from "@/next/ast/dtype"; +import type { Loc, TypeId } from "@/next/ast/common"; +import type { DTypeParamRef } from "@/next/ast/dtype"; import type * as Ast from "@/next/ast/type"; -export type MFnType = { - readonly typeParams: readonly TypeId[]; - readonly args: readonly MTypedParameter[]; - readonly returnType: DecodedType, -} - -export type MMethodFnType = { - readonly typeParams: readonly TypeId[]; - readonly self: SelfType; - readonly args: readonly MTypedParameter[]; - readonly returnType: DecodedType, -} - -export type MTypedParameter = { - readonly kind: "typed_parameter"; - readonly name: OptionalId; - readonly type: DecodedType; - readonly loc: Loc; -}; - export type SelfType = | MethodGroundType | MVTypeRef @@ -48,17 +28,21 @@ export type MethodGroundType = | MGTypeTuple | MGTypeTensor; -export type MGTypeInt = Ast.TypeInt -export type MGTypeSlice = Ast.TypeSlice -export type MGTypeCell = Ast.TypeCell -export type MGTypeBuilder = Ast.TypeBuilder -export type MGTypeUnit = Ast.TypeUnit -export type MGTypeVoid = Ast.TypeVoid -export type MGTypeNull = Ast.TypeNull -export type MGTypeBool = Ast.TypeBool -export type MGTypeAddress = Ast.TypeAddress -export type MGTypeString = Ast.TypeString -export type MGTypeStringBuilder = Ast.TypeStringBuilder +export type Ground = T & { + readonly ground: "yes", +} + +export type MGTypeInt = Ground +export type MGTypeSlice = Ground +export type MGTypeCell = Ground +export type MGTypeBuilder = Ground +export type MGTypeUnit = Ground +export type MGTypeVoid = Ground +export type MGTypeNull = Ground +export type MGTypeBool = Ground +export type MGTypeAddress = Ground +export type MGTypeString = Ground +export type MGTypeStringBuilder = Ground export type MGTypeRef = { readonly ground: "yes", diff --git a/src/next/ast/via.ts b/src/next/ast/via.ts new file mode 100644 index 0000000000..a4c4d666d6 --- /dev/null +++ b/src/next/ast/via.ts @@ -0,0 +1,25 @@ +import type { TactImport, TactSource } from "@/next/imports/source"; + +import type * as Ast from "@/next/ast"; + +// provenance for definition: where did it come from +export type Via = ViaUser | ViaBuiltin + +// is defined in compiler, always was there +export type ViaBuiltin = { + readonly kind: 'builtin'; +} + +export type ViaUser = { + readonly kind: 'user'; + // which imports it came through + readonly imports: readonly TactImport[]; + // where in the code it was defined + readonly defLoc: Ast.Loc; + // in which source + readonly source: TactSource; +} + +export type ViaMember = { + readonly inheritance: readonly ViaUser[]; +} diff --git a/src/next/types/aliases.ts b/src/next/types/aliases.ts new file mode 100644 index 0000000000..4282c7d4a4 --- /dev/null +++ b/src/next/types/aliases.ts @@ -0,0 +1,302 @@ +import * as Ast from "@/next/ast"; +import * as E from "@/next/types/errors"; +import type { TactSource } from "@/next/imports/source"; +import { throwInternal } from "@/error/errors"; +import { decodeTypeParams } from "@/next/types/type-params"; +import { decodeType } from "@/next/types/types"; +import { zip } from "@/utils/array"; + +export function* getAllAliases( + sigs: ReadonlyMap, + imported: readonly Ast.SourceCheckResult[], + source: TactSource, +) { + const importedAliases: Map = new Map(); + const localAliases: Map = new Map(); + + // status of checking alias bodies + const status: Map = new Map(); + + // check that neither of the types have cyclic alias references + function* checkTypes(types: readonly Ast.DecodedType[]): E.WithLog { + let result = true; + for (const type of types) { + const partialResult = yield* checkType(type); + // NB: separate from previous line to avoid short-circuiting + // we want to give ALL error message + result &&= partialResult; + } + return result; + } + + // check decoded type has no cyclic alias references + function* checkType(type: Ast.DecodedType): E.WithLog { + switch (type.kind) { + case "recover": + case "TyInt": + case "TySlice": + case "TyCell": + case "TyBuilder": + case "unit_type": + case "TypeVoid": + case "TypeNull": + case "TypeBool": + case "TypeAddress": + case "TypeString": + case "TypeParam": + case "TypeStringBuilder": { + return true; + } + case "TypeBounced": + case "TypeMaybe": { + return yield* checkType(type.type); + } + case "map_type": { + return (yield* checkType(type.key)) && (yield* checkType(type.value)); + } + case "type_ref": + case "tuple_type": + case "tensor_type": { + return yield* checkTypes(type.typeArgs); + } + case "TypeAlias": { + const result = yield* checkTypes(type.typeArgs); + const name = type.name.text; + if (importedAliases.has(name)) { + return result; + } + const local = localAliases.get(name); + if (local) { + const alias = yield* decodeAlias(local); + return result && alias.kind === 'alias'; + } + return throwInternal("Alias reference was decoded, but doesn't exist"); + } + } + } + + // convert alias into better representation + function* decodeAlias(decl: Ast.AliasDecl): E.WithLog { + const name = decl.name.text; + const s = status.get(name); + const via = Ast.ViaOrigin(decl.loc, source); + if (!s) { + status.set(name, Visiting); + const params = yield* decodeTypeParams(decl.typeParams); + const type = yield* decodeType(sigs, params, decl.type); + const result = !(yield* checkType(type)) + ? Ast.BadSig(decl.typeParams.length, via) + : Ast.AliasSig(params, type, via); + status.set(name, Result(result)); + return result; + } else if (s.kind === 'result') { + return s.result; + } else { + yield EAliasOccurs(name, decl.loc); + return Ast.BadSig(decl.typeParams.length, via); + } + } + + // collect aliases from imports + for (const { globals } of imported) { + for (const [name, decl] of globals.typeDecls) { + if (decl.kind === 'alias' && !importedAliases.has(name)) { + importedAliases.set(name, decl); + } + } + } + + // collect local aliases + for (const decl of source.items.types) { + const name = decl.name.text; + if (decl.kind === 'alias_decl') { + localAliases.set(name, decl); + } + } + + // decode local aliases and combine with imported + const result: Map = + new Map(importedAliases); + for (const [name, decl] of localAliases) { + const alias = yield* decodeAlias(decl) + result.set(name, alias); + } + return result; +} + +type Status = Result | Visiting +// alias was already decoded +type Result = { + readonly kind: 'result'; + readonly result: Ast.AliasSig | Ast.BadSig; +} +const Result = (alias: Ast.AliasSig | Ast.BadSig): Result => ({ kind: 'result', result: alias }); +// we're decoding it right now +type Visiting = { + readonly kind: 'visiting'; +} +const Visiting: Visiting = { kind: 'visiting' }; + +const EAliasOccurs = ( + name: string, + loc: Ast.Loc, +): E.TcError => ({ + loc, + descr: [ + E.TEText(`Alias "${name}" was expanded inside itself`), + ], +}); + +export const dealiasType = ( + sigs: ReadonlyMap, + aliases: ReadonlyMap, + typeParams: Ast.TypeParams, + type: Ast.Type, +) => { + const recN = (types: readonly Ast.DecodedType[]): readonly Ast.DecodedType[] => { + return types.map(type => rec(type)); + }; + const rec = (type: Ast.DecodedType): Ast.DecodedType => { + switch (type.kind) { + case "recover": { + return type; + } + case "type_ref": { + const args = recN(type.typeArgs); + return Ast.DTypeRef(type.name, args, type.loc); + } + case "TypeAlias": { + const alias = aliases.get(type.name.text); + if (!alias) { + return throwInternal("Decoder returned broken reference"); + } + if (alias.kind === 'bad') { + return Ast.DTypeRecover(); + } + const args = recN(type.typeArgs); + // NB! if we could decode alias once, there might be + // a nested one too + return rec( + substitute(alias.type, alias.typeParams, args) + ); + } + case "TypeParam": { + return type; + } + case "map_type": { + const key = rec(type.key); + const value = rec(type.value); + return Ast.DTypeMap(key, value, type.loc); + } + case "TypeBounced": { + const args = rec(type.type); + return Ast.DTypeBounced(args, type.loc); + } + case "TypeMaybe": { + const args = rec(type.type); + return Ast.DTypeMaybe(args, type.loc); + } + case "tuple_type": { + const args = recN(type.typeArgs); + return Ast.DTypeTuple(args, type.loc); + } + case "tensor_type": { + const args = recN(type.typeArgs); + return Ast.DTypeTensor(args, type.loc); + } + case "TyInt": + case "TySlice": + case "TyCell": + case "TyBuilder": + case "unit_type": + case "TypeVoid": + case "TypeNull": + case "TypeBool": + case "TypeAddress": + case "TypeString": + case "TypeStringBuilder": { + return type; + } + } + }; + + function* root() { + return rec(yield* decodeType(sigs, typeParams, type)); + } + return root(); +}; + +const substitute = ( + type: Ast.DecodedType, + params: Ast.TypeParams, + args: readonly Ast.DecodedType[], +): Ast.DecodedType => { + if (params.order.length !== args.length) { + return throwInternal("Decoder didn't check alias arity"); + } + + const substMap = new Map(zip(params.order, args).map(([param, arg]) => { + return [param.text, arg]; + })); + + const recN = (types: readonly Ast.DecodedType[]): readonly Ast.DecodedType[] => { + return types.map(type => rec(type)); + }; + + const rec = (type: Ast.DecodedType): Ast.DecodedType => { + switch (type.kind) { + case "TypeParam": { + const arg = substMap.get(type.name.text); + if (!arg) { + return throwInternal("Decoder didn't scope alias's type args"); + } + return arg; + } + case "type_ref": { + const args = recN(type.typeArgs); + return Ast.DTypeRef(type.name, args, type.loc); + } + case "TypeAlias": { + const args = recN(type.typeArgs); + return Ast.DTypeAliasRef(type.name, args, type.loc); + } + case "map_type": { + const key = rec(type.key); + const value = rec(type.value); + return Ast.DTypeMap(key, value, type.loc); + } + case "TypeBounced": { + const args = rec(type.type); + return Ast.DTypeBounced(args, type.loc); + } + case "TypeMaybe": { + const args = rec(type.type); + return Ast.DTypeMaybe(args, type.loc); + } + case "tuple_type": { + const args = recN(type.typeArgs); + return Ast.DTypeTuple(args, type.loc); + } + case "tensor_type": { + const args = recN(type.typeArgs); + return Ast.DTypeTensor(args, type.loc); + } + case "recover": + case "TyInt": + case "TySlice": + case "TyCell": + case "TyBuilder": + case "unit_type": + case "TypeVoid": + case "TypeNull": + case "TypeBool": + case "TypeAddress": + case "TypeString": + case "TypeStringBuilder": { + return type; + } + } + }; + + return rec(type); +}; \ No newline at end of file diff --git a/src/next/types/builtins.ts b/src/next/types/builtins.ts index 2d03e01342..7c9f5cb669 100644 --- a/src/next/types/builtins.ts +++ b/src/next/types/builtins.ts @@ -4,38 +4,42 @@ import * as Ast from "@/next/ast"; const r = Ast.Builtin(); -const Param = (name: string, type: Ast.DecodedType) => { - return Ast.MTypedParameter( - Ast.Id(name, r), - type, - r, - ); +const TypeParams = (typeParams: readonly string[]): Ast.TypeParams => { + const arr = typeParams.map(name => Ast.TypeId(name, r)); + return Ast.TypeParams(arr, new Set(typeParams)); }; -const t = Ast.TypeId("T", r); -const tParam = Ast.DTypeParamRef(t, r); - -const k = Ast.TypeId("K", r); -const kParam = Ast.DTypeParamRef(k, r); -const key = Param("key", kParam); +const Params = (params: Record): Ast.Parameters => { + const order: Ast.Parameter[] = []; + const set: Set = new Set(); + for (const [name, type] of Object.entries(params)) { + order.push(Ast.Parameter(Ast.Id(name, r), type, r)); + set.add(name); + } + return Ast.Parameters(order, set); +}; -const v = Ast.TypeId("V", r); -const vParam = Ast.DTypeParamRef(v, r); -const value = Param("value", vParam); +const Ref = (name: string): Ast.DTypeParamRef => { + return Ast.DTypeParamRef(Ast.TypeId(name, r), r); +}; -const mapType = Ast.MVTypeMap(kParam, vParam, r); +const mapType = Ast.MVTypeMap(Ref("K"), Ref("V"), r); -const GenericFn = (name: string, typeParams: readonly Ast.TypeId[], args: readonly Ast.MTypedParameter[], returnType: Ast.DecodedType): [string, Ast.MFnType] => { - return [name, Ast.MFnType(typeParams, args, returnType)]; +const GenericFn = (name: string, typeParams: readonly string[], params: Record, returnType: Ast.DecodedType): [string, Ast.DecodedFnType] => { + return [name, Ast.DecodedFnType( + TypeParams(typeParams), + Params(params), + returnType, + )]; }; -const Fn = (name: string, args: readonly Ast.MTypedParameter[], returnType: Ast.DecodedType): [string, Ast.MFnType] => { - return [name, Ast.MFnType([], args, returnType)]; +const Fn = (name: string, params: Record, returnType: Ast.DecodedType): [string, Ast.DecodedFnType] => { + return GenericFn(name, [], params, returnType); }; -const MapMethod = (name: string, args: readonly Ast.MTypedParameter[], returnType: Ast.DecodedType): [string, Ast.MMethodFnType] => { - return [name, Ast.MMethodFnType( - [k, v], +const MapMethod = (name: string, params: Record, returnType: Ast.DecodedType): [string, Ast.DecodedMethodType] => { + return [name, Ast.DecodedMethodType( + TypeParams(["K", "V"]), mapType, - args, + Params(params), returnType, )]; }; @@ -61,75 +65,75 @@ export const builtinTypes = new Map([ ].map(s => [s, s])); const ArithBin = (name: string) => { - return Fn(name, [Param("left", Int), Param("right", Int)], Int); + return Fn(name, { left: Int, right: Int }, Int); }; const CompBin = (name: string) => { - return Fn(name, [Param("left", Int), Param("right", Int)], Bool); + return Fn(name, { left: Int, right: Int }, Bool); }; const BoolBin = (name: string) => { - return Fn(name, [Param("left", Bool), Param("right", Bool)], Bool); + return Fn(name, { left: Bool, right: Bool }, Bool); }; const EqBin = (name: string) => { - return GenericFn(name, [t], [Param("left", tParam), Param("right", tParam)], Bool); + return GenericFn(name, ["T"], { left: Ref("T"), right: Ref("T") }, Bool); }; -export const builtinFunctions: Map = new Map([ +export const builtinFunctions: Map = new Map([ // dump(arg: T): Void - GenericFn("dump", [t], [Param("data", tParam)], Void), + GenericFn("dump", ["T"], { data: Ref("T") }, Void), // ton(value: String): Int - Fn("ton", [Param("value", String)], Int), + Fn("ton", { value: String }, Int), // require(that: Bool, msg: String): Void - Fn("require", [Param("that", Bool), Param("msg", String)], Void), + Fn("require", { that: Bool, msg: String }, Void), // address(s: String): Address - Fn("address", [Param("s", String)], Address), + Fn("address", { s: String }, Address), // cell(bocBase64: String): Cell - Fn("cell", [Param("bocBase64", String)], Cell), + Fn("cell", { bocBase64: String }, Cell), // dumpStack(): Void - Fn("dumpStack", [], Void), + Fn("dumpStack", {}, Void), // emptyMap(): map - GenericFn("emptyMap", [k, v], [], mapType), + GenericFn("emptyMap", ["K", "V"], {}, mapType), // slice(bocBase64: String): Slice - Fn("slice", [Param("bocBase64", String)], Slice), + Fn("slice", { bocBase64: String }, Slice), // rawSlice(hex: String): Slice - Fn("rawSlice", [Param("hex", String)], Slice), + Fn("rawSlice", { hex: String }, Slice), // ascii(str: String): Int - Fn("ascii", [Param("str", String)], Int), + Fn("ascii", { str: String }, Int), // crc32(str: String): Int - Fn("crc32", [Param("str", String)], Int), + Fn("crc32", { str: String }, Int), // sha256(data: Slice): Int - Fn("sha256", [Param("str", Slice)], Int), + Fn("sha256", { str: Slice }, Int), ]); -export const builtinMethods: Map = new Map([ +export const builtinMethods: Map = new Map([ // set(key: K, value: V): void - MapMethod("set", [key, value], Void), + MapMethod("set", { key: Ref("K"), value: Ref("V") }, Void), // get(key: K): Maybe - MapMethod("get", [key], Maybe(vParam)), + MapMethod("get", { key: Ref("K") }, Maybe(Ref("V"))), // del(key: K): Bool - MapMethod("del", [key], Bool), + MapMethod("del", { key: Ref("K") }, Bool), // asCell(): Maybe - MapMethod("asCell", [], Maybe(Cell)), + MapMethod("asCell", {}, Maybe(Cell)), // isEmpty(): Bool - MapMethod("isEmpty", [], Bool), + MapMethod("isEmpty", {}, Bool), // exists(key: K): Bool - MapMethod("exists", [key], Bool), + MapMethod("exists", { key: Ref("K") }, Bool), // deepEquals(other: map): Bool - MapMethod("deepEquals", [Param("other", mapType)], Bool), + MapMethod("deepEquals", { other: mapType }, Bool), // replace(key: K, value: V): Bool - MapMethod("replace", [key, value], Bool), + MapMethod("replace", { key: Ref("K"), value: Ref("V") }, Bool), // replaceGet(key: K, value: V): map - MapMethod("replaceGet", [key, value], mapType), + MapMethod("replaceGet", { key: Ref("K"), value: Ref("V") }, mapType), ]); -export const builtinUnary: Map = new Map([ - Fn("+", [Param("arg", Int)], Int), - Fn("-", [Param("arg", Int)], Int), - Fn("~", [Param("arg", Int)], Int), - Fn("!", [Param("arg", Bool)], Bool), - GenericFn("!!", [t], [Param("arg", Maybe(tParam))], tParam), +export const builtinUnary: Map = new Map([ + Fn("+", { arg: Int }, Int), + Fn("-", { arg: Int }, Int), + Fn("~", { arg: Int }, Int), + Fn("!", { arg: Bool }, Bool), + GenericFn("!!", ["T"], { arg: Maybe(Ref("T")) }, Ref("T")), ]); -export const builtinBinary: Map = new Map([ +export const builtinBinary: Map = new Map([ // (left: Int, right: Int): Int ArithBin("+"), ArithBin("-"), @@ -154,27 +158,27 @@ export const builtinBinary: Map = new Map([ BoolBin("||"), ]); -export const getStaticBuiltin = (type: Ast.DecodedType): Map => { +export const getStaticBuiltin = (type: Ast.DecodedType): Map => { return new Map([ // Foo.fromSlice(slice: Slice) - Fn("fromSlice", [Param("slice", Slice)], type), + Fn("fromSlice", { slice: Slice }, type), // Foo.fromSlice(cell: Cell) - Fn("fromCell", [Param("cell", Cell)], type), + Fn("fromCell", { cell: Cell }, type), ]) }; export const structBuiltin = new Map([ // Foo.toSlice(): Slice - Fn("toSlice", [], Slice), + Fn("toSlice", {}, Slice), // Foo.toCell(): Cell - Fn("toCell", [], Cell), + Fn("toCell", {}, Cell), ]); export const messageBuiltin = new Map([ // Foo.toSlice(): Slice - Fn("toSlice", [], Slice), + Fn("toSlice", {}, Slice), // Foo.toCell(): Cell - Fn("toCell", [], Cell), + Fn("toCell", {}, Cell), // Foo.opcode(): Int - Fn("opcode", [], Int) + Fn("opcode", {}, Int) ]); diff --git a/src/next/types/constants.ts b/src/next/types/constants.ts new file mode 100644 index 0000000000..eb313b1fce --- /dev/null +++ b/src/next/types/constants.ts @@ -0,0 +1,78 @@ +import * as Ast from "@/next/ast"; +import * as E from "@/next/types/errors"; +import { dealiasType } from "@/next/types/aliases"; +import type { TactImport, TactSource } from "@/next/imports/source"; +import { builtinFunctions } from "@/next/types/builtins"; +import { checkExpr } from "@/next/types/expression"; + +const errorKind = "function"; + +export function* getAllConstants( + imported: readonly Ast.SourceCheckResult[], + source: TactSource, + sigs: ReadonlyMap, + aliases: ReadonlyMap, + fnSigs: ReadonlyMap, + extSigs: ReadonlyMap, +): E.WithLog> { + const allConstSigs = [ + // imported + ...imported.flatMap(({ globals, importedBy }) => ( + [...globals.constSigs] + .map(([name, s]) => [name, toSigDecoded(s, importedBy)] as const) + )), + // local + ...yield* E.mapLog(source.items.constants, function* (constant) { + const { name, init, loc } = constant; + const via = Ast.ViaOrigin(loc, source); + const initType = yield* decodeInit(init, loc, sigs, aliases); + return [name.text, Ast.ConstSig(initType, via)] as const; + }), + ]; + // remove builtins + const filteredSigs = yield* E.filterLog(allConstSigs, function* ([name, { via }]) { + const isBuiltin = builtinFunctions.has(name); + if (isBuiltin) { + yield E.ERedefine(errorKind, name, Ast.ViaBuiltin(), via); + } + return !isBuiltin; + }); + return yield* E.toMap(errorKind, filteredSigs); +} + +function* decodeInit( + init: Ast.ConstantInit, + loc: Ast.Loc, + sigs: ReadonlyMap, + aliases: ReadonlyMap, +): E.WithLog { + if (init.kind === "constant_decl") { + yield ETopLevelDecl(loc); + return Ast.DTypeRecover(); + } + const { type, initializer } = init; + + const typeParams = Ast.TypeParams([], new Set()); + const ascribedType = type + ? yield* dealiasType(sigs, aliases, typeParams, type) + : undefined; + + const computedType = yield* checkExpr( + initializer, + + ); + + return ascribedType; +} + +const toSigDecoded = (fn: Ast.ConstSig, importedBy: TactImport): Ast.ConstSig => { + const via = Ast.ViaImport(importedBy, fn.via); + return Ast.ConstSig(fn.type, via); +}; + +const ETopLevelDecl = (loc: Ast.Loc): E.TcError => ({ + loc, + descr: [ + E.TEText(`Top-level constant must have a body`), + ], +}); diff --git a/src/next/types/errors.ts b/src/next/types/errors.ts index 5128ee1557..1b7d551531 100644 --- a/src/next/types/errors.ts +++ b/src/next/types/errors.ts @@ -1,6 +1,6 @@ import { throwInternal } from "@/error/errors"; -import type { Loc } from "@/next/ast"; -import type * as V from "@/next/types/via"; +import type { Loc, Via, ViaUser } from "@/next/ast"; +import type * as V from "@/next/ast/via"; export type WithLog = Generator @@ -16,6 +16,49 @@ export function runLog(gen: Generator): readonly [R, readon } } +export function* mapLog(xs: readonly T[], f: (x: T) => WithLog): WithLog { + const result: U[] = []; + for (const x of xs) { + result.push(yield* f(x)); + } + return result; +} + +export function* filterLog(xs: readonly T[], f: (x: T) => WithLog): WithLog { + const result: T[] = []; + for (const x of xs) { + const res = yield* f(x); + if (res) { + result.push(x); + } + } + return result; +} + +export function* toMap( + kind: string, + xs: readonly (readonly [string, V])[], +): WithLog> { + const result: Map = new Map(); + for (const [key, next] of xs) { + const prev = result.get(key); + if (prev) { + yield ERedefine(kind, key, next.via, prev.via); + } else { + result.set(key, next); + } + } + return result; +} + +export const ERedefine = (kind: string, name: string, prev: Via, next: ViaUser): TcError => ({ + loc: viaToRange(next), + descr: [ + TEText(`There already is a ${kind} "${name}" from`), + TEVia(prev), + ], +}); + export type TcError = { // location where IDE should show this error readonly loc: Loc; diff --git a/src/next/types/expression.ts b/src/next/types/expression.ts new file mode 100644 index 0000000000..d168f55cda --- /dev/null +++ b/src/next/types/expression.ts @@ -0,0 +1,12 @@ +import * as Ast from "@/next/ast"; +import * as E from "@/next/types/errors"; +import type { TactImport, TactSource } from "@/next/imports/source"; +import { builtinFunctions } from "@/next/types/builtins"; +import { decodeFnType } from "@/next/types/util"; + +export function* checkExpr( + node: Ast.Expression, + +) { + +} \ No newline at end of file diff --git a/src/next/types/extensions.ts b/src/next/types/extensions.ts new file mode 100644 index 0000000000..ee5f6c905d --- /dev/null +++ b/src/next/types/extensions.ts @@ -0,0 +1,420 @@ +import * as Ast from "@/next/ast"; +import * as E from "@/next/types/errors"; +import { dealiasType } from "@/next/types/aliases"; +import { decodeFnType } from "@/next/types/util"; +import { builtinMethods } from "@/next/types/builtins"; +import { throwInternal } from "@/error/errors"; +import type { TactImport, TactSource } from "@/next/imports/source"; +import { zip } from "@/utils/array"; + +export function* getAllExtensions( + imported: readonly Ast.SourceCheckResult[], + source: TactSource, + sigs: ReadonlyMap, + aliases: Map, +): E.WithLog> { + const importedExts = imported.flatMap(({ globals, importedBy }) => ( + [...globals.extSigs] + .map(([name, exts]) => [name, exts.map(ext => toSigDecoded(ext, importedBy))] as const) + )); + const localExts = yield* E.mapLog(source.items.extensions, function* (ext) { + const { selfType, mutates, fun } = ext; + const { name, type, body, inline, loc } = fun; + const via = Ast.ViaOrigin(loc, source); + const decodedFn = yield* decodeFnType(type, via, sigs, aliases); + const self = yield* toSelfType(sigs, yield* dealiasType( + sigs, + aliases, + decodedFn.typeParams, + selfType, + )); + if (!self) { + return []; + } + const methodType = Ast.DecodedMethodType( + decodedFn.typeParams, + self, + decodedFn.params, + decodedFn.returnType, + ); + return [[name.text, [Ast.ExtSig(methodType, via)]] as const]; + }); + + const result: Map = new Map(); + for (const [name, exts] of [...importedExts, ...localExts.flat()]) { + const prev = result.get(name) ?? []; + result.set(name, prev); + for (const ext of exts) { + const builtin = builtinMethods.get(name); + if (builtin && !isCompatible(builtin, ext.type)) { + yield EMethodOverlap(name, Ast.ViaBuiltin(), ext.via); + continue; + } + const prevs = result.get(name) ?? []; + if (yield* areCompatible(name, prevs, ext)) { + prev.push(ext); + } + } + } + + return result; +} + +function* areCompatible( + name: string, + prevs: readonly Ast.ExtSig[], + next: Ast.ExtSig, +): E.WithLog { + for (const prev of prevs) { + // NB! checking by reference, see `toSigDecoded` + if (prev.type !== next.type && !isCompatible(prev.type, next.type)) { + yield EMethodOverlap(name, prev.via, next.via); + return false; + } + } + return true; +} + +const EMethodOverlap = ( + name: string, + prev: Ast.Via, + next: Ast.ViaUser, +): E.TcError => ({ + loc: E.viaToRange(next), + descr: [ + E.TEText(`Method "${name}" overlaps previously defined method`), + E.TEVia(prev), + ], +}); + +function isCompatible( + prev: Ast.DecodedMethodType, + next: Ast.DecodedMethodType, +): boolean { + return prev.self.kind !== next.self.kind || + prev.self.ground === 'yes' && + next.self.ground === 'yes' && + !areEqual(prev.self, next.self); +} + +function areEqual( + prevSelf: Ast.MethodGroundType, + nextSelf: Ast.MethodGroundType +): boolean { + switch (prevSelf.kind) { + case "TyInt": + case "TySlice": + case "TyCell": + case "TyBuilder": + case "unit_type": + case "TypeVoid": + case "TypeNull": + case "TypeBool": + case "TypeAddress": + case "TypeString": + case "TypeStringBuilder": { + return prevSelf.kind === nextSelf.kind; + } + case "type_ref": { + return prevSelf.kind === nextSelf.kind && + prevSelf.name.text === nextSelf.name.text && + allEqual(prevSelf.typeArgs, nextSelf.typeArgs); + } + case "map_type": { + return prevSelf.kind === nextSelf.kind && + allEqual( + [prevSelf.key, prevSelf.value], + [nextSelf.key, nextSelf.value], + ); + } + case "TypeMaybe": { + return prevSelf.kind === nextSelf.kind && + areEqual(prevSelf.type, prevSelf.type); + } + case "tuple_type": + case "tensor_type": { + return prevSelf.kind === nextSelf.kind && + allEqual(prevSelf.typeArgs, nextSelf.typeArgs); + } + } +} + +function allEqual( + prevs: readonly Ast.MethodGroundType[], + nexts: readonly Ast.MethodGroundType[], +): boolean { + return zip(prevs, nexts).every(([prev, next]) => areEqual(prev, next)); +} + +const toSigDecoded = ( + prev: Ast.ExtSig, + importedBy: TactImport, +): Ast.ExtSig => { + const via = Ast.ViaImport(importedBy, prev.via); + // NB! it's important to NOT change the reference to prev.type + // as we're deduplicating same extension by reference + return Ast.ExtSig(prev.type, via); +}; + +function* toSelfType( + sigs: ReadonlyMap, + type: Ast.DecodedType, +): E.WithLog { + switch (type.kind) { + case "recover": { + return undefined; + } + case "type_ref": { + const def = sigs.get(type.name.text); + if (!def) { + return throwInternal("Decoder returned broken reference") + } + switch (def.use) { + case "alias": { + return throwInternal("Decoder returned broken reference") + } + case "contract": { + yield ENoMethods("contract", type.loc); + return undefined; + } + case "forbidden": { + return undefined; + } + case "usual": { + const allVars = type.typeArgs.filter(arg => { + return arg.kind === 'TypeParam'; + }); + if (type.typeArgs.length === allVars.length) { + const argNames = new Set(allVars.map(v => v.name.text)); + if (argNames.size !== allVars.length) { + // type variables are not distinct + yield EBadMethodType(type.loc); + return undefined; + } + return Ast.MVTypeRef( + type.name, + allVars, + type.loc, + ); + } + if (type.typeArgs.length > 0 && allVars.length > 0) { + // has vars, but it's not all the parameters + yield EBadMethodType(type.loc); + return undefined; + } + const ground: Ast.MethodGroundType[] = []; + for (const arg of type.typeArgs) { + const result = yield* toGroundType(sigs, arg); + if (!result) { + yield EBadMethodType(type.loc); + return undefined; + } + ground.push(result); + } + return Ast.MGTypeRef( + type.name, + ground, + type.loc, + ); + } + } + // somehow typescript wants this + return throwInternal("Unknown declaration type"); + } + case "TypeAlias": { + return throwInternal("resolveAliases didn't resolve them"); + } + case "TypeParam": { + yield EBadMethodType(type.loc); + return undefined; + } + case "map_type": { + if (type.key.kind === 'TypeParam' && type.value.kind === 'TypeParam') { + return Ast.MVTypeMap( + type.key, + type.value, + type.loc, + ); + } + const ground = yield* toGroundType(sigs, type); + if (!ground) { + yield EBadMethodType(type.loc); + return undefined; + } + return ground; + } + case "TypeBounced": { + yield EBadMethodType(type.loc); + return undefined; + } + case "TypeMaybe": { + if (type.type.kind === 'TypeParam') { + return Ast.MVTypeMaybe( + type.type, + type.loc, + ); + } + const ground = yield* toGroundType(sigs, type); + if (!ground) { + yield EBadMethodType(type.loc); + return undefined; + } + return ground; + } + case "tensor_type": + case "tuple_type": { + const mvCons = type.kind === 'tuple_type' + ? Ast.MVTypeTuple + : Ast.MVTypeTensor; + const allVars = type.typeArgs.filter(arg => { + return arg.kind === 'TypeParam'; + }); + if (type.typeArgs.length === allVars.length) { + const argNames = new Set(allVars.map(v => v.name.text)); + if (argNames.size !== allVars.length) { + // type variables are not distinct + yield EBadMethodType(type.loc); + return undefined; + } + return mvCons( + allVars, + type.loc, + ); + } + const ground = yield* toGroundType(sigs, type); + if (!ground) { + yield EBadMethodType(type.loc); + return undefined; + } + return ground; + } + case "TyInt": + case "TySlice": + case "TyCell": + case "TyBuilder": + case "unit_type": + case "TypeVoid": + case "TypeNull": + case "TypeBool": + case "TypeAddress": + case "TypeString": + case "TypeStringBuilder": { + return { + ground: "yes", + ...type, + }; + } + } +} + +function* toGroundType( + sigs: ReadonlyMap, + type: Ast.DecodedType +): E.WithLog { + switch (type.kind) { + case "recover": { + return undefined; + } + case "type_ref": { + const typeDecl = sigs.get(type.name.text); + if (!typeDecl) { + return throwInternal("Decoder returned broken reference") + } + switch (typeDecl.use) { + case "contract": { + yield ENoMethods("contract", type.loc); + return undefined; + } + case "alias": { + return throwInternal("Decoder returned broken reference") + } + case "forbidden": { + return undefined; + } + case "usual": { + const ground: Ast.MethodGroundType[] = []; + for (const arg of type.typeArgs) { + const result = yield* toGroundType(sigs, arg); + if (!result) { + return undefined; + } + ground.push(result); + } + return Ast.MGTypeRef( + type.name, + ground, + type.loc, + ); + } + } + // somehow typescript wants this + return throwInternal("Unknown declaration type"); + } + case "TypeAlias": { + return throwInternal("resolveAliases didn't resolve them"); + } + case "TypeParam": { + return undefined; + } + case "map_type": { + const key = yield* toGroundType(sigs, type.key); + const value = yield* toGroundType(sigs, type.value); + return key && value && Ast.MGTypeMap(key, value, type.loc); + } + case "TypeBounced": { + return undefined; + } + case "TypeMaybe": { + const child = yield* toGroundType(sigs, type.type); + return child && Ast.MGTypeMaybe(child, type.loc); + } + case "tuple_type": { + const children = yield* E.mapLog(type.typeArgs, function* (child) { + const result = yield* toGroundType(sigs, child); + return result ? [result] : []; + }); + return Ast.MGTypeTuple(children.flat(), type.loc); + } + case "tensor_type": { + const children = yield* E.mapLog(type.typeArgs, function* (child) { + const result = yield* toGroundType(sigs, child); + return result ? [result] : []; + }); + return Ast.MGTypeTensor(children.flat(), type.loc); + } + case "TyInt": + case "TySlice": + case "TyCell": + case "TyBuilder": + case "unit_type": + case "TypeVoid": + case "TypeNull": + case "TypeBool": + case "TypeAddress": + case "TypeString": + case "TypeStringBuilder": { + return { + ground: "yes", + ...type, + }; + } + } +} + +const EBadMethodType = ( + loc: Ast.Loc, +): E.TcError => ({ + loc, + descr: [ + E.TEText(`Type of self must either have no type parameters, or be a generic type with distinct type parameters`), + ], +}); +const ENoMethods = ( + kind: string, + loc: Ast.Loc, +): E.TcError => ({ + loc, + descr: [ + E.TEText(`Cannot define methods on ${kind}`), + ], +}); \ No newline at end of file diff --git a/src/next/types/flat.ts b/src/next/types/flat.ts deleted file mode 100644 index f1df87aed2..0000000000 --- a/src/next/types/flat.ts +++ /dev/null @@ -1,124 +0,0 @@ -import type * as Ast from "@/next/ast"; -import type { TactImport } from "@/next/imports/source"; -import * as V from "@/next/types/via"; - -export type Scope = { - readonly types: Registry; - readonly functions: Registry; - readonly constants: Registry; - readonly extensions: ExtRegistry; -} - -export type Registry = Map>; - -export type Def = { - // the definition - readonly value: T; - // where it was defined - readonly via: V.ViaUser; -} -export const Def = (value: T, via: V.ViaUser): Def => ({ value, via }); -export const importDef = (importedBy: TactImport, { value, via }: Def): Def => Def(value, V.ViaImport(importedBy, via)); - -export type ExtRegistry = Map - -export type ExtEntry = { - readonly self: Ast.SelfType; - readonly typeParams: readonly Ast.TypeId[]; - readonly mutates: boolean; - readonly fun: Ast.Function; - readonly via: V.ViaUser; -} - -export type FlatDecl = - | InvalidDecl - | FlatAlias - | FlatContract - | FlatTrait - | Ast.StructDecl - | Ast.MessageDecl - | Ast.UnionDecl; - -export type InvalidDecl = { - readonly kind: 'InvalidDecl'; - readonly name: Ast.TypeId; - readonly arity: number; - readonly loc: Ast.Loc; -} -export const InvalidDecl = ( - name: Ast.TypeId, - arity: number, - loc: Ast.Loc, -): InvalidDecl => ({ kind: 'InvalidDecl', name, arity, loc }); - -export type FlatAlias = { - readonly kind: 'FlatAlias'; - readonly name: Ast.TypeId; - readonly typeParams: readonly Ast.TypeId[]; - readonly type: Ast.DecodedType; - readonly loc: Ast.Loc; -} -export const FlatAlias = ( - name: Ast.TypeId, - typeParams: readonly Ast.TypeId[], - type: Ast.DecodedType, - loc: Ast.Loc, -): FlatAlias => ({ kind: 'FlatAlias', name, type, typeParams, loc }); - -export type Schema = { - readonly typeArgs: readonly Ast.TypeId[]; - readonly type: Ast.DecodedType; -} - -export type FlatContent = { - readonly name: Ast.TypeId; - readonly attributes: readonly Ast.ContractAttribute[]; - readonly declarations: Ast.LocalItems; - readonly loc: Ast.Loc; -}; -export const FlatContent = ( - name: Ast.TypeId, - attributes: readonly Ast.ContractAttribute[], - declarations: Ast.LocalItems, - loc: Ast.Loc, -): FlatContent => ({ attributes, declarations, name, loc }); - -export type FlatContract = { - readonly kind: 'FlatContract'; - readonly init: undefined | Ast.Init; - readonly content: FlatContent; -}; -export const FlatContract = ( - init: undefined | Ast.Init, - content: FlatContent, -): FlatContract => ({ kind: 'FlatContract', content, init }); - -export type FlatTrait = { - readonly kind: 'FlatTrait'; - readonly content: FlatContent; -}; -export const FlatTrait = (content: FlatContent): FlatTrait => ({ kind: 'FlatTrait', content }); - -export type FlatItems = { - readonly fields: readonly Ast.FieldDecl[]; - readonly methods: readonly FlatMethod[]; - readonly receivers: readonly Ast.Receiver[]; - readonly constants: readonly Ast.Constant[]; -}; -export const FlatItems = ( - fields: readonly Ast.FieldDecl[], - methods: readonly FlatMethod[], - receivers: readonly Ast.Receiver[], - constants: readonly Ast.Constant[], -): FlatItems => ({ constants, fields, methods, receivers }); - -export type FlatMethod = { - readonly mutates: boolean; - readonly fun: Ast.Function; - readonly get: undefined | Ast.GetAttribute; -}; -export const FlatMethod = ( - mutates: boolean, - fun: Ast.Function, - get: undefined | Ast.GetAttribute, -): FlatMethod => ({ fun, get, mutates }); diff --git a/src/next/types/functions.ts b/src/next/types/functions.ts new file mode 100644 index 0000000000..3b32d0de27 --- /dev/null +++ b/src/next/types/functions.ts @@ -0,0 +1,53 @@ +import * as Ast from "@/next/ast"; +import * as E from "@/next/types/errors"; +import type { TactImport, TactSource } from "@/next/imports/source"; +import { builtinFunctions } from "@/next/types/builtins"; +import { decodeFnType } from "@/next/types/util"; + +const errorKind = "function"; + +export function* getAllFunctions( + imported: readonly Ast.SourceCheckResult[], + source: TactSource, + sigs: ReadonlyMap, + aliases: Map, +): E.WithLog> { + const allFnSigs = [ + // imported + ...imported.flatMap(({ globals, importedBy }) => ( + [...globals.fnSigs] + .map(([name, s]) => [name, toSigDecoded(s, importedBy)] as const) + )), + // local + ...yield* E.mapLog(source.items.functions, function* (fn) { + const { name, type, inline, body, loc } = fn; + const via = Ast.ViaOrigin(loc, source); + const fnType = yield* decodeFnType(type, via, sigs, aliases); + return [name.text, Ast.FnSig(fnType, via)] as const; + }), + ]; + + // remove duplicates and builtins + const filteredSigs: Map = new Map(); + for (const [name, sig] of allFnSigs) { + const isBuiltin = builtinFunctions.has(name); + if (isBuiltin) { + yield E.ERedefine(errorKind, name, Ast.ViaBuiltin(), sig.via); + continue; + } + const prev = filteredSigs.get(name); + if (!prev) { + filteredSigs.set(name, sig); + continue; + } + if (prev.via.source !== sig.via.source) { + yield E.ERedefine(errorKind, name, sig.via, prev.via); + } + } + return filteredSigs; +} + +const toSigDecoded = (fn: Ast.FnSig, importedBy: TactImport): Ast.FnSig => { + const via = Ast.ViaImport(importedBy, fn.via); + return Ast.FnSig(fn.type, via); +}; diff --git a/src/next/types/reg.ts b/src/next/types/reg.ts new file mode 100644 index 0000000000..04c91b1de7 --- /dev/null +++ b/src/next/types/reg.ts @@ -0,0 +1,30 @@ +import * as E from "@/next/types/errors"; +import * as Ast from "@/next/ast"; + +export function* concatReg( + builtins: Map, + kind: string, + all: ReadonlyMap[] +): E.WithLog> { + const prev: Map = new Map(); + for (const next of all) { + for (const [name, nextItem] of next) { + const prevItem = prev.get(name); + // defined in compiler + if (builtins.has(name)) { + yield E.ERedefine(kind, name, Ast.ViaBuiltin(), nextItem.via); + continue; + } + // not defined yet; define it now + if (typeof prevItem === 'undefined') { + prev.set(name, nextItem); + continue; + } + // already defined, and it's not a diamond situation + if (prevItem.via.source !== nextItem.via.source) { + yield E.ERedefine(kind, name, prevItem.via, nextItem.via); + } + } + } + return prev; +} \ No newline at end of file diff --git a/src/next/types/traits.ts b/src/next/types/traits.ts new file mode 100644 index 0000000000..36486ee363 --- /dev/null +++ b/src/next/types/traits.ts @@ -0,0 +1,36 @@ +import * as Ast from "@/next/ast"; +import * as E from "@/next/types/errors"; +import type { TactImport, TactSource } from "@/next/imports/source"; +import { decodeFnType } from "@/next/types/util"; + +export function* getTraitSigs( + imported: readonly Ast.SourceCheckResult[], + source: TactSource, + sigs: ReadonlyMap, + aliases: Map, +) { + const allTraitsSigs = [ + // imported + ...imported.flatMap(({ globals, importedBy }) => ( + [...globals.typeDecls] + .flatMap(([name, s]) => { + if (s.kind !== 'trait') { + return []; + } + return [[name, toSigDecoded(s, importedBy)] as const]; + }) + )), + // local + ...yield* E.mapLog(source.items.functions, function* (fn) { + const { name, type, inline, body, loc } = fn; + const via = Ast.ViaOrigin(loc, source); + const fnType = yield* decodeFnType(type, via, sigs, aliases); + return [name.text, Ast.FnSig(fnType, via)] as const; + }), + ]; +} + +const toSigDecoded = (fn: Ast.TraitSig, importedBy: TactImport): Ast.FnSig => { + const via = Ast.ViaImport(importedBy, fn.via); + return Ast.FnSig(fn.type, via); +}; diff --git a/src/next/types/type-params.ts b/src/next/types/type-params.ts new file mode 100644 index 0000000000..bc83382dab --- /dev/null +++ b/src/next/types/type-params.ts @@ -0,0 +1,30 @@ +import * as Ast from "@/next/ast"; +import * as E from "@/next/types/errors"; +import { recoverName } from "@/next/types/util"; + +export function* decodeTypeParams(ids: readonly Ast.TypeId[]): E.WithLog { + const set: Set = new Set(); + const order: Ast.TypeId[] = []; + + for (const id of ids) { + if (set.has(id.text)) { + yield EDuplicateTypeParam(id.text, id.loc); + const newName = recoverName(id.text, set); + order.push(Ast.TypeId(newName, id.loc)); + } else { + set.add(id.text); + order.push(id); + } + } + + return Ast.TypeParams(ids, set); +} + +const EDuplicateTypeParam = (name: string, loc: Ast.Loc): E.TcError => ({ + loc, + descr: [ + E.TEText(`Duplicate type parameter "${name}"`), + ], +}); + + diff --git a/src/next/types/typecheck.ts b/src/next/types/typecheck.ts index 00317fdce3..c92b266054 100644 --- a/src/next/types/typecheck.ts +++ b/src/next/types/typecheck.ts @@ -1,37 +1,22 @@ /* eslint-disable @typescript-eslint/consistent-type-imports */ /* eslint-disable @typescript-eslint/no-unused-vars */ /* eslint-disable require-yield */ -import * as V from "@/next/types/via"; +// import { logDeep } from "@/utils/log-deep.build"; import * as E from "@/next/types/errors"; import * as Ast from "@/next/ast"; import { memo } from "@/utils/tricks"; import type { ResolvedImport, TactImport, TactSource } from "@/next/imports/source"; -// import { logDeep } from "@/utils/log-deep.build"; -import { builtinFunctions, builtinMethods, builtinTypes } from "@/next/types/builtins"; -import { Def, ExtEntry, ExtRegistry, FlatAlias, FlatDecl, InvalidDecl, Registry, Scope } from "@/next/types/flat"; -import { throwInternal } from "@/error/errors"; -import { zip } from "@/utils/array"; - -export type SourceCheckResult = { - // import that lead to reading this file - readonly importedBy: TactImport; - // scopes that were computed from this file - readonly globals: Scope; -} - -export type TypeEntry = { - readonly arity: number; - readonly decl: T -} -export const TypeEntry = ( - arity: number, - decl: T, -): TypeEntry => ({ arity, decl }); - -export const typecheck = (root: TactSource): [Scope, E.TcError[]] => { +import { getDecodeType } from "@/next/types/types"; +import { getAllAliases } from "@/next/types/aliases"; +import { getAllFunctions } from "@/next/types/functions"; +import { getAllConstants } from "@/next/types/constants"; +import { getAllExtensions } from "@/next/types/extensions"; +import { getTraitSigs } from "@/next/types/traits"; + +export const typecheck = (root: TactSource): [Ast.Scope, E.TcError[]] => { const allErrors: E.TcError[] = []; - const recur = memo((source: TactSource): Scope => { + const recur = memo((source: TactSource): Ast.Scope => { const [value, errors] = E.runLog(tcSource( // leave only imports of .tact onlyTactImports(source.imports) @@ -65,64 +50,55 @@ const onlyTactImports = (imports: readonly ResolvedImport[]): readonly TactImpor function* tcSource( // list of import+source pairs for every of file's imports - imported: readonly SourceCheckResult[], + imported: readonly Ast.SourceCheckResult[], // source for current file source: TactSource, -): E.WithLog { - const importedTypes = imported.map(({ globals, importedBy }) => ( - mapRegVia>(new Map( - globals.types.entries().map(([name, { value, via }]) => [ - name, { value: TypeEntry(getArity(value), value), via } - ]) - ), importedBy) - )); - const localTypes = source.items.types.map((item) => createRef( - item.name.text, - TypeEntry(getArity(item), item), - V.ViaOrigin(item.loc, source), - )); - const undecodedTypes = yield* concatReg( - builtinTypes, - 'type', - [...importedTypes, ...localTypes], +): E.WithLog { + // kind-level descriptors for types + const allSigs = yield* getDecodeType( + imported, + source, ); - const aliasDecodedTypes = yield* decodeAliases(undecodedTypes); - - const functions = yield* mergeReg( - imported, source, - 'function', - (s) => s.functions, - source.items.functions, - builtinFunctions, + // aliases can loop, have to check separately + const allAliasSigs = yield* getAllAliases( + allSigs, + imported, + source, ); - - const constants = yield* mergeReg( - imported, source, - 'constant', - (s) => s.constants, - source.items.constants, - new Map([]), + // get descriptors for functions + const fnSigs = yield* getAllFunctions( + imported, + source, + allSigs, + allAliasSigs, ); - - const extensions = yield* mergeExt( + // get descriptors for extensions + const extSigs = yield* getAllExtensions( imported, source, - source.items.extensions, - builtinMethods, - aliasDecodedTypes, - ) - - // for (const t of source.items.types) { - // yield* checkTypeDecl(t, unifier, all); - // } + allSigs, + allAliasSigs, + ); + const traitSigs = yield* getTraitSigs( + imported, + source, + allSigs, + allAliasSigs, + ); + // NB! we don't only check constants, but also get an + // expression checker out of it. constants might have no + // type annotation, and are required to check exprs + const { constSigs, checkExpr } = yield* getAllConstants( + imported, + source, + allSigs, + allAliasSigs, + fnSigs, + extSigs, + methodSigs, + ); - // for (const c of source.items.constants) { - // yield* checkConstant(c, unifier.withParams([]), all); - // } - // for (const f of source.items.functions) { - // yield* checkFunction(f, all); - // } // check aliases (no recursion) // scope extensions @@ -135,1010 +111,9 @@ function* tcSource( // TODO: constant/function/extension loops return { - types, - functions, - constants, - extensions, - }; -} -const getArity = (type: Ast.TypeDecl | FlatDecl): number => { - switch (type.kind) { - case "FlatContract": - case "FlatTrait": - case "contract": - case "trait": - case "message_decl": { - return 0; - } - case 'InvalidDecl': { - return type.arity; - } - case "struct_decl": - case "union_decl": - case "FlatAlias": - case "alias_decl": { - return type.typeParams.length; - } - } -}; - -type AliasDecodedDecl = - | FlatDecl - | Ast.Contract - | Ast.Trait -const decodeAliases = ( - userTypes: Registry>, -): E.WithLog>> => { - const EAliasOccurs = ( - name: string, - loc: Ast.Loc, - ): E.TcError => ({ - loc, - descr: [ - E.TEText(`Alias "${name}" was expanded inside itself`), - ], - }); - - type Status = Success | Failure | Visiting - // alias was already decoded - type Success = { - readonly kind: 'success'; - readonly alias: FlatAlias; - } - // failed at decoding the alias - type Failure = { - readonly kind: 'failure'; - } - // we're decoding it right now - type Visiting = { - readonly kind: 'visiting'; - } - - // status of checking alias bodies - const status: Map = new Map(); - - // check that neither of the types have cyclic alias references - function* checkTypes(types: readonly Ast.DecodedType[]): E.WithLog { - let result = true; - for (const type of types) { - const partialResult = yield* checkType(type); - // NB: separate from previous line to avoid short-circuiting - // we want to give ALL error message - result &&= partialResult; - } - return result; - } - - // check decoded type has no cyclic alias references - function* checkType(type: Ast.DecodedType): E.WithLog { - switch (type.kind) { - case "TyInt": - case "TySlice": - case "TyCell": - case "TyBuilder": - case "unit_type": - case "TypeVoid": - case "TypeNull": - case "TypeBool": - case "TypeAddress": - case "TypeString": - case "TypeParam": - case "TypeStringBuilder": { - return true; - } - case "TypeBounced": - case "TypeMaybe": { - return yield* checkType(type.type); - } - case "map_type": { - return (yield* checkType(type.key)) && (yield* checkType(type.value)); - } - case "type_ref": - case "tuple_type": - case "tensor_type": { - return yield* checkTypes(type.typeArgs); - } - case "TypeAlias": { - // check alias reference's arguments - const result = yield* checkTypes(type.typeArgs); - const alias = userTypes.get(type.name.text); - if (!alias) { - return throwInternal("Alias reference was decoded, but doesn't exist"); - } - const decl = alias.value.decl - if (decl.kind === 'alias_decl') { - return Boolean(yield* decodeAlias(decl)) && result; - } - if (decl.kind === 'FlatAlias') { - // we don't need to check FlatAlias, because it - // was already checked in one of the previous sources - return result; - } - return throwInternal("Alias reference was decoded, but does not reference alias"); - } - } - } - - // convert alias into better representation - function* decodeAlias(decl: Ast.AliasDecl): E.WithLog { - const name = decl.name.text; - const s = status.get(name); - if (!s) { - // remember we're trying to do it right now, - // so that we can throw occurs check for cyclic aliases - status.set(name, { kind: 'visiting' }); - - // decode type of the alias body - const type = yield* decodeType( - userTypes, - decl.typeParams, - decl.type, - ); - - // something went wrong trying to decode alias body - if (!type) { - status.set(name, { kind: 'failure' }); - return undefined; - } - - const alias = FlatAlias( - decl.name, - decl.typeParams, - type, - decl.loc, - ); - yield* checkType(type); - - // remember that we're done with this alias - status.set(name, { kind: 'success', alias }); - return alias; - } else if (s.kind === 'failure') { - return undefined; - } else if (s.kind === 'success') { - return s.alias; - } else { - yield EAliasOccurs(name, decl.loc); - return undefined; - } - } - function* root(): E.WithLog>> { - const result: [string, Def>][] = []; - // for every type declaration - for (const [name, def] of userTypes) { - const decl = def.value.decl; - // if it's not an alias, return it unchanged - // cannot decode it yet - if (decl.kind !== 'alias_decl') { - result.push([name, { value: { - arity: def.value.arity, - decl: decl, - }, via: def.via }]); - continue; - } - // decode the alias - const res = yield* decodeAlias(decl); - if (!res) { - // if decoding failed, store it as invalid type declaration - result.push([name, { value: { - arity: def.value.arity, - decl: InvalidDecl(decl.name, def.value.arity, decl.loc), - }, via: def.via }]); - continue; - } - // we've actually manage to decode the alias - // and it has neither broken types, nor loops - result.push([name, { value: { - arity: def.value.arity, - decl: res, - }, via: def.via }]); - } - return new Map(result); - } - return root(); -}; - -const decodeType = ( - userTypes: Registry>, - typeParams: readonly Ast.TypeId[], - type: Ast.Type, -): E.WithLog => { - const ETypeNotFound = ( - name: string, - loc: Ast.Loc, - ): E.TcError => ({ - loc, - descr: [ - E.TEText(`Type "${name}" is not defined`), - ], - }); - function* matchArity( - name: string, - got: number, - expected: number, - loc: Ast.Loc, - ): E.WithLog { - const result = got === expected; - if (!result) { - yield EArity(name, expected, got, loc); - } - return result; - } - const EArity = ( - name: string, - expected: number, - got: number, - loc: Ast.Loc, - ): E.TcError => ({ - loc, - descr: [ - E.TEText(`Type "${name}" is expected to have ${expected} type arguments, got ${got}`), - ], - }); - - // decode all the types in an array - function* recN( - types: readonly Ast.Type[], - ): E.WithLog { - const results: Ast.DecodedType[] = []; - for (const type of types) { - const result = yield* rec(type); - if (result) { - results.push(result); - } else { - return undefined - } - } - return results; - } - - // decode a type - function* rec( - type: Ast.Type, - ): E.WithLog { - switch (type.kind) { - case "unit_type": - case "TyInt": - case "TySlice": - case "TyCell": - case "TyBuilder": - case "TypeVoid": - case "TypeNull": - case "TypeBool": - case "TypeAddress": - case "TypeString": - case "TypeStringBuilder": { - return type; - } - case "tuple_type": { - const result = yield* recN(type.typeArgs); - return result && Ast.DTypeTuple(result, type.loc); - } - case "tensor_type": { - const result = yield* recN(type.typeArgs); - return result && Ast.DTypeTensor(result, type.loc); - } - case "map_type": { - const key = yield* rec(type.key); - const value = yield* rec(type.value); - if (!key || !value) { - return undefined; - } - return Ast.DTypeMap(key, value, type.loc); - } - case "TypeBounced": { - const child = yield* rec(type.type); - if (!child) { - return undefined; - } - return Ast.DTypeBounced(child, type.loc); - } - case "TypeMaybe": { - const child = yield* rec(type.type); - if (!child) { - return undefined; - } - return Ast.DTypeMaybe(child, type.loc); - } - case "cons_type": { - // this is where the meat of the procedure is - // cons can be either parameter, type reference, - // alias reference, or reference to undefined type - const name = type.name.text; - const arity = type.typeArgs.length; - - const args = yield* recN(type.typeArgs); - - // if it's in a list of type parameters, this - // is a parameter - const param = typeParams.find(p => p.text); - if (param) { - // if we used type parameter generically, throw error - // because we do not support HKT - if (!(yield* matchArity(name, arity, 0, type.loc))) { - return undefined; - } - return Ast.DTypeParamRef( - type.name, - type.loc, - ); - } - - const typeEntry = userTypes.get(name); - - // there is no such type at all! - if (!typeEntry) { - yield ETypeNotFound(name, type.loc); - return undefined; - } - - // check number of type arguments does match - if (!(yield* matchArity( - name, - arity, - typeEntry.value.arity, - type.loc, - ))) { - return undefined; - } - - // arguments did match, but something is wrong with them - if (!args) { - return undefined; - } - - const decl = typeEntry.value.decl; - switch (decl.kind) { - case "InvalidDecl": { - // something went wrong with the declaration we refer to - // so this cannot be a valid type - return undefined; - } - case "FlatAlias": - case "alias_decl": { - // this is an alias reference - return Ast.DTypeAliasRef(type.name, args, type.loc); - } - case "FlatContract": - case "FlatTrait": - case "struct_decl": - case "message_decl": - case "union_decl": - case "contract": - case "trait": { - // this is a ground type reference - return Ast.DTypeRef(type.name, args, type.loc); - } - } - } - } - } - - return rec(type); -} - -function* mergeExt( - results: readonly SourceCheckResult[], - source: TactSource, - items: readonly Ast.Extension[], - builtins: ReadonlyMap, - userTypes: Registry>, -): E.WithLog { - const EMethodOverlap = ( - name: string, - prev: V.Via, - next: V.ViaUser, - ): E.TcError => ({ - loc: E.viaToRange(next), - descr: [ - E.TEText(`Method "${name}" overlaps previously defined method`), - E.TEVia(prev), - ], - }); - - const imported: ExtRegistry[] = results.map(({ globals, importedBy }) => { - return new Map(globals.extensions.entries().map(([k, v]) => { - return [k, v.map((e) => ({ - via: V.ViaImport(importedBy, e.via), - self: e.self, - typeParams: e.typeParams, - mutates: e.mutates, - fun: e.fun, - }))]; - })); - }); - - const local: ExtRegistry[] = []; - for (const item of items) { - const fun = item.fun; - const type = yield* decodeType( - userTypes, - fun.type.typeParams, - item.selfType - ); - - if (!type) { - // self type is wrong - continue; - } - - // type without any aliases - const methodType = yield* toSelfType( - userTypes, - resolveAliases(userTypes, type) - ); - if (!methodType) { - continue; - } - - local.push(new Map([[fun.name.text, [{ - via: V.ViaOrigin(fun.loc, source), - self: methodType, - typeParams: fun.type.typeParams, - mutates: item.mutates, - fun: item.fun, - }]]])); - } - - const all = [...imported, ...local]; - - const prev: Map = new Map(); - for (const next of all) { - for (const [name, nextMap] of next) { - const prevMap = [...prev.get(name) ?? []]; - const builtin = builtins.get(name); - for (const entry of nextMap) { - const { typeParams, self } = entry - // defined in compiler - const prevBuiltin = !areOrdered(builtin, nextSchema); - if (prevBuiltin) { - yield EMethodOverlap(name, V.ViaBuiltin(), nextDef.via); - continue; - } - const prevEntry = prevMap.find(([prevSchema]) => !unifier.areOrdered( - prevSchema, nextSchema - )); - // not defined yet; define it now - if (!prevEntry) { - prevMap.push([nextSchema, nextDef]); - continue; - } - const [, prevDef] = prevEntry; - // already defined, and it's not a diamond situation - if (prevDef.via.source !== nextDef.via.source) { - yield EMethodOverlap(name, prevDef.via, nextDef.via); - } - } - prev.set(name, prevMap); - } - } - return prev; -} - -const resolveAliases = ( - userTypes: Registry>, - type: Ast.DecodedType, -) => { - const recN = (types: readonly Ast.DecodedType[]): readonly Ast.DecodedType[] => { - return types.map(type => rec(type)); - }; - const rec = (type: Ast.DecodedType): Ast.DecodedType => { - switch (type.kind) { - case "type_ref": { - return Ast.DTypeRef( - type.name, - recN(type.typeArgs), - type.loc, - ); - } - case "TypeAlias": { - const def = userTypes.get(type.name.text); - if (!def) { - return throwInternal("Decoder returned broken reference"); - } - const decl = def.value.decl; - if (decl.kind !== 'FlatAlias') { - return throwInternal("Decoder returned broken reference"); - } - // NB! if we could decode alias once, there might be - // a nested one too - return rec(substitute( - decl.type, - decl.typeParams, - recN(type.typeArgs), - )); - } - case "TypeParam": { - return type; - } - case "map_type": { - return Ast.DTypeMap( - rec(type.key), - rec(type.value), - type.loc, - ); - } - case "TypeBounced": { - return Ast.DTypeBounced( - rec(type.type), - type.loc, - ); - } - case "TypeMaybe": { - return Ast.DTypeMaybe( - rec(type.type), - type.loc, - ); - } - case "tuple_type": { - return Ast.DTypeTuple( - recN(type.typeArgs), - type.loc, - ); - } - case "tensor_type": { - return Ast.DTypeTensor( - recN(type.typeArgs), - type.loc, - ); - } - case "TyInt": - case "TySlice": - case "TyCell": - case "TyBuilder": - case "unit_type": - case "TypeVoid": - case "TypeNull": - case "TypeBool": - case "TypeAddress": - case "TypeString": - case "TypeStringBuilder": { - return type; - } - } - }; - return rec(type); -}; - -const substitute = ( - type: Ast.DecodedType, - params: readonly Ast.TypeId[], - args: readonly Ast.DecodedType[], -): Ast.DecodedType => { - if (params.length !== args.length) { - return throwInternal("Decoder didn't check alias arity"); - } - - const substMap = new Map(zip(params, args).map(([param, arg]) => { - return [param.text, arg]; - })) - - const recN = (types: readonly Ast.DecodedType[]): readonly Ast.DecodedType[] => { - return types.map(type => rec(type)); + fnSigs, + typeDecls, + constSigs, + extSigs, }; - - const rec = (type: Ast.DecodedType): Ast.DecodedType => { - switch (type.kind) { - case "TypeParam": { - const arg = substMap.get(type.name.text); - if (!arg) { - return throwInternal("Decoder didn't scope alias's type args"); - } - return arg; - } - case "type_ref": { - return Ast.DTypeRef( - type.name, - recN(type.typeArgs), - type.loc, - ); - } - case "TypeAlias": { - return Ast.DTypeAliasRef( - type.name, - recN(type.typeArgs), - type.loc, - ); - } - case "map_type": { - return Ast.DTypeMap( - rec(type.key), - rec(type.value), - type.loc, - ); - } - case "TypeBounced": { - return Ast.DTypeBounced( - rec(type.type), - type.loc, - ); - } - case "TypeMaybe": { - return Ast.DTypeMaybe( - rec(type.type), - type.loc, - ); - } - case "tuple_type": { - return Ast.DTypeTuple( - recN(type.typeArgs), - type.loc, - ); - } - case "tensor_type": { - return Ast.DTypeTensor( - recN(type.typeArgs), - type.loc, - ); - } - case "TyInt": - case "TySlice": - case "TyCell": - case "TyBuilder": - case "unit_type": - case "TypeVoid": - case "TypeNull": - case "TypeBool": - case "TypeAddress": - case "TypeString": - case "TypeStringBuilder": { - return type; - } - } - }; - - return rec(type); -}; - -function* toSelfType( - userTypes: Registry>, - type: Ast.DecodedType, -): E.WithLog { - switch (type.kind) { - case "type_ref": { - const def = userTypes.get(type.name.text); - if (!def) { - return throwInternal("Decoder returned broken reference") - } - const decl = def.value.decl; - switch (decl.kind) { - case "InvalidDecl": { - return undefined; - } - case "FlatAlias": { - return throwInternal("Decoder returned broken reference") - } - case "FlatContract": - case "contract": { - yield ENoMethods("contract", type.loc); - return undefined; - } - case "FlatTrait": - case "trait": { - yield ENoMethods("trait", type.loc); - return undefined; - } - case "struct_decl": - case "message_decl": - case "union_decl": { - const allVars = type.typeArgs.filter(arg => { - return arg.kind === 'TypeParam'; - }); - if (type.typeArgs.length === allVars.length) { - const argNames = new Set(allVars.map(v => v.name.text)); - if (argNames.size !== allVars.length) { - // type variables are not distinct - yield EBadMethodType(type.loc); - return undefined; - } - return Ast.MVTypeRef( - type.name, - allVars, - type.loc, - ); - } - if (type.typeArgs.length > 0 && allVars.length > 0) { - // has vars, but it's not all the parameters - yield EBadMethodType(type.loc); - return undefined; - } - const ground: Ast.MethodGroundType[] = []; - for (const arg of type.typeArgs) { - const result = yield* toGroundType(userTypes, arg); - if (!result) { - yield EBadMethodType(type.loc); - return undefined; - } - ground.push(result); - } - return Ast.MGTypeRef( - type.name, - ground, - type.loc, - ); - } - } - // somehow typescript wants this - return throwInternal("Unknown declaration type"); - } - case "TypeAlias": { - return throwInternal("resolveAliases didn't resolve them"); - } - case "TypeParam": { - yield EBadMethodType(type.loc); - return undefined; - } - case "map_type": { - if (type.key.kind === 'TypeParam' && type.value.kind === 'TypeParam') { - return Ast.MVTypeMap( - type.key, - type.value, - type.loc, - ); - } - const ground = yield* toGroundType(userTypes, type); - if (!ground) { - yield EBadMethodType(type.loc); - return undefined; - } - return ground; - } - case "TypeBounced": { - yield EBadMethodType(type.loc); - return undefined; - } - case "TypeMaybe": { - if (type.type.kind === 'TypeParam') { - return Ast.MVTypeMaybe( - type.type, - type.loc, - ); - } - const ground = yield* toGroundType(userTypes, type); - if (!ground) { - yield EBadMethodType(type.loc); - return undefined; - } - return ground; - } - case "tensor_type": - case "tuple_type": { - const mvCons = type.kind === 'tuple_type' - ? Ast.MVTypeTuple - : Ast.MVTypeTensor; - const allVars = type.typeArgs.filter(arg => { - return arg.kind === 'TypeParam'; - }); - if (type.typeArgs.length === allVars.length) { - const argNames = new Set(allVars.map(v => v.name.text)); - if (argNames.size !== allVars.length) { - // type variables are not distinct - yield EBadMethodType(type.loc); - return undefined; - } - return mvCons( - allVars, - type.loc, - ); - } - const ground = yield* toGroundType(userTypes, type); - if (!ground) { - yield EBadMethodType(type.loc); - return undefined; - } - return ground; - } - case "TyInt": - case "TySlice": - case "TyCell": - case "TyBuilder": - case "unit_type": - case "TypeVoid": - case "TypeNull": - case "TypeBool": - case "TypeAddress": - case "TypeString": - case "TypeStringBuilder": { - return type; - } - } -} -const EBadMethodType = ( - loc: Ast.Loc, -): E.TcError => ({ - loc, - descr: [ - E.TEText(`Type of self must either have no type parameters, or be a generic type with distinct type parameters`), - ], -}); -const ENoMethods = ( - kind: string, - loc: Ast.Loc, -): E.TcError => ({ - loc, - descr: [ - E.TEText(`Cannot define methods on ${kind}`), - ], -}); - -function* toGroundType( - userTypes: Registry>, - type: Ast.DecodedType -): E.WithLog { - switch (type.kind) { - case "type_ref": { - const def = userTypes.get(type.name.text); - if (!def) { - return throwInternal("Decoder returned broken reference") - } - const decl = def.value.decl; - switch (decl.kind) { - case "InvalidDecl": { - return undefined; - } - case "FlatAlias": { - return throwInternal("Decoder returned broken reference") - } - case "FlatContract": - case "contract": { - yield ENoMethods("contract", type.loc); - return undefined; - } - case "FlatTrait": - case "trait": { - yield ENoMethods("trait", type.loc); - return undefined; - } - case "struct_decl": - case "message_decl": - case "union_decl": { - const ground: Ast.MethodGroundType[] = []; - for (const arg of type.typeArgs) { - const result = yield* toGroundType(userTypes, arg); - if (!result) { - return undefined; - } - ground.push(result); - } - return Ast.MGTypeRef( - type.name, - ground, - type.loc, - ); - } - } - // somehow typescript wants this - return throwInternal("Unknown declaration type"); - } - case "TypeAlias": { - return throwInternal("resolveAliases didn't resolve them"); - } - case "TypeParam": { - return undefined; - } - case "map_type": { - const key = yield* toGroundType(userTypes, type.key); - const value = yield* toGroundType(userTypes, type.value); - if (!key || !value) { - return undefined; - } - return Ast.MGTypeMap(key, value, type.loc); - } - case "TypeBounced": { - return undefined; - } - case "TypeMaybe": { - const child = yield* toGroundType(userTypes, type.type); - if (!child) { - return undefined; - } - return Ast.MGTypeMaybe(child, type.loc); - } - case "tuple_type": { - const children: Ast.MethodGroundType[] = []; - for (const child of type.typeArgs) { - const result = yield* toGroundType(userTypes, child); - if (!result) { - return undefined; - } - children.push(result); - } - return Ast.MGTypeTuple(children, type.loc); - } - case "tensor_type": { - const children: Ast.MethodGroundType[] = []; - for (const child of type.typeArgs) { - const result = yield* toGroundType(userTypes, child); - if (!result) { - return undefined; - } - children.push(result); - } - return Ast.MGTypeTensor(children, type.loc); - } - case "TyInt": - case "TySlice": - case "TyCell": - case "TyBuilder": - case "unit_type": - case "TypeVoid": - case "TypeNull": - case "TypeBool": - case "TypeAddress": - case "TypeString": - case "TypeStringBuilder": { - return type; - } - } -} - -function* mergeReg( - results: readonly SourceCheckResult[], - source: TactSource, - kind: string, - get1: (s: Scope) => Registry, - items: readonly T[], - builtin: Map, -): E.WithLog> { - const imported = results.map(({ globals, importedBy }) => ( - mapRegVia(get1(globals), importedBy) - )); - const local = items.map((item) => createRef( - item.name.text, - item, - V.ViaOrigin(item.loc, source), - )); - return yield* concatReg( - builtin, - kind, - [...imported, ...local], - ) -} - -const createRef = (name: string, value: V, via: V.ViaUser): Registry => { - return new Map([[name, { value, via }]]); -}; - -const mapRegVia = (fns: Registry, importedBy: TactImport): Registry => { - return new Map(fns.entries().map(([k, v]) => { - return [k, { - value: v.value, - via: V.ViaImport(importedBy, v.via), - }]; - })); -}; - -function* concatReg( - builtins: Map, - kind: string, - all: readonly Registry[] -): E.WithLog> { - const ERedefine = (kind: string, name: string, prev: V.Via, next: V.ViaUser): E.TcError => ({ - loc: E.viaToRange(next), - descr: [ - E.TEText(`There already is a ${kind} "${name}" from`), - E.TEVia(prev), - ], - }); - - const prev: Map> = new Map(); - for (const next of all) { - for (const [name, nextItem] of next) { - const prevItem = prev.get(name); - // defined in compiler - if (builtins.has(name)) { - yield ERedefine(kind, name, V.ViaBuiltin(), nextItem.via); - continue; - } - // not defined yet; define it now - if (typeof prevItem === 'undefined') { - prev.set(name, nextItem); - continue; - } - // already defined, and it's not a diamond situation - if (prevItem.via.source !== nextItem.via.source) { - yield ERedefine(kind, name, prevItem.via, nextItem.via); - } - } - } - return prev; -} +} \ No newline at end of file diff --git a/src/next/types/types.ts b/src/next/types/types.ts new file mode 100644 index 0000000000..c2066d6ade --- /dev/null +++ b/src/next/types/types.ts @@ -0,0 +1,226 @@ +import * as Ast from "@/next/ast"; +import { builtinTypes } from "@/next/types/builtins"; +import { concatReg } from "@/next/types/reg"; +import type { TactImport, TactSource } from "@/next/imports/source"; +import * as E from "@/next/types/errors"; + +export function* getDecodeType( + imported: readonly Ast.SourceCheckResult[], + source: TactSource, +) { + const importedSigs = importSigs(imported); + const localSigs = getLocalSigs(source); + const sigs = yield* concatReg( + builtinTypes, + 'type', + [...importedSigs, ...localSigs], + ); + + return sigs; +} + +const importSigs = (imported: readonly Ast.SourceCheckResult[]) => { + return imported.map(({ globals, importedBy }) => ( + new Map( + globals.typeDecls.entries() + .map(([name, s]) => [name, toSigDecoded(s, importedBy)]) + ) + )); +}; + +const toSigDecoded = (decl: Ast.TypeDeclSig, importedBy: TactImport): Ast.DeclSig => { + const via = Ast.ViaImport(importedBy, decl.via); + switch (decl.kind) { + case "bad": + return Ast.DeclSig('forbidden', decl.arity, via); + case "alias": + return Ast.DeclSig('alias', decl.typeParams.order.length, via) + case "contract": + case "trait": + return Ast.DeclSig('contract', 0, via); + case "struct": + case "message": + case "union": + return Ast.DeclSig('usual', decl.typeParams.order.length, via); + } +}; + +const getLocalSigs = (source: TactSource) => { + return source.items.types + .map((decl) => new Map([[decl.name.text, toSigNew(decl, source)]])) +}; + +const toSigNew = (decl: Ast.TypeDecl, source: TactSource) => { + const via = Ast.ViaOrigin(decl.loc, source); + switch (decl.kind) { + case "alias_decl": { + return Ast.DeclSig('alias', decl.typeParams.length, via); + } + case "contract": + case "trait": { + return Ast.DeclSig('contract', 0, via); + } + case "message_decl": { + return Ast.DeclSig('usual', 0, via); + } + case "struct_decl": + case "union_decl": { + return Ast.DeclSig('usual', decl.typeParams.length, via); + } + } +}; + +export function decodeType( + sigs: ReadonlyMap, + typeParams: Ast.TypeParams, + type: Ast.Type, +): E.WithLog { + // decode all the types in an array + function* recN( + types: readonly Ast.Type[], + ): E.WithLog { + const results: Ast.DecodedType[] = []; + for (const type of types) { + const result = yield* rec(type); + results.push(result); + } + return results; + } + + // decode a type + function* rec( + type: Ast.Type, + ): E.WithLog { + switch (type.kind) { + case "unit_type": + case "TyInt": + case "TySlice": + case "TyCell": + case "TyBuilder": + case "TypeVoid": + case "TypeNull": + case "TypeBool": + case "TypeAddress": + case "TypeString": + case "TypeStringBuilder": { + return type; + } + case "tuple_type": { + const result = yield* recN(type.typeArgs); + return Ast.DTypeTuple(result, type.loc); + } + case "tensor_type": { + const result = yield* recN(type.typeArgs); + return Ast.DTypeTensor(result, type.loc); + } + case "map_type": { + const key = yield* rec(type.key); + const value = yield* rec(type.value); + return Ast.DTypeMap(key, value, type.loc); + } + case "TypeBounced": { + const child = yield* rec(type.type); + return Ast.DTypeBounced(child, type.loc); + } + case "TypeMaybe": { + const child = yield* rec(type.type); + return Ast.DTypeMaybe(child, type.loc); + } + case "cons_type": { + // this is where the meat of the procedure is + // cons can be either parameter, type reference, + // alias reference, or reference to undefined type + const name = type.name.text; + const arity = type.typeArgs.length; + + const args = yield* recN(type.typeArgs); + + // if it's in a list of type parameters, this + // is a parameter + if (typeParams.set.has(name)) { + // if we used type parameter generically, throw error + // because we do not support HKT + if (!(yield* matchArity(name, arity, 0, type.loc))) { + return Ast.DTypeRecover(); + } + return Ast.DTypeParamRef( + type.name, + type.loc, + ); + } + + const typeEntry = sigs.get(name); + + // there is no such type at all! + if (!typeEntry) { + yield ETypeNotFound(name, type.loc); + return Ast.DTypeRecover(); + } + + // check number of type arguments does match + if (!(yield* matchArity( + name, + arity, + typeEntry.arity, + type.loc, + ))) { + return Ast.DTypeRecover(); + } + + switch (typeEntry.use) { + case "usual": + case "contract": { + // this is a ground type reference + return Ast.DTypeRef(type.name, args, type.loc); + } + case "alias": { + // this is an alias reference + return Ast.DTypeAliasRef(type.name, args, type.loc); + } + case "forbidden": { + // something went wrong with the declaration we refer to + // so this cannot be a valid type + return Ast.DTypeRecover(); + } + } + } + } + } + + return rec(type); +} + +const ETypeNotFound = ( + name: string, + loc: Ast.Loc, +): E.TcError => ({ + loc, + descr: [ + E.TEText(`Type "${name}" is not defined`), + ], +}); + +function* matchArity( + name: string, + got: number, + expected: number, + loc: Ast.Loc, +): E.WithLog { + const result = got === expected; + if (!result) { + yield EArity(name, expected, got, loc); + } + return result; +} + +const EArity = ( + name: string, + expected: number, + got: number, + loc: Ast.Loc, +): E.TcError => ({ + loc, + descr: [ + E.TEText(`Type "${name}" is expected to have ${expected} type arguments, got ${got}`), + ], +}); \ No newline at end of file diff --git a/src/next/types/util.ts b/src/next/types/util.ts new file mode 100644 index 0000000000..e5795c2303 --- /dev/null +++ b/src/next/types/util.ts @@ -0,0 +1,74 @@ +import * as Ast from "@/next/ast"; +import * as E from "@/next/types/errors"; +import { dealiasType } from "@/next/types/aliases"; +import { decodeTypeParams } from "@/next/types/type-params"; +import { throwInternal } from "@/error/errors"; + +export const recoverName = (name: string, set: ReadonlySet) => { + for (let i = 0; i < 100; ++i) { + const nextName = `${name}${i}`; + if (!set.has(nextName)) { + return nextName; + } + } + return throwInternal("Iteration limit reached"); +}; + +export function* decodeFnType( + { typeParams, params, returnType }: Ast.FnType, + via: Ast.ViaUser, + sigs: ReadonlyMap, + aliases: ReadonlyMap, +): E.WithLog { + const decodedTypeParams = yield* decodeTypeParams(typeParams); + const dealias = (type: Ast.Type) => { + return dealiasType(sigs, aliases, decodedTypeParams, type); + }; + return Ast.DecodedFnType( + decodedTypeParams, + yield* decodeParams(dealias, params), + yield* dealias(returnType ?? Ast.TypeVoid(via.defLoc)), + ); +} + +function* decodeParams( + dealias: (type: Ast.Type) => E.WithLog, + params: readonly Ast.TypedParameter[], +): E.WithLog { + const order: Ast.Parameter[] = []; + const set: Set = new Set(); + for (const param of params) { + const name = yield* decodeParamName(param.name, set); + order.push(Ast.Parameter( + param.name, + yield* dealias(param.type), + param.loc, + )); + if (typeof name !== 'undefined') { + set.add(name); + } + } + return Ast.Parameters(order, set); +} + +function* decodeParamName( + node: Ast.OptionalId, + set: ReadonlySet, +): E.WithLog { + if (node.kind === 'wildcard') { + return undefined; + } + const name = node.text; + if (!set.has(name)) { + return name; + } + yield EDuplicateParam(name, node.loc); + return recoverName(name, set); +} + +const EDuplicateParam = (name: string, loc: Ast.Loc): E.TcError => ({ + loc, + descr: [ + E.TEText(`Duplicate parameter "${name}"`), + ], +}); \ No newline at end of file diff --git a/src/next/types/via.ts b/src/next/types/via.ts deleted file mode 100644 index 2cecae7aca..0000000000 --- a/src/next/types/via.ts +++ /dev/null @@ -1,47 +0,0 @@ -import type { TactImport, TactSource } from "@/next/imports/source"; -import { hideProperty } from "@/utils/tricks"; -import type * as Ast from "@/next/ast"; - -// provenance for definition: where did it come from -export type Via = ViaUser | ViaBuiltin - -// is defined in compiler, always was there -export type ViaBuiltin = { - readonly kind: 'builtin'; -} - -export const ViaBuiltin = (): ViaBuiltin => ({ kind: 'builtin' }); - -export type ViaUser = { - readonly kind: 'user'; - // which imports it came through - readonly imports: readonly TactImport[]; - // where in the code it was defined - readonly defLoc: Ast.Loc; - // in which source - readonly source: TactSource; -} - -// when something was just defined -export const ViaOrigin = (defLoc: Ast.Loc, source: TactSource): ViaUser => { - const result: ViaUser = { - kind: 'user', - imports: [], - defLoc, - source, - }; - hideProperty(result, 'source'); - return result; -}; - -// when it came through an import -export const ViaImport = (throughImport: TactImport, via: ViaUser): ViaUser => { - const result: ViaUser = { - kind: 'user', - imports: [throughImport, ...via.imports], - defLoc: via.defLoc, - source: via.source, - }; - hideProperty(result, 'source'); - return result; -}; \ No newline at end of file From b9e972017afc1936ea03d2d98aa4ded82b0c1fdc Mon Sep 17 00:00:00 2001 From: verytactical <186486509+verytactical@users.noreply.github.com> Date: Wed, 28 May 2025 20:14:58 +0400 Subject: [PATCH 24/38] 1 --- spell/cspell-list.txt | 2 + src/next/ast/checked-expr.ts | 196 +++++++++++++ src/next/ast/checked-stmt.ts | 120 ++++++++ src/next/ast/checked.ts | 161 ++++++----- src/next/ast/generated/checked-expr.ts | 198 ++++++++++++++ src/next/ast/generated/checked-stmt.ts | 120 ++++++++ src/next/ast/generated/checked.ts | 223 ++++++++------- src/next/ast/generated/type.ts | 2 +- src/next/ast/generated/value.ts | 10 + src/next/ast/generated/via.ts | 16 +- src/next/ast/index.ts | 4 + src/next/ast/lazy.ts | 38 +++ src/next/ast/root.ts | 2 +- src/next/ast/type.ts | 2 +- src/next/ast/value.ts | 6 + src/next/ast/via.ts | 4 +- src/next/grammar/index.ts | 18 +- src/next/types/alias.ts | 17 ++ src/next/types/aliases.ts | 302 -------------------- src/next/types/body.ts | 263 ++++++++++++++++++ src/next/types/builtins.ts | 35 ++- src/next/types/constant-def.ts | 34 +++ src/next/types/constants.ts | 69 ++--- src/next/types/contract.ts | 120 ++++++++ src/next/types/errors.ts | 42 ++- src/next/types/expr-eval.ts | 11 + src/next/types/expression.ts | 8 +- src/next/types/extensions.ts | 234 +++++++++------- src/next/types/fields.ts | 192 +++++++++++++ src/next/types/functions.ts | 50 ++-- src/next/types/methods.ts | 207 ++++++++++++++ src/next/types/name.ts | 11 + src/next/types/override.ts | 118 ++++++++ src/next/types/reg.ts | 30 -- src/next/types/statements.ts | 10 + src/next/types/traits-scope.ts | 51 ++++ src/next/types/traits.ts | 36 --- src/next/types/{util.ts => type-fn.ts} | 28 +- src/next/types/type-method.ts | 10 + src/next/types/type-params.ts | 2 +- src/next/types/type.ts | 365 +++++++++++++++++++++++++ src/next/types/typecheck.ts | 80 +----- src/next/types/typedecl.ts | 90 ++++++ src/next/types/types.ts | 226 --------------- 44 files changed, 2716 insertions(+), 1047 deletions(-) create mode 100644 src/next/ast/checked-expr.ts create mode 100644 src/next/ast/checked-stmt.ts create mode 100644 src/next/ast/generated/checked-expr.ts create mode 100644 src/next/ast/generated/checked-stmt.ts create mode 100644 src/next/ast/generated/value.ts create mode 100644 src/next/ast/lazy.ts create mode 100644 src/next/ast/value.ts create mode 100644 src/next/types/alias.ts delete mode 100644 src/next/types/aliases.ts create mode 100644 src/next/types/body.ts create mode 100644 src/next/types/constant-def.ts create mode 100644 src/next/types/contract.ts create mode 100644 src/next/types/expr-eval.ts create mode 100644 src/next/types/fields.ts create mode 100644 src/next/types/methods.ts create mode 100644 src/next/types/name.ts create mode 100644 src/next/types/override.ts delete mode 100644 src/next/types/reg.ts create mode 100644 src/next/types/statements.ts create mode 100644 src/next/types/traits-scope.ts delete mode 100644 src/next/types/traits.ts rename src/next/types/{util.ts => type-fn.ts} (66%) create mode 100644 src/next/types/type-method.ts create mode 100644 src/next/types/type.ts create mode 100644 src/next/types/typedecl.ts delete mode 100644 src/next/types/types.ts diff --git a/spell/cspell-list.txt b/spell/cspell-list.txt index 3f1f0f3b19..155bdd2330 100644 --- a/spell/cspell-list.txt +++ b/spell/cspell-list.txt @@ -32,6 +32,7 @@ Comptime CSBT Daniil Danil +dealias decompilation Decompilation decompile @@ -52,6 +53,7 @@ Epva errno Esorat extracurrency +Fieldish flamegraph flamegraphs forall diff --git a/src/next/ast/checked-expr.ts b/src/next/ast/checked-expr.ts new file mode 100644 index 0000000000..a0b6cfcb77 --- /dev/null +++ b/src/next/ast/checked-expr.ts @@ -0,0 +1,196 @@ +import type { Id, Loc, TypeId } from "@/next/ast/common"; +import type { DecodedType, DTypeMap } from "@/next/ast/dtype"; +import type { BinaryOperation, NumberBase, UnaryOperation } from "@/next/ast/expression"; +import type { Lazy } from "@/next/ast/lazy"; + +export type DecodedExpression = + | DOpBinary + | DOpUnary + | DConditional + | DMethodCall + | DStaticCall + | DStaticMethodCall + | DFieldAccess + | DStructInstance + | DInitOf + | DCodeOf + | DNumber + | DBoolean + | DNull + | DString + | DVar + | DUnit + | DTuple + | DTensor + | DMapLiteral + | DSetLiteral; + +export type DVar = { + readonly kind: "var"; + readonly name: string; + readonly computedType: Lazy; + readonly loc: Loc; +}; + +export type DNumber = { + readonly kind: "number"; + readonly base: NumberBase; + readonly value: bigint; + readonly computedType: Lazy; + readonly loc: Loc; +}; + +export type DBoolean = { + readonly kind: "boolean"; + readonly value: boolean; + readonly computedType: Lazy; + readonly loc: Loc; +}; + +export type DString = { + readonly kind: "string"; + readonly value: string; + readonly computedType: Lazy; + readonly loc: Loc; +}; + +export type DNull = { + readonly kind: "null"; + readonly computedType: Lazy; + readonly loc: Loc; +}; + +export type DOpBinary = { + readonly kind: "op_binary"; + readonly op: BinaryOperation; + readonly left: DecodedExpression; + readonly right: DecodedExpression; + readonly computedType: Lazy; + readonly loc: Loc; +}; + +export type DOpUnary = { + readonly kind: "op_unary"; + readonly op: UnaryOperation; + readonly operand: DecodedExpression; + readonly computedType: Lazy; + readonly loc: Loc; +}; + +export type DFieldAccess = { + readonly kind: "field_access"; + readonly aggregate: DecodedExpression; + readonly field: Id; + readonly computedType: Lazy; + readonly loc: Loc; +}; + +export type DMethodCall = { + readonly kind: "method_call"; + readonly self: DecodedExpression; // anything with a method + readonly method: Id; + readonly typeArgs: readonly DecodedType[]; + readonly args: readonly DecodedExpression[]; + readonly computedType: Lazy; + readonly loc: Loc; +}; + +// builtins or top-level (module) functions +export type DStaticCall = { + readonly kind: "static_call"; + readonly function: Id; + readonly typeArgs: readonly DecodedType[]; + readonly args: readonly DecodedExpression[]; + readonly computedType: Lazy; + readonly loc: Loc; +}; + +export type DStaticMethodCall = { + readonly kind: "static_method_call"; + readonly self: TypeId; + readonly typeArgs: readonly DecodedType[]; + readonly function: Id; + readonly args: readonly DecodedExpression[]; + readonly computedType: Lazy; + readonly loc: Loc; +}; + +export type DStructInstance = { + readonly kind: "struct_instance"; + readonly type: TypeId; + readonly typeArgs: readonly DecodedType[]; + readonly args: readonly DStructFieldInitializer[]; + readonly computedType: Lazy; + readonly loc: Loc; +}; + +export type DStructFieldInitializer = { + readonly field: Id; + readonly initializer: DecodedExpression; + readonly loc: Loc; +}; + +export type DMapLiteral = { + readonly kind: "map_literal"; + readonly type: DTypeMap; + readonly fields: readonly DMapField[]; + readonly computedType: Lazy; + readonly loc: Loc; +}; + +export type DMapField = { + readonly key: DecodedExpression; + readonly value: DecodedExpression; +}; + +export type DSetLiteral = { + readonly kind: "set_literal"; + readonly valueType: DecodedType; + readonly fields: readonly DecodedExpression[]; + readonly computedType: Lazy; + readonly loc: Loc; +}; + +export type DInitOf = { + readonly kind: "init_of"; + readonly contract: TypeId; + readonly args: readonly DecodedExpression[]; + readonly computedType: Lazy; + readonly loc: Loc; +}; + +export type DCodeOf = { + readonly kind: "code_of"; + readonly contract: TypeId; + readonly computedType: Lazy; + readonly loc: Loc; +}; + +export type DConditional = { + readonly kind: "conditional"; + readonly condition: DecodedExpression; + readonly thenBranch: DecodedExpression; + readonly elseBranch: DecodedExpression; + readonly computedType: Lazy; + readonly loc: Loc; +}; + +export type DUnit = { + readonly kind: "unit"; + readonly computedType: Lazy; + readonly loc: Loc; +}; + +export type DTuple = { + readonly kind: "tuple"; + readonly children: readonly DecodedExpression[]; + readonly computedType: Lazy; + readonly loc: Loc; +}; + +export type DTensor = { + readonly kind: "tensor"; + readonly children: readonly DecodedExpression[]; + readonly computedType: Lazy; + readonly loc: Loc; +}; diff --git a/src/next/ast/checked-stmt.ts b/src/next/ast/checked-stmt.ts new file mode 100644 index 0000000000..10b03cf6be --- /dev/null +++ b/src/next/ast/checked-stmt.ts @@ -0,0 +1,120 @@ +import type { DecodedExpression } from "@/next/ast/checked-expr"; +import type { Id, Loc, OptionalId, TypeId } from "@/next/ast/common"; +import type { AugmentedAssignOperation } from "@/next/ast/statement"; + +export type DecodedStatement = + | DStatementLet + | DStatementReturn + | DStatementExpression + | DStatementAssign + | DStatementAugmentedAssign + | DStatementCondition + | DStatementWhile + | DStatementUntil + | DStatementRepeat + | DStatementTry + | DStatementForEach + | DStatementDestruct + | DStatementBlock; + +export type DStatementList = readonly DecodedStatement[]; + +export type DStatementLet = { + readonly kind: "statement_let"; + readonly name: OptionalId; + readonly expression: DecodedExpression; + readonly loc: Loc; +}; + +export type DStatementReturn = { + readonly kind: "statement_return"; + readonly expression: DecodedExpression | undefined; + readonly loc: Loc; +}; + +export type DStatementExpression = { + readonly kind: "statement_expression"; + readonly expression: DecodedExpression; + readonly loc: Loc; +}; + +export type DStatementAssign = { + readonly kind: "statement_assign"; + readonly path: DecodedExpression; // left-hand side of `=` + readonly expression: DecodedExpression; + readonly loc: Loc; +}; + +export type DStatementAugmentedAssign = { + readonly kind: "statement_augmentedassign"; + readonly op: AugmentedAssignOperation; + readonly path: DecodedExpression; + readonly expression: DecodedExpression; + readonly loc: Loc; +}; + +export type DStatementCondition = { + readonly kind: "statement_condition"; + readonly condition: DecodedExpression; + readonly trueStatements: DStatementList; + readonly falseStatements: DStatementList | undefined; + readonly loc: Loc; +}; + +export type DStatementWhile = { + readonly kind: "statement_while"; + readonly condition: DecodedExpression; + readonly statements: DStatementList; + readonly loc: Loc; +}; + +export type DStatementUntil = { + readonly kind: "statement_until"; + readonly condition: DecodedExpression; + readonly statements: DStatementList; + readonly loc: Loc; +}; + +export type DStatementRepeat = { + readonly kind: "statement_repeat"; + readonly iterations: DecodedExpression; + readonly statements: DStatementList; + readonly loc: Loc; +}; + +export type DStatementTry = { + readonly kind: "statement_try"; + readonly statements: DStatementList; + readonly catchBlock: DCatchBlock | undefined; + readonly loc: Loc; +}; + +export type DCatchBlock = { + readonly catchName: OptionalId; + readonly catchStatements: DStatementList; +}; + +export type DStatementForEach = { + readonly kind: "statement_foreach"; + readonly keyName: OptionalId; + readonly valueName: OptionalId; + readonly map: DecodedExpression; + readonly statements: DStatementList; + readonly loc: Loc; +}; + +export type DStatementDestruct = { + readonly kind: "statement_destruct"; + readonly type: TypeId; + /** field name -> [field id, local id] */ + readonly identifiers: ReadonlyMap; + readonly ignoreUnspecifiedFields: boolean; + readonly expression: DecodedExpression; + readonly loc: Loc; +}; + +export type DStatementBlock = { + readonly kind: "statement_block"; + readonly statements: DStatementList; + readonly loc: Loc; +}; diff --git a/src/next/ast/checked.ts b/src/next/ast/checked.ts index 5bffe5da1f..ea1c3cf304 100644 --- a/src/next/ast/checked.ts +++ b/src/next/ast/checked.ts @@ -1,6 +1,10 @@ -import type { Loc, OptionalId, TypeId } from "@/next/ast/common"; +import type { DecodedExpression } from "@/next/ast/checked-expr"; +import type { DecodedStatement } from "@/next/ast/checked-stmt"; +import type { FuncId, Loc, OptionalId, TypeId } from "@/next/ast/common"; import type { DecodedType, DTypeRef } from "@/next/ast/dtype"; +import type { Lazy } from "@/next/ast/lazy"; import type { SelfType } from "@/next/ast/mtype"; +import type { AsmInstruction, AsmShuffle, ContractAttribute } from "@/next/ast/root"; import type { ViaMember, ViaUser } from "@/next/ast/via"; import type { TactImport } from "@/next/imports/source"; @@ -11,17 +15,19 @@ export type SourceCheckResult = { readonly globals: Scope; } -export type DeclSigs = ReadonlyMap - export type Scope = { - readonly typeDecls: ReadonlyMap; - readonly fnSigs: ReadonlyMap; - readonly constSigs: ReadonlyMap; - readonly extSigs: ReadonlyMap; + readonly typeDecls: ReadonlyMap>; + readonly functions: ReadonlyMap>; + readonly constants: ReadonlyMap>; + readonly extensions: ReadonlyMap[]>>; +} + +export type Decl = { + readonly decl: T; + readonly via: ViaUser; } export type TypeDeclSig = - | BadSig | AliasSig | ContractSig | TraitSig @@ -29,112 +35,124 @@ export type TypeDeclSig = | MessageSig | UnionSig -export type DeclSig = { - readonly use: TypeUse; - readonly arity: number; - readonly via: ViaUser; -} -export type TypeUse = "usual" | "alias" | "contract" | "forbidden" - export type ConstSig = { - readonly type: DecodedType; - readonly via: ViaUser; + readonly initializer: Lazy; + readonly type: Lazy; } export type FnSig = { readonly type: DecodedFnType; - readonly via: ViaUser; + readonly inline: boolean; + readonly body: Body; } +export type Body = TactBody | FuncBody | FiftBody + +export type TactBody = { + readonly kind: "tact"; + readonly statements: readonly DecodedStatement[]; +}; +export type FuncBody = { + readonly kind: "func"; + readonly nativeName: FuncId; +}; +export type FiftBody = { + readonly kind: "fift"; + readonly shuffle: Lazy; + readonly instructions: readonly AsmInstruction[]; +}; + export type ExtSig = { readonly type: DecodedMethodType; - readonly via: ViaUser; -} - -export type BadSig = { - readonly kind: 'bad'; - readonly arity: number; - readonly via: ViaUser; + readonly inline: boolean; + readonly body: Body; } export type AliasSig = { readonly kind: 'alias'; readonly typeParams: TypeParams; - readonly type: DecodedType; - readonly via: ViaUser; + readonly type: Lazy; } export type ContractSig = { readonly kind: 'contract'; - readonly init: Parameters; - readonly content: CommonSig; - readonly via: ViaUser; + readonly attributes: readonly ContractAttribute[]; + readonly params: Parameters; + readonly content: Lazy; } +export type ContractContent = CommonSig< + Lazy, + Body +> export type TraitSig = { readonly kind: 'trait'; - readonly content: CommonSig; - readonly via: ViaUser; -} -export type CommonSig = { - readonly name: TypeId; - readonly fields: Ordered; - readonly constants: ReadonlyMap; - readonly methods: ReadonlyMap; + readonly content: Lazy; +} +export type TraitContent = CommonSig< + Lazy | undefined, + Body | undefined +> +export type CommonSig = { + readonly fieldish: Ordered>>; + readonly methods: ReadonlyMap>>; readonly bounce: BounceSig; readonly internal: RecvSig; readonly external: RecvSig; } -export type InhFieldSig = { - readonly type: DecodedType - readonly via: ViaMember; +export type Fieldish = InhFieldSig | FieldConstSig; +export type InhFieldSig = { + readonly kind: 'field'; + readonly type: Lazy + readonly init: Expr; } - -export type FieldConstSig = { +export type FieldConstSig = { + readonly kind: 'constant'; readonly overridable: boolean; - readonly override: boolean; - readonly type: DecodedType; - readonly via: ViaMember; + readonly type: Lazy; + readonly init: Expr; } -export type MethodSig = { +export type MethodSig = { readonly overridable: boolean; - readonly override: boolean; - readonly type: DecodedFnType; - readonly via: ViaMember; + readonly type: DecodedMethodType; + readonly inline: boolean; + readonly body: Body; + readonly getMethodId: Lazy | undefined; } export type BounceSig = { - readonly message: ReadonlyMap; - readonly messageAny: undefined | MessageAnyRecv; + readonly message: ReadonlyMap>; + readonly messageAny: undefined | DeclMem; } export type RecvSig = { - readonly message: ReadonlyMap; - readonly messageAny: undefined | MessageAnyRecv; - readonly string: ReadonlyMap; - readonly stringAny: undefined | StringAnyRecv; - readonly empty: undefined | EmptyRecv; + readonly message: ReadonlyMap>; + readonly messageAny: undefined | DeclMem; + readonly string: ReadonlyMap>; + readonly stringAny: undefined | DeclMem; + readonly empty: undefined | DeclMem; } export type MessageRecv = { readonly name: OptionalId; readonly type: DTypeRef; - readonly via: ViaMember; } export type MessageAnyRecv = { readonly name: OptionalId; - readonly via: ViaMember; } export type StringRecv = { readonly comment: string; - readonly via: ViaMember; } export type StringAnyRecv = { readonly name: OptionalId; - readonly via: ViaMember; } export type EmptyRecv = { + readonly one: 1; +} + +export type DeclMem = { + readonly decl: T; readonly via: ViaMember; } @@ -142,44 +160,43 @@ export type StructSig = { readonly kind: "struct"; readonly typeParams: TypeParams; readonly fields: Ordered; - readonly via: ViaUser; } export type MessageSig = { readonly kind: "message"; - readonly typeParams: TypeParams; readonly fields: Ordered; - readonly via: ViaUser; } export type UnionSig = { readonly kind: "union"; readonly typeParams: TypeParams; - readonly cases: ReadonlyMap>; - readonly via: ViaUser; + readonly cases: ReadonlyMap>>; } export type FieldSig = { - readonly type: DecodedType; + readonly type: Lazy; readonly via: ViaUser; } export type DecodedFnType = { + readonly kind: "DecodedFnType"; readonly typeParams: TypeParams; readonly params: Parameters; - readonly returnType: DecodedType, + readonly returnType: Lazy, } export type DecodedMethodType = { + readonly kind: "DecodedMethodType"; + readonly mutates: boolean; readonly typeParams: TypeParams; readonly self: SelfType; readonly params: Parameters; - readonly returnType: DecodedType, + readonly returnType: Lazy, } export type DecodedParameter = { readonly name: OptionalId; - readonly type: DecodedType; + readonly type: Lazy; readonly loc: Loc; }; @@ -195,7 +212,7 @@ export type Parameters = { export type Parameter = { readonly name: OptionalId; - readonly type: DecodedType; + readonly type: Lazy; readonly loc: Loc; }; @@ -203,5 +220,3 @@ export type TypeParams = { readonly order: readonly TypeId[]; readonly set: ReadonlySet; } - - diff --git a/src/next/ast/generated/checked-expr.ts b/src/next/ast/generated/checked-expr.ts new file mode 100644 index 0000000000..c8b37ac848 --- /dev/null +++ b/src/next/ast/generated/checked-expr.ts @@ -0,0 +1,198 @@ +/* eslint-disable @typescript-eslint/no-unnecessary-condition */ +import type * as $ from "@/next/ast/checked-expr"; +import type * as $c from "@/next/ast/common"; +import type * as $d from "@/next/ast/dtype"; +import type * as $e from "@/next/ast/expression"; +import type { Lazy } from "@/next/ast/lazy"; + + +export type DCodeOf = $.DCodeOf; +export const DCodeOf = (contract: $c.TypeId, computedType: Lazy<$d.DecodedType>, loc: $c.Loc): $.DCodeOf => Object.freeze({ + kind: "code_of", + contract, + computedType, + loc +}); +export const isDCodeOf = ($value: DCodeOf) => $value.kind === "code_of"; +export type DNumber = $.DNumber; +export const DNumber = (base: $e.NumberBase, value: bigint, computedType: Lazy<$d.DecodedType>, loc: $c.Loc): $.DNumber => Object.freeze({ + kind: "number", + base, + value, + computedType, + loc +}); +export const isDNumber = ($value: DNumber) => $value.kind === "number"; +export type DBoolean = $.DBoolean; +export const DBoolean = (value: boolean, computedType: Lazy<$d.DecodedType>, loc: $c.Loc): $.DBoolean => Object.freeze({ + kind: "boolean", + value, + computedType, + loc +}); +export const isDBoolean = ($value: DBoolean) => $value.kind === "boolean"; +export type DNull = $.DNull; +export const DNull = (computedType: Lazy<$d.DecodedType>, loc: $c.Loc): $.DNull => Object.freeze({ + kind: "null", + computedType, + loc +}); +export const isDNull = ($value: DNull) => $value.kind === "null"; +export type DString = $.DString; +export const DString = (value: string, computedType: Lazy<$d.DecodedType>, loc: $c.Loc): $.DString => Object.freeze({ + kind: "string", + value, + computedType, + loc +}); +export const isDString = ($value: DString) => $value.kind === "string"; +export type DVar = $.DVar; +export const DVar = (name: string, computedType: Lazy<$d.DecodedType>, loc: $c.Loc): $.DVar => Object.freeze({ + kind: "var", + name, + computedType, + loc +}); +export const isDVar = ($value: DVar) => $value.kind === "var"; +export type DUnit = $.DUnit; +export const DUnit = (computedType: Lazy<$d.DecodedType>, loc: $c.Loc): $.DUnit => Object.freeze({ + kind: "unit", + computedType, + loc +}); +export const isDUnit = ($value: DUnit) => $value.kind === "unit"; +export type DSetLiteral = $.DSetLiteral; +export const DSetLiteral = (valueType: $d.DecodedType, computedType: Lazy<$d.DecodedType>, fields: readonly $.DecodedExpression[], loc: $c.Loc): $.DSetLiteral => Object.freeze({ + kind: "set_literal", + valueType, + fields, + computedType, + loc +}); +export const isDSetLiteral = ($value: DSetLiteral) => $value.kind === "set_literal"; +export type DMapField = $.DMapField; +export const DMapField = (key: $.DecodedExpression, value: $.DecodedExpression): $.DMapField => Object.freeze({ + key, + value +}); +export type DMapLiteral = $.DMapLiteral; +export const DMapLiteral = (type_: $d.DTypeMap, computedType: Lazy<$d.DecodedType>, fields: readonly $.DMapField[], loc: $c.Loc): $.DMapLiteral => Object.freeze({ + kind: "map_literal", + type: type_, + fields, + computedType, + loc +}); +export const isDMapLiteral = ($value: DMapLiteral) => $value.kind === "map_literal"; +export type DTensor = $.DTensor; +export const DTensor = (children: readonly $.DecodedExpression[], computedType: Lazy<$d.DecodedType>, loc: $c.Loc): $.DTensor => Object.freeze({ + kind: "tensor", + children, + computedType, + loc +}); +export const isDTensor = ($value: DTensor) => $value.kind === "tensor"; +export type DTuple = $.DTuple; +export const DTuple = (children: readonly $.DecodedExpression[], computedType: Lazy<$d.DecodedType>, loc: $c.Loc): $.DTuple => Object.freeze({ + kind: "tuple", + children, + computedType, + loc +}); +export const isDTuple = ($value: DTuple) => $value.kind === "tuple"; +export type DInitOf = $.DInitOf; +export const DInitOf = (contract: $c.TypeId, args: readonly $.DecodedExpression[], computedType: Lazy<$d.DecodedType>, loc: $c.Loc): $.DInitOf => Object.freeze({ + kind: "init_of", + contract, + args, + computedType, + loc +}); +export const isDInitOf = ($value: DInitOf) => $value.kind === "init_of"; +export type DStructFieldInitializer = $.DStructFieldInitializer; +export const DStructFieldInitializer = (field: $c.Id, initializer: $.DecodedExpression, loc: $c.Loc): $.DStructFieldInitializer => Object.freeze({ + field, + initializer, + loc +}); +export type DStructInstance = $.DStructInstance; +export const DStructInstance = (type_: $c.TypeId, typeArgs: readonly $d.DecodedType[], args: readonly $.DStructFieldInitializer[], computedType: Lazy<$d.DecodedType>, loc: $c.Loc): $.DStructInstance => Object.freeze({ + kind: "struct_instance", + type: type_, + typeArgs, + args, + computedType, + loc +}); +export const isDStructInstance = ($value: DStructInstance) => $value.kind === "struct_instance"; +export type DFieldAccess = $.DFieldAccess; +export const DFieldAccess = (aggregate: $.DecodedExpression, field: $c.Id, computedType: Lazy<$d.DecodedType>, loc: $c.Loc): $.DFieldAccess => Object.freeze({ + kind: "field_access", + aggregate, + field, + computedType, + loc +}); +export const isDFieldAccess = ($value: DFieldAccess) => $value.kind === "field_access"; +export type DStaticMethodCall = $.DStaticMethodCall; +export const DStaticMethodCall = (self: $c.TypeId, typeArgs: readonly $d.DecodedType[], function_: $c.Id, args: readonly $.DecodedExpression[], computedType: Lazy<$d.DecodedType>, loc: $c.Loc): $.DStaticMethodCall => Object.freeze({ + kind: "static_method_call", + self, + typeArgs, + function: function_, + args, + computedType, + loc +}); +export const isDStaticMethodCall = ($value: DStaticMethodCall) => $value.kind === "static_method_call"; +export type DStaticCall = $.DStaticCall; +export const DStaticCall = (function_: $c.Id, typeArgs: readonly $d.DecodedType[], args: readonly $.DecodedExpression[], computedType: Lazy<$d.DecodedType>, loc: $c.Loc): $.DStaticCall => Object.freeze({ + kind: "static_call", + function: function_, + typeArgs, + args, + computedType, + loc +}); +export const isDStaticCall = ($value: DStaticCall) => $value.kind === "static_call"; +export type DMethodCall = $.DMethodCall; +export const DMethodCall = (self: $.DecodedExpression, method: $c.Id, typeArgs: readonly $d.DecodedType[], args: readonly $.DecodedExpression[], computedType: Lazy<$d.DecodedType>, loc: $c.Loc): $.DMethodCall => Object.freeze({ + kind: "method_call", + self, + method, + typeArgs, + args, + computedType, + loc +}); +export const isDMethodCall = ($value: DMethodCall) => $value.kind === "method_call"; +export type DConditional = $.DConditional; +export const DConditional = (condition: $.DecodedExpression, thenBranch: $.DecodedExpression, elseBranch: $.DecodedExpression, computedType: Lazy<$d.DecodedType>, loc: $c.Loc): $.DConditional => Object.freeze({ + kind: "conditional", + condition, + thenBranch, + elseBranch, + computedType, + loc +}); +export const isDConditional = ($value: DConditional) => $value.kind === "conditional"; +export type DOpUnary = $.DOpUnary; +export const DOpUnary = (op: $e.UnaryOperation, operand: $.DecodedExpression, computedType: Lazy<$d.DecodedType>, loc: $c.Loc): $.DOpUnary => Object.freeze({ + kind: "op_unary", + op, + operand, + computedType, + loc +}); +export const isDOpUnary = ($value: DOpUnary) => $value.kind === "op_unary"; +export type DOpBinary = $.DOpBinary; +export const DOpBinary = (op: $e.BinaryOperation, left: $.DecodedExpression, right: $.DecodedExpression, computedType: Lazy<$d.DecodedType>, loc: $c.Loc): $.DOpBinary => Object.freeze({ + kind: "op_binary", + op, + left, + right, + computedType, + loc +}); +export const isDOpBinary = ($value: DOpBinary) => $value.kind === "op_binary"; +export type DecodedExpression = $.DecodedExpression; diff --git a/src/next/ast/generated/checked-stmt.ts b/src/next/ast/generated/checked-stmt.ts new file mode 100644 index 0000000000..773c3f65ea --- /dev/null +++ b/src/next/ast/generated/checked-stmt.ts @@ -0,0 +1,120 @@ +/* eslint-disable @typescript-eslint/no-unnecessary-condition */ +import type * as $ from "@/next/ast/checked-stmt"; +import type * as $e from "@/next/ast/checked-expr"; +import type * as $c from "@/next/ast/common"; +import type * as $s from "@/next/ast/statement"; + +export type DStatementLet = $.DStatementLet; +export const DStatementLet = (name: $c.OptionalId, expression: $e.DecodedExpression, loc: $c.Loc): $.DStatementLet => Object.freeze({ + kind: "statement_let", + name, + expression, + loc +}); +export const isDStatementLet = ($value: DStatementLet) => $value.kind === "statement_let"; +export type DStatementReturn = $.DStatementReturn; +export const DStatementReturn = (expression: $e.DecodedExpression | undefined, loc: $c.Loc): $.DStatementReturn => Object.freeze({ + kind: "statement_return", + expression, + loc +}); +export const isDStatementReturn = ($value: DStatementReturn) => $value.kind === "statement_return"; +export type DStatementExpression = $.DStatementExpression; +export const DStatementExpression = (expression: $e.DecodedExpression, loc: $c.Loc): $.DStatementExpression => Object.freeze({ + kind: "statement_expression", + expression, + loc +}); +export const isDStatementExpression = ($value: DStatementExpression) => $value.kind === "statement_expression"; +export type DStatementAssign = $.DStatementAssign; +export const DStatementAssign = (path: $e.DecodedExpression, expression: $e.DecodedExpression, loc: $c.Loc): $.DStatementAssign => Object.freeze({ + kind: "statement_assign", + path, + expression, + loc +}); +export const isDStatementAssign = ($value: DStatementAssign) => $value.kind === "statement_assign"; +export type DStatementAugmentedAssign = $.DStatementAugmentedAssign; +export const DStatementAugmentedAssign = (op: $s.AugmentedAssignOperation, path: $e.DecodedExpression, expression: $e.DecodedExpression, loc: $c.Loc): $.DStatementAugmentedAssign => Object.freeze({ + kind: "statement_augmentedassign", + op, + path, + expression, + loc +}); +export const isDStatementAugmentedAssign = ($value: DStatementAugmentedAssign) => $value.kind === "statement_augmentedassign"; +export type DStatementDestruct = $.DStatementDestruct; +export const DStatementDestruct = (type_: $c.TypeId, identifiers: ReadonlyMap, ignoreUnspecifiedFields: boolean, expression: $e.DecodedExpression, loc: $c.Loc): $.DStatementDestruct => Object.freeze({ + kind: "statement_destruct", + type: type_, + identifiers, + ignoreUnspecifiedFields, + expression, + loc +}); +export const isDStatementDestruct = ($value: DStatementDestruct) => $value.kind === "statement_destruct"; +export type DStatementBlock = $.DStatementBlock; +export const DStatementBlock = (statements: $.DStatementList, loc: $c.Loc): $.DStatementBlock => Object.freeze({ + kind: "statement_block", + statements, + loc +}); +export const isDStatementBlock = ($value: DStatementBlock) => $value.kind === "statement_block"; +export type DStatementForEach = $.DStatementForEach; +export const DStatementForEach = (keyName: $c.OptionalId, valueName: $c.OptionalId, map: $e.DecodedExpression, statements: $.DStatementList, loc: $c.Loc): $.DStatementForEach => Object.freeze({ + kind: "statement_foreach", + keyName, + valueName, + map, + statements, + loc +}); +export const isDStatementForEach = ($value: DStatementForEach) => $value.kind === "statement_foreach"; +export type DCatchBlock = $.DCatchBlock; +export const DCatchBlock = (catchName: $c.OptionalId, catchStatements: $.DStatementList): $.DCatchBlock => Object.freeze({ + catchName, + catchStatements +}); +export type DStatementTry = $.DStatementTry; +export const DStatementTry = (statements: $.DStatementList, catchBlock: $.DCatchBlock | undefined, loc: $c.Loc): $.DStatementTry => Object.freeze({ + kind: "statement_try", + statements, + catchBlock, + loc +}); +export const isDStatementTry = ($value: DStatementTry) => $value.kind === "statement_try"; +export type DStatementRepeat = $.DStatementRepeat; +export const DStatementRepeat = (iterations: $e.DecodedExpression, statements: $.DStatementList, loc: $c.Loc): $.DStatementRepeat => Object.freeze({ + kind: "statement_repeat", + iterations, + statements, + loc +}); +export const isDStatementRepeat = ($value: DStatementRepeat) => $value.kind === "statement_repeat"; +export type DStatementUntil = $.DStatementUntil; +export const DStatementUntil = (condition: $e.DecodedExpression, statements: $.DStatementList, loc: $c.Loc): $.DStatementUntil => Object.freeze({ + kind: "statement_until", + condition, + statements, + loc +}); +export const isDStatementUntil = ($value: DStatementUntil) => $value.kind === "statement_until"; +export type DStatementWhile = $.DStatementWhile; +export const DStatementWhile = (condition: $e.DecodedExpression, statements: $.DStatementList, loc: $c.Loc): $.DStatementWhile => Object.freeze({ + kind: "statement_while", + condition, + statements, + loc +}); +export const isDStatementWhile = ($value: DStatementWhile) => $value.kind === "statement_while"; +export type DStatementList = $.DStatementList; +export type DStatementCondition = $.DStatementCondition; +export const DStatementCondition = (condition: $e.DecodedExpression, trueStatements: $.DStatementList, falseStatements: $.DStatementList | undefined, loc: $c.Loc): $.DStatementCondition => Object.freeze({ + kind: "statement_condition", + condition, + trueStatements, + falseStatements, + loc +}); +export const isDStatementCondition = ($value: DStatementCondition) => $value.kind === "statement_condition"; +export type DecodedStatement = $.DecodedStatement; diff --git a/src/next/ast/generated/checked.ts b/src/next/ast/generated/checked.ts index 9de5f5e346..85df72a2b9 100644 --- a/src/next/ast/generated/checked.ts +++ b/src/next/ast/generated/checked.ts @@ -5,180 +5,135 @@ import type * as $m from "@/next/ast/mtype"; import type * as $v from "@/next/ast/via"; import type * as $ from "@/next/ast/checked"; import type { TactImport } from "@/next/imports/source"; +import type { Lazy } from "@/next/ast/lazy"; +import type { AsmInstruction, AsmShuffle, ContractAttribute } from "@/next/ast/root"; +import type { DecodedStatement } from "@/next/ast/checked-stmt"; +import type { DecodedExpression } from "@/next/ast/checked-expr"; -export type TypeUse = $.TypeUse; -export const allTypeUse: readonly $.TypeUse[] = ["usual", "alias", "forbidden"]; -export type DeclSig = $.DeclSig; -export const DeclSig = (use: $.TypeUse, arity: number, via: $v.ViaUser): $.DeclSig => Object.freeze({ - use, - arity, - via -}); -export type DeclSigs = $.DeclSigs; export type TypeParams = $.TypeParams; export const TypeParams = (order: readonly $c.TypeId[], set: ReadonlySet): TypeParams => Object.freeze({ order, set, }); export type AliasSig = $.AliasSig; -export const AliasSig = (typeParams: $.TypeParams, type_: $d.DecodedType, via: $v.ViaUser): $.AliasSig => Object.freeze({ +export const AliasSig = (typeParams: $.TypeParams, type_: Lazy<$d.DecodedType>): $.AliasSig => Object.freeze({ kind: 'alias', typeParams, type: type_, - via }); export type Ordered = $.Ordered; export const Ordered = (order: readonly string[], map: ReadonlyMap): $.Ordered => Object.freeze({ order, map }); -export type InhFieldSig = $.InhFieldSig; -export const InhFieldSig = (type_: $d.DecodedType, via: $v.ViaMember): $.InhFieldSig => Object.freeze({ - type: type_, - via -}); -export type FieldConstSig = $.FieldConstSig; -export const FieldConstSig = (overridable: boolean, override: boolean, type_: $d.DecodedType, via: $v.ViaMember): $.FieldConstSig => Object.freeze({ - overridable, - override, - type: type_, - via -}); + export type DecodedFnType = $.DecodedFnType; -export const DecodedFnType = (typeParams: $.TypeParams, params: $.Parameters, returnType: $d.DecodedType): $.DecodedFnType => Object.freeze({ +export const DecodedFnType = (typeParams: $.TypeParams, params: $.Parameters, returnType: Lazy<$d.DecodedType>): $.DecodedFnType => Object.freeze({ + kind: "DecodedFnType", typeParams, params, returnType }); -export type MethodSig = $.MethodSig; -export const MethodSig = (overridable: boolean, override: boolean, type_: $.DecodedFnType, via: $v.ViaMember): $.MethodSig => Object.freeze({ - overridable, - override, - type: type_, - via -}); export type MessageRecv = $.MessageRecv; -export const MessageRecv = (name: $c.OptionalId, type_: $d.DTypeRef, via: $v.ViaMember): $.MessageRecv => Object.freeze({ +export const MessageRecv = (name: $c.OptionalId, type_: $d.DTypeRef): $.MessageRecv => Object.freeze({ name, type: type_, - via }); export type MessageAnyRecv = $.MessageAnyRecv; -export const MessageAnyRecv = (name: $c.OptionalId, via: $v.ViaMember): $.MessageAnyRecv => Object.freeze({ +export const MessageAnyRecv = (name: $c.OptionalId): $.MessageAnyRecv => Object.freeze({ name, - via }); export type BounceSig = $.BounceSig; -export const BounceSig = (message: ReadonlyMap, messageAny: $.MessageAnyRecv | undefined): $.BounceSig => Object.freeze({ +export const BounceSig = (message: ReadonlyMap>, messageAny: DeclMem<$.MessageAnyRecv> | undefined): $.BounceSig => Object.freeze({ message, messageAny }); export type StringRecv = $.StringRecv; -export const StringRecv = (comment: string, via: $v.ViaMember): $.StringRecv => Object.freeze({ +export const StringRecv = (comment: string): $.StringRecv => Object.freeze({ comment, - via }); export type StringAnyRecv = $.StringAnyRecv; -export const StringAnyRecv = (name: $c.OptionalId, via: $v.ViaMember): $.StringAnyRecv => Object.freeze({ +export const StringAnyRecv = (name: $c.OptionalId): $.StringAnyRecv => Object.freeze({ name, - via }); export type EmptyRecv = $.EmptyRecv; -export const EmptyRecv = (via: $v.ViaMember): $.EmptyRecv => Object.freeze({ - via +export const EmptyRecv = (): $.EmptyRecv => Object.freeze({ + one: 1, }); export type RecvSig = $.RecvSig; -export const RecvSig = (message: ReadonlyMap, messageAny: $.MessageAnyRecv | undefined, string_: ReadonlyMap, stringAny: $.StringAnyRecv | undefined, empty: $.EmptyRecv | undefined): $.RecvSig => Object.freeze({ +export const RecvSig = ( + message: ReadonlyMap>, + messageAny: DeclMem<$.MessageAnyRecv> | undefined, + string_: ReadonlyMap>, + stringAny: DeclMem<$.StringAnyRecv> | undefined, + empty: DeclMem<$.EmptyRecv> | undefined +): $.RecvSig => Object.freeze({ message, messageAny, string: string_, stringAny, empty }); -export type CommonSig = $.CommonSig; -export const CommonSig = (name: $c.TypeId, fields: $.Ordered<$.InhFieldSig>, constants: ReadonlyMap, methods: ReadonlyMap, bounce: $.BounceSig, internal: $.RecvSig, external: $.RecvSig): $.CommonSig => Object.freeze({ - name, - fields, - constants, - methods, - bounce, - internal, - external -}); -export type ContractSig = $.ContractSig; -export const ContractSig = (init: $.Parameters, content: $.CommonSig, via: $v.ViaUser): $.ContractSig => Object.freeze({ - kind: 'contract', - init, - content, - via, -}); -export type TraitSig = $.TraitSig; -export const TraitSig = (content: $.CommonSig, via: $v.ViaUser): $.TraitSig => Object.freeze({ - kind: 'trait', - content, - via -}); export type FieldSig = $.FieldSig; -export const FieldSig = (type_: $d.DecodedType, via: $v.ViaUser): $.FieldSig => Object.freeze({ +export const FieldSig = (type_: Lazy<$d.DecodedType>, via: $v.ViaUser): $.FieldSig => Object.freeze({ type: type_, via }); export type StructSig = $.StructSig; -export const StructSig = (typeParams: $.TypeParams, fields: $.Ordered<$.FieldSig>, via: $v.ViaUser): $.StructSig => Object.freeze({ +export const StructSig = (typeParams: $.TypeParams, fields: $.Ordered<$.FieldSig>): $.StructSig => Object.freeze({ kind: "struct", typeParams, fields, - via }); export const isStructSig = ($value: StructSig) => $value.kind === "struct"; export type MessageSig = $.MessageSig; -export const MessageSig = (typeParams: $.TypeParams, fields: $.Ordered<$.FieldSig>, via: $v.ViaUser): $.MessageSig => Object.freeze({ +export const MessageSig = (typeParams: $.TypeParams, fields: $.Ordered<$.FieldSig>): $.MessageSig => Object.freeze({ kind: "message", typeParams, fields, - via }); export const isMessageSig = ($value: MessageSig) => $value.kind === "message"; export type UnionSig = $.UnionSig; -export const UnionSig = (typeParams: $.TypeParams, cases: ReadonlyMap>, via: $v.ViaUser): $.UnionSig => Object.freeze({ +export const UnionSig = (typeParams: $.TypeParams, cases: ReadonlyMap>>): $.UnionSig => Object.freeze({ kind: "union", typeParams, cases, - via }); export const isUnionSig = ($value: UnionSig) => $value.kind === "union"; export type TypeDeclSig = $.TypeDeclSig; -export type FnSig = $.FnSig; -export const FnSig = (type_: $.DecodedFnType, via: $v.ViaUser): $.FnSig => Object.freeze({ - type: type_, - via -}); export type ConstSig = $.ConstSig; -export const ConstSig = (type_: $d.DecodedType, via: $v.ViaUser): $.ConstSig => Object.freeze({ +export const ConstSig = (init: Lazy, type_: Lazy<$d.DecodedType>): $.ConstSig => Object.freeze({ + initializer: init, type: type_, - via }); export type ExtSig = $.ExtSig; -export const ExtSig = (type: $.DecodedMethodType, via: $v.ViaUser): $.ExtSig => Object.freeze({ +export const ExtSig = (type: $.DecodedMethodType, inline: boolean, body: $.Body): $.ExtSig => Object.freeze({ type, - via + inline, + body, }); export type Scope = $.Scope; -export const Scope = (typeDecls: ReadonlyMap, fnSigs: ReadonlyMap, constSigs: ReadonlyMap, extSigs: ReadonlyMap): $.Scope => Object.freeze({ +export type Decl = $.Decl; +export const Decl = (decl: T, via: $v.ViaUser): Decl => ({ + decl, via +}); +export const Scope = (typeDecls: ReadonlyMap>, fnSigs: ReadonlyMap>, constSigs: ReadonlyMap>, extSigs: ReadonlyMap[]>>): $.Scope => Object.freeze({ typeDecls, - fnSigs, - constSigs, - extSigs + functions: fnSigs, + constants: constSigs, + extensions: extSigs }); export type DecodedMethodType = $.DecodedMethodType; -export const DecodedMethodType = (typeParams: $.TypeParams, self: $m.SelfType, params: $.Parameters, returnType: $d.DecodedType): $.DecodedMethodType => Object.freeze({ +export const DecodedMethodType = (mutates: boolean, typeParams: $.TypeParams, self: $m.SelfType, params: $.Parameters, returnType: Lazy<$d.DecodedType>): $.DecodedMethodType => Object.freeze({ + kind: "DecodedMethodType", + mutates, typeParams, self, params, returnType }); export type DecodedParameter = $.DecodedParameter; -export const DecodedParameter = (name: $c.OptionalId, type_: $d.DecodedType, loc: $c.Loc): $.DecodedParameter => Object.freeze({ +export const DecodedParameter = (name: $c.OptionalId, type_: Lazy<$d.DecodedType>, loc: $c.Loc): $.DecodedParameter => Object.freeze({ name, type: type_, loc @@ -188,18 +143,8 @@ export const SourceCheckResult = (importedBy: TactImport, globals: $.Scope): $.S importedBy, globals }); -export type BadSig = $.BadSig; -export const BadSig = ( - arity: number, - via: $v.ViaUser, -): $.BadSig => Object.freeze({ - kind: "bad", - arity, - via, -}); -export const isBadSig = ($value: BadSig) => $value.kind === "bad"; export type Parameter = $.Parameter; -export const Parameter = (name: $c.OptionalId, type_: $d.DecodedType, loc: $c.Loc): $.Parameter => Object.freeze({ +export const Parameter = (name: $c.OptionalId, type_: Lazy<$d.DecodedType>, loc: $c.Loc): $.Parameter => Object.freeze({ name, type: type_, loc @@ -208,4 +153,82 @@ export type Parameters = $.Parameters; export const Parameters = (order: readonly $.Parameter[], set: ReadonlySet): $.Parameters => Object.freeze({ order, set -}); \ No newline at end of file +}); +export type TactBody = $.TactBody; +export const TactBody = (statements: readonly DecodedStatement[]): $.TactBody => Object.freeze({ + kind: "tact", + statements +}); +export const isTactBody = ($value: TactBody) => $value.kind === "tact"; +export type FuncBody = $.FuncBody; +export const FuncBody = (nativeName: $c.FuncId): $.FuncBody => Object.freeze({ + kind: "func", + nativeName +}); +export const isFuncBody = ($value: FuncBody) => $value.kind === "func"; +export type FiftBody = $.FiftBody; +export const FiftBody = (shuffle: Lazy, instructions: readonly AsmInstruction[]): $.FiftBody => Object.freeze({ + kind: "fift", + shuffle, + instructions +}); +export const isFiftBody = ($value: FiftBody) => $value.kind === "fift"; +export type Body = $.Body; +export type FnSig = $.FnSig; +export const FnSig = (type_: $.DecodedFnType, inline: boolean, body: $.Body): $.FnSig => Object.freeze({ + type: type_, + inline, + body, +}); +export type DeclMem = $.DeclMem; +export const DeclMem = (decl: T, via: $v.ViaMember): DeclMem => ({ + decl, via +}); +export type InhFieldSig = $.InhFieldSig; +export const InhFieldSig = (type_: Lazy<$d.DecodedType>, init: Expr): $.InhFieldSig => Object.freeze({ + kind: "field", + type: type_, + init +}); +export const isInhFieldSig = ($value: InhFieldSig) => $value.kind === "field"; +export type FieldConstSig = $.FieldConstSig; +export const FieldConstSig = (overridable: boolean, type_: Lazy<$d.DecodedType>, init: Expr): $.FieldConstSig => Object.freeze({ + kind: "constant", + overridable, + type: type_, + init +}); +export const isFieldConstSig = ($value: FieldConstSig) => $value.kind === "constant"; +export type Fieldish = $.Fieldish; +export type MethodSig = $.MethodSig; +export const MethodSig = (overridable: boolean, type_: $.DecodedMethodType, inline: boolean, body: Body, getMethodId: Lazy | undefined): $.MethodSig => Object.freeze({ + overridable, + type: type_, + inline, + body, + getMethodId +}); +export type CommonSig = $.CommonSig; +export const CommonSig = (fieldish: $.Ordered<$.DeclMem<$.Fieldish>>, methods: ReadonlyMap>>, bounce: $.BounceSig, internal: $.RecvSig, external: $.RecvSig): $.CommonSig => Object.freeze({ + fieldish, + methods, + bounce, + internal, + external +}); +export type ContractSig = $.ContractSig; +export const ContractSig = (attributes: readonly ContractAttribute[], params: $.Parameters, content: Lazy<$.CommonSig, $.Body>>): $.ContractSig => Object.freeze({ + kind: "contract", + attributes, + params, + content +}); +export const isContractSig = ($value: ContractSig) => $value.kind === "contract"; +export type ContractContent = $.ContractContent; +export type TraitContent = $.TraitContent; +export type TraitSig = $.TraitSig; +export const TraitSig = (content: Lazy<$.CommonSig | undefined, $.Body | undefined>>): $.TraitSig => Object.freeze({ + kind: "trait", + content +}); +export const isTraitSig = ($value: TraitSig) => $value.kind === "trait"; diff --git a/src/next/ast/generated/type.ts b/src/next/ast/generated/type.ts index 6c25d2c9c4..4492c3e67f 100644 --- a/src/next/ast/generated/type.ts +++ b/src/next/ast/generated/type.ts @@ -205,7 +205,7 @@ export const TypedParameter = (name: $c.OptionalId, type_: $.Type, loc: $c.Loc): loc }); export type FnType = $.FnType; -export const FnType = (typeParams: readonly $c.TypeId[], params: readonly $.TypedParameter[], returnType: $.Type | undefined): $.FnType => Object.freeze({ +export const FnType = (typeParams: readonly $c.TypeId[], params: readonly $.TypedParameter[], returnType: $.Type): $.FnType => Object.freeze({ typeParams, params, returnType diff --git a/src/next/ast/generated/value.ts b/src/next/ast/generated/value.ts new file mode 100644 index 0000000000..f638af2ea7 --- /dev/null +++ b/src/next/ast/generated/value.ts @@ -0,0 +1,10 @@ +/* eslint-disable @typescript-eslint/no-unnecessary-condition */ +import type * as $ from "@/next/ast/value"; + +export type VNumber = $.VNumber; +export const VNumber = (value: bigint): $.VNumber => Object.freeze({ + kind: "number", + value +}); +export const isVNumber = ($value: VNumber) => $value.kind === "number"; +export type Value = $.Value; diff --git a/src/next/ast/generated/via.ts b/src/next/ast/generated/via.ts index 85d23beb56..cba60e1793 100644 --- a/src/next/ast/generated/via.ts +++ b/src/next/ast/generated/via.ts @@ -34,6 +34,16 @@ export const ViaImport = (throughImport: TactImport, via: $.ViaUser): $.ViaUser return result; }; -export const ViaMember = ( - inheritance: readonly $.ViaUser[] -): $.ViaMember => ({ inheritance }); \ No newline at end of file +export const ViaMemberOrigin = ( + parentName: string, + defLoc: $c.Loc +): $.ViaMember => ({ defLoc, parentName, traits: [] }); + +export const ViaMemberTrait = ( + parentName: string, + defLoc: $c.Loc, + via: $.ViaMember, +): $.ViaMember => ({ defLoc, parentName, traits: [ + [via.parentName, via.defLoc], + ...via.traits +] }); diff --git a/src/next/ast/index.ts b/src/next/ast/index.ts index 3e487640e5..c9024e3897 100644 --- a/src/next/ast/index.ts +++ b/src/next/ast/index.ts @@ -7,4 +7,8 @@ export * from "@/next/ast/generated/dtype"; export * from "@/next/ast/generated/mtype"; export * from "@/next/ast/generated/via"; export * from "@/next/ast/generated/checked"; +export * from "@/next/ast/generated/checked-expr"; +export * from "@/next/ast/generated/checked-stmt"; export * from "@/next/ast/generated/root"; +export * from "@/next/ast/generated/value"; +export * from "@/next/ast/lazy"; diff --git a/src/next/ast/lazy.ts b/src/next/ast/lazy.ts new file mode 100644 index 0000000000..bfe3074ae9 --- /dev/null +++ b/src/next/ast/lazy.ts @@ -0,0 +1,38 @@ +/* eslint-disable require-yield */ +import { throwInternal } from "@/error/errors"; +import type { WithLog } from "@/next/types/errors"; + +export type Lazy = () => WithLog + +export const Lazy = ( + callback: () => WithLog, + onOccurs: () => WithLog = impossible, +): Lazy => { + let result: 'waiting' | 'running' | [T] = 'waiting'; + function* delayed() { + if (typeof result !== 'string') { + return result[0]; + } + if (result === 'running') { + return yield* onOccurs(); + } + result = 'running'; + const output = yield* callback(); + result = [output]; + return output; + } + delayed.toJSON = () => { + return result; + }; + return delayed; +}; + +export const mapLazy = (f: Lazy, g: (t: T) => U): Lazy => { + return function* () { + return g(yield* f()); + }; +}; + +function* impossible(): WithLog { + return throwInternal("Infinite loop in typechecker"); +} diff --git a/src/next/ast/root.ts b/src/next/ast/root.ts index e962b74742..f22496c865 100644 --- a/src/next/ast/root.ts +++ b/src/next/ast/root.ts @@ -63,7 +63,7 @@ export type Contract = { export type Init = InitFunction | InitParams; export type InitFunction = { readonly kind: "init_function"; - readonly args: readonly TypedParameter[]; + readonly params: readonly TypedParameter[]; readonly statements: readonly Statement[]; readonly loc: Loc; }; diff --git a/src/next/ast/type.ts b/src/next/ast/type.ts index e2cd3f66a2..dcaf4ea7a8 100644 --- a/src/next/ast/type.ts +++ b/src/next/ast/type.ts @@ -3,7 +3,7 @@ import type { Loc, OptionalId, TypeId } from "@/next/ast/common"; export type FnType = { readonly typeParams: readonly TypeId[]; readonly params: readonly TypedParameter[]; - readonly returnType: Type | undefined, + readonly returnType: Type, } export type MethodFnType = { diff --git a/src/next/ast/value.ts b/src/next/ast/value.ts new file mode 100644 index 0000000000..4d47d05820 --- /dev/null +++ b/src/next/ast/value.ts @@ -0,0 +1,6 @@ +export type Value = VNumber + +export type VNumber = { + readonly kind: 'number'; + readonly value: bigint; +} diff --git a/src/next/ast/via.ts b/src/next/ast/via.ts index a4c4d666d6..176f3963c6 100644 --- a/src/next/ast/via.ts +++ b/src/next/ast/via.ts @@ -21,5 +21,7 @@ export type ViaUser = { } export type ViaMember = { - readonly inheritance: readonly ViaUser[]; + readonly traits: readonly [string, Ast.Loc][]; + readonly defLoc: Ast.Loc; + readonly parentName: string; } diff --git a/src/next/grammar/index.ts b/src/next/grammar/index.ts index f04e2dc2b2..afbf8383c5 100644 --- a/src/next/grammar/index.ts +++ b/src/next/grammar/index.ts @@ -4,7 +4,6 @@ import type { $ast } from "@/next/grammar/grammar"; import * as G from "@/next/grammar/grammar"; import { SyntaxErrors } from "@/next/grammar/errors"; import { makeMakeVisitor } from "@/utils/tricks"; -import type { Loc } from "@/next/ast/common"; import { throwInternal } from "@/error/errors"; import type { SourceLogger } from "@/error/logger-util"; import { parseImportString } from "@/next/grammar/import-parser"; @@ -1457,18 +1456,19 @@ const parseAsmShuffle = const parseAsmFunctionRaw = (node: $ast.AsmFunction): Handler => (ctx) => { + const range = ctx.toRange(node.loc); return Ast.Function( !!parseNamedAttr("inline")(node.attributes)(ctx), parseId(node.name)(ctx), Ast.FnType( map(parseList(node.typeParams), parseTypeId)(ctx), map(parseList(node.parameters), parseParameter)(ctx), - node.returnType ? parseType(node.returnType)(ctx) : undefined, + node.returnType ? parseType(node.returnType)(ctx) : Ast.TypeVoid(range), ), Ast.AsmBody(parseAsmShuffle(node.shuffle)(ctx), [ node.instructions.trim(), ]), - ctx.toRange(node.loc), + range, ); }; @@ -1621,6 +1621,7 @@ const parseContract = const parseFunctionRaw = (node: $ast.$Function): Handler => (ctx) => { + const range = ctx.toRange(node.loc); return Ast.Function( !!parseNamedAttr("inline")(node.attributes)(ctx), parseId(node.name)(ctx), @@ -1629,12 +1630,12 @@ const parseFunctionRaw = map(parseList(node.parameters), parseParameter)(ctx), node.returnType ? parseType(node.returnType)(ctx) - : undefined, + : Ast.TypeVoid(range), ), node.body.$ === "FunctionDeclaration" ? Ast.AbstractBody() : Ast.RegularBody(map(node.body.body, parseStatement)(ctx)), - ctx.toRange(node.loc), + range, ); }; @@ -1737,16 +1738,19 @@ const parseNativeFunctionDecl = loc, }: $ast.NativeFunctionDecl): Handler => (ctx) => { + const range = ctx.toRange(loc); return Ast.Function( !!parseNamedAttr("inline")(attributes)(ctx), parseId(name)(ctx), Ast.FnType( map(parseList(typeParams), parseTypeId)(ctx), map(parseList(parameters), parseParameter)(ctx), - returnType ? parseType(returnType)(ctx) : undefined, + returnType + ? parseType(returnType)(ctx) + : Ast.TypeVoid(range), ), Ast.NativeBody(parseFuncId(nativeName)(ctx)), - ctx.toRange(loc), + range, ); }; diff --git a/src/next/types/alias.ts b/src/next/types/alias.ts new file mode 100644 index 0000000000..04f0133704 --- /dev/null +++ b/src/next/types/alias.ts @@ -0,0 +1,17 @@ +/* eslint-disable require-yield */ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import * as Ast from "@/next/ast"; +import type * as E from "@/next/types/errors"; +import { decodeTypeParams } from "@/next/types/type-params"; +import { decodeTypeLazy } from "@/next/types/type"; + +export function* decodeAlias( + { typeParams, type }: Ast.AliasDecl, + scopeRef: () => Ast.Scope, +): E.WithLog { + const decodedParams = yield* decodeTypeParams(typeParams); + return Ast.AliasSig( + decodedParams, + decodeTypeLazy(decodedParams, type, scopeRef), + ); +} diff --git a/src/next/types/aliases.ts b/src/next/types/aliases.ts deleted file mode 100644 index 4282c7d4a4..0000000000 --- a/src/next/types/aliases.ts +++ /dev/null @@ -1,302 +0,0 @@ -import * as Ast from "@/next/ast"; -import * as E from "@/next/types/errors"; -import type { TactSource } from "@/next/imports/source"; -import { throwInternal } from "@/error/errors"; -import { decodeTypeParams } from "@/next/types/type-params"; -import { decodeType } from "@/next/types/types"; -import { zip } from "@/utils/array"; - -export function* getAllAliases( - sigs: ReadonlyMap, - imported: readonly Ast.SourceCheckResult[], - source: TactSource, -) { - const importedAliases: Map = new Map(); - const localAliases: Map = new Map(); - - // status of checking alias bodies - const status: Map = new Map(); - - // check that neither of the types have cyclic alias references - function* checkTypes(types: readonly Ast.DecodedType[]): E.WithLog { - let result = true; - for (const type of types) { - const partialResult = yield* checkType(type); - // NB: separate from previous line to avoid short-circuiting - // we want to give ALL error message - result &&= partialResult; - } - return result; - } - - // check decoded type has no cyclic alias references - function* checkType(type: Ast.DecodedType): E.WithLog { - switch (type.kind) { - case "recover": - case "TyInt": - case "TySlice": - case "TyCell": - case "TyBuilder": - case "unit_type": - case "TypeVoid": - case "TypeNull": - case "TypeBool": - case "TypeAddress": - case "TypeString": - case "TypeParam": - case "TypeStringBuilder": { - return true; - } - case "TypeBounced": - case "TypeMaybe": { - return yield* checkType(type.type); - } - case "map_type": { - return (yield* checkType(type.key)) && (yield* checkType(type.value)); - } - case "type_ref": - case "tuple_type": - case "tensor_type": { - return yield* checkTypes(type.typeArgs); - } - case "TypeAlias": { - const result = yield* checkTypes(type.typeArgs); - const name = type.name.text; - if (importedAliases.has(name)) { - return result; - } - const local = localAliases.get(name); - if (local) { - const alias = yield* decodeAlias(local); - return result && alias.kind === 'alias'; - } - return throwInternal("Alias reference was decoded, but doesn't exist"); - } - } - } - - // convert alias into better representation - function* decodeAlias(decl: Ast.AliasDecl): E.WithLog { - const name = decl.name.text; - const s = status.get(name); - const via = Ast.ViaOrigin(decl.loc, source); - if (!s) { - status.set(name, Visiting); - const params = yield* decodeTypeParams(decl.typeParams); - const type = yield* decodeType(sigs, params, decl.type); - const result = !(yield* checkType(type)) - ? Ast.BadSig(decl.typeParams.length, via) - : Ast.AliasSig(params, type, via); - status.set(name, Result(result)); - return result; - } else if (s.kind === 'result') { - return s.result; - } else { - yield EAliasOccurs(name, decl.loc); - return Ast.BadSig(decl.typeParams.length, via); - } - } - - // collect aliases from imports - for (const { globals } of imported) { - for (const [name, decl] of globals.typeDecls) { - if (decl.kind === 'alias' && !importedAliases.has(name)) { - importedAliases.set(name, decl); - } - } - } - - // collect local aliases - for (const decl of source.items.types) { - const name = decl.name.text; - if (decl.kind === 'alias_decl') { - localAliases.set(name, decl); - } - } - - // decode local aliases and combine with imported - const result: Map = - new Map(importedAliases); - for (const [name, decl] of localAliases) { - const alias = yield* decodeAlias(decl) - result.set(name, alias); - } - return result; -} - -type Status = Result | Visiting -// alias was already decoded -type Result = { - readonly kind: 'result'; - readonly result: Ast.AliasSig | Ast.BadSig; -} -const Result = (alias: Ast.AliasSig | Ast.BadSig): Result => ({ kind: 'result', result: alias }); -// we're decoding it right now -type Visiting = { - readonly kind: 'visiting'; -} -const Visiting: Visiting = { kind: 'visiting' }; - -const EAliasOccurs = ( - name: string, - loc: Ast.Loc, -): E.TcError => ({ - loc, - descr: [ - E.TEText(`Alias "${name}" was expanded inside itself`), - ], -}); - -export const dealiasType = ( - sigs: ReadonlyMap, - aliases: ReadonlyMap, - typeParams: Ast.TypeParams, - type: Ast.Type, -) => { - const recN = (types: readonly Ast.DecodedType[]): readonly Ast.DecodedType[] => { - return types.map(type => rec(type)); - }; - const rec = (type: Ast.DecodedType): Ast.DecodedType => { - switch (type.kind) { - case "recover": { - return type; - } - case "type_ref": { - const args = recN(type.typeArgs); - return Ast.DTypeRef(type.name, args, type.loc); - } - case "TypeAlias": { - const alias = aliases.get(type.name.text); - if (!alias) { - return throwInternal("Decoder returned broken reference"); - } - if (alias.kind === 'bad') { - return Ast.DTypeRecover(); - } - const args = recN(type.typeArgs); - // NB! if we could decode alias once, there might be - // a nested one too - return rec( - substitute(alias.type, alias.typeParams, args) - ); - } - case "TypeParam": { - return type; - } - case "map_type": { - const key = rec(type.key); - const value = rec(type.value); - return Ast.DTypeMap(key, value, type.loc); - } - case "TypeBounced": { - const args = rec(type.type); - return Ast.DTypeBounced(args, type.loc); - } - case "TypeMaybe": { - const args = rec(type.type); - return Ast.DTypeMaybe(args, type.loc); - } - case "tuple_type": { - const args = recN(type.typeArgs); - return Ast.DTypeTuple(args, type.loc); - } - case "tensor_type": { - const args = recN(type.typeArgs); - return Ast.DTypeTensor(args, type.loc); - } - case "TyInt": - case "TySlice": - case "TyCell": - case "TyBuilder": - case "unit_type": - case "TypeVoid": - case "TypeNull": - case "TypeBool": - case "TypeAddress": - case "TypeString": - case "TypeStringBuilder": { - return type; - } - } - }; - - function* root() { - return rec(yield* decodeType(sigs, typeParams, type)); - } - return root(); -}; - -const substitute = ( - type: Ast.DecodedType, - params: Ast.TypeParams, - args: readonly Ast.DecodedType[], -): Ast.DecodedType => { - if (params.order.length !== args.length) { - return throwInternal("Decoder didn't check alias arity"); - } - - const substMap = new Map(zip(params.order, args).map(([param, arg]) => { - return [param.text, arg]; - })); - - const recN = (types: readonly Ast.DecodedType[]): readonly Ast.DecodedType[] => { - return types.map(type => rec(type)); - }; - - const rec = (type: Ast.DecodedType): Ast.DecodedType => { - switch (type.kind) { - case "TypeParam": { - const arg = substMap.get(type.name.text); - if (!arg) { - return throwInternal("Decoder didn't scope alias's type args"); - } - return arg; - } - case "type_ref": { - const args = recN(type.typeArgs); - return Ast.DTypeRef(type.name, args, type.loc); - } - case "TypeAlias": { - const args = recN(type.typeArgs); - return Ast.DTypeAliasRef(type.name, args, type.loc); - } - case "map_type": { - const key = rec(type.key); - const value = rec(type.value); - return Ast.DTypeMap(key, value, type.loc); - } - case "TypeBounced": { - const args = rec(type.type); - return Ast.DTypeBounced(args, type.loc); - } - case "TypeMaybe": { - const args = rec(type.type); - return Ast.DTypeMaybe(args, type.loc); - } - case "tuple_type": { - const args = recN(type.typeArgs); - return Ast.DTypeTuple(args, type.loc); - } - case "tensor_type": { - const args = recN(type.typeArgs); - return Ast.DTypeTensor(args, type.loc); - } - case "recover": - case "TyInt": - case "TySlice": - case "TyCell": - case "TyBuilder": - case "unit_type": - case "TypeVoid": - case "TypeNull": - case "TypeBool": - case "TypeAddress": - case "TypeString": - case "TypeStringBuilder": { - return type; - } - } - }; - - return rec(type); -}; \ No newline at end of file diff --git a/src/next/types/body.ts b/src/next/types/body.ts new file mode 100644 index 0000000000..e5a6e95b8a --- /dev/null +++ b/src/next/types/body.ts @@ -0,0 +1,263 @@ +/* eslint-disable require-yield */ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import * as Ast from "@/next/ast"; +import * as E from "@/next/types/errors"; +import { isSubsetOf } from "@/utils/isSubsetOf"; +import { decodeStatements } from "@/next/types/statements"; + +export function* decodeBody( + node: Ast.FunctionalBody, + fnType: Ast.DecodedFnType | Ast.DecodedMethodType, + loc: Ast.Loc, + scopeRef: () => Ast.Scope, +): E.WithLog { + switch (node.kind) { + case "abstract_body": { + yield ENoBody(loc) + return Ast.TactBody([]); + } + case "regular_body": { + return Ast.TactBody( + decodeStatements(node.statements, scopeRef) + ); + } + case "asm_body": { + return Ast.FiftBody( + checkShuffleLazy( + node.shuffle, + fnType, + loc, + scopeRef, + ), + node.instructions, + ); + } + case "native_body": { + return Ast.FuncBody(node.nativeName); + } + } +} + +const ENoBody = ( + loc: Ast.Loc, +): E.TcError => ({ + loc, + descr: [ + E.TEText(`Function must have a body`), + ], +}); + +const checkShuffleLazy = ( + shuffle: Ast.AsmShuffle, + fnType: Ast.DecodedFnType | Ast.DecodedMethodType, + loc: Ast.Loc, + scopeRef: () => Ast.Scope, +) => Ast.Lazy(() => checkShuffle( + shuffle, + fnType, + loc, + scopeRef, +)); + +function* checkShuffle( + shuffle: Ast.AsmShuffle, + fnType: Ast.DecodedFnType | Ast.DecodedMethodType, + loc: Ast.Loc, + scopeRef: () => Ast.Scope, +) { + const { args, ret } = shuffle; + if (args.length !== 0) { + const argSet = new Set(args.map((id) => id.text)); + + if (argSet.size !== args.length) { + yield EDuplicateArgs(loc); + } + + const paramsArray: string[] = []; + for (const typedId of fnType.params.order) { + if (typedId.name.kind === "wildcard") { + yield EWildcardArgs(loc); + } else { + paramsArray.push(typedId.name.text); + } + } + + const paramSet = new Set(paramsArray); + if (!isSubsetOf(paramSet, argSet)) { + yield EMissingArgs(loc); + } + + if (!isSubsetOf(argSet, paramSet)) { + yield EExtraArgs(loc); + } + } + + if (ret.length !== 0) { + const shuffleRetSet = new Set(ret.map((num) => num.value)); + if (shuffleRetSet.size !== ret.length) { + yield EDuplicateRet(loc); + } + + const retTupleSize = yield* getRetTupleSize( + fnType, + scopeRef, + ); + + if (typeof retTupleSize !== 'undefined') { + const returnValueSet = new Set([ + ...Array(retTupleSize).keys().map(x => BigInt(x)) + ]); + + if (!isSubsetOf(returnValueSet, shuffleRetSet)) { + yield EMissingRet(loc); + } + + if (!isSubsetOf(shuffleRetSet, returnValueSet)) { + yield EExtraRet(loc); + } + } + } + + return shuffle; +} + +function* getRetTupleSize( + { kind, returnType }: Ast.DecodedFnType | Ast.DecodedMethodType, + scopeRef: () => Ast.Scope, +): E.WithLog { + const type = yield* returnType(); + const baseSize = yield* getTypeTupleSize(type, scopeRef); + if (typeof baseSize === 'undefined') { + return undefined; + } + return baseSize + (kind === 'DecodedMethodType' ? 1 : 0); +} + +function* getTypeTupleSize( + type: Ast.DecodedType, + scopeRef: () => Ast.Scope, +) { +// TODO: mutating functions also return `self` arg (implicitly in Tact, but explicitly in FunC) + // retTupleSize += isMutating ? 1 : 0; + switch (type.kind) { + case "recover": { + return undefined; + } + case "type_ref": { + const decl = scopeRef().typeDecls.get(type.name.text); + if (!decl) { + return undefined; + } + switch (decl.decl.kind) { + case "contract": { + return decl.decl.content.fields.order.length; + } + case "struct": + case "message": { + return decl.decl.fields.order.length; + } + case "union": { + // unions don't have exact size + return undefined; + } + case "alias": { + // aliases already handled by decoder + return undefined; + } + case "trait": { + // traits cannot be used as types + return undefined; + } + } + // typescript wants this + return undefined; + } + case "TypeAlias": { + return undefined; + } + case "TypeParam": { + // this size can be anything + return undefined; + } + case "map_type": { + return 1; + } + case "TypeBounced": { + // undefined can have weird encodings + return undefined; + } + case "TypeMaybe": { + return getTypeTupleSize(type.type, scopeRef); + } + case "tuple_type": { + return 1; + } + case "tensor_type": { + return type.typeArgs.length; + } + case "TyInt": + case "TySlice": + case "TyCell": + case "TyBuilder": + case "unit_type": + case "TypeBool": + case "TypeAddress": + case "TypeString": + case "TypeStringBuilder": + case "TypeNull": { + return 1; + } + case "TypeVoid": { + return 0; + } + } +} + +const EDuplicateArgs = (loc: Ast.Loc): E.TcError => ({ + loc, + descr: [ + E.TEText(`Argument rearrangement cannot have duplicates`), + ], +}); + +const EWildcardArgs = (loc: Ast.Loc): E.TcError => ({ + loc, + descr: [ + E.TEText(`Argument rearrangement cannot use wildcards`), + ], +}); + +const EMissingArgs = (loc: Ast.Loc): E.TcError => ({ + loc, + descr: [ + E.TEText(`Argument rearrangement must mention all function parameters`), + ], +}); + +const EExtraArgs = (loc: Ast.Loc): E.TcError => ({ + loc, + descr: [ + E.TEText(`Argument rearrangement must mention only function parameters`), + ], +}); + +const EDuplicateRet = (loc: Ast.Loc): E.TcError => ({ + loc, + descr: [ + E.TEText(`Return rearrangement cannot have duplicates`), + ], +}); + +const EMissingRet = (loc: Ast.Loc): E.TcError => ({ + loc, + descr: [ + E.TEText(`Return rearrangement must mention all function parameters`), + ], +}); + +const EExtraRet = (loc: Ast.Loc): E.TcError => ({ + loc, + descr: [ + E.TEText(`Return rearrangement must mention only function parameters`), + ], +}); diff --git a/src/next/types/builtins.ts b/src/next/types/builtins.ts index 7c9f5cb669..ed06c35167 100644 --- a/src/next/types/builtins.ts +++ b/src/next/types/builtins.ts @@ -1,9 +1,17 @@ +/* eslint-disable require-yield */ /* eslint-disable @typescript-eslint/no-unused-vars */ import * as Ast from "@/next/ast"; +// FIXME +export const tactMethodIds = [113617n, 115390n, 121275n]; + const r = Ast.Builtin(); +const FakeLazy = (t: T): Ast.Lazy => function* () { + return t; +}; + const TypeParams = (typeParams: readonly string[]): Ast.TypeParams => { const arr = typeParams.map(name => Ast.TypeId(name, r)); return Ast.TypeParams(arr, new Set(typeParams)); @@ -13,7 +21,7 @@ const Params = (params: Record): Ast.Parameters => { const order: Ast.Parameter[] = []; const set: Set = new Set(); for (const [name, type] of Object.entries(params)) { - order.push(Ast.Parameter(Ast.Id(name, r), type, r)); + order.push(Ast.Parameter(Ast.Id(name, r), FakeLazy(type), r)); set.add(name); } return Ast.Parameters(order, set); @@ -29,18 +37,19 @@ const GenericFn = (name: string, typeParams: readonly string[], params: Record, returnType: Ast.DecodedType): [string, Ast.DecodedFnType] => { return GenericFn(name, [], params, returnType); }; -const MapMethod = (name: string, params: Record, returnType: Ast.DecodedType): [string, Ast.DecodedMethodType] => { +const MapMethod = (name: string, mutates: boolean, params: Record, returnType: Ast.DecodedType): [string, Ast.DecodedMethodType] => { return [name, Ast.DecodedMethodType( + mutates, TypeParams(["K", "V"]), mapType, Params(params), - returnType, + FakeLazy(returnType), )]; }; @@ -106,23 +115,23 @@ export const builtinFunctions: Map = new Map([ export const builtinMethods: Map = new Map([ // set(key: K, value: V): void - MapMethod("set", { key: Ref("K"), value: Ref("V") }, Void), + MapMethod("set", true, { key: Ref("K"), value: Ref("V") }, Void), // get(key: K): Maybe - MapMethod("get", { key: Ref("K") }, Maybe(Ref("V"))), + MapMethod("get", false, { key: Ref("K") }, Maybe(Ref("V"))), // del(key: K): Bool - MapMethod("del", { key: Ref("K") }, Bool), + MapMethod("del", true, { key: Ref("K") }, Bool), // asCell(): Maybe - MapMethod("asCell", {}, Maybe(Cell)), + MapMethod("asCell", false, {}, Maybe(Cell)), // isEmpty(): Bool - MapMethod("isEmpty", {}, Bool), + MapMethod("isEmpty", false, {}, Bool), // exists(key: K): Bool - MapMethod("exists", { key: Ref("K") }, Bool), + MapMethod("exists", false, { key: Ref("K") }, Bool), // deepEquals(other: map): Bool - MapMethod("deepEquals", { other: mapType }, Bool), + MapMethod("deepEquals", false, { other: mapType }, Bool), // replace(key: K, value: V): Bool - MapMethod("replace", { key: Ref("K"), value: Ref("V") }, Bool), + MapMethod("replace", true, { key: Ref("K"), value: Ref("V") }, Bool), // replaceGet(key: K, value: V): map - MapMethod("replaceGet", { key: Ref("K"), value: Ref("V") }, mapType), + MapMethod("replaceGet", true, { key: Ref("K"), value: Ref("V") }, mapType), ]); export const builtinUnary: Map = new Map([ diff --git a/src/next/types/constant-def.ts b/src/next/types/constant-def.ts new file mode 100644 index 0000000000..1f6aba6f3b --- /dev/null +++ b/src/next/types/constant-def.ts @@ -0,0 +1,34 @@ +import * as Ast from "@/next/ast"; +import { assignType, decodeTypeLazy } from "@/next/types/type"; +import { decodeExpr } from "@/next/types/expression"; + +export function decodeConstantDef( + typeParams: Ast.TypeParams, + init: Ast.ConstantDef, + scopeRef: () => Ast.Scope, +): [Ast.Lazy, Ast.Lazy] { + const { type, initializer } = init; + + const ascribedType = type + ? decodeTypeLazy(typeParams, type, scopeRef) + : undefined; + + const lazyExpr = decodeExpr(initializer, scopeRef); + + const decodedType = Ast.Lazy(function* () { + const expr = yield* lazyExpr(); + const computed = yield* expr.computedType(); + if (!ascribedType) { + return computed; + } + const ascribed = yield* ascribedType(); + yield* assignType( + ascribed, + computed, + scopeRef, + ); + return ascribed; + }); + + return [decodedType, lazyExpr]; +} \ No newline at end of file diff --git a/src/next/types/constants.ts b/src/next/types/constants.ts index eb313b1fce..6650ff8f5c 100644 --- a/src/next/types/constants.ts +++ b/src/next/types/constants.ts @@ -1,32 +1,32 @@ +/* eslint-disable require-yield */ import * as Ast from "@/next/ast"; import * as E from "@/next/types/errors"; -import { dealiasType } from "@/next/types/aliases"; -import type { TactImport, TactSource } from "@/next/imports/source"; +import type { TactSource } from "@/next/imports/source"; import { builtinFunctions } from "@/next/types/builtins"; -import { checkExpr } from "@/next/types/expression"; +import { decodeConstantDef } from "@/next/types/constant-def"; const errorKind = "function"; -export function* getAllConstants( +export function* decodeConstants( imported: readonly Ast.SourceCheckResult[], source: TactSource, - sigs: ReadonlyMap, - aliases: ReadonlyMap, - fnSigs: ReadonlyMap, - extSigs: ReadonlyMap, -): E.WithLog> { + scopeRef: () => Ast.Scope, +): E.WithLog>> { const allConstSigs = [ // imported ...imported.flatMap(({ globals, importedBy }) => ( - [...globals.constSigs] - .map(([name, s]) => [name, toSigDecoded(s, importedBy)] as const) + [...globals.constants] + .map(([name, s]) => [name, Ast.Decl(s.decl, Ast.ViaImport(importedBy, s.via))] as const) )), // local - ...yield* E.mapLog(source.items.constants, function* (constant) { - const { name, init, loc } = constant; - const via = Ast.ViaOrigin(loc, source); - const initType = yield* decodeInit(init, loc, sigs, aliases); - return [name.text, Ast.ConstSig(initType, via)] as const; + ...yield* E.mapLog(source.items.constants, function* (c) { + return [ + c.name.text, + Ast.Decl( + yield* decodeConstant(c, scopeRef), + Ast.ViaOrigin(c.loc, source) + ), + ] as const; }), ]; // remove builtins @@ -40,36 +40,23 @@ export function* getAllConstants( return yield* E.toMap(errorKind, filteredSigs); } -function* decodeInit( - init: Ast.ConstantInit, - loc: Ast.Loc, - sigs: ReadonlyMap, - aliases: ReadonlyMap, -): E.WithLog { +function* decodeConstant( + constant: Ast.Constant, + scopeRef: () => Ast.Scope, +) { + const { init, loc } = constant; if (init.kind === "constant_decl") { yield ETopLevelDecl(loc); - return Ast.DTypeRecover(); + const type = function*() { return Ast.DTypeRecover(); }; + const expr = function*() { return Ast.DNull(type, Ast.Builtin()); }; + return Ast.ConstSig(expr, type); + } else { + const typeParams = Ast.TypeParams([], new Set()); + const [type, expr] = decodeConstantDef(typeParams, init, scopeRef); + return Ast.ConstSig(expr, type); } - const { type, initializer } = init; - - const typeParams = Ast.TypeParams([], new Set()); - const ascribedType = type - ? yield* dealiasType(sigs, aliases, typeParams, type) - : undefined; - - const computedType = yield* checkExpr( - initializer, - - ); - - return ascribedType; } -const toSigDecoded = (fn: Ast.ConstSig, importedBy: TactImport): Ast.ConstSig => { - const via = Ast.ViaImport(importedBy, fn.via); - return Ast.ConstSig(fn.type, via); -}; - const ETopLevelDecl = (loc: Ast.Loc): E.TcError => ({ loc, descr: [ diff --git a/src/next/types/contract.ts b/src/next/types/contract.ts new file mode 100644 index 0000000000..0848495eda --- /dev/null +++ b/src/next/types/contract.ts @@ -0,0 +1,120 @@ +/* eslint-disable require-yield */ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import * as Ast from "@/next/ast"; +import * as E from "@/next/types/errors"; +import { throwInternal } from "@/error/errors"; +import { getFieldishGeneral } from "@/next/types/fields"; +import { getInheritedTraits } from "@/next/types/traits-scope"; +import { getMethodsGeneral } from "@/next/types/methods"; + +export function* decodeContract( + contract: Ast.Contract, + scopeRef: () => Ast.Scope, +) { + const { name, attributes, declarations, init } = contract; + const { constants, fields, methods, receivers } = declarations; + + // delayed until we get all traits + const content = Ast.Lazy(function* () { + const traits = yield* getInheritedTraits( + contract.traits, + scopeRef, + ); + + // const contentRef = () => content; + const content: Ast.ContractContent = { + fieldish: yield* getFieldishFromContract( + name.text, + traits, + constants, + fields, + scopeRef, + ), + methods: yield* getMethodsFromContract( + name, + traits, + methods, + scopeRef, + ), + bounce, + external, + internal, + }; + + return content; + }); + + const decodedInit = decodeInit(init, fields, scopeRef); + + return Ast.ContractSig(attributes, decodedInit, content); +} + +function* getMethodsFromContract( + typeName: Ast.TypeId, + traits: readonly Ast.Decl[], + methods: readonly Ast.Method[], + scopeRef: () => Ast.Scope +): E.WithLog>>> { + const res = yield* getMethodsGeneral(typeName, traits, methods, scopeRef); + + const map: Map>> = new Map(); + for (const [name, { via, decl: method }] of res) { + if (method.body) { + // have to recreate DeclMem, because TS doesn't + // narrow here + map.set(name, Ast.DeclMem( + { ...method, body: method.body }, + via, + )); + } else { + // field/constant doesn't have initializer + yield EAbstract("method", name, via); + } + } + + return map; +} + +function* getFieldishFromContract( + typeName: string, + traits: readonly Ast.Decl[], + constants: readonly Ast.FieldConstant[], + fields: readonly Ast.FieldDecl[], + scopeRef: () => Ast.Scope, +): E.WithLog>>>> { + const res = yield* getFieldishGeneral(typeName, traits, constants, fields, scopeRef); + + const order: string[] = []; + const map: Map>>> = new Map(); + for (const name of res.order) { + const field = res.map.get(name); + if (!field) { + return throwInternal("getFieldishTrait lost fields"); + } + if (field.decl.init) { + // have to recreate DeclMem, because TS doesn't + // narrow here + map.set(name, Ast.DeclMem( + { ...field.decl, init: field.decl.init }, + field.via, + )); + } else { + // field/constant doesn't have initializer + yield EAbstract("field", name, field.via); + } + } + + return { order, map }; +} + +const EAbstract = ( + kind: string, + name: string, + next: Ast.ViaMember, +): E.TcError => ({ + loc: next.defLoc, + descr: [ + E.TEText(`Contract ${kind} "${name}" must have an initializer`), + E.TEViaMember(next), + ], +}); diff --git a/src/next/types/errors.ts b/src/next/types/errors.ts index 1b7d551531..f4e3f85073 100644 --- a/src/next/types/errors.ts +++ b/src/next/types/errors.ts @@ -1,5 +1,5 @@ import { throwInternal } from "@/error/errors"; -import type { Loc, Via, ViaUser } from "@/next/ast"; +import type { Loc, Via, ViaMember, ViaUser } from "@/next/ast"; import type * as V from "@/next/ast/via"; export type WithLog = Generator @@ -51,14 +51,6 @@ export function* toMap( return result; } -export const ERedefine = (kind: string, name: string, prev: Via, next: ViaUser): TcError => ({ - loc: viaToRange(next), - descr: [ - TEText(`There already is a ${kind} "${name}" from`), - TEVia(prev), - ], -}); - export type TcError = { // location where IDE should show this error readonly loc: Loc; @@ -66,7 +58,7 @@ export type TcError = { readonly descr: readonly TELine[]; } -export type TELine = TEText | TEVia | TECode; +export type TELine = TEText | TEVia | TEViaMember | TECode; export type TEText = { readonly kind: 'text'; @@ -82,6 +74,13 @@ export type TEVia = { export const TEVia = (via: V.Via): TEVia => ({ kind: 'via', via }); +export type TEViaMember = { + readonly kind: 'via-member'; + readonly via: V.ViaMember; +} + +export const TEViaMember = (via: V.ViaMember): TEViaMember => ({ kind: 'via-member', via }); + export type TECode = { readonly kind: 'code'; readonly loc: Loc; @@ -100,3 +99,26 @@ export const viaToRange = ({ imports, defLoc: definedAt }: V.ViaUser): Loc => { } return throwInternal("Implicit import shadows something. Duplicates in stdlib?"); }; + +export const ERedefine = (kind: string, name: string, prev: Via, next: ViaUser): TcError => ({ + loc: viaToRange(next), + descr: [ + TEText(`There already is a ${kind} "${name}" from`), + TEVia(prev), + ], +}); + +export const ERedefineMember = ( + name: string, + prev: ViaMember, + next: ViaMember, +): TcError => ({ + loc: next.defLoc, + descr: [ + TEText(`"${name}" is inherited twice`), + TEText(`First defined at`), + TEViaMember(prev), + TEText(`Redefined at`), + TEViaMember(next), + ], +}); \ No newline at end of file diff --git a/src/next/types/expr-eval.ts b/src/next/types/expr-eval.ts new file mode 100644 index 0000000000..7b90a7f09a --- /dev/null +++ b/src/next/types/expr-eval.ts @@ -0,0 +1,11 @@ +/* eslint-disable require-yield */ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import * as Ast from "@/next/ast"; +import type * as E from "@/next/types/errors"; + +export function* evalExpr( + expr: Ast.DecodedExpression, + scopeRef: () => Ast.Scope, +): E.WithLog { + return Ast.VNumber(0n); +} diff --git a/src/next/types/expression.ts b/src/next/types/expression.ts index d168f55cda..81750a0ee8 100644 --- a/src/next/types/expression.ts +++ b/src/next/types/expression.ts @@ -2,11 +2,11 @@ import * as Ast from "@/next/ast"; import * as E from "@/next/types/errors"; import type { TactImport, TactSource } from "@/next/imports/source"; import { builtinFunctions } from "@/next/types/builtins"; -import { decodeFnType } from "@/next/types/util"; +import { decodeFnType } from "@/next/types/type-fn"; -export function* checkExpr( +export function* decodeExpr( node: Ast.Expression, - -) { + scopeRef: () => Ast.Scope, +): Ast.Lazy { } \ No newline at end of file diff --git a/src/next/types/extensions.ts b/src/next/types/extensions.ts index ee5f6c905d..14e2a7b70c 100644 --- a/src/next/types/extensions.ts +++ b/src/next/types/extensions.ts @@ -1,73 +1,131 @@ import * as Ast from "@/next/ast"; import * as E from "@/next/types/errors"; -import { dealiasType } from "@/next/types/aliases"; -import { decodeFnType } from "@/next/types/util"; -import { builtinMethods } from "@/next/types/builtins"; -import { throwInternal } from "@/error/errors"; -import type { TactImport, TactSource } from "@/next/imports/source"; import { zip } from "@/utils/array"; +import { throwInternal } from "@/error/errors"; +import { decodeFnType } from "@/next/types/type-fn"; +import { dealiasTypeLazy } from "@/next/types/type"; +import { decodeBody } from "@/next/types/body"; +import { builtinMethods } from "@/next/types/builtins"; +import type { TactSource } from "@/next/imports/source"; -export function* getAllExtensions( +export function decodeExtensions( imported: readonly Ast.SourceCheckResult[], source: TactSource, - sigs: ReadonlyMap, - aliases: Map, -): E.WithLog> { - const importedExts = imported.flatMap(({ globals, importedBy }) => ( - [...globals.extSigs] - .map(([name, exts]) => [name, exts.map(ext => toSigDecoded(ext, importedBy))] as const) - )); - const localExts = yield* E.mapLog(source.items.extensions, function* (ext) { - const { selfType, mutates, fun } = ext; - const { name, type, body, inline, loc } = fun; - const via = Ast.ViaOrigin(loc, source); - const decodedFn = yield* decodeFnType(type, via, sigs, aliases); - const self = yield* toSelfType(sigs, yield* dealiasType( - sigs, - aliases, - decodedFn.typeParams, - selfType, - )); - if (!self) { - return []; + scopeRef: () => Ast.Scope, +): ReadonlyMap[]>> { + const allExts: Map[]>[]> = new Map(); + + // imported + for (const { globals, importedBy } of imported) { + for (const [name, lazyExts] of globals.extensions) { + const map = allExts.get(name) ?? []; + allExts.set(name, map); + map.push(function* () { + const exts = yield* lazyExts(); + return exts.map(ext => Ast.Decl( + ext.decl, + Ast.ViaImport(importedBy, ext.via), + )); + }); } - const methodType = Ast.DecodedMethodType( - decodedFn.typeParams, - self, - decodedFn.params, - decodedFn.returnType, - ); - return [[name.text, [Ast.ExtSig(methodType, via)]] as const]; - }); + } - const result: Map = new Map(); - for (const [name, exts] of [...importedExts, ...localExts.flat()]) { - const prev = result.get(name) ?? []; - result.set(name, prev); - for (const ext of exts) { - const builtin = builtinMethods.get(name); - if (builtin && !isCompatible(builtin, ext.type)) { - yield EMethodOverlap(name, Ast.ViaBuiltin(), ext.via); - continue; + // local + for (const ext of source.items.extensions) { + const name = ext.fun.name.text; + const map = allExts.get(name) ?? []; + allExts.set(name, map); + map.push(function* () { + const decoded = yield* decodeExt(ext, scopeRef); + if (!decoded) { + return []; } - const prevs = result.get(name) ?? []; - if (yield* areCompatible(name, prevs, ext)) { - prev.push(ext); + return [Ast.Decl( + decoded, + Ast.ViaOrigin(ext.fun.loc, source), + )]; + }); + } + + const result: Map[]>> = new Map(); + for (const [name, exts] of allExts) { + // checking method overlap is only possible when all the types + // can be resolved + result.set(name, Ast.Lazy(function* () { + // force all thunks + const all: Ast.Decl[] = []; + for (const lazyExt of exts) { + const exts = yield* lazyExt(); + all.push(...exts); } - } + + // check overlap and deduplicate + const prevs: Ast.Decl[] = []; + for (const ext of all) { + const builtin = builtinMethods.get(name); + if (builtin && !isCompatible(builtin, ext.decl.type)) { + yield EMethodOverlap(name, Ast.ViaBuiltin(), ext.via); + continue; + } + if (yield* areCompatible(name, prevs, ext)) { + prevs.push(ext); + } + } + return prevs; + })); } return result; } +function* decodeExt( + node: Ast.Extension, + scopeRef: () => Ast.Scope, +) { + const { selfType, mutates, fun } = node; + const { type, body, inline, loc } = fun; + + const decodedFn = yield* decodeFnType(type, scopeRef); + + const lazySelf = dealiasTypeLazy( + decodedFn.typeParams, + selfType, + scopeRef, + ); + const self = yield* toSelfType(yield* lazySelf(), scopeRef); + + if (!self) { + return undefined; + } + + const methodType = Ast.DecodedMethodType( + mutates, + decodedFn.typeParams, + self, + decodedFn.params, + decodedFn.returnType, + ); + + const decodedBody = yield* decodeBody( + body, + methodType, + loc, + scopeRef, + ); + + return Ast.ExtSig(methodType, inline, decodedBody); +} + function* areCompatible( name: string, - prevs: readonly Ast.ExtSig[], - next: Ast.ExtSig, + prevs: readonly Ast.Decl[], + next: Ast.Decl, ): E.WithLog { for (const prev of prevs) { + const prevType = prev.decl.type; + const nextType = next.decl.type; // NB! checking by reference, see `toSigDecoded` - if (prev.type !== next.type && !isCompatible(prev.type, next.type)) { + if (prevType !== nextType && !isCompatible(prevType, nextType)) { yield EMethodOverlap(name, prev.via, next.via); return false; } @@ -90,11 +148,13 @@ const EMethodOverlap = ( function isCompatible( prev: Ast.DecodedMethodType, next: Ast.DecodedMethodType, -): boolean { - return prev.self.kind !== next.self.kind || - prev.self.ground === 'yes' && - next.self.ground === 'yes' && - !areEqual(prev.self, next.self); +) { + const prevSelf = prev.self; + const nextSelf = next.self; + return prevSelf.kind !== nextSelf.kind || + prevSelf.ground === 'yes' && + nextSelf.ground === 'yes' && + !areEqual(prevSelf, nextSelf); } function areEqual( @@ -146,41 +206,31 @@ function allEqual( return zip(prevs, nexts).every(([prev, next]) => areEqual(prev, next)); } -const toSigDecoded = ( - prev: Ast.ExtSig, - importedBy: TactImport, -): Ast.ExtSig => { - const via = Ast.ViaImport(importedBy, prev.via); - // NB! it's important to NOT change the reference to prev.type - // as we're deduplicating same extension by reference - return Ast.ExtSig(prev.type, via); -}; - function* toSelfType( - sigs: ReadonlyMap, type: Ast.DecodedType, + scopeRef: () => Ast.Scope, ): E.WithLog { switch (type.kind) { case "recover": { return undefined; } case "type_ref": { - const def = sigs.get(type.name.text); + const def = scopeRef().typeDecls.get(type.name.text); if (!def) { return throwInternal("Decoder returned broken reference") } - switch (def.use) { + switch (def.decl.kind) { case "alias": { return throwInternal("Decoder returned broken reference") } - case "contract": { + case "contract": + case "trait": { yield ENoMethods("contract", type.loc); return undefined; } - case "forbidden": { - return undefined; - } - case "usual": { + case "struct": + case "message": + case "union": { const allVars = type.typeArgs.filter(arg => { return arg.kind === 'TypeParam'; }); @@ -204,7 +254,7 @@ function* toSelfType( } const ground: Ast.MethodGroundType[] = []; for (const arg of type.typeArgs) { - const result = yield* toGroundType(sigs, arg); + const result = yield* toGroundType(arg, scopeRef); if (!result) { yield EBadMethodType(type.loc); return undefined; @@ -236,7 +286,7 @@ function* toSelfType( type.loc, ); } - const ground = yield* toGroundType(sigs, type); + const ground = yield* toGroundType(type, scopeRef); if (!ground) { yield EBadMethodType(type.loc); return undefined; @@ -254,7 +304,7 @@ function* toSelfType( type.loc, ); } - const ground = yield* toGroundType(sigs, type); + const ground = yield* toGroundType(type, scopeRef); if (!ground) { yield EBadMethodType(type.loc); return undefined; @@ -281,7 +331,7 @@ function* toSelfType( type.loc, ); } - const ground = yield* toGroundType(sigs, type); + const ground = yield* toGroundType(type, scopeRef); if (!ground) { yield EBadMethodType(type.loc); return undefined; @@ -308,33 +358,33 @@ function* toSelfType( } function* toGroundType( - sigs: ReadonlyMap, - type: Ast.DecodedType + type: Ast.DecodedType, + scopeRef: () => Ast.Scope, ): E.WithLog { switch (type.kind) { case "recover": { return undefined; } case "type_ref": { - const typeDecl = sigs.get(type.name.text); + const typeDecl = scopeRef().typeDecls.get(type.name.text); if (!typeDecl) { return throwInternal("Decoder returned broken reference") } - switch (typeDecl.use) { - case "contract": { + switch (typeDecl.decl.kind) { + case "contract": + case "trait": { yield ENoMethods("contract", type.loc); return undefined; } case "alias": { return throwInternal("Decoder returned broken reference") } - case "forbidden": { - return undefined; - } - case "usual": { + case "struct": + case "message": + case "union": { const ground: Ast.MethodGroundType[] = []; for (const arg of type.typeArgs) { - const result = yield* toGroundType(sigs, arg); + const result = yield* toGroundType(arg, scopeRef); if (!result) { return undefined; } @@ -357,27 +407,27 @@ function* toGroundType( return undefined; } case "map_type": { - const key = yield* toGroundType(sigs, type.key); - const value = yield* toGroundType(sigs, type.value); + const key = yield* toGroundType(type.key, scopeRef); + const value = yield* toGroundType(type.value, scopeRef); return key && value && Ast.MGTypeMap(key, value, type.loc); } case "TypeBounced": { return undefined; } case "TypeMaybe": { - const child = yield* toGroundType(sigs, type.type); + const child = yield* toGroundType(type.type, scopeRef); return child && Ast.MGTypeMaybe(child, type.loc); } case "tuple_type": { const children = yield* E.mapLog(type.typeArgs, function* (child) { - const result = yield* toGroundType(sigs, child); + const result = yield* toGroundType(child, scopeRef); return result ? [result] : []; }); return Ast.MGTypeTuple(children.flat(), type.loc); } case "tensor_type": { const children = yield* E.mapLog(type.typeArgs, function* (child) { - const result = yield* toGroundType(sigs, child); + const result = yield* toGroundType(child, scopeRef); return result ? [result] : []; }); return Ast.MGTypeTensor(children.flat(), type.loc); diff --git a/src/next/types/fields.ts b/src/next/types/fields.ts new file mode 100644 index 0000000000..1c52d6b63a --- /dev/null +++ b/src/next/types/fields.ts @@ -0,0 +1,192 @@ +/* eslint-disable require-yield */ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import * as Ast from "@/next/ast"; +import * as E from "@/next/types/errors"; +import { throwInternal } from "@/error/errors"; +import { decodeTypeLazy } from "@/next/types/type"; +import { decodeExpr } from "@/next/types/expression"; +import { checkFieldOverride } from "@/next/types/override"; +import { decodeConstantDef } from "@/next/types/constant-def"; + +type MaybeExpr = Ast.Lazy | undefined + +export function* getFieldishGeneral( + typeName: string, + traits: readonly Ast.Decl[], + constants: readonly Ast.FieldConstant[], + fields: readonly Ast.FieldDecl[], + scopeRef: () => Ast.Scope, +): E.WithLog>>> { + // collect all inherited fields and constants + const inherited: Map>> = new Map(); + for (const { via, decl: { fieldish } } of traits) { + for (const name of fieldish.order) { + const field = fieldish.map.get(name); + if (!field) { + return throwInternal("Field was lost"); + } + const nextVia = Ast.ViaMemberTrait( + name, + via.defLoc, + field.via, + ); + const prev = inherited.get(name); + if (prev) { + yield E.ERedefineMember(name, prev.via, nextVia); + } else { + inherited.set(name, Ast.DeclMem(field.decl, nextVia)); + } + } + } + + // in which order fields were defined + const order: string[] = []; + + // collection of all defined fields and constants + const all: Map>> = new Map(); + + // whether inherited field/constant was defined locally + const overridden: Set = new Set(); + + for (const field of fields) { + const name = field.name; + const nextVia = Ast.ViaMemberOrigin(typeName, field.loc); + + const prev = all.get(name.text); + if (prev) { + // duplicate local field + yield E.ERedefineMember(name.text, prev.via, nextVia); + } + + // remember order of fields + order.push(name.text); + + // decode field + all.set(name.text, decodeField(typeName, field, scopeRef)); + + // check if this field was inherited + const prevInh = inherited.get(name.text); + if (prevInh) { + // remember that this inherited field was handled + overridden.add(name.text); + + if (prevInh.decl.kind !== 'field') { + // cannot override constant with field + yield E.ERedefineMember(name.text, prevInh.via, nextVia); + } + } + } + + for (const field of constants) { + const { override, overridable, body } = field; + const { init, name, loc } = body; + const nextVia = Ast.ViaMemberOrigin(typeName, loc); + + const prev = all.get(name.text); + if (prev) { + // duplicate local constant + yield E.ERedefineMember(name.text, prev.via, nextVia); + } + + // we mostly need this for technical reasons: + // fields and constants occupy the same namespace + order.push(name.text); + + // remember that this inherited constant was handled. + // we always override previous constants for type + // recovery reasons, so no other conditions are given + const prevInh = inherited.get(name.text); + if (prevInh) { + overridden.add(name.text); + } + + // get the definition + const next = yield* decodeConstant(init, overridable, nextVia, scopeRef); + + // check that override/abstract/virtual modifiers are correct + yield* checkFieldOverride( + name.text, + prevInh, + next.decl.type, + nextVia, + override, + scopeRef, + ); + + // we're all set to store this constant + all.set(name.text, next); + } + + // add fields/constants that were NOT overridden + for (const [name, field] of inherited) { + if (overridden.has(name)) { + continue; + } + if (field.decl.kind === 'field') { + // fields must always be redefined + yield EMustCopyField(name, field.via); + } else { + // constants are inherited as is + } + all.set(name, field); + } + + return { + order, + map: all, + }; +} + +function decodeField( + typeName: string, + field: Ast.FieldDecl, + scopeRef: () => Ast.Scope, +) { + const { initializer, name, type, loc } = field; + const nextVia = Ast.ViaMemberOrigin(typeName, loc); + + // contracts don't have type parameters + const typeParams = Ast.TypeParams([], new Set()); + + // decode field + return Ast.DeclMem( + Ast.InhFieldSig( + decodeTypeLazy(typeParams, type, scopeRef), + initializer && decodeExpr(initializer, scopeRef), + ), + nextVia, + ); +} + +const EMustCopyField = ( + name: string, + prev: Ast.ViaMember, +): E.TcError => ({ + loc: prev.defLoc, + descr: [ + E.TEText(`Field "${name}" was defined in parent trait, but never mentioned`), + E.TEViaMember(prev), + ], +}); + +function* decodeConstant( + init: Ast.ConstantInit, + overridable: boolean, + nextVia: Ast.ViaMember, + scopeRef: () => Ast.Scope, +): E.WithLog>> { + const typeParams = Ast.TypeParams([], new Set()); + if (init.kind === 'constant_decl') { + const type = decodeTypeLazy(typeParams, init.type, scopeRef); + return Ast.DeclMem( + Ast.FieldConstSig(overridable, type, undefined), + nextVia, + ); + } else { + const [type, expr] = decodeConstantDef(typeParams, init, scopeRef); + return Ast.DeclMem( + Ast.FieldConstSig(overridable, type, expr), + nextVia, + ); + } +} diff --git a/src/next/types/functions.ts b/src/next/types/functions.ts index 3b32d0de27..2edbada957 100644 --- a/src/next/types/functions.ts +++ b/src/next/types/functions.ts @@ -1,34 +1,42 @@ +/* eslint-disable require-yield */ +/* eslint-disable @typescript-eslint/no-unused-vars */ import * as Ast from "@/next/ast"; import * as E from "@/next/types/errors"; -import type { TactImport, TactSource } from "@/next/imports/source"; +import type { TactSource } from "@/next/imports/source"; import { builtinFunctions } from "@/next/types/builtins"; -import { decodeFnType } from "@/next/types/util"; +import { decodeFnType } from "@/next/types/type-fn"; +import { decodeBody } from "@/next/types/body"; const errorKind = "function"; -export function* getAllFunctions( +export function* decodeFunctions( imported: readonly Ast.SourceCheckResult[], source: TactSource, - sigs: ReadonlyMap, - aliases: Map, -): E.WithLog> { + scopeRef: () => Ast.Scope, +): E.WithLog>> { const allFnSigs = [ // imported ...imported.flatMap(({ globals, importedBy }) => ( - [...globals.fnSigs] - .map(([name, s]) => [name, toSigDecoded(s, importedBy)] as const) + [...globals.functions] + .map(([name, fn]) => [ + name, + Ast.Decl(fn.decl, Ast.ViaImport(importedBy, fn.via)), + ] as const) )), // local ...yield* E.mapLog(source.items.functions, function* (fn) { - const { name, type, inline, body, loc } = fn; - const via = Ast.ViaOrigin(loc, source); - const fnType = yield* decodeFnType(type, via, sigs, aliases); - return [name.text, Ast.FnSig(fnType, via)] as const; + return [ + fn.name.text, + Ast.Decl( + yield* decodeFunction(fn, scopeRef), + Ast.ViaOrigin(fn.loc, source) + ) + ] as const; }), ]; // remove duplicates and builtins - const filteredSigs: Map = new Map(); + const filteredSigs: Map> = new Map(); for (const [name, sig] of allFnSigs) { const isBuiltin = builtinFunctions.has(name); if (isBuiltin) { @@ -47,7 +55,15 @@ export function* getAllFunctions( return filteredSigs; } -const toSigDecoded = (fn: Ast.FnSig, importedBy: TactImport): Ast.FnSig => { - const via = Ast.ViaImport(importedBy, fn.via); - return Ast.FnSig(fn.type, via); -}; +function* decodeFunction( + fn: Ast.Function, + scopeRef: () => Ast.Scope, +) { + const { type, inline, body, loc } = fn; + const fnType = yield* decodeFnType(type, scopeRef); + return Ast.FnSig( + fnType, + inline, + yield* decodeBody(body, fnType, loc, scopeRef), + ); +} diff --git a/src/next/types/methods.ts b/src/next/types/methods.ts new file mode 100644 index 0000000000..97e81180d2 --- /dev/null +++ b/src/next/types/methods.ts @@ -0,0 +1,207 @@ +/* eslint-disable require-yield */ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import * as Ast from "@/next/ast"; +import * as E from "@/next/types/errors"; +import { decodeBody } from "@/next/types/body"; +import { decodeFnType } from "@/next/types/type-fn"; +import { checkMethodOverride } from "@/next/types/override"; +import { decodeExpr } from "@/next/types/expression"; +import { crc16 } from "@/utils/crc16"; +import { tactMethodIds } from "@/next/types/builtins"; +import { evalExpr } from "@/next/types/expr-eval"; + +export function* getMethodsGeneral( + typeName: Ast.TypeId, + traits: readonly Ast.Decl[], + methods: readonly Ast.Method[], + scopeRef: () => Ast.Scope, +): E.WithLog>>> { + // collect all inherited methods + const inherited: Map>> = new Map(); + for (const { via, decl: { methods } } of traits) { + for (const [name, method] of methods) { + const nextVia = Ast.ViaMemberTrait( + name, + via.defLoc, + method.via, + ); + const prev = inherited.get(name); + if (prev) { + yield E.ERedefineMember(name, prev.via, nextVia); + } else { + inherited.set(name, Ast.DeclMem( + method.decl, + nextVia, + )); + } + } + } + + // collection of all defined methods + const all: Map>> = new Map(); + + // whether inherited field/constant was defined locally + const overridden: Set = new Set(); + + for (const method of methods) { + const { override, overridable, mutates, fun, get } = method; + const { name, inline, type, body, loc } = fun; + const nextVia = Ast.ViaMemberOrigin(typeName.text, loc); + + const decodedFn = yield* decodeFnType(type, scopeRef); + const selfType = Ast.MVTypeRef(typeName, [], loc); + const methodType = Ast.DecodedMethodType( + mutates, + decodedFn.typeParams, + selfType, + decodedFn.params, + decodedFn.returnType, + ); + const decodedBody = body.kind !== 'abstract_body' + ? yield* decodeBody( + body, + methodType, + loc, + scopeRef, + ) + : undefined; + const getMethodId = decodeGetLazy( + name, + get, + scopeRef, + ); + + // check for abstract + + const prevInh = inherited.get(name.text); + if (prevInh) { + overridden.add(name.text); + } + + // check that override/abstract/virtual modifiers are correct + yield* checkMethodOverride( + name.text, + prevInh, + methodType, + nextVia, + override, + scopeRef, + ); + + const methodSig = Ast.MethodSig( + overridable, + methodType, + inline, + decodedBody, + getMethodId, + ); + + all.set(name.text, Ast.DeclMem(methodSig, nextVia)); + } + + // add methods that were NOT overridden + for (const [name, field] of inherited) { + if (overridden.has(name)) { + continue; + } + all.set(name, field); + } + + return all; +} + +function decodeGetLazy( + fnName: Ast.Id, + get: Ast.GetAttribute | undefined, + scopeRef: () => Ast.Scope, +): undefined | Ast.Lazy { + if (!get) { + return undefined; + } + return Ast.Lazy(() => decodeGet(fnName, get, scopeRef)); +} + +function* decodeGet( + fnName: Ast.Id, + get: Ast.GetAttribute, + scopeRef: () => Ast.Scope, +): E.WithLog { + if (get.methodId) { + // decode expression + const exprLazy = decodeExpr(get.methodId, scopeRef); + + // force computation + const expr = yield* exprLazy(); + + // check type of expression + const type = yield* expr.computedType(); + + if (type.kind === 'TyInt') { + // evaluate expression + const methodId = yield* evalExpr(expr, scopeRef); + + if ( + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + methodId.kind === 'number' && + (yield* checkMethodId(methodId.value, expr.loc)) + ) { + return methodId.value; + } + + // if evaluation failed, fallthrough to computing it + } else { + // TODO: yield EMismatch(); + } + } + + // compute method id out of function name + const methodId = BigInt((crc16(fnName.text) & 0xffff) | 0x10000); + + // just in case + yield* checkMethodId(methodId, fnName.loc); + + return methodId; +} + +function* checkMethodId(methodId: bigint, loc: Ast.Loc) { + if (methodId < -(2n ** 18n) || methodId >= 2n ** 18n) { + // method ids are 19-bit signed integers + yield EBadId(loc); + return false; + } else if (-4n <= methodId && methodId < 2n ** 14n) { + // method ids -4, -3, -2, -1, 0 ... 2^14 - 1 (inclusive) are kind of reserved by TVM + // for the upper bound see F12_n (CALL) TVM instruction + // and many small ids will be taken by internal procedures + // + // also, some ids are taken by the getters generated by Tact: + // supported_interfaces -> 113617 + // lazy_deployment_completed -> 115390 + // get_abi_ipfs -> 121275 + yield EReservedTvmId(loc); + return false; + } else if (tactMethodIds.includes(methodId)) { + yield EReservedTactId(loc, tactMethodIds); + return false; + } else { + return true; + } +} + +const EBadId = (loc: Ast.Loc): E.TcError => ({ + loc, + descr: [ + E.TEText(`Method ids must fit 19-bit signed integer range`), + ], +}); +const EReservedTvmId = (loc: Ast.Loc): E.TcError => ({ + loc, + descr: [ + E.TEText(`Method ids cannot overlap with the TVM reserved ids: -4, -3, -2, -1, 0 ... 2^14 - 1`), + ], +}); +const EReservedTactId = (loc: Ast.Loc, tactMethodIds: readonly bigint[]): E.TcError => ({ + loc, + descr: [ + E.TEText(`Method ids cannot overlap with Tact reserved method ids: ${tactMethodIds.map((n) => n.toString()).join(", ")}`), + ], +}); \ No newline at end of file diff --git a/src/next/types/name.ts b/src/next/types/name.ts new file mode 100644 index 0000000000..bb7c1e7a24 --- /dev/null +++ b/src/next/types/name.ts @@ -0,0 +1,11 @@ +import { throwInternal } from "@/error/errors"; + +export const recoverName = (name: string, set: ReadonlySet) => { + for (let i = 0; i < 100; ++i) { + const nextName = `${name}${i}`; + if (!set.has(nextName)) { + return nextName; + } + } + return throwInternal("Iteration limit reached"); +}; diff --git a/src/next/types/override.ts b/src/next/types/override.ts new file mode 100644 index 0000000000..a7c6aefe4e --- /dev/null +++ b/src/next/types/override.ts @@ -0,0 +1,118 @@ +/* eslint-disable require-yield */ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import type * as Ast from "@/next/ast"; +import * as E from "@/next/types/errors"; +import { assignType } from "@/next/types/type"; +import { assignMethodType } from "@/next/types/type-method"; + +export function* checkFieldOverride( + name: string, + prev: Ast.DeclMem | undefined + >> | undefined, + nextType: Ast.Lazy, + nextVia: Ast.ViaMember, + override: boolean, + scopeRef: () => Ast.Scope, +): E.WithLog { + if (prev) { + if (prev.decl.kind !== 'constant') { + // cannot override field with constant + yield E.ERedefineMember(name, prev.via, nextVia); + } else if (override) { + // overriding without override + yield ENeedOverride(name, prev.via, nextVia); + } else if (!prev.decl.overridable) { + // to override it must be virtual or abstract + yield ENeedAbstract(name, prev.via, nextVia); + } else { + // overriding constant + yield* assignType( + yield* prev.decl.type(), + yield* nextType(), + scopeRef, + ); + } + } else { + if (override) { + // override of nothing + yield EEmptyOverride(name, nextVia); + } else { + // defining new constant + } + } +} + +export function* checkMethodOverride( + name: string, + prev: Ast.DeclMem> | undefined, + nextType: Ast.DecodedMethodType, + nextVia: Ast.ViaMember, + override: boolean, + scopeRef: () => Ast.Scope, +): E.WithLog { + if (prev) { + if (override) { + // overriding without override + yield ENeedOverride(name, prev.via, nextVia); + } else if (!prev.decl.overridable) { + // to override it must be virtual or abstract + yield ENeedAbstract(name, prev.via, nextVia); + } else { + // overriding method + yield* assignMethodType( + prev.decl.type, + nextType, + scopeRef, + ); + } + } else { + if (override) { + // override of nothing + yield EEmptyOverride(name, nextVia); + } else { + // defining new method + } + } +} + +const ENeedOverride = ( + name: string, + prev: Ast.ViaMember, + next: Ast.ViaMember, +): E.TcError => ({ + loc: next.defLoc, + descr: [ + E.TEText(`Overriding "${name}" without "override"`), + E.TEText(`First defined at`), + E.TEViaMember(prev), + E.TEText(`Redefined at`), + E.TEViaMember(next), + ], +}); + +const ENeedAbstract = ( + name: string, + prev: Ast.ViaMember, + next: Ast.ViaMember, +): E.TcError => ({ + loc: next.defLoc, + descr: [ + E.TEText(`To override "${name}" it has to be "virtual" or "abstract"`), + E.TEText(`First defined at`), + E.TEViaMember(prev), + E.TEText(`Redefined at`), + E.TEViaMember(next), + ], +}); + +const EEmptyOverride = ( + name: string, + next: Ast.ViaMember, +): E.TcError => ({ + loc: next.defLoc, + descr: [ + E.TEText(`To override "${name}" it has to exist`), + E.TEViaMember(next), + ], +}); \ No newline at end of file diff --git a/src/next/types/reg.ts b/src/next/types/reg.ts deleted file mode 100644 index 04c91b1de7..0000000000 --- a/src/next/types/reg.ts +++ /dev/null @@ -1,30 +0,0 @@ -import * as E from "@/next/types/errors"; -import * as Ast from "@/next/ast"; - -export function* concatReg( - builtins: Map, - kind: string, - all: ReadonlyMap[] -): E.WithLog> { - const prev: Map = new Map(); - for (const next of all) { - for (const [name, nextItem] of next) { - const prevItem = prev.get(name); - // defined in compiler - if (builtins.has(name)) { - yield E.ERedefine(kind, name, Ast.ViaBuiltin(), nextItem.via); - continue; - } - // not defined yet; define it now - if (typeof prevItem === 'undefined') { - prev.set(name, nextItem); - continue; - } - // already defined, and it's not a diamond situation - if (prevItem.via.source !== nextItem.via.source) { - yield E.ERedefine(kind, name, prevItem.via, nextItem.via); - } - } - } - return prev; -} \ No newline at end of file diff --git a/src/next/types/statements.ts b/src/next/types/statements.ts new file mode 100644 index 0000000000..a38351923b --- /dev/null +++ b/src/next/types/statements.ts @@ -0,0 +1,10 @@ +import type * as Ast from "@/next/ast"; +import type * as E from "@/next/types/errors"; +import type { TactSource } from "@/next/imports/source"; + +export function decodeStatements( + statements: readonly Ast.Statement[], + scopeRef: () => Ast.Scope, +): readonly Ast.DecodedStatement[] { + return []; +} \ No newline at end of file diff --git a/src/next/types/traits-scope.ts b/src/next/types/traits-scope.ts new file mode 100644 index 0000000000..c17b753e31 --- /dev/null +++ b/src/next/types/traits-scope.ts @@ -0,0 +1,51 @@ +/* eslint-disable require-yield */ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import * as Ast from "@/next/ast"; +import * as E from "@/next/types/errors"; + +type MaybeExpr = Ast.Lazy | undefined + +export function* getInheritedTraits( + traits: readonly Ast.TypeId[], + scopeRef: () => Ast.Scope, +): E.WithLog>[]> { + const decls = scopeRef().typeDecls; + const prevTraits: Ast.Decl>[] = []; + for (const trait of traits) { + const name = trait.text; + const decl = decls.get(trait.text); + if (!decl) { + yield EUndefinedTrait(trait.text, trait.loc); + continue; + } + const { via, decl: traitDecl } = decl; + if (traitDecl.kind !== 'trait') { + yield EOnlyTraits(trait.loc); + continue; + } + prevTraits.push(Ast.Decl( + yield* traitDecl.content(), + via, + )); + } + return prevTraits; +} + +const EUndefinedTrait = ( + name: string, + loc: Ast.Loc, +): E.TcError => ({ + loc, + descr: [ + E.TEText(`Traits "${name}" is not defined`), + ], +}); + +const EOnlyTraits = ( + loc: Ast.Loc, +): E.TcError => ({ + loc, + descr: [ + E.TEText(`Can only inherit traits`), + ], +}); diff --git a/src/next/types/traits.ts b/src/next/types/traits.ts deleted file mode 100644 index 36486ee363..0000000000 --- a/src/next/types/traits.ts +++ /dev/null @@ -1,36 +0,0 @@ -import * as Ast from "@/next/ast"; -import * as E from "@/next/types/errors"; -import type { TactImport, TactSource } from "@/next/imports/source"; -import { decodeFnType } from "@/next/types/util"; - -export function* getTraitSigs( - imported: readonly Ast.SourceCheckResult[], - source: TactSource, - sigs: ReadonlyMap, - aliases: Map, -) { - const allTraitsSigs = [ - // imported - ...imported.flatMap(({ globals, importedBy }) => ( - [...globals.typeDecls] - .flatMap(([name, s]) => { - if (s.kind !== 'trait') { - return []; - } - return [[name, toSigDecoded(s, importedBy)] as const]; - }) - )), - // local - ...yield* E.mapLog(source.items.functions, function* (fn) { - const { name, type, inline, body, loc } = fn; - const via = Ast.ViaOrigin(loc, source); - const fnType = yield* decodeFnType(type, via, sigs, aliases); - return [name.text, Ast.FnSig(fnType, via)] as const; - }), - ]; -} - -const toSigDecoded = (fn: Ast.TraitSig, importedBy: TactImport): Ast.FnSig => { - const via = Ast.ViaImport(importedBy, fn.via); - return Ast.FnSig(fn.type, via); -}; diff --git a/src/next/types/util.ts b/src/next/types/type-fn.ts similarity index 66% rename from src/next/types/util.ts rename to src/next/types/type-fn.ts index e5795c2303..4890528fff 100644 --- a/src/next/types/util.ts +++ b/src/next/types/type-fn.ts @@ -1,38 +1,26 @@ import * as Ast from "@/next/ast"; import * as E from "@/next/types/errors"; -import { dealiasType } from "@/next/types/aliases"; import { decodeTypeParams } from "@/next/types/type-params"; -import { throwInternal } from "@/error/errors"; - -export const recoverName = (name: string, set: ReadonlySet) => { - for (let i = 0; i < 100; ++i) { - const nextName = `${name}${i}`; - if (!set.has(nextName)) { - return nextName; - } - } - return throwInternal("Iteration limit reached"); -}; +import { dealiasTypeLazy } from "@/next/types/type"; +import { recoverName } from "@/next/types/name"; export function* decodeFnType( { typeParams, params, returnType }: Ast.FnType, - via: Ast.ViaUser, - sigs: ReadonlyMap, - aliases: ReadonlyMap, + scopeRef: () => Ast.Scope, ): E.WithLog { const decodedTypeParams = yield* decodeTypeParams(typeParams); const dealias = (type: Ast.Type) => { - return dealiasType(sigs, aliases, decodedTypeParams, type); + return dealiasTypeLazy(decodedTypeParams, type, scopeRef); }; return Ast.DecodedFnType( decodedTypeParams, yield* decodeParams(dealias, params), - yield* dealias(returnType ?? Ast.TypeVoid(via.defLoc)), + dealias(returnType), ); } function* decodeParams( - dealias: (type: Ast.Type) => E.WithLog, + dealias: (type: Ast.Type) => Ast.Lazy, params: readonly Ast.TypedParameter[], ): E.WithLog { const order: Ast.Parameter[] = []; @@ -41,7 +29,7 @@ function* decodeParams( const name = yield* decodeParamName(param.name, set); order.push(Ast.Parameter( param.name, - yield* dealias(param.type), + dealias(param.type), param.loc, )); if (typeof name !== 'undefined') { @@ -71,4 +59,4 @@ const EDuplicateParam = (name: string, loc: Ast.Loc): E.TcError => ({ descr: [ E.TEText(`Duplicate parameter "${name}"`), ], -}); \ No newline at end of file +}); diff --git a/src/next/types/type-method.ts b/src/next/types/type-method.ts new file mode 100644 index 0000000000..c73482a9c3 --- /dev/null +++ b/src/next/types/type-method.ts @@ -0,0 +1,10 @@ +import * as Ast from "@/next/ast"; +import * as E from "@/next/types/errors"; + +export function* assignMethodType( + prev: Ast.DecodedMethodType, + next: Ast.DecodedMethodType, + scopeRef: () => Ast.Scope +): E.WithLog { + +} \ No newline at end of file diff --git a/src/next/types/type-params.ts b/src/next/types/type-params.ts index bc83382dab..5498590a41 100644 --- a/src/next/types/type-params.ts +++ b/src/next/types/type-params.ts @@ -1,6 +1,6 @@ import * as Ast from "@/next/ast"; import * as E from "@/next/types/errors"; -import { recoverName } from "@/next/types/util"; +import { recoverName } from "@/next/types/name"; export function* decodeTypeParams(ids: readonly Ast.TypeId[]): E.WithLog { const set: Set = new Set(); diff --git a/src/next/types/type.ts b/src/next/types/type.ts new file mode 100644 index 0000000000..1367fb26d7 --- /dev/null +++ b/src/next/types/type.ts @@ -0,0 +1,365 @@ +/* eslint-disable require-yield */ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import { throwInternal } from "@/error/errors"; +import * as Ast from "@/next/ast"; +import * as E from "@/next/types/errors"; +import { zip } from "@/utils/array"; + +export const decodeTypeLazy = ( + typeParams: Ast.TypeParams, + type: Ast.Type, + scopeRef: () => Ast.Scope, +) => Ast.Lazy(() => decodeType( + typeParams, + type, + scopeRef().typeDecls, +)); + +export const dealiasTypeLazy = ( + typeParams: Ast.TypeParams, + type: Ast.Type, + scopeRef: () => Ast.Scope, +) => Ast.Lazy(function* () { + const decoded = yield* decodeType( + typeParams, + type, + scopeRef().typeDecls, + ); + return yield* dealiasType( + decoded, + scopeRef().typeDecls, + ); +}); + +function decodeType( + typeParams: Ast.TypeParams, + type: Ast.Type, + typeDecls: ReadonlyMap>, +) { + // decode all the types in an array + function* recN( + types: readonly Ast.Type[], + ): E.WithLog { + const results: Ast.DecodedType[] = []; + for (const type of types) { + const result = yield* rec(type); + results.push(result); + } + return results; + } + + // decode a type + function* rec( + type: Ast.Type, + ): E.WithLog { + switch (type.kind) { + case "unit_type": + case "TyInt": + case "TySlice": + case "TyCell": + case "TyBuilder": + case "TypeVoid": + case "TypeNull": + case "TypeBool": + case "TypeAddress": + case "TypeString": + case "TypeStringBuilder": { + return type; + } + case "tuple_type": { + const result = yield* recN(type.typeArgs); + return Ast.DTypeTuple(result, type.loc); + } + case "tensor_type": { + const result = yield* recN(type.typeArgs); + return Ast.DTypeTensor(result, type.loc); + } + case "map_type": { + const key = yield* rec(type.key); + const value = yield* rec(type.value); + return Ast.DTypeMap(key, value, type.loc); + } + case "TypeBounced": { + const child = yield* rec(type.type); + return Ast.DTypeBounced(child, type.loc); + } + case "TypeMaybe": { + const child = yield* rec(type.type); + return Ast.DTypeMaybe(child, type.loc); + } + case "cons_type": { + // this is where the meat of the procedure is + // cons can be either parameter, type reference, + // alias reference, or reference to undefined type + const name = type.name.text; + const arity = type.typeArgs.length; + + const args = yield* recN(type.typeArgs); + + // if it's in a list of type parameters, this + // is a parameter + if (typeParams.set.has(name)) { + // if we used type parameter generically, throw error + // because we do not support HKT + if (!(yield* matchArity(name, arity, 0, type.loc))) { + return Ast.DTypeRecover(); + } + return Ast.DTypeParamRef( + type.name, + type.loc, + ); + } + + const typeEntry = typeDecls.get(name); + + // there is no such type at all! + if (!typeEntry) { + yield ETypeNotFound(name, type.loc); + return Ast.DTypeRecover(); + } + + // check number of type arguments does match + if (!(yield* matchArity( + name, + arity, + getArity(typeEntry.decl), + type.loc, + ))) { + return Ast.DTypeRecover(); + } + + switch (typeEntry.decl.kind) { + case "trait": { + yield ETraitNotType(type.loc); + return Ast.DTypeRecover(); + } + case "contract": { + // this is a ground type reference + return Ast.DTypeRef(type.name, [], type.loc); + } + case "struct": + case "message": + case "union": { + // this is a ground type reference + return Ast.DTypeRef(type.name, args, type.loc); + } + case "alias": { + // this is an alias reference + return Ast.DTypeAliasRef(type.name, args, type.loc); + } + } + } + } + } + + return rec(type); +} + +const getArity = (decl: Ast.TypeDeclSig): number => { + switch (decl.kind) { + case "alias": + case "struct": + case "union": + return decl.typeParams.order.length; + case "contract": + case "trait": + case "message": + return 0; + } +} + +const ETypeNotFound = ( + name: string, + loc: Ast.Loc, +): E.TcError => ({ + loc, + descr: [ + E.TEText(`Type "${name}" is not defined`), + ], +}); + +function* matchArity( + name: string, + got: number, + expected: number, + loc: Ast.Loc, +): E.WithLog { + const result = got === expected; + if (!result) { + yield EArity(name, expected, got, loc); + } + return result; +} + +const EArity = ( + name: string, + expected: number, + got: number, + loc: Ast.Loc, +): E.TcError => ({ + loc, + descr: [ + E.TEText(`Type "${name}" is expected to have ${expected} type arguments, got ${got}`), + ], +}); + +const ETraitNotType = ( + loc: Ast.Loc, +): E.TcError => ({ + loc, + descr: [ + E.TEText(`Traits cannot be used as types`), + ], +}); + +const dealiasType = ( + type: Ast.DecodedType, + typeDecls: ReadonlyMap>, +) => { + function* rec(type: Ast.DecodedType): E.WithLog { + switch (type.kind) { + case "recover": { + return type; + } + case "type_ref": { + const args = yield* E.mapLog(type.typeArgs, rec); + return Ast.DTypeRef(type.name, args, type.loc); + } + case "TypeAlias": { + const alias = typeDecls.get(type.name.text); + if (!alias || alias.decl.kind !== 'alias') { + return throwInternal("Type decoder must not return types with dangling references"); + } + // NB! if we could decode alias once, there might be + // a nested one too + return yield* rec(substitute( + yield* alias.decl.type(), + alias.decl.typeParams, + yield* E.mapLog(type.typeArgs, rec), + )); + } + case "TypeParam": { + return type; + } + case "map_type": { + const key = yield* rec(type.key); + const value = yield* rec(type.value); + return Ast.DTypeMap(key, value, type.loc); + } + case "TypeBounced": { + const args = yield* rec(type.type); + return Ast.DTypeBounced(args, type.loc); + } + case "TypeMaybe": { + const args = yield* rec(type.type); + return Ast.DTypeMaybe(args, type.loc); + } + case "tuple_type": { + const args = yield* E.mapLog(type.typeArgs, rec); + return Ast.DTypeTuple(args, type.loc); + } + case "tensor_type": { + const args = yield* E.mapLog(type.typeArgs, rec); + return Ast.DTypeTensor(args, type.loc); + } + case "TyInt": + case "TySlice": + case "TyCell": + case "TyBuilder": + case "unit_type": + case "TypeVoid": + case "TypeNull": + case "TypeBool": + case "TypeAddress": + case "TypeString": + case "TypeStringBuilder": { + return type; + } + } + } + + return rec(type); +}; + +const substitute = ( + type: Ast.DecodedType, + params: Ast.TypeParams, + args: readonly Ast.DecodedType[], +): Ast.DecodedType => { + if (params.order.length !== args.length) { + return throwInternal("Decoder didn't check alias arity"); + } + + const substMap = new Map(zip(params.order, args).map(([param, arg]) => { + return [param.text, arg]; + })); + + const recN = (types: readonly Ast.DecodedType[]): readonly Ast.DecodedType[] => { + return types.map(type => rec(type)); + }; + + const rec = (type: Ast.DecodedType): Ast.DecodedType => { + switch (type.kind) { + case "TypeParam": { + const arg = substMap.get(type.name.text); + if (!arg) { + return throwInternal("Decoder didn't scope alias's type args"); + } + return arg; + } + case "type_ref": { + const args = recN(type.typeArgs); + return Ast.DTypeRef(type.name, args, type.loc); + } + case "TypeAlias": { + const args = recN(type.typeArgs); + return Ast.DTypeAliasRef(type.name, args, type.loc); + } + case "map_type": { + const key = rec(type.key); + const value = rec(type.value); + return Ast.DTypeMap(key, value, type.loc); + } + case "TypeBounced": { + const args = rec(type.type); + return Ast.DTypeBounced(args, type.loc); + } + case "TypeMaybe": { + const args = rec(type.type); + return Ast.DTypeMaybe(args, type.loc); + } + case "tuple_type": { + const args = recN(type.typeArgs); + return Ast.DTypeTuple(args, type.loc); + } + case "tensor_type": { + const args = recN(type.typeArgs); + return Ast.DTypeTensor(args, type.loc); + } + case "recover": + case "TyInt": + case "TySlice": + case "TyCell": + case "TyBuilder": + case "unit_type": + case "TypeVoid": + case "TypeNull": + case "TypeBool": + case "TypeAddress": + case "TypeString": + case "TypeStringBuilder": { + return type; + } + } + }; + + return rec(type); +}; + +export function* assignType( + ascribed: Ast.DecodedType, + computed: Ast.DecodedType, + scopeRef: () => Ast.Scope, +) { + +} \ No newline at end of file diff --git a/src/next/types/typecheck.ts b/src/next/types/typecheck.ts index c92b266054..2d5f6fb8dd 100644 --- a/src/next/types/typecheck.ts +++ b/src/next/types/typecheck.ts @@ -6,12 +6,10 @@ import * as E from "@/next/types/errors"; import * as Ast from "@/next/ast"; import { memo } from "@/utils/tricks"; import type { ResolvedImport, TactImport, TactSource } from "@/next/imports/source"; -import { getDecodeType } from "@/next/types/types"; -import { getAllAliases } from "@/next/types/aliases"; -import { getAllFunctions } from "@/next/types/functions"; -import { getAllConstants } from "@/next/types/constants"; -import { getAllExtensions } from "@/next/types/extensions"; -import { getTraitSigs } from "@/next/types/traits"; +import { decodeTypeDecls } from "@/next/types/typedecl"; +import { decodeFunctions } from "@/next/types/functions"; +import { decodeConstants } from "@/next/types/constants"; +import { decodeExtensions } from "@/next/types/extensions"; export const typecheck = (root: TactSource): [Ast.Scope, E.TcError[]] => { const allErrors: E.TcError[] = []; @@ -54,66 +52,12 @@ function* tcSource( // source for current file source: TactSource, ): E.WithLog { - // kind-level descriptors for types - const allSigs = yield* getDecodeType( - imported, - source, - ); - // aliases can loop, have to check separately - const allAliasSigs = yield* getAllAliases( - allSigs, - imported, - source, - ); - // get descriptors for functions - const fnSigs = yield* getAllFunctions( - imported, - source, - allSigs, - allAliasSigs, - ); - // get descriptors for extensions - const extSigs = yield* getAllExtensions( - imported, - source, - allSigs, - allAliasSigs, - ); - const traitSigs = yield* getTraitSigs( - imported, - source, - allSigs, - allAliasSigs, - ); - // NB! we don't only check constants, but also get an - // expression checker out of it. constants might have no - // type annotation, and are required to check exprs - const { constSigs, checkExpr } = yield* getAllConstants( - imported, - source, - allSigs, - allAliasSigs, - fnSigs, - extSigs, - methodSigs, - ); - - - - // check aliases (no recursion) - // scope extensions - // check functions/extension/constant/method body - // source.items.constants.map(node => checkConstant(node)) - // check type uses (all types should be defined) - // check kinds (all uses of types are correct) - // get() opcode - // message opcode `Expression | undefined`, can only be done after types are checked - // TODO: constant/function/extension loops - - return { - fnSigs, - typeDecls, - constSigs, - extSigs, - }; + const scopeRef = () => scope; + const scope: Ast.Scope = { + typeDecls: yield* decodeTypeDecls(imported, source, scopeRef), + functions: yield* decodeFunctions(imported, source, scopeRef), + constants: yield* decodeConstants(imported, source, scopeRef), + extensions: decodeExtensions(imported, source, scopeRef), + } + return scope; } \ No newline at end of file diff --git a/src/next/types/typedecl.ts b/src/next/types/typedecl.ts new file mode 100644 index 0000000000..b528f6648e --- /dev/null +++ b/src/next/types/typedecl.ts @@ -0,0 +1,90 @@ +/* eslint-disable require-yield */ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import * as Ast from "@/next/ast"; +import * as E from "@/next/types/errors"; +import { builtinTypes } from "@/next/types/builtins"; +import type { TactSource } from "@/next/imports/source"; +import { decodeAlias } from "@/next/types/alias"; +import { decodeContract } from "@/next/types/contract"; + +const errorKind = 'type'; + +export function* decodeTypeDecls( + imported: readonly Ast.SourceCheckResult[], + source: TactSource, + scopeRef: () => Ast.Scope, +): E.WithLog>> { + const importedSigs = imported.map(({ globals, importedBy }) => ( + new Map( + globals.typeDecls.entries() + .map(([name, s]) => [name, Ast.Decl(s.decl, Ast.ViaImport(importedBy, s.via))]) + ) + )); + + const localSigs = yield* E.mapLog( + source.items.types, + function* (decl) { + const via = Ast.ViaOrigin(decl.loc, source); + return new Map([[ + decl.name.text, + Ast.Decl( + yield* decodeTypeDecl(decl, source, scopeRef), + via, + ), + ]]); + }, + ); + + const prev: Map> = new Map(); + for (const next of [...importedSigs, ...localSigs]) { + for (const [name, nextItem] of next) { + const prevItem = prev.get(name); + // defined in compiler + if (builtinTypes.has(name)) { + yield E.ERedefine(errorKind, name, Ast.ViaBuiltin(), nextItem.via); + continue; + } + // not defined yet; define it now + if (typeof prevItem === 'undefined') { + prev.set(name, nextItem); + continue; + } + // already defined, and it's not a diamond situation + if (prevItem.via.source !== nextItem.via.source) { + yield E.ERedefine(errorKind, name, prevItem.via, nextItem.via); + } + } + } + return prev; +} + +function* decodeTypeDecl( + decl: Ast.TypeDecl, + source: TactSource, + scopeRef: () => Ast.Scope, +): E.WithLog { + switch (decl.kind) { + case "alias_decl": { + return yield* decodeAlias(decl, scopeRef); + } + case "contract": { + return yield* decodeContract(decl, scopeRef); + } + case "trait": { + throw new Error(); + // return Ast.DeclSig('contract', 0, via); + } + case "message_decl": { + throw new Error(); + // return Ast.DeclSig('usual', 0, via); + } + case "struct_decl": { + throw new Error(); + // return Ast.DeclSig('usual', decl.typeParams.length, via); + } + case "union_decl": { + throw new Error(); + // return Ast.DeclSig('usual', decl.typeParams.length, via); + } + } +} diff --git a/src/next/types/types.ts b/src/next/types/types.ts deleted file mode 100644 index c2066d6ade..0000000000 --- a/src/next/types/types.ts +++ /dev/null @@ -1,226 +0,0 @@ -import * as Ast from "@/next/ast"; -import { builtinTypes } from "@/next/types/builtins"; -import { concatReg } from "@/next/types/reg"; -import type { TactImport, TactSource } from "@/next/imports/source"; -import * as E from "@/next/types/errors"; - -export function* getDecodeType( - imported: readonly Ast.SourceCheckResult[], - source: TactSource, -) { - const importedSigs = importSigs(imported); - const localSigs = getLocalSigs(source); - const sigs = yield* concatReg( - builtinTypes, - 'type', - [...importedSigs, ...localSigs], - ); - - return sigs; -} - -const importSigs = (imported: readonly Ast.SourceCheckResult[]) => { - return imported.map(({ globals, importedBy }) => ( - new Map( - globals.typeDecls.entries() - .map(([name, s]) => [name, toSigDecoded(s, importedBy)]) - ) - )); -}; - -const toSigDecoded = (decl: Ast.TypeDeclSig, importedBy: TactImport): Ast.DeclSig => { - const via = Ast.ViaImport(importedBy, decl.via); - switch (decl.kind) { - case "bad": - return Ast.DeclSig('forbidden', decl.arity, via); - case "alias": - return Ast.DeclSig('alias', decl.typeParams.order.length, via) - case "contract": - case "trait": - return Ast.DeclSig('contract', 0, via); - case "struct": - case "message": - case "union": - return Ast.DeclSig('usual', decl.typeParams.order.length, via); - } -}; - -const getLocalSigs = (source: TactSource) => { - return source.items.types - .map((decl) => new Map([[decl.name.text, toSigNew(decl, source)]])) -}; - -const toSigNew = (decl: Ast.TypeDecl, source: TactSource) => { - const via = Ast.ViaOrigin(decl.loc, source); - switch (decl.kind) { - case "alias_decl": { - return Ast.DeclSig('alias', decl.typeParams.length, via); - } - case "contract": - case "trait": { - return Ast.DeclSig('contract', 0, via); - } - case "message_decl": { - return Ast.DeclSig('usual', 0, via); - } - case "struct_decl": - case "union_decl": { - return Ast.DeclSig('usual', decl.typeParams.length, via); - } - } -}; - -export function decodeType( - sigs: ReadonlyMap, - typeParams: Ast.TypeParams, - type: Ast.Type, -): E.WithLog { - // decode all the types in an array - function* recN( - types: readonly Ast.Type[], - ): E.WithLog { - const results: Ast.DecodedType[] = []; - for (const type of types) { - const result = yield* rec(type); - results.push(result); - } - return results; - } - - // decode a type - function* rec( - type: Ast.Type, - ): E.WithLog { - switch (type.kind) { - case "unit_type": - case "TyInt": - case "TySlice": - case "TyCell": - case "TyBuilder": - case "TypeVoid": - case "TypeNull": - case "TypeBool": - case "TypeAddress": - case "TypeString": - case "TypeStringBuilder": { - return type; - } - case "tuple_type": { - const result = yield* recN(type.typeArgs); - return Ast.DTypeTuple(result, type.loc); - } - case "tensor_type": { - const result = yield* recN(type.typeArgs); - return Ast.DTypeTensor(result, type.loc); - } - case "map_type": { - const key = yield* rec(type.key); - const value = yield* rec(type.value); - return Ast.DTypeMap(key, value, type.loc); - } - case "TypeBounced": { - const child = yield* rec(type.type); - return Ast.DTypeBounced(child, type.loc); - } - case "TypeMaybe": { - const child = yield* rec(type.type); - return Ast.DTypeMaybe(child, type.loc); - } - case "cons_type": { - // this is where the meat of the procedure is - // cons can be either parameter, type reference, - // alias reference, or reference to undefined type - const name = type.name.text; - const arity = type.typeArgs.length; - - const args = yield* recN(type.typeArgs); - - // if it's in a list of type parameters, this - // is a parameter - if (typeParams.set.has(name)) { - // if we used type parameter generically, throw error - // because we do not support HKT - if (!(yield* matchArity(name, arity, 0, type.loc))) { - return Ast.DTypeRecover(); - } - return Ast.DTypeParamRef( - type.name, - type.loc, - ); - } - - const typeEntry = sigs.get(name); - - // there is no such type at all! - if (!typeEntry) { - yield ETypeNotFound(name, type.loc); - return Ast.DTypeRecover(); - } - - // check number of type arguments does match - if (!(yield* matchArity( - name, - arity, - typeEntry.arity, - type.loc, - ))) { - return Ast.DTypeRecover(); - } - - switch (typeEntry.use) { - case "usual": - case "contract": { - // this is a ground type reference - return Ast.DTypeRef(type.name, args, type.loc); - } - case "alias": { - // this is an alias reference - return Ast.DTypeAliasRef(type.name, args, type.loc); - } - case "forbidden": { - // something went wrong with the declaration we refer to - // so this cannot be a valid type - return Ast.DTypeRecover(); - } - } - } - } - } - - return rec(type); -} - -const ETypeNotFound = ( - name: string, - loc: Ast.Loc, -): E.TcError => ({ - loc, - descr: [ - E.TEText(`Type "${name}" is not defined`), - ], -}); - -function* matchArity( - name: string, - got: number, - expected: number, - loc: Ast.Loc, -): E.WithLog { - const result = got === expected; - if (!result) { - yield EArity(name, expected, got, loc); - } - return result; -} - -const EArity = ( - name: string, - expected: number, - got: number, - loc: Ast.Loc, -): E.TcError => ({ - loc, - descr: [ - E.TEText(`Type "${name}" is expected to have ${expected} type arguments, got ${got}`), - ], -}); \ No newline at end of file From 279083b3427df15416607b3978a8f2d480927e2d Mon Sep 17 00:00:00 2001 From: verytactical <186486509+verytactical@users.noreply.github.com> Date: Fri, 30 May 2025 04:31:38 +0400 Subject: [PATCH 25/38] 1 --- spell/cspell-list.txt | 1 + src/next/ast/checked-expr.ts | 78 +-- src/next/ast/checked.ts | 80 ++- src/next/ast/dtype.ts | 3 +- src/next/ast/expression.ts | 2 +- src/next/ast/generated/checked-expr.ts | 64 +- src/next/ast/generated/checked.ts | 158 +++-- src/next/ast/generated/dtype.ts | 4 +- src/next/ast/generated/root.ts | 9 +- src/next/ast/generated/value.ts | 6 +- src/next/ast/mtype.ts | 10 +- src/next/ast/root.ts | 1 + src/next/ast/value.ts | 4 + src/next/grammar/errors.ts | 3 + src/next/grammar/index.ts | 8 +- src/next/scoping/typecheck.ts | 868 ------------------------- src/next/types/body.ts | 3 +- src/next/types/builtins.ts | 7 +- src/next/types/constant-def.ts | 72 +- src/next/types/constants.ts | 9 +- src/next/types/contract.ts | 166 ++++- src/next/types/expression.ts | 504 +++++++++++++- src/next/types/extensions.ts | 8 +- src/next/types/fields.ts | 62 +- src/next/types/message.ts | 96 +++ src/next/types/methods.ts | 52 +- src/next/types/override.ts | 2 +- src/next/types/receivers.ts | 239 +++++++ src/next/types/struct-fields.ts | 68 ++ src/next/types/struct.ts | 15 + src/next/types/trait.ts | 66 ++ src/next/types/traits-scope.ts | 10 +- src/next/types/type-fn.ts | 112 +++- src/next/types/type.ts | 204 +++++- src/next/types/typedecl.ts | 25 +- src/next/types/union.ts | 93 +++ src/next/types/value.ts | 22 + 37 files changed, 1964 insertions(+), 1170 deletions(-) create mode 100644 src/next/types/message.ts create mode 100644 src/next/types/receivers.ts create mode 100644 src/next/types/struct-fields.ts create mode 100644 src/next/types/struct.ts create mode 100644 src/next/types/trait.ts create mode 100644 src/next/types/union.ts create mode 100644 src/next/types/value.ts diff --git a/spell/cspell-list.txt b/spell/cspell-list.txt index 155bdd2330..a1e437988f 100644 --- a/spell/cspell-list.txt +++ b/spell/cspell-list.txt @@ -79,6 +79,7 @@ infixl infixr initof injectivity +Instanitable Ints ipfs IPFS diff --git a/src/next/ast/checked-expr.ts b/src/next/ast/checked-expr.ts index a0b6cfcb77..73dbe59395 100644 --- a/src/next/ast/checked-expr.ts +++ b/src/next/ast/checked-expr.ts @@ -1,7 +1,10 @@ +import type { Ordered } from "@/next/ast/checked"; import type { Id, Loc, TypeId } from "@/next/ast/common"; -import type { DecodedType, DTypeMap } from "@/next/ast/dtype"; +import type * as D from "@/next/ast/dtype"; import type { BinaryOperation, NumberBase, UnaryOperation } from "@/next/ast/expression"; -import type { Lazy } from "@/next/ast/lazy"; +import type { SelfType } from "@/next/ast/mtype"; + +export type TypeArgs = ReadonlyMap; export type DecodedExpression = | DOpBinary @@ -19,16 +22,23 @@ export type DecodedExpression = | DNull | DString | DVar + | DSelf | DUnit | DTuple | DTensor | DMapLiteral | DSetLiteral; +export type DSelf = { + readonly kind: "self"; + readonly computedType: SelfType; + readonly loc: Loc; +} + export type DVar = { readonly kind: "var"; readonly name: string; - readonly computedType: Lazy; + readonly computedType: D.DecodedType; readonly loc: Loc; }; @@ -36,27 +46,27 @@ export type DNumber = { readonly kind: "number"; readonly base: NumberBase; readonly value: bigint; - readonly computedType: Lazy; + readonly computedType: D.DTypeInt; readonly loc: Loc; }; export type DBoolean = { readonly kind: "boolean"; readonly value: boolean; - readonly computedType: Lazy; + readonly computedType: D.DTypeBool; readonly loc: Loc; }; export type DString = { readonly kind: "string"; readonly value: string; - readonly computedType: Lazy; + readonly computedType: D.DTypeString; readonly loc: Loc; }; export type DNull = { readonly kind: "null"; - readonly computedType: Lazy; + readonly computedType: D.DTypeNull; readonly loc: Loc; }; @@ -65,7 +75,8 @@ export type DOpBinary = { readonly op: BinaryOperation; readonly left: DecodedExpression; readonly right: DecodedExpression; - readonly computedType: Lazy; + readonly typeArgs: TypeArgs; + readonly computedType: D.DecodedType; readonly loc: Loc; }; @@ -73,7 +84,8 @@ export type DOpUnary = { readonly kind: "op_unary"; readonly op: UnaryOperation; readonly operand: DecodedExpression; - readonly computedType: Lazy; + readonly typeArgs: TypeArgs; + readonly computedType: D.DecodedType; readonly loc: Loc; }; @@ -81,17 +93,18 @@ export type DFieldAccess = { readonly kind: "field_access"; readonly aggregate: DecodedExpression; readonly field: Id; - readonly computedType: Lazy; + readonly computedType: D.DecodedType; readonly loc: Loc; }; export type DMethodCall = { readonly kind: "method_call"; - readonly self: DecodedExpression; // anything with a method + readonly self: DecodedExpression; readonly method: Id; - readonly typeArgs: readonly DecodedType[]; + // NB! these are substitutions to self type readonly args: readonly DecodedExpression[]; - readonly computedType: Lazy; + readonly typeArgs: TypeArgs; + readonly computedType: D.DecodedType; readonly loc: Loc; }; @@ -99,42 +112,33 @@ export type DMethodCall = { export type DStaticCall = { readonly kind: "static_call"; readonly function: Id; - readonly typeArgs: readonly DecodedType[]; + readonly typeArgs: TypeArgs; readonly args: readonly DecodedExpression[]; - readonly computedType: Lazy; + readonly computedType: D.DecodedType; readonly loc: Loc; }; export type DStaticMethodCall = { readonly kind: "static_method_call"; readonly self: TypeId; - readonly typeArgs: readonly DecodedType[]; + readonly typeArgs: TypeArgs; readonly function: Id; readonly args: readonly DecodedExpression[]; - readonly computedType: Lazy; + readonly computedType: D.DecodedType; readonly loc: Loc; }; export type DStructInstance = { readonly kind: "struct_instance"; - readonly type: TypeId; - readonly typeArgs: readonly DecodedType[]; - readonly args: readonly DStructFieldInitializer[]; - readonly computedType: Lazy; - readonly loc: Loc; -}; - -export type DStructFieldInitializer = { - readonly field: Id; - readonly initializer: DecodedExpression; + readonly fields: Ordered; + readonly computedType: D.DTypeRef | D.DTypeRecover; readonly loc: Loc; }; export type DMapLiteral = { readonly kind: "map_literal"; - readonly type: DTypeMap; readonly fields: readonly DMapField[]; - readonly computedType: Lazy; + readonly computedType: D.DTypeMap; readonly loc: Loc; }; @@ -145,9 +149,9 @@ export type DMapField = { export type DSetLiteral = { readonly kind: "set_literal"; - readonly valueType: DecodedType; + readonly valueType: D.DecodedType; readonly fields: readonly DecodedExpression[]; - readonly computedType: Lazy; + readonly computedType: D.DecodedType; readonly loc: Loc; }; @@ -155,14 +159,14 @@ export type DInitOf = { readonly kind: "init_of"; readonly contract: TypeId; readonly args: readonly DecodedExpression[]; - readonly computedType: Lazy; + readonly computedType: D.DecodedType; readonly loc: Loc; }; export type DCodeOf = { readonly kind: "code_of"; readonly contract: TypeId; - readonly computedType: Lazy; + readonly computedType: D.DecodedType; readonly loc: Loc; }; @@ -171,26 +175,26 @@ export type DConditional = { readonly condition: DecodedExpression; readonly thenBranch: DecodedExpression; readonly elseBranch: DecodedExpression; - readonly computedType: Lazy; + readonly computedType: D.DecodedType; readonly loc: Loc; }; export type DUnit = { readonly kind: "unit"; - readonly computedType: Lazy; + readonly computedType: D.DTypeUnit; readonly loc: Loc; }; export type DTuple = { readonly kind: "tuple"; readonly children: readonly DecodedExpression[]; - readonly computedType: Lazy; + readonly computedType: D.DTypeTuple; readonly loc: Loc; }; export type DTensor = { readonly kind: "tensor"; readonly children: readonly DecodedExpression[]; - readonly computedType: Lazy; + readonly computedType: D.DTypeTensor; readonly loc: Loc; }; diff --git a/src/next/ast/checked.ts b/src/next/ast/checked.ts index ea1c3cf304..2024fcc1f4 100644 --- a/src/next/ast/checked.ts +++ b/src/next/ast/checked.ts @@ -1,10 +1,10 @@ -import type { DecodedExpression } from "@/next/ast/checked-expr"; import type { DecodedStatement } from "@/next/ast/checked-stmt"; import type { FuncId, Loc, OptionalId, TypeId } from "@/next/ast/common"; -import type { DecodedType, DTypeRef } from "@/next/ast/dtype"; +import type { DecodedType, DTypeRef, DTypeBounced } from "@/next/ast/dtype"; import type { Lazy } from "@/next/ast/lazy"; import type { SelfType } from "@/next/ast/mtype"; import type { AsmInstruction, AsmShuffle, ContractAttribute } from "@/next/ast/root"; +import type { Value } from "@/next/ast/value"; import type { ViaMember, ViaUser } from "@/next/ast/via"; import type { TactImport } from "@/next/imports/source"; @@ -36,7 +36,7 @@ export type TypeDeclSig = | UnionSig export type ConstSig = { - readonly initializer: Lazy; + readonly initializer: Lazy; readonly type: Lazy; } @@ -74,14 +74,43 @@ export type AliasSig = { readonly type: Lazy; } +export type InitSig = + | InitEmpty + | InitSimple + | InitFn +export type InitEmpty = { + readonly kind: 'empty'; + // initOf() would take 0 parameters + // values to fill all the fields + readonly fill: Lazy>>; +} +export type InitSimple = { + readonly kind: 'simple'; + // initOf() takes these parameters and + // sets them into correspondingly named fields + readonly fill: Ordered; + readonly loc: Loc; +} +export type InitFn = { + readonly kind: 'function'; + // here we just specify the function + readonly params: Parameters; + readonly statements: readonly DecodedStatement[]; +} +export type InitParam = { + readonly type: Lazy; + readonly init: undefined | Lazy; + readonly loc: Loc; +} + export type ContractSig = { readonly kind: 'contract'; readonly attributes: readonly ContractAttribute[]; - readonly params: Parameters; + readonly init: InitSig; readonly content: Lazy; } export type ContractContent = CommonSig< - Lazy, + Lazy, Body > export type TraitSig = { @@ -89,22 +118,25 @@ export type TraitSig = { readonly content: Lazy; } export type TraitContent = CommonSig< - Lazy | undefined, + Lazy | undefined, Body | undefined > export type CommonSig = { readonly fieldish: Ordered>>; readonly methods: ReadonlyMap>>; + readonly receivers: Receivers; +} +export type Receivers = { readonly bounce: BounceSig; readonly internal: RecvSig; readonly external: RecvSig; } -export type Fieldish = InhFieldSig | FieldConstSig; -export type InhFieldSig = { +export type Fieldish = InhFieldSig | FieldConstSig; +export type InhFieldSig = { readonly kind: 'field'; readonly type: Lazy - readonly init: Expr; + readonly init: Lazy | undefined; } export type FieldConstSig = { readonly kind: 'constant'; @@ -122,33 +154,41 @@ export type MethodSig = { } export type BounceSig = { - readonly message: ReadonlyMap>; + // NB! can't compute opcodes until all receivers are present + readonly message: readonly DeclMem[]; readonly messageAny: undefined | DeclMem; } export type RecvSig = { - readonly message: ReadonlyMap>; + // NB! can't compute opcodes until all receivers are present + readonly message: readonly DeclMem[]; readonly messageAny: undefined | DeclMem; - readonly string: ReadonlyMap>; readonly stringAny: undefined | DeclMem; readonly empty: undefined | DeclMem; } +export type OpcodeRecv = MessageRecv | StringRecv; export type MessageRecv = { + readonly kind: "binary"; readonly name: OptionalId; - readonly type: DTypeRef; + readonly type: DTypeRef | DTypeBounced; + readonly statements: readonly DecodedStatement[]; } export type MessageAnyRecv = { readonly name: OptionalId; + readonly statements: readonly DecodedStatement[]; } export type StringRecv = { + readonly kind: "string"; readonly comment: string; + readonly statements: readonly DecodedStatement[]; } export type StringAnyRecv = { readonly name: OptionalId; + readonly statements: readonly DecodedStatement[]; } export type EmptyRecv = { - readonly one: 1; + readonly statements: readonly DecodedStatement[]; } export type DeclMem = { @@ -159,23 +199,19 @@ export type DeclMem = { export type StructSig = { readonly kind: "struct"; readonly typeParams: TypeParams; - readonly fields: Ordered; + readonly fields: Ordered; } export type MessageSig = { readonly kind: "message"; - readonly fields: Ordered; + readonly opcode: Lazy; + readonly fields: Ordered; } export type UnionSig = { readonly kind: "union"; readonly typeParams: TypeParams; - readonly cases: ReadonlyMap>>; -} - -export type FieldSig = { - readonly type: Lazy; - readonly via: ViaUser; + readonly cases: ReadonlyMap>; } export type DecodedFnType = { diff --git a/src/next/ast/dtype.ts b/src/next/ast/dtype.ts index 24761d8974..b1d6ae55f0 100644 --- a/src/next/ast/dtype.ts +++ b/src/next/ast/dtype.ts @@ -61,7 +61,8 @@ export type DTypeParamRef = { export type DTypeBounced = { readonly kind: "TypeBounced" - readonly type: DecodedType; + // name of the message type + readonly name: TypeId; readonly loc: Loc; } diff --git a/src/next/ast/expression.ts b/src/next/ast/expression.ts index 2eb0ff0b9e..09dbbe29d9 100644 --- a/src/next/ast/expression.ts +++ b/src/next/ast/expression.ts @@ -107,7 +107,7 @@ export type MethodCall = { readonly kind: "method_call"; readonly self: Expression; // anything with a method readonly method: Id; - readonly typeArgs: readonly Type[]; + // readonly typeArgs: readonly Type[]; readonly args: readonly Expression[]; readonly loc: Loc; }; diff --git a/src/next/ast/generated/checked-expr.ts b/src/next/ast/generated/checked-expr.ts index c8b37ac848..7c0d51f192 100644 --- a/src/next/ast/generated/checked-expr.ts +++ b/src/next/ast/generated/checked-expr.ts @@ -1,13 +1,13 @@ /* eslint-disable @typescript-eslint/no-unnecessary-condition */ +import type { Ordered } from "@/next/ast/checked"; import type * as $ from "@/next/ast/checked-expr"; import type * as $c from "@/next/ast/common"; import type * as $d from "@/next/ast/dtype"; import type * as $e from "@/next/ast/expression"; -import type { Lazy } from "@/next/ast/lazy"; - +import type { SelfType } from "@/next/ast/mtype"; export type DCodeOf = $.DCodeOf; -export const DCodeOf = (contract: $c.TypeId, computedType: Lazy<$d.DecodedType>, loc: $c.Loc): $.DCodeOf => Object.freeze({ +export const DCodeOf = (contract: $c.TypeId, computedType: $d.DecodedType, loc: $c.Loc): $.DCodeOf => Object.freeze({ kind: "code_of", contract, computedType, @@ -15,7 +15,7 @@ export const DCodeOf = (contract: $c.TypeId, computedType: Lazy<$d.DecodedType>, }); export const isDCodeOf = ($value: DCodeOf) => $value.kind === "code_of"; export type DNumber = $.DNumber; -export const DNumber = (base: $e.NumberBase, value: bigint, computedType: Lazy<$d.DecodedType>, loc: $c.Loc): $.DNumber => Object.freeze({ +export const DNumber = (base: $e.NumberBase, value: bigint, computedType: $d.DTypeInt, loc: $c.Loc): $.DNumber => Object.freeze({ kind: "number", base, value, @@ -24,7 +24,7 @@ export const DNumber = (base: $e.NumberBase, value: bigint, computedType: Lazy<$ }); export const isDNumber = ($value: DNumber) => $value.kind === "number"; export type DBoolean = $.DBoolean; -export const DBoolean = (value: boolean, computedType: Lazy<$d.DecodedType>, loc: $c.Loc): $.DBoolean => Object.freeze({ +export const DBoolean = (value: boolean, computedType: $d.DTypeBool, loc: $c.Loc): $.DBoolean => Object.freeze({ kind: "boolean", value, computedType, @@ -32,14 +32,14 @@ export const DBoolean = (value: boolean, computedType: Lazy<$d.DecodedType>, loc }); export const isDBoolean = ($value: DBoolean) => $value.kind === "boolean"; export type DNull = $.DNull; -export const DNull = (computedType: Lazy<$d.DecodedType>, loc: $c.Loc): $.DNull => Object.freeze({ +export const DNull = (computedType: $d.DTypeNull, loc: $c.Loc): $.DNull => Object.freeze({ kind: "null", computedType, loc }); export const isDNull = ($value: DNull) => $value.kind === "null"; export type DString = $.DString; -export const DString = (value: string, computedType: Lazy<$d.DecodedType>, loc: $c.Loc): $.DString => Object.freeze({ +export const DString = (value: string, computedType: $d.DTypeString, loc: $c.Loc): $.DString => Object.freeze({ kind: "string", value, computedType, @@ -47,22 +47,29 @@ export const DString = (value: string, computedType: Lazy<$d.DecodedType>, loc: }); export const isDString = ($value: DString) => $value.kind === "string"; export type DVar = $.DVar; -export const DVar = (name: string, computedType: Lazy<$d.DecodedType>, loc: $c.Loc): $.DVar => Object.freeze({ +export const DVar = (name: string, computedType: $d.DecodedType, loc: $c.Loc): $.DVar => Object.freeze({ kind: "var", name, computedType, loc }); export const isDVar = ($value: DVar) => $value.kind === "var"; +export type DSelf = $.DSelf; +export const DSelf = (computedType: SelfType, loc: $c.Loc): $.DSelf => Object.freeze({ + kind: "self", + computedType, + loc +}); +export const isDSelf = ($value: DSelf) => $value.kind === "self"; export type DUnit = $.DUnit; -export const DUnit = (computedType: Lazy<$d.DecodedType>, loc: $c.Loc): $.DUnit => Object.freeze({ +export const DUnit = (computedType: $d.DTypeUnit, loc: $c.Loc): $.DUnit => Object.freeze({ kind: "unit", computedType, loc }); export const isDUnit = ($value: DUnit) => $value.kind === "unit"; export type DSetLiteral = $.DSetLiteral; -export const DSetLiteral = (valueType: $d.DecodedType, computedType: Lazy<$d.DecodedType>, fields: readonly $.DecodedExpression[], loc: $c.Loc): $.DSetLiteral => Object.freeze({ +export const DSetLiteral = (valueType: $d.DecodedType, computedType: $d.DecodedType, fields: readonly $.DecodedExpression[], loc: $c.Loc): $.DSetLiteral => Object.freeze({ kind: "set_literal", valueType, fields, @@ -76,16 +83,15 @@ export const DMapField = (key: $.DecodedExpression, value: $.DecodedExpression): value }); export type DMapLiteral = $.DMapLiteral; -export const DMapLiteral = (type_: $d.DTypeMap, computedType: Lazy<$d.DecodedType>, fields: readonly $.DMapField[], loc: $c.Loc): $.DMapLiteral => Object.freeze({ +export const DMapLiteral = (computedType: $d.DTypeMap, fields: readonly $.DMapField[], loc: $c.Loc): $.DMapLiteral => Object.freeze({ kind: "map_literal", - type: type_, fields, computedType, loc }); export const isDMapLiteral = ($value: DMapLiteral) => $value.kind === "map_literal"; export type DTensor = $.DTensor; -export const DTensor = (children: readonly $.DecodedExpression[], computedType: Lazy<$d.DecodedType>, loc: $c.Loc): $.DTensor => Object.freeze({ +export const DTensor = (children: readonly $.DecodedExpression[], computedType: $d.DTypeTensor, loc: $c.Loc): $.DTensor => Object.freeze({ kind: "tensor", children, computedType, @@ -93,7 +99,7 @@ export const DTensor = (children: readonly $.DecodedExpression[], computedType: }); export const isDTensor = ($value: DTensor) => $value.kind === "tensor"; export type DTuple = $.DTuple; -export const DTuple = (children: readonly $.DecodedExpression[], computedType: Lazy<$d.DecodedType>, loc: $c.Loc): $.DTuple => Object.freeze({ +export const DTuple = (children: readonly $.DecodedExpression[], computedType: $d.DTypeTuple, loc: $c.Loc): $.DTuple => Object.freeze({ kind: "tuple", children, computedType, @@ -101,7 +107,7 @@ export const DTuple = (children: readonly $.DecodedExpression[], computedType: L }); export const isDTuple = ($value: DTuple) => $value.kind === "tuple"; export type DInitOf = $.DInitOf; -export const DInitOf = (contract: $c.TypeId, args: readonly $.DecodedExpression[], computedType: Lazy<$d.DecodedType>, loc: $c.Loc): $.DInitOf => Object.freeze({ +export const DInitOf = (contract: $c.TypeId, args: readonly $.DecodedExpression[], computedType: $d.DecodedType, loc: $c.Loc): $.DInitOf => Object.freeze({ kind: "init_of", contract, args, @@ -109,24 +115,16 @@ export const DInitOf = (contract: $c.TypeId, args: readonly $.DecodedExpression[ loc }); export const isDInitOf = ($value: DInitOf) => $value.kind === "init_of"; -export type DStructFieldInitializer = $.DStructFieldInitializer; -export const DStructFieldInitializer = (field: $c.Id, initializer: $.DecodedExpression, loc: $c.Loc): $.DStructFieldInitializer => Object.freeze({ - field, - initializer, - loc -}); export type DStructInstance = $.DStructInstance; -export const DStructInstance = (type_: $c.TypeId, typeArgs: readonly $d.DecodedType[], args: readonly $.DStructFieldInitializer[], computedType: Lazy<$d.DecodedType>, loc: $c.Loc): $.DStructInstance => Object.freeze({ +export const DStructInstance = (fields: Ordered, computedType: $d.DTypeRef | $d.DTypeRecover, loc: $c.Loc): $.DStructInstance => Object.freeze({ kind: "struct_instance", - type: type_, - typeArgs, - args, + fields, computedType, loc }); export const isDStructInstance = ($value: DStructInstance) => $value.kind === "struct_instance"; export type DFieldAccess = $.DFieldAccess; -export const DFieldAccess = (aggregate: $.DecodedExpression, field: $c.Id, computedType: Lazy<$d.DecodedType>, loc: $c.Loc): $.DFieldAccess => Object.freeze({ +export const DFieldAccess = (aggregate: $.DecodedExpression, field: $c.Id, computedType: $d.DecodedType, loc: $c.Loc): $.DFieldAccess => Object.freeze({ kind: "field_access", aggregate, field, @@ -135,7 +133,7 @@ export const DFieldAccess = (aggregate: $.DecodedExpression, field: $c.Id, compu }); export const isDFieldAccess = ($value: DFieldAccess) => $value.kind === "field_access"; export type DStaticMethodCall = $.DStaticMethodCall; -export const DStaticMethodCall = (self: $c.TypeId, typeArgs: readonly $d.DecodedType[], function_: $c.Id, args: readonly $.DecodedExpression[], computedType: Lazy<$d.DecodedType>, loc: $c.Loc): $.DStaticMethodCall => Object.freeze({ +export const DStaticMethodCall = (self: $c.TypeId, typeArgs: $.TypeArgs, function_: $c.Id, args: readonly $.DecodedExpression[], computedType: $d.DecodedType, loc: $c.Loc): $.DStaticMethodCall => Object.freeze({ kind: "static_method_call", self, typeArgs, @@ -146,7 +144,7 @@ export const DStaticMethodCall = (self: $c.TypeId, typeArgs: readonly $d.Decoded }); export const isDStaticMethodCall = ($value: DStaticMethodCall) => $value.kind === "static_method_call"; export type DStaticCall = $.DStaticCall; -export const DStaticCall = (function_: $c.Id, typeArgs: readonly $d.DecodedType[], args: readonly $.DecodedExpression[], computedType: Lazy<$d.DecodedType>, loc: $c.Loc): $.DStaticCall => Object.freeze({ +export const DStaticCall = (function_: $c.Id, typeArgs: $.TypeArgs, args: readonly $.DecodedExpression[], computedType: $d.DecodedType, loc: $c.Loc): $.DStaticCall => Object.freeze({ kind: "static_call", function: function_, typeArgs, @@ -156,7 +154,7 @@ export const DStaticCall = (function_: $c.Id, typeArgs: readonly $d.DecodedType[ }); export const isDStaticCall = ($value: DStaticCall) => $value.kind === "static_call"; export type DMethodCall = $.DMethodCall; -export const DMethodCall = (self: $.DecodedExpression, method: $c.Id, typeArgs: readonly $d.DecodedType[], args: readonly $.DecodedExpression[], computedType: Lazy<$d.DecodedType>, loc: $c.Loc): $.DMethodCall => Object.freeze({ +export const DMethodCall = (self: $.DecodedExpression, method: $c.Id, args: readonly $.DecodedExpression[], typeArgs: $.TypeArgs, computedType: $d.DecodedType, loc: $c.Loc): $.DMethodCall => Object.freeze({ kind: "method_call", self, method, @@ -167,7 +165,7 @@ export const DMethodCall = (self: $.DecodedExpression, method: $c.Id, typeArgs: }); export const isDMethodCall = ($value: DMethodCall) => $value.kind === "method_call"; export type DConditional = $.DConditional; -export const DConditional = (condition: $.DecodedExpression, thenBranch: $.DecodedExpression, elseBranch: $.DecodedExpression, computedType: Lazy<$d.DecodedType>, loc: $c.Loc): $.DConditional => Object.freeze({ +export const DConditional = (condition: $.DecodedExpression, thenBranch: $.DecodedExpression, elseBranch: $.DecodedExpression, computedType: $d.DecodedType, loc: $c.Loc): $.DConditional => Object.freeze({ kind: "conditional", condition, thenBranch, @@ -177,20 +175,22 @@ export const DConditional = (condition: $.DecodedExpression, thenBranch: $.Decod }); export const isDConditional = ($value: DConditional) => $value.kind === "conditional"; export type DOpUnary = $.DOpUnary; -export const DOpUnary = (op: $e.UnaryOperation, operand: $.DecodedExpression, computedType: Lazy<$d.DecodedType>, loc: $c.Loc): $.DOpUnary => Object.freeze({ +export const DOpUnary = (op: $e.UnaryOperation, operand: $.DecodedExpression, typeArgs: ReadonlyMap, computedType: $d.DecodedType, loc: $c.Loc): $.DOpUnary => Object.freeze({ kind: "op_unary", op, operand, + typeArgs, computedType, loc }); export const isDOpUnary = ($value: DOpUnary) => $value.kind === "op_unary"; export type DOpBinary = $.DOpBinary; -export const DOpBinary = (op: $e.BinaryOperation, left: $.DecodedExpression, right: $.DecodedExpression, computedType: Lazy<$d.DecodedType>, loc: $c.Loc): $.DOpBinary => Object.freeze({ +export const DOpBinary = (op: $e.BinaryOperation, left: $.DecodedExpression, right: $.DecodedExpression, typeArgs: ReadonlyMap, computedType: $d.DecodedType, loc: $c.Loc): $.DOpBinary => Object.freeze({ kind: "op_binary", op, left, right, + typeArgs, computedType, loc }); diff --git a/src/next/ast/generated/checked.ts b/src/next/ast/generated/checked.ts index 85df72a2b9..03aeeb9ec0 100644 --- a/src/next/ast/generated/checked.ts +++ b/src/next/ast/generated/checked.ts @@ -8,7 +8,7 @@ import type { TactImport } from "@/next/imports/source"; import type { Lazy } from "@/next/ast/lazy"; import type { AsmInstruction, AsmShuffle, ContractAttribute } from "@/next/ast/root"; import type { DecodedStatement } from "@/next/ast/checked-stmt"; -import type { DecodedExpression } from "@/next/ast/checked-expr"; +import type { Value } from "@/next/ast/value"; export type TypeParams = $.TypeParams; export const TypeParams = (order: readonly $c.TypeId[], set: ReadonlySet): TypeParams => Object.freeze({ @@ -34,67 +34,21 @@ export const DecodedFnType = (typeParams: $.TypeParams, params: $.Parameters, re params, returnType }); -export type MessageRecv = $.MessageRecv; -export const MessageRecv = (name: $c.OptionalId, type_: $d.DTypeRef): $.MessageRecv => Object.freeze({ - name, - type: type_, -}); -export type MessageAnyRecv = $.MessageAnyRecv; -export const MessageAnyRecv = (name: $c.OptionalId): $.MessageAnyRecv => Object.freeze({ - name, -}); export type BounceSig = $.BounceSig; -export const BounceSig = (message: ReadonlyMap>, messageAny: DeclMem<$.MessageAnyRecv> | undefined): $.BounceSig => Object.freeze({ +export const BounceSig = (message: readonly DeclMem[], messageAny: DeclMem<$.MessageAnyRecv> | undefined): $.BounceSig => Object.freeze({ message, messageAny }); -export type StringRecv = $.StringRecv; -export const StringRecv = (comment: string): $.StringRecv => Object.freeze({ - comment, -}); -export type StringAnyRecv = $.StringAnyRecv; -export const StringAnyRecv = (name: $c.OptionalId): $.StringAnyRecv => Object.freeze({ - name, -}); -export type EmptyRecv = $.EmptyRecv; -export const EmptyRecv = (): $.EmptyRecv => Object.freeze({ - one: 1, -}); -export type RecvSig = $.RecvSig; -export const RecvSig = ( - message: ReadonlyMap>, - messageAny: DeclMem<$.MessageAnyRecv> | undefined, - string_: ReadonlyMap>, - stringAny: DeclMem<$.StringAnyRecv> | undefined, - empty: DeclMem<$.EmptyRecv> | undefined -): $.RecvSig => Object.freeze({ - message, - messageAny, - string: string_, - stringAny, - empty -}); -export type FieldSig = $.FieldSig; -export const FieldSig = (type_: Lazy<$d.DecodedType>, via: $v.ViaUser): $.FieldSig => Object.freeze({ - type: type_, - via -}); + export type StructSig = $.StructSig; -export const StructSig = (typeParams: $.TypeParams, fields: $.Ordered<$.FieldSig>): $.StructSig => Object.freeze({ +export const StructSig = (typeParams: $.TypeParams, fields: $.Ordered<$.InhFieldSig>): $.StructSig => Object.freeze({ kind: "struct", typeParams, fields, }); export const isStructSig = ($value: StructSig) => $value.kind === "struct"; -export type MessageSig = $.MessageSig; -export const MessageSig = (typeParams: $.TypeParams, fields: $.Ordered<$.FieldSig>): $.MessageSig => Object.freeze({ - kind: "message", - typeParams, - fields, -}); -export const isMessageSig = ($value: MessageSig) => $value.kind === "message"; export type UnionSig = $.UnionSig; -export const UnionSig = (typeParams: $.TypeParams, cases: ReadonlyMap>>): $.UnionSig => Object.freeze({ +export const UnionSig = (typeParams: $.TypeParams, cases: ReadonlyMap>): $.UnionSig => Object.freeze({ kind: "union", typeParams, cases, @@ -102,7 +56,7 @@ export const UnionSig = (typeParams: $.TypeParams, cases: ReadonlyMap $value.kind === "union"; export type TypeDeclSig = $.TypeDeclSig; export type ConstSig = $.ConstSig; -export const ConstSig = (init: Lazy, type_: Lazy<$d.DecodedType>): $.ConstSig => Object.freeze({ +export const ConstSig = (init: Lazy, type_: Lazy<$d.DecodedType>): $.ConstSig => Object.freeze({ initializer: init, type: type_, }); @@ -184,13 +138,13 @@ export type DeclMem = $.DeclMem; export const DeclMem = (decl: T, via: $v.ViaMember): DeclMem => ({ decl, via }); -export type InhFieldSig = $.InhFieldSig; -export const InhFieldSig = (type_: Lazy<$d.DecodedType>, init: Expr): $.InhFieldSig => Object.freeze({ +export type InhFieldSig = $.InhFieldSig; +export const InhFieldSig = (type_: Lazy<$d.DecodedType>, init: Lazy | undefined): $.InhFieldSig => Object.freeze({ kind: "field", type: type_, init }); -export const isInhFieldSig = ($value: InhFieldSig) => $value.kind === "field"; +export const isInhFieldSig = ($value: InhFieldSig) => $value.kind === "field"; export type FieldConstSig = $.FieldConstSig; export const FieldConstSig = (overridable: boolean, type_: Lazy<$d.DecodedType>, init: Expr): $.FieldConstSig => Object.freeze({ kind: "constant", @@ -208,27 +162,95 @@ export const MethodSig = (overridable: boolean, type_: $.DecodedMethodTyp body, getMethodId }); +export type Receivers = $.Receivers; export type CommonSig = $.CommonSig; -export const CommonSig = (fieldish: $.Ordered<$.DeclMem<$.Fieldish>>, methods: ReadonlyMap>>, bounce: $.BounceSig, internal: $.RecvSig, external: $.RecvSig): $.CommonSig => Object.freeze({ +export const CommonSig = (fieldish: $.Ordered<$.DeclMem<$.Fieldish>>, methods: ReadonlyMap>>, receivers: $.Receivers): $.CommonSig => Object.freeze({ fieldish, methods, - bounce, - internal, - external -}); -export type ContractSig = $.ContractSig; -export const ContractSig = (attributes: readonly ContractAttribute[], params: $.Parameters, content: Lazy<$.CommonSig, $.Body>>): $.ContractSig => Object.freeze({ - kind: "contract", - attributes, - params, - content + receivers }); -export const isContractSig = ($value: ContractSig) => $value.kind === "contract"; export type ContractContent = $.ContractContent; export type TraitContent = $.TraitContent; export type TraitSig = $.TraitSig; -export const TraitSig = (content: Lazy<$.CommonSig | undefined, $.Body | undefined>>): $.TraitSig => Object.freeze({ +export const TraitSig = (content: Lazy<$.CommonSig | undefined, $.Body | undefined>>): $.TraitSig => Object.freeze({ kind: "trait", content }); export const isTraitSig = ($value: TraitSig) => $value.kind === "trait"; +export type MessageRecv = $.MessageRecv; +export const MessageRecv = (name: $c.OptionalId, type_: $d.DTypeRef | $d.DTypeBounced, statements: readonly DecodedStatement[]): $.MessageRecv => Object.freeze({ + kind: "binary", + name, + type: type_, + statements +}); +export type MessageAnyRecv = $.MessageAnyRecv; +export const MessageAnyRecv = (name: $c.OptionalId, statements: readonly DecodedStatement[]): $.MessageAnyRecv => Object.freeze({ + name, + statements +}); +export type StringRecv = $.StringRecv; +export const StringRecv = (comment: string, statements: readonly DecodedStatement[]): $.StringRecv => Object.freeze({ + kind: "string", + comment, + statements +}); +export type StringAnyRecv = $.StringAnyRecv; +export const StringAnyRecv = (name: $c.OptionalId, statements: readonly DecodedStatement[]): $.StringAnyRecv => Object.freeze({ + name, + statements +}); +export type EmptyRecv = $.EmptyRecv; +export const EmptyRecv = (statements: readonly DecodedStatement[]): $.EmptyRecv => Object.freeze({ + statements +}); +export type OpcodeRecv = $.OpcodeRecv; +export type RecvSig = $.RecvSig; +export const RecvSig = (message: readonly DeclMem[], messageAny: $.DeclMem<$.MessageAnyRecv> | undefined, stringAny: $.DeclMem<$.StringAnyRecv> | undefined, empty: $.DeclMem<$.EmptyRecv> | undefined): $.RecvSig => Object.freeze({ + message, + messageAny, + stringAny, + empty +}); +export type MessageSig = $.MessageSig; +export const MessageSig = (opcode: Lazy, fields: $.Ordered<$.InhFieldSig>): $.MessageSig => Object.freeze({ + kind: "message", + opcode, + fields +}); +export const isMessageSig = ($value: MessageSig) => $value.kind === "message"; +export type InitEmpty = $.InitEmpty; +export const InitEmpty = (fill: Lazy<$.Ordered>>): $.InitEmpty => Object.freeze({ + kind: "empty", + fill +}); +export const isInitEmpty = ($value: InitEmpty) => $value.kind === "empty"; +export type InitParam = $.InitParam; +export const InitParam = (type_: Lazy<$d.DecodedType>, init: Lazy | undefined, loc: $c.Loc): $.InitParam => Object.freeze({ + type: type_, + init, + loc +}); +export type InitSimple = $.InitSimple; +export const InitSimple = (fill: $.Ordered<$.InitParam>, loc: $c.Loc): $.InitSimple => Object.freeze({ + kind: "simple", + fill, + loc +}); +export const isInitSimple = ($value: InitSimple) => $value.kind === "simple"; +export type InitFn = $.InitFn; +export const InitFn = (params: $.Parameters, statements: readonly DecodedStatement[]): $.InitFn => Object.freeze({ + kind: "function", + params, + statements +}); +export const isInitFn = ($value: InitFn) => $value.kind === "function"; +export type InitSig = $.InitSig; +export type ContractSig = $.ContractSig; +export const ContractSig = (attributes: readonly ContractAttribute[], init: $.InitSig, content: Lazy<$.ContractContent>): $.ContractSig => Object.freeze({ + kind: "contract", + attributes, + init, + content +}); +export const isContractSig = ($value: ContractSig) => $value.kind === "contract"; diff --git a/src/next/ast/generated/dtype.ts b/src/next/ast/generated/dtype.ts index 59299428c5..9898715057 100644 --- a/src/next/ast/generated/dtype.ts +++ b/src/next/ast/generated/dtype.ts @@ -31,9 +31,9 @@ export const DTypeMaybe = (type_: $.DecodedType, loc: $c.Loc): $.DTypeMaybe => O }); export const isDTypeMaybe = ($value: DTypeMaybe) => $value.kind === "TypeMaybe"; export type DTypeBounced = $.DTypeBounced; -export const DTypeBounced = (type_: $.DecodedType, loc: $c.Loc): $.DTypeBounced => Object.freeze({ +export const DTypeBounced = (name: $c.TypeId, loc: $c.Loc): $.DTypeBounced => Object.freeze({ kind: "TypeBounced", - type: type_, + name, loc }); export const isDTypeBounced = ($value: DTypeBounced) => $value.kind === "TypeBounced"; diff --git a/src/next/ast/generated/root.ts b/src/next/ast/generated/root.ts index e979fba306..8a5901912b 100644 --- a/src/next/ast/generated/root.ts +++ b/src/next/ast/generated/root.ts @@ -142,17 +142,18 @@ export const AliasDecl = (name: $c.TypeId, typeParams: readonly $c.TypeId[], typ }); export const isAliasDecl = ($value: AliasDecl) => $value.kind === "alias_decl"; export type InitFunction = $.InitFunction; -export const InitFunction = (args: readonly $t.TypedParameter[], statements: readonly $s.Statement[], loc: $c.Loc): $.InitFunction => Object.freeze({ +export const InitFunction = (params: readonly $t.TypedParameter[], statements: readonly $s.Statement[], loc: $c.Loc): $.InitFunction => Object.freeze({ kind: "init_function", - args, + params, statements, loc }); export const isInitFunction = ($value: InitFunction) => $value.kind === "init_function"; export type InitParams = $.InitParams; -export const InitParams = (params: readonly $.FieldDecl[]): $.InitParams => Object.freeze({ +export const InitParams = (params: readonly $.FieldDecl[], loc: $c.Loc): $.InitParams => Object.freeze({ kind: "init_params", - params + params, + loc, }); export const isInitParams = ($value: InitParams) => $value.kind === "init_params"; export type Init = $.Init; diff --git a/src/next/ast/generated/value.ts b/src/next/ast/generated/value.ts index f638af2ea7..9d433c9995 100644 --- a/src/next/ast/generated/value.ts +++ b/src/next/ast/generated/value.ts @@ -1,10 +1,12 @@ /* eslint-disable @typescript-eslint/no-unnecessary-condition */ +import type { Loc } from "@/next/ast/common"; import type * as $ from "@/next/ast/value"; export type VNumber = $.VNumber; -export const VNumber = (value: bigint): $.VNumber => Object.freeze({ +export const VNumber = (value: bigint, loc: Loc): $.VNumber => Object.freeze({ kind: "number", - value + value, + loc }); export const isVNumber = ($value: VNumber) => $value.kind === "number"; export type Value = $.Value; diff --git a/src/next/ast/mtype.ts b/src/next/ast/mtype.ts index 29de0edbe7..2b5e071f92 100644 --- a/src/next/ast/mtype.ts +++ b/src/next/ast/mtype.ts @@ -12,6 +12,10 @@ export type SelfType = export type MethodGroundType = | MGTypeRef + | MGTypeMap + | MGTypeMaybe + | MGTypeTuple + | MGTypeTensor | MGTypeInt | MGTypeSlice | MGTypeCell @@ -22,11 +26,7 @@ export type MethodGroundType = | MGTypeBool | MGTypeAddress | MGTypeString - | MGTypeStringBuilder - | MGTypeMap - | MGTypeMaybe - | MGTypeTuple - | MGTypeTensor; + | MGTypeStringBuilder; export type Ground = T & { readonly ground: "yes", diff --git a/src/next/ast/root.ts b/src/next/ast/root.ts index f22496c865..8a70532908 100644 --- a/src/next/ast/root.ts +++ b/src/next/ast/root.ts @@ -70,6 +70,7 @@ export type InitFunction = { export type InitParams = { readonly kind: "init_params"; readonly params: readonly FieldDecl[]; + readonly loc: Loc; }; export type Trait = { diff --git a/src/next/ast/value.ts b/src/next/ast/value.ts index 4d47d05820..90f5925b6d 100644 --- a/src/next/ast/value.ts +++ b/src/next/ast/value.ts @@ -1,6 +1,10 @@ +import type { Loc } from "@/next/ast/common"; + export type Value = VNumber export type VNumber = { readonly kind: 'number'; readonly value: bigint; + // loc of expression that resulted in this value + readonly loc: Loc; } diff --git a/src/next/grammar/errors.ts b/src/next/grammar/errors.ts index 6f9c512c5f..afcbf33789 100644 --- a/src/next/grammar/errors.ts +++ b/src/next/grammar/errors.ts @@ -56,6 +56,9 @@ export const SyntaxErrors = (l: SourceLogger) => ({ notCallable: () => (loc: Range) => { return l.at(loc).error(l.text`Expression is not callable`); }, + noGenericMethods: () => (loc: Range) => { + return l.at(loc).error(l.text`Cannot pass type arguments to generic method`); + }, noBouncedWithoutArg: () => (loc: Range) => { return l .at(loc) diff --git a/src/next/grammar/index.ts b/src/next/grammar/index.ts index afbf8383c5..863a22087c 100644 --- a/src/next/grammar/index.ts +++ b/src/next/grammar/index.ts @@ -542,10 +542,14 @@ const parseSuffixCall = loc, ); } else if (child.kind === "field_access") { + const parsedTypeArgs = map(parseList(typeArgs), parseType)(ctx); + if (parsedTypeArgs.length > 0) { + ctx.err.noGenericMethods()(loc); + } return Ast.MethodCall( child.aggregate, child.field, - map(parseList(typeArgs), parseType)(ctx), + [], paramsAst, loc, ); @@ -1595,7 +1599,7 @@ const parseContract = if (initFn) { ctx.err.initFnAndParams()(ctx.toRange(initFn.loc)); } - return Ast.InitParams(params); + return Ast.InitParams(params, ctx.toRange(loc)); // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition } else if (initFn) { return Ast.InitFunction( diff --git a/src/next/scoping/typecheck.ts b/src/next/scoping/typecheck.ts index b1fc0ff402..33e91b1bb1 100644 --- a/src/next/scoping/typecheck.ts +++ b/src/next/scoping/typecheck.ts @@ -172,34 +172,6 @@ const getExprChecker = ( } }; - const mgu = (left: Ty.Type, right: Ty.Type, loc: Ty.Loc): Ty.Type => { - left = simplifyHead(left); - right = simplifyHead(right); - if (left.kind === 'ERROR' || right.kind === 'ERROR') { - return Ty.TypeErrorRecovered(); - } - if (left.kind === 'type_var' || right.kind === 'type_var') { - return throwInternal("Trying to unify type variable"); - } - const children: MismatchTree[] = []; - if (assignToAux1(left, right, children)) { - return left; - } - if (assignToAux1(right, left, children)) { - return right; - } - if (isNull(right)) { - return Maybe(left, loc); - } - if (isNull(left)) { - return Maybe(right, loc); - } - for (const tree of children) { - err.typeMismatch(tree)(loc); - } - return Ty.TypeErrorRecovered(); - }; - let nextId = 0; const freshTVar = () => { const id = nextId++; @@ -221,463 +193,6 @@ const getExprChecker = ( }; }; - const checkNull = (node: Ast.Null): Ty.Type => { - return Null(Ty.Inferred(node.loc, "null literal")); - }; - - const checkUnit = (node: Ast.Unit): Ty.Type => { - return Unit(Ty.Inferred(node.loc, "unit literal")); - }; - - const checkString = (node: Ast.String): Ty.Type => { - return String(Ty.Inferred(node.loc, "string literal")); - }; - - const checkNumber = (node: Ast.Number): Ty.Type => { - return Int257(Ty.Inferred(node.loc, "numeric literal")); - }; - - const checkBoolean = (node: Ast.Boolean): Ty.Type => { - return Bool(Ty.Inferred(node.loc, "boolean literal")); - }; - - const checkUnaryExpr = (node: Ast.OpUnary): Ty.Type => { - const resultLoc = Ty.Inferred(node.loc, `result of ${node.op} operator`); - const paramLoc = Ty.Builtin(`parameter of "${node.op}" operator`); - const argType = checkExpr(node.operand); - switch (node.op) { - case "+": - case "-": - case "~": { - if (!assignTo(Int257(paramLoc), argType)) { - return Ty.TypeErrorRecovered(); - } - return Int257(resultLoc); - } - case "!": { - if (!assignTo(Bool(paramLoc), argType)) { - return Ty.TypeErrorRecovered(); - } - return Bool(resultLoc); - } - case "!!": { - // fun !!_(x: T?): T; - const tv = freshTVar(); - if (!assignTo(Maybe(tv.type, paramLoc), argType)) { - return Ty.TypeErrorRecovered(); - } - return tv.resolve(Ty.Builtin(`type argument of optional type`)); - } - } - }; - - const checkBinaryExpr = (node: Ast.OpBinary): Ty.Type => { - const resultLoc = Ty.Inferred(node.loc, `result of ${node.op} operator`); - const leftLoc = Ty.Builtin(`left parameter of "${node.op}" operator`); - const rightLoc = Ty.Builtin(`right parameter of "${node.op}" operator`); - const leftType = checkExpr(node.left); - const rightType = checkExpr(node.right); - - switch (node.op) { - case "+": - case "-": - case "*": - case "/": - case "%": - case "<<": - case ">>": - case "&": - case "|": - case "^": { - if ( - !assignTo(Int257(leftLoc), leftType) - || !assignTo(Int257(rightLoc), rightType) - ) { - return Ty.TypeErrorRecovered(); - } - return Int257(resultLoc); - } - case ">": - case "<": - case ">=": - case "<=": { - if ( - !assignTo(Int257(leftLoc), leftType) - || !assignTo(Int257(rightLoc), rightType) - ) { - return Ty.TypeErrorRecovered(); - } - return Bool(resultLoc); - } - case "!=": - case "==": { - const common = mgu(leftType, rightType, resultLoc); - if (common.kind === 'ERROR') { - return common; - } - if (supportsEquality(common)) { - return Bool(resultLoc); - } - return Ty.TypeErrorRecovered(); - } - case "&&": - case "||": { - if ( - !assignTo(Bool(leftLoc), leftType) - || !assignTo(Bool(rightLoc), rightType) - ) { - return Ty.TypeErrorRecovered(); - } - return Bool(resultLoc); - } - } - }; - - const checkTernary = (node: Ast.Conditional): Ty.Type => { - const resultLoc = Ty.Inferred(node.loc, `result of ternary operator`); - const condLoc = Ty.Builtin(`condition of ternary operator`); - const commonType = mgu( - checkExpr(node.thenBranch), - checkExpr(node.elseBranch), - resultLoc, - ); - if ( - !assignTo(Bool(condLoc), checkExpr(node.condition)) - || commonType.kind === 'ERROR' - ) { - return Ty.TypeErrorRecovered(); - } - return commonType; - }; - - const getContract = (id: Ty.TypeId): undefined | Ast.Contract => { - const contract = getType(id.text); - if (typeof contract === 'undefined') { - err.contractNotDefined()(id.loc); - return undefined; - } - if (contract.kind !== 'contract') { - err.typeNotContract()(id.loc); - return undefined; - } - return contract; - }; - - const getStruct = (id: Ty.TypeId): undefined | Ast.StructDecl | Ast.MessageDecl => { - const struct = getType(id.text); - if (typeof struct === 'undefined') { - err.structNotDefined()(id.loc); - return undefined; - } - if (struct.kind !== 'struct_decl' && struct.kind !== 'message_decl') { - err.typeNotStruct()(id.loc); - return undefined; - } - return struct; - }; - - const checkCodeOf = (node: Ast.CodeOf): Ty.Type => { - if (!getContract(node.contract)) { - return Ty.TypeErrorRecovered(); - } - return Cell(Ty.Inferred(node.loc, "return value of codeOf operator")); - }; - - const checkInitOf = (node: Ast.InitOf): Ty.Type => { - const contract = getContract(node.contract); - if (!contract) { - return Ty.TypeErrorRecovered(); - } - - const { init } = contract; - if (!init) { - err.noInit()(node.loc) - return Ty.TypeErrorRecovered(); - } - - const paramCount = init.params.length; - const argCount = node.args.length; - if (paramCount < argCount) { - err.fnArity(`Contract ${contract.name.text}`, argCount, paramCount)(node.loc); - } - - for (const [index, param] of init.params.entries()) { - const arg = node.args[index]; - // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition - if (arg) { - const children: MismatchTree[] = []; - if (!assignToAux1(param.type, checkExpr(arg), children)) { - for (const tree of children) { - // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition - err.typeMismatch(tree)(arg ? arg.loc : node.loc); - } - } - } else if (param.kind !== 'field_decl' || !param.initializer) { - err.fnArity(`Contract ${contract.name.text}`, argCount, paramCount)(node.loc); - } - } - - return StateInit(Ty.Inferred(node.loc, "result of initOf operator")); - }; - - type Substitutor = { - readonly subst: (type: Ty.Type) => Ty.Type; - readonly getArgs: () => readonly Ty.Type[]; - } - - const fillUpTypeArgs = (args: readonly Ty.Type[], params: readonly Ty.TypeId[]): readonly Ty.Type[] => [ - // cut extraneous arguments - ...args.slice(0, params.length), - // pad with missing arguments - ...new Array(Math.max(0, params.length - args.length)) - .fill(0).map(() => Ty.TypeErrorRecovered()) - ]; - const substTypeParams = ( - struct: Ast.StructDecl | Ast.MessageDecl, - node: { - readonly typeArgs: readonly Ty.Type[], - readonly loc: Ty.Loc, - }, - ): Substitutor => { - if (struct.kind === 'message_decl') { - if (node.typeArgs.length > 0) { - err.typeArity(struct.name.text, node.typeArgs.length, 0)(node.loc); - } - // messages do not have type parameters - return { - subst: (type) => type, - getArgs: () => [], - }; - } - if (struct.typeParams.length !== 0 && node.typeArgs.length === 0) { - // struct F { x: Int; } - // let a = F { x: 1 }; - const vars = struct.typeParams.map(param => ({ - ...freshTVar(), - name: param.text, - })); - return { - subst: (type) => { - // substitute type variables - return substParams( - type, - struct.typeParams, - vars.map(v => v.type), - ); - }, - getArgs: () => vars.map(v => { - // resolve type variables after all the fields - // are assigned - return v.resolve(Ty.Inferred( - node.loc, - `inferred type parameter ${v.name}`, - )); - }), - }; - } - if (struct.typeParams.length !== node.typeArgs.length) { - err.typeArity(struct.name.text, node.typeArgs.length, 0)(node.loc); - } - // struct F { x: Int; } - // let a = F { x: 1 }; - return { - subst: (type: Ty.Type) => { - // substitute passed args - return substParams( - type, - struct.typeParams, - node.typeArgs, - ); - }, - getArgs: () => fillUpTypeArgs(node.typeArgs, struct.typeParams), - }; - }; - const checkStructInstance = (node: Ast.StructInstance): Ty.Type => { - const struct = getStruct(node.type); - if (!struct) { - return Ty.TypeErrorRecovered(); - } - const { subst, getArgs } = substTypeParams(struct, node); - const defined: Set = new Set(); - for (const { field: { text, loc }, initializer } of node.args) { - if (defined.has(text)) { - err.duplicateField()(loc); - } - const field = struct.fields.find(field => field.name.text === text); - if (field) { - assignTo(subst(field.type), checkExpr(initializer)); - } else { - err.fieldNotDefined()(loc); - } - } - for (const field of struct.fields) { - if (!defined.has(field.name.text) && !field.initializer) { - assignTo(field.type, Null(Ty.Inferred(node.loc, `omitted field "${field.name.text}"`))); - } - } - const loc = Ty.Inferred(node.loc, "struct literal"); - return Ty.TypeCons( - Ty.TypeId(node.type.text, loc), - getArgs(), - loc, - ); - }; - - const checkStaticMethodCall = (node: Ast.StaticMethodCall): Ty.Type => { - const struct = getStruct(node.self); - if (!struct) { - return Ty.TypeErrorRecovered(); - } - const name = node.function.text; - if (name !== "fromSlice" && name !== "fromCell") { - err.staticMethodNotDefined()(node.function.loc); - return Ty.TypeErrorRecovered(); - } - const paramLoc = Ty.Builtin(`parameter of .${name}()`); - const [arg] = node.args; - if (node.args.length !== 1 || !arg) { - err.fnArity(name, node.args.length, 1)(node.loc); - } else if (name === 'fromSlice') { - // fromSlice: Struct.(Slice) -> struct - assignTo(Slice(paramLoc), checkExpr(arg)); - } else if (name === 'fromCell') { - // fromCell: Struct.(Cell) -> struct - assignTo(Cell(paramLoc), checkExpr(arg)); - } - // Message.opcode() - if (struct.kind === 'struct_decl' && struct.typeParams.length !== node.typeArgs.length) { - err.typeArity(struct.name.text, node.typeArgs.length, 0)(node.loc); - } - const resultLoc = Ty.Inferred(node.loc, `result of .${name}()`); - return Ty.TypeCons( - Ty.TypeId(node.self.text, resultLoc), - struct.kind === 'struct_decl' - ? fillUpTypeArgs(node.typeArgs, struct.typeParams) - : [], - resultLoc, - ); - }; - - const checkFunctionCall = (node: Ast.StaticCall): Ty.Type => { - // dump: checkDump, // (T) -> void - - // ton: checkTon, // (String) -> Int, строка должна быть конст - // require: checkRequire, // (Bool, String) -> void - // address: checkAddress, // (String) -> Address - // cell: checkCell, // (String) -> Cell - // dumpStack: checkDumpStack, // () -> void - // emptyMap: checkEmptyMap, // () -> Null - // sha256: checkSha256, // (String) -> Int - // sha256: checkSha256, // (Slice) -> Int - // slice: checkSlice, // (String) -> Slice - // rawSlice: checkRawSlice, // (String) -> Slice - // ascii: checkAscii, // (String) -> Int - // crc32: checkCrc32, // (String) -> Int - const resultLoc = Ty.Inferred(node.loc, `result of ${node.op} operator`); - const leftLoc = Ty.Builtin(`left parameter of "${node.op}" operator`); - const rightLoc = Ty.Builtin(`right parameter of "${node.op}" operator`); - const leftType = checkExpr(node.left); - const rightType = checkExpr(node.right); - if ( - !assignTo(Int257(leftLoc), leftType) - || !assignTo(Int257(rightLoc), rightType) - ) { - return Ty.TypeErrorRecovered(); - } - return Int257(resultLoc); - }; - - const checkMethodCall = (node: Ast.MethodCall): Ty.Type => { - const self = checkExpr(node.self); - switch (self.kind) { - case "cons_type": { - // struct - // extends fun toCell(self: Struct): Cell - // extends fun toSlice(self: Struct): Slice - - // bounced<> не переносит методы - - // null - // Maybe<>, map<>, Null; может быть >1 кандидата - return; - } - case "map_type": { - // extends fun set(self: map, key: K, value: V) -> void - // extends fun get(self: map, key: K) -> Maybe - // extends fun del(self: map, key: K) -> Bool - // extends fun asCell(self: map, ) -> Maybe - // extends fun isEmpty(self: map, ) -> Bool - // extends fun exists(self: map, key: K) -> Bool - // extends fun deepEquals(self: map, other: map) -> Bool // mgu - // extends fun replace(self: map, key: K, value: V) -> Bool - // extends fun replaceGet(self: map, key: K, value: V) -> map - } - case "ERROR": - case "type_var": { - return; - } - case "TyInt": - case "TySlice": - case "TyCell": - case "TyBuilder": - case "tuple_type": - case "unit_type": - case "tensor_type": - } - }; - - const checkField = (node: Ast.FieldAccess): Ty.Type => { - // resolveFieldAccess - // только struct или Maybe или bounced - // обрезать bounced поля (см. partialFieldCount) - // ищем в полях и константах - }; - - const checkVariable = (node: Ast.Var): Ty.Type => { - // 1. константы - // 3. переменные - // 4. кастомная ошибка, когда foo, но нужен self.foo - }; - - const checkTuple = (node: Ast.Tuple): Ty.Type => { - // - }; - - const checkTensor = (node: Ast.Tensor): Ty.Type => { - // - }; - - const checkMapLiteral = (node: Ast.MapLiteral): Ty.Type => { - // - }; - - const checkSetLiteral = (node: Ast.SetLiteral): Ty.Type => { - // - }; - - const checkExpr = makeVisitor()({ - null: checkNull, - unit: checkUnit, - string: checkString, - number: checkNumber, - boolean: checkBoolean, - op_unary: checkUnaryExpr, - op_binary: checkBinaryExpr, - conditional: checkTernary, - init_of: checkInitOf, - code_of: checkCodeOf, - struct_instance: checkStructInstance, - static_call: checkFunctionCall, - method_call: checkMethodCall, - field_access: checkField, - var: checkVariable, - tuple: checkTuple, - tensor: checkTensor, - map_literal: checkMapLiteral, - set_literal: checkSetLiteral, - static_method_call: checkStaticMethodCall, - }); - return { assignTo, freshTVar, @@ -685,14 +200,6 @@ const getExprChecker = ( }; }; -const supportsEquality = (common: Ty.Type): boolean => { - return common.kind === 'cons_type' && common.name.text === 'Maybe' && common.typeArgs.every(arg => supportsEquality(arg)) - || common.kind === 'map_type' - || common.kind === 'cons_type' && [ - "Int", "Bool", "Address", "Cell", "Slice", "String" - ].includes(common.name.text) -}; - const substParams = (into: Ty.Type, params: readonly Ty.TypeId[], args: readonly Ty.Type[]) => { return zip(params, args) .reduce((type, [param, arg]) => { @@ -735,378 +242,3 @@ const substParam = (into: Ty.Type, param: string, value: Ty.Type): Ty.Type => { return rec(into); }; - -// import { throwInternal } from "@/error/errors"; -// import * as Ast from "@/next/ast"; -// import * as E from "@/next/types/errors"; -// import type { Registry } from "@/next/types/merger"; -// import type { TypeEntry } from "@/next/types/typecheck"; - -// export const decodeType = ( -// userTypes: Registry, -// typeParams: readonly Ast.TypeId[], -// type: Ast.Type, -// ): E.WithLog => { -// function* recN( -// types: readonly Ast.Type[], -// ): E.WithLog { -// const results: Ast.Type[] = []; -// for (const type of types) { -// const result = yield* rec(type); -// if (result) { -// results.push(result); -// } else { -// return undefined -// } -// } -// return results; -// } - -// function* rec( -// type: Ast.Type, -// ): E.WithLog { -// switch (type.kind) { -// case "unit_type": -// case "TyInt": -// case "TySlice": -// case "TyCell": -// case "TyBuilder": -// case "TypeVoid": -// case "TypeNull": -// case "TypeBool": -// case "TypeAddress": -// case "TypeString": -// case "TypeStringBuilder": -// case "TypeParam": { -// return type; -// } -// case "tuple_type": { -// const result = yield* recN(type.typeArgs); -// return result && Ast.TypeTuple(result, type.loc); -// } -// case "tensor_type": { -// const result = yield* recN(type.typeArgs); -// return result && Ast.TypeTensor(result, type.loc); -// } -// case "map_type": { -// const key = yield* rec(type.key); -// const value = yield* rec(type.value); -// if (!key || !value) { -// return undefined; -// } -// return Ast.TypeMap(key, value, type.loc); -// } -// case "TypeBounced": { -// const child = yield* rec(type.type); -// if (!child) { -// return undefined; -// } -// return Ast.TypeBounced(child, type.loc); -// } -// case "TypeMaybe": { -// const child = yield* rec(type.type); -// if (!child) { -// return undefined; -// } -// return Ast.TypeMaybe(child, type.loc); -// } -// case "TypeAlias": { -// return throwInternal("Alias references are never generated in parser"); -// } -// case "cons_type": { -// const name = type.name.text; -// const arity = type.typeArgs.length; - -// const args = yield* recN(type.typeArgs); - -// const param = typeParams.find(p => p.text); -// if (param) { -// if (!(yield* matchArity(name, arity, 0, type.loc))) { -// return undefined; -// } -// return Ast.TypeParam( -// type.name, -// type.loc, -// ); -// } - -// if (!args) { -// return undefined; -// } - -// const typeEntry = userTypes.get(name); -// if (typeEntry) { -// if (!(yield* matchArity( -// name, -// arity, -// typeEntry.value.arity, -// type.loc, -// ))) { -// return undefined; -// } -// const decl = typeEntry.value.type; -// switch (decl.kind) { -// case "FlatAlias": { -// return ; -// } -// case "alias_decl": { -// return; -// } -// case "FlatContract": -// case "FlatTrait": -// case "struct_decl": -// case "message_decl": -// case "union_decl": -// case "contract": -// case "trait": { -// return Ast.TypeCons(type.name, args, type.loc); -// } -// } -// } - -// yield ETypeNotFound(name, type.loc); -// return undefined; -// } -// } -// } - -// return rec(type); -// } - -// export const ETypeNotFound = ( -// name: string, -// loc: Ast.Range, -// ): E.TcError => ({ -// loc, -// descr: [ -// E.TEText(`Type "${name}" is not defined`), -// ], -// }); -// export const EContractTraitType = ( -// kind: string, -// name: string, -// loc: Ast.Range, -// ): E.TcError => ({ -// loc, -// descr: [ -// E.TEText(`Cannot use ${kind} ${name} as a type`), -// ], -// }); - - -// export function* matchArity( -// name: string, -// got: number, -// expected: number, -// loc: Ast.Range, -// ): E.WithLog { -// const result = got === expected; -// if (!result) { -// yield EArity(name, expected, got, loc); -// } -// return result; -// } -// export const EArity = ( -// name: string, -// expected: number, -// got: number, -// loc: Ast.Range, -// ): E.TcError => ({ -// loc, -// descr: [ -// E.TEText(`Type "${name}" is expected to have ${expected} type arguments, got ${got}`), -// ], -// }); - -// import * as V from "@/next/types/via"; -// import * as E from "@/next/types/errors"; -// import type * as Ast from "@/next/ast"; -// import type { TactImport, TactSource } from "@/next/imports/source"; -// import type { FlatDecl, Schema } from "@/next/types/flat"; - -// export type Def = { -// // the definition -// readonly value: T; -// // where it was defined -// readonly via: V.ViaUser; -// } -// export const Def = (value: T, via: V.ViaUser): Def => ({ value, via }); -// export const importDef = (importedBy: TactImport, { value, via }: Def): Def => Def(value, V.ViaImport(importedBy, via)); - -// export type Registry = Map>; - -// export type StructMethod = { -// readonly mutates: boolean; -// readonly fun: Ast.Function; -// } - -// export type TypeMap = readonly (readonly [Schema, Def])[] - -// export type ExtRegistry = Map - -// export type Scope = { -// readonly types: Registry; -// readonly functions: Registry; -// readonly constants: Registry; -// readonly extensions: ExtRegistry; -// } - -// export type SourceCheckResult = { -// // import that lead to reading this file -// readonly importedBy: TactImport; -// // scopes that were computed from this file -// readonly globals: Scope; -// } - -// export function* mergeExt( -// results: readonly SourceCheckResult[], -// source: TactSource, -// items: Ast.Extension[], -// builtins: ReadonlyMap, -// ): E.WithLog { -// const EMethodOverlap = ( -// name: string, -// prev: V.Via, -// next: V.ViaUser, -// ): E.TcError => ({ -// loc: E.viaToRange(next), -// descr: [ -// E.TEText(`Method "${name}" overlaps previously defined method`), -// E.TEVia(prev), -// ], -// }); - -// const imported: ExtRegistry[] = results.map(({ globals, importedBy }) => { -// const exts = globals.extensions; -// return new Map(exts.entries().map(([k, v]) => { -// return [k, v.map(([k, v]) => [k, { -// value: v.value, -// via: V.ViaImport(importedBy, v.via), -// }])]; -// })); -// }); - -// const local: ExtRegistry[] = []; -// for (const item of items) { -// const fun = item.method.fun; -// const schema = { -// typeArgs: fun.typeParams, -// type: item.selfType, -// }; -// const def = { -// value: item.method, -// via: V.ViaOrigin(fun.loc, source), -// }; -// const { canExtend } = unifier.withParams(fun.typeParams); -// if (yield* canExtend(item.selfType)) { -// local.push(new Map([[fun.name.text, [[schema, def]]]])); -// } -// } - -// const all = [...imported, ...local]; - -// const prev: Map])[]> = new Map(); -// for (const next of all) { -// for (const [name, nextMap] of next) { -// const prevMap = [...prev.get(name) ?? []]; -// const builtin = builtins.get(name) ?? []; -// for (const [nextSchema, nextDef] of nextMap) { -// // defined in compiler -// const prevBuiltin = builtin.find(prevSchema => !unifier.areOrdered( -// prevSchema, nextSchema -// )); -// if (prevBuiltin) { -// yield EMethodOverlap(name, V.ViaBuiltin(), nextDef.via); -// continue; -// } -// const prevEntry = prevMap.find(([prevSchema]) => !unifier.areOrdered( -// prevSchema, nextSchema -// )); -// // not defined yet; define it now -// if (!prevEntry) { -// prevMap.push([nextSchema, nextDef]); -// continue; -// } -// const [, prevDef] = prevEntry; -// // already defined, and it's not a diamond situation -// if (prevDef.via.source !== nextDef.via.source) { -// yield EMethodOverlap(name, prevDef.via, nextDef.via); -// } -// } -// prev.set(name, prevMap); -// } -// } -// return prev; -// } - -// export function* merge( -// results: readonly SourceCheckResult[], -// source: TactSource, -// kind: string, -// get1: (s: Scope) => Registry, -// items: T[], -// builtin: Map, -// ): E.WithLog> { -// const imported = results.map(({ globals, importedBy }) => ( -// mapRegVia(get1(globals), importedBy) -// )); -// const local = items.map((item) => createRef( -// item.name.text, -// item, -// V.ViaOrigin(item.loc, source), -// )); -// return yield* concatReg( -// builtin, -// kind, -// [...imported, ...local], -// ) -// } - -// export const createRef = (name: string, value: V, via: V.ViaUser): Registry => { -// return new Map([[name, { value, via }]]); -// }; - -// export const mapRegVia = (fns: Registry, importedBy: TactImport): Registry => { -// return new Map(fns.entries().map(([k, v]) => { -// return [k, { -// value: v.value, -// via: V.ViaImport(importedBy, v.via), -// }]; -// })); -// }; - -// export function* concatReg( -// builtins: Map, -// kind: string, -// all: readonly Registry[] -// ): E.WithLog> { -// const ERedefine = (kind: string, name: string, prev: V.Via, next: V.ViaUser): E.TcError => ({ -// loc: E.viaToRange(next), -// descr: [ -// E.TEText(`There already is a ${kind} "${name}" from`), -// E.TEVia(prev), -// ], -// }); - -// const prev: Map> = new Map(); -// for (const next of all) { -// for (const [name, nextItem] of next) { -// const prevItem = prev.get(name); -// // defined in compiler -// if (builtins.has(name)) { -// yield ERedefine(kind, name, V.ViaBuiltin(), nextItem.via); -// continue; -// } -// // not defined yet; define it now -// if (typeof prevItem === 'undefined') { -// prev.set(name, nextItem); -// continue; -// } -// // already defined, and it's not a diamond situation -// if (prevItem.via.source !== nextItem.via.source) { -// yield ERedefine(kind, name, prevItem.via, nextItem.via); -// } -// } -// } -// return prev; -// } diff --git a/src/next/types/body.ts b/src/next/types/body.ts index e5a6e95b8a..e37d3d9e75 100644 --- a/src/next/types/body.ts +++ b/src/next/types/body.ts @@ -150,7 +150,8 @@ function* getTypeTupleSize( } switch (decl.decl.kind) { case "contract": { - return decl.decl.content.fields.order.length; + const content = yield* decl.decl.content(); + return content.fieldish.order.length; } case "struct": case "message": { diff --git a/src/next/types/builtins.ts b/src/next/types/builtins.ts index ed06c35167..5cb3b5b8db 100644 --- a/src/next/types/builtins.ts +++ b/src/next/types/builtins.ts @@ -66,7 +66,7 @@ export const StringBuilder = Ast.TypeStringBuilder(r); export const MapType = (k: Ast.DecodedType, v: Ast.DecodedType) => Ast.DTypeMap(k, v, r); export const Maybe = (t: Ast.DecodedType) => Ast.DTypeMaybe(t, r) export const Unit = Ast.TypeUnit(r); -export const StateInit = Ast.TypeCons(Ast.TypeId("StateInit", r), [], r); +export const StateInit = Ast.DTypeRef(Ast.TypeId("StateInit", r), [], r); export const builtinTypes = new Map([ "Int", "Slice", "Cell", "Builder", "Void", "Null", "Bool", @@ -109,8 +109,9 @@ export const builtinFunctions: Map = new Map([ Fn("ascii", { str: String }, Int), // crc32(str: String): Int Fn("crc32", { str: String }, Int), - // sha256(data: Slice): Int - Fn("sha256", { str: Slice }, Int), + // don't forget about our best friend, sha256 + // it is the only overloaded function in the language + // sha256(data: Slice | String): Int ]); export const builtinMethods: Map = new Map([ diff --git a/src/next/types/constant-def.ts b/src/next/types/constant-def.ts index 1f6aba6f3b..fea0694cbb 100644 --- a/src/next/types/constant-def.ts +++ b/src/next/types/constant-def.ts @@ -1,34 +1,52 @@ import * as Ast from "@/next/ast"; import { assignType, decodeTypeLazy } from "@/next/types/type"; import { decodeExpr } from "@/next/types/expression"; +import { evalExpr } from "@/next/types/expr-eval"; export function decodeConstantDef( typeParams: Ast.TypeParams, - init: Ast.ConstantDef, + { type, initializer }: Ast.ConstantDef, scopeRef: () => Ast.Scope, -): [Ast.Lazy, Ast.Lazy] { - const { type, initializer } = init; - - const ascribedType = type - ? decodeTypeLazy(typeParams, type, scopeRef) - : undefined; - - const lazyExpr = decodeExpr(initializer, scopeRef); - - const decodedType = Ast.Lazy(function* () { - const expr = yield* lazyExpr(); - const computed = yield* expr.computedType(); - if (!ascribedType) { - return computed; - } - const ascribed = yield* ascribedType(); - yield* assignType( - ascribed, - computed, - scopeRef, - ); - return ascribed; - }); - - return [decodedType, lazyExpr]; -} \ No newline at end of file + selfType: undefined | Ast.SelfType, +): [Ast.Lazy, Ast.Lazy] { + if (type) { + // if there is an ascribed type, that's the one we return + const ascribedType = decodeTypeLazy(typeParams, type, scopeRef); + // also we have to check that it's the expected type prior to + // evaluating the expression + const lazyExpr = Ast.Lazy(function* () { + const expr = yield* decodeExpr( + typeParams, + initializer, + scopeRef, + selfType, + new Map(), + ); + const computed = expr.computedType; + const ascribed = yield* ascribedType(); + yield* assignType( ascribed, computed, scopeRef); + return yield* evalExpr(expr, scopeRef); + }); + return [ascribedType, lazyExpr]; + } else { + // first we decode expression + const expr = Ast.Lazy(function* () { + return yield* decodeExpr( + typeParams, + initializer, + scopeRef, + selfType, + new Map(), + ); + }); + // then we evaluate it without any other checks + const lazyExpr = Ast.Lazy(function* () { + return yield* evalExpr(yield* expr(), scopeRef); + }); + // resulting type is whatever the type expression has + const computedType = Ast.Lazy(function* () { + return (yield* expr()).computedType; + }); + return [computedType, lazyExpr]; + } +} diff --git a/src/next/types/constants.ts b/src/next/types/constants.ts index 6650ff8f5c..bbd8e9a3bf 100644 --- a/src/next/types/constants.ts +++ b/src/next/types/constants.ts @@ -48,11 +48,16 @@ function* decodeConstant( if (init.kind === "constant_decl") { yield ETopLevelDecl(loc); const type = function*() { return Ast.DTypeRecover(); }; - const expr = function*() { return Ast.DNull(type, Ast.Builtin()); }; + const expr = function*() { return Ast.VNumber(0n, constant.loc); }; return Ast.ConstSig(expr, type); } else { const typeParams = Ast.TypeParams([], new Set()); - const [type, expr] = decodeConstantDef(typeParams, init, scopeRef); + const [type, expr] = decodeConstantDef( + typeParams, + init, + scopeRef, + undefined, + ); return Ast.ConstSig(expr, type); } } diff --git a/src/next/types/contract.ts b/src/next/types/contract.ts index 0848495eda..40ed5f6597 100644 --- a/src/next/types/contract.ts +++ b/src/next/types/contract.ts @@ -6,6 +6,10 @@ import { throwInternal } from "@/error/errors"; import { getFieldishGeneral } from "@/next/types/fields"; import { getInheritedTraits } from "@/next/types/traits-scope"; import { getMethodsGeneral } from "@/next/types/methods"; +import { getReceivers } from "@/next/types/receivers"; +import { decodeDealiasTypeLazy, decodeTypeLazy } from "@/next/types/type"; +import { decodeParams } from "@/next/types/type-fn"; +import { decodeStatements } from "@/next/types/statements"; export function* decodeContract( contract: Ast.Contract, @@ -14,8 +18,15 @@ export function* decodeContract( const { name, attributes, declarations, init } = contract; const { constants, fields, methods, receivers } = declarations; - // delayed until we get all traits - const content = Ast.Lazy(function* () { + // here we have a strange loop + // to get fields in contentLazy we need contract parameters from initLazy + // to compute fields for empty init, we need to know contentLazy + // to check init body in initLazy we have to know `self` from contentLazy + + const decodedInit = yield* decodeInit(init, () => contentLazy(), scopeRef); + + // delayed until we get all traits and init + const contentLazy: Ast.Lazy = Ast.Lazy(function* () { const traits = yield* getInheritedTraits( contract.traits, scopeRef, @@ -24,8 +35,9 @@ export function* decodeContract( // const contentRef = () => content; const content: Ast.ContractContent = { fieldish: yield* getFieldishFromContract( - name.text, + name, traits, + decodedInit, constants, fields, scopeRef, @@ -36,18 +48,123 @@ export function* decodeContract( methods, scopeRef, ), - bounce, - external, - internal, + receivers: yield* getReceivers( + name, + traits, + receivers, + scopeRef, + ), }; return content; }); - const decodedInit = decodeInit(init, fields, scopeRef); + return Ast.ContractSig(attributes, decodedInit, contentLazy); +} + +function* decodeInit( + init: Ast.Init | undefined, + contentLazy: Ast.Lazy, + scopeRef: () => Ast.Scope, +): E.WithLog { + const typeParams = Ast.TypeParams([], new Set()); + if (!init) { + // no init + const lazyInit = Ast.Lazy(function* () { + const order: string[] = []; + const map: Map> = new Map(); + const { fieldish } = (yield* contentLazy()); + for (const name of fieldish.order) { + const f = fieldish.map.get(name); + if (!f) { + return throwInternal("Missing field"); + } + if (f.decl.kind === 'field') { + const init = f.decl.init; + if (init) { + order.push(name); + map.set(name, init); + } else { + yield ENoInitializerEmpty(f.via.defLoc); + } + } + } + return Ast.Ordered(order, map); + }); + return Ast.InitEmpty(lazyInit); + } else if (init.kind === 'init_params') { + const order: string[] = []; + const paramMap: Map = new Map(); + for (const param of init.params) { + const name = param.name.text; + const prev = paramMap.get(name); + if (prev) { + yield EDuplicateParam(name, prev.loc, param.loc); + } else { + order.push(name); + paramMap.set(name, param); + } + } + + const map: Map = new Map(); + for (const [name, param] of paramMap) { + const decoded = decodeTypeLazy(typeParams, param.type, scopeRef) + if (!param.initializer) { + yield ENoInitializerParams(param.loc); + } + // TODO: support Foo { } syntax for contracts + // const lazyExpr = Ast.Lazy(function* () { + // const expr = yield* decodeExpr(param.initializer, scopeRef)(); + // const computed = expr.computedType; + // const ascribed = yield* decoded(); + // yield* assignType( ascribed, computed, scopeRef); + // return yield* evalExpr(expr, scopeRef); + // }); + map.set(name, Ast.InitParam(decoded, undefined, param.loc)); + } + return Ast.InitSimple(Ast.Ordered(order, map), init.loc); + } else { + const { params, statements } = init; + + const decodedParams = yield* decodeParams((type) => { + return decodeDealiasTypeLazy(typeParams, type, scopeRef); + }, params); + + const body = decodeStatements(statements, scopeRef); - return Ast.ContractSig(attributes, decodedInit, content); + return Ast.InitFn(decodedParams, body); + } } +const EDuplicateParam = ( + name: string, + prev: Ast.Loc, + next: Ast.Loc, +): E.TcError => ({ + loc: next, + descr: [ + E.TEText(`Contract parameter ${name} was already defined`), + E.TEText(`New definition:`), + E.TECode(next), + E.TEText(`Previously defined at:`), + E.TECode(prev), + ], +}); +const ENoInitializerParams = ( + loc: Ast.Loc, +): E.TcError => ({ + loc, + descr: [ + E.TEText(`Contract parameters cannot have an initializer`), + ], +}); +const ENoInitializerEmpty = ( + loc: Ast.Loc, +): E.TcError => ({ + loc, + descr: [ + E.TEText(`When there is no init() or contract parameters, all fields must have an initializer`), + ], +}); function* getMethodsFromContract( typeName: Ast.TypeId, @@ -76,16 +193,17 @@ function* getMethodsFromContract( } function* getFieldishFromContract( - typeName: string, + typeName: Ast.TypeId, traits: readonly Ast.Decl[], + init: Ast.InitSig, constants: readonly Ast.FieldConstant[], fields: readonly Ast.FieldDecl[], scopeRef: () => Ast.Scope, -): E.WithLog>>>> { +): E.WithLog>>>> { const res = yield* getFieldishGeneral(typeName, traits, constants, fields, scopeRef); const order: string[] = []; - const map: Map>>> = new Map(); + const map: Map>>> = new Map(); for (const name of res.order) { const field = res.map.get(name); if (!field) { @@ -104,9 +222,31 @@ function* getFieldishFromContract( } } - return { order, map }; + if (init.kind === 'simple') { + const map: Map>>> = new Map(); + if (order.length !== 0) { + yield EFieldsTwice(init.loc); + } + for (const [name, param] of init.fill.map) { + order.push(name); + map.set(name, Ast.DeclMem( + Ast.InhFieldSig(param.type, param.init), + Ast.ViaMemberOrigin(typeName.text, param.loc), + )); + } + return { order: init.fill.order, map }; + } else { + return { order, map }; + } } - +const EFieldsTwice = ( + loc: Ast.Loc, +): E.TcError => ({ + loc, + descr: [ + E.TEText(`Cannot define other fields when using contract parameters`), + ], +}); const EAbstract = ( kind: string, name: string, diff --git a/src/next/types/expression.ts b/src/next/types/expression.ts index 81750a0ee8..b66d00367f 100644 --- a/src/next/types/expression.ts +++ b/src/next/types/expression.ts @@ -1,12 +1,504 @@ +/* eslint-disable require-yield */ +import { throwInternal } from "@/error/errors"; import * as Ast from "@/next/ast"; +import { Bool, builtinBinary, builtinFunctions, getStaticBuiltin, StateInit } from "@/next/types/builtins"; import * as E from "@/next/types/errors"; -import type { TactImport, TactSource } from "@/next/imports/source"; -import { builtinFunctions } from "@/next/types/builtins"; -import { decodeFnType } from "@/next/types/type-fn"; +import { assignType, decodeTypeLazy, decodeTypeMap, instantiateStruct, mgu } from "@/next/types/type"; +import { getCallResult, lookupFunction, lookupMethod } from "@/next/types/type-fn"; +import { convertValueToExpr } from "@/next/types/value"; -export function* decodeExpr( +type Decode = (node: T, ctx: Context) => E.WithLog +type Context = { + readonly scopeRef: () => Ast.Scope; + readonly selfType: Ast.SelfType | undefined; + readonly typeParams: Ast.TypeParams; + // TODO: must already be deshadowed + readonly localScopeRef: ReadonlyMap; +} + +export function decodeExpr( + typeParams: Ast.TypeParams, node: Ast.Expression, scopeRef: () => Ast.Scope, -): Ast.Lazy { + selfType: Ast.SelfType | undefined, + localScopeRef: ReadonlyMap, +): E.WithLog { + return rec(node, { + typeParams, + scopeRef, + selfType, + localScopeRef, + }); +} + +const rec: Decode = (node, ctx) => { + switch (node.kind) { + case "null": return decodeNullCons(node, ctx); + case "unit": return decodeUnitCons(node, ctx); + case "string": return decodeStringCons(node, ctx); + case "number": return decodeNumberCons(node, ctx); + case "boolean": return decodeBooleanCons(node, ctx); + case "tuple": return decodeTupleCons(node, ctx); + case "tensor": return decodeTensorCons(node, ctx); + case "map_literal": return decodeMapCons(node, ctx); + case "set_literal": return decodeSetCons(node, ctx); + case "struct_instance": return decodeStructCons(node, ctx); + + case "var": return decodeVar(node, ctx); + case "op_binary": return decodeBinary(node, ctx); + case "op_unary": return decodeUnary(node, ctx); + case "conditional": return decodeTernary(node, ctx); + case "method_call": return decodeMethodCall(node, ctx); + case "static_call": return decodeFunctionCall(node, ctx); + case "static_method_call": return decodeStaticMethodCall(node, ctx); + case "field_access": return decodeFieldAccess(node, ctx); + case "init_of": return decodeInitOf(node, ctx); + case "code_of": return decodeCodeOf(node, ctx); + } +} + +const decodeNullCons: Decode = function* (node) { + return Ast.DNull(Ast.TypeNull(node.loc), node.loc); +} +const decodeUnitCons: Decode = function* (node) { + return Ast.DUnit(Ast.TypeUnit(node.loc), node.loc); +} +const decodeStringCons: Decode = function* (node) { + return Ast.DString(node.value, Ast.TypeString(node.loc), node.loc); +} +const decodeNumberCons: Decode = function* (node) { + return Ast.DNumber(node.base, node.value, Ast.TypeInt(Ast.IFInt('signed', 257, node.loc), node.loc), node.loc); +} +const decodeBooleanCons: Decode = function* (node) { + return Ast.DBoolean(node.value, Ast.TypeBool(node.loc), node.loc); +} +const decodeTupleCons: Decode = function* (node, ctx) { + const children = yield* E.mapLog(node.children, child => rec(child, ctx)); + const args = children.map(child => child.computedType); + return Ast.DTuple(children, Ast.DTypeTuple(args, node.loc), node.loc); +} +const decodeTensorCons: Decode = function* (node, ctx) { + const children = yield* E.mapLog(node.children, child => rec(child, ctx)); + const args = children.map(child => child.computedType); + return Ast.DTensor(children, Ast.DTypeTensor(args, node.loc), node.loc); +} +const decodeMapCons: Decode = function* (node, ctx) { + const ascribed = yield* decodeTypeMap(ctx.typeParams, node.type, ctx.scopeRef); + const fields = yield* E.mapLog(node.fields, function* (field) { + const key = yield* rec(field.key, ctx); + yield* assignType(ascribed.key, key.computedType, ctx.scopeRef); + const value = yield* rec(field.value, ctx); + yield* assignType(ascribed.value, value.computedType, ctx.scopeRef); + return Ast.DMapField(key, value); + }); + return Ast.DMapLiteral(ascribed, fields, node.loc); +} +const decodeSetCons: Decode = function* () { + return throwInternal("Set literals must have been declined before"); +} +const decodeStructCons: Decode = function* (node, ctx) { + const typeArgs = yield* E.mapLog(node.typeArgs, function* (arg) { + return yield* decodeTypeLazy(ctx.typeParams, arg, ctx.scopeRef)(); + }); + const instance = yield* instantiateStruct( + node.type, + typeArgs, + ctx.typeParams, + ctx.scopeRef, + ); + const fields = yield* checkFields( + instance?.fields, + node.args, + node.loc, + ctx, + ); + return Ast.DStructInstance( + fields, + instance?.type ?? Ast.DTypeRecover(), + node.loc + ); +} +function* checkFields( + typeFields: Ast.Ordered | undefined, + args: readonly Ast.StructFieldInitializer[], + loc: Ast.Loc, + ctx: Context, +) { + const map: Map = new Map(); + for (const arg of args) { + const fieldName = arg.field.text; + + const prev = map.get(fieldName); + if (prev) { + yield EDuplicateField(fieldName, prev.loc, arg.loc); + continue; + } + const expr = yield* rec(arg.initializer, ctx); + + if (typeFields) { + const typeField = typeFields.map.get(fieldName); + if (typeField) { + yield* assignType( + yield* typeField.type(), + expr.computedType, + ctx.scopeRef, + ); + } else { + yield ENoSuchField(fieldName, arg.loc); + } + } + + map.set(fieldName, expr); + } + + if (typeFields) { + const result: Map = new Map(); + for (const fieldName of typeFields.order) { + const field = typeFields.map.get(fieldName); + if (!field) { + return throwInternal("Ordered<>: lost fields") + } + const fieldInst = map.get(fieldName); + if (fieldInst) { + result.set(fieldName, fieldInst); + } else if (field.init) { + const inst = convertValueToExpr(yield* field.init()); + result.set(fieldName, inst); + } else { + yield EMissingField(fieldName, loc); + result.set(fieldName, Ast.DNull( + Ast.TypeNull(loc), + loc, + )); + } + } + return Ast.Ordered(typeFields.order, result) + } else { + return Ast.Ordered([...map.keys()], map) + } +} +const EMissingField = (name: string, prev: Ast.Loc): E.TcError => ({ + loc: prev, + descr: [ + E.TEText(`Value for field "${name}" is missing`), + E.TECode(prev), + ], +}); +const ENoSuchField = (name: string, next: Ast.Loc): E.TcError => ({ + loc: next, + descr: [ + E.TEText(`There is no field "${name}"`), + E.TECode(next), + ], +}); +const EDuplicateField = (name: string, prev: Ast.Loc, next: Ast.Loc): E.TcError => ({ + loc: prev, + descr: [ + E.TEText(`Duplicate field "${name}"`), + E.TEText(`Defined at:`), + E.TECode(next), + E.TEText(`Previously defined at:`), + E.TECode(prev), + ], +}); +const decodeVar: Decode = function* (node, ctx) { + if (node.name !== 'self') { + const type = yield* lookupVar(node.name, node.loc, ctx); + return Ast.DVar(node.name, type, node.loc); + } + if (ctx.selfType) { + return Ast.DSelf(ctx.selfType, node.loc); + } + yield ENoSelf(node.loc); + return Ast.DVar(node.name, Ast.TypeNull(node.loc), node.loc); +}; +const ENoSelf = (loc: Ast.Loc): E.TcError => ({ + loc, + descr: [ + E.TEText(`"self" is not allowed here`), + ], +}); +function* lookupVar( + name: string, + loc: Ast.Loc, + ctx: Context, +): E.WithLog { + const local = ctx.localScopeRef.get(name); + if (local) { + return local; + } + const global = ctx.scopeRef().constants.get(name); + if (global) { + return yield* global.decl.type(); + } + yield EUndefined(name, loc); + return Ast.DTypeRecover(); +} +const EUndefined = (name: string, loc: Ast.Loc): E.TcError => ({ + loc, + descr: [ + E.TEText(`Variable "${name}" not defined`), + ], +}); +const decodeBinary: Decode = function* (node, ctx) { + const left = yield* rec(node.left, ctx); + const right = yield* rec(node.right, ctx); + const fnType = builtinBinary.get(node.op); + if (!fnType) { + return throwInternal("Builtin operator is not in the map"); + } + const { returnType, typeArgs } = yield* getCallResult( + fnType, + [left.computedType, right.computedType], + ); + if (node.op === '==' || node.op === '!=') { + const typeArg = typeArgs.get("T"); + if (!typeArg) { + return throwInternal("getCallResult produced incorrect substitution"); + } + if (typeArg.kind !== 'recover' && !supportsEquality(typeArg)) { + yield ENoEquality(node.loc); + } + } + return Ast.DOpBinary(node.op, left, right, typeArgs, returnType, node.loc); +} +const ENoEquality = (loc: Ast.Loc): E.TcError => ({ + loc, + descr: [ + E.TEText(`Equality on this type is not supported`), + ], +}); +const supportsEquality = (common: Ast.DecodedType): boolean => { + switch (common.kind) { + case "unit_type": + case "TyInt": + case "TySlice": + case "TyCell": + case "TypeNull": + case "TypeBool": + case "TypeAddress": + case "TypeString": + case "map_type": { + return true; + } + case "TypeMaybe": { + return supportsEquality(common.type); + } + case "recover": + case "type_ref": + case "TypeVoid": + case "TypeAlias": + case "TypeParam": + case "TypeBounced": + case "tuple_type": + case "tensor_type": + case "TyBuilder": + case "TypeStringBuilder": { + return false; + } + } +}; +const decodeUnary: Decode = function* (node, ctx) { + const operand = yield* rec(node.operand, ctx); + const fnType = builtinBinary.get(node.op); + if (!fnType) { + return throwInternal("Builtin operator is not in the map"); + } + const { returnType, typeArgs } = yield* getCallResult( + fnType, + [operand.computedType], + ); + + return Ast.DOpUnary(node.op, operand, typeArgs, returnType, node.loc); +} +const decodeTernary: Decode = function* (node, ctx) { + const condition = yield* rec(node.condition, ctx); + yield* assignType(Bool, condition.computedType, ctx.scopeRef); + const thenBranch = yield* rec(node.thenBranch, ctx); + const elseBranch = yield* rec(node.elseBranch, ctx); + const commonType = yield* mgu(thenBranch.computedType, elseBranch.computedType, ctx.scopeRef); + return Ast.DConditional(condition, thenBranch, elseBranch, commonType, node.loc); +} +const decodeMethodCall: Decode = function* (node, ctx) { + const self = yield* rec(node.self, ctx); + const args = yield* E.mapLog(node.args, arg => rec(arg, ctx)); + + const { typeDecls, extensions } = ctx.scopeRef(); + const { returnType, typeArgs } = yield* lookupMethod( + self.computedType, + node.method.text, + args.map(child => child.computedType), + typeDecls, + extensions, + ); + return Ast.DMethodCall(self, node.method, args, typeArgs, returnType, node.loc); +} +const decodeFunctionCall: Decode = function* (node, ctx) { + const name = node.function; + + const args = yield* E.mapLog(node.args, arg => rec(arg, ctx)); + + if (name.text === 'sha256') { + const [arg] = args; + const int = Ast.TypeInt(Ast.IFInt('signed', 257, node.loc), node.loc); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + if (args.length !== 1 || arg?.computedType.kind !== 'TySlice' && arg?.computedType.kind !== 'TypeString') { + yield EMismatchSha256(node.loc); + return Ast.DNumber("10", 0n, int, node.loc); + } else { + return Ast.DStaticCall(name, new Map(), args, int, node.loc); + } + } + + const builtinFnType = builtinFunctions.get(name.text); + const globalFnType = ctx.scopeRef().functions.get(name.text)?.decl.type; + const fnType = builtinFnType ?? globalFnType; + + const { returnType, typeArgs } = yield* lookupFunction( + fnType, + yield* E.mapLog(node.typeArgs, function* (arg) { + return yield* decodeTypeLazy(ctx.typeParams, arg, ctx.scopeRef)(); + }), + args.map(child => child.computedType), + ); -} \ No newline at end of file + return Ast.DStaticCall(name, typeArgs, args, returnType, node.loc); +} +const EMismatchSha256 = (loc: Ast.Loc): E.TcError => ({ + loc, + descr: [ + E.TEText(`sha256() takes either Slice or String`), + ], +}); +const decodeStaticMethodCall: Decode = function* (node, ctx) { + if (node.typeArgs.length > 0) { + yield EFunctionArity(node.loc); + } + const args = yield* E.mapLog(node.args, arg => rec(arg, ctx)); + const selfDecl = ctx.scopeRef().typeDecls.get(node.self.text); + if (selfDecl?.decl.kind === 'struct' || selfDecl?.decl.kind === 'message') { + const builtins = getStaticBuiltin(Ast.DTypeRef(node.self, [], node.loc)); + const builtin = builtins.get(node.function.text); + if (!builtin) { + yield EUndefinedStatic(node.function.text, node.loc); + return Ast.DNull(Ast.TypeNull(node.loc), node.loc); + } + const { returnType, typeArgs } = yield* lookupFunction( + builtin, + [], + args.map(child => child.computedType), + ); + return Ast.DStaticMethodCall(node.self, typeArgs, node.function, args, returnType, node.loc); + } else { + yield EUndefinedStatic(node.function.text, node.loc); + return Ast.DNull(Ast.TypeNull(node.loc), node.loc); + } +} +const EUndefinedStatic = (name: string, loc: Ast.Loc): E.TcError => ({ + loc, + descr: [ + E.TEText(`Static method ${name} doesn't exist`), + ], +}); +const EFunctionArity = (loc: Ast.Loc): E.TcError => ({ + loc, + descr: [ + E.TEText(`Function doesn't take any generic arguments`), + ], +}); +const decodeFieldAccess: Decode = function* (node, ctx) { + const expr = yield* rec(node.aggregate, ctx); + switch (expr.computedType.kind) { + case "type_ref": { + // node.field.text + // message, struct / fields + // contract, trait (self.) / fields, constants + return; + } + case "TypeMaybe": { + // node.field.text + // lookup arg type + return; + } + case "TypeBounced": { + // cut type + return; + } + case "recover": + case "TypeAlias": + case "TypeParam": + case "map_type": + case "tuple_type": + case "tensor_type": + case "TyInt": + case "TySlice": + case "TyCell": + case "TyBuilder": + case "unit_type": + case "TypeVoid": + case "TypeNull": + case "TypeBool": + case "TypeAddress": + case "TypeString": + case "TypeStringBuilder": { + // recover + } + } + return Ast.DFieldAccess(expr, node.field, computedType, node.loc); +} +const decodeInitOf: Decode = function* (node, ctx) { + const args = yield* E.mapLog(node.args, arg => rec(arg, ctx)); + const contract = ctx.scopeRef().typeDecls.get(node.contract.text); + if (contract?.decl.kind !== 'contract') { + yield ENotContract(node.contract.text, node.loc); + return Ast.DInitOf(node.contract, args, StateInit, node.loc); + } + const typeParams = Ast.TypeParams([], new Set()); + const params = yield* initParams(contract.decl.init); + yield* lookupFunction( + Ast.DecodedFnType(typeParams, params, function*() { return StateInit; }), + [], + args.map(child => child.computedType), + ); + return Ast.DInitOf(node.contract, args, StateInit, node.loc); +} +function* initParams(init: Ast.InitSig) { + switch (init.kind) { + case "function": { + return init.params; + } + case "empty": { + return Ast.Parameters([], new Set()); + } + case "simple": { + const order: Ast.Parameter[] = []; + const set: Set = new Set(); + for (const name of init.fill.order) { + const param = init.fill.map.get(name); + if (!param) { + return throwInternal("Ordered<>: missing param"); + } + set.add(name); + order.push({ + name: Ast.Id(name, param.loc), + type: param.type, + loc: param.loc, + }); + } + return Ast.Parameters(order, set); + } + } +} +const decodeCodeOf: Decode = function* (node, ctx) { + const contract = ctx.scopeRef().typeDecls.get(node.contract.text); + if (contract?.decl.kind !== 'contract') { + yield ENotContract(node.contract.text, node.loc); + } + return Ast.DCodeOf(node.contract, Ast.TypeCell(Ast.SFDefault(node.loc), node.loc), node.loc); +} +const ENotContract = (name: string, loc: Ast.Loc): E.TcError => ({ + loc, + descr: [ + E.TEText(`"${name}" is not a contract`), + ], +}); diff --git a/src/next/types/extensions.ts b/src/next/types/extensions.ts index 14e2a7b70c..479df17c44 100644 --- a/src/next/types/extensions.ts +++ b/src/next/types/extensions.ts @@ -3,7 +3,7 @@ import * as E from "@/next/types/errors"; import { zip } from "@/utils/array"; import { throwInternal } from "@/error/errors"; import { decodeFnType } from "@/next/types/type-fn"; -import { dealiasTypeLazy } from "@/next/types/type"; +import { decodeDealiasTypeLazy } from "@/next/types/type"; import { decodeBody } from "@/next/types/body"; import { builtinMethods } from "@/next/types/builtins"; import type { TactSource } from "@/next/imports/source"; @@ -87,12 +87,12 @@ function* decodeExt( const decodedFn = yield* decodeFnType(type, scopeRef); - const lazySelf = dealiasTypeLazy( + const lazySelf = decodeDealiasTypeLazy( decodedFn.typeParams, selfType, scopeRef, ); - const self = yield* toSelfType(yield* lazySelf(), scopeRef); + const self = yield* decodeSelfType(yield* lazySelf(), scopeRef); if (!self) { return undefined; @@ -206,7 +206,7 @@ function allEqual( return zip(prevs, nexts).every(([prev, next]) => areEqual(prev, next)); } -function* toSelfType( +function* decodeSelfType( type: Ast.DecodedType, scopeRef: () => Ast.Scope, ): E.WithLog { diff --git a/src/next/types/fields.ts b/src/next/types/fields.ts index 1c52d6b63a..0bcf727e9a 100644 --- a/src/next/types/fields.ts +++ b/src/next/types/fields.ts @@ -3,15 +3,16 @@ import * as Ast from "@/next/ast"; import * as E from "@/next/types/errors"; import { throwInternal } from "@/error/errors"; -import { decodeTypeLazy } from "@/next/types/type"; +import { assignType, decodeTypeLazy } from "@/next/types/type"; import { decodeExpr } from "@/next/types/expression"; import { checkFieldOverride } from "@/next/types/override"; import { decodeConstantDef } from "@/next/types/constant-def"; +import { evalExpr } from "@/next/types/expr-eval"; -type MaybeExpr = Ast.Lazy | undefined +type MaybeExpr = Ast.Lazy | undefined export function* getFieldishGeneral( - typeName: string, + typeName: Ast.TypeId, traits: readonly Ast.Decl[], constants: readonly Ast.FieldConstant[], fields: readonly Ast.FieldDecl[], @@ -39,6 +40,12 @@ export function* getFieldishGeneral( } } + const selfType = Ast.MVTypeRef( + typeName, + [], + typeName.loc, + ) + // in which order fields were defined const order: string[] = []; @@ -50,7 +57,7 @@ export function* getFieldishGeneral( for (const field of fields) { const name = field.name; - const nextVia = Ast.ViaMemberOrigin(typeName, field.loc); + const nextVia = Ast.ViaMemberOrigin(typeName.text, field.loc); const prev = all.get(name.text); if (prev) { @@ -62,7 +69,12 @@ export function* getFieldishGeneral( order.push(name.text); // decode field - all.set(name.text, decodeField(typeName, field, scopeRef)); + all.set(name.text, decodeField( + typeName.text, + field, + scopeRef, + selfType, + )); // check if this field was inherited const prevInh = inherited.get(name.text); @@ -80,7 +92,7 @@ export function* getFieldishGeneral( for (const field of constants) { const { override, overridable, body } = field; const { init, name, loc } = body; - const nextVia = Ast.ViaMemberOrigin(typeName, loc); + const nextVia = Ast.ViaMemberOrigin(typeName.text, loc); const prev = all.get(name.text); if (prev) { @@ -101,7 +113,13 @@ export function* getFieldishGeneral( } // get the definition - const next = yield* decodeConstant(init, overridable, nextVia, scopeRef); + const next = yield* decodeConstant( + init, + overridable, + nextVia, + scopeRef, + selfType, + ); // check that override/abstract/virtual modifiers are correct yield* checkFieldOverride( @@ -141,6 +159,7 @@ function decodeField( typeName: string, field: Ast.FieldDecl, scopeRef: () => Ast.Scope, + selfType: Ast.SelfType, ) { const { initializer, name, type, loc } = field; const nextVia = Ast.ViaMemberOrigin(typeName, loc); @@ -148,12 +167,25 @@ function decodeField( // contracts don't have type parameters const typeParams = Ast.TypeParams([], new Set()); + const decoded = decodeTypeLazy(typeParams, type, scopeRef); + + const init = initializer && Ast.Lazy(function* () { + const ascribed = yield* decoded(); + const expr = yield* decodeExpr( + typeParams, + initializer, + scopeRef, + selfType, + new Map(), + ); + const computed = expr.computedType; + yield* assignType(ascribed, computed, scopeRef); + return yield* evalExpr(expr, scopeRef); + }); + // decode field return Ast.DeclMem( - Ast.InhFieldSig( - decodeTypeLazy(typeParams, type, scopeRef), - initializer && decodeExpr(initializer, scopeRef), - ), + Ast.InhFieldSig(decoded, init), nextVia, ); } @@ -174,6 +206,7 @@ function* decodeConstant( overridable: boolean, nextVia: Ast.ViaMember, scopeRef: () => Ast.Scope, + selfType: Ast.SelfType, ): E.WithLog>> { const typeParams = Ast.TypeParams([], new Set()); if (init.kind === 'constant_decl') { @@ -183,7 +216,12 @@ function* decodeConstant( nextVia, ); } else { - const [type, expr] = decodeConstantDef(typeParams, init, scopeRef); + const [type, expr] = decodeConstantDef( + typeParams, + init, + scopeRef, + selfType, + ); return Ast.DeclMem( Ast.FieldConstSig(overridable, type, expr), nextVia, diff --git a/src/next/types/message.ts b/src/next/types/message.ts new file mode 100644 index 0000000000..025fe3ff70 --- /dev/null +++ b/src/next/types/message.ts @@ -0,0 +1,96 @@ +/* eslint-disable require-yield */ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import { throwInternal } from "@/error/errors"; +import * as Ast from "@/next/ast"; +import { Int } from "@/next/types/builtins"; +import * as E from "@/next/types/errors"; +import { evalExpr } from "@/next/types/expr-eval"; +import { decodeExpr } from "@/next/types/expression"; +import { decodeFields } from "@/next/types/struct-fields"; +import { assignType } from "@/next/types/type"; +import { highest32ofSha256, sha256 } from "@/utils/sha256"; + +export function* decodeMessage( + message: Ast.MessageDecl, + scopeRef: () => Ast.Scope, +): E.WithLog { + const typeParams = Ast.TypeParams([], new Set()); + const fields = yield* decodeFields( + message.fields, + typeParams, + scopeRef, + ); + const lazyExpr = Ast.Lazy(function* () { + const opcode = yield* decodeOpcode( + typeParams, + message.opcode, + message.name.text, + fields.order, + scopeRef, + ); + if (opcode === 0n) { + yield EZero(message.loc); + } else if (opcode < 0n) { + yield ENegative(message.loc); + } else if (opcode > 0xffff_ffff) { + yield ETooLarge(message.loc); + } + return opcode; + }); + + return Ast.MessageSig(lazyExpr, fields); +} +const EZero = ( + next: Ast.Loc, +): E.TcError => ({ + loc: next, + descr: [ + E.TEText(`Zero opcode is reserved for text comments`), + ], +}); +const ENegative = ( + next: Ast.Loc, +): E.TcError => ({ + loc: next, + descr: [ + E.TEText(`Opcode must be positive`), + ], +}); +const ETooLarge = ( + next: Ast.Loc, +): E.TcError => ({ + loc: next, + descr: [ + E.TEText(`Opcode is too large`), + ], +}); + +function* decodeOpcode( + typeParams: Ast.TypeParams, + opcode: Ast.Expression | undefined, + messageName: string, + fieldsNames: readonly string[], + scopeRef: () => Ast.Scope, +) { + if (opcode) { + const expr = yield* decodeExpr( + typeParams, + opcode, + scopeRef, + undefined, + new Map(), + ); + const computed = expr.computedType; + if (yield* assignType(Int, computed, scopeRef)) { + const result = yield* evalExpr(expr, scopeRef); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + if (result.kind === 'number') { + return result.value + } else { + return throwInternal("Const eval returned non-number for Int") + } + } + } + const signature = messageName + "{" + fieldsNames.join(",") + "}"; + return highest32ofSha256(sha256(signature)); +} diff --git a/src/next/types/methods.ts b/src/next/types/methods.ts index 97e81180d2..9adc8e3d6a 100644 --- a/src/next/types/methods.ts +++ b/src/next/types/methods.ts @@ -7,8 +7,9 @@ import { decodeFnType } from "@/next/types/type-fn"; import { checkMethodOverride } from "@/next/types/override"; import { decodeExpr } from "@/next/types/expression"; import { crc16 } from "@/utils/crc16"; -import { tactMethodIds } from "@/next/types/builtins"; +import { Int, tactMethodIds } from "@/next/types/builtins"; import { evalExpr } from "@/next/types/expr-eval"; +import { assignType } from "@/next/types/type"; export function* getMethodsGeneral( typeName: Ast.TypeId, @@ -66,12 +67,15 @@ export function* getMethodsGeneral( ) : undefined; const getMethodId = decodeGetLazy( + decodedFn.typeParams, // FIXME: should `get` really get access to them? name, get, scopeRef, + selfType, ); - - // check for abstract + if (getMethodId && decodedFn.typeParams.order.length > 0) { + yield EGenericGetter(loc); + } const prevInh = inherited.get(name.text); if (prevInh) { @@ -109,37 +113,50 @@ export function* getMethodsGeneral( return all; } +const EGenericGetter = (loc: Ast.Loc): E.TcError => ({ + loc, + descr: [ + E.TEText(`Getter method cannot be generic`), + ], +}); function decodeGetLazy( + typeParams: Ast.TypeParams, fnName: Ast.Id, get: Ast.GetAttribute | undefined, scopeRef: () => Ast.Scope, + selfType: Ast.SelfType, ): undefined | Ast.Lazy { if (!get) { return undefined; } - return Ast.Lazy(() => decodeGet(fnName, get, scopeRef)); + return Ast.Lazy(() => decodeGet( + typeParams, + fnName, + get, + scopeRef, + selfType, + )); } function* decodeGet( + typeParams: Ast.TypeParams, fnName: Ast.Id, get: Ast.GetAttribute, scopeRef: () => Ast.Scope, + selfType: Ast.SelfType, ): E.WithLog { if (get.methodId) { - // decode expression - const exprLazy = decodeExpr(get.methodId, scopeRef); - - // force computation - const expr = yield* exprLazy(); - - // check type of expression - const type = yield* expr.computedType(); - - if (type.kind === 'TyInt') { - // evaluate expression + const expr = yield* decodeExpr( + typeParams, + get.methodId, + scopeRef, + selfType, + new Map(), + ); + const type = expr.computedType; + if (yield* assignType(Int, type, scopeRef)) { const methodId = yield* evalExpr(expr, scopeRef); - if ( // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition methodId.kind === 'number' && @@ -147,7 +164,6 @@ function* decodeGet( ) { return methodId.value; } - // if evaluation failed, fallthrough to computing it } else { // TODO: yield EMismatch(); @@ -156,10 +172,8 @@ function* decodeGet( // compute method id out of function name const methodId = BigInt((crc16(fnName.text) & 0xffff) | 0x10000); - // just in case yield* checkMethodId(methodId, fnName.loc); - return methodId; } diff --git a/src/next/types/override.ts b/src/next/types/override.ts index a7c6aefe4e..8d25c83a6c 100644 --- a/src/next/types/override.ts +++ b/src/next/types/override.ts @@ -8,7 +8,7 @@ import { assignMethodType } from "@/next/types/type-method"; export function* checkFieldOverride( name: string, prev: Ast.DeclMem | undefined + Ast.Lazy | undefined >> | undefined, nextType: Ast.Lazy, nextVia: Ast.ViaMember, diff --git a/src/next/types/receivers.ts b/src/next/types/receivers.ts new file mode 100644 index 0000000000..9c37aee3ad --- /dev/null +++ b/src/next/types/receivers.ts @@ -0,0 +1,239 @@ +/* eslint-disable require-yield */ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import * as Ast from "@/next/ast"; +import * as E from "@/next/types/errors"; +import { decodeStatements } from "@/next/types/statements"; +import { decodeDealiasTypeLazy } from "@/next/types/type"; + +// const hash = commentPseudoOpcode( +// commentRcv.selector.comment, +// receivers.fallback !== "undefined", +// commentRcv.ast.loc, +// ); + +export function* getReceivers( + typeName: Ast.TypeId, + traits: readonly Ast.Decl[], + receivers: readonly Ast.Receiver[], + scopeRef: () => Ast.Scope, +): E.WithLog { + const impExternals: Ast.Decl[] = []; + const impInternals: Ast.Decl[] = []; + const impBounces: Ast.Decl[] = []; + for (const { via, decl } of traits) { + const { external, internal, bounce } = decl.receivers; + impExternals.push(Ast.Decl(external, via)); + impInternals.push(Ast.Decl(internal, via)); + impBounces.push(Ast.Decl(bounce, via)); + } + + const localInternals: Ast.DeclMem<[Ast.ReceiverSubKind, readonly Ast.Statement[]]>[] = []; + const localExternals: Ast.DeclMem<[Ast.ReceiverSubKind, readonly Ast.Statement[]]>[] = []; + const localBounces: Ast.DeclMem<[Ast.TypedParameter, readonly Ast.Statement[]]>[] = []; + for (const receiver of receivers) { + const { selector, statements, loc } = receiver; + const via = Ast.ViaMemberOrigin(typeName.text, loc); + switch (selector.kind) { + case "internal": + case "external": { + const arr = selector.kind === 'internal' + ? localInternals + : localExternals; + arr.push(Ast.DeclMem([selector.subKind, statements], via)); + continue; + } + case "bounce": { + localBounces.push(Ast.DeclMem([selector.param, statements], via)); + } + } + } + return { + bounce: yield* mergeBounce(typeName, impBounces, localBounces, scopeRef), + external: yield* mergeReceivers(typeName, impExternals, localExternals, scopeRef), + internal: yield* mergeReceivers(typeName, impInternals, localInternals, scopeRef), + }; +} + +function* mergeReceivers( + typeName: Ast.TypeId, + imported: readonly Ast.Decl[], + local: Ast.DeclMem[], + scopeRef: () => Ast.Scope, +): E.WithLog { + const allMessage: Ast.DeclMem[] = []; + let allMessageAny: undefined | Ast.DeclMem; + let allStringAny: undefined | Ast.DeclMem; + let allEmpty: undefined | Ast.DeclMem; + + // imported + for (const { via: viaTrait, decl } of imported) { + const { message, messageAny, stringAny, empty } = decl; + for (const { via, decl } of message) { + const nextVia = Ast.ViaMemberTrait(typeName.text, viaTrait.defLoc, via); + // we don't check for duplicates in receivers here, because + // the thing that matters is they have different opcodes + allMessage.push(Ast.DeclMem(decl, nextVia)); + } + if (messageAny) { + const nextVia = Ast.ViaMemberTrait(typeName.text, viaTrait.defLoc, messageAny.via); + if (allMessageAny) { + yield ERedefineReceiver("fallback binary", allMessageAny.via, nextVia); + } + allMessageAny = Ast.DeclMem(messageAny.decl, nextVia); + } + if (stringAny) { + const nextVia = Ast.ViaMemberTrait(typeName.text, viaTrait.defLoc, stringAny.via); + if (allStringAny) { + yield ERedefineReceiver("fallback string", allStringAny.via, nextVia); + } + allStringAny = Ast.DeclMem(stringAny.decl, nextVia); + } + if (empty) { + const nextVia = Ast.ViaMemberTrait(typeName.text, viaTrait.defLoc, empty.via); + if (allEmpty) { + yield ERedefineReceiver("empty", allEmpty.via, nextVia); + } + allEmpty = Ast.DeclMem(empty.decl, nextVia); + } + } + + // local + for (const { via, decl: [subKind, body] } of local) { + const statements = decodeStatements(body, scopeRef); + switch (subKind.kind) { + case "simple": { + const { name, type } = subKind.param; + const typeParams = Ast.TypeParams([], new Set()); + const decoded = yield* decodeDealiasTypeLazy(typeParams, type, scopeRef)(); + if (decoded.kind === 'TySlice') { + if (allMessageAny) { + yield ERedefineReceiver("fallback binary", allMessageAny.via, via); + } + allMessageAny = Ast.DeclMem( + Ast.MessageAnyRecv(name, statements), + via, + ); + } else if (decoded.kind === 'TypeString') { + if (allStringAny) { + yield ERedefineReceiver("fallback string", allStringAny.via, via); + } + allStringAny = Ast.DeclMem( + Ast.StringAnyRecv(name, statements), + via, + ); + } else if (decoded.kind === 'type_ref') { + allMessage.push(Ast.DeclMem( + Ast.MessageRecv(name, decoded, statements), + via, + )); + } else { + yield EInvalidRecv(via.defLoc); + } + continue; + } + case "fallback": { + if (allEmpty) { + yield ERedefineReceiver("fallback string", allEmpty.via, via); + } + allEmpty = Ast.DeclMem( + Ast.EmptyRecv(statements), + via, + ); + continue; + } + case "comment": { + allMessage.push(Ast.DeclMem( + Ast.StringRecv(subKind.comment.value, statements), + via, + )); + continue; + } + } + } + + return { + message: allMessage, + messageAny: allMessageAny, + stringAny: allStringAny, + empty: allEmpty, + }; +} + +function* mergeBounce( + typeName: Ast.TypeId, + imported: readonly Ast.Decl[], + local: readonly Ast.DeclMem<[Ast.TypedParameter, readonly Ast.Statement[]]>[], + scopeRef: () => Ast.Scope +): E.WithLog { + const allMessage: Ast.DeclMem[] = []; + let allMessageAny: undefined | Ast.DeclMem; + + // imported + for (const { via: viaTrait, decl: { message, messageAny } } of imported) { + for (const { via, decl } of message) { + const nextVia = Ast.ViaMemberTrait(typeName.text, viaTrait.defLoc, via); + // we don't check for duplicates in receivers here, because + // the thing that matters is they have different opcodes + allMessage.push(Ast.DeclMem(decl, nextVia)); + } + if (messageAny) { + const nextVia = Ast.ViaMemberTrait(typeName.text, viaTrait.defLoc, messageAny.via); + if (allMessageAny) { + yield ERedefineReceiver("fallback binary", allMessageAny.via, nextVia); + } + allMessageAny = Ast.DeclMem(messageAny.decl, nextVia); + } + } + + // local + for (const { via, decl: [{ name, type }, body] } of local) { + const statements = decodeStatements(body, scopeRef); + const typeParams = Ast.TypeParams([], new Set()); + const decoded = yield* decodeDealiasTypeLazy(typeParams, type, scopeRef)(); + if (decoded.kind === 'TySlice') { + if (allMessageAny) { + yield ERedefineReceiver("fallback binary", allMessageAny.via, via); + } + allMessageAny = Ast.DeclMem( + Ast.MessageAnyRecv(name, statements), + via, + ); + } else if (decoded.kind === 'type_ref' || decoded.kind === 'TypeBounced') { + allMessage.push(Ast.DeclMem( + Ast.MessageRecv(name, decoded, statements), + via, + )); + } else { + yield EInvalidRecv(via.defLoc); + } + } + + return { + message: allMessage, + messageAny: allMessageAny, + }; +} + +const EInvalidRecv = ( + loc: Ast.Loc, +): E.TcError => ({ + loc, + descr: [ + E.TEText(`Receiver's parameter must be a message type, Slice, or String`), + ], +}); + +const ERedefineReceiver = ( + kind: string, + prev: Ast.ViaMember, + next: Ast.ViaMember, +): E.TcError => ({ + loc: next.defLoc, + descr: [ + E.TEText(`There already is a ${kind} receiver`), + E.TEText(`First defined at`), + E.TEViaMember(prev), + E.TEText(`Redefined at`), + E.TEViaMember(next), + ], +}); \ No newline at end of file diff --git a/src/next/types/struct-fields.ts b/src/next/types/struct-fields.ts new file mode 100644 index 0000000000..d0df3f2462 --- /dev/null +++ b/src/next/types/struct-fields.ts @@ -0,0 +1,68 @@ +/* eslint-disable require-yield */ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import * as Ast from "@/next/ast"; +import * as E from "@/next/types/errors"; +import { evalExpr } from "@/next/types/expr-eval"; +import { decodeExpr } from "@/next/types/expression"; +import { assignType, decodeTypeLazy } from "@/next/types/type"; + +export function* decodeFields( + fields: readonly Ast.FieldDecl[], + typeParams: Ast.TypeParams, + scopeRef: () => Ast.Scope, +) { + const order: string[] = []; + const all: Map = new Map(); + for (const field of fields) { + const { initializer, loc } = field; + const name = field.name.text; + + const prev = all.get(name); + if (prev) { + const [prevLoc] = prev; + yield EDuplicateField(name, prevLoc, loc); + continue; + } + + const ascribedType = decodeTypeLazy( + typeParams, + field.type, + scopeRef, + ); + + const lazyExpr = initializer ? Ast.Lazy(function* () { + const expr = yield* decodeExpr( + typeParams, + initializer, + scopeRef, + undefined, + new Map(), + ); + const computed = expr.computedType; + const ascribed = yield* ascribedType(); + yield* assignType( ascribed, computed, scopeRef); + return yield* evalExpr(expr, scopeRef); + }) : undefined; + + order.push(name); + all.set(name, [loc, Ast.InhFieldSig(ascribedType, lazyExpr)]); + } + + const map = new Map([...all].map(([name, [, field]]) => [name, field])); + return Ast.Ordered(order, map); +} + +const EDuplicateField = ( + name: string, + prev: Ast.Loc, + next: Ast.Loc, +): E.TcError => ({ + loc: next, + descr: [ + E.TEText(`Duplicate field ${name}`), + E.TEText(`New definition:`), + E.TECode(next), + E.TEText(`Previously defined at:`), + E.TECode(prev), + ], +}); \ No newline at end of file diff --git a/src/next/types/struct.ts b/src/next/types/struct.ts new file mode 100644 index 0000000000..b016bef228 --- /dev/null +++ b/src/next/types/struct.ts @@ -0,0 +1,15 @@ +/* eslint-disable require-yield */ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import * as Ast from "@/next/ast"; +import type * as E from "@/next/types/errors"; +import { decodeFields } from "@/next/types/struct-fields"; +import { decodeTypeParams } from "@/next/types/type-params"; + +export function* decodeStruct( + struct: Ast.StructDecl, + scopeRef: () => Ast.Scope, +): E.WithLog { + const typeParams = yield* decodeTypeParams(struct.typeParams); + const fields = yield* decodeFields(struct.fields, typeParams, scopeRef); + return Ast.StructSig(typeParams, fields); +} diff --git a/src/next/types/trait.ts b/src/next/types/trait.ts new file mode 100644 index 0000000000..913bff02d4 --- /dev/null +++ b/src/next/types/trait.ts @@ -0,0 +1,66 @@ +/* eslint-disable require-yield */ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import * as Ast from "@/next/ast"; +import * as E from "@/next/types/errors"; +import { getFieldishGeneral } from "@/next/types/fields"; +import { getInheritedTraits } from "@/next/types/traits-scope"; +import { getMethodsGeneral } from "@/next/types/methods"; +import { getReceivers } from "@/next/types/receivers"; + +export function* decodeTrait( + trait: Ast.Trait, + scopeRef: () => Ast.Scope, +): E.WithLog { + const { attributes, declarations, name, loc } = trait; + const { constants, fields, methods, receivers } = declarations; + + const attr = attributes[0]; + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + if (attr) { + yield ENoAttributes(attr.loc); + } + + // delayed until we get all traits and init + const contentLazy = Ast.Lazy(function* () { + const traits = yield* getInheritedTraits( + trait.traits, + scopeRef, + ); + + // const contentRef = () => content; + const content: Ast.TraitContent = { + fieldish: yield* getFieldishGeneral( + name, + traits, + constants, + fields, + scopeRef, + ), + methods: yield* getMethodsGeneral( + name, + traits, + methods, + scopeRef, + ), + receivers: yield* getReceivers( + name, + traits, + receivers, + scopeRef, + ), + }; + + return content; + }); + + return Ast.TraitSig(contentLazy); +} + +const ENoAttributes = ( + loc: Ast.Loc, +): E.TcError => ({ + loc, + descr: [ + E.TEText(`Traits cannot have attributes`), + ], +}); diff --git a/src/next/types/traits-scope.ts b/src/next/types/traits-scope.ts index c17b753e31..6005bb6785 100644 --- a/src/next/types/traits-scope.ts +++ b/src/next/types/traits-scope.ts @@ -3,19 +3,17 @@ import * as Ast from "@/next/ast"; import * as E from "@/next/types/errors"; -type MaybeExpr = Ast.Lazy | undefined - export function* getInheritedTraits( traits: readonly Ast.TypeId[], scopeRef: () => Ast.Scope, -): E.WithLog>[]> { +): E.WithLog[]> { const decls = scopeRef().typeDecls; - const prevTraits: Ast.Decl>[] = []; + const prevTraits: Ast.Decl[] = []; for (const trait of traits) { const name = trait.text; - const decl = decls.get(trait.text); + const decl = decls.get(name); if (!decl) { - yield EUndefinedTrait(trait.text, trait.loc); + yield EUndefinedTrait(name, trait.loc); continue; } const { via, decl: traitDecl } = decl; diff --git a/src/next/types/type-fn.ts b/src/next/types/type-fn.ts index 4890528fff..f0efc5be84 100644 --- a/src/next/types/type-fn.ts +++ b/src/next/types/type-fn.ts @@ -1,8 +1,9 @@ import * as Ast from "@/next/ast"; import * as E from "@/next/types/errors"; import { decodeTypeParams } from "@/next/types/type-params"; -import { dealiasTypeLazy } from "@/next/types/type"; +import { decodeDealiasTypeLazy } from "@/next/types/type"; import { recoverName } from "@/next/types/name"; +import { messageBuiltin, structBuiltin } from "@/next/types/builtins"; export function* decodeFnType( { typeParams, params, returnType }: Ast.FnType, @@ -10,7 +11,7 @@ export function* decodeFnType( ): E.WithLog { const decodedTypeParams = yield* decodeTypeParams(typeParams); const dealias = (type: Ast.Type) => { - return dealiasTypeLazy(decodedTypeParams, type, scopeRef); + return decodeDealiasTypeLazy(decodedTypeParams, type, scopeRef); }; return Ast.DecodedFnType( decodedTypeParams, @@ -19,7 +20,7 @@ export function* decodeFnType( ); } -function* decodeParams( +export function* decodeParams( dealias: (type: Ast.Type) => Ast.Lazy, params: readonly Ast.TypedParameter[], ): E.WithLog { @@ -60,3 +61,108 @@ const EDuplicateParam = (name: string, loc: Ast.Loc): E.TcError => ({ E.TEText(`Duplicate parameter "${name}"`), ], }); + +export type CallResult = { + readonly returnType: Ast.DecodedType; + readonly typeArgs: ReadonlyMap; +} + +export function* getCallResult( + fn: Ast.DecodedFnType, + args: readonly Ast.DecodedType[], +): E.WithLog { + // yield* assignType(ascribed.key, key.computedType, ctx.scopeRef); +} + +export function* lookupMethod( + selfType: Ast.DecodedType, + methodName: string, + computedArgTypes: readonly Ast.DecodedType[], + typeDecls: ReadonlyMap>, + extensions: ReadonlyMap[]>>, +): E.WithLog { + if (self.computedType.kind === 'type_ref') { + const selfDecl = ctx.scopeRef().typeDecls.get(self.computedType.name.text); + if (!selfDecl) { + // + } else if (selfDecl.decl.kind === 'struct') { + const builtin = structBuiltin.get(node.method.text); + if (builtin) { + return Ast.DMethodCall(self, node.method, args, typeArgs, returnType, node.loc); + } + } else if (selfDecl.decl.kind === 'message') { + const builtin = messageBuiltin.get(node.method.text); + } + } + + switch (selfType.kind) { + case "recover": + case "type_ref": + case "TypeAlias": + case "TypeParam": + case "map_type": + case "TypeBounced": + case "TypeMaybe": + case "tuple_type": + case "tensor_type": + case "TyInt": + case "TySlice": + case "TyCell": + case "TyBuilder": + case "unit_type": + case "TypeVoid": + case "TypeNull": + case "TypeBool": + case "TypeAddress": + case "TypeString": + case "TypeStringBuilder": + } + if (selfType.kind === 'type_ref') { + const typeName = selfType.name.text; + const decl = typeDecls.get(typeName) + switch (decl?.decl.kind) { + case undefined: { + return; + } + case "alias": { + return; + } + case "trait": + case "contract": { + const { methods } = yield* decl.decl.content(); + const method = methods.get(methodName); + if (!method) { + return; + } + const methodType = method.decl.type; + return; + } + case "struct": + case "message": + case "union": { + const extsLazy = extensions.get(methodName); + if (!extsLazy) { + return; + } + for (const { decl } of yield* extsLazy()) { + const methodType = decl.type; + // methodType.typeParams + // typeArgs + if (methodType.self.ground === 'yes') { + // + } else { + // + } + } + } + } + } +} + +export function* lookupFunction( + fnType: Ast.DecodedFnType | undefined, + ascribed: readonly Ast.DecodedType[], + argTypes: readonly Ast.DecodedType[], +): E.WithLog { + +} \ No newline at end of file diff --git a/src/next/types/type.ts b/src/next/types/type.ts index 1367fb26d7..664ac0b09a 100644 --- a/src/next/types/type.ts +++ b/src/next/types/type.ts @@ -15,7 +15,7 @@ export const decodeTypeLazy = ( scopeRef().typeDecls, )); -export const dealiasTypeLazy = ( +export const decodeDealiasTypeLazy = ( typeParams: Ast.TypeParams, type: Ast.Type, scopeRef: () => Ast.Scope, @@ -25,13 +25,45 @@ export const dealiasTypeLazy = ( type, scopeRef().typeDecls, ); - return yield* dealiasType( + return yield* dealiasTypeAux( decoded, scopeRef().typeDecls, ); }); -function decodeType( +export function* dealiasType( + type: Ast.DecodedType, + scopeRef: () => Ast.Scope, +) { + return yield* dealiasTypeAux( + type, + scopeRef().typeDecls, + ); +} + +export function* decodeTypeMap( + typeParams: Ast.TypeParams, + type: Ast.TypeMap, + scopeRef: () => Ast.Scope, +) { + const { typeDecls } = scopeRef(); + const key = yield* decodeType(typeParams, type.key, typeDecls); + const value = yield* decodeType(typeParams, type.value, typeDecls); + return Ast.DTypeMap(key, value, type.loc); +} + +export function* decodeTypeSet( + typeParams: Ast.TypeParams, + type: Ast.TypeMap, + scopeRef: () => Ast.Scope, +) { + const { typeDecls } = scopeRef(); + const key = yield* decodeType(typeParams, type.key, typeDecls); + const value = yield* decodeType(typeParams, type.value, typeDecls); + return Ast.DTypeMap(key, value, type.loc); +} + +export function decodeType( typeParams: Ast.TypeParams, type: Ast.Type, typeDecls: ReadonlyMap>, @@ -75,13 +107,27 @@ function decodeType( return Ast.DTypeTensor(result, type.loc); } case "map_type": { + // NB! modify along with decodeTypeMap above const key = yield* rec(type.key); const value = yield* rec(type.value); return Ast.DTypeMap(key, value, type.loc); } case "TypeBounced": { const child = yield* rec(type.type); - return Ast.DTypeBounced(child, type.loc); + if (child.kind !== 'type_ref' || child.typeArgs.length > 0) { + yield EBouncedMessage(type.loc); + return Ast.DTypeRecover(); + } + const typeEntry = typeDecls.get(child.name.text); + if (!typeEntry) { + yield EBouncedMessage(type.loc); + return Ast.DTypeRecover(); + } else if (typeEntry.decl.kind === 'message') { + return Ast.DTypeBounced(child.name, type.loc); + } else { + yield EBouncedMessage(type.loc); + return Ast.DTypeRecover(); + } } case "TypeMaybe": { const child = yield* rec(type.type); @@ -168,6 +214,15 @@ const getArity = (decl: Ast.TypeDeclSig): number => { } } +const EBouncedMessage = ( + loc: Ast.Loc, +): E.TcError => ({ + loc, + descr: [ + E.TEText(`Only message types can be bounced<>`), + ], +}); + const ETypeNotFound = ( name: string, loc: Ast.Loc, @@ -212,7 +267,7 @@ const ETraitNotType = ( ], }); -const dealiasType = ( +const dealiasTypeAux = ( type: Ast.DecodedType, typeDecls: ReadonlyMap>, ) => { @@ -246,10 +301,6 @@ const dealiasType = ( const value = yield* rec(type.value); return Ast.DTypeMap(key, value, type.loc); } - case "TypeBounced": { - const args = yield* rec(type.type); - return Ast.DTypeBounced(args, type.loc); - } case "TypeMaybe": { const args = yield* rec(type.type); return Ast.DTypeMaybe(args, type.loc); @@ -272,7 +323,8 @@ const dealiasType = ( case "TypeBool": case "TypeAddress": case "TypeString": - case "TypeStringBuilder": { + case "TypeStringBuilder": + case "TypeBounced": { return type; } } @@ -320,10 +372,6 @@ const substitute = ( const value = rec(type.value); return Ast.DTypeMap(key, value, type.loc); } - case "TypeBounced": { - const args = rec(type.type); - return Ast.DTypeBounced(args, type.loc); - } case "TypeMaybe": { const args = rec(type.type); return Ast.DTypeMaybe(args, type.loc); @@ -347,7 +395,8 @@ const substitute = ( case "TypeBool": case "TypeAddress": case "TypeString": - case "TypeStringBuilder": { + case "TypeStringBuilder": + case "TypeBounced": { return type; } } @@ -356,10 +405,133 @@ const substitute = ( return rec(type); }; +export function* instantiateStruct( + typeName: Ast.TypeId, + typeArgs: readonly Ast.DecodedType[], + // NB! these are type params from enclosing scope + typeParams: Ast.TypeParams, + scopeRef: () => Ast.Scope, +): E.WithLog }> { + const decl = scopeRef().typeDecls.get(typeName.text); + switch (decl?.decl.kind) { + case undefined: { + yield ENoSuchType(typeName.text, typeName.loc); + return undefined; + } + case "contract": { + // TODO: support Foo { } syntax for contracts + yield ENotInstantiable(typeName.text, typeName.loc); + return undefined; + } + case "trait": + case "union": { + yield ENotInstantiable(typeName.text, typeName.loc); + return undefined; + } + case "struct": + case "message": { + const declArity = decl.decl.kind === "message" + ? 0 + : decl.decl.typeParams.order.length; + const useArity = typeArgs.length; + if (declArity !== useArity) { + yield ETypeArity( + typeName.text, + typeName.loc, + declArity, + useArity, + ); + return undefined; + } + return { + type: Ast.DTypeRef(typeName, typeArgs, typeName.loc), + fields: decl.decl.fields + }; + } + case "alias": { + const declArity = decl.decl.typeParams.order.length; + const useArity = typeArgs.length; + if (declArity !== useArity) { + yield ETypeArity( + typeName.text, + typeName.loc, + declArity, + useArity, + ); + return undefined; + } + const type = yield* dealiasType( + Ast.DTypeAliasRef(typeName, typeArgs, typeName.loc), + scopeRef, + ); + if (type.kind !== 'type_ref') { + yield ENotInstantiable(typeName.text, typeName.loc); + return undefined; + } + return yield* instantiateStruct( + type.name, + type.typeArgs, + typeParams, + scopeRef, + ); + } + } +} +const ENoSuchType = (name: string, loc: Ast.Loc): E.TcError => ({ + loc, + descr: [ + E.TEText(`Type ${name} is not defined`), + ], +}); +const ENotInstantiable = (name: string, loc: Ast.Loc): E.TcError => ({ + loc, + descr: [ + E.TEText(`Cannot create value of type ${name}`), + ], +}); +const ETypeArity = (name: string, loc: Ast.Loc, declArity: number, useArity: number): E.TcError => ({ + loc, + descr: [ + E.TEText(`Type ${name} expects ${declArity} arguments, got ${useArity}`), + ], +}); + export function* assignType( ascribed: Ast.DecodedType, computed: Ast.DecodedType, scopeRef: () => Ast.Scope, -) { +): E.WithLog { + +} +export function* mgu( + left: Ast.DecodedType, + right: Ast.DecodedType, + scopeRef: () => Ast.Scope, +): E.WithLog { + // left = simplifyHead(left); + // right = simplifyHead(right); + // if (left.kind === 'ERROR' || right.kind === 'ERROR') { + // return Ty.TypeErrorRecovered(); + // } + // if (left.kind === 'type_var' || right.kind === 'type_var') { + // return throwInternal("Trying to unify type variable"); + // } + // const children: MismatchTree[] = []; + // if (assignToAux1(left, right, children)) { + // return left; + // } + // if (assignToAux1(right, left, children)) { + // return right; + // } + // if (isNull(right)) { + // return Maybe(left, loc); + // } + // if (isNull(left)) { + // return Maybe(right, loc); + // } + // for (const tree of children) { + // err.typeMismatch(tree)(loc); + // } + // return Ty.TypeErrorRecovered(); } \ No newline at end of file diff --git a/src/next/types/typedecl.ts b/src/next/types/typedecl.ts index b528f6648e..48525f9cdc 100644 --- a/src/next/types/typedecl.ts +++ b/src/next/types/typedecl.ts @@ -2,10 +2,14 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ import * as Ast from "@/next/ast"; import * as E from "@/next/types/errors"; -import { builtinTypes } from "@/next/types/builtins"; import type { TactSource } from "@/next/imports/source"; +import { builtinTypes } from "@/next/types/builtins"; import { decodeAlias } from "@/next/types/alias"; import { decodeContract } from "@/next/types/contract"; +import { decodeTrait } from "@/next/types/trait"; +import { decodeStruct } from "@/next/types/struct"; +import { decodeMessage } from "@/next/types/message"; +import { decodeUnion } from "@/next/types/union"; const errorKind = 'type'; @@ -28,7 +32,7 @@ export function* decodeTypeDecls( return new Map([[ decl.name.text, Ast.Decl( - yield* decodeTypeDecl(decl, source, scopeRef), + yield* decodeTypeDecl(decl, scopeRef), via, ), ]]); @@ -60,7 +64,6 @@ export function* decodeTypeDecls( function* decodeTypeDecl( decl: Ast.TypeDecl, - source: TactSource, scopeRef: () => Ast.Scope, ): E.WithLog { switch (decl.kind) { @@ -71,20 +74,16 @@ function* decodeTypeDecl( return yield* decodeContract(decl, scopeRef); } case "trait": { - throw new Error(); - // return Ast.DeclSig('contract', 0, via); - } - case "message_decl": { - throw new Error(); - // return Ast.DeclSig('usual', 0, via); + return yield* decodeTrait(decl, scopeRef); } case "struct_decl": { - throw new Error(); - // return Ast.DeclSig('usual', decl.typeParams.length, via); + return yield* decodeStruct(decl, scopeRef); + } + case "message_decl": { + return yield* decodeMessage(decl, scopeRef); } case "union_decl": { - throw new Error(); - // return Ast.DeclSig('usual', decl.typeParams.length, via); + return yield* decodeUnion(decl, scopeRef); } } } diff --git a/src/next/types/union.ts b/src/next/types/union.ts new file mode 100644 index 0000000000..a9f62e6980 --- /dev/null +++ b/src/next/types/union.ts @@ -0,0 +1,93 @@ +/* eslint-disable require-yield */ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import * as Ast from "@/next/ast"; +import * as E from "@/next/types/errors"; +import { evalExpr } from "@/next/types/expr-eval"; +import { decodeExpr } from "@/next/types/expression"; +import { assignType, decodeTypeLazy } from "@/next/types/type"; +import { decodeTypeParams } from "@/next/types/type-params"; + +type Cons = { + readonly fields: ReadonlyMap; + readonly loc: Ast.Loc; +} + +export function* decodeUnion( + union: Ast.UnionDecl, + scopeRef: () => Ast.Scope, +): E.WithLog { + const typeParams = yield* decodeTypeParams(union.typeParams); + + const cases: Map = new Map(); + for (const cons of union.cases) { + const caseName = cons.name.text; + const prevCons = cases.get(caseName); + if (prevCons) { + yield EDuplicateCons(caseName, prevCons.loc, cons.name.loc) + continue; + } + const fields: Map = new Map(); + for (const field of cons.fields) { + const fieldName = field.name.text; + const prevField = fields.get(fieldName); + if (prevField) { + const [, prevFieldLoc] = prevField; + yield EDuplicateField(fieldName, prevFieldLoc, field.name.loc) + } + const ascribedType = decodeTypeLazy(typeParams, field.type, scopeRef); + const initializer = field.initializer; + const lazyExpr = initializer ? Ast.Lazy(function* () { + const expr = yield* decodeExpr( + typeParams, + initializer, + scopeRef, + undefined, + new Map(), + ); + const computed = expr.computedType; + const ascribed = yield* ascribedType(); + yield* assignType( ascribed, computed, scopeRef); + return yield* evalExpr(expr, scopeRef); + }) : undefined; + const decoded = Ast.InhFieldSig(ascribedType, lazyExpr); + fields.set(fieldName, [decoded, field.name.loc]) + } + cases.set(caseName, { + fields: new Map([...fields].map(([name, [type]]) => [name, type])), + loc: cons.name.loc, + }) + } + + const map = new Map([...cases].map(([name, { fields }]) => [name, fields])); + return Ast.UnionSig(typeParams, map); +} + +const EDuplicateCons = ( + name: string, + prev: Ast.Loc, + next: Ast.Loc, +): E.TcError => ({ + loc: next, + descr: [ + E.TEText(`Duplicate union case "${name}"`), + E.TEText(`Defined at:`), + E.TECode(next), + E.TEText(`Previously defined at:`), + E.TECode(prev), + ], +}); + +const EDuplicateField = ( + name: string, + prev: Ast.Loc, + next: Ast.Loc, +): E.TcError => ({ + loc: next, + descr: [ + E.TEText(`Duplicate field "${name}"`), + E.TEText(`Defined at:`), + E.TECode(next), + E.TEText(`Previously defined at:`), + E.TECode(prev), + ], +}); \ No newline at end of file diff --git a/src/next/types/value.ts b/src/next/types/value.ts new file mode 100644 index 0000000000..57880e8b0a --- /dev/null +++ b/src/next/types/value.ts @@ -0,0 +1,22 @@ +/* eslint-disable require-yield */ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import * as Ast from "@/next/ast"; + +export function convertValueToExpr( + node: Ast.Value +): Ast.DecodedExpression { + switch (node.kind) { + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + case 'number': { + return Ast.DNumber( + "10", + node.value, + Ast.TypeInt( + Ast.IFInt("signed", 257, node.loc), + node.loc + ), + node.loc, + ); + } + } +} \ No newline at end of file From 8a008f5a49a8cb9f141d733f4ea74cb060c9c7b5 Mon Sep 17 00:00:00 2001 From: verytactical <186486509+verytactical@users.noreply.github.com> Date: Sat, 31 May 2025 14:13:58 +0400 Subject: [PATCH 26/38] 1 --- src/next/ast/checked-expr.ts | 37 +++ src/next/ast/checked-stmt.ts | 10 +- src/next/ast/checked.ts | 7 + src/next/ast/dtype.ts | 14 + src/next/ast/generated/checked-expr.ts | 34 ++ src/next/ast/generated/checked-stmt.ts | 8 +- src/next/ast/generated/checked.ts | 1 + src/next/ast/generated/dtype.ts | 21 +- src/next/ast/generated/mtype.ts | 7 +- src/next/ast/generated/statement.ts | 4 +- src/next/ast/generated/type.ts | 8 +- src/next/ast/mtype.ts | 5 + src/next/ast/statement.ts | 4 +- src/next/ast/type.ts | 6 + src/next/grammar/index.ts | 4 +- src/next/scoping/errors.ts | 6 - src/next/scoping/typecheck.ts | 60 +--- src/next/types/builtins.ts | 31 +- src/next/types/errors.ts | 8 + src/next/types/expression.ts | 161 ++++++--- src/next/types/extensions.ts | 5 + src/next/types/lvalue.ts | 52 +++ src/next/types/statements.ts | 437 ++++++++++++++++++++++++- src/next/types/tlb.ts | 154 +++++++++ src/next/types/type.ts | 85 ++++- 25 files changed, 1029 insertions(+), 140 deletions(-) create mode 100644 src/next/types/lvalue.ts create mode 100644 src/next/types/tlb.ts diff --git a/src/next/ast/checked-expr.ts b/src/next/ast/checked-expr.ts index 73dbe59395..1902440967 100644 --- a/src/next/ast/checked-expr.ts +++ b/src/next/ast/checked-expr.ts @@ -4,6 +4,8 @@ import type * as D from "@/next/ast/dtype"; import type { BinaryOperation, NumberBase, UnaryOperation } from "@/next/ast/expression"; import type { SelfType } from "@/next/ast/mtype"; +// TODO: put Self into main AST and parser + export type TypeArgs = ReadonlyMap; export type DecodedExpression = @@ -11,6 +13,7 @@ export type DecodedExpression = | DOpUnary | DConditional | DMethodCall + | DThrowCall | DStaticCall | DStaticMethodCall | DFieldAccess @@ -29,6 +32,32 @@ export type DecodedExpression = | DMapLiteral | DSetLiteral; +export type LValue = + | LVar + | LSelf + | LFieldAccess + +export type LSelf = { + readonly kind: "self"; + readonly computedType: SelfType; + readonly loc: Loc; +} + +export type LVar = { + readonly kind: "var"; + readonly name: string; + readonly computedType: D.DecodedType; + readonly loc: Loc; +}; + +export type LFieldAccess = { + readonly kind: "field_access"; + readonly aggregate: LValue; + readonly field: Id; + readonly computedType: D.DecodedType; + readonly loc: Loc; +}; + export type DSelf = { readonly kind: "self"; readonly computedType: SelfType; @@ -108,6 +137,14 @@ export type DMethodCall = { readonly loc: Loc; }; +export type DThrowCall = { + readonly kind: "throw_call"; + readonly function: Id; + readonly args: readonly DecodedExpression[]; + readonly computedType: D.DecodedType; + readonly loc: Loc; +} + // builtins or top-level (module) functions export type DStaticCall = { readonly kind: "static_call"; diff --git a/src/next/ast/checked-stmt.ts b/src/next/ast/checked-stmt.ts index 10b03cf6be..2750770c54 100644 --- a/src/next/ast/checked-stmt.ts +++ b/src/next/ast/checked-stmt.ts @@ -1,4 +1,4 @@ -import type { DecodedExpression } from "@/next/ast/checked-expr"; +import type { DecodedExpression, LValue } from "@/next/ast/checked-expr"; import type { Id, Loc, OptionalId, TypeId } from "@/next/ast/common"; import type { AugmentedAssignOperation } from "@/next/ast/statement"; @@ -40,7 +40,7 @@ export type DStatementExpression = { export type DStatementAssign = { readonly kind: "statement_assign"; - readonly path: DecodedExpression; // left-hand side of `=` + readonly path: LValue; readonly expression: DecodedExpression; readonly loc: Loc; }; @@ -48,7 +48,7 @@ export type DStatementAssign = { export type DStatementAugmentedAssign = { readonly kind: "statement_augmentedassign"; readonly op: AugmentedAssignOperation; - readonly path: DecodedExpression; + readonly path: LValue; readonly expression: DecodedExpression; readonly loc: Loc; }; @@ -90,8 +90,8 @@ export type DStatementTry = { }; export type DCatchBlock = { - readonly catchName: OptionalId; - readonly catchStatements: DStatementList; + readonly name: OptionalId; + readonly statements: DStatementList; }; export type DStatementForEach = { diff --git a/src/next/ast/checked.ts b/src/next/ast/checked.ts index 2024fcc1f4..55157e17b1 100644 --- a/src/next/ast/checked.ts +++ b/src/next/ast/checked.ts @@ -35,6 +35,13 @@ export type TypeDeclSig = | MessageSig | UnionSig +export type TypeDeclRefable = + | ContractSig + | TraitSig + | StructSig + | MessageSig + | UnionSig + export type ConstSig = { readonly initializer: Lazy; readonly type: Lazy; diff --git a/src/next/ast/dtype.ts b/src/next/ast/dtype.ts index b1d6ae55f0..836724718e 100644 --- a/src/next/ast/dtype.ts +++ b/src/next/ast/dtype.ts @@ -1,6 +1,12 @@ +import type { TypeDeclRefable } from "@/next/ast/checked"; import type { Loc, TypeId } from "@/next/ast/common"; import type * as Ast from "@/next/ast/type"; +// TODO: +// readonly tlb: Lazy +// readonly effects: Lazy +// readonly ref: NoPrint + export type DecodedType = | DTypeRecover | DTypeRef @@ -20,6 +26,7 @@ export type DecodedType = | DTypeNull | DTypeBool | DTypeAddress + | DTypeStateInit | DTypeString | DTypeStringBuilder; @@ -34,14 +41,20 @@ export type DTypeBool = Ast.TypeBool export type DTypeAddress = Ast.TypeAddress export type DTypeString = Ast.TypeString export type DTypeStringBuilder = Ast.TypeStringBuilder +export type DTypeStateInit = Ast.TypeStateInit; export type DTypeRecover = { readonly kind: "recover"; } +export type NotDealiased = { + readonly kind: "NotDealiased"; +} + export type DTypeRef = { readonly kind: "type_ref"; readonly name: TypeId; + readonly type: TypeDeclRefable; readonly typeArgs: readonly DecodedType[]; readonly loc: Loc; }; @@ -49,6 +62,7 @@ export type DTypeRef = { export type DTypeAliasRef = { readonly kind: "TypeAlias" readonly name: TypeId; + readonly type: NotDealiased | DecodedType; readonly typeArgs: readonly DecodedType[]; readonly loc: Loc; } diff --git a/src/next/ast/generated/checked-expr.ts b/src/next/ast/generated/checked-expr.ts index 7c0d51f192..bfcc3a74ff 100644 --- a/src/next/ast/generated/checked-expr.ts +++ b/src/next/ast/generated/checked-expr.ts @@ -196,3 +196,37 @@ export const DOpBinary = (op: $e.BinaryOperation, left: $.DecodedExpression, rig }); export const isDOpBinary = ($value: DOpBinary) => $value.kind === "op_binary"; export type DecodedExpression = $.DecodedExpression; +export type DThrowCall = $.DThrowCall; +export const DThrowCall = (function_: $c.Id, args: readonly $.DecodedExpression[], computedType: $d.DecodedType, loc: $c.Loc): $.DThrowCall => Object.freeze({ + kind: "throw_call", + function: function_, + args, + computedType, + loc, +}); +export const isDThrowCall = ($value: DThrowCall) => $value.kind === "throw_call"; +export type LVar = $.LVar; +export const LVar = (name: string, computedType: $d.DecodedType, loc: $c.Loc): $.LVar => Object.freeze({ + kind: "var", + name, + computedType, + loc +}); +export const isLVar = ($value: LVar) => $value.kind === "var"; +export type LSelf = $.LSelf; +export const LSelf = (computedType: SelfType, loc: $c.Loc): $.LSelf => Object.freeze({ + kind: "self", + computedType, + loc +}); +export const isLSelf = ($value: LSelf) => $value.kind === "self"; +export type LFieldAccess = $.LFieldAccess; +export const LFieldAccess = (aggregate: $.LValue, field: $c.Id, computedType: $d.DecodedType, loc: $c.Loc): $.LFieldAccess => Object.freeze({ + kind: "field_access", + aggregate, + field, + computedType, + loc +}); +export const isLFieldAccess = ($value: LFieldAccess) => $value.kind === "field_access"; +export type LValue = $.LValue; \ No newline at end of file diff --git a/src/next/ast/generated/checked-stmt.ts b/src/next/ast/generated/checked-stmt.ts index 773c3f65ea..70bd9789fd 100644 --- a/src/next/ast/generated/checked-stmt.ts +++ b/src/next/ast/generated/checked-stmt.ts @@ -27,7 +27,7 @@ export const DStatementExpression = (expression: $e.DecodedExpression, loc: $c.L }); export const isDStatementExpression = ($value: DStatementExpression) => $value.kind === "statement_expression"; export type DStatementAssign = $.DStatementAssign; -export const DStatementAssign = (path: $e.DecodedExpression, expression: $e.DecodedExpression, loc: $c.Loc): $.DStatementAssign => Object.freeze({ +export const DStatementAssign = (path: $e.LValue, expression: $e.DecodedExpression, loc: $c.Loc): $.DStatementAssign => Object.freeze({ kind: "statement_assign", path, expression, @@ -35,7 +35,7 @@ export const DStatementAssign = (path: $e.DecodedExpression, expression: $e.Deco }); export const isDStatementAssign = ($value: DStatementAssign) => $value.kind === "statement_assign"; export type DStatementAugmentedAssign = $.DStatementAugmentedAssign; -export const DStatementAugmentedAssign = (op: $s.AugmentedAssignOperation, path: $e.DecodedExpression, expression: $e.DecodedExpression, loc: $c.Loc): $.DStatementAugmentedAssign => Object.freeze({ +export const DStatementAugmentedAssign = (op: $s.AugmentedAssignOperation, path: $e.LValue, expression: $e.DecodedExpression, loc: $c.Loc): $.DStatementAugmentedAssign => Object.freeze({ kind: "statement_augmentedassign", op, path, @@ -72,8 +72,8 @@ export const DStatementForEach = (keyName: $c.OptionalId, valueName: $c.Optional export const isDStatementForEach = ($value: DStatementForEach) => $value.kind === "statement_foreach"; export type DCatchBlock = $.DCatchBlock; export const DCatchBlock = (catchName: $c.OptionalId, catchStatements: $.DStatementList): $.DCatchBlock => Object.freeze({ - catchName, - catchStatements + name: catchName, + statements: catchStatements }); export type DStatementTry = $.DStatementTry; export const DStatementTry = (statements: $.DStatementList, catchBlock: $.DCatchBlock | undefined, loc: $c.Loc): $.DStatementTry => Object.freeze({ diff --git a/src/next/ast/generated/checked.ts b/src/next/ast/generated/checked.ts index 03aeeb9ec0..531b66924b 100644 --- a/src/next/ast/generated/checked.ts +++ b/src/next/ast/generated/checked.ts @@ -247,6 +247,7 @@ export const InitFn = (params: $.Parameters, statements: readonly DecodedStateme export const isInitFn = ($value: InitFn) => $value.kind === "function"; export type InitSig = $.InitSig; export type ContractSig = $.ContractSig; +export type TypeDeclRefable = $.TypeDeclRefable; export const ContractSig = (attributes: readonly ContractAttribute[], init: $.InitSig, content: Lazy<$.ContractContent>): $.ContractSig => Object.freeze({ kind: "contract", attributes, diff --git a/src/next/ast/generated/dtype.ts b/src/next/ast/generated/dtype.ts index 9898715057..4ce40c9e1a 100644 --- a/src/next/ast/generated/dtype.ts +++ b/src/next/ast/generated/dtype.ts @@ -1,6 +1,7 @@ /* eslint-disable @typescript-eslint/no-unnecessary-condition */ import type * as $ from "@/next/ast/dtype"; import type * as $c from "@/next/ast/common"; +import { TypeDeclRefable } from "@/next/ast/checked"; export type DTypeParamRef = $.DTypeParamRef; export const DTypeParamRef = (name: $c.TypeId, loc: $c.Loc): $.DTypeParamRef => Object.freeze({ @@ -46,17 +47,19 @@ export const DTypeMap = (key: $.DecodedType, value: $.DecodedType, loc: $c.Loc): }); export const isDTypeMap = ($value: DTypeMap) => $value.kind === "map_type"; export type DTypeAliasRef = $.DTypeAliasRef; -export const DTypeAliasRef = (name: $c.TypeId, typeArgs: readonly $.DecodedType[], loc: $c.Loc): $.DTypeAliasRef => Object.freeze({ +export const DTypeAliasRef = (type: NotDealiased | DecodedType, name: $c.TypeId, typeArgs: readonly $.DecodedType[], loc: $c.Loc): $.DTypeAliasRef => Object.freeze({ kind: "TypeAlias", name, + type, typeArgs, loc }); export const isDTypeAliasRef = ($value: DTypeAliasRef) => $value.kind === "TypeAlias"; export type DTypeRef = $.DTypeRef; -export const DTypeRef = (name: $c.TypeId, typeArgs: readonly $.DecodedType[], loc: $c.Loc): $.DTypeRef => Object.freeze({ +export const DTypeRef = (name: $c.TypeId, type: TypeDeclRefable, typeArgs: readonly $.DecodedType[], loc: $c.Loc): $.DTypeRef => Object.freeze({ kind: "type_ref", name, + type, typeArgs, loc }); @@ -64,6 +67,18 @@ export const isDTypeRef = ($value: DTypeRef) => $value.kind === "type_ref"; export type DecodedType = $.DecodedType; export type DTypeRecover = $.DTypeRecover; export const DTypeRecover = (): $.DTypeRecover => Object.freeze({ - kind: "recover" + kind: "recover" }); export const isDTypeRecover = ($value: DTypeRecover) => $value.kind === "recover"; +export type DTypeStateInit = $.DTypeStateInit; +export const DTypeStateInit = (loc: $c.Loc): $.DTypeStateInit => Object.freeze({ + kind: "TypeStateInit", + loc +}); +export const isDTypeStateInit = ($value: DTypeStateInit) => $value.kind === "TypeStateInit"; + +export type NotDealiased = $.NotDealiased; +export const NotDealiased = (): $.NotDealiased => Object.freeze({ + kind: "NotDealiased" +}); +export const isNotDealiased = ($value: NotDealiased) => $value.kind === "NotDealiased"; diff --git a/src/next/ast/generated/mtype.ts b/src/next/ast/generated/mtype.ts index 986ba5214d..9428b34332 100644 --- a/src/next/ast/generated/mtype.ts +++ b/src/next/ast/generated/mtype.ts @@ -2,6 +2,7 @@ import type * as $ from "@/next/ast/mtype"; import type * as $c from "@/next/ast/common"; import type * as $d from "@/next/ast/dtype"; +import type { TypeDeclRefable } from "@/next/ast/checked"; export type MGTypeInt = $.MGTypeInt; export type MGTypeSlice = $.MGTypeSlice; @@ -15,10 +16,11 @@ export type MGTypeAddress = $.MGTypeAddress; export type MGTypeString = $.MGTypeString; export type MGTypeStringBuilder = $.MGTypeStringBuilder; export type MGTypeRef = $.MGTypeRef; -export const MGTypeRef = (name: $c.TypeId, typeArgs: readonly $.MethodGroundType[], loc: $c.Loc): $.MGTypeRef => Object.freeze({ +export const MGTypeRef = (name: $c.TypeId, type: TypeDeclRefable, typeArgs: readonly $.MethodGroundType[], loc: $c.Loc): $.MGTypeRef => Object.freeze({ ground: "yes", kind: "type_ref", name, + type, typeArgs, loc }); @@ -57,10 +59,11 @@ export const MGTypeTensor = (typeArgs: readonly $.MethodGroundType[], loc: $c.Lo }); export const isMGTypeTensor = ($value: MGTypeTensor) => $value.kind === "tensor_type"; export type MVTypeRef = $.MVTypeRef; -export const MVTypeRef = (name: $c.TypeId, typeArgs: readonly $d.DTypeParamRef[], loc: $c.Loc): $.MVTypeRef => Object.freeze({ +export const MVTypeRef = (name: $c.TypeId, type: TypeDeclRefable, typeArgs: readonly $d.DTypeParamRef[], loc: $c.Loc): $.MVTypeRef => Object.freeze({ ground: "no", kind: "type_ref", name, + type, typeArgs, loc }); diff --git a/src/next/ast/generated/statement.ts b/src/next/ast/generated/statement.ts index b36ecbe6db..c3a1e1df3f 100644 --- a/src/next/ast/generated/statement.ts +++ b/src/next/ast/generated/statement.ts @@ -144,8 +144,8 @@ export const CatchBlock = ( catchStatements: readonly $.Statement[], ): $.CatchBlock => Object.freeze({ - catchName, - catchStatements, + name: catchName, + statements: catchStatements, }); export type StatementTry = $.StatementTry; export const StatementTry = ( diff --git a/src/next/ast/generated/type.ts b/src/next/ast/generated/type.ts index 4492c3e67f..912ab6ce7f 100644 --- a/src/next/ast/generated/type.ts +++ b/src/next/ast/generated/type.ts @@ -216,4 +216,10 @@ export const MethodFnType = (typeParams: readonly $c.TypeId[], self: $.Type, arg self, args, returnType -}); \ No newline at end of file +}); +export type TypeStateInit = $.TypeStateInit; +export const TypeStateInit = (loc: $c.Loc): $.TypeStateInit => Object.freeze({ + kind: "TypeStateInit", + loc +}); +export const isTypeStateInit = ($value: TypeStateInit) => $value.kind === "TypeStateInit"; diff --git a/src/next/ast/mtype.ts b/src/next/ast/mtype.ts index 2b5e071f92..5f21889411 100644 --- a/src/next/ast/mtype.ts +++ b/src/next/ast/mtype.ts @@ -1,3 +1,4 @@ +import type { TypeDeclRefable } from "@/next/ast/checked"; import type { Loc, TypeId } from "@/next/ast/common"; import type { DTypeParamRef } from "@/next/ast/dtype"; import type * as Ast from "@/next/ast/type"; @@ -26,6 +27,7 @@ export type MethodGroundType = | MGTypeBool | MGTypeAddress | MGTypeString + | MGTypeStateInit | MGTypeStringBuilder; export type Ground = T & { @@ -41,6 +43,7 @@ export type MGTypeVoid = Ground export type MGTypeNull = Ground export type MGTypeBool = Ground export type MGTypeAddress = Ground +export type MGTypeStateInit = Ground export type MGTypeString = Ground export type MGTypeStringBuilder = Ground @@ -48,6 +51,7 @@ export type MGTypeRef = { readonly ground: "yes", readonly kind: "type_ref"; readonly name: TypeId; + readonly type: TypeDeclRefable; readonly typeArgs: readonly MethodGroundType[]; readonly loc: Loc; }; @@ -87,6 +91,7 @@ export type MVTypeRef = { readonly ground: "no", readonly kind: "type_ref"; readonly name: TypeId; + readonly type: TypeDeclRefable; readonly typeArgs: readonly DTypeParamRef[]; readonly loc: Loc; }; diff --git a/src/next/ast/statement.ts b/src/next/ast/statement.ts index 39230b1aaf..b22d76e8fd 100644 --- a/src/next/ast/statement.ts +++ b/src/next/ast/statement.ts @@ -103,8 +103,8 @@ export type StatementTry = { }; export type CatchBlock = { - readonly catchName: OptionalId; - readonly catchStatements: readonly Statement[]; + readonly name: OptionalId; + readonly statements: readonly Statement[]; }; export type StatementForEach = { diff --git a/src/next/ast/type.ts b/src/next/ast/type.ts index dcaf4ea7a8..0689d6b723 100644 --- a/src/next/ast/type.ts +++ b/src/next/ast/type.ts @@ -33,6 +33,7 @@ export type Type = | TypeNull | TypeBool | TypeAddress + | TypeStateInit | TypeString | TypeStringBuilder | TypeBounced @@ -65,6 +66,11 @@ export type TypeAddress = { readonly loc: Loc; } +export type TypeStateInit = { + readonly kind: "TypeStateInit" + readonly loc: Loc; +} + export type TypeString = { readonly kind: "TypeString" readonly loc: Loc; diff --git a/src/next/grammar/index.ts b/src/next/grammar/index.ts index 863a22087c..6024c9e712 100644 --- a/src/next/grammar/index.ts +++ b/src/next/grammar/index.ts @@ -840,8 +840,8 @@ const parseStatementTry = return Ast.StatementTry( parseStatements(body)(ctx), { - catchName: parseOptionalId(handler.name)(ctx), - catchStatements: parseStatements(handler.body)(ctx), + name: parseOptionalId(handler.name)(ctx), + statements: parseStatements(handler.body)(ctx), }, ctx.toRange(loc), ); diff --git a/src/next/scoping/errors.ts b/src/next/scoping/errors.ts index af0ff5bb02..3ec6645563 100644 --- a/src/next/scoping/errors.ts +++ b/src/next/scoping/errors.ts @@ -4,12 +4,6 @@ import type { Loc } from "@/next/ast"; import type * as Ty from "@/next/scoping/generated/type"; import { printType } from "@/next/scoping/print-type"; -export type MismatchTree = { - readonly to: Ty.LocType; - readonly from: Ty.LocType; - readonly children: MismatchTree[]; -} - export const TcErrors = (l: SourceLogger) => ({ shadowsImported: (name: string, prevPath: string, prevRange: Loc | Implicit) => (loc: Loc | Implicit) => { if (loc.kind !== 'range') { diff --git a/src/next/scoping/typecheck.ts b/src/next/scoping/typecheck.ts index 33e91b1bb1..91d85dcddb 100644 --- a/src/next/scoping/typecheck.ts +++ b/src/next/scoping/typecheck.ts @@ -1,20 +1,19 @@ -() => E.WithLog - -export type Unifier = ReturnType -export type LocalUnifier = ReturnType - /* eslint-disable @typescript-eslint/no-unnecessary-condition */ /* eslint-disable @typescript-eslint/no-base-to-string */ -import { makeVisitor, memo } from "@/utils/tricks"; -import type { Logger } from "@/error/logger-util"; -import type { Implicit, TactImport, TactSource } from "@/next/imports/source"; import type * as Ast from "@/next/ast"; -import type { Loc } from "@/next/ast"; import * as Ty from "@/next/scoping/generated/type"; import { zip } from "@/utils/array"; import { throwInternal } from "@/error/errors"; import { type MismatchTree, TcErrors } from "@/next/scoping/errors"; +const VarGen = () => { + let nextId = 0; + return function freshTVar() { + const id = nextId++; + return Ast.VTypeVar(id); + }; +}; + // left: Either // left: Int // left: Maybe @@ -199,46 +198,3 @@ const getExprChecker = ( checkExpr, }; }; - -const substParams = (into: Ty.Type, params: readonly Ty.TypeId[], args: readonly Ty.Type[]) => { - return zip(params, args) - .reduce((type, [param, arg]) => { - return substParam(type, param.text, arg); - }, into); -}; - -const substParam = (into: Ty.Type, param: string, value: Ty.Type): Ty.Type => { - const rec = (into: Ty.Type): Ty.Type => { - switch (into.kind) { - case "ERROR": - case "type_var": - case "TyInt": - case "TySlice": - case "TyCell": - case "TyBuilder": - case "unit_type": { - return into; - } - case "cons_type": { - if (into.name.text !== param) { - return Ty.TypeCons(into.name, into.typeArgs.map(arg => rec(arg)), into.loc); - } - if (into.typeArgs.length !== 0) { - // err.noHkt(param)(into.loc); - } - return value; - } - case "map_type": { - return Ty.TypeMap(rec(into.key), rec(into.value), into.loc); - } - case "tuple_type": { - return Ty.TypeTuple(into.typeArgs.map(arg => rec(arg)), into.loc); - } - case "tensor_type": { - return Ty.TypeTensor(into.typeArgs.map(arg => rec(arg)), into.loc); - } - } - }; - - return rec(into); -}; diff --git a/src/next/types/builtins.ts b/src/next/types/builtins.ts index 5cb3b5b8db..20f30e5706 100644 --- a/src/next/types/builtins.ts +++ b/src/next/types/builtins.ts @@ -66,7 +66,7 @@ export const StringBuilder = Ast.TypeStringBuilder(r); export const MapType = (k: Ast.DecodedType, v: Ast.DecodedType) => Ast.DTypeMap(k, v, r); export const Maybe = (t: Ast.DecodedType) => Ast.DTypeMaybe(t, r) export const Unit = Ast.TypeUnit(r); -export const StateInit = Ast.DTypeRef(Ast.TypeId("StateInit", r), [], r); +export const StateInit = Ast.DTypeStateInit(r); export const builtinTypes = new Map([ "Int", "Slice", "Cell", "Builder", "Void", "Null", "Bool", @@ -76,15 +76,21 @@ export const builtinTypes = new Map([ const ArithBin = (name: string) => { return Fn(name, { left: Int, right: Int }, Int); }; -const CompBin = (name: string) => { - return Fn(name, { left: Int, right: Int }, Bool); -}; const BoolBin = (name: string) => { return Fn(name, { left: Bool, right: Bool }, Bool); }; +const CompBin = (name: string) => { + return Fn(name, { left: Int, right: Int }, Bool); +}; const EqBin = (name: string) => { return GenericFn(name, ["T"], { left: Ref("T"), right: Ref("T") }, Bool); }; +const ArithAssign = (name: string) => { + return Fn(name, { left: Int, right: Int }, Void); +}; +const BoolAssign = (name: string) => { + return Fn(name, { left: Bool, right: Bool }, Void); +}; export const builtinFunctions: Map = new Map([ // dump(arg: T): Void @@ -168,6 +174,23 @@ export const builtinBinary: Map = new Map([ BoolBin("||"), ]); +export const builtinAugmented: Map = new Map([ + // (left: Int, right: Int): Void; + ArithAssign("+="), + ArithAssign("-="), + ArithAssign("*="), + ArithAssign("/="), + ArithAssign("%="), + ArithAssign("<<="), + ArithAssign(">>="), + ArithAssign("&="), + ArithAssign("|="), + ArithAssign("^="), + // (left: Bool, right: Bool): Void; + BoolAssign("&&="), + BoolAssign("||="), +]); + export const getStaticBuiltin = (type: Ast.DecodedType): Map => { return new Map([ // Foo.fromSlice(slice: Slice) diff --git a/src/next/types/errors.ts b/src/next/types/errors.ts index f4e3f85073..83b15a4dee 100644 --- a/src/next/types/errors.ts +++ b/src/next/types/errors.ts @@ -24,6 +24,14 @@ export function* mapLog(xs: readonly T[], f: (x: T) => WithLog): WithLo return result; } +export function* reduceLog(xs: readonly T[], init: U, f: (acc: U, x: T) => WithLog): WithLog { + let acc = init; + for (const x of xs) { + acc = yield* f(acc, x); + } + return acc; +} + export function* filterLog(xs: readonly T[], f: (x: T) => WithLog): WithLog { const result: T[] = []; for (const x of xs) { diff --git a/src/next/types/expression.ts b/src/next/types/expression.ts index b66d00367f..41c193caeb 100644 --- a/src/next/types/expression.ts +++ b/src/next/types/expression.ts @@ -1,9 +1,9 @@ /* eslint-disable require-yield */ -import { throwInternal } from "@/error/errors"; import * as Ast from "@/next/ast"; -import { Bool, builtinBinary, builtinFunctions, getStaticBuiltin, StateInit } from "@/next/types/builtins"; import * as E from "@/next/types/errors"; -import { assignType, decodeTypeLazy, decodeTypeMap, instantiateStruct, mgu } from "@/next/types/type"; +import { throwInternal } from "@/error/errors"; +import { Bool, builtinBinary, builtinFunctions, getStaticBuiltin, StateInit } from "@/next/types/builtins"; +import { assignType, dealiasType, decodeDealiasTypeLazy, decodeTypeLazy, decodeTypeMap, instantiateStruct, mgu } from "@/next/types/type"; import { getCallResult, lookupFunction, lookupMethod } from "@/next/types/type-fn"; import { convertValueToExpr } from "@/next/types/value"; @@ -12,8 +12,7 @@ type Context = { readonly scopeRef: () => Ast.Scope; readonly selfType: Ast.SelfType | undefined; readonly typeParams: Ast.TypeParams; - // TODO: must already be deshadowed - readonly localScopeRef: ReadonlyMap; + readonly localScopeRef: ReadonlyMap; } export function decodeExpr( @@ -21,9 +20,9 @@ export function decodeExpr( node: Ast.Expression, scopeRef: () => Ast.Scope, selfType: Ast.SelfType | undefined, - localScopeRef: ReadonlyMap, + localScopeRef: ReadonlyMap, ): E.WithLog { - return rec(node, { + return decodeExprCtx(node, { typeParams, scopeRef, selfType, @@ -31,7 +30,7 @@ export function decodeExpr( }); } -const rec: Decode = (node, ctx) => { +export const decodeExprCtx: Decode = (node, ctx) => { switch (node.kind) { case "null": return decodeNullCons(node, ctx); case "unit": return decodeUnitCons(node, ctx); @@ -60,42 +59,51 @@ const rec: Decode = (node, ctx) => { const decodeNullCons: Decode = function* (node) { return Ast.DNull(Ast.TypeNull(node.loc), node.loc); } + const decodeUnitCons: Decode = function* (node) { return Ast.DUnit(Ast.TypeUnit(node.loc), node.loc); } + const decodeStringCons: Decode = function* (node) { return Ast.DString(node.value, Ast.TypeString(node.loc), node.loc); } + const decodeNumberCons: Decode = function* (node) { return Ast.DNumber(node.base, node.value, Ast.TypeInt(Ast.IFInt('signed', 257, node.loc), node.loc), node.loc); } + const decodeBooleanCons: Decode = function* (node) { return Ast.DBoolean(node.value, Ast.TypeBool(node.loc), node.loc); } + const decodeTupleCons: Decode = function* (node, ctx) { - const children = yield* E.mapLog(node.children, child => rec(child, ctx)); + const children = yield* E.mapLog(node.children, child => decodeExprCtx(child, ctx)); const args = children.map(child => child.computedType); return Ast.DTuple(children, Ast.DTypeTuple(args, node.loc), node.loc); } + const decodeTensorCons: Decode = function* (node, ctx) { - const children = yield* E.mapLog(node.children, child => rec(child, ctx)); + const children = yield* E.mapLog(node.children, child => decodeExprCtx(child, ctx)); const args = children.map(child => child.computedType); return Ast.DTensor(children, Ast.DTypeTensor(args, node.loc), node.loc); } + const decodeMapCons: Decode = function* (node, ctx) { const ascribed = yield* decodeTypeMap(ctx.typeParams, node.type, ctx.scopeRef); const fields = yield* E.mapLog(node.fields, function* (field) { - const key = yield* rec(field.key, ctx); + const key = yield* decodeExprCtx(field.key, ctx); yield* assignType(ascribed.key, key.computedType, ctx.scopeRef); - const value = yield* rec(field.value, ctx); + const value = yield* decodeExprCtx(field.value, ctx); yield* assignType(ascribed.value, value.computedType, ctx.scopeRef); return Ast.DMapField(key, value); }); return Ast.DMapLiteral(ascribed, fields, node.loc); } + const decodeSetCons: Decode = function* () { return throwInternal("Set literals must have been declined before"); } + const decodeStructCons: Decode = function* (node, ctx) { const typeArgs = yield* E.mapLog(node.typeArgs, function* (arg) { return yield* decodeTypeLazy(ctx.typeParams, arg, ctx.scopeRef)(); @@ -133,7 +141,7 @@ function* checkFields( yield EDuplicateField(fieldName, prev.loc, arg.loc); continue; } - const expr = yield* rec(arg.initializer, ctx); + const expr = yield* decodeExprCtx(arg.initializer, ctx); if (typeFields) { const typeField = typeFields.map.get(fieldName); @@ -201,6 +209,7 @@ const EDuplicateField = (name: string, prev: Ast.Loc, next: Ast.Loc): E.TcError E.TECode(prev), ], }); + const decodeVar: Decode = function* (node, ctx) { if (node.name !== 'self') { const type = yield* lookupVar(node.name, node.loc, ctx); @@ -225,7 +234,8 @@ function* lookupVar( ): E.WithLog { const local = ctx.localScopeRef.get(name); if (local) { - return local; + const [type] = local; + return type; } const global = ctx.scopeRef().constants.get(name); if (global) { @@ -240,9 +250,10 @@ const EUndefined = (name: string, loc: Ast.Loc): E.TcError => ({ E.TEText(`Variable "${name}" not defined`), ], }); + const decodeBinary: Decode = function* (node, ctx) { - const left = yield* rec(node.left, ctx); - const right = yield* rec(node.right, ctx); + const left = yield* decodeExprCtx(node.left, ctx); + const right = yield* decodeExprCtx(node.right, ctx); const fnType = builtinBinary.get(node.op); if (!fnType) { return throwInternal("Builtin operator is not in the map"); @@ -293,13 +304,15 @@ const supportsEquality = (common: Ast.DecodedType): boolean => { case "tuple_type": case "tensor_type": case "TyBuilder": + case "TypeStateInit": case "TypeStringBuilder": { return false; } } }; + const decodeUnary: Decode = function* (node, ctx) { - const operand = yield* rec(node.operand, ctx); + const operand = yield* decodeExprCtx(node.operand, ctx); const fnType = builtinBinary.get(node.op); if (!fnType) { return throwInternal("Builtin operator is not in the map"); @@ -311,17 +324,19 @@ const decodeUnary: Decode = function* (node, ctx) { return Ast.DOpUnary(node.op, operand, typeArgs, returnType, node.loc); } + const decodeTernary: Decode = function* (node, ctx) { - const condition = yield* rec(node.condition, ctx); + const condition = yield* decodeExprCtx(node.condition, ctx); yield* assignType(Bool, condition.computedType, ctx.scopeRef); - const thenBranch = yield* rec(node.thenBranch, ctx); - const elseBranch = yield* rec(node.elseBranch, ctx); + const thenBranch = yield* decodeExprCtx(node.thenBranch, ctx); + const elseBranch = yield* decodeExprCtx(node.elseBranch, ctx); const commonType = yield* mgu(thenBranch.computedType, elseBranch.computedType, ctx.scopeRef); return Ast.DConditional(condition, thenBranch, elseBranch, commonType, node.loc); } + const decodeMethodCall: Decode = function* (node, ctx) { - const self = yield* rec(node.self, ctx); - const args = yield* E.mapLog(node.args, arg => rec(arg, ctx)); + const self = yield* decodeExprCtx(node.self, ctx); + const args = yield* E.mapLog(node.args, arg => decodeExprCtx(arg, ctx)); const { typeDecls, extensions } = ctx.scopeRef(); const { returnType, typeArgs } = yield* lookupMethod( @@ -333,10 +348,11 @@ const decodeMethodCall: Decode = function* (nod ); return Ast.DMethodCall(self, node.method, args, typeArgs, returnType, node.loc); } -const decodeFunctionCall: Decode = function* (node, ctx) { + +const decodeFunctionCall: Decode = function* (node, ctx) { const name = node.function; - const args = yield* E.mapLog(node.args, arg => rec(arg, ctx)); + const args = yield* E.mapLog(node.args, arg => decodeExprCtx(arg, ctx)); if (name.text === 'sha256') { const [arg] = args; @@ -357,12 +373,16 @@ const decodeFunctionCall: Decode const { returnType, typeArgs } = yield* lookupFunction( fnType, yield* E.mapLog(node.typeArgs, function* (arg) { - return yield* decodeTypeLazy(ctx.typeParams, arg, ctx.scopeRef)(); + return yield* decodeDealiasTypeLazy(ctx.typeParams, arg, ctx.scopeRef)(); }), args.map(child => child.computedType), ); - return Ast.DStaticCall(name, typeArgs, args, returnType, node.loc); + if (name.text === 'throw' || name.text === 'nativeThrow') { + return Ast.DThrowCall(name, args, returnType, node.loc); + } else { + return Ast.DStaticCall(name, typeArgs, args, returnType, node.loc); + } } const EMismatchSha256 = (loc: Ast.Loc): E.TcError => ({ loc, @@ -370,14 +390,15 @@ const EMismatchSha256 = (loc: Ast.Loc): E.TcError => ({ E.TEText(`sha256() takes either Slice or String`), ], }); + const decodeStaticMethodCall: Decode = function* (node, ctx) { if (node.typeArgs.length > 0) { yield EFunctionArity(node.loc); } - const args = yield* E.mapLog(node.args, arg => rec(arg, ctx)); + const args = yield* E.mapLog(node.args, arg => decodeExprCtx(arg, ctx)); const selfDecl = ctx.scopeRef().typeDecls.get(node.self.text); if (selfDecl?.decl.kind === 'struct' || selfDecl?.decl.kind === 'message') { - const builtins = getStaticBuiltin(Ast.DTypeRef(node.self, [], node.loc)); + const builtins = getStaticBuiltin(Ast.DTypeRef(node.self, selfDecl.decl, [], node.loc)); const builtin = builtins.get(node.function.text); if (!builtin) { yield EUndefinedStatic(node.function.text, node.loc); @@ -406,26 +427,77 @@ const EFunctionArity = (loc: Ast.Loc): E.TcError => ({ E.TEText(`Function doesn't take any generic arguments`), ], }); + const decodeFieldAccess: Decode = function* (node, ctx) { - const expr = yield* rec(node.aggregate, ctx); - switch (expr.computedType.kind) { + const expr = yield* decodeExprCtx(node.aggregate, ctx); + const selfType = expr.computedType; + const returnType = yield* lookupField(selfType, node.field, ctx.scopeRef); + return Ast.DFieldAccess(expr, node.field, returnType, node.loc); +} + +function* lookupField( + selfType: Ast.DecodedType, + fieldName: Ast.Id, + scopeRef: () => Ast.Scope, +): E.WithLog { + switch (selfType.kind) { case "type_ref": { - // node.field.text - // message, struct / fields - // contract, trait (self.) / fields, constants - return; + const decl = selfType.type; + switch (decl.kind) { + case "contract": + case "trait": { + const fields = (yield* decl.content()).fieldish; + const field = fields.map.get(fieldName.text); + if (!field) { + yield ENoSuchField(fieldName.text, fieldName.loc); + return Ast.DTypeRecover(); + } + return yield* field.decl.type(); + } + case "struct": + case "message": { + const field = decl.fields.map.get(fieldName.text); + if (!field) { + yield ENoSuchField(fieldName.text, fieldName.loc); + return Ast.DTypeRecover(); + } + return yield* field.type(); + } + case "union": { + yield ENoSuchField(fieldName.text, fieldName.loc); + return Ast.DTypeRecover(); + } + } + // linter asks for this unreachable code + return throwInternal("Not all ref cases handled"); } case "TypeMaybe": { - // node.field.text - // lookup arg type - return; + const type = yield* lookupField(selfType.type, fieldName, scopeRef); + if (type.kind === 'recover') { + return type; + } else { + return Ast.DTypeMaybe(type, fieldName.loc); + } } case "TypeBounced": { - // cut type - return; + const decl = scopeRef().typeDecls.get(selfType.name.text); + if (!decl || decl.decl.kind !== 'message') { + yield ENoSuchField(fieldName.text, fieldName.loc); + return Ast.DTypeRecover(); + } + const field = decl.decl.fields.map.get(fieldName.text); + if (!field) { + yield ENoSuchField(fieldName.text, fieldName.loc); + return Ast.DTypeRecover(); + } + // TODO: resolveDescriptors > resolvePartialFields + return yield* field.type(); } case "recover": - case "TypeAlias": + case "TypeAlias": { + const type = yield* dealiasType(selfType, scopeRef); + return yield* lookupField(type, fieldName, scopeRef); + } case "TypeParam": case "map_type": case "tuple_type": @@ -440,14 +512,16 @@ const decodeFieldAccess: Decode = function* ( case "TypeBool": case "TypeAddress": case "TypeString": + case "TypeStateInit": case "TypeStringBuilder": { - // recover + yield ENoSuchField(fieldName.text, fieldName.loc); + return Ast.DTypeRecover(); } } - return Ast.DFieldAccess(expr, node.field, computedType, node.loc); } + const decodeInitOf: Decode = function* (node, ctx) { - const args = yield* E.mapLog(node.args, arg => rec(arg, ctx)); + const args = yield* E.mapLog(node.args, arg => decodeExprCtx(arg, ctx)); const contract = ctx.scopeRef().typeDecls.get(node.contract.text); if (contract?.decl.kind !== 'contract') { yield ENotContract(node.contract.text, node.loc); @@ -489,6 +563,7 @@ function* initParams(init: Ast.InitSig) { } } } + const decodeCodeOf: Decode = function* (node, ctx) { const contract = ctx.scopeRef().typeDecls.get(node.contract.text); if (contract?.decl.kind !== 'contract') { diff --git a/src/next/types/extensions.ts b/src/next/types/extensions.ts index 479df17c44..721d626a5d 100644 --- a/src/next/types/extensions.ts +++ b/src/next/types/extensions.ts @@ -172,6 +172,7 @@ function areEqual( case "TypeBool": case "TypeAddress": case "TypeString": + case "TypeStateInit": case "TypeStringBuilder": { return prevSelf.kind === nextSelf.kind; } @@ -263,6 +264,7 @@ function* decodeSelfType( } return Ast.MGTypeRef( type.name, + def.decl, ground, type.loc, ); @@ -348,6 +350,7 @@ function* decodeSelfType( case "TypeBool": case "TypeAddress": case "TypeString": + case "TypeStateInit": case "TypeStringBuilder": { return { ground: "yes", @@ -392,6 +395,7 @@ function* toGroundType( } return Ast.MGTypeRef( type.name, + typeDecl.decl, ground, type.loc, ); @@ -442,6 +446,7 @@ function* toGroundType( case "TypeBool": case "TypeAddress": case "TypeString": + case "TypeStateInit": case "TypeStringBuilder": { return { ground: "yes", diff --git a/src/next/types/lvalue.ts b/src/next/types/lvalue.ts new file mode 100644 index 0000000000..4c76a56487 --- /dev/null +++ b/src/next/types/lvalue.ts @@ -0,0 +1,52 @@ +/* eslint-disable require-yield */ +import * as Ast from "@/next/ast"; +import * as E from "@/next/types/errors"; + +export function* convertExprToLValue(node: Ast.DecodedExpression): E.WithLog { + switch (node.kind) { + case "field_access": { + const aggregate = yield* convertExprToLValue(node.aggregate); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + return aggregate && Ast.LFieldAccess( + aggregate, + node.field, + node.computedType, + node.loc, + ); + } + case "var": + case "self": { + return node; + } + case "string": + case "number": + case "boolean": + case "op_binary": + case "op_unary": + case "conditional": + case "method_call": + case "throw_call": + case "static_call": + case "static_method_call": + case "struct_instance": + case "init_of": + case "code_of": + case "null": + case "unit": + case "tuple": + case "tensor": + case "map_literal": + case "set_literal": { + yield ENotLValue(node.loc); + return undefined; + } + } +} + +const ENotLValue = (prev: Ast.Loc): E.TcError => ({ + loc: prev, + descr: [ + E.TEText(`This expression cannot be used on the left side of assignment`), + E.TECode(prev), + ], +}); \ No newline at end of file diff --git a/src/next/types/statements.ts b/src/next/types/statements.ts index a38351923b..e368ed08e8 100644 --- a/src/next/types/statements.ts +++ b/src/next/types/statements.ts @@ -1,10 +1,439 @@ -import type * as Ast from "@/next/ast"; -import type * as E from "@/next/types/errors"; -import type { TactSource } from "@/next/imports/source"; +/* eslint-disable require-yield */ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable @typescript-eslint/no-unused-expressions */ +import * as Ast from "@/next/ast"; +import * as E from "@/next/types/errors"; +import { throwInternal } from "@/error/errors"; +import { Bool, builtinAugmented, Int } from "@/next/types/builtins"; +import { decodeExprCtx } from "@/next/types/expression"; +import { convertExprToLValue } from "@/next/types/lvalue"; +import { assignType, decodeType } from "@/next/types/type"; +import { getCallResult } from "@/next/types/type-fn"; export function decodeStatements( statements: readonly Ast.Statement[], scopeRef: () => Ast.Scope, ): readonly Ast.DecodedStatement[] { + const context: Context = { + scopeRef, + localScopeRef, + required: getRequired(selfType), + selfType, + returnType, + typeParams, + }; + yield* rec(statements, context, emptyEff); return []; -} \ No newline at end of file +} + +const rec: Decode< + readonly Ast.Statement[], + readonly Ast.DecodedStatement[] +> = function* (nodes, ctx, eff) { + const results: Ast.DecodedStatement[] = []; + let state = [ctx, eff] as const; + for (const node of nodes) { + const result = yield* decodeStatement(node, ctx, eff); + results.push(result.node); + state = [result.context, result.effects]; + } + const [context, effects] = state; + return Result(results, context, effects); +}; + +type Decode = ( + node: T, + context: Context, + effects: Effects, +) => E.WithLog> + +type Result = { + readonly node: U; + readonly context: Context; + readonly effects: Effects; +} +const Result = ( + node: U, + context: Context, + effects: Effects, +): Result => Object.freeze({ node, context, effects }); + +type Context = { + readonly scopeRef: () => Ast.Scope; + readonly selfType: Ast.SelfType | undefined; + readonly required: undefined | ReadonlySet; + readonly typeParams: Ast.TypeParams; + readonly returnType: Ast.DecodedType; + readonly localScopeRef: ReadonlyMap; +} + +type Effects = { + readonly returnOrThrow: boolean; + readonly setSelfPaths: ReadonlySet; +} +const Effects = ( + returnOrThrow: boolean, + setSelfPaths: ReadonlySet, +): Effects => Object.freeze({ returnOrThrow, setSelfPaths }) + +function* getRequired(selfType: Ast.SelfType | undefined): E.WithLog> { + if (!selfType) { + return new Set(); + } + const required: Set = new Set(); + switch (selfType.kind) { + case "type_ref": { + switch (selfType.type.kind) { + case "contract": + case "trait": { + const { fieldish } = (yield* selfType.type.content()); + for (const [name, field] of fieldish.map) { + if (field.decl.kind === 'field' && !field.decl.init) { + required.add(name) + } + } + return required; + } + case "struct": + case "message": + case "union": { + // no requirement to fill self on these, because they have + // no init() + return required; + } + } + // linter needs this + return required; + } + case "map_type": + case "TypeMaybe": + case "tuple_type": + case "tensor_type": + case "TyInt": + case "TySlice": + case "TyCell": + case "TyBuilder": + case "unit_type": + case "TypeVoid": + case "TypeNull": + case "TypeBool": + case "TypeAddress": + case "TypeString": + case "TypeStateInit": + case "TypeStringBuilder": { + return undefined; + } + } +} + +const emptyEff: Effects = Object.freeze({ + returnOrThrow: false, + setSelfPaths: new Set(), +}); + +// when two branches merge +const mergeEff = (left: Effects, right: Effects): Effects => { + return Effects( + left.returnOrThrow && right.returnOrThrow, + new Set([...left.setSelfPaths].filter(p => right.setSelfPaths.has(p))) + ); +}; + +// on every assign +function* setHadAssign( + eff: Effects, + lvalue: Ast.LValue, +): E.WithLog { + const setSelfPaths = new Set(eff.setSelfPaths); + switch (lvalue.kind) { + case "self": { + // self = ...; + yield ENoSelfAssign(lvalue.loc); + break; + } + case "field_access": { + if (lvalue.aggregate.kind === 'self') { + // self.x = ...; + setSelfPaths.add(lvalue.field.text); + } + break; + } + case "var": { + // x = ...; + } + } + return Effects(eff.returnOrThrow, setSelfPaths); +} +const ENoSelfAssign = (loc: Ast.Loc): E.TcError => ({ + loc, + descr: [ + E.TEText(`Cannot assign to self`), + ], +}); + +// on every return or throw +function* setHadExit( + eff: Effects, + successful: boolean, + required: undefined | ReadonlySet, + returnLoc: Ast.Loc, +): E.WithLog { + if (successful && required) { + const missing = [...required].filter(p => !eff.setSelfPaths.has(p)); + for (const fieldName of missing) { + yield EMissingSelfInit(fieldName, returnLoc); + } + } + return Effects(true, eff.setSelfPaths); +} +const EMissingSelfInit = (name: string, loc: Ast.Loc): E.TcError => ({ + loc, + descr: [ + E.TEText(`Field "self.${name}" is not initialized by this moment`), + ], +}); + +function* defineVar( + node: Ast.OptionalId, + type: Ast.DecodedType, + ctx: Context, +): E.WithLog { + if (node.kind === 'wildcard') { + // there is nothing to define for a wildcard + return ctx; + } + + if (node.text === 'self') { + yield ENoDefineSelf(node.loc); + return ctx; + } + + const prev = ctx.localScopeRef.get(node.text); + if (prev) { + const [, prevLoc] = prev; + yield ERedefineVar(node.text, prevLoc, node.loc); + return ctx; + } + + const constant = ctx.scopeRef().constants.get(node.text); + if (constant) { + const prevLoc = constant.via.defLoc; + yield EShadowConst(node.text, prevLoc, node.loc); + return ctx; + } + + const localScopeRef = new Map(ctx.localScopeRef); + localScopeRef.set(node.text, [type, node.loc]); + return { ...ctx, localScopeRef }; +} +const ENoDefineSelf = (loc: Ast.Loc): E.TcError => ({ + loc, + descr: [ + E.TEText(`Cannot define a variable "self"`), + ], +}); +const ERedefineVar = (name: string, prev: Ast.Loc, next: Ast.Loc): E.TcError => ({ + loc: next, + descr: [ + E.TEText(`Variable ${name} is already defined`), + E.TEText(`Defined at:`), + E.TECode(next), + E.TEText(`Previously defined at:`), + E.TECode(prev), + ], +}); +const EShadowConst = (name: string, prev: Ast.Loc, next: Ast.Loc): E.TcError => ({ + loc: next, + descr: [ + E.TEText(`Variable ${name} shadows a global constant`), + E.TEText(`Defined at:`), + E.TECode(next), + E.TEText(`Previously defined at:`), + E.TECode(prev), + ], +}); + + +const decodeStatement: Decode = function (stmt, ctx, eff) { + switch (stmt.kind) { + case "statement_let": return decodeLet(stmt, ctx, eff); + case "statement_return": return decodeReturn(stmt, ctx, eff); + case "statement_expression": return decodeExpression(stmt, ctx, eff); + case "statement_assign": return decodeAssign(stmt, ctx, eff); + case "statement_augmentedassign": return decodeAssignAugmented(stmt, ctx, eff); + case "statement_condition": return decodeCondition(stmt, ctx, eff); + case "statement_while": return decodeWhile(stmt, ctx, eff); + case "statement_until": return decodeUntil(stmt, ctx, eff); + case "statement_repeat": return decodeRepeat(stmt, ctx, eff); + case "statement_try": return decodeTry(stmt, ctx, eff); + case "statement_foreach": return decodeForeach(stmt, ctx, eff); + case "statement_destruct": return decodeDestruct(stmt, ctx, eff); + case "statement_block": return decodeBlock(stmt, ctx, eff); + } +} + +const decodeLet: Decode = function* (node, ctx, eff) { + const expr = yield* decodeExprCtx(node.expression, ctx); + const result = Ast.DStatementLet(node.name, expr, node.loc); + if (node.type) { + const ascribed = yield* decodeType(ctx.typeParams, node.type, ctx.scopeRef().typeDecls) + yield* assignType(ascribed, expr.computedType, ctx.scopeRef); + const newCtx = yield* defineVar(node.name, ascribed, ctx); + return Result(result, newCtx, eff); + } else { + const newCtx = yield* defineVar(node.name, expr.computedType, ctx); + return Result(result, newCtx, eff); + } +}; + +const decodeReturn: Decode = function* (node, ctx, eff) { + const newEff = yield* setHadExit(eff, true, ctx.required, node.loc); + if (node.expression) { + const expr = yield* decodeExprCtx(node.expression, ctx); + yield* assignType(ctx.returnType, expr.computedType, ctx.scopeRef); + return Result(Ast.DStatementReturn(expr, node.loc), ctx, newEff); + } else { + return Result(Ast.DStatementReturn(undefined, node.loc), ctx, newEff); + } +}; + +const decodeExpression: Decode = function* (node, ctx, eff) { + const expr = yield* decodeExprCtx(node.expression, ctx); + if (expr.kind === 'throw_call') { + const newEff = yield* setHadExit(eff, true, ctx.required, node.loc); + return Result(Ast.DStatementExpression(expr, node.loc), ctx, newEff); + } else { + return Result(Ast.DStatementExpression(expr, node.loc), ctx, eff); + } +}; + +const decodeAssign: Decode = function* (node, ctx, eff) { + const right = yield* decodeExprCtx(node.expression, ctx); + const left = yield* decodeExprCtx(node.path, ctx); + const path = yield* convertExprToLValue(left); + if (path) { + yield* assignType(path.computedType, right.computedType, ctx.scopeRef); + const newEff = yield* setHadAssign(eff, path); + return Result(Ast.DStatementAssign(path, right, node.loc), ctx, newEff); + } else { + return Result(Ast.DStatementExpression(right, node.loc), ctx, eff); + } +}; + +const decodeAssignAugmented: Decode = function* (node, ctx, eff) { + const right = yield* decodeExprCtx(node.expression, ctx); + const left = yield* decodeExprCtx(node.path, ctx); + const path = yield* convertExprToLValue(left); + const fnType = builtinAugmented.get(node.op); + if (!fnType) { + return throwInternal("Builtin operator is not in the map"); + } + yield* getCallResult(fnType, [left.computedType, right.computedType]); + if (path) { + const newEff = yield* setHadAssign(eff, path); + return Result(Ast.DStatementAugmentedAssign(node.op, path, right, node.loc), ctx, newEff); + } else { + return Result(Ast.DStatementExpression(right, node.loc), ctx, eff); + } +}; + +const decodeCondition: Decode = function* (node, ctx, eff) { + const condition = yield* decodeExprCtx(node.condition, ctx); + yield* assignType(Bool, condition.computedType, ctx.scopeRef); + const trueRes = yield* rec(node.trueStatements, ctx, eff); + if (node.falseStatements) { + const falseRes = yield* rec(node.falseStatements, ctx, eff); + const newEff = mergeEff(trueRes.effects, falseRes.effects); + return Result(Ast.DStatementCondition(condition, trueRes.node, falseRes.node, node.loc), ctx, newEff); + } else { + const newEff = mergeEff(trueRes.effects, eff); + return Result(Ast.DStatementCondition(condition, trueRes.node, undefined, node.loc), ctx, newEff); + } +}; + +const decodeWhile: Decode = function* (node, ctx, eff) { + const condition = yield* decodeExprCtx(node.condition, ctx); + yield* assignType(Bool, condition.computedType, ctx.scopeRef); + const result = yield* rec(node.statements, ctx, eff); + // might be executed zero times, so it doesn't matter + // if it always returns, or assigns to `self` + return Result(Ast.DStatementWhile(condition, result.node, node.loc), ctx, eff); +}; + +const decodeUntil: Decode = function* (node, ctx, eff) { + const condition = yield* decodeExprCtx(node.condition, ctx); + yield* assignType(Bool, condition.computedType, ctx.scopeRef); + const result = yield* rec(node.statements, ctx, eff); + // until executes its body at least once + return Result(Ast.DStatementUntil(condition, result.node, node.loc), ctx, result.effects); +}; + +const decodeRepeat: Decode = function* (node, ctx, eff) { + const iterations = yield* decodeExprCtx(node.iterations, ctx); + yield* assignType(Int, iterations.computedType, ctx.scopeRef); + const result = yield* rec(node.statements, ctx, eff); + // might be executed zero times, so it doesn't matter + // if it always returns, or assigns to `self` + return Result(Ast.DStatementRepeat(iterations, result.node, node.loc), ctx, eff); +}; + +const decodeTry: Decode = function* (node, ctx, eff) { + const tryRes = yield* rec(node.statements, ctx, eff); + if (node.catchBlock) { + const newCtx = yield* defineVar(node.catchBlock.name, Int, ctx); + const catchRes = yield* rec(node.catchBlock.statements, newCtx, eff); + const catchBlock = Ast.DCatchBlock(node.catchBlock.name, catchRes.node); + const newEff = mergeEff(tryRes.effects, catchRes.effects); + return Result(Ast.DStatementTry(tryRes.node, catchBlock, node.loc), ctx, newEff); + } else { + return Result(Ast.DStatementTry(tryRes.node, undefined, node.loc), ctx, tryRes.effects); + } +}; + +const decodeForeach: Decode = function* (node, ctx, eff) { + const map = yield* decodeExprCtx(node.map, ctx); + const innerCtx = yield* defineForVars( + map.computedType, + node.keyName, + node.valueName, + ctx, + ); + const result = yield* rec(node.statements, innerCtx, eff); + return Result(Ast.DStatementForEach(node.keyName, node.valueName, map, result.node, node.loc), ctx, eff); +}; +function* defineForVars( + type: Ast.DecodedType, + keyName: Ast.OptionalId, + valueName: Ast.OptionalId, + ctx: Context, +): E.WithLog { + if (type.kind === 'map_type') { + const ctxKey = yield* defineVar(keyName, type.key, ctx); + const ctxKV = yield* defineVar(valueName, type.value, ctxKey); + return ctxKV; + } else if (type.kind === 'TypeAlias') { + const childType = type.type; + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + if (childType.kind === 'NotDealiased') { + return throwInternal("Non-dealiased type in foreach"); + } + return yield* defineForVars(childType, keyName, valueName, ctx); + } else { + const ctxKey = yield* defineVar(keyName, Ast.DTypeRecover(), ctx); + const ctxKV = yield* defineVar(valueName, Ast.DTypeRecover(), ctxKey); + return ctxKV; + } +} + +const decodeDestruct: Decode = function* (node, ctx, eff) { + const expr = yield* decodeExprCtx(node.expression, ctx); + node.identifiers // defineVar each, ReadonlyMap -> Ordered, assignType like in decodeStructCons + node.ignoreUnspecifiedFields // throw if #identifier != declTypes.get(node.type).fields.filter(x => x.kind === 'field').length + node.type // assignType(ascribed, expr.computedType) +}; + +const decodeBlock: Decode = function* (node, ctx, eff) { + const [body, bodyCtx] = yield* rec(node.statements, ctx, eff); + // TODO: handle return/self bullshit + return [Ast.DStatementBlock(body, node.loc), ctx]; +}; \ No newline at end of file diff --git a/src/next/types/tlb.ts b/src/next/types/tlb.ts new file mode 100644 index 0000000000..682c3fc549 --- /dev/null +++ b/src/next/types/tlb.ts @@ -0,0 +1,154 @@ +import * as Ast from "@/next/ast"; +import * as E from "@/next/types/errors"; + +export type TlbType = + | TlbInt + | TlbVarInt + | TlbBool + | TlbAddress + | TlbString + | TlbUnknown + | TlbLiteral + | TlbBits + | TlbMap + | TlbRef + | TlbMaybe + | TlbFields + | TlbUnion + +export type TlbTypeNoRef = + | TlbInt + | TlbVarInt + | TlbBool + | TlbAddress + | TlbLiteral + | TlbBits + | TlbMaybeNoRef + | TlbFieldsNoRef + | TlbUnionNoRef + +export type TlbInt = { + readonly kind: 'int'; + readonly sign: Ast.Signedness; + readonly width: number; +} + +export type TlbVarInt = { + readonly kind: 'varint'; + readonly sign: Ast.Signedness; + readonly width: Ast.VarIntWidth; +} + +export type TlbBool = { + readonly kind: 'bool'; +} + +export type TlbAddress = { + readonly kind: 'address'; +} + +export type TlbString = { + readonly kind: 'string'; +} + +export type TlbUnknown = { + // aka ^Cell + readonly kind: 'unknown'; +} + +export type TlbLiteral = { + readonly kind: 'literal'; + readonly width: number; + readonly value: bigint; +} + +export type TlbBits = { + readonly kind: 'ref'; + readonly width: number; +} + +export type TlbRef = { + readonly kind: 'ref'; + readonly type: TlbType; +} + +export type TlbMap = { + readonly kind: 'map'; + readonly key: TlbTypeNoRef; + readonly value: TlbType; +} + +export type TlbMaybe = { + readonly kind: 'maybe'; + readonly type: TlbType; +} + +export type TlbFields = { + readonly kind: 'fields'; + readonly children: readonly TlbType[]; +} + +export type TlbUnion = { + readonly kind: 'union'; + readonly prefixWidth: number; + readonly children: readonly TlbCase[]; +} + +export type TlbCase = { + readonly prefix: bigint; + readonly type: TlbType; +} + +export type TlbMaybeNoRef = { + readonly kind: 'maybe'; + readonly type: TlbCaseNoRef; +} + +export type TlbFieldsNoRef = { + readonly kind: 'fields'; + readonly children: readonly TlbCaseNoRef[]; +} + +export type TlbUnionNoRef = { + readonly kind: 'union'; + readonly prefixWidth: number; + readonly children: readonly TlbCaseNoRef[]; +} + +export type TlbCaseNoRef = { + readonly prefix: bigint; + readonly type: TlbCaseNoRef; +} + +export function convertTypeToTlb( + node: Ast.DecodedType, +) { + switch (node.kind) { + case "recover": { + return undefined; + } + case "type_ref": { + + } + case "TypeAlias": { + + } + case "TypeParam": + case "map_type": + case "TypeBounced": + case "TypeMaybe": + case "tuple_type": + case "tensor_type": + case "TyInt": + case "TySlice": + case "TyCell": + case "TyBuilder": + case "unit_type": + case "TypeVoid": + case "TypeNull": + case "TypeBool": + case "TypeAddress": + case "TypeString": + case "TypeStringBuilder": + } +} \ No newline at end of file diff --git a/src/next/types/type.ts b/src/next/types/type.ts index 664ac0b09a..a6feade76f 100644 --- a/src/next/types/type.ts +++ b/src/next/types/type.ts @@ -5,6 +5,27 @@ import * as Ast from "@/next/ast"; import * as E from "@/next/types/errors"; import { zip } from "@/utils/array"; +// type C = map +// type B = [T, U] +// type A = B> + +// head-first +// A -> B> -> [X, C] -> [X, map] + +// arg-first +// A -> B> -> B> -> [X, map] + +// if head of the type is an alias +// substitute alias +// store head and args +// recurse +// if head of the type is another type +// recurse on arguments + +// we never substitute into alias-cons (throwInternal) +// substitution only happens into body of alias decl +// body of alias decl is not dealiased, thus doesn't have alias-cons + export const decodeTypeLazy = ( typeParams: Ast.TypeParams, type: Ast.Type, @@ -95,6 +116,7 @@ export function decodeType( case "TypeBool": case "TypeAddress": case "TypeString": + case "TypeStateInit": case "TypeStringBuilder": { return type; } @@ -181,17 +203,17 @@ export function decodeType( } case "contract": { // this is a ground type reference - return Ast.DTypeRef(type.name, [], type.loc); + return Ast.DTypeRef(type.name, typeEntry.decl, [], type.loc); } case "struct": case "message": case "union": { // this is a ground type reference - return Ast.DTypeRef(type.name, args, type.loc); + return Ast.DTypeRef(type.name, typeEntry.decl, args, type.loc); } case "alias": { // this is an alias reference - return Ast.DTypeAliasRef(type.name, args, type.loc); + return Ast.DTypeAliasRef(Ast.NotDealiased(), type.name, args, type.loc); } } } @@ -278,7 +300,7 @@ const dealiasTypeAux = ( } case "type_ref": { const args = yield* E.mapLog(type.typeArgs, rec); - return Ast.DTypeRef(type.name, args, type.loc); + return Ast.DTypeRef(type.name, type.type, args, type.loc); } case "TypeAlias": { const alias = typeDecls.get(type.name.text); @@ -287,11 +309,12 @@ const dealiasTypeAux = ( } // NB! if we could decode alias once, there might be // a nested one too - return yield* rec(substitute( + const decoded = yield* rec(substitute( yield* alias.decl.type(), alias.decl.typeParams, yield* E.mapLog(type.typeArgs, rec), )); + return Ast.DTypeAliasRef(decoded, type.name, type.typeArgs, type.loc); } case "TypeParam": { return type; @@ -324,6 +347,7 @@ const dealiasTypeAux = ( case "TypeAddress": case "TypeString": case "TypeStringBuilder": + case "TypeStateInit": case "TypeBounced": { return type; } @@ -333,6 +357,7 @@ const dealiasTypeAux = ( return rec(type); }; +// NB! is substitute is used for something other than aliases, do not throwInternal on type.type const substitute = ( type: Ast.DecodedType, params: Ast.TypeParams, @@ -361,11 +386,14 @@ const substitute = ( } case "type_ref": { const args = recN(type.typeArgs); - return Ast.DTypeRef(type.name, args, type.loc); + return Ast.DTypeRef(type.name, type.type, args, type.loc); } case "TypeAlias": { const args = recN(type.typeArgs); - return Ast.DTypeAliasRef(type.name, args, type.loc); + if (type.type.kind !== 'NotDealiased') { + return throwInternal("Substitution must not happen into a type with resolved aliases"); + } + return Ast.DTypeAliasRef(type.type, type.name, args, type.loc); } case "map_type": { const key = rec(type.key); @@ -396,6 +424,7 @@ const substitute = ( case "TypeAddress": case "TypeString": case "TypeStringBuilder": + case "TypeStateInit": case "TypeBounced": { return type; } @@ -444,7 +473,12 @@ export function* instantiateStruct( return undefined; } return { - type: Ast.DTypeRef(typeName, typeArgs, typeName.loc), + type: Ast.DTypeRef( + typeName, + decl.decl, + typeArgs, + typeName.loc, + ), fields: decl.decl.fields }; } @@ -461,7 +495,12 @@ export function* instantiateStruct( return undefined; } const type = yield* dealiasType( - Ast.DTypeAliasRef(typeName, typeArgs, typeName.loc), + Ast.DTypeAliasRef( + Ast.NotDealiased(), + typeName, + typeArgs, + typeName.loc, + ), scopeRef, ); if (type.kind !== 'type_ref') { @@ -501,7 +540,33 @@ export function* assignType( computed: Ast.DecodedType, scopeRef: () => Ast.Scope, ): E.WithLog { - + // export type MismatchTree = { + // readonly to: Ty.LocType; + // readonly from: Ty.LocType; + // readonly children: MismatchTree[]; + // } + // switch (to.kind) { + // case 'TyBuilder': + // case 'TyCell': + // case 'TyInt': + // case 'TySlice': + // case "unit_type": { + // return from.kind === to.kind; + // } + // case "tuple_type": + // case "tensor_type": { + // return from.kind === to.kind && assignAll(to.typeArgs, from.typeArgs, tree); + // } + // case "map_type": { + // return isNull(from) + // || from.kind === 'map_type' && assignToAux1(to.key, from.key, tree) && assignToAux1(to.value, from.value, tree); + // } + // case 'cons_type': { + // return hasTypeParam(to.name.text) && to.typeArgs.length === 0 + // || to.name.text === 'Maybe' && isNull(from) + // || from.kind === 'cons_type' && to.name.text === from.name.text && assignAll(to.typeArgs, from.typeArgs, tree); + // } + // } } export function* mgu( From c25640c2ccda537e643c8bd200be97800d127590 Mon Sep 17 00:00:00 2001 From: verytactical <186486509+verytactical@users.noreply.github.com> Date: Sat, 31 May 2025 16:04:17 +0400 Subject: [PATCH 27/38] 1 --- src/next/ast/checked-expr.ts | 1 + src/next/ast/dtype.ts | 1 - src/next/types/body.ts | 1 + 3 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/next/ast/checked-expr.ts b/src/next/ast/checked-expr.ts index 1902440967..b436d7091f 100644 --- a/src/next/ast/checked-expr.ts +++ b/src/next/ast/checked-expr.ts @@ -5,6 +5,7 @@ import type { BinaryOperation, NumberBase, UnaryOperation } from "@/next/ast/exp import type { SelfType } from "@/next/ast/mtype"; // TODO: put Self into main AST and parser +// TODO: add effects export type TypeArgs = ReadonlyMap; diff --git a/src/next/ast/dtype.ts b/src/next/ast/dtype.ts index 836724718e..054154dae3 100644 --- a/src/next/ast/dtype.ts +++ b/src/next/ast/dtype.ts @@ -5,7 +5,6 @@ import type * as Ast from "@/next/ast/type"; // TODO: // readonly tlb: Lazy // readonly effects: Lazy -// readonly ref: NoPrint export type DecodedType = | DTypeRecover diff --git a/src/next/types/body.ts b/src/next/types/body.ts index e37d3d9e75..3dd3a87ede 100644 --- a/src/next/types/body.ts +++ b/src/next/types/body.ts @@ -204,6 +204,7 @@ function* getTypeTupleSize( case "TypeBool": case "TypeAddress": case "TypeString": + case "TypeStateInit": case "TypeStringBuilder": case "TypeNull": { return 1; From c47a7e25b2140b48b74fd90b36cdd6d0127a8895 Mon Sep 17 00:00:00 2001 From: verytactical <186486509+verytactical@users.noreply.github.com> Date: Sat, 31 May 2025 16:21:25 +0400 Subject: [PATCH 28/38] 1 --- src/next/ast/allocation.ts | 121 ++++++++++++++++++++++++++++++ src/next/ast/dtype.ts | 2 + src/next/grammar/import-parser.ts | 12 +-- src/next/test/_test.build.ts | 4 +- src/next/types/tlb.ts | 120 ----------------------------- 5 files changed, 130 insertions(+), 129 deletions(-) create mode 100644 src/next/ast/allocation.ts diff --git a/src/next/ast/allocation.ts b/src/next/ast/allocation.ts new file mode 100644 index 0000000000..8faccb73ac --- /dev/null +++ b/src/next/ast/allocation.ts @@ -0,0 +1,121 @@ +import * as Ast from "@/next/ast"; +import * as E from "@/next/types/errors"; + +export type TlbType = + | TlbInt + | TlbVarInt + | TlbBool + | TlbAddress + | TlbString + | TlbUnknown + | TlbLiteral + | TlbBits + | TlbMap + | TlbRef + | TlbMaybe + | TlbFields + | TlbUnion + +export type TlbTypeNoRef = + | TlbInt + | TlbVarInt + | TlbBool + | TlbAddress + | TlbLiteral + | TlbBits + | TlbMaybeNoRef + | TlbFieldsNoRef + | TlbUnionNoRef + +export type TlbInt = { + readonly kind: 'int'; + readonly sign: Ast.Signedness; + readonly width: number; +} + +export type TlbVarInt = { + readonly kind: 'varint'; + readonly sign: Ast.Signedness; + readonly width: Ast.VarIntWidth; +} + +export type TlbBool = { + readonly kind: 'bool'; +} + +export type TlbAddress = { + readonly kind: 'address'; +} + +export type TlbString = { + readonly kind: 'string'; +} + +export type TlbUnknown = { + // aka ^Cell + readonly kind: 'unknown'; +} + +export type TlbLiteral = { + readonly kind: 'literal'; + readonly width: number; + readonly value: bigint; +} + +export type TlbBits = { + readonly kind: 'ref'; + readonly width: number; +} + +export type TlbRef = { + readonly kind: 'ref'; + readonly type: TlbType; +} + +export type TlbMap = { + readonly kind: 'map'; + readonly key: TlbTypeNoRef; + readonly value: TlbType; +} + +export type TlbMaybe = { + readonly kind: 'maybe'; + readonly type: TlbType; +} + +export type TlbFields = { + readonly kind: 'fields'; + readonly children: readonly TlbType[]; +} + +export type TlbUnion = { + readonly kind: 'union'; + readonly prefixWidth: number; + readonly children: readonly TlbCase[]; +} + +export type TlbCase = { + readonly prefix: bigint; + readonly type: TlbType; +} + +export type TlbMaybeNoRef = { + readonly kind: 'maybe'; + readonly type: TlbCaseNoRef; +} + +export type TlbFieldsNoRef = { + readonly kind: 'fields'; + readonly children: readonly TlbCaseNoRef[]; +} + +export type TlbUnionNoRef = { + readonly kind: 'union'; + readonly prefixWidth: number; + readonly children: readonly TlbCaseNoRef[]; +} + +export type TlbCaseNoRef = { + readonly prefix: bigint; + readonly type: TlbCaseNoRef; +} \ No newline at end of file diff --git a/src/next/ast/dtype.ts b/src/next/ast/dtype.ts index 054154dae3..0fdc217b3a 100644 --- a/src/next/ast/dtype.ts +++ b/src/next/ast/dtype.ts @@ -55,6 +55,8 @@ export type DTypeRef = { readonly name: TypeId; readonly type: TypeDeclRefable; readonly typeArgs: readonly DecodedType[]; + // readonly funcType: Lazy; + // readonly alloc: Lazy readonly loc: Loc; }; diff --git a/src/next/grammar/import-parser.ts b/src/next/grammar/import-parser.ts index c52ac3e595..f92963fcec 100644 --- a/src/next/grammar/import-parser.ts +++ b/src/next/grammar/import-parser.ts @@ -1,6 +1,6 @@ import type * as Ast from "@/next/ast"; import { emptyPath, fromString } from "@/next/fs"; -import type { Language, Loc } from "@/next/ast/common"; +import type { Language, Range } from "@/next/ast/common"; import type { SourceLogger } from "@/error/logger-util"; const detectLanguage = (path: string): Language | undefined => { @@ -29,18 +29,18 @@ const guessExtension = ( const stdlibPrefix = "@stdlib/"; export const ImportErrors = (l: SourceLogger) => ({ - importWithBackslash: () => (loc: Loc) => { + importWithBackslash: () => (loc: Range) => { return l.at(loc).error(l.text`Import path can't contain "\\"`); }, - noFolderImports: () => (loc: Loc) => { + noFolderImports: () => (loc: Range) => { return l.at(loc).error(l.text`Cannot import a folder`); }, - invalidImport: () => (loc: Loc) => { + invalidImport: () => (loc: Range) => { return l .at(loc) .error(l.text`Import must start with ./, ../ or @stdlib/`); }, - escapingImport: () => (loc: Loc) => { + escapingImport: () => (loc: Range) => { return l .at(loc) .error(l.text`Standard library imports should be inside its root`); @@ -51,7 +51,7 @@ export type ImportErrors = ReturnType>; export function parseImportString( importText: string, - range: Loc, + range: Range, err: ImportErrors, ): Ast.ImportPath { if (importText.endsWith("/")) { diff --git a/src/next/test/_test.build.ts b/src/next/test/_test.build.ts index 0b7714856d..2f7f16c140 100644 --- a/src/next/test/_test.build.ts +++ b/src/next/test/_test.build.ts @@ -19,9 +19,7 @@ export const runTest = async (path: string): Promise => { } const tcResult = typecheck(result); - types = tcResult.errors.length - ? { errors: tcResult.errors } - : { scope: tcResult.value }; + types = tcResult; }); }); return toJs({ types, result }); diff --git a/src/next/types/tlb.ts b/src/next/types/tlb.ts index 682c3fc549..4b18bfe771 100644 --- a/src/next/types/tlb.ts +++ b/src/next/types/tlb.ts @@ -1,124 +1,4 @@ -import * as Ast from "@/next/ast"; -import * as E from "@/next/types/errors"; -export type TlbType = - | TlbInt - | TlbVarInt - | TlbBool - | TlbAddress - | TlbString - | TlbUnknown - | TlbLiteral - | TlbBits - | TlbMap - | TlbRef - | TlbMaybe - | TlbFields - | TlbUnion - -export type TlbTypeNoRef = - | TlbInt - | TlbVarInt - | TlbBool - | TlbAddress - | TlbLiteral - | TlbBits - | TlbMaybeNoRef - | TlbFieldsNoRef - | TlbUnionNoRef - -export type TlbInt = { - readonly kind: 'int'; - readonly sign: Ast.Signedness; - readonly width: number; -} - -export type TlbVarInt = { - readonly kind: 'varint'; - readonly sign: Ast.Signedness; - readonly width: Ast.VarIntWidth; -} - -export type TlbBool = { - readonly kind: 'bool'; -} - -export type TlbAddress = { - readonly kind: 'address'; -} - -export type TlbString = { - readonly kind: 'string'; -} - -export type TlbUnknown = { - // aka ^Cell - readonly kind: 'unknown'; -} - -export type TlbLiteral = { - readonly kind: 'literal'; - readonly width: number; - readonly value: bigint; -} - -export type TlbBits = { - readonly kind: 'ref'; - readonly width: number; -} - -export type TlbRef = { - readonly kind: 'ref'; - readonly type: TlbType; -} - -export type TlbMap = { - readonly kind: 'map'; - readonly key: TlbTypeNoRef; - readonly value: TlbType; -} - -export type TlbMaybe = { - readonly kind: 'maybe'; - readonly type: TlbType; -} - -export type TlbFields = { - readonly kind: 'fields'; - readonly children: readonly TlbType[]; -} - -export type TlbUnion = { - readonly kind: 'union'; - readonly prefixWidth: number; - readonly children: readonly TlbCase[]; -} - -export type TlbCase = { - readonly prefix: bigint; - readonly type: TlbType; -} - -export type TlbMaybeNoRef = { - readonly kind: 'maybe'; - readonly type: TlbCaseNoRef; -} - -export type TlbFieldsNoRef = { - readonly kind: 'fields'; - readonly children: readonly TlbCaseNoRef[]; -} - -export type TlbUnionNoRef = { - readonly kind: 'union'; - readonly prefixWidth: number; - readonly children: readonly TlbCaseNoRef[]; -} - -export type TlbCaseNoRef = { - readonly prefix: bigint; - readonly type: TlbCaseNoRef; -} export function convertTypeToTlb( node: Ast.DecodedType, From f3502c05834b52445b9c3a43a87fd1b35be9298d Mon Sep 17 00:00:00 2001 From: verytactical <186486509+verytactical@users.noreply.github.com> Date: Sun, 1 Jun 2025 01:38:32 +0400 Subject: [PATCH 29/38] 1 --- spell/cspell-list.txt | 1 + src/next/ast/allocation.ts | 4 +- src/next/ast/checked-stmt.ts | 8 +- src/next/ast/checked.ts | 16 +- src/next/ast/generated/checked-stmt.ts | 8 +- src/next/ast/generated/checked.ts | 15 +- src/next/ast/generated/statement.ts | 4 +- src/next/ast/statement.ts | 4 +- src/next/grammar/grammar.peggy | 2 +- src/next/grammar/grammar.ts | 3 +- src/next/grammar/index.ts | 13 +- src/next/scoping/errors.ts | 123 ------------ src/next/scoping/generated/type.ts | 189 ------------------ src/next/scoping/print-type.ts | 52 ----- src/next/scoping/type.ts | 155 --------------- src/next/scoping/typecheck.ts | 200 ------------------- src/next/types/constant-def.ts | 3 +- src/next/types/constants.ts | 1 + src/next/types/contract.ts | 98 ++++++++- src/next/types/errors.ts | 27 ++- src/next/types/expr-eval.ts | 2 +- src/next/types/expression.ts | 11 +- src/next/types/extensions.ts | 1 + src/next/types/fields.ts | 7 +- src/next/types/message.ts | 2 +- src/next/types/methods.ts | 5 +- src/next/types/override.ts | 2 +- src/next/types/statements.ts | 241 +++++++++++++++------- src/next/types/struct-fields.ts | 2 +- src/next/types/trait.ts | 6 +- src/next/types/type-print.ts | 117 +++++++++++ src/next/types/type.ts | 264 +++++++++++++++++++------ src/next/types/union.ts | 2 +- 33 files changed, 677 insertions(+), 911 deletions(-) delete mode 100644 src/next/scoping/errors.ts delete mode 100644 src/next/scoping/generated/type.ts delete mode 100644 src/next/scoping/print-type.ts delete mode 100644 src/next/scoping/type.ts delete mode 100644 src/next/scoping/typecheck.ts create mode 100644 src/next/types/type-print.ts diff --git a/spell/cspell-list.txt b/spell/cspell-list.txt index c541e2a35d..4a686eeb93 100644 --- a/spell/cspell-list.txt +++ b/spell/cspell-list.txt @@ -61,6 +61,7 @@ flamegraph flamegraphs forall formedness +froms frontmatter funcfiftlib funcid diff --git a/src/next/ast/allocation.ts b/src/next/ast/allocation.ts index 8faccb73ac..ae78e8b84b 100644 --- a/src/next/ast/allocation.ts +++ b/src/next/ast/allocation.ts @@ -1,5 +1,5 @@ -import * as Ast from "@/next/ast"; -import * as E from "@/next/types/errors"; +import type * as Ast from "@/next/ast"; +// import * as E from "@/next/types/errors"; export type TlbType = | TlbInt diff --git a/src/next/ast/checked-stmt.ts b/src/next/ast/checked-stmt.ts index 2750770c54..77771e05e2 100644 --- a/src/next/ast/checked-stmt.ts +++ b/src/next/ast/checked-stmt.ts @@ -1,3 +1,4 @@ +import type { Ordered } from "@/next/ast/checked"; import type { DecodedExpression, LValue } from "@/next/ast/checked-expr"; import type { Id, Loc, OptionalId, TypeId } from "@/next/ast/common"; import type { AugmentedAssignOperation } from "@/next/ast/statement"; @@ -107,12 +108,17 @@ export type DStatementDestruct = { readonly kind: "statement_destruct"; readonly type: TypeId; /** field name -> [field id, local id] */ - readonly identifiers: ReadonlyMap; + readonly identifiers: Ordered; readonly ignoreUnspecifiedFields: boolean; readonly expression: DecodedExpression; readonly loc: Loc; }; +export type DestructPattern = { + readonly field: Id; + readonly variable: OptionalId; +} + export type DStatementBlock = { readonly kind: "statement_block"; readonly statements: DStatementList; diff --git a/src/next/ast/checked.ts b/src/next/ast/checked.ts index 55157e17b1..0255e23c6e 100644 --- a/src/next/ast/checked.ts +++ b/src/next/ast/checked.ts @@ -53,11 +53,13 @@ export type FnSig = { readonly body: Body; } +export type Statements = Lazy; + export type Body = TactBody | FuncBody | FiftBody export type TactBody = { readonly kind: "tact"; - readonly statements: readonly DecodedStatement[]; + readonly statements: Statements; }; export type FuncBody = { readonly kind: "func"; @@ -102,7 +104,7 @@ export type InitFn = { readonly kind: 'function'; // here we just specify the function readonly params: Parameters; - readonly statements: readonly DecodedStatement[]; + readonly statements: Statements; } export type InitParam = { readonly type: Lazy; @@ -179,23 +181,23 @@ export type MessageRecv = { readonly kind: "binary"; readonly name: OptionalId; readonly type: DTypeRef | DTypeBounced; - readonly statements: readonly DecodedStatement[]; + readonly statements: Statements; } export type MessageAnyRecv = { readonly name: OptionalId; - readonly statements: readonly DecodedStatement[]; + readonly statements: Statements; } export type StringRecv = { readonly kind: "string"; readonly comment: string; - readonly statements: readonly DecodedStatement[]; + readonly statements: Statements; } export type StringAnyRecv = { readonly name: OptionalId; - readonly statements: readonly DecodedStatement[]; + readonly statements: Statements; } export type EmptyRecv = { - readonly statements: readonly DecodedStatement[]; + readonly statements: Statements; } export type DeclMem = { diff --git a/src/next/ast/generated/checked-stmt.ts b/src/next/ast/generated/checked-stmt.ts index 70bd9789fd..ffd863cb91 100644 --- a/src/next/ast/generated/checked-stmt.ts +++ b/src/next/ast/generated/checked-stmt.ts @@ -3,6 +3,7 @@ import type * as $ from "@/next/ast/checked-stmt"; import type * as $e from "@/next/ast/checked-expr"; import type * as $c from "@/next/ast/common"; import type * as $s from "@/next/ast/statement"; +import type { Ordered } from "@/next/ast/checked"; export type DStatementLet = $.DStatementLet; export const DStatementLet = (name: $c.OptionalId, expression: $e.DecodedExpression, loc: $c.Loc): $.DStatementLet => Object.freeze({ @@ -43,8 +44,13 @@ export const DStatementAugmentedAssign = (op: $s.AugmentedAssignOperation, path: loc }); export const isDStatementAugmentedAssign = ($value: DStatementAugmentedAssign) => $value.kind === "statement_augmentedassign"; +export type DestructPattern = $.DestructPattern; +export const DestructPattern = (field: $c.Id, variable: $c.OptionalId): $.DestructPattern => Object.freeze({ + field, + variable, +}); export type DStatementDestruct = $.DStatementDestruct; -export const DStatementDestruct = (type_: $c.TypeId, identifiers: ReadonlyMap, ignoreUnspecifiedFields: boolean, expression: $e.DecodedExpression, loc: $c.Loc): $.DStatementDestruct => Object.freeze({ +export const DStatementDestruct = (type_: $c.TypeId, identifiers: Ordered<$.DestructPattern>, ignoreUnspecifiedFields: boolean, expression: $e.DecodedExpression, loc: $c.Loc): $.DStatementDestruct => Object.freeze({ kind: "statement_destruct", type: type_, identifiers, diff --git a/src/next/ast/generated/checked.ts b/src/next/ast/generated/checked.ts index 531b66924b..6940b60555 100644 --- a/src/next/ast/generated/checked.ts +++ b/src/next/ast/generated/checked.ts @@ -109,7 +109,7 @@ export const Parameters = (order: readonly $.Parameter[], set: ReadonlySet Object.freeze({ +export const TactBody = (statements: Lazy): $.TactBody => Object.freeze({ kind: "tact", statements }); @@ -178,30 +178,30 @@ export const TraitSig = (content: Lazy<$.CommonSig | undefined, $.Bo }); export const isTraitSig = ($value: TraitSig) => $value.kind === "trait"; export type MessageRecv = $.MessageRecv; -export const MessageRecv = (name: $c.OptionalId, type_: $d.DTypeRef | $d.DTypeBounced, statements: readonly DecodedStatement[]): $.MessageRecv => Object.freeze({ +export const MessageRecv = (name: $c.OptionalId, type_: $d.DTypeRef | $d.DTypeBounced, statements: Lazy): $.MessageRecv => Object.freeze({ kind: "binary", name, type: type_, statements }); export type MessageAnyRecv = $.MessageAnyRecv; -export const MessageAnyRecv = (name: $c.OptionalId, statements: readonly DecodedStatement[]): $.MessageAnyRecv => Object.freeze({ +export const MessageAnyRecv = (name: $c.OptionalId, statements: Lazy): $.MessageAnyRecv => Object.freeze({ name, statements }); export type StringRecv = $.StringRecv; -export const StringRecv = (comment: string, statements: readonly DecodedStatement[]): $.StringRecv => Object.freeze({ +export const StringRecv = (comment: string, statements: Lazy): $.StringRecv => Object.freeze({ kind: "string", comment, statements }); export type StringAnyRecv = $.StringAnyRecv; -export const StringAnyRecv = (name: $c.OptionalId, statements: readonly DecodedStatement[]): $.StringAnyRecv => Object.freeze({ +export const StringAnyRecv = (name: $c.OptionalId, statements: Lazy): $.StringAnyRecv => Object.freeze({ name, statements }); export type EmptyRecv = $.EmptyRecv; -export const EmptyRecv = (statements: readonly DecodedStatement[]): $.EmptyRecv => Object.freeze({ +export const EmptyRecv = (statements: Lazy): $.EmptyRecv => Object.freeze({ statements }); export type OpcodeRecv = $.OpcodeRecv; @@ -239,12 +239,13 @@ export const InitSimple = (fill: $.Ordered<$.InitParam>, loc: $c.Loc): $.InitSim }); export const isInitSimple = ($value: InitSimple) => $value.kind === "simple"; export type InitFn = $.InitFn; -export const InitFn = (params: $.Parameters, statements: readonly DecodedStatement[]): $.InitFn => Object.freeze({ +export const InitFn = (params: $.Parameters, statements: Lazy): $.InitFn => Object.freeze({ kind: "function", params, statements }); export const isInitFn = ($value: InitFn) => $value.kind === "function"; +export type Statements = $.Statements; export type InitSig = $.InitSig; export type ContractSig = $.ContractSig; export type TypeDeclRefable = $.TypeDeclRefable; diff --git a/src/next/ast/generated/statement.ts b/src/next/ast/generated/statement.ts index c3a1e1df3f..aaf483d696 100644 --- a/src/next/ast/generated/statement.ts +++ b/src/next/ast/generated/statement.ts @@ -93,7 +93,8 @@ export const isStatementAugmentedAssign = ($value: StatementAugmentedAssign) => export type StatementDestruct = $.StatementDestruct; export const StatementDestruct = ( type_: $c.TypeId, - identifiers: ReadonlyMap, + typeArgs: readonly $t.Type[], + identifiers: readonly (readonly [$c.Id, $c.OptionalId])[], ignoreUnspecifiedFields: boolean, expression: $e.Expression, loc: $c.Loc, @@ -101,6 +102,7 @@ export const StatementDestruct = ( Object.freeze({ kind: "statement_destruct", type: type_, + typeArgs, identifiers, ignoreUnspecifiedFields, expression, diff --git a/src/next/ast/statement.ts b/src/next/ast/statement.ts index b22d76e8fd..b88c118136 100644 --- a/src/next/ast/statement.ts +++ b/src/next/ast/statement.ts @@ -119,8 +119,8 @@ export type StatementForEach = { export type StatementDestruct = { readonly kind: "statement_destruct"; readonly type: TypeId; - /** field name -> [field id, local id] */ - readonly identifiers: ReadonlyMap; + readonly typeArgs: readonly Type[]; + readonly identifiers: readonly (readonly [Id, OptionalId])[]; readonly ignoreUnspecifiedFields: boolean; readonly expression: Expression; readonly loc: Loc; diff --git a/src/next/grammar/grammar.peggy b/src/next/grammar/grammar.peggy index 4b096326ac..2c478fe82c 100644 --- a/src/next/grammar/grammar.peggy +++ b/src/next/grammar/grammar.peggy @@ -260,7 +260,7 @@ statement statements = "{" @statement* "}"; StatementLet = keyword<"let"> name:Id type:ascription? "=" init:expression semicolon; -StatementDestruct = keyword<"let"> type:TypeId "{" fields:inter rest:optionalRest "}" "=" init:expression semicolon; +StatementDestruct = keyword<"let"> type:TypeId typeArgs:typeArgs? "{" fields:inter rest:optionalRest "}" "=" init:expression semicolon; StatementBlock = body:statements; StatementReturn = keyword<"return"> expression:expression? semicolon; StatementExpression = expression:expression semicolon; diff --git a/src/next/grammar/grammar.ts b/src/next/grammar/grammar.ts index 90b2cdc2f2..e9fa4bda9f 100644 --- a/src/next/grammar/grammar.ts +++ b/src/next/grammar/grammar.ts @@ -274,6 +274,7 @@ export namespace $ast { export type StatementDestruct = $.Located<{ readonly $: "StatementDestruct"; readonly type: TypeId; + readonly typeArgs: typeArgs | undefined; readonly fields: inter; readonly rest: optionalRest; readonly init: expression; @@ -583,7 +584,7 @@ export const generic = (T: $.Parser): $.Parser<$ast.generic> => $.righ export const typeParams: $.Parser<$ast.typeParams> = generic(TypeId); export const typeArgs: $.Parser<$ast.typeArgs> = generic($type); export const StatementLet: $.Parser<$ast.StatementLet> = $.loc($.field($.pure("StatementLet"), "$", $.right(keyword($.str("let")), $.field(Id, "name", $.field($.opt(ascription), "type", $.right($.str("="), $.field($.lazy(() => expression), "init", $.right(semicolon, $.eps)))))))); -export const StatementDestruct: $.Parser<$ast.StatementDestruct> = $.loc($.field($.pure("StatementDestruct"), "$", $.right(keyword($.str("let")), $.field(TypeId, "type", $.right($.str("{"), $.field(inter($.lazy(() => destructItem), $.str(",")), "fields", $.field($.lazy(() => optionalRest), "rest", $.right($.str("}"), $.right($.str("="), $.field($.lazy(() => expression), "init", $.right(semicolon, $.eps))))))))))); +export const StatementDestruct: $.Parser<$ast.StatementDestruct> = $.loc($.field($.pure("StatementDestruct"), "$", $.right(keyword($.str("let")), $.field(TypeId, "type", $.field($.opt(typeArgs), "typeArgs", $.right($.str("{"), $.field(inter($.lazy(() => destructItem), $.str(",")), "fields", $.field($.lazy(() => optionalRest), "rest", $.right($.str("}"), $.right($.str("="), $.field($.lazy(() => expression), "init", $.right(semicolon, $.eps)))))))))))); export const StatementBlock: $.Parser<$ast.StatementBlock> = $.loc($.field($.pure("StatementBlock"), "$", $.field($.lazy(() => statements), "body", $.eps))); export const StatementReturn: $.Parser<$ast.StatementReturn> = $.loc($.field($.pure("StatementReturn"), "$", $.right(keyword($.str("return")), $.field($.opt($.lazy(() => expression)), "expression", $.right(semicolon, $.eps))))); export const StatementCondition: $.Parser<$ast.StatementCondition> = $.loc($.field($.pure("StatementCondition"), "$", $.right(keyword($.str("if")), $.field($.lazy(() => expression), "condition", $.field($.lazy(() => statements), "trueBranch", $.field($.opt($.right(keyword($.str("else")), $.alt($.lazy(() => FalseBranch), $.lazy(() => StatementCondition)))), "falseBranch", $.eps)))))); diff --git a/src/next/grammar/index.ts b/src/next/grammar/index.ts index 6024c9e712..6adb9e4659 100644 --- a/src/next/grammar/index.ts +++ b/src/next/grammar/index.ts @@ -718,25 +718,18 @@ const parseDestructItem: ( const parseStatementDestruct = ({ type, + typeArgs, fields, rest, init, loc, }: $ast.StatementDestruct): Handler => (ctx) => { - const ids: Map = new Map(); - for (const param of parseList(fields)) { - const pair = parseDestructItem(param)(ctx); - const [field] = pair; - const name = field.text; - if (ids.has(name)) { - ctx.err.duplicateField(name)(ctx.toRange(param.loc)); - } - ids.set(name, pair); - } + const ids = map(parseList(fields), parseDestructItem)(ctx); return Ast.StatementDestruct( parseTypeId(type)(ctx), + map(parseList(typeArgs), parseType)(ctx), ids, rest.$ === "RestArgument", parseExpression(init)(ctx), diff --git a/src/next/scoping/errors.ts b/src/next/scoping/errors.ts deleted file mode 100644 index 3ec6645563..0000000000 --- a/src/next/scoping/errors.ts +++ /dev/null @@ -1,123 +0,0 @@ -import type { SourceLogger } from "@/error/logger-util"; -import type { Implicit } from "@/next/imports/source"; -import type { Loc } from "@/next/ast"; -import type * as Ty from "@/next/scoping/generated/type"; -import { printType } from "@/next/scoping/print-type"; - -export const TcErrors = (l: SourceLogger) => ({ - shadowsImported: (name: string, prevPath: string, prevRange: Loc | Implicit) => (loc: Loc | Implicit) => { - if (loc.kind !== 'range') { - return l.internal(l.text`Import from standard library cannot shadow anything`); - } - const id = prevRange.kind === 'range' - ? l.text`"${l.locatedId(name, prevPath, prevRange)}"` - : l.text`from standard library`; - return l.at(loc).error(l.text`Declaration of "${name}" shadows previous declaration ${id}`); - }, - shadowsBuiltin: (name: string) => (loc: Loc | Implicit) => { - if (loc.kind !== 'range') { - return l.internal(l.text`Import from standard library cannot shadow anything`); - } - return l.at(loc).error(l.text`"${name}" is primitive and cannot be redefined`); - }, - typeNotDefined: (name: string) => (loc: Ty.Loc) => { - if (loc.kind !== 'range') { - return l.internal(l.text`${loc.kind} type is not defined`); - } - return l.at(loc).error(l.text`Type "${name}" is not defined`); - }, - typeArity: (name: string, factualLen: number, expectedLen: number) => (loc: Ty.Loc) => { - if (loc.kind !== 'range') { - return l.internal(l.text`${loc.kind} type arity mismatch`); - } - return l.at(loc).error(l.text`Generic type "${name}" expected ${expectedLen.toString()} parameters, but got ${factualLen.toString()}`); - }, - fnArity: (name: string, factualLen: number, expectedLen: number) => (loc: Ty.Loc) => { - if (loc.kind !== 'range') { - return l.internal(l.text`${loc.kind} arity mismatch`); - } - return l.at(loc).error(l.text`"${name}" expected ${expectedLen.toString()} parameters, but got ${factualLen.toString()}`); - }, - noHkt: (name: string) => (loc: Ty.Loc) => { - if (loc.kind !== 'range') { - return l.internal(l.text`${loc.kind} is a hkt`); - } - return l.at(loc).error(l.text`Type variable "${name}" is not a type constructor`); - }, - instantiationLimit: () => (loc: Ty.Loc) => { - if (loc.kind !== 'range') { - return l.internal(l.text`${loc.kind} too deep`); - } - return l.at(loc).error(l.text`Instantiation is excessively deep`); - }, - typeMismatch: (root: MismatchTree) => (loc: Ty.Loc) => { - if (loc.kind !== 'range') { - return l.internal(l.text`${loc.kind} mismatch`); - } - const rec = ({ to, from, children }: MismatchTree, prefix: M, depth: number): M => { - const padding = new Array(depth + 1).join(' '); - const row = l.text`${padding}${printType(from)} is not assignable to ${printType(to)}`; - return children.reduce((message, child) => { - return rec(child, message, depth + 1); - }, l.text`${prefix}\n${row}`); - }; - return l.at(loc).error(rec(root, l.text``, 0)); - }, - danglingTypeParam: () => (loc: Ty.Loc) => { - if (loc.kind !== 'range') { - return l.internal(l.text`${loc.kind} mismatch`); - } - // def fun(/* T unused */) { } - return l.at(loc).error(l.text`Cannot infer type parameter`); - }, - contractNotDefined: () => (loc: Ty.Loc) => { - if (loc.kind !== 'range') { - return l.internal(l.text`${loc.kind} mismatch`); - } - return l.at(loc).error(l.text`No such contract`); - }, - typeNotContract: () => (loc: Ty.Loc) => { - if (loc.kind !== 'range') { - return l.internal(l.text`${loc.kind} mismatch`); - } - return l.at(loc).error(l.text`Type is not a contract`); - }, - structNotDefined: () => (loc: Ty.Loc) => { - if (loc.kind !== 'range') { - return l.internal(l.text`${loc.kind} mismatch`); - } - return l.at(loc).error(l.text`No such struct or message`); - }, - typeNotStruct: () => (loc: Ty.Loc) => { - if (loc.kind !== 'range') { - return l.internal(l.text`${loc.kind} mismatch`); - } - return l.at(loc).error(l.text`Type is not a struct or message`); - }, - staticMethodNotDefined: () => (loc: Ty.Loc) => { - if (loc.kind !== 'range') { - return l.internal(l.text`${loc.kind} mismatch`); - } - return l.at(loc).error(l.text`Only fromCell and fromSlice static methods are supported`); - }, - noInit: () => (loc: Ty.Loc) => { - if (loc.kind !== 'range') { - return l.internal(l.text`${loc.kind} mismatch`); - } - return l.at(loc).error(l.text`Contract has neither init() nor parameters`); - }, - duplicateField: () => (loc: Ty.Loc) => { - if (loc.kind !== 'range') { - return l.internal(l.text`${loc.kind} mismatch`); - } - return l.at(loc).error(l.text`Duplicate field in struct instance`); - }, - fieldNotDefined: () => (loc: Ty.Loc) => { - if (loc.kind !== 'range') { - return l.internal(l.text`${loc.kind} mismatch`); - } - return l.at(loc).error(l.text`No such field`); - }, -}); - -export type TcErrors = ReturnType>; \ No newline at end of file diff --git a/src/next/scoping/generated/type.ts b/src/next/scoping/generated/type.ts deleted file mode 100644 index 4f052b0153..0000000000 --- a/src/next/scoping/generated/type.ts +++ /dev/null @@ -1,189 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unnecessary-condition */ -import type * as $ from "@/next/scoping/type"; - -export type Inferred = $.Inferred; -export const Inferred = (range: $.Loc, readableName: string): $.Inferred => Object.freeze({ - kind: "inferred", - range, - readableName -}); -export const isInferred = ($value: Inferred) => $value.kind === "inferred"; -export type Loc = $.Loc; - -export type Signedness = $.Signedness; -export const allSignedness: readonly $.Signedness[] = ["signed", "unsigned"]; -export type IFInt = $.IFInt; -export const IFInt = ( - sign: $.Signedness, - width: number, - loc: $.Loc, -): $.IFInt => - Object.freeze({ - kind: "FInt", - sign, - width, - loc, - }); -export const isIFInt = ($value: IFInt) => $value.kind === "FInt"; -export type VarIntWidth = $.VarIntWidth; -export const allVarIntWidth: readonly $.VarIntWidth[] = ["16", "32"]; -export type IFVarInt = $.IFVarInt; -export const IFVarInt = ( - sign: $.Signedness, - width: $.VarIntWidth, - loc: $.Loc, -): $.IFVarInt => - Object.freeze({ - kind: "FVarInt", - sign, - width, - loc, - }); -export const isIFVarInt = ($value: IFVarInt) => $value.kind === "FVarInt"; -export type IntFormat = $.IntFormat; -export type TypeInt = $.TypeInt; -export const TypeInt = (format: $.IntFormat, loc: $.Loc): $.TypeInt => - Object.freeze({ - kind: "TyInt", - format, - loc, - }); -export const isTypeInt = ($value: TypeInt) => $value.kind === "TyInt"; -export type SFBits = $.SFBits; -export const SFBits = (bits: number, loc: $.Loc): $.SFBits => - Object.freeze({ - kind: "SFBits", - bits, - loc, - }); -export const isSFBits = ($value: SFBits) => $value.kind === "SFBits"; -export type SFRemaining = $.SFRemaining; -export const SFRemaining = (loc: $.Loc): $.SFRemaining => - Object.freeze({ - kind: "SFRemaining", - loc, - }); -export const isSFRemaining = ($value: SFRemaining) => - $value.kind === "SFRemaining"; -export type SFDefault = $.SFDefault; -export const SFDefault = (loc: $.Loc): $.SFDefault => - Object.freeze({ - kind: "SFDefault", - loc, - }); -export const isSFDefault = ($value: SFDefault) => $value.kind === "SFDefault"; -export type SliceFormat = $.SliceFormat; -export type TypeSlice = $.TypeSlice; -export const TypeSlice = (format: $.SliceFormat, loc: $.Loc): $.TypeSlice => - Object.freeze({ - kind: "TySlice", - format, - loc, - }); -export const isTypeSlice = ($value: TypeSlice) => $value.kind === "TySlice"; -export type RemFormat = $.RemFormat; -export type TypeCell = $.TypeCell; -export const TypeCell = (format: $.RemFormat, loc: $.Loc): $.TypeCell => - Object.freeze({ - kind: "TyCell", - format, - loc, - }); -export const isTypeCell = ($value: TypeCell) => $value.kind === "TyCell"; -export type TypeBuilder = $.TypeBuilder; -export const TypeBuilder = ( - format: $.RemFormat, - loc: $.Loc, -): $.TypeBuilder => - Object.freeze({ - kind: "TyBuilder", - format, - loc, - }); -export const isTypeBuilder = ($value: TypeBuilder) => - $value.kind === "TyBuilder"; -export type TypeUnit = $.TypeUnit; -export const TypeUnit = (loc: $.Loc): $.TypeUnit => - Object.freeze({ - kind: "unit_type", - loc, - }); -export const isTypeUnit = ($value: TypeUnit) => $value.kind === "unit_type"; -export type TypeTensor = $.TypeTensor; -export const TypeTensor = ( - typeArgs: readonly $.Type[], - loc: $.Loc, -): $.TypeTensor => - Object.freeze({ - kind: "tensor_type", - typeArgs, - loc, - }); -export const isTypeTensor = ($value: TypeTensor) => - $value.kind === "tensor_type"; -export type TypeTuple = $.TypeTuple; -export const TypeTuple = ( - typeArgs: readonly $.Type[], - loc: $.Loc, -): $.TypeTuple => - Object.freeze({ - kind: "tuple_type", - typeArgs, - loc, - }); -export const isTypeTuple = ($value: TypeTuple) => $value.kind === "tuple_type"; -export type TypeCons = $.TypeCons; -export const TypeCons = ( - name: $.TypeId, - typeArgs: readonly $.Type[], - loc: $.Loc, -): $.TypeCons => - Object.freeze({ - kind: "cons_type", - name, - typeArgs, - loc, - }); -export const isTypeCons = ($value: TypeCons) => $value.kind === "cons_type"; -export type LocType = $.LocType; -export type Type = $.Type; -export type TypeMap = $.TypeMap; -export const TypeMap = (key: $.Type, value: $.Type, loc: $.Loc): $.TypeMap => - Object.freeze({ - kind: "map_type", - key, - value, - loc, - }); -export const isTypeMap = ($value: TypeMap) => $value.kind === "map_type"; -export type TypeFunction = $.TypeFunction; -export const TypeFunction = (params: readonly $.Type[], returnType: $.Type | undefined): $.TypeFunction => Object.freeze({ - kind: "function", - params, - returnType -}); -export const isTypeFunction = ($value: TypeFunction) => $value.kind === "function"; -export type Builtin = $.Builtin; -export const Builtin = (readableName: string): $.Builtin => Object.freeze({ - kind: "builtin", - readableName -}); -export const isBuiltin = ($value: Builtin) => $value.kind === "builtin"; -export type TypeVar = $.TypeVar; -export const TypeVar = (id: number): $.TypeVar => Object.freeze({ - kind: "type_var", - id -}); -export const isTypeVar = ($value: TypeVar) => $value.kind === "type_var"; -export type TypeId = $.TypeId; -export const TypeId = (text: string, loc: $.Loc): $.TypeId => Object.freeze({ - kind: "type_id", - text, - loc -}); -export const isTypeId = ($value: TypeId) => $value.kind === "type_id"; -export type TypeErrorRecovered = $.TypeErrorRecovered; -export const TypeErrorRecovered = (): $.TypeErrorRecovered => Object.freeze({ - kind: "ERROR" -}); -export const isTypeErrorRecovered = ($value: TypeErrorRecovered) => $value.kind === "ERROR"; diff --git a/src/next/scoping/print-type.ts b/src/next/scoping/print-type.ts deleted file mode 100644 index 4ff37afed4..0000000000 --- a/src/next/scoping/print-type.ts +++ /dev/null @@ -1,52 +0,0 @@ -import type * as Ty from "@/next/scoping/generated/type"; - -export const printType = (type: Ty.Type): string => { - switch (type.kind) { - case "ERROR": return `_`; - case "type_var": return `#${type.id}`; - case "unit_type": return `()`; - case "TyInt": return `Int${printIntFormat(type.format)}` - case "TySlice": return `Slice${printSliceFormat(type.format)}`; - case "TyCell": return `Cell${printRemFormat(type.format)}`; - case "TyBuilder": return `Builder${printRemFormat(type.format)}`; - case "tuple_type": return `[${printTypeList(type.typeArgs)}]`; - case "tensor_type": return `(${printTypeList(type.typeArgs)})`; - case "map_type": return `map<${printType(type.key)}, ${printType(type.value)}>` - case "cons_type": { - return type.name.text + ( - type.typeArgs.length === 0 - ? '' - : `<${printTypeList(type.typeArgs)}>` - ); - } - } -}; - -const printTypeList = (types: readonly Ty.Type[]): string => { - return types.map(type => printType(type)).join(', '); -}; - -const printIntFormat = (format: Ty.IntFormat): string => { - if (format.kind === 'FInt' && format.sign === 'signed' && format.width === 257) { - return ''; - } - return " as " + (format.kind === 'FVarInt' ? "var" : "") - + (format.sign === 'unsigned' ? 'uint' : 'int') - + (format.kind === 'FVarInt' ? format.width : format.width.toString()); -}; - -const printSliceFormat = (format: Ty.SliceFormat): string => { - if (format.kind === 'SFBits') { - // FIXME: bits not divisible by 8 - return ` as bytes${format.bits >> 3}`; - } else { - return printRemFormat(format); - } -}; - -const printRemFormat = (format: Ty.RemFormat): string => { - switch (format.kind) { - case "SFRemaining": return ` as remaining`; - case "SFDefault": return ``; - } -}; diff --git a/src/next/scoping/type.ts b/src/next/scoping/type.ts deleted file mode 100644 index e3d6847ccb..0000000000 --- a/src/next/scoping/type.ts +++ /dev/null @@ -1,155 +0,0 @@ -import type { Loc } from "@/next/ast"; - -export type TypeId = { - readonly kind: "type_id"; - readonly text: string; - readonly loc: Loc; -}; - -export type Loc = Loc | Inferred | Builtin; - -/** - * Type that was computed from AST - */ -export type Inferred = { - readonly kind: "inferred"; - readonly range: Loc; - readonly readableName: string; -} - -/** - * Type that came from builtins, where we don't have location at all - */ -export type Builtin = { - readonly kind: "builtin"; - readonly readableName: string; -} - -export type TypeFunction = { - readonly kind: "function"; - // readonly typeParams: readonly string[]; - readonly params: readonly Type[]; - readonly returnType: undefined | Type; -} - -export type Type = - | TypeErrorRecovered - | TypeVar - | TypeMap - | TypeCons - | TypeInt - | TypeSlice - | TypeCell - | TypeBuilder - | TypeTuple - | TypeUnit - | TypeTensor; - -export type LocType = - | TypeMap - | TypeCons - | TypeInt - | TypeSlice - | TypeCell - | TypeBuilder - | TypeTuple - | TypeUnit - | TypeTensor - -export type TypeErrorRecovered = { - readonly kind: "ERROR"; -}; - -export type TypeVar = { - readonly kind: "type_var"; - readonly id: number; -}; - -export type TypeCons = { - readonly kind: "cons_type"; - readonly name: TypeId; - readonly typeArgs: readonly Type[]; - readonly loc: Loc; -}; - -export type TypeBool = { - readonly kind: "TyBool"; - readonly loc: Loc; -}; - -export type TypeInt = { - readonly kind: "TyInt"; - readonly format: IntFormat; - readonly loc: Loc; -}; -export type IntFormat = IFInt | IFVarInt; -export type IFInt = { - readonly kind: "FInt"; - readonly sign: Signedness; - readonly width: number; - readonly loc: Loc; -}; -export type IFVarInt = { - readonly kind: "FVarInt"; - readonly sign: Signedness; - readonly width: VarIntWidth; - readonly loc: Loc; -}; -export type VarIntWidth = "16" | "32"; -export type Signedness = "signed" | "unsigned"; - -export type TypeSlice = { - readonly kind: "TySlice"; - readonly format: SliceFormat; - readonly loc: Loc; -}; -export type SliceFormat = SFBits | SFRemaining | SFDefault; -export type SFBits = { - readonly kind: "SFBits"; - readonly bits: number; - readonly loc: Loc; -}; -export type SFRemaining = { - readonly kind: "SFRemaining"; - readonly loc: Loc; -}; -export type SFDefault = { - readonly kind: "SFDefault"; - readonly loc: Loc; -}; - -export type TypeCell = { - readonly kind: "TyCell"; - readonly format: RemFormat; - readonly loc: Loc; -}; -export type TypeBuilder = { - readonly kind: "TyBuilder"; - readonly format: RemFormat; - readonly loc: Loc; -}; -export type RemFormat = SFRemaining | SFDefault; - -export type TypeTuple = { - readonly kind: "tuple_type"; - readonly typeArgs: readonly Type[]; - readonly loc: Loc; -}; - -export type TypeUnit = { - readonly kind: "unit_type"; - readonly loc: Loc; -}; - -export type TypeTensor = { - readonly kind: "tensor_type"; - readonly typeArgs: readonly Type[]; - readonly loc: Loc; -}; - -export type TypeMap = { - readonly kind: "map_type"; - readonly key: Type; // any type except tensor - readonly value: Type; // any type except tensor - readonly loc: Loc; -}; diff --git a/src/next/scoping/typecheck.ts b/src/next/scoping/typecheck.ts deleted file mode 100644 index 91d85dcddb..0000000000 --- a/src/next/scoping/typecheck.ts +++ /dev/null @@ -1,200 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unnecessary-condition */ -/* eslint-disable @typescript-eslint/no-base-to-string */ -import type * as Ast from "@/next/ast"; -import * as Ty from "@/next/scoping/generated/type"; -import { zip } from "@/utils/array"; -import { throwInternal } from "@/error/errors"; -import { type MismatchTree, TcErrors } from "@/next/scoping/errors"; - -const VarGen = () => { - let nextId = 0; - return function freshTVar() { - const id = nextId++; - return Ast.VTypeVar(id); - }; -}; - -// left: Either -// left: Int -// left: Maybe -// left: Slice - -// isGround = нет типовых переменных: Either -// isSimple = Cons : Either -// isGround || isSimple -// extends fun foo(self: Either) {} -// extends fun foo(self: Either) {} -// fun bar() { let e: Either = ...; e.foo() } - -// extends fun foo(self: T); -// extends fun foo(self: Either); -// let x: Either; -// x.foo(); -// findTypeMethod("foo", Either); - -// const contractExt: Map = new Map(); - -const isNull = (type: Ty.LocType) => type.kind === 'cons_type' && type.name.text === 'Null'; - -const getExprChecker = ( - getType: (key: string) => Ast.TypeDecl | undefined, - hasTypeParam: (key: string) => boolean, - err: TcErrors, -) => { - const typeVars: Map = new Map(); - - const simplifyHead = (type: Ty.Type): Ty.Type => simplifyHeadAux(type, 0); - const simplifyHeadAux = (type: Ty.Type, depth: number): Ty.Type => { - switch (type.kind) { - case "type_var": return simplifyVar(type, depth); - case "cons_type": return simplifyAlias(type, depth); - default: return type; - } - }; - const simplifyVar = (type: Ty.TypeVar, depth: number): Ty.Type => { - const foundType = typeVars.get(type.id); - return foundType ? simplifyHeadAux(foundType, depth + 1) : type; - }; - const simplifyAlias = (type: Ty.TypeCons, depth: number): Ty.Type => { - if (depth >= 100) { - err.instantiationLimit()(type.loc); - return Ty.TypeErrorRecovered(); - } - const name = type.name.text; - const maybeAlias = getType(name); - if (!maybeAlias) { - err.typeNotDefined(name)(type.name.loc); - return Ty.TypeErrorRecovered(); - } - if (maybeAlias.kind !== 'alias_decl') { - return type; - } - const factualLen = type.typeArgs.length; - const expectedLen = maybeAlias.typeParams.length; - if (factualLen !== expectedLen) { - err.typeArity(name, factualLen, expectedLen)(type.loc); - } - return simplifyHeadAux( - substParams( - maybeAlias.type, - maybeAlias.typeParams, - type.typeArgs, - ), - depth + 1, - ); - }; - - const assignTo = (to: Ty.Type, from: Ty.Type): boolean => { - if (from.kind === 'ERROR') { - return false; - } - if (from.kind === 'type_var') { - return throwInternal("Type variable on top level of assignment"); - } - const children: MismatchTree[] = []; - const result = assignToAux1(to, from, children); - if (!result) { - for (const tree of children) { - err.typeMismatch(tree)(from.loc); - } - } - return result; - }; - const assignAll = ( - to: readonly Ty.Type[], - from: readonly Ty.Type[], - parent: MismatchTree[] - ): boolean => { - if (to.length !== from.length) { - return throwInternal("Arity check failed after kind checks"); - } - return zip(to, from) - .map(([elemTo, elemFrom]) => assignToAux1(elemTo, elemFrom, parent)) - // eslint-disable-next-line @typescript-eslint/no-unnecessary-boolean-literal-compare - .every(x => x === true) - }; - const assignToAux1 = ( - to: Ty.Type, - from: Ty.Type, - parent: MismatchTree[] - ) => { - // Substitute type variables and aliases - to = simplifyHead(to); - from = simplifyHead(from); - // If either argument is already a recovery, no more - // error messages should be emitted - if (to.kind === 'ERROR' || from.kind === 'ERROR') { - return false; - } - // If we're assigning something with type variables in it, - // the global invariant of type synthesis was violated - if (from.kind === 'type_var') { - return throwInternal("Type variable on right side of assignment"); - } - if (to.kind === 'type_var') { - typeVars.set(to.id, from); - return true; - } - const children: MismatchTree[] = []; - const result = assignToAux2(to, from, children); - if (!result) { - parent.push({ to, from, children }); - } - return result; - }; - const assignToAux2 = ( - to: Ty.LocType, - from: Ty.LocType, - tree: MismatchTree[], - ): boolean => { - switch (to.kind) { - case 'TyBuilder': - case 'TyCell': - case 'TyInt': - case 'TySlice': - case "unit_type": { - return from.kind === to.kind; - } - case "tuple_type": - case "tensor_type": { - return from.kind === to.kind && assignAll(to.typeArgs, from.typeArgs, tree); - } - case "map_type": { - return isNull(from) - || from.kind === 'map_type' && assignToAux1(to.key, from.key, tree) && assignToAux1(to.value, from.value, tree); - } - case 'cons_type': { - return hasTypeParam(to.name.text) && to.typeArgs.length === 0 - || to.name.text === 'Maybe' && isNull(from) - || from.kind === 'cons_type' && to.name.text === from.name.text && assignAll(to.typeArgs, from.typeArgs, tree); - } - } - }; - - let nextId = 0; - const freshTVar = () => { - const id = nextId++; - - const resolve = (loc: Ty.Loc) => { - const type = typeVars.get(id); - if (!type) { - // TODO: think if it should be check at declaration - // time and `throwInternal` here - err.danglingTypeParam()(loc); - return Ty.TypeErrorRecovered(); - } - return type; - }; - - return { - type: Ty.TypeVar(id), - resolve, - }; - }; - - return { - assignTo, - freshTVar, - checkExpr, - }; -}; diff --git a/src/next/types/constant-def.ts b/src/next/types/constant-def.ts index fea0694cbb..ceadaf6423 100644 --- a/src/next/types/constant-def.ts +++ b/src/next/types/constant-def.ts @@ -4,6 +4,7 @@ import { decodeExpr } from "@/next/types/expression"; import { evalExpr } from "@/next/types/expr-eval"; export function decodeConstantDef( + defLoc: Ast.Loc, typeParams: Ast.TypeParams, { type, initializer }: Ast.ConstantDef, scopeRef: () => Ast.Scope, @@ -24,7 +25,7 @@ export function decodeConstantDef( ); const computed = expr.computedType; const ascribed = yield* ascribedType(); - yield* assignType( ascribed, computed, scopeRef); + yield* assignType(defLoc, ascribed, computed); return yield* evalExpr(expr, scopeRef); }); return [ascribedType, lazyExpr]; diff --git a/src/next/types/constants.ts b/src/next/types/constants.ts index bbd8e9a3bf..ef13f68b72 100644 --- a/src/next/types/constants.ts +++ b/src/next/types/constants.ts @@ -53,6 +53,7 @@ function* decodeConstant( } else { const typeParams = Ast.TypeParams([], new Set()); const [type, expr] = decodeConstantDef( + loc, typeParams, init, scopeRef, diff --git a/src/next/types/contract.ts b/src/next/types/contract.ts index 40ed5f6597..f54d437b74 100644 --- a/src/next/types/contract.ts +++ b/src/next/types/contract.ts @@ -10,6 +10,7 @@ import { getReceivers } from "@/next/types/receivers"; import { decodeDealiasTypeLazy, decodeTypeLazy } from "@/next/types/type"; import { decodeParams } from "@/next/types/type-fn"; import { decodeStatements } from "@/next/types/statements"; +import { Void } from "@/next/types/builtins"; export function* decodeContract( contract: Ast.Contract, @@ -23,7 +24,11 @@ export function* decodeContract( // to compute fields for empty init, we need to know contentLazy // to check init body in initLazy we have to know `self` from contentLazy - const decodedInit = yield* decodeInit(init, () => contentLazy(), scopeRef); + const decodedInit = yield* decodeInit( + init, + () => contentLazy(), + scopeRef, + ); // delayed until we get all traits and init const contentLazy: Ast.Lazy = Ast.Lazy(function* () { @@ -35,6 +40,7 @@ export function* decodeContract( // const contentRef = () => content; const content: Ast.ContractContent = { fieldish: yield* getFieldishFromContract( + contractSig, name, traits, decodedInit, @@ -43,6 +49,7 @@ export function* decodeContract( scopeRef, ), methods: yield* getMethodsFromContract( + contractSig, name, traits, methods, @@ -59,10 +66,13 @@ export function* decodeContract( return content; }); - return Ast.ContractSig(attributes, decodedInit, contentLazy); + const contractSig = Ast.ContractSig(attributes, decodedInit, contentLazy); + + return contractSig; } function* decodeInit( + selfType: Ast.SelfType, init: Ast.Init | undefined, contentLazy: Ast.Lazy, scopeRef: () => Ast.Scope, @@ -130,9 +140,20 @@ function* decodeInit( return decodeDealiasTypeLazy(typeParams, type, scopeRef); }, params); - const body = decodeStatements(statements, scopeRef); + const body = yield* decodeStatements( + statements, + typeParams, + selfType, + Void, + yield* getRequired(selfType), + scopeRef, + ); + + // TODO: make Lazy a builder + // (Lazy: LazyBuilder) + // Lazy(`body of ${name}`, function* (Lazy) { ... }) - return Ast.InitFn(decodedParams, body); + return Ast.InitFn(decodedParams, body.node); } } const EDuplicateParam = ( @@ -166,13 +187,70 @@ const ENoInitializerEmpty = ( ], }); +function* getRequired(selfType: Ast.SelfType | undefined): E.WithLog> { + if (!selfType) { + return new Set(); + } + const required: Set = new Set(); + switch (selfType.kind) { + case "type_ref": { + switch (selfType.type.kind) { + case "contract": + case "trait": { + const { fieldish } = (yield* selfType.type.content()); + for (const [name, field] of fieldish.map) { + if (field.decl.kind === 'field' && !field.decl.init) { + required.add(name) + } + } + return required; + } + case "struct": + case "message": + case "union": { + // no requirement to fill self on these, because they have + // no init() + return required; + } + } + // linter needs this + return required; + } + case "map_type": + case "TypeMaybe": + case "tuple_type": + case "tensor_type": + case "TyInt": + case "TySlice": + case "TyCell": + case "TyBuilder": + case "unit_type": + case "TypeVoid": + case "TypeNull": + case "TypeBool": + case "TypeAddress": + case "TypeString": + case "TypeStateInit": + case "TypeStringBuilder": { + return undefined; + } + } +} + function* getMethodsFromContract( + contractSig: Ast.ContractSig, typeName: Ast.TypeId, traits: readonly Ast.Decl[], methods: readonly Ast.Method[], scopeRef: () => Ast.Scope ): E.WithLog>>> { - const res = yield* getMethodsGeneral(typeName, traits, methods, scopeRef); + const res = yield* getMethodsGeneral( + contractSig, + typeName, + traits, + methods, + scopeRef, + ); const map: Map>> = new Map(); for (const [name, { via, decl: method }] of res) { @@ -193,6 +271,7 @@ function* getMethodsFromContract( } function* getFieldishFromContract( + contractSig: Ast.ContractSig, typeName: Ast.TypeId, traits: readonly Ast.Decl[], init: Ast.InitSig, @@ -200,7 +279,14 @@ function* getFieldishFromContract( fields: readonly Ast.FieldDecl[], scopeRef: () => Ast.Scope, ): E.WithLog>>>> { - const res = yield* getFieldishGeneral(typeName, traits, constants, fields, scopeRef); + const res = yield* getFieldishGeneral( + contractSig, + typeName, + traits, + constants, + fields, + scopeRef, + ); const order: string[] = []; const map: Map>>> = new Map(); diff --git a/src/next/types/errors.ts b/src/next/types/errors.ts index 83b15a4dee..e3eace6b13 100644 --- a/src/next/types/errors.ts +++ b/src/next/types/errors.ts @@ -1,7 +1,9 @@ import { throwInternal } from "@/error/errors"; -import type { Loc, Via, ViaMember, ViaUser } from "@/next/ast"; +import type { DecodedType, Loc, Via, ViaMember, ViaUser } from "@/next/ast"; import type * as V from "@/next/ast/via"; +// TODO: move to src/next/ast/ to avoid an extra E.* everywhere + export type WithLog = Generator export function runLog(gen: Generator): readonly [R, readonly T[]] { @@ -66,36 +68,49 @@ export type TcError = { readonly descr: readonly TELine[]; } -export type TELine = TEText | TEVia | TEViaMember | TECode; +export type TELine = TEText | TEVia | TEViaMember | TECode | TEMismatch; export type TEText = { readonly kind: 'text'; readonly text: string; } - export const TEText = (text: string): TEText => ({ kind: 'text', text }); export type TEVia = { readonly kind: 'via'; readonly via: V.Via; } - export const TEVia = (via: V.Via): TEVia => ({ kind: 'via', via }); export type TEViaMember = { readonly kind: 'via-member'; readonly via: V.ViaMember; } - export const TEViaMember = (via: V.ViaMember): TEViaMember => ({ kind: 'via-member', via }); export type TECode = { readonly kind: 'code'; readonly loc: Loc; } - export const TECode = (loc: Loc): TECode => ({ kind: 'code', loc }); +export type TEMismatch = { + readonly kind: 'mismatch'; + readonly tree: MatchTree; +} +export const TEMismatch = (tree: MatchTree): TEMismatch => ({ kind: 'mismatch', tree }); + +export type MatchTree = { + readonly expected: DecodedType; + readonly got: DecodedType; + readonly children: readonly MatchTree[]; +} +export const MatchTree = ( + expected: DecodedType, + got: DecodedType, + children: readonly MatchTree[], +): MatchTree => ({ expected, got, children }); + export const viaToRange = ({ imports, defLoc: definedAt }: V.ViaUser): Loc => { const [head] = imports; if (typeof head === 'undefined') { diff --git a/src/next/types/expr-eval.ts b/src/next/types/expr-eval.ts index 7b90a7f09a..d7a88f6e84 100644 --- a/src/next/types/expr-eval.ts +++ b/src/next/types/expr-eval.ts @@ -7,5 +7,5 @@ export function* evalExpr( expr: Ast.DecodedExpression, scopeRef: () => Ast.Scope, ): E.WithLog { - return Ast.VNumber(0n); + return Ast.VNumber(0n, expr.loc); } diff --git a/src/next/types/expression.ts b/src/next/types/expression.ts index 41c193caeb..7d0fa58510 100644 --- a/src/next/types/expression.ts +++ b/src/next/types/expression.ts @@ -92,9 +92,9 @@ const decodeMapCons: Decode = function* (node, const ascribed = yield* decodeTypeMap(ctx.typeParams, node.type, ctx.scopeRef); const fields = yield* E.mapLog(node.fields, function* (field) { const key = yield* decodeExprCtx(field.key, ctx); - yield* assignType(ascribed.key, key.computedType, ctx.scopeRef); + yield* assignType(field.key.loc, ascribed.key, key.computedType); const value = yield* decodeExprCtx(field.value, ctx); - yield* assignType(ascribed.value, value.computedType, ctx.scopeRef); + yield* assignType(field.value.loc, ascribed.value, value.computedType); return Ast.DMapField(key, value); }); return Ast.DMapLiteral(ascribed, fields, node.loc); @@ -114,6 +114,7 @@ const decodeStructCons: Decode = functi ctx.typeParams, ctx.scopeRef, ); + // see checkFields in statement.ts const fields = yield* checkFields( instance?.fields, node.args, @@ -147,9 +148,9 @@ function* checkFields( const typeField = typeFields.map.get(fieldName); if (typeField) { yield* assignType( + expr.loc, yield* typeField.type(), expr.computedType, - ctx.scopeRef, ); } else { yield ENoSuchField(fieldName, arg.loc); @@ -327,10 +328,10 @@ const decodeUnary: Decode = function* (node, ctx) { const decodeTernary: Decode = function* (node, ctx) { const condition = yield* decodeExprCtx(node.condition, ctx); - yield* assignType(Bool, condition.computedType, ctx.scopeRef); + yield* assignType(condition.loc, Bool, condition.computedType); const thenBranch = yield* decodeExprCtx(node.thenBranch, ctx); const elseBranch = yield* decodeExprCtx(node.elseBranch, ctx); - const commonType = yield* mgu(thenBranch.computedType, elseBranch.computedType, ctx.scopeRef); + const commonType = yield* mgu(thenBranch.computedType, elseBranch.computedType, node.loc); return Ast.DConditional(condition, thenBranch, elseBranch, commonType, node.loc); } diff --git a/src/next/types/extensions.ts b/src/next/types/extensions.ts index 721d626a5d..cace049c89 100644 --- a/src/next/types/extensions.ts +++ b/src/next/types/extensions.ts @@ -244,6 +244,7 @@ function* decodeSelfType( } return Ast.MVTypeRef( type.name, + def.decl, allVars, type.loc, ); diff --git a/src/next/types/fields.ts b/src/next/types/fields.ts index 0bcf727e9a..e9b98aa487 100644 --- a/src/next/types/fields.ts +++ b/src/next/types/fields.ts @@ -12,6 +12,7 @@ import { evalExpr } from "@/next/types/expr-eval"; type MaybeExpr = Ast.Lazy | undefined export function* getFieldishGeneral( + traitSigRef: Ast.TraitSig | Ast.ContractSig, typeName: Ast.TypeId, traits: readonly Ast.Decl[], constants: readonly Ast.FieldConstant[], @@ -42,6 +43,7 @@ export function* getFieldishGeneral( const selfType = Ast.MVTypeRef( typeName, + traitSigRef, [], typeName.loc, ) @@ -161,7 +163,7 @@ function decodeField( scopeRef: () => Ast.Scope, selfType: Ast.SelfType, ) { - const { initializer, name, type, loc } = field; + const { initializer, type, loc } = field; const nextVia = Ast.ViaMemberOrigin(typeName, loc); // contracts don't have type parameters @@ -179,7 +181,7 @@ function decodeField( new Map(), ); const computed = expr.computedType; - yield* assignType(ascribed, computed, scopeRef); + yield* assignType(loc, ascribed, computed); return yield* evalExpr(expr, scopeRef); }); @@ -217,6 +219,7 @@ function* decodeConstant( ); } else { const [type, expr] = decodeConstantDef( + nextVia.defLoc, typeParams, init, scopeRef, diff --git a/src/next/types/message.ts b/src/next/types/message.ts index 025fe3ff70..b5fae59a8a 100644 --- a/src/next/types/message.ts +++ b/src/next/types/message.ts @@ -81,7 +81,7 @@ function* decodeOpcode( new Map(), ); const computed = expr.computedType; - if (yield* assignType(Int, computed, scopeRef)) { + if (yield* assignType(opcode.loc, Int, computed)) { const result = yield* evalExpr(expr, scopeRef); // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (result.kind === 'number') { diff --git a/src/next/types/methods.ts b/src/next/types/methods.ts index 9adc8e3d6a..3ec2c7ff8f 100644 --- a/src/next/types/methods.ts +++ b/src/next/types/methods.ts @@ -12,6 +12,7 @@ import { evalExpr } from "@/next/types/expr-eval"; import { assignType } from "@/next/types/type"; export function* getMethodsGeneral( + declSig: Ast.TraitSig | Ast.ContractSig, typeName: Ast.TypeId, traits: readonly Ast.Decl[], methods: readonly Ast.Method[], @@ -50,7 +51,7 @@ export function* getMethodsGeneral( const nextVia = Ast.ViaMemberOrigin(typeName.text, loc); const decodedFn = yield* decodeFnType(type, scopeRef); - const selfType = Ast.MVTypeRef(typeName, [], loc); + const selfType = Ast.MVTypeRef(typeName, declSig, [], loc); const methodType = Ast.DecodedMethodType( mutates, decodedFn.typeParams, @@ -155,7 +156,7 @@ function* decodeGet( new Map(), ); const type = expr.computedType; - if (yield* assignType(Int, type, scopeRef)) { + if (yield* assignType(expr.loc, Int, type)) { const methodId = yield* evalExpr(expr, scopeRef); if ( // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition diff --git a/src/next/types/override.ts b/src/next/types/override.ts index 8d25c83a6c..412cc85434 100644 --- a/src/next/types/override.ts +++ b/src/next/types/override.ts @@ -28,9 +28,9 @@ export function* checkFieldOverride( } else { // overriding constant yield* assignType( + nextVia.defLoc, yield* prev.decl.type(), yield* nextType(), - scopeRef, ); } } else { diff --git a/src/next/types/statements.ts b/src/next/types/statements.ts index e368ed08e8..6193bb3211 100644 --- a/src/next/types/statements.ts +++ b/src/next/types/statements.ts @@ -4,26 +4,29 @@ import * as Ast from "@/next/ast"; import * as E from "@/next/types/errors"; import { throwInternal } from "@/error/errors"; -import { Bool, builtinAugmented, Int } from "@/next/types/builtins"; +import { Bool, builtinAugmented, Int, Void } from "@/next/types/builtins"; import { decodeExprCtx } from "@/next/types/expression"; import { convertExprToLValue } from "@/next/types/lvalue"; -import { assignType, decodeType } from "@/next/types/type"; +import { assignType, dealiasType, decodeType, decodeTypeLazy } from "@/next/types/type"; import { getCallResult } from "@/next/types/type-fn"; export function decodeStatements( statements: readonly Ast.Statement[], + typeParams: Ast.TypeParams, + selfType: undefined | Ast.SelfType, + returnType: Ast.DecodedType, + required: undefined | ReadonlySet, scopeRef: () => Ast.Scope, -): readonly Ast.DecodedStatement[] { - const context: Context = { +) { + const ctx: Context = { + localScopeRef: new Map(), + required, + returnType, scopeRef, - localScopeRef, - required: getRequired(selfType), selfType, - returnType, typeParams, }; - yield* rec(statements, context, emptyEff); - return []; + return rec(statements, ctx, emptyEff); } const rec: Decode< @@ -76,56 +79,6 @@ const Effects = ( setSelfPaths: ReadonlySet, ): Effects => Object.freeze({ returnOrThrow, setSelfPaths }) -function* getRequired(selfType: Ast.SelfType | undefined): E.WithLog> { - if (!selfType) { - return new Set(); - } - const required: Set = new Set(); - switch (selfType.kind) { - case "type_ref": { - switch (selfType.type.kind) { - case "contract": - case "trait": { - const { fieldish } = (yield* selfType.type.content()); - for (const [name, field] of fieldish.map) { - if (field.decl.kind === 'field' && !field.decl.init) { - required.add(name) - } - } - return required; - } - case "struct": - case "message": - case "union": { - // no requirement to fill self on these, because they have - // no init() - return required; - } - } - // linter needs this - return required; - } - case "map_type": - case "TypeMaybe": - case "tuple_type": - case "tensor_type": - case "TyInt": - case "TySlice": - case "TyCell": - case "TyBuilder": - case "unit_type": - case "TypeVoid": - case "TypeNull": - case "TypeBool": - case "TypeAddress": - case "TypeString": - case "TypeStateInit": - case "TypeStringBuilder": { - return undefined; - } - } -} - const emptyEff: Effects = Object.freeze({ returnOrThrow: false, setSelfPaths: new Set(), @@ -253,7 +206,6 @@ const EShadowConst = (name: string, prev: Ast.Loc, next: Ast.Loc): E.TcError => ], }); - const decodeStatement: Decode = function (stmt, ctx, eff) { switch (stmt.kind) { case "statement_let": return decodeLet(stmt, ctx, eff); @@ -277,7 +229,7 @@ const decodeLet: Decode = function* (node, const result = Ast.DStatementLet(node.name, expr, node.loc); if (node.type) { const ascribed = yield* decodeType(ctx.typeParams, node.type, ctx.scopeRef().typeDecls) - yield* assignType(ascribed, expr.computedType, ctx.scopeRef); + yield* assignType(expr.loc, ascribed, expr.computedType); const newCtx = yield* defineVar(node.name, ascribed, ctx); return Result(result, newCtx, eff); } else { @@ -290,9 +242,10 @@ const decodeReturn: Decode = function const newEff = yield* setHadExit(eff, true, ctx.required, node.loc); if (node.expression) { const expr = yield* decodeExprCtx(node.expression, ctx); - yield* assignType(ctx.returnType, expr.computedType, ctx.scopeRef); + yield* assignType(expr.loc, ctx.returnType, expr.computedType); return Result(Ast.DStatementReturn(expr, node.loc), ctx, newEff); } else { + yield* assignType(node.loc, ctx.returnType, Void); return Result(Ast.DStatementReturn(undefined, node.loc), ctx, newEff); } }; @@ -312,7 +265,7 @@ const decodeAssign: Decode = function* (node, ctx, eff) { const condition = yield* decodeExprCtx(node.condition, ctx); - yield* assignType(Bool, condition.computedType, ctx.scopeRef); + yield* assignType(condition.loc, Bool, condition.computedType); const trueRes = yield* rec(node.trueStatements, ctx, eff); if (node.falseStatements) { const falseRes = yield* rec(node.falseStatements, ctx, eff); @@ -353,7 +306,7 @@ const decodeCondition: Decode = const decodeWhile: Decode = function* (node, ctx, eff) { const condition = yield* decodeExprCtx(node.condition, ctx); - yield* assignType(Bool, condition.computedType, ctx.scopeRef); + yield* assignType(condition.loc, Bool, condition.computedType); const result = yield* rec(node.statements, ctx, eff); // might be executed zero times, so it doesn't matter // if it always returns, or assigns to `self` @@ -362,7 +315,7 @@ const decodeWhile: Decode = function* ( const decodeUntil: Decode = function* (node, ctx, eff) { const condition = yield* decodeExprCtx(node.condition, ctx); - yield* assignType(Bool, condition.computedType, ctx.scopeRef); + yield* assignType(condition.loc, Bool, condition.computedType); const result = yield* rec(node.statements, ctx, eff); // until executes its body at least once return Result(Ast.DStatementUntil(condition, result.node, node.loc), ctx, result.effects); @@ -370,7 +323,7 @@ const decodeUntil: Decode = function* ( const decodeRepeat: Decode = function* (node, ctx, eff) { const iterations = yield* decodeExprCtx(node.iterations, ctx); - yield* assignType(Int, iterations.computedType, ctx.scopeRef); + yield* assignType(iterations.loc, Int, iterations.computedType); const result = yield* rec(node.statements, ctx, eff); // might be executed zero times, so it doesn't matter // if it always returns, or assigns to `self` @@ -425,15 +378,155 @@ function* defineForVars( } } -const decodeDestruct: Decode = function* (node, ctx, eff) { +const decodeDestruct: Decode = function* (node, ctx, eff) { const expr = yield* decodeExprCtx(node.expression, ctx); - node.identifiers // defineVar each, ReadonlyMap -> Ordered, assignType like in decodeStructCons - node.ignoreUnspecifiedFields // throw if #identifier != declTypes.get(node.type).fields.filter(x => x.kind === 'field').length - node.type // assignType(ascribed, expr.computedType) + + const typeArgs = yield* E.mapLog(node.typeArgs, function* (arg) { + return yield* decodeTypeLazy(ctx.typeParams, arg, ctx.scopeRef)(); + }); + + const decl = yield* findStruct(node.type, typeArgs, ctx.scopeRef); + if (!decl) { + return Result(Ast.DStatementExpression(expr, node.loc), ctx, eff); + } + + const ascribed = Ast.DTypeRef(node.type, decl, typeArgs, node.loc); + yield* assignType(node.loc, ascribed, expr.computedType); + + // see checkFields in expression.ts + const [fields, newCtx] = yield* checkFields( + node.loc, + node.identifiers, + decl.fields, + node.ignoreUnspecifiedFields, + ctx, + ); + + return Result(Ast.DStatementDestruct(node.type, fields, node.ignoreUnspecifiedFields, expr, node.loc), newCtx, eff); }; +function* checkFields( + nodeLoc: Ast.Loc, + stmtFields: readonly (readonly [Ast.Id, Ast.OptionalId])[], + declFields: Ast.Ordered, + ignoreUnspecifiedFields: boolean, + ctx: Context, +): E.WithLog, Context]> { + const order: string[] = []; + const map: Map = new Map(); + for (const [field, variable] of stmtFields) { + const fieldName = field.text; + const prev = map.get(fieldName); + if (prev) { + const [, prevLoc] = prev; + yield EDuplicateField(fieldName, prevLoc, field.loc); + continue; + } + + const decl = declFields.map.get(fieldName); + if (!decl) { + yield ENoSuchField(fieldName, field.loc); + continue; + } + + order.push(fieldName); + + map.set(fieldName, [Ast.DestructPattern( + field, + variable, + ), field.loc]); + + ctx = yield* defineVar( + variable, + yield* decl.type(), + ctx + ); + } + + if (!ignoreUnspecifiedFields) { + for (const fieldName of declFields.order) { + if (!map.has(fieldName)) { + yield EMissingField(fieldName, nodeLoc); + } + } + } + + const result = new Map( + [...map].map(([name, [pattern]]) => [name, pattern]) + ); + return [Ast.Ordered(order, result), ctx]; +} +const EMissingField = (name: string, prev: Ast.Loc): E.TcError => ({ + loc: prev, + descr: [ + E.TEText(`Value for field "${name}" is missing`), + E.TECode(prev), + ], +}); +const ENoSuchField = (name: string, next: Ast.Loc): E.TcError => ({ + loc: next, + descr: [ + E.TEText(`There is no field "${name}"`), + E.TECode(next), + ], +}); +const EDuplicateField = (name: string, prev: Ast.Loc, next: Ast.Loc): E.TcError => ({ + loc: prev, + descr: [ + E.TEText(`Duplicate field "${name}"`), + E.TEText(`Defined at:`), + E.TECode(next), + E.TEText(`Previously defined at:`), + E.TECode(prev), + ], +}); +function* findStruct( + id: Ast.TypeId, + typeArgs: Ast.DecodedType[], + scopeRef: () => Ast.Scope, +) { + const decl = scopeRef().typeDecls.get(id.text); + if (!decl) { + return throwInternal("Bad ref from decoder"); + } + switch (decl.decl.kind) { + case "alias": { + const type = yield* dealiasType( + Ast.DTypeAliasRef( + Ast.NotDealiased(), + id, + typeArgs, + id.loc, + ), + scopeRef, + ); + if (type.kind === 'type_ref' && (type.type.kind === 'struct' || type.type.kind === 'message')) { + return type.type; + } else { + yield ENotDestructible(id.text, id.loc); + return undefined; + } + } + case "contract": + case "union": + case "trait": { + yield ENotDestructible(id.text, id.loc); + return undefined; + } + case "struct": + case "message": { + return decl.decl; + } + } +} +const ENotDestructible = (name: string, prev: Ast.Loc): E.TcError => ({ + loc: prev, + descr: [ + E.TEText(`Type "${name}" doesn't `), + E.TECode(prev), + ], +}); const decodeBlock: Decode = function* (node, ctx, eff) { - const [body, bodyCtx] = yield* rec(node.statements, ctx, eff); - // TODO: handle return/self bullshit - return [Ast.DStatementBlock(body, node.loc), ctx]; + const result = yield* rec(node.statements, ctx, eff); + return Result(Ast.DStatementBlock(result.node, node.loc), ctx, result.effects); }; \ No newline at end of file diff --git a/src/next/types/struct-fields.ts b/src/next/types/struct-fields.ts index d0df3f2462..27fed4f388 100644 --- a/src/next/types/struct-fields.ts +++ b/src/next/types/struct-fields.ts @@ -40,7 +40,7 @@ export function* decodeFields( ); const computed = expr.computedType; const ascribed = yield* ascribedType(); - yield* assignType( ascribed, computed, scopeRef); + yield* assignType(expr.loc, ascribed, computed); return yield* evalExpr(expr, scopeRef); }) : undefined; diff --git a/src/next/types/trait.ts b/src/next/types/trait.ts index 913bff02d4..bd7f8abca6 100644 --- a/src/next/types/trait.ts +++ b/src/next/types/trait.ts @@ -30,6 +30,7 @@ export function* decodeTrait( // const contentRef = () => content; const content: Ast.TraitContent = { fieldish: yield* getFieldishGeneral( + traitSig, name, traits, constants, @@ -37,6 +38,7 @@ export function* decodeTrait( scopeRef, ), methods: yield* getMethodsGeneral( + traitSig, name, traits, methods, @@ -53,7 +55,9 @@ export function* decodeTrait( return content; }); - return Ast.TraitSig(contentLazy); + const traitSig = Ast.TraitSig(contentLazy); + + return traitSig; } const ENoAttributes = ( diff --git a/src/next/types/type-print.ts b/src/next/types/type-print.ts new file mode 100644 index 0000000000..9634678c40 --- /dev/null +++ b/src/next/types/type-print.ts @@ -0,0 +1,117 @@ +import type * as Ast from "@/next/ast"; + +export function printType(node: Ast.DecodedType, allowRecover: boolean) { + function recN(nodes: readonly Ast.DecodedType[]): undefined | string { + const results: string[] = []; + for (const node of nodes) { + const result = rec(node); + if (result) { + results.push(result); + } else { + return undefined; + } + } + return results.join(', '); + } + + function rec(node: Ast.DecodedType): undefined | string { + switch (node.kind) { + case "recover": { + return allowRecover ? '$ERROR' : undefined; + } + case "type_ref": + case "TypeAlias": { + const name = node.name.text; + if (node.typeArgs.length === 0) { + return name; + } else { + const args = recN(node.typeArgs); + return args && `${name}<${args}>`; + } + } + case "TypeParam": { + return node.name.text; + } + case "map_type": { + const key = rec(node.key); + const value = rec(node.value); + return key && value && `Map<${key}, ${value}>`; + } + case "TypeBounced": { + return `bounced<${node.name.text}>`; + } + case "TypeMaybe": { + const type = rec(node.type); + return type && `Maybe<${type}>`; + } + case "tuple_type": + case "tensor_type": { + const typeArgs = recN(node.typeArgs); + return typeArgs && `[${typeArgs}]`; + } + case "TyInt": { + return `Int${printIntFormat(node.format)}` + } + case "TySlice": { + return `Slice${printSliceFormat(node.format)}`; + } + case "TyCell": { + return `Cell${printRemFormat(node.format)}`; + } + case "TyBuilder": { + return `Builder${printRemFormat(node.format)}`; + } + case "unit_type": { + return `()`; + } + case "TypeVoid": { + return `Void`; + } + case "TypeNull": { + return `Null`; + } + case "TypeBool": { + return `Bool`; + } + case "TypeAddress": { + return `Address`; + } + case "TypeStateInit": { + return `StateInit`; + } + case "TypeString": { + return `String`; + } + case "TypeStringBuilder": { + return `StringBuilder`; + } + } + } + + return rec(node); +} + +const printIntFormat = (format: Ast.IntFormat): string => { + if (format.kind === 'FInt' && format.sign === 'signed' && format.width === 257) { + return ''; + } + return " as " + (format.kind === 'FVarInt' ? "var" : "") + + (format.sign === 'unsigned' ? 'uint' : 'int') + + (format.kind === 'FVarInt' ? format.width : format.width.toString()); +}; + +const printSliceFormat = (format: Ast.SliceFormat): string => { + if (format.kind === 'SFBits') { + // FIXME: bits not divisible by 8 + return ` as bytes${format.bits >> 3}`; + } else { + return printRemFormat(format); + } +}; + +const printRemFormat = (format: Ast.RemFormat): string => { + switch (format.kind) { + case "SFRemaining": return ` as remaining`; + case "SFDefault": return ``; + } +}; diff --git a/src/next/types/type.ts b/src/next/types/type.ts index a6feade76f..baa71e4c50 100644 --- a/src/next/types/type.ts +++ b/src/next/types/type.ts @@ -3,6 +3,7 @@ import { throwInternal } from "@/error/errors"; import * as Ast from "@/next/ast"; import * as E from "@/next/types/errors"; +import { printType } from "@/next/types/type-print"; import { zip } from "@/utils/array"; // type C = map @@ -536,67 +537,216 @@ const ETypeArity = (name: string, loc: Ast.Loc, declArity: number, useArity: num }); export function* assignType( - ascribed: Ast.DecodedType, - computed: Ast.DecodedType, - scopeRef: () => Ast.Scope, + loc: Ast.Loc, + to: Ast.DecodedType, + from: Ast.DecodedType, ): E.WithLog { - // export type MismatchTree = { - // readonly to: Ty.LocType; - // readonly from: Ty.LocType; - // readonly children: MismatchTree[]; - // } - // switch (to.kind) { - // case 'TyBuilder': - // case 'TyCell': - // case 'TyInt': - // case 'TySlice': - // case "unit_type": { - // return from.kind === to.kind; - // } - // case "tuple_type": - // case "tensor_type": { - // return from.kind === to.kind && assignAll(to.typeArgs, from.typeArgs, tree); - // } - // case "map_type": { - // return isNull(from) - // || from.kind === 'map_type' && assignToAux1(to.key, from.key, tree) && assignToAux1(to.value, from.value, tree); - // } - // case 'cons_type': { - // return hasTypeParam(to.name.text) && to.typeArgs.length === 0 - // || to.name.text === 'Maybe' && isNull(from) - // || from.kind === 'cons_type' && to.name.text === from.name.text && assignAll(to.typeArgs, from.typeArgs, tree); - // } - // } + const result = assignTypeAux(to, from); + if (result.kind === 'failure') { + yield EMismatch(result.tree, loc); + return false; + } + return true; +} + +type AssignResult = AssignSuccess | AssignFailure +type AssignSuccess = { + readonly kind: 'success'; +} +const AssignSuccess = (): AssignSuccess => Object.freeze({ kind: 'success' }); +type AssignFailure = { + readonly kind: 'failure'; + readonly tree: E.MatchTree; +} +const AssignFailure = (tree: E.MatchTree): AssignFailure => Object.freeze({ kind: 'failure', tree }); + +type Log = Generator; + +function assignTypeAux( + to: Ast.DecodedType, + from: Ast.DecodedType, +) { + function* recN( + tos: readonly Ast.DecodedType[], + froms: readonly Ast.DecodedType[], + ): Log { + if (tos.length !== froms.length) { + return throwInternal("Arg count does not match after type decoding"); + } + let result = true; + for (const [to, from] of zip(tos, froms)) { + const res = yield* rec(to, from); + // NB! cannot merge into one line, otherwise it will + // short-circuit + result &&= res; + } + return result; + } + + function* rec( + to: Ast.DecodedType, + from: Ast.DecodedType, + ): Log { + const result = collectMismatches(to, from); + if (result.kind === 'failure') { + yield result.tree; + return false; + } + return true; + } + + function collectMismatches( + to: Ast.DecodedType, + from: Ast.DecodedType, + ): AssignResult { + const gen = check(to, from); + const results: E.MatchTree[] = []; + for (; ;) { + const res = gen.next(); + if (!res.done) { + // collect all errors (if any) + results.push(res.value); + continue; + } + if (!results.length) { + return AssignSuccess(); + } + const toStr = printType(to, false); + const fromStr = printType(from, false); + if (!toStr || !fromStr) { + // if types have errors, we don't print the error + // because it resulted from another error + return AssignSuccess(); + } + return AssignFailure(E.MatchTree(to, from, results)); + } + } + + function* check( + to: Ast.DecodedType, + from: Ast.DecodedType, + ): Log { + if (from.kind === 'TypeAlias') { + if (from.type.kind === 'NotDealiased') { + return throwInternal("Decoder returned aliased type"); + } + from = from.type; + return yield* rec(to, from); + } + switch (to.kind) { + case "recover": { + return true; + } + case "TypeAlias": { + if (to.type.kind === 'NotDealiased') { + return throwInternal("Decoder returned aliased type"); + } + to = to.type; + return yield* rec(to, from); + } + case "type_ref": { + return to.kind === from.kind && + to.name.text === from.name.text && + (yield* recN(to.typeArgs, from.typeArgs)); + } + case "tuple_type": + case "tensor_type": { + return to.kind === from.kind && + (yield* recN(to.typeArgs, from.typeArgs)); + } + case "TypeParam": { + return to.kind === from.kind && + to.name.text === from.name.text; + } + case "TypeBounced": { + return to.kind === from.kind && + to.name.text === from.name.text; + } + case "TypeMaybe": { + return from.kind === 'TypeNull' || + to.kind === from.kind && + (yield* rec(to.type, from.type)); + } + case "map_type": { + return from.kind === 'TypeNull' || + to.kind === from.kind && + (yield* rec(to.key, from.key)) && + (yield* rec(to.value, from.value)); + } + case "TyInt": + case "TySlice": + case "TyCell": + case "TyBuilder": + case "unit_type": + case "TypeVoid": + case "TypeNull": + case "TypeBool": + case "TypeAddress": + case "TypeStateInit": + case "TypeString": + case "TypeStringBuilder": { + return from.kind === to.kind; + } + } + } + + return collectMismatches(to, from); } +const EMismatch = (tree: E.MatchTree, loc: Ast.Loc): E.TcError => ({ + loc, + descr: [ + E.TEText(`Type mismatch`), + E.TEMismatch(tree), + ], +}); export function* mgu( left: Ast.DecodedType, right: Ast.DecodedType, - scopeRef: () => Ast.Scope, + loc: Ast.Loc, ): E.WithLog { - // left = simplifyHead(left); - // right = simplifyHead(right); - // if (left.kind === 'ERROR' || right.kind === 'ERROR') { - // return Ty.TypeErrorRecovered(); - // } - // if (left.kind === 'type_var' || right.kind === 'type_var') { - // return throwInternal("Trying to unify type variable"); - // } - // const children: MismatchTree[] = []; - // if (assignToAux1(left, right, children)) { - // return left; - // } - // if (assignToAux1(right, left, children)) { - // return right; - // } - // if (isNull(right)) { - // return Maybe(left, loc); - // } - // if (isNull(left)) { - // return Maybe(right, loc); - // } - // for (const tree of children) { - // err.typeMismatch(tree)(loc); - // } - // return Ty.TypeErrorRecovered(); -} \ No newline at end of file + function* rec( + left: Ast.DecodedType, + right: Ast.DecodedType, + ): E.WithLog { + if (right.kind === 'TypeAlias') { + if (right.type.kind === 'NotDealiased') { + return throwInternal("Decoder returned aliased type"); + } + right = right.type; + return yield* rec(left, right); + } + if (left.kind === 'TypeAlias') { + if (left.type.kind === 'NotDealiased') { + return throwInternal("Decoder returned aliased type"); + } + left = left.type; + return yield* rec(left, left); + } + const resultL = assignTypeAux(left, right); + if (resultL.kind === 'success') { + return left; + } + const resultR = assignTypeAux(right, left); + if (resultR.kind === 'success') { + return right; + } + if (right.kind === 'TypeNull') { + return Ast.DTypeMaybe(left, loc); + } + if (left.kind === 'TypeNull') { + return Ast.DTypeMaybe(right, loc); + } + yield ENotUnifiable(resultL.tree, loc); + return Ast.DTypeRecover(); + } + + return yield* rec(left, right); +} +const ENotUnifiable = (tree: E.MatchTree, loc: Ast.Loc): E.TcError => ({ + loc, + descr: [ + E.TEText(`Branches of condition have mismatched types`), + E.TEMismatch(tree), + ], +}); \ No newline at end of file diff --git a/src/next/types/union.ts b/src/next/types/union.ts index a9f62e6980..9c25020b68 100644 --- a/src/next/types/union.ts +++ b/src/next/types/union.ts @@ -46,7 +46,7 @@ export function* decodeUnion( ); const computed = expr.computedType; const ascribed = yield* ascribedType(); - yield* assignType( ascribed, computed, scopeRef); + yield* assignType(expr.loc, ascribed, computed); return yield* evalExpr(expr, scopeRef); }) : undefined; const decoded = Ast.InhFieldSig(ascribedType, lazyExpr); From 951cc794cec7da3a6cb39ba6e344a42399275870 Mon Sep 17 00:00:00 2001 From: verytactical <186486509+verytactical@users.noreply.github.com> Date: Mon, 2 Jun 2025 01:15:41 +0400 Subject: [PATCH 30/38] 1 --- spell/cspell-list.txt | 1 + src/next/ast/checked.ts | 8 +- src/next/ast/dtype.ts | 4 + src/next/ast/effects.ts | 4 + src/next/ast/generated/checked-expr.ts | 1 + src/next/ast/generated/checked.ts | 19 +- src/next/ast/generated/dtype.ts | 7 +- src/next/ast/generated/effects.ts | 7 + src/next/ast/index.ts | 1 + src/next/types/body.ts | 23 +- src/next/types/constant-def.ts | 3 +- src/next/types/constants.ts | 4 +- src/next/types/contract.ts | 85 +--- src/next/types/effects.ts | 69 ++++ src/next/types/expression.ts | 61 +-- src/next/types/fields.ts | 16 +- src/next/types/message.ts | 8 +- src/next/types/methods.ts | 16 +- src/next/types/override.ts | 13 +- src/next/types/receivers.ts | 55 ++- src/next/types/statements.ts | 385 +++++++++--------- src/next/types/struct-fields.ts | 3 +- src/next/types/tlb.ts | 62 ++- src/next/types/trait.ts | 8 + src/next/types/type-fn.ts | 108 +---- src/next/types/type-method.ts | 10 - src/next/types/type-params.ts | 2 + src/next/types/type.ts | 534 ++++++++++++++++++++++--- src/next/types/union.ts | 4 +- 29 files changed, 968 insertions(+), 553 deletions(-) create mode 100644 src/next/ast/effects.ts create mode 100644 src/next/ast/generated/effects.ts create mode 100644 src/next/types/effects.ts delete mode 100644 src/next/types/type-method.ts diff --git a/spell/cspell-list.txt b/spell/cspell-list.txt index 4a686eeb93..f9ba1418f3 100644 --- a/spell/cspell-list.txt +++ b/spell/cspell-list.txt @@ -34,6 +34,7 @@ CSBT Daniil Danil dealias +dealiased decompilation Decompilation decompile diff --git a/src/next/ast/checked.ts b/src/next/ast/checked.ts index 0255e23c6e..1bbfe6825d 100644 --- a/src/next/ast/checked.ts +++ b/src/next/ast/checked.ts @@ -1,6 +1,7 @@ import type { DecodedStatement } from "@/next/ast/checked-stmt"; import type { FuncId, Loc, OptionalId, TypeId } from "@/next/ast/common"; import type { DecodedType, DTypeRef, DTypeBounced } from "@/next/ast/dtype"; +import type { Effects } from "@/next/ast/effects"; import type { Lazy } from "@/next/ast/lazy"; import type { SelfType } from "@/next/ast/mtype"; import type { AsmInstruction, AsmShuffle, ContractAttribute } from "@/next/ast/root"; @@ -53,7 +54,12 @@ export type FnSig = { readonly body: Body; } -export type Statements = Lazy; +export type Statements = Lazy; + +export type StatementsAux = { + readonly body: readonly DecodedStatement[]; + readonly effects: Effects; +}; export type Body = TactBody | FuncBody | FiftBody diff --git a/src/next/ast/dtype.ts b/src/next/ast/dtype.ts index 0fdc217b3a..3c2171567f 100644 --- a/src/next/ast/dtype.ts +++ b/src/next/ast/dtype.ts @@ -6,6 +6,10 @@ import type * as Ast from "@/next/ast/type"; // readonly tlb: Lazy // readonly effects: Lazy +export type DNotSet = { + readonly kind: "not-set"; +} + export type DecodedType = | DTypeRecover | DTypeRef diff --git a/src/next/ast/effects.ts b/src/next/ast/effects.ts new file mode 100644 index 0000000000..495635e7f5 --- /dev/null +++ b/src/next/ast/effects.ts @@ -0,0 +1,4 @@ +export type Effects = { + readonly returnOrThrow: boolean; + readonly setSelfPaths: ReadonlySet; +} diff --git a/src/next/ast/generated/checked-expr.ts b/src/next/ast/generated/checked-expr.ts index bfcc3a74ff..cd8c71376c 100644 --- a/src/next/ast/generated/checked-expr.ts +++ b/src/next/ast/generated/checked-expr.ts @@ -143,6 +143,7 @@ export const DStaticMethodCall = (self: $c.TypeId, typeArgs: $.TypeArgs, functio loc }); export const isDStaticMethodCall = ($value: DStaticMethodCall) => $value.kind === "static_method_call"; +export type TypeArgs = $.TypeArgs export type DStaticCall = $.DStaticCall; export const DStaticCall = (function_: $c.Id, typeArgs: $.TypeArgs, args: readonly $.DecodedExpression[], computedType: $d.DecodedType, loc: $c.Loc): $.DStaticCall => Object.freeze({ kind: "static_call", diff --git a/src/next/ast/generated/checked.ts b/src/next/ast/generated/checked.ts index 6940b60555..0e15421d1c 100644 --- a/src/next/ast/generated/checked.ts +++ b/src/next/ast/generated/checked.ts @@ -9,6 +9,7 @@ import type { Lazy } from "@/next/ast/lazy"; import type { AsmInstruction, AsmShuffle, ContractAttribute } from "@/next/ast/root"; import type { DecodedStatement } from "@/next/ast/checked-stmt"; import type { Value } from "@/next/ast/value"; +import type { Effects } from "@/next/ast/effects"; export type TypeParams = $.TypeParams; export const TypeParams = (order: readonly $c.TypeId[], set: ReadonlySet): TypeParams => Object.freeze({ @@ -109,7 +110,7 @@ export const Parameters = (order: readonly $.Parameter[], set: ReadonlySet): $.TactBody => Object.freeze({ +export const TactBody = (statements: Lazy): $.TactBody => Object.freeze({ kind: "tact", statements }); @@ -178,30 +179,30 @@ export const TraitSig = (content: Lazy<$.CommonSig | undefined, $.Bo }); export const isTraitSig = ($value: TraitSig) => $value.kind === "trait"; export type MessageRecv = $.MessageRecv; -export const MessageRecv = (name: $c.OptionalId, type_: $d.DTypeRef | $d.DTypeBounced, statements: Lazy): $.MessageRecv => Object.freeze({ +export const MessageRecv = (name: $c.OptionalId, type_: $d.DTypeRef | $d.DTypeBounced, statements: Lazy): $.MessageRecv => Object.freeze({ kind: "binary", name, type: type_, statements }); export type MessageAnyRecv = $.MessageAnyRecv; -export const MessageAnyRecv = (name: $c.OptionalId, statements: Lazy): $.MessageAnyRecv => Object.freeze({ +export const MessageAnyRecv = (name: $c.OptionalId, statements: Lazy): $.MessageAnyRecv => Object.freeze({ name, statements }); export type StringRecv = $.StringRecv; -export const StringRecv = (comment: string, statements: Lazy): $.StringRecv => Object.freeze({ +export const StringRecv = (comment: string, statements: Lazy): $.StringRecv => Object.freeze({ kind: "string", comment, statements }); export type StringAnyRecv = $.StringAnyRecv; -export const StringAnyRecv = (name: $c.OptionalId, statements: Lazy): $.StringAnyRecv => Object.freeze({ +export const StringAnyRecv = (name: $c.OptionalId, statements: Lazy): $.StringAnyRecv => Object.freeze({ name, statements }); export type EmptyRecv = $.EmptyRecv; -export const EmptyRecv = (statements: Lazy): $.EmptyRecv => Object.freeze({ +export const EmptyRecv = (statements: Lazy): $.EmptyRecv => Object.freeze({ statements }); export type OpcodeRecv = $.OpcodeRecv; @@ -238,8 +239,12 @@ export const InitSimple = (fill: $.Ordered<$.InitParam>, loc: $c.Loc): $.InitSim loc }); export const isInitSimple = ($value: InitSimple) => $value.kind === "simple"; +export type StatementsAux = $.StatementsAux +export const StatementsAux = (body: readonly DecodedStatement[], effects: Effects): $.StatementsAux => Object.freeze({ + body, effects, +}); export type InitFn = $.InitFn; -export const InitFn = (params: $.Parameters, statements: Lazy): $.InitFn => Object.freeze({ +export const InitFn = (params: $.Parameters, statements: Lazy): $.InitFn => Object.freeze({ kind: "function", params, statements diff --git a/src/next/ast/generated/dtype.ts b/src/next/ast/generated/dtype.ts index 4ce40c9e1a..72294d1faf 100644 --- a/src/next/ast/generated/dtype.ts +++ b/src/next/ast/generated/dtype.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-unnecessary-condition */ import type * as $ from "@/next/ast/dtype"; import type * as $c from "@/next/ast/common"; -import { TypeDeclRefable } from "@/next/ast/checked"; +import type { TypeDeclRefable } from "@/next/ast/checked"; export type DTypeParamRef = $.DTypeParamRef; export const DTypeParamRef = (name: $c.TypeId, loc: $c.Loc): $.DTypeParamRef => Object.freeze({ @@ -82,3 +82,8 @@ export const NotDealiased = (): $.NotDealiased => Object.freeze({ kind: "NotDealiased" }); export const isNotDealiased = ($value: NotDealiased) => $value.kind === "NotDealiased"; +export type DNotSet = $.DNotSet; +export const DNotSet = (): $.DNotSet => Object.freeze({ + kind: "not-set" +}); +export const isDNotSet = ($value: DNotSet) => $value.kind === "not-set"; diff --git a/src/next/ast/generated/effects.ts b/src/next/ast/generated/effects.ts new file mode 100644 index 0000000000..5fa59f98d1 --- /dev/null +++ b/src/next/ast/generated/effects.ts @@ -0,0 +1,7 @@ +import type * as $ from "@/next/ast/effects"; + +export type Effects = $.Effects +export const Effects = ( + returnOrThrow: boolean, + setSelfPaths: ReadonlySet, +): $.Effects => Object.freeze({ returnOrThrow, setSelfPaths }) diff --git a/src/next/ast/index.ts b/src/next/ast/index.ts index c9024e3897..2806ed181f 100644 --- a/src/next/ast/index.ts +++ b/src/next/ast/index.ts @@ -11,4 +11,5 @@ export * from "@/next/ast/generated/checked-expr"; export * from "@/next/ast/generated/checked-stmt"; export * from "@/next/ast/generated/root"; export * from "@/next/ast/generated/value"; +export * from "@/next/ast/generated/effects"; export * from "@/next/ast/lazy"; diff --git a/src/next/types/body.ts b/src/next/types/body.ts index 3dd3a87ede..8a55259e47 100644 --- a/src/next/types/body.ts +++ b/src/next/types/body.ts @@ -3,7 +3,8 @@ import * as Ast from "@/next/ast"; import * as E from "@/next/types/errors"; import { isSubsetOf } from "@/utils/isSubsetOf"; -import { decodeStatements } from "@/next/types/statements"; +import { decodeStatementsLazy } from "@/next/types/statements"; +import { emptyEff } from "@/next/types/effects"; export function* decodeBody( node: Ast.FunctionalBody, @@ -14,12 +15,24 @@ export function* decodeBody( switch (node.kind) { case "abstract_body": { yield ENoBody(loc) - return Ast.TactBody([]); + return Ast.TactBody(function* () { + return Ast.StatementsAux([], emptyEff); + }); } case "regular_body": { - return Ast.TactBody( - decodeStatements(node.statements, scopeRef) - ); + const selfTypeRef = () => { + return fnType.kind === 'DecodedMethodType' + ? fnType.self + : undefined; + }; + return Ast.TactBody(decodeStatementsLazy( + node.statements, + fnType.typeParams, + selfTypeRef, + fnType.returnType, + true, + scopeRef, + )); } case "asm_body": { return Ast.FiftBody( diff --git a/src/next/types/constant-def.ts b/src/next/types/constant-def.ts index ceadaf6423..0f831345a5 100644 --- a/src/next/types/constant-def.ts +++ b/src/next/types/constant-def.ts @@ -2,6 +2,7 @@ import * as Ast from "@/next/ast"; import { assignType, decodeTypeLazy } from "@/next/types/type"; import { decodeExpr } from "@/next/types/expression"; import { evalExpr } from "@/next/types/expr-eval"; +import { emptyTypeParams } from "@/next/types/type-params"; export function decodeConstantDef( defLoc: Ast.Loc, @@ -25,7 +26,7 @@ export function decodeConstantDef( ); const computed = expr.computedType; const ascribed = yield* ascribedType(); - yield* assignType(defLoc, ascribed, computed); + yield* assignType(defLoc, emptyTypeParams, ascribed, computed, false); return yield* evalExpr(expr, scopeRef); }); return [ascribedType, lazyExpr]; diff --git a/src/next/types/constants.ts b/src/next/types/constants.ts index ef13f68b72..61f0f7826a 100644 --- a/src/next/types/constants.ts +++ b/src/next/types/constants.ts @@ -4,6 +4,7 @@ import * as E from "@/next/types/errors"; import type { TactSource } from "@/next/imports/source"; import { builtinFunctions } from "@/next/types/builtins"; import { decodeConstantDef } from "@/next/types/constant-def"; +import { emptyTypeParams } from "@/next/types/type-params"; const errorKind = "function"; @@ -51,10 +52,9 @@ function* decodeConstant( const expr = function*() { return Ast.VNumber(0n, constant.loc); }; return Ast.ConstSig(expr, type); } else { - const typeParams = Ast.TypeParams([], new Set()); const [type, expr] = decodeConstantDef( loc, - typeParams, + emptyTypeParams, init, scopeRef, undefined, diff --git a/src/next/types/contract.ts b/src/next/types/contract.ts index f54d437b74..06185cd7db 100644 --- a/src/next/types/contract.ts +++ b/src/next/types/contract.ts @@ -9,8 +9,9 @@ import { getMethodsGeneral } from "@/next/types/methods"; import { getReceivers } from "@/next/types/receivers"; import { decodeDealiasTypeLazy, decodeTypeLazy } from "@/next/types/type"; import { decodeParams } from "@/next/types/type-fn"; -import { decodeStatements } from "@/next/types/statements"; +import { decodeStatementsLazy } from "@/next/types/statements"; import { Void } from "@/next/types/builtins"; +import { emptyTypeParams } from "@/next/types/type-params"; export function* decodeContract( contract: Ast.Contract, @@ -25,6 +26,7 @@ export function* decodeContract( // to check init body in initLazy we have to know `self` from contentLazy const decodedInit = yield* decodeInit( + () => selfType, init, () => contentLazy(), scopeRef, @@ -56,6 +58,7 @@ export function* decodeContract( scopeRef, ), receivers: yield* getReceivers( + () => selfType, name, traits, receivers, @@ -68,16 +71,22 @@ export function* decodeContract( const contractSig = Ast.ContractSig(attributes, decodedInit, contentLazy); + const selfType = Ast.MVTypeRef( + contract.name, + contractSig, + [], + contract.loc, + ); + return contractSig; } function* decodeInit( - selfType: Ast.SelfType, + selfTypeRef: () => Ast.SelfType, init: Ast.Init | undefined, contentLazy: Ast.Lazy, scopeRef: () => Ast.Scope, ): E.WithLog { - const typeParams = Ast.TypeParams([], new Set()); if (!init) { // no init const lazyInit = Ast.Lazy(function* () { @@ -118,7 +127,7 @@ function* decodeInit( const map: Map = new Map(); for (const [name, param] of paramMap) { - const decoded = decodeTypeLazy(typeParams, param.type, scopeRef) + const decoded = decodeTypeLazy(emptyTypeParams, param.type, scopeRef) if (!param.initializer) { yield ENoInitializerParams(param.loc); } @@ -137,23 +146,19 @@ function* decodeInit( const { params, statements } = init; const decodedParams = yield* decodeParams((type) => { - return decodeDealiasTypeLazy(typeParams, type, scopeRef); + return decodeDealiasTypeLazy(emptyTypeParams, type, scopeRef); }, params); - const body = yield* decodeStatements( + const body = decodeStatementsLazy( statements, - typeParams, - selfType, - Void, - yield* getRequired(selfType), + emptyTypeParams, + selfTypeRef, + function* () { return Void }, + true, scopeRef, ); - // TODO: make Lazy a builder - // (Lazy: LazyBuilder) - // Lazy(`body of ${name}`, function* (Lazy) { ... }) - - return Ast.InitFn(decodedParams, body.node); + return Ast.InitFn(decodedParams, body); } } const EDuplicateParam = ( @@ -187,56 +192,6 @@ const ENoInitializerEmpty = ( ], }); -function* getRequired(selfType: Ast.SelfType | undefined): E.WithLog> { - if (!selfType) { - return new Set(); - } - const required: Set = new Set(); - switch (selfType.kind) { - case "type_ref": { - switch (selfType.type.kind) { - case "contract": - case "trait": { - const { fieldish } = (yield* selfType.type.content()); - for (const [name, field] of fieldish.map) { - if (field.decl.kind === 'field' && !field.decl.init) { - required.add(name) - } - } - return required; - } - case "struct": - case "message": - case "union": { - // no requirement to fill self on these, because they have - // no init() - return required; - } - } - // linter needs this - return required; - } - case "map_type": - case "TypeMaybe": - case "tuple_type": - case "tensor_type": - case "TyInt": - case "TySlice": - case "TyCell": - case "TyBuilder": - case "unit_type": - case "TypeVoid": - case "TypeNull": - case "TypeBool": - case "TypeAddress": - case "TypeString": - case "TypeStateInit": - case "TypeStringBuilder": { - return undefined; - } - } -} - function* getMethodsFromContract( contractSig: Ast.ContractSig, typeName: Ast.TypeId, diff --git a/src/next/types/effects.ts b/src/next/types/effects.ts new file mode 100644 index 0000000000..c72bf0bab8 --- /dev/null +++ b/src/next/types/effects.ts @@ -0,0 +1,69 @@ +import * as Ast from "@/next/ast"; +import * as E from "@/next/types/errors"; + +export const emptyEff: Ast.Effects = Object.freeze({ + returnOrThrow: false, + setSelfPaths: new Set(), +}); + +// when two branches merge +export const mergeEff = (left: Ast.Effects, right: Ast.Effects): Ast.Effects => { + return Ast.Effects( + left.returnOrThrow && right.returnOrThrow, + new Set([...left.setSelfPaths].filter(p => right.setSelfPaths.has(p))) + ); +}; + +// on every assign +export function* setHadAssign( + eff: Ast.Effects, + lvalue: Ast.LValue, +): E.WithLog { + const setSelfPaths = new Set(eff.setSelfPaths); + switch (lvalue.kind) { + case "self": { + // self = ...; + yield ENoSelfAssign(lvalue.loc); + break; + } + case "field_access": { + if (lvalue.aggregate.kind === 'self') { + // self.x = ...; + setSelfPaths.add(lvalue.field.text); + } + break; + } + case "var": { + // x = ...; + } + } + return Ast.Effects(eff.returnOrThrow, setSelfPaths); +} +const ENoSelfAssign = (loc: Ast.Loc): E.TcError => ({ + loc, + descr: [ + E.TEText(`Cannot assign to self`), + ], +}); + +// on every return or throw +export function* setHadExit( + eff: Ast.Effects, + successful: boolean, + required: undefined | ReadonlySet, + returnLoc: Ast.Loc, +): E.WithLog { + if (successful && required) { + const missing = [...required].filter(p => !eff.setSelfPaths.has(p)); + for (const fieldName of missing) { + yield EMissingSelfInit(fieldName, returnLoc); + } + } + return Ast.Effects(true, eff.setSelfPaths); +} +const EMissingSelfInit = (name: string, loc: Ast.Loc): E.TcError => ({ + loc, + descr: [ + E.TEText(`Field "self.${name}" is not initialized by this moment`), + ], +}); diff --git a/src/next/types/expression.ts b/src/next/types/expression.ts index 7d0fa58510..9602b07430 100644 --- a/src/next/types/expression.ts +++ b/src/next/types/expression.ts @@ -3,9 +3,9 @@ import * as Ast from "@/next/ast"; import * as E from "@/next/types/errors"; import { throwInternal } from "@/error/errors"; import { Bool, builtinBinary, builtinFunctions, getStaticBuiltin, StateInit } from "@/next/types/builtins"; -import { assignType, dealiasType, decodeDealiasTypeLazy, decodeTypeLazy, decodeTypeMap, instantiateStruct, mgu } from "@/next/types/type"; -import { getCallResult, lookupFunction, lookupMethod } from "@/next/types/type-fn"; +import { assignType, dealiasType, decodeDealiasTypeLazy, decodeTypeLazy, decodeTypeMap, checkFnCall, instantiateStruct, checkFnCallWithArgs, mgu, lookupMethod } from "@/next/types/type"; import { convertValueToExpr } from "@/next/types/value"; +import { emptyTypeParams } from "@/next/types/type-params"; type Decode = (node: T, ctx: Context) => E.WithLog type Context = { @@ -92,9 +92,9 @@ const decodeMapCons: Decode = function* (node, const ascribed = yield* decodeTypeMap(ctx.typeParams, node.type, ctx.scopeRef); const fields = yield* E.mapLog(node.fields, function* (field) { const key = yield* decodeExprCtx(field.key, ctx); - yield* assignType(field.key.loc, ascribed.key, key.computedType); + yield* assignType(field.key.loc, emptyTypeParams, ascribed.key, key.computedType, false); const value = yield* decodeExprCtx(field.value, ctx); - yield* assignType(field.value.loc, ascribed.value, value.computedType); + yield* assignType(field.value.loc, emptyTypeParams, ascribed.value, value.computedType, false); return Ast.DMapField(key, value); }); return Ast.DMapLiteral(ascribed, fields, node.loc); @@ -149,8 +149,10 @@ function* checkFields( if (typeField) { yield* assignType( expr.loc, + emptyTypeParams, yield* typeField.type(), expr.computedType, + false, ); } else { yield ENoSuchField(fieldName, arg.loc); @@ -259,12 +261,16 @@ const decodeBinary: Decode = function* (node, ctx) if (!fnType) { return throwInternal("Builtin operator is not in the map"); } - const { returnType, typeArgs } = yield* getCallResult( + const { returnType, typeArgMap } = yield* checkFnCall( + node.loc, fnType, - [left.computedType, right.computedType], + [ + [left.loc, left.computedType], + [right.loc, right.computedType] + ], ); if (node.op === '==' || node.op === '!=') { - const typeArg = typeArgs.get("T"); + const typeArg = typeArgMap.get("T"); if (!typeArg) { return throwInternal("getCallResult produced incorrect substitution"); } @@ -272,7 +278,7 @@ const decodeBinary: Decode = function* (node, ctx) yield ENoEquality(node.loc); } } - return Ast.DOpBinary(node.op, left, right, typeArgs, returnType, node.loc); + return Ast.DOpBinary(node.op, left, right, typeArgMap, returnType, node.loc); } const ENoEquality = (loc: Ast.Loc): E.TcError => ({ loc, @@ -318,17 +324,18 @@ const decodeUnary: Decode = function* (node, ctx) { if (!fnType) { return throwInternal("Builtin operator is not in the map"); } - const { returnType, typeArgs } = yield* getCallResult( + const { returnType, typeArgMap } = yield* checkFnCall( + node.loc, fnType, - [operand.computedType], + [[operand.loc, operand.computedType]], ); - return Ast.DOpUnary(node.op, operand, typeArgs, returnType, node.loc); + return Ast.DOpUnary(node.op, operand, typeArgMap, returnType, node.loc); } const decodeTernary: Decode = function* (node, ctx) { const condition = yield* decodeExprCtx(node.condition, ctx); - yield* assignType(condition.loc, Bool, condition.computedType); + yield* assignType(condition.loc, emptyTypeParams, Bool, condition.computedType, false); const thenBranch = yield* decodeExprCtx(node.thenBranch, ctx); const elseBranch = yield* decodeExprCtx(node.elseBranch, ctx); const commonType = yield* mgu(thenBranch.computedType, elseBranch.computedType, node.loc); @@ -340,14 +347,14 @@ const decodeMethodCall: Decode = function* (nod const args = yield* E.mapLog(node.args, arg => decodeExprCtx(arg, ctx)); const { typeDecls, extensions } = ctx.scopeRef(); - const { returnType, typeArgs } = yield* lookupMethod( + const { returnType, typeArgMap } = yield* lookupMethod( self.computedType, - node.method.text, - args.map(child => child.computedType), + node.method, + args.map(child => [child.loc, child.computedType]), typeDecls, extensions, ); - return Ast.DMethodCall(self, node.method, args, typeArgs, returnType, node.loc); + return Ast.DMethodCall(self, node.method, args, typeArgMap, returnType, node.loc); } const decodeFunctionCall: Decode = function* (node, ctx) { @@ -371,18 +378,19 @@ const decodeFunctionCall: Decode child.computedType), + args.map(child => [child.loc, child.computedType]), ); if (name.text === 'throw' || name.text === 'nativeThrow') { return Ast.DThrowCall(name, args, returnType, node.loc); } else { - return Ast.DStaticCall(name, typeArgs, args, returnType, node.loc); + return Ast.DStaticCall(name, typeArgMap, args, returnType, node.loc); } } const EMismatchSha256 = (loc: Ast.Loc): E.TcError => ({ @@ -405,12 +413,13 @@ const decodeStaticMethodCall: Decode child.computedType), + args.map(child => [child.loc, child.computedType]), ); - return Ast.DStaticMethodCall(node.self, typeArgs, node.function, args, returnType, node.loc); + return Ast.DStaticMethodCall(node.self, typeArgMap, node.function, args, returnType, node.loc); } else { yield EUndefinedStatic(node.function.text, node.loc); return Ast.DNull(Ast.TypeNull(node.loc), node.loc); @@ -528,12 +537,12 @@ const decodeInitOf: Decode = function* (node, ctx) { yield ENotContract(node.contract.text, node.loc); return Ast.DInitOf(node.contract, args, StateInit, node.loc); } - const typeParams = Ast.TypeParams([], new Set()); const params = yield* initParams(contract.decl.init); - yield* lookupFunction( - Ast.DecodedFnType(typeParams, params, function*() { return StateInit; }), + yield* checkFnCallWithArgs( + node.loc, + Ast.DecodedFnType(emptyTypeParams, params, function*() { return StateInit; }), [], - args.map(child => child.computedType), + args.map(child => [child.loc, child.computedType]), ); return Ast.DInitOf(node.contract, args, StateInit, node.loc); } diff --git a/src/next/types/fields.ts b/src/next/types/fields.ts index e9b98aa487..5688c4abce 100644 --- a/src/next/types/fields.ts +++ b/src/next/types/fields.ts @@ -8,6 +8,7 @@ import { decodeExpr } from "@/next/types/expression"; import { checkFieldOverride } from "@/next/types/override"; import { decodeConstantDef } from "@/next/types/constant-def"; import { evalExpr } from "@/next/types/expr-eval"; +import { emptyTypeParams } from "@/next/types/type-params"; type MaybeExpr = Ast.Lazy | undefined @@ -130,7 +131,6 @@ export function* getFieldishGeneral( next.decl.type, nextVia, override, - scopeRef, ); // we're all set to store this constant @@ -166,22 +166,19 @@ function decodeField( const { initializer, type, loc } = field; const nextVia = Ast.ViaMemberOrigin(typeName, loc); - // contracts don't have type parameters - const typeParams = Ast.TypeParams([], new Set()); - - const decoded = decodeTypeLazy(typeParams, type, scopeRef); + const decoded = decodeTypeLazy(emptyTypeParams, type, scopeRef); const init = initializer && Ast.Lazy(function* () { const ascribed = yield* decoded(); const expr = yield* decodeExpr( - typeParams, + emptyTypeParams, initializer, scopeRef, selfType, new Map(), ); const computed = expr.computedType; - yield* assignType(loc, ascribed, computed); + yield* assignType(loc, emptyTypeParams, ascribed, computed, false); return yield* evalExpr(expr, scopeRef); }); @@ -210,9 +207,8 @@ function* decodeConstant( scopeRef: () => Ast.Scope, selfType: Ast.SelfType, ): E.WithLog>> { - const typeParams = Ast.TypeParams([], new Set()); if (init.kind === 'constant_decl') { - const type = decodeTypeLazy(typeParams, init.type, scopeRef); + const type = decodeTypeLazy(emptyTypeParams, init.type, scopeRef); return Ast.DeclMem( Ast.FieldConstSig(overridable, type, undefined), nextVia, @@ -220,7 +216,7 @@ function* decodeConstant( } else { const [type, expr] = decodeConstantDef( nextVia.defLoc, - typeParams, + emptyTypeParams, init, scopeRef, selfType, diff --git a/src/next/types/message.ts b/src/next/types/message.ts index b5fae59a8a..9da8d25337 100644 --- a/src/next/types/message.ts +++ b/src/next/types/message.ts @@ -8,21 +8,21 @@ import { evalExpr } from "@/next/types/expr-eval"; import { decodeExpr } from "@/next/types/expression"; import { decodeFields } from "@/next/types/struct-fields"; import { assignType } from "@/next/types/type"; +import { emptyTypeParams } from "@/next/types/type-params"; import { highest32ofSha256, sha256 } from "@/utils/sha256"; export function* decodeMessage( message: Ast.MessageDecl, scopeRef: () => Ast.Scope, ): E.WithLog { - const typeParams = Ast.TypeParams([], new Set()); const fields = yield* decodeFields( message.fields, - typeParams, + emptyTypeParams, scopeRef, ); const lazyExpr = Ast.Lazy(function* () { const opcode = yield* decodeOpcode( - typeParams, + emptyTypeParams, message.opcode, message.name.text, fields.order, @@ -81,7 +81,7 @@ function* decodeOpcode( new Map(), ); const computed = expr.computedType; - if (yield* assignType(opcode.loc, Int, computed)) { + if (yield* assignType(opcode.loc, emptyTypeParams, Int, computed, false)) { const result = yield* evalExpr(expr, scopeRef); // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (result.kind === 'number') { diff --git a/src/next/types/methods.ts b/src/next/types/methods.ts index 3ec2c7ff8f..62c76aa1de 100644 --- a/src/next/types/methods.ts +++ b/src/next/types/methods.ts @@ -10,6 +10,7 @@ import { crc16 } from "@/utils/crc16"; import { Int, tactMethodIds } from "@/next/types/builtins"; import { evalExpr } from "@/next/types/expr-eval"; import { assignType } from "@/next/types/type"; +import { emptyTypeParams } from "@/next/types/type-params"; export function* getMethodsGeneral( declSig: Ast.TraitSig | Ast.ContractSig, @@ -54,7 +55,7 @@ export function* getMethodsGeneral( const selfType = Ast.MVTypeRef(typeName, declSig, [], loc); const methodType = Ast.DecodedMethodType( mutates, - decodedFn.typeParams, + emptyTypeParams, selfType, decodedFn.params, decodedFn.returnType, @@ -68,14 +69,14 @@ export function* getMethodsGeneral( ) : undefined; const getMethodId = decodeGetLazy( - decodedFn.typeParams, // FIXME: should `get` really get access to them? + emptyTypeParams, name, get, scopeRef, selfType, ); - if (getMethodId && decodedFn.typeParams.order.length > 0) { - yield EGenericGetter(loc); + if (type.typeParams.length > 0) { + yield EGenericMethod(loc); } const prevInh = inherited.get(name.text); @@ -90,7 +91,6 @@ export function* getMethodsGeneral( methodType, nextVia, override, - scopeRef, ); const methodSig = Ast.MethodSig( @@ -114,10 +114,10 @@ export function* getMethodsGeneral( return all; } -const EGenericGetter = (loc: Ast.Loc): E.TcError => ({ +const EGenericMethod = (loc: Ast.Loc): E.TcError => ({ loc, descr: [ - E.TEText(`Getter method cannot be generic`), + E.TEText(`Method cannot be generic`), ], }); @@ -156,7 +156,7 @@ function* decodeGet( new Map(), ); const type = expr.computedType; - if (yield* assignType(expr.loc, Int, type)) { + if (yield* assignType(expr.loc, emptyTypeParams, Int, type, false)) { const methodId = yield* evalExpr(expr, scopeRef); if ( // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition diff --git a/src/next/types/override.ts b/src/next/types/override.ts index 412cc85434..b9a97054a9 100644 --- a/src/next/types/override.ts +++ b/src/next/types/override.ts @@ -1,9 +1,7 @@ -/* eslint-disable require-yield */ -/* eslint-disable @typescript-eslint/no-unused-vars */ import type * as Ast from "@/next/ast"; import * as E from "@/next/types/errors"; -import { assignType } from "@/next/types/type"; -import { assignMethodType } from "@/next/types/type-method"; +import { assignMethodType, assignType } from "@/next/types/type"; +import { emptyTypeParams } from "@/next/types/type-params"; export function* checkFieldOverride( name: string, @@ -13,7 +11,6 @@ export function* checkFieldOverride( nextType: Ast.Lazy, nextVia: Ast.ViaMember, override: boolean, - scopeRef: () => Ast.Scope, ): E.WithLog { if (prev) { if (prev.decl.kind !== 'constant') { @@ -29,8 +26,10 @@ export function* checkFieldOverride( // overriding constant yield* assignType( nextVia.defLoc, + emptyTypeParams, yield* prev.decl.type(), yield* nextType(), + true, ); } } else { @@ -49,7 +48,6 @@ export function* checkMethodOverride( nextType: Ast.DecodedMethodType, nextVia: Ast.ViaMember, override: boolean, - scopeRef: () => Ast.Scope, ): E.WithLog { if (prev) { if (override) { @@ -63,7 +61,8 @@ export function* checkMethodOverride( yield* assignMethodType( prev.decl.type, nextType, - scopeRef, + prev.via, + nextVia, ); } } else { diff --git a/src/next/types/receivers.ts b/src/next/types/receivers.ts index 9c37aee3ad..f8fd485a35 100644 --- a/src/next/types/receivers.ts +++ b/src/next/types/receivers.ts @@ -1,9 +1,11 @@ /* eslint-disable require-yield */ /* eslint-disable @typescript-eslint/no-unused-vars */ import * as Ast from "@/next/ast"; +import { Void } from "@/next/types/builtins"; import * as E from "@/next/types/errors"; -import { decodeStatements } from "@/next/types/statements"; +import { decodeStatementsLazy } from "@/next/types/statements"; import { decodeDealiasTypeLazy } from "@/next/types/type"; +import { emptyTypeParams } from "@/next/types/type-params"; // const hash = commentPseudoOpcode( // commentRcv.selector.comment, @@ -12,6 +14,7 @@ import { decodeDealiasTypeLazy } from "@/next/types/type"; // ); export function* getReceivers( + selfTypeRef: () => Ast.SelfType, typeName: Ast.TypeId, traits: readonly Ast.Decl[], receivers: readonly Ast.Receiver[], @@ -48,13 +51,32 @@ export function* getReceivers( } } return { - bounce: yield* mergeBounce(typeName, impBounces, localBounces, scopeRef), - external: yield* mergeReceivers(typeName, impExternals, localExternals, scopeRef), - internal: yield* mergeReceivers(typeName, impInternals, localInternals, scopeRef), + bounce: yield* mergeBounce( + selfTypeRef, + typeName, + impBounces, + localBounces, + scopeRef, + ), + external: yield* mergeReceivers( + selfTypeRef, + typeName, + impExternals, + localExternals, + scopeRef, + ), + internal: yield* mergeReceivers( + selfTypeRef, + typeName, + impInternals, + localInternals, + scopeRef, + ), }; } function* mergeReceivers( + selfTypeRef: () => Ast.SelfType, typeName: Ast.TypeId, imported: readonly Ast.Decl[], local: Ast.DeclMem[], @@ -99,12 +121,18 @@ function* mergeReceivers( // local for (const { via, decl: [subKind, body] } of local) { - const statements = decodeStatements(body, scopeRef); + const statements = decodeStatementsLazy( + body, + emptyTypeParams, + selfTypeRef, + function* () { return Void; }, + true, + scopeRef, + ); switch (subKind.kind) { case "simple": { const { name, type } = subKind.param; - const typeParams = Ast.TypeParams([], new Set()); - const decoded = yield* decodeDealiasTypeLazy(typeParams, type, scopeRef)(); + const decoded = yield* decodeDealiasTypeLazy(emptyTypeParams, type, scopeRef)(); if (decoded.kind === 'TySlice') { if (allMessageAny) { yield ERedefineReceiver("fallback binary", allMessageAny.via, via); @@ -160,6 +188,7 @@ function* mergeReceivers( } function* mergeBounce( + selfTypeRef: () => Ast.SelfType, typeName: Ast.TypeId, imported: readonly Ast.Decl[], local: readonly Ast.DeclMem<[Ast.TypedParameter, readonly Ast.Statement[]]>[], @@ -187,9 +216,15 @@ function* mergeBounce( // local for (const { via, decl: [{ name, type }, body] } of local) { - const statements = decodeStatements(body, scopeRef); - const typeParams = Ast.TypeParams([], new Set()); - const decoded = yield* decodeDealiasTypeLazy(typeParams, type, scopeRef)(); + const statements = decodeStatementsLazy( + body, + emptyTypeParams, + selfTypeRef, + function* () { return Void; }, + true, + scopeRef, + ); + const decoded = yield* decodeDealiasTypeLazy(emptyTypeParams, type, scopeRef)(); if (decoded.kind === 'TySlice') { if (allMessageAny) { yield ERedefineReceiver("fallback binary", allMessageAny.via, via); diff --git a/src/next/types/statements.ts b/src/next/types/statements.ts index 6193bb3211..3a41c3b03a 100644 --- a/src/next/types/statements.ts +++ b/src/next/types/statements.ts @@ -7,29 +7,37 @@ import { throwInternal } from "@/error/errors"; import { Bool, builtinAugmented, Int, Void } from "@/next/types/builtins"; import { decodeExprCtx } from "@/next/types/expression"; import { convertExprToLValue } from "@/next/types/lvalue"; -import { assignType, dealiasType, decodeType, decodeTypeLazy } from "@/next/types/type"; -import { getCallResult } from "@/next/types/type-fn"; +import { assignType, dealiasType, decodeType, decodeTypeLazy, checkFnCall } from "@/next/types/type"; +import { emptyEff, mergeEff, setHadAssign, setHadExit } from "@/next/types/effects"; +import { emptyTypeParams } from "@/next/types/type-params"; -export function decodeStatements( +export function decodeStatementsLazy( statements: readonly Ast.Statement[], typeParams: Ast.TypeParams, - selfType: undefined | Ast.SelfType, - returnType: Ast.DecodedType, - required: undefined | ReadonlySet, + selfTypeRef: () => undefined | Ast.SelfType, + returnType: Ast.Lazy, + isInit: boolean, scopeRef: () => Ast.Scope, ) { - const ctx: Context = { - localScopeRef: new Map(), - required, - returnType, - scopeRef, - selfType, - typeParams, - }; - return rec(statements, ctx, emptyEff); + return Ast.Lazy(function* () { + const selfType = selfTypeRef(); + const required = isInit + ? yield* getRequired(selfType) + : undefined; + const ctx: Context = { + localScopeRef: new Map(), + required, + returnType: yield* returnType(), + scopeRef, + selfType, + typeParams, + }; + const res = yield* decodeStmts(statements, ctx, emptyEff); + return Ast.StatementsAux(res.node, res.effects); + }); } -const rec: Decode< +const decodeStmts: Decode< readonly Ast.Statement[], readonly Ast.DecodedStatement[] > = function* (nodes, ctx, eff) { @@ -44,168 +52,6 @@ const rec: Decode< return Result(results, context, effects); }; -type Decode = ( - node: T, - context: Context, - effects: Effects, -) => E.WithLog> - -type Result = { - readonly node: U; - readonly context: Context; - readonly effects: Effects; -} -const Result = ( - node: U, - context: Context, - effects: Effects, -): Result => Object.freeze({ node, context, effects }); - -type Context = { - readonly scopeRef: () => Ast.Scope; - readonly selfType: Ast.SelfType | undefined; - readonly required: undefined | ReadonlySet; - readonly typeParams: Ast.TypeParams; - readonly returnType: Ast.DecodedType; - readonly localScopeRef: ReadonlyMap; -} - -type Effects = { - readonly returnOrThrow: boolean; - readonly setSelfPaths: ReadonlySet; -} -const Effects = ( - returnOrThrow: boolean, - setSelfPaths: ReadonlySet, -): Effects => Object.freeze({ returnOrThrow, setSelfPaths }) - -const emptyEff: Effects = Object.freeze({ - returnOrThrow: false, - setSelfPaths: new Set(), -}); - -// when two branches merge -const mergeEff = (left: Effects, right: Effects): Effects => { - return Effects( - left.returnOrThrow && right.returnOrThrow, - new Set([...left.setSelfPaths].filter(p => right.setSelfPaths.has(p))) - ); -}; - -// on every assign -function* setHadAssign( - eff: Effects, - lvalue: Ast.LValue, -): E.WithLog { - const setSelfPaths = new Set(eff.setSelfPaths); - switch (lvalue.kind) { - case "self": { - // self = ...; - yield ENoSelfAssign(lvalue.loc); - break; - } - case "field_access": { - if (lvalue.aggregate.kind === 'self') { - // self.x = ...; - setSelfPaths.add(lvalue.field.text); - } - break; - } - case "var": { - // x = ...; - } - } - return Effects(eff.returnOrThrow, setSelfPaths); -} -const ENoSelfAssign = (loc: Ast.Loc): E.TcError => ({ - loc, - descr: [ - E.TEText(`Cannot assign to self`), - ], -}); - -// on every return or throw -function* setHadExit( - eff: Effects, - successful: boolean, - required: undefined | ReadonlySet, - returnLoc: Ast.Loc, -): E.WithLog { - if (successful && required) { - const missing = [...required].filter(p => !eff.setSelfPaths.has(p)); - for (const fieldName of missing) { - yield EMissingSelfInit(fieldName, returnLoc); - } - } - return Effects(true, eff.setSelfPaths); -} -const EMissingSelfInit = (name: string, loc: Ast.Loc): E.TcError => ({ - loc, - descr: [ - E.TEText(`Field "self.${name}" is not initialized by this moment`), - ], -}); - -function* defineVar( - node: Ast.OptionalId, - type: Ast.DecodedType, - ctx: Context, -): E.WithLog { - if (node.kind === 'wildcard') { - // there is nothing to define for a wildcard - return ctx; - } - - if (node.text === 'self') { - yield ENoDefineSelf(node.loc); - return ctx; - } - - const prev = ctx.localScopeRef.get(node.text); - if (prev) { - const [, prevLoc] = prev; - yield ERedefineVar(node.text, prevLoc, node.loc); - return ctx; - } - - const constant = ctx.scopeRef().constants.get(node.text); - if (constant) { - const prevLoc = constant.via.defLoc; - yield EShadowConst(node.text, prevLoc, node.loc); - return ctx; - } - - const localScopeRef = new Map(ctx.localScopeRef); - localScopeRef.set(node.text, [type, node.loc]); - return { ...ctx, localScopeRef }; -} -const ENoDefineSelf = (loc: Ast.Loc): E.TcError => ({ - loc, - descr: [ - E.TEText(`Cannot define a variable "self"`), - ], -}); -const ERedefineVar = (name: string, prev: Ast.Loc, next: Ast.Loc): E.TcError => ({ - loc: next, - descr: [ - E.TEText(`Variable ${name} is already defined`), - E.TEText(`Defined at:`), - E.TECode(next), - E.TEText(`Previously defined at:`), - E.TECode(prev), - ], -}); -const EShadowConst = (name: string, prev: Ast.Loc, next: Ast.Loc): E.TcError => ({ - loc: next, - descr: [ - E.TEText(`Variable ${name} shadows a global constant`), - E.TEText(`Defined at:`), - E.TECode(next), - E.TEText(`Previously defined at:`), - E.TECode(prev), - ], -}); - const decodeStatement: Decode = function (stmt, ctx, eff) { switch (stmt.kind) { case "statement_let": return decodeLet(stmt, ctx, eff); @@ -229,7 +75,7 @@ const decodeLet: Decode = function* (node, const result = Ast.DStatementLet(node.name, expr, node.loc); if (node.type) { const ascribed = yield* decodeType(ctx.typeParams, node.type, ctx.scopeRef().typeDecls) - yield* assignType(expr.loc, ascribed, expr.computedType); + yield* assignType(expr.loc, emptyTypeParams, ascribed, expr.computedType, false); const newCtx = yield* defineVar(node.name, ascribed, ctx); return Result(result, newCtx, eff); } else { @@ -242,10 +88,10 @@ const decodeReturn: Decode = function const newEff = yield* setHadExit(eff, true, ctx.required, node.loc); if (node.expression) { const expr = yield* decodeExprCtx(node.expression, ctx); - yield* assignType(expr.loc, ctx.returnType, expr.computedType); + yield* assignType(expr.loc, emptyTypeParams, ctx.returnType, expr.computedType, false); return Result(Ast.DStatementReturn(expr, node.loc), ctx, newEff); } else { - yield* assignType(node.loc, ctx.returnType, Void); + yield* assignType(node.loc, emptyTypeParams, ctx.returnType, Void, false); return Result(Ast.DStatementReturn(undefined, node.loc), ctx, newEff); } }; @@ -265,7 +111,7 @@ const decodeAssign: Decode = function* (node, ctx, eff) { const condition = yield* decodeExprCtx(node.condition, ctx); - yield* assignType(condition.loc, Bool, condition.computedType); - const trueRes = yield* rec(node.trueStatements, ctx, eff); + yield* assignType(condition.loc, emptyTypeParams, Bool, condition.computedType, false); + const trueRes = yield* decodeStmts(node.trueStatements, ctx, eff); if (node.falseStatements) { - const falseRes = yield* rec(node.falseStatements, ctx, eff); + const falseRes = yield* decodeStmts(node.falseStatements, ctx, eff); const newEff = mergeEff(trueRes.effects, falseRes.effects); return Result(Ast.DStatementCondition(condition, trueRes.node, falseRes.node, node.loc), ctx, newEff); } else { @@ -306,8 +159,8 @@ const decodeCondition: Decode = const decodeWhile: Decode = function* (node, ctx, eff) { const condition = yield* decodeExprCtx(node.condition, ctx); - yield* assignType(condition.loc, Bool, condition.computedType); - const result = yield* rec(node.statements, ctx, eff); + yield* assignType(condition.loc, emptyTypeParams, Bool, condition.computedType, false); + const result = yield* decodeStmts(node.statements, ctx, eff); // might be executed zero times, so it doesn't matter // if it always returns, or assigns to `self` return Result(Ast.DStatementWhile(condition, result.node, node.loc), ctx, eff); @@ -315,26 +168,26 @@ const decodeWhile: Decode = function* ( const decodeUntil: Decode = function* (node, ctx, eff) { const condition = yield* decodeExprCtx(node.condition, ctx); - yield* assignType(condition.loc, Bool, condition.computedType); - const result = yield* rec(node.statements, ctx, eff); + yield* assignType(condition.loc, emptyTypeParams, Bool, condition.computedType, false); + const result = yield* decodeStmts(node.statements, ctx, eff); // until executes its body at least once return Result(Ast.DStatementUntil(condition, result.node, node.loc), ctx, result.effects); }; const decodeRepeat: Decode = function* (node, ctx, eff) { const iterations = yield* decodeExprCtx(node.iterations, ctx); - yield* assignType(iterations.loc, Int, iterations.computedType); - const result = yield* rec(node.statements, ctx, eff); + yield* assignType(iterations.loc, emptyTypeParams, Int, iterations.computedType, false); + const result = yield* decodeStmts(node.statements, ctx, eff); // might be executed zero times, so it doesn't matter // if it always returns, or assigns to `self` return Result(Ast.DStatementRepeat(iterations, result.node, node.loc), ctx, eff); }; const decodeTry: Decode = function* (node, ctx, eff) { - const tryRes = yield* rec(node.statements, ctx, eff); + const tryRes = yield* decodeStmts(node.statements, ctx, eff); if (node.catchBlock) { const newCtx = yield* defineVar(node.catchBlock.name, Int, ctx); - const catchRes = yield* rec(node.catchBlock.statements, newCtx, eff); + const catchRes = yield* decodeStmts(node.catchBlock.statements, newCtx, eff); const catchBlock = Ast.DCatchBlock(node.catchBlock.name, catchRes.node); const newEff = mergeEff(tryRes.effects, catchRes.effects); return Result(Ast.DStatementTry(tryRes.node, catchBlock, node.loc), ctx, newEff); @@ -351,7 +204,7 @@ const decodeForeach: Decode = funct node.valueName, ctx, ); - const result = yield* rec(node.statements, innerCtx, eff); + const result = yield* decodeStmts(node.statements, innerCtx, eff); return Result(Ast.DStatementForEach(node.keyName, node.valueName, map, result.node, node.loc), ctx, eff); }; function* defineForVars( @@ -391,7 +244,7 @@ const decodeDestruct: Decode ({ }); const decodeBlock: Decode = function* (node, ctx, eff) { - const result = yield* rec(node.statements, ctx, eff); + const result = yield* decodeStmts(node.statements, ctx, eff); return Result(Ast.DStatementBlock(result.node, node.loc), ctx, result.effects); -}; \ No newline at end of file +}; + +type Decode = ( + node: T, + context: Context, + effects: Ast.Effects, +) => E.WithLog> + +type Result = { + readonly node: U; + readonly context: Context; + readonly effects: Ast.Effects; +} +const Result = ( + node: U, + context: Context, + effects: Ast.Effects, +): Result => Object.freeze({ node, context, effects }); + +type Context = { + readonly scopeRef: () => Ast.Scope; + readonly selfType: Ast.SelfType | undefined; + readonly required: undefined | ReadonlySet; + readonly typeParams: Ast.TypeParams; + readonly returnType: Ast.DecodedType; + readonly localScopeRef: ReadonlyMap; +} + +function* defineVar( + node: Ast.OptionalId, + type: Ast.DecodedType, + ctx: Context, +): E.WithLog { + if (node.kind === 'wildcard') { + // there is nothing to define for a wildcard + return ctx; + } + + if (node.text === 'self') { + yield ENoDefineSelf(node.loc); + return ctx; + } + + const prev = ctx.localScopeRef.get(node.text); + if (prev) { + const [, prevLoc] = prev; + yield ERedefineVar(node.text, prevLoc, node.loc); + return ctx; + } + + const constant = ctx.scopeRef().constants.get(node.text); + if (constant) { + const prevLoc = constant.via.defLoc; + yield EShadowConst(node.text, prevLoc, node.loc); + return ctx; + } + + const localScopeRef = new Map(ctx.localScopeRef); + localScopeRef.set(node.text, [type, node.loc]); + return { ...ctx, localScopeRef }; +} +const ENoDefineSelf = (loc: Ast.Loc): E.TcError => ({ + loc, + descr: [ + E.TEText(`Cannot define a variable "self"`), + ], +}); +const ERedefineVar = (name: string, prev: Ast.Loc, next: Ast.Loc): E.TcError => ({ + loc: next, + descr: [ + E.TEText(`Variable ${name} is already defined`), + E.TEText(`Defined at:`), + E.TECode(next), + E.TEText(`Previously defined at:`), + E.TECode(prev), + ], +}); +const EShadowConst = (name: string, prev: Ast.Loc, next: Ast.Loc): E.TcError => ({ + loc: next, + descr: [ + E.TEText(`Variable ${name} shadows a global constant`), + E.TEText(`Defined at:`), + E.TECode(next), + E.TEText(`Previously defined at:`), + E.TECode(prev), + ], +}); + +function* getRequired(selfType: Ast.SelfType | undefined): E.WithLog> { + if (!selfType) { + return new Set(); + } + const required: Set = new Set(); + switch (selfType.kind) { + case "type_ref": { + switch (selfType.type.kind) { + case "contract": + case "trait": { + const { fieldish } = (yield* selfType.type.content()); + for (const [name, field] of fieldish.map) { + if (field.decl.kind === 'field' && !field.decl.init) { + required.add(name) + } + } + return required; + } + case "struct": + case "message": + case "union": { + // no requirement to fill self on these, because they have + // no init() + return required; + } + } + // linter needs this + return required; + } + case "map_type": + case "TypeMaybe": + case "tuple_type": + case "tensor_type": + case "TyInt": + case "TySlice": + case "TyCell": + case "TyBuilder": + case "unit_type": + case "TypeVoid": + case "TypeNull": + case "TypeBool": + case "TypeAddress": + case "TypeString": + case "TypeStateInit": + case "TypeStringBuilder": { + return undefined; + } + } +} \ No newline at end of file diff --git a/src/next/types/struct-fields.ts b/src/next/types/struct-fields.ts index 27fed4f388..32cfac533c 100644 --- a/src/next/types/struct-fields.ts +++ b/src/next/types/struct-fields.ts @@ -5,6 +5,7 @@ import * as E from "@/next/types/errors"; import { evalExpr } from "@/next/types/expr-eval"; import { decodeExpr } from "@/next/types/expression"; import { assignType, decodeTypeLazy } from "@/next/types/type"; +import { emptyTypeParams } from "@/next/types/type-params"; export function* decodeFields( fields: readonly Ast.FieldDecl[], @@ -40,7 +41,7 @@ export function* decodeFields( ); const computed = expr.computedType; const ascribed = yield* ascribedType(); - yield* assignType(expr.loc, ascribed, computed); + yield* assignType(expr.loc, emptyTypeParams, ascribed, computed, false); return yield* evalExpr(expr, scopeRef); }) : undefined; diff --git a/src/next/types/tlb.ts b/src/next/types/tlb.ts index 4b18bfe771..219cb1f52f 100644 --- a/src/next/types/tlb.ts +++ b/src/next/types/tlb.ts @@ -1,34 +1,32 @@ +// export function convertTypeToTlb( +// node: Ast.DecodedType, +// ) { +// switch (node.kind) { +// case "recover": { +// return undefined; +// } +// case "type_ref": { +// } +// case "TypeAlias": { -export function convertTypeToTlb( - node: Ast.DecodedType, -) { - switch (node.kind) { - case "recover": { - return undefined; - } - case "type_ref": { - - } - case "TypeAlias": { - - } - case "TypeParam": - case "map_type": - case "TypeBounced": - case "TypeMaybe": - case "tuple_type": - case "tensor_type": - case "TyInt": - case "TySlice": - case "TyCell": - case "TyBuilder": - case "unit_type": - case "TypeVoid": - case "TypeNull": - case "TypeBool": - case "TypeAddress": - case "TypeString": - case "TypeStringBuilder": - } -} \ No newline at end of file +// } +// case "TypeParam": +// case "map_type": +// case "TypeBounced": +// case "TypeMaybe": +// case "tuple_type": +// case "tensor_type": +// case "TyInt": +// case "TySlice": +// case "TyCell": +// case "TyBuilder": +// case "unit_type": +// case "TypeVoid": +// case "TypeNull": +// case "TypeBool": +// case "TypeAddress": +// case "TypeString": +// case "TypeStringBuilder": +// } +// } \ No newline at end of file diff --git a/src/next/types/trait.ts b/src/next/types/trait.ts index bd7f8abca6..66a1e61a9f 100644 --- a/src/next/types/trait.ts +++ b/src/next/types/trait.ts @@ -45,6 +45,7 @@ export function* decodeTrait( scopeRef, ), receivers: yield* getReceivers( + () => selfType, name, traits, receivers, @@ -57,6 +58,13 @@ export function* decodeTrait( const traitSig = Ast.TraitSig(contentLazy); + const selfType = Ast.MVTypeRef( + trait.name, + traitSig, + [], + trait.loc, + ); + return traitSig; } diff --git a/src/next/types/type-fn.ts b/src/next/types/type-fn.ts index f0efc5be84..5e7d89e304 100644 --- a/src/next/types/type-fn.ts +++ b/src/next/types/type-fn.ts @@ -1,9 +1,10 @@ +/* eslint-disable require-yield */ +/* eslint-disable @typescript-eslint/no-unused-vars */ import * as Ast from "@/next/ast"; import * as E from "@/next/types/errors"; import { decodeTypeParams } from "@/next/types/type-params"; import { decodeDealiasTypeLazy } from "@/next/types/type"; import { recoverName } from "@/next/types/name"; -import { messageBuiltin, structBuiltin } from "@/next/types/builtins"; export function* decodeFnType( { typeParams, params, returnType }: Ast.FnType, @@ -61,108 +62,3 @@ const EDuplicateParam = (name: string, loc: Ast.Loc): E.TcError => ({ E.TEText(`Duplicate parameter "${name}"`), ], }); - -export type CallResult = { - readonly returnType: Ast.DecodedType; - readonly typeArgs: ReadonlyMap; -} - -export function* getCallResult( - fn: Ast.DecodedFnType, - args: readonly Ast.DecodedType[], -): E.WithLog { - // yield* assignType(ascribed.key, key.computedType, ctx.scopeRef); -} - -export function* lookupMethod( - selfType: Ast.DecodedType, - methodName: string, - computedArgTypes: readonly Ast.DecodedType[], - typeDecls: ReadonlyMap>, - extensions: ReadonlyMap[]>>, -): E.WithLog { - if (self.computedType.kind === 'type_ref') { - const selfDecl = ctx.scopeRef().typeDecls.get(self.computedType.name.text); - if (!selfDecl) { - // - } else if (selfDecl.decl.kind === 'struct') { - const builtin = structBuiltin.get(node.method.text); - if (builtin) { - return Ast.DMethodCall(self, node.method, args, typeArgs, returnType, node.loc); - } - } else if (selfDecl.decl.kind === 'message') { - const builtin = messageBuiltin.get(node.method.text); - } - } - - switch (selfType.kind) { - case "recover": - case "type_ref": - case "TypeAlias": - case "TypeParam": - case "map_type": - case "TypeBounced": - case "TypeMaybe": - case "tuple_type": - case "tensor_type": - case "TyInt": - case "TySlice": - case "TyCell": - case "TyBuilder": - case "unit_type": - case "TypeVoid": - case "TypeNull": - case "TypeBool": - case "TypeAddress": - case "TypeString": - case "TypeStringBuilder": - } - if (selfType.kind === 'type_ref') { - const typeName = selfType.name.text; - const decl = typeDecls.get(typeName) - switch (decl?.decl.kind) { - case undefined: { - return; - } - case "alias": { - return; - } - case "trait": - case "contract": { - const { methods } = yield* decl.decl.content(); - const method = methods.get(methodName); - if (!method) { - return; - } - const methodType = method.decl.type; - return; - } - case "struct": - case "message": - case "union": { - const extsLazy = extensions.get(methodName); - if (!extsLazy) { - return; - } - for (const { decl } of yield* extsLazy()) { - const methodType = decl.type; - // methodType.typeParams - // typeArgs - if (methodType.self.ground === 'yes') { - // - } else { - // - } - } - } - } - } -} - -export function* lookupFunction( - fnType: Ast.DecodedFnType | undefined, - ascribed: readonly Ast.DecodedType[], - argTypes: readonly Ast.DecodedType[], -): E.WithLog { - -} \ No newline at end of file diff --git a/src/next/types/type-method.ts b/src/next/types/type-method.ts deleted file mode 100644 index c73482a9c3..0000000000 --- a/src/next/types/type-method.ts +++ /dev/null @@ -1,10 +0,0 @@ -import * as Ast from "@/next/ast"; -import * as E from "@/next/types/errors"; - -export function* assignMethodType( - prev: Ast.DecodedMethodType, - next: Ast.DecodedMethodType, - scopeRef: () => Ast.Scope -): E.WithLog { - -} \ No newline at end of file diff --git a/src/next/types/type-params.ts b/src/next/types/type-params.ts index 5498590a41..0ad38eacc6 100644 --- a/src/next/types/type-params.ts +++ b/src/next/types/type-params.ts @@ -2,6 +2,8 @@ import * as Ast from "@/next/ast"; import * as E from "@/next/types/errors"; import { recoverName } from "@/next/types/name"; +export const emptyTypeParams = Ast.TypeParams([], new Set()); + export function* decodeTypeParams(ids: readonly Ast.TypeId[]): E.WithLog { const set: Set = new Set(); const order: Ast.TypeId[] = []; diff --git a/src/next/types/type.ts b/src/next/types/type.ts index baa71e4c50..7229746a98 100644 --- a/src/next/types/type.ts +++ b/src/next/types/type.ts @@ -2,31 +2,12 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ import { throwInternal } from "@/error/errors"; import * as Ast from "@/next/ast"; +import { messageBuiltin, structBuiltin } from "@/next/types/builtins"; import * as E from "@/next/types/errors"; +import { emptyTypeParams } from "@/next/types/type-params"; import { printType } from "@/next/types/type-print"; import { zip } from "@/utils/array"; -// type C = map -// type B = [T, U] -// type A = B> - -// head-first -// A -> B> -> [X, C] -> [X, map] - -// arg-first -// A -> B> -> B> -> [X, map] - -// if head of the type is an alias -// substitute alias -// store head and args -// recurse -// if head of the type is another type -// recurse on arguments - -// we never substitute into alias-cons (throwInternal) -// substitution only happens into body of alias decl -// body of alias decl is not dealiased, thus doesn't have alias-cons - export const decodeTypeLazy = ( typeParams: Ast.TypeParams, type: Ast.Type, @@ -178,7 +159,7 @@ export function decodeType( type.loc, ); } - + const typeEntry = typeDecls.get(name); // there is no such type at all! @@ -310,7 +291,7 @@ const dealiasTypeAux = ( } // NB! if we could decode alias once, there might be // a nested one too - const decoded = yield* rec(substitute( + const decoded = yield* rec(substituteTypeArgs( yield* alias.decl.type(), alias.decl.typeParams, yield* E.mapLog(type.typeArgs, rec), @@ -358,8 +339,8 @@ const dealiasTypeAux = ( return rec(type); }; -// NB! is substitute is used for something other than aliases, do not throwInternal on type.type -const substitute = ( +// NB! if substitute is used for something other than aliases, do not throwInternal on type.type +export const substituteTypeArgs = ( type: Ast.DecodedType, params: Ast.TypeParams, args: readonly Ast.DecodedType[], @@ -375,7 +356,7 @@ const substitute = ( const recN = (types: readonly Ast.DecodedType[]): readonly Ast.DecodedType[] => { return types.map(type => rec(type)); }; - + const rec = (type: Ast.DecodedType): Ast.DecodedType => { switch (type.kind) { case "TypeParam": { @@ -390,11 +371,13 @@ const substitute = ( return Ast.DTypeRef(type.name, type.type, args, type.loc); } case "TypeAlias": { - const args = recN(type.typeArgs); - if (type.type.kind !== 'NotDealiased') { - return throwInternal("Substitution must not happen into a type with resolved aliases"); + if (type.type.kind === 'NotDealiased') { + const args = recN(type.typeArgs); + return Ast.DTypeAliasRef(type.type, type.name, args, type.loc); + } else { + const args = recN(type.typeArgs); // ?? + return Ast.DTypeAliasRef(rec(type.type), type.name, args, type.loc); } - return Ast.DTypeAliasRef(type.type, type.name, args, type.loc); } case "map_type": { const key = rec(type.key); @@ -476,8 +459,8 @@ export function* instantiateStruct( return { type: Ast.DTypeRef( typeName, - decl.decl, - typeArgs, + decl.decl, + typeArgs, typeName.loc, ), fields: decl.decl.fields @@ -536,18 +519,75 @@ const ETypeArity = (name: string, loc: Ast.Loc, declArity: number, useArity: num ], }); +export function typeParamsToSubst(typeParams: Ast.TypeParams) { + const subst: Map = new Map( + typeParams.order.map(name => [name.text, Ast.DNotSet()]) + ); + return subst; +} + +export function* substToTypeArgMap( + loc: Ast.Loc, + subst: Map +): E.WithLog { + const res = substToTypeArgMapAux(subst); + if (res.ok) { + return res.args; + } else { + for (const name of res.names) { + yield EFreeTypeParam(name, loc); + } + return undefined; + } +} + +function substToTypeArgMapAux( + subst: Map +): { ok: true, args: Ast.TypeArgs} | { ok: false, names: readonly string[] } { + const args: Map = new Map(); + const names: string[] = []; + for (const [name, type] of subst) { + if (type.kind === 'not-set') { + names.push(name); + } else { + args.set(name, type); + } + } + if (names.length > 0) { + return { ok: false, names }; + } else { + return { ok: true, args }; + } +} + export function* assignType( loc: Ast.Loc, + toFreeTypeParam: Ast.TypeParams, to: Ast.DecodedType, from: Ast.DecodedType, -): E.WithLog { - const result = assignTypeAux(to, from); + strict: boolean, +): E.WithLog { + const subst = typeParamsToSubst(toFreeTypeParam); + const result = assignTypeAux(to, from, subst, strict); if (result.kind === 'failure') { yield EMismatch(result.tree, loc); - return false; + return undefined; } - return true; + return yield* substToTypeArgMap(loc, subst); } +const EFreeTypeParam = (paramName: string, loc: Ast.Loc): E.TcError => ({ + loc, + descr: [ + E.TEText(`No substitution for type parameter "${paramName}"`), + ], +}); +const EMismatch = (tree: E.MatchTree, loc: Ast.Loc): E.TcError => ({ + loc, + descr: [ + E.TEText(`Type mismatch`), + E.TEMismatch(tree), + ], +}); type AssignResult = AssignSuccess | AssignFailure type AssignSuccess = { @@ -562,12 +602,14 @@ const AssignFailure = (tree: E.MatchTree): AssignFailure => Object.freeze({ kind type Log = Generator; -function assignTypeAux( +export function assignTypeAux( to: Ast.DecodedType, from: Ast.DecodedType, + subst: Map, + strict: boolean, ) { function* recN( - tos: readonly Ast.DecodedType[], + tos: readonly Ast.DecodedType[], froms: readonly Ast.DecodedType[], ): Log { if (tos.length !== froms.length) { @@ -584,7 +626,7 @@ function assignTypeAux( } function* rec( - to: Ast.DecodedType, + to: Ast.DecodedType, from: Ast.DecodedType, ): Log { const result = collectMismatches(to, from); @@ -596,7 +638,7 @@ function assignTypeAux( } function collectMismatches( - to: Ast.DecodedType, + to: Ast.DecodedType, from: Ast.DecodedType, ): AssignResult { const gen = check(to, from); @@ -623,7 +665,7 @@ function assignTypeAux( } function* check( - to: Ast.DecodedType, + to: Ast.DecodedType, from: Ast.DecodedType, ): Log { if (from.kind === 'TypeAlias') { @@ -645,9 +687,17 @@ function assignTypeAux( return yield* rec(to, from); } case "type_ref": { - return to.kind === from.kind && - to.name.text === from.name.text && - (yield* recN(to.typeArgs, from.typeArgs)); + const typeVar = subst.get(to.name.text); + if (!typeVar) { + return to.kind === from.kind && + to.name.text === from.name.text && + (yield* recN(to.typeArgs, from.typeArgs)); + } else if (typeVar.kind === 'not-set') { + subst.set(to.name.text, from); + return true; + } else { + return yield* rec(typeVar, from); + } } case "tuple_type": case "tensor_type": { @@ -657,20 +707,20 @@ function assignTypeAux( case "TypeParam": { return to.kind === from.kind && to.name.text === from.name.text; - } + } case "TypeBounced": { return to.kind === from.kind && to.name.text === from.name.text; } case "TypeMaybe": { - return from.kind === 'TypeNull' || + return !strict && from.kind === 'TypeNull' || to.kind === from.kind && (yield* rec(to.type, from.type)); } case "map_type": { - return from.kind === 'TypeNull' || + return !strict && from.kind === 'TypeNull' || to.kind === from.kind && - (yield* rec(to.key, from.key)) && + (yield* rec(to.key, from.key)) && (yield* rec(to.value, from.value)); } case "TyInt": @@ -692,13 +742,6 @@ function assignTypeAux( return collectMismatches(to, from); } -const EMismatch = (tree: E.MatchTree, loc: Ast.Loc): E.TcError => ({ - loc, - descr: [ - E.TEText(`Type mismatch`), - E.TEMismatch(tree), - ], -}); export function* mgu( left: Ast.DecodedType, @@ -723,11 +766,11 @@ export function* mgu( left = left.type; return yield* rec(left, left); } - const resultL = assignTypeAux(left, right); + const resultL = assignTypeAux(left, right, new Map(), false); if (resultL.kind === 'success') { return left; } - const resultR = assignTypeAux(right, left); + const resultR = assignTypeAux(right, left, new Map(), false); if (resultR.kind === 'success') { return right; } @@ -749,4 +792,381 @@ const ENotUnifiable = (tree: E.MatchTree, loc: Ast.Loc): E.TcError => ({ E.TEText(`Branches of condition have mismatched types`), E.TEMismatch(tree), ], +}); + +export type CallResult = { + readonly returnType: Ast.DecodedType; + readonly typeArgMap: Ast.TypeArgs; +} + +export function* checkFnCall( + loc: Ast.Loc, + fnType: Ast.DecodedFnType | Ast.DecodedMethodType, + args: readonly (readonly [Ast.Loc, Ast.DecodedType])[], +): E.WithLog { + const { typeParams, params, returnType } = fnType; + + const subst = typeParamsToSubst(typeParams); + + for (const [index, { name, type, loc }] of params.order.entries()) { + const pair = args[index]; + if (!pair) { + // not enough args + break; + } + const [argLoc, arg] = pair; + const result = assignTypeAux( + yield* type(), + arg, + subst, + false, + ); + if (result.kind === 'failure') { + yield EMismatchArg( + getParamName(name, index), + result.tree, + argLoc, + ); + } + } + + // not enough or too many args + if (params.order.length !== args.length) { + yield EFnArity('Function', params.order.length, args.length, loc); + } + + const typeArgsMap = yield* substToTypeArgMap(loc, subst); + + if (!typeArgsMap) { + return { + returnType: Ast.DTypeRecover(), + typeArgMap: new Map(), + }; + } + + const typeArgs: Ast.DecodedType[] = []; + for (const param of typeParams.order) { + const arg = typeArgsMap.get(param.text); + if (!arg) { + return throwInternal("substToTypeArgMap lost param"); + } + typeArgs.push(arg); + } + + const retType = substituteTypeArgs( + yield* returnType(), + typeParams, + typeArgs, + ); + + return { returnType: retType, typeArgMap: typeArgsMap }; +} +const EMismatchArg = (name: string, tree: E.MatchTree, loc: Ast.Loc): E.TcError => ({ + loc, + descr: [ + E.TEText(`Type doesn't match type of parameter ${name}`), + E.TEMismatch(tree), + ], +}); + +function getParamName(name: Ast.OptionalId, index: number) { + return name.kind === 'id' ? name.text : `#${index + 1}`; +} + +const EFnArity = ( + kind: string, + expected: number, + got: number, + loc: Ast.Loc, +): E.TcError => ({ + loc, + descr: [ + E.TEText(`${kind} is expected to have ${expected} type arguments, got ${got}`), + ], +}); + +export function* checkFnCallWithArgs( + loc: Ast.Loc, + fnType: Ast.DecodedFnType | undefined, + ascribedTypeArgs: readonly Ast.DecodedType[], + args: readonly (readonly [Ast.Loc, Ast.DecodedType])[], +): E.WithLog { + if (!fnType) { + yield ENoFunction(loc); + return { returnType: Ast.DTypeRecover(), typeArgMap: new Map() }; + } + if (ascribedTypeArgs.length === 0) { + return yield* checkFnCall(loc, fnType, args) + } + if (fnType.typeParams.order.length !== ascribedTypeArgs.length) { + return { returnType: Ast.DTypeRecover(), typeArgMap: new Map() }; + } + const result = yield* checkFnCall( + loc, + substFnType(fnType, ascribedTypeArgs), + args, + ); + return { + returnType: result.returnType, + typeArgMap: new Map( + zip(fnType.typeParams.order, args) + .map(([name, [, type]]) => [name.text, type]), + ), + }; +} +const ENoFunction = (loc: Ast.Loc): E.TcError => ({ + loc, + descr: [ + E.TEText(`No such function`), + E.TECode(loc), + ], +}); + +function substFnType( + { typeParams, params, returnType }: Ast.DecodedFnType | Ast.DecodedMethodType, + args: readonly Ast.DecodedType[], +) { + const order: Ast.Parameter[] = []; + for (const param of params.order) { + order.push(Ast.Parameter( + param.name, + Ast.Lazy(function* () { + return substituteTypeArgs( + yield* param.type(), + typeParams, + args, + ); + }), + param.loc, + )); + } + return Ast.DecodedFnType( + emptyTypeParams, + Ast.Parameters( + order, + params.set + ), + Ast.Lazy(function* () { + return substituteTypeArgs( + yield* returnType(), + typeParams, + args, + ); + }), + ); +} + +export function* lookupMethod( + selfType: Ast.DecodedType, + method: Ast.Id, + args: readonly (readonly [Ast.Loc, Ast.DecodedType])[], + typeDecls: ReadonlyMap>, + extensions: ReadonlyMap[]>>, +): E.WithLog { + if (selfType.kind === 'recover') { + return { returnType: Ast.DTypeRecover(), typeArgMap: new Map() }; + } + if (selfType.kind === 'TypeAlias') { + if (selfType.type.kind === 'NotDealiased') { + return throwInternal("Calling method on non-dealiased type") + } + + return yield* lookupMethod( + selfType, + method, + args, + typeDecls, + extensions, + ); + } + + if (selfType.kind !== 'type_ref') { + return yield* lookupExts( + selfType, + method, + args, + extensions, + ); + } + + const selfDecl = typeDecls.get(selfType.name.text); + if (!selfDecl) { + yield ENoMethod(method.loc); + return { returnType: Ast.DTypeRecover(), typeArgMap: new Map() }; + } + + if (selfDecl.decl.kind === 'struct' || selfDecl.decl.kind === 'message') { + const builtinMap = selfDecl.decl.kind === 'struct' + ? structBuiltin + : messageBuiltin; + const builtin = builtinMap.get(method.text); + if (builtin) { + return yield* checkFnCall(method.loc, builtin, args); + } + return yield* lookupExts( + selfType, + method, + args, + extensions, + ); + } + + if (selfDecl.decl.kind === 'contract' || selfDecl.decl.kind === 'trait') { + const content = yield* selfDecl.decl.content(); + const met = content.methods.get(method.text); + if (!met) { + yield ENoMethod(method.loc); + return { returnType: Ast.DTypeRecover(), typeArgMap: new Map() }; + } + return yield* checkFnCall( + method.loc, + met.decl.type, + args + ); + } + + yield ENoMethod(method.loc); + return { returnType: Ast.DTypeRecover(), typeArgMap: new Map() }; +} + +function* lookupExts( + selfType: Ast.DecodedType, + method: Ast.Id, + args: readonly (readonly [Ast.Loc, Ast.DecodedType])[], + extensions: ReadonlyMap[]>>, +) { + const lazyExts = extensions.get(method.text); + if (!lazyExts) { + yield ENoMethod(method.loc); + return { returnType: Ast.DTypeRecover(), typeArgMap: new Map() }; + } + const exts = yield* lazyExts(); + const grounds: [Ast.DecodedMethodType, Ast.TypeArgs][] = [] + const withVars: [Ast.DecodedMethodType, Ast.TypeArgs][] = [] + for (const { decl } of exts) { + const subst = typeParamsToSubst(decl.type.typeParams); + const result = assignTypeAux(decl.type.self, selfType, subst, true); + if (result.kind !== 'success') { + continue; + } + const res = substToTypeArgMapAux(subst); + if (!res.ok) { + continue; + } + const into = decl.type.self.ground + ? grounds + : withVars; + into.push([decl.type, res.args]); + } + if (grounds.length > 1 || withVars.length > 1) { + return throwInternal("Overlapping methods were allowed"); + } + const [ground] = grounds; + const [withVar] = withVars; + const either = ground || withVar; + if (!either) { + yield ENoMethod(method.loc); + return { returnType: Ast.DTypeRecover(), typeArgMap: new Map() }; + } + const [methodType, typeArgs] = either; + const result = yield* checkFnCall( + method.loc, + substFnType( + methodType, + typeArgsToParams(typeArgs, methodType.typeParams), + ), + args + ); + return { + returnType: result.returnType, + typeArgMap: typeArgs, + }; +} + +function typeArgsToParams( + args: Ast.TypeArgs, + params: Ast.TypeParams, +) { + const result: Ast.DecodedType[] = []; + for (const name of params.order) { + const arg = args.get(name.text); + if (!arg) { + return throwInternal("Lost type arguments"); + } + result.push(arg); + } + return result; +} + +const ENoMethod = (loc: Ast.Loc): E.TcError => ({ + loc, + descr: [ + E.TEText(`No such method`), + E.TECode(loc), + ], +}); + +export function* assignMethodType( + prev: Ast.DecodedMethodType, + next: Ast.DecodedMethodType, + prevVia: Ast.ViaMember, + nextVia: Ast.ViaMember +): E.WithLog { + const result = assignTypeAux( + yield* prev.returnType(), + yield* next.returnType(), + new Map(), + true + ); + if (result.kind === 'failure') { + yield EMismatchReturn(result.tree, prevVia.defLoc, nextVia.defLoc); + return undefined; + } + const prevArity = prev.params.order.length; + const nextArity = next.params.order.length; + + for (const [index, [prevParam, nextParam]] of zip(prev.params.order, next.params.order).entries()) { + const result = assignTypeAux( + yield* prevParam.type(), + yield* nextParam.type(), + new Map(), + true + ); + if (result.kind === 'failure') { + yield EMismatchParam( + getParamName(nextParam.name, index), + result.tree, + prevVia.defLoc, + nextVia.defLoc, + ); + } + } + + if (prevArity !== nextArity) { + yield EFnArity('Method', prevArity, nextArity, nextVia.defLoc) + } +} + +const EMismatchReturn = (tree: E.MatchTree, prev: Ast.Loc, next: Ast.Loc): E.TcError => ({ + loc: next, + descr: [ + E.TEText(`Return type doesn't match with inherited method`), + E.TEMismatch(tree), + E.TEText(`Inherited from:`), + E.TECode(prev), + E.TEText(`Override at:`), + E.TECode(next), + ], +}); + +const EMismatchParam = (name: string, tree: E.MatchTree, prev: Ast.Loc, next: Ast.Loc): E.TcError => ({ + loc: next, + descr: [ + E.TEText(`Type of parameter ${name} doesn't match with inherited method`), + E.TEMismatch(tree), + E.TEText(`Inherited from:`), + E.TECode(prev), + E.TEText(`Override at:`), + E.TECode(next), + ], }); \ No newline at end of file diff --git a/src/next/types/union.ts b/src/next/types/union.ts index 9c25020b68..6dee138d07 100644 --- a/src/next/types/union.ts +++ b/src/next/types/union.ts @@ -5,7 +5,7 @@ import * as E from "@/next/types/errors"; import { evalExpr } from "@/next/types/expr-eval"; import { decodeExpr } from "@/next/types/expression"; import { assignType, decodeTypeLazy } from "@/next/types/type"; -import { decodeTypeParams } from "@/next/types/type-params"; +import { decodeTypeParams, emptyTypeParams } from "@/next/types/type-params"; type Cons = { readonly fields: ReadonlyMap; @@ -46,7 +46,7 @@ export function* decodeUnion( ); const computed = expr.computedType; const ascribed = yield* ascribedType(); - yield* assignType(expr.loc, ascribed, computed); + yield* assignType(expr.loc, emptyTypeParams, ascribed, computed, false); return yield* evalExpr(expr, scopeRef); }) : undefined; const decoded = Ast.InhFieldSig(ascribedType, lazyExpr); From 21036c66012be66555df534bf07071800a7c2c47 Mon Sep 17 00:00:00 2001 From: verytactical <186486509+verytactical@users.noreply.github.com> Date: Mon, 2 Jun 2025 01:57:21 +0400 Subject: [PATCH 31/38] cleanup --- src/next/ast/checked-expr.ts | 3 -- src/next/ast/expression.ts | 1 - src/next/ast/generated/vtype.ts | 74 ---------------------------- src/next/ast/index.ts | 1 - src/next/ast/vtype.ts | 85 --------------------------------- src/next/types/body.ts | 2 - src/next/types/contract.ts | 8 ---- src/next/types/methods.ts | 2 - src/next/types/type.ts | 1 - 9 files changed, 177 deletions(-) delete mode 100644 src/next/ast/generated/vtype.ts delete mode 100644 src/next/ast/vtype.ts diff --git a/src/next/ast/checked-expr.ts b/src/next/ast/checked-expr.ts index b436d7091f..d890f1f422 100644 --- a/src/next/ast/checked-expr.ts +++ b/src/next/ast/checked-expr.ts @@ -4,9 +4,6 @@ import type * as D from "@/next/ast/dtype"; import type { BinaryOperation, NumberBase, UnaryOperation } from "@/next/ast/expression"; import type { SelfType } from "@/next/ast/mtype"; -// TODO: put Self into main AST and parser -// TODO: add effects - export type TypeArgs = ReadonlyMap; export type DecodedExpression = diff --git a/src/next/ast/expression.ts b/src/next/ast/expression.ts index 09dbbe29d9..c413f38aa3 100644 --- a/src/next/ast/expression.ts +++ b/src/next/ast/expression.ts @@ -107,7 +107,6 @@ export type MethodCall = { readonly kind: "method_call"; readonly self: Expression; // anything with a method readonly method: Id; - // readonly typeArgs: readonly Type[]; readonly args: readonly Expression[]; readonly loc: Loc; }; diff --git a/src/next/ast/generated/vtype.ts b/src/next/ast/generated/vtype.ts deleted file mode 100644 index 33d7a4fcdd..0000000000 --- a/src/next/ast/generated/vtype.ts +++ /dev/null @@ -1,74 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unnecessary-condition */ -import type * as $ from "@/next/ast/vtype"; -import type * as $c from "@/next/ast/common"; - -export type VTypeVar = $.VTypeVar; -export const VTypeVar = (id: number): $.VTypeVar => Object.freeze({ - kind: "type_var", - id -}); -export const isVTypeVar = ($value: VTypeVar) => $value.kind === "type_var"; -export type VTypeInt = $.VTypeInt; -export type VTypeSlice = $.VTypeSlice; -export type VTypeCell = $.VTypeCell; -export type VTypeBuilder = $.VTypeBuilder; -export type VTypeUnit = $.VTypeUnit; -export type VTypeVoid = $.VTypeVoid; -export type VTypeNull = $.VTypeNull; -export type VTypeBool = $.VTypeBool; -export type VTypeAddress = $.VTypeAddress; -export type VTypeString = $.VTypeString; -export type VTypeStringBuilder = $.VTypeStringBuilder; -export type VTypeMaybe = $.VTypeMaybe; -export const VTypeMaybe = (type_: $.VType, loc: $c.Loc): $.VTypeMaybe => Object.freeze({ - kind: "TypeMaybe", - type: type_, - loc -}); -export const isVTypeMaybe = ($value: VTypeMaybe) => $value.kind === "TypeMaybe"; -export type VTypeBounced = $.VTypeBounced; -export const VTypeBounced = (type_: $.VType, loc: $c.Loc): $.VTypeBounced => Object.freeze({ - kind: "TypeBounced", - type: type_, - loc -}); -export const isVTypeBounced = ($value: VTypeBounced) => $value.kind === "TypeBounced"; -export type VTypeTensor = $.VTypeTensor; -export const VTypeTensor = (typeArgs: readonly $.VType[], loc: $c.Loc): $.VTypeTensor => Object.freeze({ - kind: "tensor_type", - typeArgs, - loc -}); -export const isVTypeTensor = ($value: VTypeTensor) => $value.kind === "tensor_type"; -export type VTypeTuple = $.VTypeTuple; -export const VTypeTuple = (typeArgs: readonly $.VType[], loc: $c.Loc): $.VTypeTuple => Object.freeze({ - kind: "tuple_type", - typeArgs, - loc -}); -export const isVTypeTuple = ($value: VTypeTuple) => $value.kind === "tuple_type"; -export type VTypeCons = $.VTypeCons; -export const VTypeCons = (name: $c.TypeId, typeArgs: readonly $.VType[], loc: $c.Loc): $.VTypeCons => Object.freeze({ - kind: "cons_type", - name, - typeArgs, - loc -}); -export const isVTypeCons = ($value: VTypeCons) => $value.kind === "cons_type"; -export type VTypeMap = $.VTypeMap; -export const VTypeMap = (key: $.VType, value: $.VType, loc: $c.Loc): $.VTypeMap => Object.freeze({ - kind: "map_type", - key, - value, - loc -}); -export const isVTypeMap = ($value: VTypeMap) => $value.kind === "map_type"; -export type VType = $.VType; -export type VTypeAlias = $.VTypeAlias; -export const VTypeAlias = (cons: $.VTypeCons, type_: $.VType, loc: $c.Loc): $.VTypeAlias => Object.freeze({ - kind: "TypeAlias", - cons, - type: type_, - loc -}); -export const isVTypeAlias = ($value: VTypeAlias) => $value.kind === "TypeAlias"; diff --git a/src/next/ast/index.ts b/src/next/ast/index.ts index 2806ed181f..51ef0ef6b4 100644 --- a/src/next/ast/index.ts +++ b/src/next/ast/index.ts @@ -2,7 +2,6 @@ export * from "@/next/ast/generated/common"; export * from "@/next/ast/generated/expression"; export * from "@/next/ast/generated/statement"; export * from "@/next/ast/generated/type"; -export * from "@/next/ast/generated/vtype"; export * from "@/next/ast/generated/dtype"; export * from "@/next/ast/generated/mtype"; export * from "@/next/ast/generated/via"; diff --git a/src/next/ast/vtype.ts b/src/next/ast/vtype.ts deleted file mode 100644 index f7cb414cf9..0000000000 --- a/src/next/ast/vtype.ts +++ /dev/null @@ -1,85 +0,0 @@ -import type { Loc, TypeId } from "@/next/ast/common"; -import type * as Ast from "@/next/ast/type"; - -export type VType = - | VTypeVar - | VTypeMap - | VTypeCons - | VTypeTuple - | VTypeTensor - | VTypeAlias - | VTypeInt - | VTypeSlice - | VTypeCell - | VTypeBuilder - | VTypeUnit - | VTypeVoid - | VTypeNull - | VTypeBool - | VTypeAddress - | VTypeString - | VTypeStringBuilder - | VTypeBounced - | VTypeMaybe; - -export type VTypeInt = Ast.TypeInt; -export type VTypeSlice = Ast.TypeSlice; -export type VTypeCell = Ast.TypeCell; -export type VTypeBuilder = Ast.TypeBuilder; -export type VTypeUnit = Ast.TypeUnit; -export type VTypeVoid = Ast.TypeVoid; -export type VTypeNull = Ast.TypeNull; -export type VTypeBool = Ast.TypeBool; -export type VTypeAddress = Ast.TypeAddress; -export type VTypeString = Ast.TypeString; -export type VTypeStringBuilder = Ast.TypeStringBuilder; - -export type VTypeVar = { - readonly kind: "type_var"; - readonly id: number; -} - -export type VTypeAlias = { - readonly kind: "TypeAlias" - readonly cons: VTypeCons; - readonly type: VType; - readonly loc: Loc; -} - -export type VTypeCons = { - readonly kind: "cons_type"; - readonly name: TypeId; - readonly typeArgs: readonly VType[]; - readonly loc: Loc; -}; - -export type VTypeTuple = { - readonly kind: "tuple_type"; - readonly typeArgs: readonly VType[]; - readonly loc: Loc; -}; - -export type VTypeTensor = { - readonly kind: "tensor_type"; - readonly typeArgs: readonly VType[]; - readonly loc: Loc; -}; - -export type VTypeMap = { - readonly kind: "map_type"; - readonly key: VType; - readonly value: VType; - readonly loc: Loc; -}; - -export type VTypeBounced = { - readonly kind: "TypeBounced" - readonly type: VType; - readonly loc: Loc; -} - -export type VTypeMaybe = { - readonly kind: "TypeMaybe" - readonly type: VType; - readonly loc: Loc; -} diff --git a/src/next/types/body.ts b/src/next/types/body.ts index 8a55259e47..4b19e83d8c 100644 --- a/src/next/types/body.ts +++ b/src/next/types/body.ts @@ -150,8 +150,6 @@ function* getTypeTupleSize( type: Ast.DecodedType, scopeRef: () => Ast.Scope, ) { -// TODO: mutating functions also return `self` arg (implicitly in Tact, but explicitly in FunC) - // retTupleSize += isMutating ? 1 : 0; switch (type.kind) { case "recover": { return undefined; diff --git a/src/next/types/contract.ts b/src/next/types/contract.ts index 06185cd7db..437e62988d 100644 --- a/src/next/types/contract.ts +++ b/src/next/types/contract.ts @@ -131,14 +131,6 @@ function* decodeInit( if (!param.initializer) { yield ENoInitializerParams(param.loc); } - // TODO: support Foo { } syntax for contracts - // const lazyExpr = Ast.Lazy(function* () { - // const expr = yield* decodeExpr(param.initializer, scopeRef)(); - // const computed = expr.computedType; - // const ascribed = yield* decoded(); - // yield* assignType( ascribed, computed, scopeRef); - // return yield* evalExpr(expr, scopeRef); - // }); map.set(name, Ast.InitParam(decoded, undefined, param.loc)); } return Ast.InitSimple(Ast.Ordered(order, map), init.loc); diff --git a/src/next/types/methods.ts b/src/next/types/methods.ts index 62c76aa1de..82cc54b5e7 100644 --- a/src/next/types/methods.ts +++ b/src/next/types/methods.ts @@ -166,8 +166,6 @@ function* decodeGet( return methodId.value; } // if evaluation failed, fallthrough to computing it - } else { - // TODO: yield EMismatch(); } } diff --git a/src/next/types/type.ts b/src/next/types/type.ts index 7229746a98..3feec5f382 100644 --- a/src/next/types/type.ts +++ b/src/next/types/type.ts @@ -432,7 +432,6 @@ export function* instantiateStruct( return undefined; } case "contract": { - // TODO: support Foo { } syntax for contracts yield ENotInstantiable(typeName.text, typeName.loc); return undefined; } From efc2c4d3284e61b9ba0ed389c02dbb793caf4d02 Mon Sep 17 00:00:00 2001 From: verytactical <186486509+verytactical@users.noreply.github.com> Date: Mon, 2 Jun 2025 01:58:13 +0400 Subject: [PATCH 32/38] 1 --- src/next/ast/dtype.ts | 4 ---- src/next/ast/lazy.ts | 1 + src/next/types/errors.ts | 2 -- src/next/types/expression.ts | 1 - 4 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/next/ast/dtype.ts b/src/next/ast/dtype.ts index 3c2171567f..689f8ac2df 100644 --- a/src/next/ast/dtype.ts +++ b/src/next/ast/dtype.ts @@ -2,10 +2,6 @@ import type { TypeDeclRefable } from "@/next/ast/checked"; import type { Loc, TypeId } from "@/next/ast/common"; import type * as Ast from "@/next/ast/type"; -// TODO: -// readonly tlb: Lazy -// readonly effects: Lazy - export type DNotSet = { readonly kind: "not-set"; } diff --git a/src/next/ast/lazy.ts b/src/next/ast/lazy.ts index bfe3074ae9..ce3ec7d7c0 100644 --- a/src/next/ast/lazy.ts +++ b/src/next/ast/lazy.ts @@ -36,3 +36,4 @@ export const mapLazy = (f: Lazy, g: (t: T) => U): Lazy => { function* impossible(): WithLog { return throwInternal("Infinite loop in typechecker"); } + diff --git a/src/next/types/errors.ts b/src/next/types/errors.ts index e3eace6b13..e6e8334872 100644 --- a/src/next/types/errors.ts +++ b/src/next/types/errors.ts @@ -2,8 +2,6 @@ import { throwInternal } from "@/error/errors"; import type { DecodedType, Loc, Via, ViaMember, ViaUser } from "@/next/ast"; import type * as V from "@/next/ast/via"; -// TODO: move to src/next/ast/ to avoid an extra E.* everywhere - export type WithLog = Generator export function runLog(gen: Generator): readonly [R, readonly T[]] { diff --git a/src/next/types/expression.ts b/src/next/types/expression.ts index 9602b07430..dac343e390 100644 --- a/src/next/types/expression.ts +++ b/src/next/types/expression.ts @@ -500,7 +500,6 @@ function* lookupField( yield ENoSuchField(fieldName.text, fieldName.loc); return Ast.DTypeRecover(); } - // TODO: resolveDescriptors > resolvePartialFields return yield* field.type(); } case "recover": From f779677bbe59673aea86a5d8b1c4699b67180d38 Mon Sep 17 00:00:00 2001 From: verytactical <186486509+verytactical@users.noreply.github.com> Date: Mon, 2 Jun 2025 05:17:32 +0400 Subject: [PATCH 33/38] rec defs --- src/next/ast/checked-expr.ts | 4 +- src/next/ast/checked.ts | 48 +++---- src/next/ast/generated/checked-expr.ts | 2 +- src/next/ast/generated/checked.ts | 49 +++---- src/next/ast/lazy.ts | 81 +++++++++--- src/next/test/_test.build.ts | 7 +- src/next/test/to-code.ts | 19 ++- src/next/types/alias.ts | 3 +- src/next/types/body.ts | 40 +++--- src/next/types/builtins.ts | 10 +- src/next/types/constant-def.ts | 45 +++++-- src/next/types/constants.ts | 19 ++- src/next/types/contract.ts | 170 ++++++++++++++++--------- src/next/types/expression.ts | 43 +++++-- src/next/types/extensions.ts | 101 +++++++++------ src/next/types/fields.ts | 39 +++--- src/next/types/functions.ts | 8 +- src/next/types/message.ts | 42 +++--- src/next/types/methods.ts | 30 +++-- src/next/types/override.ts | 4 +- src/next/types/receivers.ts | 34 +++-- src/next/types/statements.ts | 43 ++++--- src/next/types/struct-fields.ts | 51 ++++++-- src/next/types/struct.ts | 8 +- src/next/types/trait.ts | 96 +++++++++----- src/next/types/type-fn.ts | 5 +- src/next/types/type.ts | 94 +++++++++----- src/next/types/typecheck.ts | 9 +- src/next/types/typedecl.ts | 16 ++- src/next/types/union.ts | 40 +++--- 30 files changed, 754 insertions(+), 406 deletions(-) diff --git a/src/next/ast/checked-expr.ts b/src/next/ast/checked-expr.ts index d890f1f422..2a66d332ca 100644 --- a/src/next/ast/checked-expr.ts +++ b/src/next/ast/checked-expr.ts @@ -1,4 +1,4 @@ -import type { Ordered } from "@/next/ast/checked"; +import type { Ordered, Recover } from "@/next/ast/checked"; import type { Id, Loc, TypeId } from "@/next/ast/common"; import type * as D from "@/next/ast/dtype"; import type { BinaryOperation, NumberBase, UnaryOperation } from "@/next/ast/expression"; @@ -165,7 +165,7 @@ export type DStaticMethodCall = { export type DStructInstance = { readonly kind: "struct_instance"; - readonly fields: Ordered; + readonly fields: Ordered>; readonly computedType: D.DTypeRef | D.DTypeRecover; readonly loc: Loc; }; diff --git a/src/next/ast/checked.ts b/src/next/ast/checked.ts index 1bbfe6825d..6335c20e45 100644 --- a/src/next/ast/checked.ts +++ b/src/next/ast/checked.ts @@ -2,7 +2,7 @@ import type { DecodedStatement } from "@/next/ast/checked-stmt"; import type { FuncId, Loc, OptionalId, TypeId } from "@/next/ast/common"; import type { DecodedType, DTypeRef, DTypeBounced } from "@/next/ast/dtype"; import type { Effects } from "@/next/ast/effects"; -import type { Lazy } from "@/next/ast/lazy"; +import type { Thunk } from "@/next/ast/lazy"; import type { SelfType } from "@/next/ast/mtype"; import type { AsmInstruction, AsmShuffle, ContractAttribute } from "@/next/ast/root"; import type { Value } from "@/next/ast/value"; @@ -20,7 +20,7 @@ export type Scope = { readonly typeDecls: ReadonlyMap>; readonly functions: ReadonlyMap>; readonly constants: ReadonlyMap>; - readonly extensions: ReadonlyMap[]>>; + readonly extensions: ReadonlyMap[]>>; } export type Decl = { @@ -28,6 +28,8 @@ export type Decl = { readonly via: ViaUser; } +export type Recover = T | undefined + export type TypeDeclSig = | AliasSig | ContractSig @@ -44,8 +46,8 @@ export type TypeDeclRefable = | UnionSig export type ConstSig = { - readonly initializer: Lazy; - readonly type: Lazy; + readonly initializer: Thunk>; + readonly type: Thunk; } export type FnSig = { @@ -54,7 +56,7 @@ export type FnSig = { readonly body: Body; } -export type Statements = Lazy; +export type Statements = Thunk>; export type StatementsAux = { readonly body: readonly DecodedStatement[]; @@ -73,7 +75,7 @@ export type FuncBody = { }; export type FiftBody = { readonly kind: "fift"; - readonly shuffle: Lazy; + readonly shuffle: Thunk>; readonly instructions: readonly AsmInstruction[]; }; @@ -86,7 +88,7 @@ export type ExtSig = { export type AliasSig = { readonly kind: 'alias'; readonly typeParams: TypeParams; - readonly type: Lazy; + readonly type: Thunk; } export type InitSig = @@ -97,7 +99,7 @@ export type InitEmpty = { readonly kind: 'empty'; // initOf() would take 0 parameters // values to fill all the fields - readonly fill: Lazy>>; + readonly fill: Thunk>>>>; } export type InitSimple = { readonly kind: 'simple'; @@ -113,8 +115,8 @@ export type InitFn = { readonly statements: Statements; } export type InitParam = { - readonly type: Lazy; - readonly init: undefined | Lazy; + readonly type: Thunk; + readonly init: undefined | Thunk>; readonly loc: Loc; } @@ -122,18 +124,18 @@ export type ContractSig = { readonly kind: 'contract'; readonly attributes: readonly ContractAttribute[]; readonly init: InitSig; - readonly content: Lazy; + readonly content: Thunk; } export type ContractContent = CommonSig< - Lazy, + Thunk>, Body > export type TraitSig = { readonly kind: 'trait'; - readonly content: Lazy; + readonly content: Thunk; } export type TraitContent = CommonSig< - Lazy | undefined, + Thunk> | undefined, Body | undefined > export type CommonSig = { @@ -150,13 +152,13 @@ export type Receivers = { export type Fieldish = InhFieldSig | FieldConstSig; export type InhFieldSig = { readonly kind: 'field'; - readonly type: Lazy - readonly init: Lazy | undefined; + readonly type: Thunk + readonly init: Thunk> | undefined; } export type FieldConstSig = { readonly kind: 'constant'; readonly overridable: boolean; - readonly type: Lazy; + readonly type: Thunk; readonly init: Expr; } @@ -165,7 +167,7 @@ export type MethodSig = { readonly type: DecodedMethodType; readonly inline: boolean; readonly body: Body; - readonly getMethodId: Lazy | undefined; + readonly getMethodId: Thunk> | undefined; } export type BounceSig = { @@ -219,7 +221,7 @@ export type StructSig = { export type MessageSig = { readonly kind: "message"; - readonly opcode: Lazy; + readonly opcode: Thunk>; readonly fields: Ordered; } @@ -233,7 +235,7 @@ export type DecodedFnType = { readonly kind: "DecodedFnType"; readonly typeParams: TypeParams; readonly params: Parameters; - readonly returnType: Lazy, + readonly returnType: Thunk, } export type DecodedMethodType = { @@ -242,12 +244,12 @@ export type DecodedMethodType = { readonly typeParams: TypeParams; readonly self: SelfType; readonly params: Parameters; - readonly returnType: Lazy, + readonly returnType: Thunk, } export type DecodedParameter = { readonly name: OptionalId; - readonly type: Lazy; + readonly type: Thunk; readonly loc: Loc; }; @@ -263,7 +265,7 @@ export type Parameters = { export type Parameter = { readonly name: OptionalId; - readonly type: Lazy; + readonly type: Thunk; readonly loc: Loc; }; diff --git a/src/next/ast/generated/checked-expr.ts b/src/next/ast/generated/checked-expr.ts index cd8c71376c..a23609acbc 100644 --- a/src/next/ast/generated/checked-expr.ts +++ b/src/next/ast/generated/checked-expr.ts @@ -116,7 +116,7 @@ export const DInitOf = (contract: $c.TypeId, args: readonly $.DecodedExpression[ }); export const isDInitOf = ($value: DInitOf) => $value.kind === "init_of"; export type DStructInstance = $.DStructInstance; -export const DStructInstance = (fields: Ordered, computedType: $d.DTypeRef | $d.DTypeRecover, loc: $c.Loc): $.DStructInstance => Object.freeze({ +export const DStructInstance = (fields: Ordered, computedType: $d.DTypeRef | $d.DTypeRecover, loc: $c.Loc): $.DStructInstance => Object.freeze({ kind: "struct_instance", fields, computedType, diff --git a/src/next/ast/generated/checked.ts b/src/next/ast/generated/checked.ts index 0e15421d1c..5ebb9cca26 100644 --- a/src/next/ast/generated/checked.ts +++ b/src/next/ast/generated/checked.ts @@ -5,7 +5,7 @@ import type * as $m from "@/next/ast/mtype"; import type * as $v from "@/next/ast/via"; import type * as $ from "@/next/ast/checked"; import type { TactImport } from "@/next/imports/source"; -import type { Lazy } from "@/next/ast/lazy"; +import type { Thunk } from "@/next/ast/lazy"; import type { AsmInstruction, AsmShuffle, ContractAttribute } from "@/next/ast/root"; import type { DecodedStatement } from "@/next/ast/checked-stmt"; import type { Value } from "@/next/ast/value"; @@ -17,7 +17,7 @@ export const TypeParams = (order: readonly $c.TypeId[], set: ReadonlySet set, }); export type AliasSig = $.AliasSig; -export const AliasSig = (typeParams: $.TypeParams, type_: Lazy<$d.DecodedType>): $.AliasSig => Object.freeze({ +export const AliasSig = (typeParams: $.TypeParams, type_: Thunk<$d.DecodedType>): $.AliasSig => Object.freeze({ kind: 'alias', typeParams, type: type_, @@ -29,7 +29,7 @@ export const Ordered = (order: readonly string[], map: ReadonlyMap }); export type DecodedFnType = $.DecodedFnType; -export const DecodedFnType = (typeParams: $.TypeParams, params: $.Parameters, returnType: Lazy<$d.DecodedType>): $.DecodedFnType => Object.freeze({ +export const DecodedFnType = (typeParams: $.TypeParams, params: $.Parameters, returnType: Thunk<$d.DecodedType>): $.DecodedFnType => Object.freeze({ kind: "DecodedFnType", typeParams, params, @@ -57,7 +57,7 @@ export const UnionSig = (typeParams: $.TypeParams, cases: ReadonlyMap $value.kind === "union"; export type TypeDeclSig = $.TypeDeclSig; export type ConstSig = $.ConstSig; -export const ConstSig = (init: Lazy, type_: Lazy<$d.DecodedType>): $.ConstSig => Object.freeze({ +export const ConstSig = (init: Thunk, type_: Thunk<$d.DecodedType>): $.ConstSig => Object.freeze({ initializer: init, type: type_, }); @@ -72,14 +72,14 @@ export type Decl = $.Decl; export const Decl = (decl: T, via: $v.ViaUser): Decl => ({ decl, via }); -export const Scope = (typeDecls: ReadonlyMap>, fnSigs: ReadonlyMap>, constSigs: ReadonlyMap>, extSigs: ReadonlyMap[]>>): $.Scope => Object.freeze({ +export const Scope = (typeDecls: ReadonlyMap>, fnSigs: ReadonlyMap>, constSigs: ReadonlyMap>, extSigs: ReadonlyMap[]>>): $.Scope => Object.freeze({ typeDecls, functions: fnSigs, constants: constSigs, extensions: extSigs }); export type DecodedMethodType = $.DecodedMethodType; -export const DecodedMethodType = (mutates: boolean, typeParams: $.TypeParams, self: $m.SelfType, params: $.Parameters, returnType: Lazy<$d.DecodedType>): $.DecodedMethodType => Object.freeze({ +export const DecodedMethodType = (mutates: boolean, typeParams: $.TypeParams, self: $m.SelfType, params: $.Parameters, returnType: Thunk<$d.DecodedType>): $.DecodedMethodType => Object.freeze({ kind: "DecodedMethodType", mutates, typeParams, @@ -88,7 +88,7 @@ export const DecodedMethodType = (mutates: boolean, typeParams: $.TypeParams, se returnType }); export type DecodedParameter = $.DecodedParameter; -export const DecodedParameter = (name: $c.OptionalId, type_: Lazy<$d.DecodedType>, loc: $c.Loc): $.DecodedParameter => Object.freeze({ +export const DecodedParameter = (name: $c.OptionalId, type_: Thunk<$d.DecodedType>, loc: $c.Loc): $.DecodedParameter => Object.freeze({ name, type: type_, loc @@ -99,18 +99,19 @@ export const SourceCheckResult = (importedBy: TactImport, globals: $.Scope): $.S globals }); export type Parameter = $.Parameter; -export const Parameter = (name: $c.OptionalId, type_: Lazy<$d.DecodedType>, loc: $c.Loc): $.Parameter => Object.freeze({ +export const Parameter = (name: $c.OptionalId, type_: Thunk<$d.DecodedType>, loc: $c.Loc): $.Parameter => Object.freeze({ name, type: type_, loc }); +export type Recover = $.Recover; export type Parameters = $.Parameters; export const Parameters = (order: readonly $.Parameter[], set: ReadonlySet): $.Parameters => Object.freeze({ order, set }); export type TactBody = $.TactBody; -export const TactBody = (statements: Lazy): $.TactBody => Object.freeze({ +export const TactBody = (statements: Thunk): $.TactBody => Object.freeze({ kind: "tact", statements }); @@ -122,7 +123,7 @@ export const FuncBody = (nativeName: $c.FuncId): $.FuncBody => Object.freeze({ }); export const isFuncBody = ($value: FuncBody) => $value.kind === "func"; export type FiftBody = $.FiftBody; -export const FiftBody = (shuffle: Lazy, instructions: readonly AsmInstruction[]): $.FiftBody => Object.freeze({ +export const FiftBody = (shuffle: Thunk, instructions: readonly AsmInstruction[]): $.FiftBody => Object.freeze({ kind: "fift", shuffle, instructions @@ -140,14 +141,14 @@ export const DeclMem = (decl: T, via: $v.ViaMember): DeclMem => ({ decl, via }); export type InhFieldSig = $.InhFieldSig; -export const InhFieldSig = (type_: Lazy<$d.DecodedType>, init: Lazy | undefined): $.InhFieldSig => Object.freeze({ +export const InhFieldSig = (type_: Thunk<$d.DecodedType>, init: Thunk | undefined): $.InhFieldSig => Object.freeze({ kind: "field", type: type_, init }); export const isInhFieldSig = ($value: InhFieldSig) => $value.kind === "field"; export type FieldConstSig = $.FieldConstSig; -export const FieldConstSig = (overridable: boolean, type_: Lazy<$d.DecodedType>, init: Expr): $.FieldConstSig => Object.freeze({ +export const FieldConstSig = (overridable: boolean, type_: Thunk<$d.DecodedType>, init: Expr): $.FieldConstSig => Object.freeze({ kind: "constant", overridable, type: type_, @@ -156,7 +157,7 @@ export const FieldConstSig = (overridable: boolean, type_: Lazy<$d.Decode export const isFieldConstSig = ($value: FieldConstSig) => $value.kind === "constant"; export type Fieldish = $.Fieldish; export type MethodSig = $.MethodSig; -export const MethodSig = (overridable: boolean, type_: $.DecodedMethodType, inline: boolean, body: Body, getMethodId: Lazy | undefined): $.MethodSig => Object.freeze({ +export const MethodSig = (overridable: boolean, type_: $.DecodedMethodType, inline: boolean, body: Body, getMethodId: Thunk | undefined): $.MethodSig => Object.freeze({ overridable, type: type_, inline, @@ -173,36 +174,36 @@ export const CommonSig = (fieldish: $.Ordered<$.DeclMem<$.Fieldish | undefined, $.Body | undefined>>): $.TraitSig => Object.freeze({ +export const TraitSig = (content: Thunk<$.CommonSig | undefined, $.Body | undefined>>): $.TraitSig => Object.freeze({ kind: "trait", content }); export const isTraitSig = ($value: TraitSig) => $value.kind === "trait"; export type MessageRecv = $.MessageRecv; -export const MessageRecv = (name: $c.OptionalId, type_: $d.DTypeRef | $d.DTypeBounced, statements: Lazy): $.MessageRecv => Object.freeze({ +export const MessageRecv = (name: $c.OptionalId, type_: $d.DTypeRef | $d.DTypeBounced, statements: Thunk): $.MessageRecv => Object.freeze({ kind: "binary", name, type: type_, statements }); export type MessageAnyRecv = $.MessageAnyRecv; -export const MessageAnyRecv = (name: $c.OptionalId, statements: Lazy): $.MessageAnyRecv => Object.freeze({ +export const MessageAnyRecv = (name: $c.OptionalId, statements: Thunk): $.MessageAnyRecv => Object.freeze({ name, statements }); export type StringRecv = $.StringRecv; -export const StringRecv = (comment: string, statements: Lazy): $.StringRecv => Object.freeze({ +export const StringRecv = (comment: string, statements: Thunk): $.StringRecv => Object.freeze({ kind: "string", comment, statements }); export type StringAnyRecv = $.StringAnyRecv; -export const StringAnyRecv = (name: $c.OptionalId, statements: Lazy): $.StringAnyRecv => Object.freeze({ +export const StringAnyRecv = (name: $c.OptionalId, statements: Thunk): $.StringAnyRecv => Object.freeze({ name, statements }); export type EmptyRecv = $.EmptyRecv; -export const EmptyRecv = (statements: Lazy): $.EmptyRecv => Object.freeze({ +export const EmptyRecv = (statements: Thunk): $.EmptyRecv => Object.freeze({ statements }); export type OpcodeRecv = $.OpcodeRecv; @@ -214,20 +215,20 @@ export const RecvSig = (message: readonly DeclMem[], messageAny: $.D empty }); export type MessageSig = $.MessageSig; -export const MessageSig = (opcode: Lazy, fields: $.Ordered<$.InhFieldSig>): $.MessageSig => Object.freeze({ +export const MessageSig = (opcode: Thunk, fields: $.Ordered<$.InhFieldSig>): $.MessageSig => Object.freeze({ kind: "message", opcode, fields }); export const isMessageSig = ($value: MessageSig) => $value.kind === "message"; export type InitEmpty = $.InitEmpty; -export const InitEmpty = (fill: Lazy<$.Ordered>>): $.InitEmpty => Object.freeze({ +export const InitEmpty = (fill: Thunk>>): $.InitEmpty => Object.freeze({ kind: "empty", fill }); export const isInitEmpty = ($value: InitEmpty) => $value.kind === "empty"; export type InitParam = $.InitParam; -export const InitParam = (type_: Lazy<$d.DecodedType>, init: Lazy | undefined, loc: $c.Loc): $.InitParam => Object.freeze({ +export const InitParam = (type_: Thunk<$d.DecodedType>, init: Thunk | undefined, loc: $c.Loc): $.InitParam => Object.freeze({ type: type_, init, loc @@ -244,7 +245,7 @@ export const StatementsAux = (body: readonly DecodedStatement[], effects: Effect body, effects, }); export type InitFn = $.InitFn; -export const InitFn = (params: $.Parameters, statements: Lazy): $.InitFn => Object.freeze({ +export const InitFn = (params: $.Parameters, statements: Thunk): $.InitFn => Object.freeze({ kind: "function", params, statements @@ -254,7 +255,7 @@ export type Statements = $.Statements; export type InitSig = $.InitSig; export type ContractSig = $.ContractSig; export type TypeDeclRefable = $.TypeDeclRefable; -export const ContractSig = (attributes: readonly ContractAttribute[], init: $.InitSig, content: Lazy<$.ContractContent>): $.ContractSig => Object.freeze({ +export const ContractSig = (attributes: readonly ContractAttribute[], init: $.InitSig, content: Thunk<$.ContractContent>): $.ContractSig => Object.freeze({ kind: "contract", attributes, init, diff --git a/src/next/ast/lazy.ts b/src/next/ast/lazy.ts index ce3ec7d7c0..17fe2d583a 100644 --- a/src/next/ast/lazy.ts +++ b/src/next/ast/lazy.ts @@ -1,14 +1,20 @@ /* eslint-disable require-yield */ -import { throwInternal } from "@/error/errors"; -import type { WithLog } from "@/next/types/errors"; +import type { Loc } from "@/next/ast/common"; +import * as E from "@/next/types/errors"; -export type Lazy = () => WithLog +type Result = 'waiting' | 'running' | readonly [T]; -export const Lazy = ( - callback: () => WithLog, - onOccurs: () => WithLog = impossible, -): Lazy => { - let result: 'waiting' | 'running' | [T] = 'waiting'; +export const printSym = Symbol("print"); + +export type Thunk = { + [printSym]: () => Result +} & (() => E.WithLog) + +function Thunk( + force: () => E.WithLog, + onOccurs: () => E.WithLog, +): Thunk { + let result: Result = 'waiting'; function* delayed() { if (typeof result !== 'string') { return result[0]; @@ -17,23 +23,62 @@ export const Lazy = ( return yield* onOccurs(); } result = 'running'; - const output = yield* callback(); + const output = yield* force(); result = [output]; return output; } - delayed.toJSON = () => { - return result; - }; + // @ts-expect-error TS bug. with text field name it works + delayed[printSym] = () => result; return delayed; +} + +export const isThunk = (arg: object): arg is Thunk => printSym in arg; + +export const FakeThunk = (t: T): Thunk => { + function* thunk() { + return t; + } + // @ts-expect-error TS bug. with text field name it works + thunk[printSym] = () => [t] as const; + return thunk; }; -export const mapLazy = (f: Lazy, g: (t: T) => U): Lazy => { - return function* () { - return g(yield* f()); +type Options = { + readonly loc: Loc, + readonly context: readonly E.TELine[], + readonly recover: T, + readonly callback: ( + builder: ThunkBuilder + ) => E.WithLog +} + +export type ThunkBuilder = ( + options: Options +) => Thunk; + +const makeBuilder = (allContext: readonly E.TELine[]): ThunkBuilder => { + return function addThunk(options: Options): Thunk { + return Thunk( + function force() { + const nextBuilder = makeBuilder( + [...options.context, ...allContext] + ); + return options.callback(nextBuilder); + }, + function* onOccurs() { + yield EOccurs(options.loc, allContext); + return options.recover; + }, + ); }; }; -function* impossible(): WithLog { - return throwInternal("Infinite loop in typechecker"); -} +const EOccurs = (loc: Loc, context: readonly E.TELine[]): E.TcError => ({ + loc, + descr: [ + E.TEText(`Recursive definition`), + ...context, + ], +}); +export const thunkBuilder = makeBuilder([]); diff --git a/src/next/test/_test.build.ts b/src/next/test/_test.build.ts index 2f7f16c140..56b406d164 100644 --- a/src/next/test/_test.build.ts +++ b/src/next/test/_test.build.ts @@ -9,7 +9,7 @@ import type { ResolvedImport } from "@/next/imports/source"; export const runTest = async (path: string): Promise => { let types: unknown; - const result = await runServer(async (log) => { + await runServer(async (log) => { await log.recover(async (log) => { // const result = await buildNoStdlib(log, path); const result = await buildE2E(log, path); @@ -18,11 +18,10 @@ export const runTest = async (path: string): Promise => { return; } - const tcResult = typecheck(result); - types = tcResult; + types = typecheck(result); }); }); - return toJs({ types, result }); + return toJs(types); }; export const buildE2E = async ( diff --git a/src/next/test/to-code.ts b/src/next/test/to-code.ts index 1e8f16efe4..f509aa2d6b 100644 --- a/src/next/test/to-code.ts +++ b/src/next/test/to-code.ts @@ -1,3 +1,5 @@ +import { isThunk, printSym } from "@/next/ast"; + function isValidId(key: string) { return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(key); } @@ -74,10 +76,25 @@ export function toJs(value: unknown): string { case "symbol": return [val.description ? `Symbol(${JSON.stringify(val.description)})` : 'Symbol()']; case "undefined": return ['undefined']; case "object": return val === null ? ["null"] : showObject(val); - case "function": return [`new Function(${val.toString()})`]; + case "function": return showFunction(val); } } + // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type + const showFunction = (val: Function): readonly string[] => { + if (!isThunk(val)) { + return [`new Function(${val.toString()})`]; + } + const result = val[printSym](); + if (result === 'waiting') { + return [`Waiting()`]; + } else if (result === 'running') { + return [`Running()`]; + } else { + return show(result); + } + }; + const showObject = (val: object): readonly string[] => { if (val instanceof Date) { return [`new Date(${val.getTime()})`]; diff --git a/src/next/types/alias.ts b/src/next/types/alias.ts index 04f0133704..5a14c612f1 100644 --- a/src/next/types/alias.ts +++ b/src/next/types/alias.ts @@ -6,12 +6,13 @@ import { decodeTypeParams } from "@/next/types/type-params"; import { decodeTypeLazy } from "@/next/types/type"; export function* decodeAlias( + Lazy: Ast.ThunkBuilder, { typeParams, type }: Ast.AliasDecl, scopeRef: () => Ast.Scope, ): E.WithLog { const decodedParams = yield* decodeTypeParams(typeParams); return Ast.AliasSig( decodedParams, - decodeTypeLazy(decodedParams, type, scopeRef), + decodeTypeLazy(Lazy, decodedParams, type, scopeRef), ); } diff --git a/src/next/types/body.ts b/src/next/types/body.ts index 4b19e83d8c..fc4430c23f 100644 --- a/src/next/types/body.ts +++ b/src/next/types/body.ts @@ -4,9 +4,9 @@ import * as Ast from "@/next/ast"; import * as E from "@/next/types/errors"; import { isSubsetOf } from "@/utils/isSubsetOf"; import { decodeStatementsLazy } from "@/next/types/statements"; -import { emptyEff } from "@/next/types/effects"; export function* decodeBody( + Lazy: Ast.ThunkBuilder, node: Ast.FunctionalBody, fnType: Ast.DecodedFnType | Ast.DecodedMethodType, loc: Ast.Loc, @@ -15,9 +15,12 @@ export function* decodeBody( switch (node.kind) { case "abstract_body": { yield ENoBody(loc) - return Ast.TactBody(function* () { - return Ast.StatementsAux([], emptyEff); - }); + return Ast.TactBody(Lazy({ + callback: function* () { return undefined; }, + context: [E.TEText("checking body of function")], + loc, + recover: undefined, + })); } case "regular_body": { const selfTypeRef = () => { @@ -26,6 +29,8 @@ export function* decodeBody( : undefined; }; return Ast.TactBody(decodeStatementsLazy( + Lazy, + loc, node.statements, fnType.typeParams, selfTypeRef, @@ -36,12 +41,17 @@ export function* decodeBody( } case "asm_body": { return Ast.FiftBody( - checkShuffleLazy( - node.shuffle, - fnType, + Lazy({ + callback: () => checkShuffle( + node.shuffle, + fnType, + loc, + scopeRef, + ), + context: [E.TEText("checking shuffle")], loc, - scopeRef, - ), + recover: undefined, + }), node.instructions, ); } @@ -60,18 +70,6 @@ const ENoBody = ( ], }); -const checkShuffleLazy = ( - shuffle: Ast.AsmShuffle, - fnType: Ast.DecodedFnType | Ast.DecodedMethodType, - loc: Ast.Loc, - scopeRef: () => Ast.Scope, -) => Ast.Lazy(() => checkShuffle( - shuffle, - fnType, - loc, - scopeRef, -)); - function* checkShuffle( shuffle: Ast.AsmShuffle, fnType: Ast.DecodedFnType | Ast.DecodedMethodType, diff --git a/src/next/types/builtins.ts b/src/next/types/builtins.ts index 20f30e5706..152c684852 100644 --- a/src/next/types/builtins.ts +++ b/src/next/types/builtins.ts @@ -8,10 +8,6 @@ export const tactMethodIds = [113617n, 115390n, 121275n]; const r = Ast.Builtin(); -const FakeLazy = (t: T): Ast.Lazy => function* () { - return t; -}; - const TypeParams = (typeParams: readonly string[]): Ast.TypeParams => { const arr = typeParams.map(name => Ast.TypeId(name, r)); return Ast.TypeParams(arr, new Set(typeParams)); @@ -21,7 +17,7 @@ const Params = (params: Record): Ast.Parameters => { const order: Ast.Parameter[] = []; const set: Set = new Set(); for (const [name, type] of Object.entries(params)) { - order.push(Ast.Parameter(Ast.Id(name, r), FakeLazy(type), r)); + order.push(Ast.Parameter(Ast.Id(name, r), Ast.FakeThunk(type), r)); set.add(name); } return Ast.Parameters(order, set); @@ -37,7 +33,7 @@ const GenericFn = (name: string, typeParams: readonly string[], params: Record, returnType: Ast.DecodedType): [string, Ast.DecodedFnType] => { @@ -49,7 +45,7 @@ const MapMethod = (name: string, mutates: boolean, params: Record Ast.Scope, selfType: undefined | Ast.SelfType, -): [Ast.Lazy, Ast.Lazy] { +): [Ast.Thunk, Ast.Thunk] { if (type) { // if there is an ascribed type, that's the one we return - const ascribedType = decodeTypeLazy(typeParams, type, scopeRef); + const ascribedType = decodeTypeLazy(Lazy, typeParams, type, scopeRef); // also we have to check that it's the expected type prior to // evaluating the expression - const lazyExpr = Ast.Lazy(function* () { + function* evaluate(Lazy: Ast.ThunkBuilder) { const expr = yield* decodeExpr( + Lazy, typeParams, initializer, scopeRef, @@ -28,26 +32,47 @@ export function decodeConstantDef( const ascribed = yield* ascribedType(); yield* assignType(defLoc, emptyTypeParams, ascribed, computed, false); return yield* evalExpr(expr, scopeRef); + } + const lazyExpr = Lazy({ + loc: defLoc, + context: [E.TEText("evaluating expression")], + recover: undefined, + callback: evaluate, }); return [ascribedType, lazyExpr]; } else { // first we decode expression - const expr = Ast.Lazy(function* () { - return yield* decodeExpr( + const expr = Lazy({ + callback: (Lazy) => decodeExpr( + Lazy, typeParams, initializer, scopeRef, selfType, new Map(), - ); + ), + context: [E.TEText("parsing expression")], + loc: defLoc, + recover: undefined, }); // then we evaluate it without any other checks - const lazyExpr = Ast.Lazy(function* () { - return yield* evalExpr(yield* expr(), scopeRef); + const lazyExpr = Lazy({ + callback: function* () { + const ast = yield* expr(); + return ast && (yield* evalExpr(ast, scopeRef)); + }, + context: [E.TEText("evaluating expression")], + loc: defLoc, + recover: undefined, }); // resulting type is whatever the type expression has - const computedType = Ast.Lazy(function* () { - return (yield* expr()).computedType; + const computedType = Lazy({ + callback: function* () { + return (yield* expr())?.computedType ?? Ast.DTypeRecover(); + }, + context: [], + loc: defLoc, + recover: Ast.DTypeRecover(), }); return [computedType, lazyExpr]; } diff --git a/src/next/types/constants.ts b/src/next/types/constants.ts index 61f0f7826a..752aebdac5 100644 --- a/src/next/types/constants.ts +++ b/src/next/types/constants.ts @@ -9,6 +9,7 @@ import { emptyTypeParams } from "@/next/types/type-params"; const errorKind = "function"; export function* decodeConstants( + Lazy: Ast.ThunkBuilder, imported: readonly Ast.SourceCheckResult[], source: TactSource, scopeRef: () => Ast.Scope, @@ -24,7 +25,7 @@ export function* decodeConstants( return [ c.name.text, Ast.Decl( - yield* decodeConstant(c, scopeRef), + yield* decodeConstant(Lazy, c, scopeRef), Ast.ViaOrigin(c.loc, source) ), ] as const; @@ -42,17 +43,29 @@ export function* decodeConstants( } function* decodeConstant( + Lazy: Ast.ThunkBuilder, constant: Ast.Constant, scopeRef: () => Ast.Scope, ) { const { init, loc } = constant; if (init.kind === "constant_decl") { yield ETopLevelDecl(loc); - const type = function*() { return Ast.DTypeRecover(); }; - const expr = function*() { return Ast.VNumber(0n, constant.loc); }; + const type = Lazy({ + loc: constant.loc, + context: [E.TEText("defining constant"), E.TECode(constant.loc)], + recover: Ast.DTypeRecover(), + callback: function*() { return Ast.DTypeRecover(); }, + }); + const expr = Lazy({ + loc: constant.loc, + context: [E.TEText("defining constant"), E.TECode(constant.loc)], + recover: Ast.VNumber(0n, constant.loc), + callback: function*() { return Ast.VNumber(0n, constant.loc); }, + }); return Ast.ConstSig(expr, type); } else { const [type, expr] = decodeConstantDef( + Lazy, loc, emptyTypeParams, init, diff --git a/src/next/types/contract.ts b/src/next/types/contract.ts index 437e62988d..445efeda30 100644 --- a/src/next/types/contract.ts +++ b/src/next/types/contract.ts @@ -14,6 +14,7 @@ import { Void } from "@/next/types/builtins"; import { emptyTypeParams } from "@/next/types/type-params"; export function* decodeContract( + Lazy: Ast.ThunkBuilder, contract: Ast.Contract, scopeRef: () => Ast.Scope, ) { @@ -26,47 +27,57 @@ export function* decodeContract( // to check init body in initLazy we have to know `self` from contentLazy const decodedInit = yield* decodeInit( + Lazy, + contract.loc, () => selfType, init, - () => contentLazy(), + () => contentLazy, scopeRef, ); // delayed until we get all traits and init - const contentLazy: Ast.Lazy = Ast.Lazy(function* () { - const traits = yield* getInheritedTraits( - contract.traits, - scopeRef, - ); - - // const contentRef = () => content; - const content: Ast.ContractContent = { - fieldish: yield* getFieldishFromContract( - contractSig, - name, - traits, - decodedInit, - constants, - fields, + const contentLazy: Ast.Thunk = Lazy({ + callback: function* (Lazy) { + const traits = yield* getInheritedTraits( + contract.traits, scopeRef, - ), - methods: yield* getMethodsFromContract( - contractSig, - name, - traits, - methods, - scopeRef, - ), - receivers: yield* getReceivers( - () => selfType, - name, - traits, - receivers, - scopeRef, - ), - }; - - return content; + ); + + // const contentRef = () => content; + const content: Ast.ContractContent = { + fieldish: yield* getFieldishFromContract( + Lazy, + contractSig, + name, + traits, + decodedInit, + constants, + fields, + scopeRef, + ), + methods: yield* getMethodsFromContract( + Lazy, + contractSig, + name, + traits, + methods, + scopeRef, + ), + receivers: yield* getReceivers( + Lazy, + () => selfType, + name, + traits, + receivers, + scopeRef, + ), + }; + + return content; + }, + context: [E.TEText("checking scope of contract")], + loc: contract.loc, + recover, }); const contractSig = Ast.ContractSig(attributes, decodedInit, contentLazy); @@ -82,33 +93,40 @@ export function* decodeContract( } function* decodeInit( + Lazy: Ast.ThunkBuilder, + contractLoc: Ast.Loc, selfTypeRef: () => Ast.SelfType, init: Ast.Init | undefined, - contentLazy: Ast.Lazy, + contentLazy: () => Ast.Thunk, scopeRef: () => Ast.Scope, ): E.WithLog { if (!init) { // no init - const lazyInit = Ast.Lazy(function* () { - const order: string[] = []; - const map: Map> = new Map(); - const { fieldish } = (yield* contentLazy()); - for (const name of fieldish.order) { - const f = fieldish.map.get(name); - if (!f) { - return throwInternal("Missing field"); - } - if (f.decl.kind === 'field') { - const init = f.decl.init; - if (init) { - order.push(name); - map.set(name, init); - } else { - yield ENoInitializerEmpty(f.via.defLoc); + const lazyInit = Lazy({ + callback: function* () { + const order: string[] = []; + const map: Map>> = new Map(); + const { fieldish } = yield* contentLazy()(); + for (const name of fieldish.order) { + const f = fieldish.map.get(name); + if (!f) { + return throwInternal("Missing field"); + } + if (f.decl.kind === 'field') { + const init = f.decl.init; + if (init) { + order.push(name); + map.set(name, init); + } else { + yield ENoInitializerEmpty(f.via.defLoc); + } } } - } - return Ast.Ordered(order, map); + return Ast.Ordered(order, map); + }, + context: [E.TEText("computing parameters of empty init")], + loc: contractLoc, + recover: undefined, }); return Ast.InitEmpty(lazyInit); } else if (init.kind === 'init_params') { @@ -127,7 +145,7 @@ function* decodeInit( const map: Map = new Map(); for (const [name, param] of paramMap) { - const decoded = decodeTypeLazy(emptyTypeParams, param.type, scopeRef) + const decoded = decodeTypeLazy(Lazy, emptyTypeParams, param.type, scopeRef) if (!param.initializer) { yield ENoInitializerParams(param.loc); } @@ -138,14 +156,21 @@ function* decodeInit( const { params, statements } = init; const decodedParams = yield* decodeParams((type) => { - return decodeDealiasTypeLazy(emptyTypeParams, type, scopeRef); + return decodeDealiasTypeLazy(Lazy, emptyTypeParams, type, scopeRef); }, params); const body = decodeStatementsLazy( + Lazy, + init.loc, statements, emptyTypeParams, selfTypeRef, - function* () { return Void }, + Lazy({ + callback: function* () { return Void; }, + context: [], + loc: init.loc, + recover: Void, + }), true, scopeRef, ); @@ -185,6 +210,7 @@ const ENoInitializerEmpty = ( }); function* getMethodsFromContract( + Lazy: Ast.ThunkBuilder, contractSig: Ast.ContractSig, typeName: Ast.TypeId, traits: readonly Ast.Decl[], @@ -192,6 +218,7 @@ function* getMethodsFromContract( scopeRef: () => Ast.Scope ): E.WithLog>>> { const res = yield* getMethodsGeneral( + Lazy, contractSig, typeName, traits, @@ -218,6 +245,7 @@ function* getMethodsFromContract( } function* getFieldishFromContract( + Lazy: Ast.ThunkBuilder, contractSig: Ast.ContractSig, typeName: Ast.TypeId, traits: readonly Ast.Decl[], @@ -225,8 +253,9 @@ function* getFieldishFromContract( constants: readonly Ast.FieldConstant[], fields: readonly Ast.FieldDecl[], scopeRef: () => Ast.Scope, -): E.WithLog>>>> { +): E.WithLog>>>>> { const res = yield* getFieldishGeneral( + Lazy, contractSig, typeName, traits, @@ -236,7 +265,7 @@ function* getFieldishFromContract( ); const order: string[] = []; - const map: Map>>> = new Map(); + const map: Map>>>> = new Map(); for (const name of res.order) { const field = res.map.get(name); if (!field) { @@ -256,7 +285,7 @@ function* getFieldishFromContract( } if (init.kind === 'simple') { - const map: Map>>> = new Map(); + const map: Map>>>> = new Map(); if (order.length !== 0) { yield EFieldsTwice(init.loc); } @@ -291,3 +320,26 @@ const EAbstract = ( E.TEViaMember(next), ], }); + +const recover: Ast.ContractContent = { + fieldish: Ast.Ordered([], new Map()), + methods: new Map(), + receivers: { + bounce: { + message: [], + messageAny: undefined, + }, + external: { + empty: undefined, + message: [], + messageAny: undefined, + stringAny: undefined, + }, + internal: { + empty: undefined, + message: [], + messageAny: undefined, + stringAny: undefined, + }, + }, +}; \ No newline at end of file diff --git a/src/next/types/expression.ts b/src/next/types/expression.ts index dac343e390..1b3a3c581e 100644 --- a/src/next/types/expression.ts +++ b/src/next/types/expression.ts @@ -9,6 +9,7 @@ import { emptyTypeParams } from "@/next/types/type-params"; type Decode = (node: T, ctx: Context) => E.WithLog type Context = { + readonly Lazy: Ast.ThunkBuilder, readonly scopeRef: () => Ast.Scope; readonly selfType: Ast.SelfType | undefined; readonly typeParams: Ast.TypeParams; @@ -16,6 +17,7 @@ type Context = { } export function decodeExpr( + Lazy: Ast.ThunkBuilder, typeParams: Ast.TypeParams, node: Ast.Expression, scopeRef: () => Ast.Scope, @@ -23,6 +25,7 @@ export function decodeExpr( localScopeRef: ReadonlyMap, ): E.WithLog { return decodeExprCtx(node, { + Lazy, typeParams, scopeRef, selfType, @@ -106,7 +109,7 @@ const decodeSetCons: Decode = function* () { const decodeStructCons: Decode = function* (node, ctx) { const typeArgs = yield* E.mapLog(node.typeArgs, function* (arg) { - return yield* decodeTypeLazy(ctx.typeParams, arg, ctx.scopeRef)(); + return yield* decodeTypeLazy(ctx.Lazy, ctx.typeParams, arg, ctx.scopeRef)(); }); const instance = yield* instantiateStruct( node.type, @@ -163,7 +166,7 @@ function* checkFields( } if (typeFields) { - const result: Map = new Map(); + const result: Map> = new Map(); for (const fieldName of typeFields.order) { const field = typeFields.map.get(fieldName); if (!field) { @@ -173,14 +176,16 @@ function* checkFields( if (fieldInst) { result.set(fieldName, fieldInst); } else if (field.init) { - const inst = convertValueToExpr(yield* field.init()); - result.set(fieldName, inst); + const value = yield* field.init(); + if (value) { + const inst = convertValueToExpr(value); + result.set(fieldName, inst); + } else { + result.set(fieldName, undefined); + } } else { yield EMissingField(fieldName, loc); - result.set(fieldName, Ast.DNull( - Ast.TypeNull(loc), - loc, - )); + result.set(fieldName, undefined); } } return Ast.Ordered(typeFields.order, result) @@ -348,6 +353,7 @@ const decodeMethodCall: Decode = function* (nod const { typeDecls, extensions } = ctx.scopeRef(); const { returnType, typeArgMap } = yield* lookupMethod( + ctx.Lazy, self.computedType, node.method, args.map(child => [child.loc, child.computedType]), @@ -379,10 +385,16 @@ const decodeFunctionCall: Decode [child.loc, child.computedType]), ); @@ -414,6 +426,7 @@ const decodeStaticMethodCall: Decode = function* (node, ctx) { } const params = yield* initParams(contract.decl.init); yield* checkFnCallWithArgs( + ctx.Lazy, node.loc, - Ast.DecodedFnType(emptyTypeParams, params, function*() { return StateInit; }), + Ast.DecodedFnType( + emptyTypeParams, + params, + ctx.Lazy({ + callback: function*() { return StateInit; }, + context: [E.TEText("checking initOf expression")], + loc: node.loc, + recover: StateInit, + }) + ), [], args.map(child => [child.loc, child.computedType]), ); diff --git a/src/next/types/extensions.ts b/src/next/types/extensions.ts index cace049c89..c60f12ae6c 100644 --- a/src/next/types/extensions.ts +++ b/src/next/types/extensions.ts @@ -9,24 +9,30 @@ import { builtinMethods } from "@/next/types/builtins"; import type { TactSource } from "@/next/imports/source"; export function decodeExtensions( + Lazy: Ast.ThunkBuilder, imported: readonly Ast.SourceCheckResult[], source: TactSource, scopeRef: () => Ast.Scope, -): ReadonlyMap[]>> { - const allExts: Map[]>[]> = new Map(); +): ReadonlyMap[]>> { + const allExts: Map[]>[]> = new Map(); // imported for (const { globals, importedBy } of imported) { for (const [name, lazyExts] of globals.extensions) { const map = allExts.get(name) ?? []; allExts.set(name, map); - map.push(function* () { - const exts = yield* lazyExts(); - return exts.map(ext => Ast.Decl( - ext.decl, - Ast.ViaImport(importedBy, ext.via), - )); - }); + map.push(Lazy({ + callback: function* () { + const exts = yield* lazyExts(); + return exts.map(ext => Ast.Decl( + ext.decl, + Ast.ViaImport(importedBy, ext.via), + )); + }, + context: [E.TEText(`importing extension method ${name}`)], + loc: Ast.Builtin(), + recover: [], + })); } } @@ -35,43 +41,55 @@ export function decodeExtensions( const name = ext.fun.name.text; const map = allExts.get(name) ?? []; allExts.set(name, map); - map.push(function* () { - const decoded = yield* decodeExt(ext, scopeRef); - if (!decoded) { - return []; - } - return [Ast.Decl( - decoded, - Ast.ViaOrigin(ext.fun.loc, source), - )]; - }); + map.push(Lazy({ + callback: function* (Lazy) { + const decoded = yield* decodeExt(Lazy, ext, scopeRef); + if (!decoded) { + return []; + } + return [Ast.Decl( + decoded, + Ast.ViaOrigin(ext.fun.loc, source), + )]; + }, + context: [ + E.TEText(`defining extension method ${ext.fun.name.text}`) + ], + loc: ext.fun.loc, + recover: [], + })); } - const result: Map[]>> = new Map(); + const result: Map[]>> = new Map(); for (const [name, exts] of allExts) { // checking method overlap is only possible when all the types // can be resolved - result.set(name, Ast.Lazy(function* () { - // force all thunks - const all: Ast.Decl[] = []; - for (const lazyExt of exts) { - const exts = yield* lazyExt(); - all.push(...exts); - } - - // check overlap and deduplicate - const prevs: Ast.Decl[] = []; - for (const ext of all) { - const builtin = builtinMethods.get(name); - if (builtin && !isCompatible(builtin, ext.decl.type)) { - yield EMethodOverlap(name, Ast.ViaBuiltin(), ext.via); - continue; + result.set(name, Lazy({ + callback: function* () { + // force all thunks + const all: Ast.Decl[] = []; + for (const lazyExt of exts) { + const exts = yield* lazyExt(); + all.push(...exts); } - if (yield* areCompatible(name, prevs, ext)) { - prevs.push(ext); + + // check overlap and deduplicate + const prevs: Ast.Decl[] = []; + for (const ext of all) { + const builtin = builtinMethods.get(name); + if (builtin && !isCompatible(builtin, ext.decl.type)) { + yield EMethodOverlap(name, Ast.ViaBuiltin(), ext.via); + continue; + } + if (yield* areCompatible(name, prevs, ext)) { + prevs.push(ext); + } } - } - return prevs; + return prevs; + }, + context: [E.TEText(`merging extensions methods with name ${name}`)], + loc: Ast.Builtin(), + recover: [], })); } @@ -79,15 +97,17 @@ export function decodeExtensions( } function* decodeExt( + Lazy: Ast.ThunkBuilder, node: Ast.Extension, scopeRef: () => Ast.Scope, ) { const { selfType, mutates, fun } = node; const { type, body, inline, loc } = fun; - const decodedFn = yield* decodeFnType(type, scopeRef); + const decodedFn = yield* decodeFnType(Lazy, type, scopeRef); const lazySelf = decodeDealiasTypeLazy( + Lazy, decodedFn.typeParams, selfType, scopeRef, @@ -107,6 +127,7 @@ function* decodeExt( ); const decodedBody = yield* decodeBody( + Lazy, body, methodType, loc, diff --git a/src/next/types/fields.ts b/src/next/types/fields.ts index 5688c4abce..c847460c8c 100644 --- a/src/next/types/fields.ts +++ b/src/next/types/fields.ts @@ -3,16 +3,16 @@ import * as Ast from "@/next/ast"; import * as E from "@/next/types/errors"; import { throwInternal } from "@/error/errors"; -import { assignType, decodeTypeLazy } from "@/next/types/type"; -import { decodeExpr } from "@/next/types/expression"; +import { decodeTypeLazy } from "@/next/types/type"; import { checkFieldOverride } from "@/next/types/override"; import { decodeConstantDef } from "@/next/types/constant-def"; -import { evalExpr } from "@/next/types/expr-eval"; import { emptyTypeParams } from "@/next/types/type-params"; +import { decodeInitializerLazy } from "@/next/types/struct-fields"; -type MaybeExpr = Ast.Lazy | undefined +type MaybeExpr = Ast.Thunk | undefined export function* getFieldishGeneral( + Lazy: Ast.ThunkBuilder, traitSigRef: Ast.TraitSig | Ast.ContractSig, typeName: Ast.TypeId, traits: readonly Ast.Decl[], @@ -73,6 +73,7 @@ export function* getFieldishGeneral( // decode field all.set(name.text, decodeField( + Lazy, typeName.text, field, scopeRef, @@ -117,6 +118,7 @@ export function* getFieldishGeneral( // get the definition const next = yield* decodeConstant( + Lazy, init, overridable, nextVia, @@ -158,6 +160,7 @@ export function* getFieldishGeneral( } function decodeField( + Lazy: Ast.ThunkBuilder, typeName: string, field: Ast.FieldDecl, scopeRef: () => Ast.Scope, @@ -166,21 +169,17 @@ function decodeField( const { initializer, type, loc } = field; const nextVia = Ast.ViaMemberOrigin(typeName, loc); - const decoded = decodeTypeLazy(emptyTypeParams, type, scopeRef); + const decoded = decodeTypeLazy(Lazy, emptyTypeParams, type, scopeRef); - const init = initializer && Ast.Lazy(function* () { - const ascribed = yield* decoded(); - const expr = yield* decodeExpr( - emptyTypeParams, - initializer, - scopeRef, - selfType, - new Map(), - ); - const computed = expr.computedType; - yield* assignType(loc, emptyTypeParams, ascribed, computed, false); - return yield* evalExpr(expr, scopeRef); - }); + const init = decodeInitializerLazy( + Lazy, + field.loc, + emptyTypeParams, + decoded, + initializer, + selfType, + scopeRef, + ); // decode field return Ast.DeclMem( @@ -201,6 +200,7 @@ const EMustCopyField = ( }); function* decodeConstant( + Lazy: Ast.ThunkBuilder, init: Ast.ConstantInit, overridable: boolean, nextVia: Ast.ViaMember, @@ -208,13 +208,14 @@ function* decodeConstant( selfType: Ast.SelfType, ): E.WithLog>> { if (init.kind === 'constant_decl') { - const type = decodeTypeLazy(emptyTypeParams, init.type, scopeRef); + const type = decodeTypeLazy(Lazy, emptyTypeParams, init.type, scopeRef); return Ast.DeclMem( Ast.FieldConstSig(overridable, type, undefined), nextVia, ); } else { const [type, expr] = decodeConstantDef( + Lazy, nextVia.defLoc, emptyTypeParams, init, diff --git a/src/next/types/functions.ts b/src/next/types/functions.ts index 2edbada957..fd64c27f4a 100644 --- a/src/next/types/functions.ts +++ b/src/next/types/functions.ts @@ -10,6 +10,7 @@ import { decodeBody } from "@/next/types/body"; const errorKind = "function"; export function* decodeFunctions( + Lazy: Ast.ThunkBuilder, imported: readonly Ast.SourceCheckResult[], source: TactSource, scopeRef: () => Ast.Scope, @@ -28,7 +29,7 @@ export function* decodeFunctions( return [ fn.name.text, Ast.Decl( - yield* decodeFunction(fn, scopeRef), + yield* decodeFunction(Lazy, fn, scopeRef), Ast.ViaOrigin(fn.loc, source) ) ] as const; @@ -56,14 +57,15 @@ export function* decodeFunctions( } function* decodeFunction( + Lazy: Ast.ThunkBuilder, fn: Ast.Function, scopeRef: () => Ast.Scope, ) { const { type, inline, body, loc } = fn; - const fnType = yield* decodeFnType(type, scopeRef); + const fnType = yield* decodeFnType(Lazy, type, scopeRef); return Ast.FnSig( fnType, inline, - yield* decodeBody(body, fnType, loc, scopeRef), + yield* decodeBody(Lazy, body, fnType, loc, scopeRef), ); } diff --git a/src/next/types/message.ts b/src/next/types/message.ts index 9da8d25337..e31962c37e 100644 --- a/src/next/types/message.ts +++ b/src/next/types/message.ts @@ -12,30 +12,38 @@ import { emptyTypeParams } from "@/next/types/type-params"; import { highest32ofSha256, sha256 } from "@/utils/sha256"; export function* decodeMessage( + Lazy: Ast.ThunkBuilder, message: Ast.MessageDecl, scopeRef: () => Ast.Scope, ): E.WithLog { const fields = yield* decodeFields( + Lazy, message.fields, emptyTypeParams, scopeRef, ); - const lazyExpr = Ast.Lazy(function* () { - const opcode = yield* decodeOpcode( - emptyTypeParams, - message.opcode, - message.name.text, - fields.order, - scopeRef, - ); - if (opcode === 0n) { - yield EZero(message.loc); - } else if (opcode < 0n) { - yield ENegative(message.loc); - } else if (opcode > 0xffff_ffff) { - yield ETooLarge(message.loc); - } - return opcode; + const lazyExpr = Lazy({ + callback: function* (Lazy) { + const opcode = yield* decodeOpcode( + Lazy, + emptyTypeParams, + message.opcode, + message.name.text, + fields.order, + scopeRef, + ); + if (opcode === 0n) { + yield EZero(message.loc); + } else if (opcode < 0n) { + yield ENegative(message.loc); + } else if (opcode > 0xffff_ffff) { + yield ETooLarge(message.loc); + } + return opcode; + }, + context: [E.TEText("computing opcode")], + loc: message.loc, + recover: undefined, }); return Ast.MessageSig(lazyExpr, fields); @@ -66,6 +74,7 @@ const ETooLarge = ( }); function* decodeOpcode( + Lazy: Ast.ThunkBuilder, typeParams: Ast.TypeParams, opcode: Ast.Expression | undefined, messageName: string, @@ -74,6 +83,7 @@ function* decodeOpcode( ) { if (opcode) { const expr = yield* decodeExpr( + Lazy, typeParams, opcode, scopeRef, diff --git a/src/next/types/methods.ts b/src/next/types/methods.ts index 82cc54b5e7..41502956e0 100644 --- a/src/next/types/methods.ts +++ b/src/next/types/methods.ts @@ -13,6 +13,7 @@ import { assignType } from "@/next/types/type"; import { emptyTypeParams } from "@/next/types/type-params"; export function* getMethodsGeneral( + Lazy: Ast.ThunkBuilder, declSig: Ast.TraitSig | Ast.ContractSig, typeName: Ast.TypeId, traits: readonly Ast.Decl[], @@ -51,7 +52,7 @@ export function* getMethodsGeneral( const { name, inline, type, body, loc } = fun; const nextVia = Ast.ViaMemberOrigin(typeName.text, loc); - const decodedFn = yield* decodeFnType(type, scopeRef); + const decodedFn = yield* decodeFnType(Lazy, type, scopeRef); const selfType = Ast.MVTypeRef(typeName, declSig, [], loc); const methodType = Ast.DecodedMethodType( mutates, @@ -62,6 +63,7 @@ export function* getMethodsGeneral( ); const decodedBody = body.kind !== 'abstract_body' ? yield* decodeBody( + Lazy, body, methodType, loc, @@ -69,6 +71,7 @@ export function* getMethodsGeneral( ) : undefined; const getMethodId = decodeGetLazy( + Lazy, emptyTypeParams, name, get, @@ -122,25 +125,33 @@ const EGenericMethod = (loc: Ast.Loc): E.TcError => ({ }); function decodeGetLazy( + Lazy: Ast.ThunkBuilder, typeParams: Ast.TypeParams, fnName: Ast.Id, get: Ast.GetAttribute | undefined, scopeRef: () => Ast.Scope, selfType: Ast.SelfType, -): undefined | Ast.Lazy { +): undefined | Ast.Thunk { if (!get) { return undefined; } - return Ast.Lazy(() => decodeGet( - typeParams, - fnName, - get, - scopeRef, - selfType, - )); + return Lazy({ + callback: (Lazy) => decodeGet( + Lazy, + typeParams, + fnName, + get, + scopeRef, + selfType, + ), + context: [E.TEText("checking get() opcode")], + loc: get.loc, + recover: undefined, + }); } function* decodeGet( + Lazy: Ast.ThunkBuilder, typeParams: Ast.TypeParams, fnName: Ast.Id, get: Ast.GetAttribute, @@ -149,6 +160,7 @@ function* decodeGet( ): E.WithLog { if (get.methodId) { const expr = yield* decodeExpr( + Lazy, typeParams, get.methodId, scopeRef, diff --git a/src/next/types/override.ts b/src/next/types/override.ts index b9a97054a9..802ff261e2 100644 --- a/src/next/types/override.ts +++ b/src/next/types/override.ts @@ -6,9 +6,9 @@ import { emptyTypeParams } from "@/next/types/type-params"; export function* checkFieldOverride( name: string, prev: Ast.DeclMem | undefined + Ast.Thunk> | undefined >> | undefined, - nextType: Ast.Lazy, + nextType: Ast.Thunk, nextVia: Ast.ViaMember, override: boolean, ): E.WithLog { diff --git a/src/next/types/receivers.ts b/src/next/types/receivers.ts index f8fd485a35..bd751f2590 100644 --- a/src/next/types/receivers.ts +++ b/src/next/types/receivers.ts @@ -7,13 +7,8 @@ import { decodeStatementsLazy } from "@/next/types/statements"; import { decodeDealiasTypeLazy } from "@/next/types/type"; import { emptyTypeParams } from "@/next/types/type-params"; -// const hash = commentPseudoOpcode( -// commentRcv.selector.comment, -// receivers.fallback !== "undefined", -// commentRcv.ast.loc, -// ); - export function* getReceivers( + Lazy: Ast.ThunkBuilder, selfTypeRef: () => Ast.SelfType, typeName: Ast.TypeId, traits: readonly Ast.Decl[], @@ -52,6 +47,7 @@ export function* getReceivers( } return { bounce: yield* mergeBounce( + Lazy, selfTypeRef, typeName, impBounces, @@ -59,6 +55,7 @@ export function* getReceivers( scopeRef, ), external: yield* mergeReceivers( + Lazy, selfTypeRef, typeName, impExternals, @@ -66,6 +63,7 @@ export function* getReceivers( scopeRef, ), internal: yield* mergeReceivers( + Lazy, selfTypeRef, typeName, impInternals, @@ -76,6 +74,7 @@ export function* getReceivers( } function* mergeReceivers( + Lazy: Ast.ThunkBuilder, selfTypeRef: () => Ast.SelfType, typeName: Ast.TypeId, imported: readonly Ast.Decl[], @@ -122,17 +121,24 @@ function* mergeReceivers( // local for (const { via, decl: [subKind, body] } of local) { const statements = decodeStatementsLazy( + Lazy, + via.defLoc, body, emptyTypeParams, selfTypeRef, - function* () { return Void; }, + Lazy({ + callback: function* () { return Void; }, + context: [], + loc: via.defLoc, + recover: Void, + }), true, scopeRef, ); switch (subKind.kind) { case "simple": { const { name, type } = subKind.param; - const decoded = yield* decodeDealiasTypeLazy(emptyTypeParams, type, scopeRef)(); + const decoded = yield* decodeDealiasTypeLazy(Lazy, emptyTypeParams, type, scopeRef)(); if (decoded.kind === 'TySlice') { if (allMessageAny) { yield ERedefineReceiver("fallback binary", allMessageAny.via, via); @@ -188,6 +194,7 @@ function* mergeReceivers( } function* mergeBounce( + Lazy: Ast.ThunkBuilder, selfTypeRef: () => Ast.SelfType, typeName: Ast.TypeId, imported: readonly Ast.Decl[], @@ -217,14 +224,21 @@ function* mergeBounce( // local for (const { via, decl: [{ name, type }, body] } of local) { const statements = decodeStatementsLazy( + Lazy, + via.defLoc, body, emptyTypeParams, selfTypeRef, - function* () { return Void; }, + Lazy({ + callback: function* () { return Void; }, + context: [], + loc: via.defLoc, + recover: Void, + }), true, scopeRef, ); - const decoded = yield* decodeDealiasTypeLazy(emptyTypeParams, type, scopeRef)(); + const decoded = yield* decodeDealiasTypeLazy(Lazy, emptyTypeParams, type, scopeRef)(); if (decoded.kind === 'TySlice') { if (allMessageAny) { yield ERedefineReceiver("fallback binary", allMessageAny.via, via); diff --git a/src/next/types/statements.ts b/src/next/types/statements.ts index 3a41c3b03a..84fbaac1e4 100644 --- a/src/next/types/statements.ts +++ b/src/next/types/statements.ts @@ -12,28 +12,36 @@ import { emptyEff, mergeEff, setHadAssign, setHadExit } from "@/next/types/effec import { emptyTypeParams } from "@/next/types/type-params"; export function decodeStatementsLazy( + Lazy: Ast.ThunkBuilder, + loc: Ast.Loc, statements: readonly Ast.Statement[], typeParams: Ast.TypeParams, selfTypeRef: () => undefined | Ast.SelfType, - returnType: Ast.Lazy, + returnType: Ast.Thunk, isInit: boolean, scopeRef: () => Ast.Scope, ) { - return Ast.Lazy(function* () { - const selfType = selfTypeRef(); - const required = isInit - ? yield* getRequired(selfType) - : undefined; - const ctx: Context = { - localScopeRef: new Map(), - required, - returnType: yield* returnType(), - scopeRef, - selfType, - typeParams, - }; - const res = yield* decodeStmts(statements, ctx, emptyEff); - return Ast.StatementsAux(res.node, res.effects); + return Lazy({ + callback: function* (Lazy) { + const selfType = selfTypeRef(); + const required = isInit + ? yield* getRequired(selfType) + : undefined; + const ctx: Context = { + Lazy, + localScopeRef: new Map(), + required, + returnType: yield* returnType(), + scopeRef, + selfType, + typeParams, + }; + const res = yield* decodeStmts(statements, ctx, emptyEff); + return Ast.StatementsAux(res.node, res.effects); + }, + context: [E.TEText("checking statements")], + loc, + recover: undefined, }); } @@ -235,7 +243,7 @@ const decodeDestruct: Decode( ): Result => Object.freeze({ node, context, effects }); type Context = { + readonly Lazy: Ast.ThunkBuilder, readonly scopeRef: () => Ast.Scope; readonly selfType: Ast.SelfType | undefined; readonly required: undefined | ReadonlySet; diff --git a/src/next/types/struct-fields.ts b/src/next/types/struct-fields.ts index 32cfac533c..cd0607f2fd 100644 --- a/src/next/types/struct-fields.ts +++ b/src/next/types/struct-fields.ts @@ -8,6 +8,7 @@ import { assignType, decodeTypeLazy } from "@/next/types/type"; import { emptyTypeParams } from "@/next/types/type-params"; export function* decodeFields( + Lazy: Ast.ThunkBuilder, fields: readonly Ast.FieldDecl[], typeParams: Ast.TypeParams, scopeRef: () => Ast.Scope, @@ -26,31 +27,61 @@ export function* decodeFields( } const ascribedType = decodeTypeLazy( + Lazy, typeParams, field.type, scopeRef, ); - const lazyExpr = initializer ? Ast.Lazy(function* () { + const lazyExpr = decodeInitializerLazy( + Lazy, + loc, + typeParams, + ascribedType, + initializer, + undefined, + scopeRef, + ); + + order.push(name); + all.set(name, [loc, Ast.InhFieldSig(ascribedType, lazyExpr)]); + } + + const map = new Map([...all].map(([name, [, field]]) => [name, field])); + return Ast.Ordered(order, map); +} + +export function decodeInitializerLazy( + Lazy: Ast.ThunkBuilder, + loc: Ast.Loc, + typeParams: Ast.TypeParams, + ascribedType: Ast.Thunk, + initializer: Ast.Expression | undefined, + selfType: undefined | Ast.SelfType, + scopeRef: () => Ast.Scope, +) { + if (!initializer) { + return undefined; + } + return Lazy({ + callback: function* (Lazy) { const expr = yield* decodeExpr( + Lazy, typeParams, initializer, scopeRef, - undefined, + selfType, new Map(), ); const computed = expr.computedType; const ascribed = yield* ascribedType(); yield* assignType(expr.loc, emptyTypeParams, ascribed, computed, false); return yield* evalExpr(expr, scopeRef); - }) : undefined; - - order.push(name); - all.set(name, [loc, Ast.InhFieldSig(ascribedType, lazyExpr)]); - } - - const map = new Map([...all].map(([name, [, field]]) => [name, field])); - return Ast.Ordered(order, map); + }, + context: [E.TEText("evaluating initial field value")], + loc, + recover: undefined, + }); } const EDuplicateField = ( diff --git a/src/next/types/struct.ts b/src/next/types/struct.ts index b016bef228..9ffc250510 100644 --- a/src/next/types/struct.ts +++ b/src/next/types/struct.ts @@ -6,10 +6,16 @@ import { decodeFields } from "@/next/types/struct-fields"; import { decodeTypeParams } from "@/next/types/type-params"; export function* decodeStruct( + Lazy: Ast.ThunkBuilder, struct: Ast.StructDecl, scopeRef: () => Ast.Scope, ): E.WithLog { const typeParams = yield* decodeTypeParams(struct.typeParams); - const fields = yield* decodeFields(struct.fields, typeParams, scopeRef); + const fields = yield* decodeFields( + Lazy, + struct.fields, + typeParams, + scopeRef, + ); return Ast.StructSig(typeParams, fields); } diff --git a/src/next/types/trait.ts b/src/next/types/trait.ts index 66a1e61a9f..36578b8a0f 100644 --- a/src/next/types/trait.ts +++ b/src/next/types/trait.ts @@ -8,6 +8,7 @@ import { getMethodsGeneral } from "@/next/types/methods"; import { getReceivers } from "@/next/types/receivers"; export function* decodeTrait( + Lazy: Ast.ThunkBuilder, trait: Ast.Trait, scopeRef: () => Ast.Scope, ): E.WithLog { @@ -21,39 +22,47 @@ export function* decodeTrait( } // delayed until we get all traits and init - const contentLazy = Ast.Lazy(function* () { - const traits = yield* getInheritedTraits( - trait.traits, - scopeRef, - ); - - // const contentRef = () => content; - const content: Ast.TraitContent = { - fieldish: yield* getFieldishGeneral( - traitSig, - name, - traits, - constants, - fields, - scopeRef, - ), - methods: yield* getMethodsGeneral( - traitSig, - name, - traits, - methods, - scopeRef, - ), - receivers: yield* getReceivers( - () => selfType, - name, - traits, - receivers, + const contentLazy = Lazy({ + callback: function* (Lazy) { + const traits = yield* getInheritedTraits( + trait.traits, scopeRef, - ), - }; - - return content; + ); + + // const contentRef = () => content; + const content: Ast.TraitContent = { + fieldish: yield* getFieldishGeneral( + Lazy, + traitSig, + name, + traits, + constants, + fields, + scopeRef, + ), + methods: yield* getMethodsGeneral( + Lazy, + traitSig, + name, + traits, + methods, + scopeRef, + ), + receivers: yield* getReceivers( + Lazy, + () => selfType, + name, + traits, + receivers, + scopeRef, + ), + }; + + return content; + }, + context: [E.TEText("checking inner scope of trait")], + loc, + recover, }); const traitSig = Ast.TraitSig(contentLazy); @@ -76,3 +85,26 @@ const ENoAttributes = ( E.TEText(`Traits cannot have attributes`), ], }); + +const recover: Ast.TraitContent = { + fieldish: Ast.Ordered([], new Map()), + methods: new Map(), + receivers: { + bounce: { + message: [], + messageAny: undefined, + }, + internal: { + message: [], + messageAny: undefined, + stringAny: undefined, + empty: undefined, + }, + external: { + message: [], + messageAny: undefined, + stringAny: undefined, + empty: undefined, + }, + }, +}; \ No newline at end of file diff --git a/src/next/types/type-fn.ts b/src/next/types/type-fn.ts index 5e7d89e304..e108258050 100644 --- a/src/next/types/type-fn.ts +++ b/src/next/types/type-fn.ts @@ -7,12 +7,13 @@ import { decodeDealiasTypeLazy } from "@/next/types/type"; import { recoverName } from "@/next/types/name"; export function* decodeFnType( + Lazy: Ast.ThunkBuilder, { typeParams, params, returnType }: Ast.FnType, scopeRef: () => Ast.Scope, ): E.WithLog { const decodedTypeParams = yield* decodeTypeParams(typeParams); const dealias = (type: Ast.Type) => { - return decodeDealiasTypeLazy(decodedTypeParams, type, scopeRef); + return decodeDealiasTypeLazy(Lazy, decodedTypeParams, type, scopeRef); }; return Ast.DecodedFnType( decodedTypeParams, @@ -22,7 +23,7 @@ export function* decodeFnType( } export function* decodeParams( - dealias: (type: Ast.Type) => Ast.Lazy, + dealias: (type: Ast.Type) => Ast.Thunk, params: readonly Ast.TypedParameter[], ): E.WithLog { const order: Ast.Parameter[] = []; diff --git a/src/next/types/type.ts b/src/next/types/type.ts index 3feec5f382..e5075f91be 100644 --- a/src/next/types/type.ts +++ b/src/next/types/type.ts @@ -9,29 +9,41 @@ import { printType } from "@/next/types/type-print"; import { zip } from "@/utils/array"; export const decodeTypeLazy = ( + Lazy: Ast.ThunkBuilder, typeParams: Ast.TypeParams, type: Ast.Type, scopeRef: () => Ast.Scope, -) => Ast.Lazy(() => decodeType( - typeParams, - type, - scopeRef().typeDecls, -)); +) => Lazy({ + callback: () => decodeType( + typeParams, + type, + scopeRef().typeDecls, + ), + context: [E.TEText("checking type"), E.TECode(type.loc)], + loc: type.loc, + recover: Ast.DTypeRecover(), +}); export const decodeDealiasTypeLazy = ( + Lazy: Ast.ThunkBuilder, typeParams: Ast.TypeParams, type: Ast.Type, scopeRef: () => Ast.Scope, -) => Ast.Lazy(function* () { - const decoded = yield* decodeType( - typeParams, - type, - scopeRef().typeDecls, - ); - return yield* dealiasTypeAux( - decoded, - scopeRef().typeDecls, - ); +) => Lazy({ + callback: function* () { + const decoded = yield* decodeType( + typeParams, + type, + scopeRef().typeDecls, + ); + return yield* dealiasTypeAux( + decoded, + scopeRef().typeDecls, + ); + }, + context: [E.TEText("checking type"), E.TECode(type.loc)], + loc: type.loc, + recover: Ast.DTypeRecover(), }); export function* dealiasType( @@ -885,6 +897,7 @@ const EFnArity = ( }); export function* checkFnCallWithArgs( + Lazy: Ast.ThunkBuilder, loc: Ast.Loc, fnType: Ast.DecodedFnType | undefined, ascribedTypeArgs: readonly Ast.DecodedType[], @@ -902,7 +915,7 @@ export function* checkFnCallWithArgs( } const result = yield* checkFnCall( loc, - substFnType(fnType, ascribedTypeArgs), + substFnType(Lazy, loc, fnType, ascribedTypeArgs), args, ); return { @@ -922,19 +935,26 @@ const ENoFunction = (loc: Ast.Loc): E.TcError => ({ }); function substFnType( + Lazy: Ast.ThunkBuilder, + fnLoc: Ast.Loc, { typeParams, params, returnType }: Ast.DecodedFnType | Ast.DecodedMethodType, args: readonly Ast.DecodedType[], ) { const order: Ast.Parameter[] = []; - for (const param of params.order) { + for (const [index, param] of params.order.entries()) { order.push(Ast.Parameter( param.name, - Ast.Lazy(function* () { - return substituteTypeArgs( - yield* param.type(), - typeParams, - args, - ); + Lazy({ + callback: function* () { + return substituteTypeArgs( + yield* param.type(), + typeParams, + args, + ); + }, + context: [E.TEText(`substituting into parameter ${getParamName(param.name, index)}`)], + loc: param.loc, + recover: Ast.DTypeRecover(), }), param.loc, )); @@ -945,22 +965,28 @@ function substFnType( order, params.set ), - Ast.Lazy(function* () { - return substituteTypeArgs( - yield* returnType(), - typeParams, - args, - ); + Lazy({ + callback: function* () { + return substituteTypeArgs( + yield* returnType(), + typeParams, + args, + ); + }, + context: [E.TEText(`substituting into return type`)], + loc: fnLoc, + recover: Ast.DTypeRecover(), }), ); } export function* lookupMethod( + Lazy: Ast.ThunkBuilder, selfType: Ast.DecodedType, method: Ast.Id, args: readonly (readonly [Ast.Loc, Ast.DecodedType])[], typeDecls: ReadonlyMap>, - extensions: ReadonlyMap[]>>, + extensions: ReadonlyMap[]>>, ): E.WithLog { if (selfType.kind === 'recover') { return { returnType: Ast.DTypeRecover(), typeArgMap: new Map() }; @@ -971,6 +997,7 @@ export function* lookupMethod( } return yield* lookupMethod( + Lazy, selfType, method, args, @@ -981,6 +1008,7 @@ export function* lookupMethod( if (selfType.kind !== 'type_ref') { return yield* lookupExts( + Lazy, selfType, method, args, @@ -1003,6 +1031,7 @@ export function* lookupMethod( return yield* checkFnCall(method.loc, builtin, args); } return yield* lookupExts( + Lazy, selfType, method, args, @@ -1029,10 +1058,11 @@ export function* lookupMethod( } function* lookupExts( + Lazy: Ast.ThunkBuilder, selfType: Ast.DecodedType, method: Ast.Id, args: readonly (readonly [Ast.Loc, Ast.DecodedType])[], - extensions: ReadonlyMap[]>>, + extensions: ReadonlyMap[]>>, ) { const lazyExts = extensions.get(method.text); if (!lazyExts) { @@ -1071,6 +1101,8 @@ function* lookupExts( const result = yield* checkFnCall( method.loc, substFnType( + Lazy, + method.loc, methodType, typeArgsToParams(typeArgs, methodType.typeParams), ), diff --git a/src/next/types/typecheck.ts b/src/next/types/typecheck.ts index 2d5f6fb8dd..a273c73771 100644 --- a/src/next/types/typecheck.ts +++ b/src/next/types/typecheck.ts @@ -52,12 +52,13 @@ function* tcSource( // source for current file source: TactSource, ): E.WithLog { + const Lazy = Ast.thunkBuilder; const scopeRef = () => scope; const scope: Ast.Scope = { - typeDecls: yield* decodeTypeDecls(imported, source, scopeRef), - functions: yield* decodeFunctions(imported, source, scopeRef), - constants: yield* decodeConstants(imported, source, scopeRef), - extensions: decodeExtensions(imported, source, scopeRef), + typeDecls: yield* decodeTypeDecls(Lazy, imported, source, scopeRef), + functions: yield* decodeFunctions(Lazy, imported, source, scopeRef), + constants: yield* decodeConstants(Lazy, imported, source, scopeRef), + extensions: decodeExtensions(Lazy, imported, source, scopeRef), } return scope; } \ No newline at end of file diff --git a/src/next/types/typedecl.ts b/src/next/types/typedecl.ts index 48525f9cdc..15a7c22e1b 100644 --- a/src/next/types/typedecl.ts +++ b/src/next/types/typedecl.ts @@ -14,6 +14,7 @@ import { decodeUnion } from "@/next/types/union"; const errorKind = 'type'; export function* decodeTypeDecls( + Lazy: Ast.ThunkBuilder, imported: readonly Ast.SourceCheckResult[], source: TactSource, scopeRef: () => Ast.Scope, @@ -32,7 +33,7 @@ export function* decodeTypeDecls( return new Map([[ decl.name.text, Ast.Decl( - yield* decodeTypeDecl(decl, scopeRef), + yield* decodeTypeDecl(Lazy, decl, scopeRef), via, ), ]]); @@ -63,27 +64,28 @@ export function* decodeTypeDecls( } function* decodeTypeDecl( + Lazy: Ast.ThunkBuilder, decl: Ast.TypeDecl, scopeRef: () => Ast.Scope, ): E.WithLog { switch (decl.kind) { case "alias_decl": { - return yield* decodeAlias(decl, scopeRef); + return yield* decodeAlias(Lazy, decl, scopeRef); } case "contract": { - return yield* decodeContract(decl, scopeRef); + return yield* decodeContract(Lazy, decl, scopeRef); } case "trait": { - return yield* decodeTrait(decl, scopeRef); + return yield* decodeTrait(Lazy, decl, scopeRef); } case "struct_decl": { - return yield* decodeStruct(decl, scopeRef); + return yield* decodeStruct(Lazy, decl, scopeRef); } case "message_decl": { - return yield* decodeMessage(decl, scopeRef); + return yield* decodeMessage(Lazy, decl, scopeRef); } case "union_decl": { - return yield* decodeUnion(decl, scopeRef); + return yield* decodeUnion(Lazy, decl, scopeRef); } } } diff --git a/src/next/types/union.ts b/src/next/types/union.ts index 6dee138d07..a6f496940e 100644 --- a/src/next/types/union.ts +++ b/src/next/types/union.ts @@ -2,10 +2,9 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ import * as Ast from "@/next/ast"; import * as E from "@/next/types/errors"; -import { evalExpr } from "@/next/types/expr-eval"; -import { decodeExpr } from "@/next/types/expression"; -import { assignType, decodeTypeLazy } from "@/next/types/type"; -import { decodeTypeParams, emptyTypeParams } from "@/next/types/type-params"; +import { decodeInitializerLazy } from "@/next/types/struct-fields"; +import { decodeTypeLazy } from "@/next/types/type"; +import { decodeTypeParams } from "@/next/types/type-params"; type Cons = { readonly fields: ReadonlyMap; @@ -13,6 +12,7 @@ type Cons = { } export function* decodeUnion( + Lazy: Ast.ThunkBuilder, union: Ast.UnionDecl, scopeRef: () => Ast.Scope, ): E.WithLog { @@ -34,21 +34,23 @@ export function* decodeUnion( const [, prevFieldLoc] = prevField; yield EDuplicateField(fieldName, prevFieldLoc, field.name.loc) } - const ascribedType = decodeTypeLazy(typeParams, field.type, scopeRef); - const initializer = field.initializer; - const lazyExpr = initializer ? Ast.Lazy(function* () { - const expr = yield* decodeExpr( - typeParams, - initializer, - scopeRef, - undefined, - new Map(), - ); - const computed = expr.computedType; - const ascribed = yield* ascribedType(); - yield* assignType(expr.loc, emptyTypeParams, ascribed, computed, false); - return yield* evalExpr(expr, scopeRef); - }) : undefined; + const ascribedType = decodeTypeLazy( + Lazy, + typeParams, + field.type, + scopeRef, + ); + + const lazyExpr = decodeInitializerLazy( + Lazy, + field.loc, + typeParams, + ascribedType, + field.initializer, + undefined, + scopeRef, + ); + const decoded = Ast.InhFieldSig(ascribedType, lazyExpr); fields.set(fieldName, [decoded, field.name.loc]) } From 6f169518c958f0dea8d92ea8d129491d9534a1ef Mon Sep 17 00:00:00 2001 From: verytactical <186486509+verytactical@users.noreply.github.com> Date: Mon, 2 Jun 2025 05:44:16 +0400 Subject: [PATCH 34/38] move errors --- src/next/{types => ast}/errors.ts | 11 ++- src/next/ast/index.ts | 1 + src/next/ast/lazy.ts | 2 +- src/next/types/alias.ts | 3 +- src/next/types/body.ts | 41 ++++----- src/next/types/constant-def.ts | 7 +- src/next/types/constants.ts | 19 ++-- src/next/types/contract.ts | 41 ++++----- src/next/types/effects.ts | 13 ++- src/next/types/expr-eval.ts | 3 +- src/next/types/expression.ts | 81 ++++++++-------- src/next/types/extensions.ts | 33 ++++--- src/next/types/fields.ts | 19 ++-- src/next/types/functions.ts | 9 +- src/next/types/lvalue.ts | 9 +- src/next/types/message.ts | 17 ++-- src/next/types/methods.ts | 25 +++-- src/next/types/override.ts | 39 ++++---- src/next/types/receivers.ts | 23 +++-- src/next/types/statements.ts | 73 ++++++++------- src/next/types/struct-fields.ts | 15 ++- src/next/types/struct.ts | 3 +- src/next/types/trait.ts | 9 +- src/next/types/traits-scope.ts | 11 +-- src/next/types/type-fn.ts | 11 +-- src/next/types/type-params.ts | 7 +- src/next/types/type.ts | 147 +++++++++++++++--------------- src/next/types/typecheck.ts | 9 +- src/next/types/typedecl.ts | 11 +-- src/next/types/union.ts | 27 +++--- 30 files changed, 347 insertions(+), 372 deletions(-) rename src/next/{types => ast}/errors.ts (92%) diff --git a/src/next/types/errors.ts b/src/next/ast/errors.ts similarity index 92% rename from src/next/types/errors.ts rename to src/next/ast/errors.ts index e6e8334872..3807935913 100644 --- a/src/next/types/errors.ts +++ b/src/next/ast/errors.ts @@ -1,5 +1,6 @@ import { throwInternal } from "@/error/errors"; -import type { DecodedType, Loc, Via, ViaMember, ViaUser } from "@/next/ast"; +import type { DecodedType } from "@/next/ast/dtype"; +import type { Loc } from "@/next/ast/common"; import type * as V from "@/next/ast/via"; export type WithLog = Generator @@ -43,7 +44,7 @@ export function* filterLog(xs: readonly T[], f: (x: T) => WithLog): return result; } -export function* toMap( +export function* toMap( kind: string, xs: readonly (readonly [string, V])[], ): WithLog> { @@ -121,7 +122,7 @@ export const viaToRange = ({ imports, defLoc: definedAt }: V.ViaUser): Loc => { return throwInternal("Implicit import shadows something. Duplicates in stdlib?"); }; -export const ERedefine = (kind: string, name: string, prev: Via, next: ViaUser): TcError => ({ +export const ERedefine = (kind: string, name: string, prev: V.Via, next: V.ViaUser): TcError => ({ loc: viaToRange(next), descr: [ TEText(`There already is a ${kind} "${name}" from`), @@ -131,8 +132,8 @@ export const ERedefine = (kind: string, name: string, prev: Via, next: ViaUser): export const ERedefineMember = ( name: string, - prev: ViaMember, - next: ViaMember, + prev: V.ViaMember, + next: V.ViaMember, ): TcError => ({ loc: next.defLoc, descr: [ diff --git a/src/next/ast/index.ts b/src/next/ast/index.ts index 51ef0ef6b4..02e21e13db 100644 --- a/src/next/ast/index.ts +++ b/src/next/ast/index.ts @@ -12,3 +12,4 @@ export * from "@/next/ast/generated/root"; export * from "@/next/ast/generated/value"; export * from "@/next/ast/generated/effects"; export * from "@/next/ast/lazy"; +export * from "@/next/ast/errors"; diff --git a/src/next/ast/lazy.ts b/src/next/ast/lazy.ts index 17fe2d583a..f6c7f589cf 100644 --- a/src/next/ast/lazy.ts +++ b/src/next/ast/lazy.ts @@ -1,6 +1,6 @@ /* eslint-disable require-yield */ import type { Loc } from "@/next/ast/common"; -import * as E from "@/next/types/errors"; +import * as E from "@/next/ast/errors"; type Result = 'waiting' | 'running' | readonly [T]; diff --git a/src/next/types/alias.ts b/src/next/types/alias.ts index 5a14c612f1..9c2b1da445 100644 --- a/src/next/types/alias.ts +++ b/src/next/types/alias.ts @@ -1,7 +1,6 @@ /* eslint-disable require-yield */ /* eslint-disable @typescript-eslint/no-unused-vars */ import * as Ast from "@/next/ast"; -import type * as E from "@/next/types/errors"; import { decodeTypeParams } from "@/next/types/type-params"; import { decodeTypeLazy } from "@/next/types/type"; @@ -9,7 +8,7 @@ export function* decodeAlias( Lazy: Ast.ThunkBuilder, { typeParams, type }: Ast.AliasDecl, scopeRef: () => Ast.Scope, -): E.WithLog { +): Ast.WithLog { const decodedParams = yield* decodeTypeParams(typeParams); return Ast.AliasSig( decodedParams, diff --git a/src/next/types/body.ts b/src/next/types/body.ts index fc4430c23f..e6cfad3f8d 100644 --- a/src/next/types/body.ts +++ b/src/next/types/body.ts @@ -1,7 +1,6 @@ /* eslint-disable require-yield */ /* eslint-disable @typescript-eslint/no-unused-vars */ import * as Ast from "@/next/ast"; -import * as E from "@/next/types/errors"; import { isSubsetOf } from "@/utils/isSubsetOf"; import { decodeStatementsLazy } from "@/next/types/statements"; @@ -11,13 +10,13 @@ export function* decodeBody( fnType: Ast.DecodedFnType | Ast.DecodedMethodType, loc: Ast.Loc, scopeRef: () => Ast.Scope, -): E.WithLog { +): Ast.WithLog { switch (node.kind) { case "abstract_body": { yield ENoBody(loc) return Ast.TactBody(Lazy({ callback: function* () { return undefined; }, - context: [E.TEText("checking body of function")], + context: [Ast.TEText("checking body of function")], loc, recover: undefined, })); @@ -48,7 +47,7 @@ export function* decodeBody( loc, scopeRef, ), - context: [E.TEText("checking shuffle")], + context: [Ast.TEText("checking shuffle")], loc, recover: undefined, }), @@ -63,10 +62,10 @@ export function* decodeBody( const ENoBody = ( loc: Ast.Loc, -): E.TcError => ({ +): Ast.TcError => ({ loc, descr: [ - E.TEText(`Function must have a body`), + Ast.TEText(`Function must have a body`), ], }); @@ -135,7 +134,7 @@ function* checkShuffle( function* getRetTupleSize( { kind, returnType }: Ast.DecodedFnType | Ast.DecodedMethodType, scopeRef: () => Ast.Scope, -): E.WithLog { +): Ast.WithLog { const type = yield* returnType(); const baseSize = yield* getTypeTupleSize(type, scopeRef); if (typeof baseSize === 'undefined') { @@ -224,51 +223,51 @@ function* getTypeTupleSize( } } -const EDuplicateArgs = (loc: Ast.Loc): E.TcError => ({ +const EDuplicateArgs = (loc: Ast.Loc): Ast.TcError => ({ loc, descr: [ - E.TEText(`Argument rearrangement cannot have duplicates`), + Ast.TEText(`Argument rearrangement cannot have duplicates`), ], }); -const EWildcardArgs = (loc: Ast.Loc): E.TcError => ({ +const EWildcardArgs = (loc: Ast.Loc): Ast.TcError => ({ loc, descr: [ - E.TEText(`Argument rearrangement cannot use wildcards`), + Ast.TEText(`Argument rearrangement cannot use wildcards`), ], }); -const EMissingArgs = (loc: Ast.Loc): E.TcError => ({ +const EMissingArgs = (loc: Ast.Loc): Ast.TcError => ({ loc, descr: [ - E.TEText(`Argument rearrangement must mention all function parameters`), + Ast.TEText(`Argument rearrangement must mention all function parameters`), ], }); -const EExtraArgs = (loc: Ast.Loc): E.TcError => ({ +const EExtraArgs = (loc: Ast.Loc): Ast.TcError => ({ loc, descr: [ - E.TEText(`Argument rearrangement must mention only function parameters`), + Ast.TEText(`Argument rearrangement must mention only function parameters`), ], }); -const EDuplicateRet = (loc: Ast.Loc): E.TcError => ({ +const EDuplicateRet = (loc: Ast.Loc): Ast.TcError => ({ loc, descr: [ - E.TEText(`Return rearrangement cannot have duplicates`), + Ast.TEText(`Return rearrangement cannot have duplicates`), ], }); -const EMissingRet = (loc: Ast.Loc): E.TcError => ({ +const EMissingRet = (loc: Ast.Loc): Ast.TcError => ({ loc, descr: [ - E.TEText(`Return rearrangement must mention all function parameters`), + Ast.TEText(`Return rearrangement must mention all function parameters`), ], }); -const EExtraRet = (loc: Ast.Loc): E.TcError => ({ +const EExtraRet = (loc: Ast.Loc): Ast.TcError => ({ loc, descr: [ - E.TEText(`Return rearrangement must mention only function parameters`), + Ast.TEText(`Return rearrangement must mention only function parameters`), ], }); diff --git a/src/next/types/constant-def.ts b/src/next/types/constant-def.ts index 634189d74e..6b1e3956b4 100644 --- a/src/next/types/constant-def.ts +++ b/src/next/types/constant-def.ts @@ -4,7 +4,6 @@ import { assignType, decodeTypeLazy } from "@/next/types/type"; import { decodeExpr } from "@/next/types/expression"; import { evalExpr } from "@/next/types/expr-eval"; import { emptyTypeParams } from "@/next/types/type-params"; -import * as E from "@/next/types/errors"; export function decodeConstantDef( Lazy: Ast.ThunkBuilder, @@ -35,7 +34,7 @@ export function decodeConstantDef( } const lazyExpr = Lazy({ loc: defLoc, - context: [E.TEText("evaluating expression")], + context: [Ast.TEText("evaluating expression")], recover: undefined, callback: evaluate, }); @@ -51,7 +50,7 @@ export function decodeConstantDef( selfType, new Map(), ), - context: [E.TEText("parsing expression")], + context: [Ast.TEText("parsing expression")], loc: defLoc, recover: undefined, }); @@ -61,7 +60,7 @@ export function decodeConstantDef( const ast = yield* expr(); return ast && (yield* evalExpr(ast, scopeRef)); }, - context: [E.TEText("evaluating expression")], + context: [Ast.TEText("evaluating expression")], loc: defLoc, recover: undefined, }); diff --git a/src/next/types/constants.ts b/src/next/types/constants.ts index 752aebdac5..a936981b5f 100644 --- a/src/next/types/constants.ts +++ b/src/next/types/constants.ts @@ -1,6 +1,5 @@ /* eslint-disable require-yield */ import * as Ast from "@/next/ast"; -import * as E from "@/next/types/errors"; import type { TactSource } from "@/next/imports/source"; import { builtinFunctions } from "@/next/types/builtins"; import { decodeConstantDef } from "@/next/types/constant-def"; @@ -13,7 +12,7 @@ export function* decodeConstants( imported: readonly Ast.SourceCheckResult[], source: TactSource, scopeRef: () => Ast.Scope, -): E.WithLog>> { +): Ast.WithLog>> { const allConstSigs = [ // imported ...imported.flatMap(({ globals, importedBy }) => ( @@ -21,7 +20,7 @@ export function* decodeConstants( .map(([name, s]) => [name, Ast.Decl(s.decl, Ast.ViaImport(importedBy, s.via))] as const) )), // local - ...yield* E.mapLog(source.items.constants, function* (c) { + ...yield* Ast.mapLog(source.items.constants, function* (c) { return [ c.name.text, Ast.Decl( @@ -32,14 +31,14 @@ export function* decodeConstants( }), ]; // remove builtins - const filteredSigs = yield* E.filterLog(allConstSigs, function* ([name, { via }]) { + const filteredSigs = yield* Ast.filterLog(allConstSigs, function* ([name, { via }]) { const isBuiltin = builtinFunctions.has(name); if (isBuiltin) { - yield E.ERedefine(errorKind, name, Ast.ViaBuiltin(), via); + yield Ast.ERedefine(errorKind, name, Ast.ViaBuiltin(), via); } return !isBuiltin; }); - return yield* E.toMap(errorKind, filteredSigs); + return yield* Ast.toMap(errorKind, filteredSigs); } function* decodeConstant( @@ -52,13 +51,13 @@ function* decodeConstant( yield ETopLevelDecl(loc); const type = Lazy({ loc: constant.loc, - context: [E.TEText("defining constant"), E.TECode(constant.loc)], + context: [Ast.TEText("defining constant"), Ast.TECode(constant.loc)], recover: Ast.DTypeRecover(), callback: function*() { return Ast.DTypeRecover(); }, }); const expr = Lazy({ loc: constant.loc, - context: [E.TEText("defining constant"), E.TECode(constant.loc)], + context: [Ast.TEText("defining constant"), Ast.TECode(constant.loc)], recover: Ast.VNumber(0n, constant.loc), callback: function*() { return Ast.VNumber(0n, constant.loc); }, }); @@ -76,9 +75,9 @@ function* decodeConstant( } } -const ETopLevelDecl = (loc: Ast.Loc): E.TcError => ({ +const ETopLevelDecl = (loc: Ast.Loc): Ast.TcError => ({ loc, descr: [ - E.TEText(`Top-level constant must have a body`), + Ast.TEText(`Top-level constant must have a body`), ], }); diff --git a/src/next/types/contract.ts b/src/next/types/contract.ts index 445efeda30..87921f5f3a 100644 --- a/src/next/types/contract.ts +++ b/src/next/types/contract.ts @@ -1,7 +1,6 @@ /* eslint-disable require-yield */ /* eslint-disable @typescript-eslint/no-unused-vars */ import * as Ast from "@/next/ast"; -import * as E from "@/next/types/errors"; import { throwInternal } from "@/error/errors"; import { getFieldishGeneral } from "@/next/types/fields"; import { getInheritedTraits } from "@/next/types/traits-scope"; @@ -75,7 +74,7 @@ export function* decodeContract( return content; }, - context: [E.TEText("checking scope of contract")], + context: [Ast.TEText("checking scope of contract")], loc: contract.loc, recover, }); @@ -99,7 +98,7 @@ function* decodeInit( init: Ast.Init | undefined, contentLazy: () => Ast.Thunk, scopeRef: () => Ast.Scope, -): E.WithLog { +): Ast.WithLog { if (!init) { // no init const lazyInit = Lazy({ @@ -124,7 +123,7 @@ function* decodeInit( } return Ast.Ordered(order, map); }, - context: [E.TEText("computing parameters of empty init")], + context: [Ast.TEText("computing parameters of empty init")], loc: contractLoc, recover: undefined, }); @@ -182,30 +181,30 @@ const EDuplicateParam = ( name: string, prev: Ast.Loc, next: Ast.Loc, -): E.TcError => ({ +): Ast.TcError => ({ loc: next, descr: [ - E.TEText(`Contract parameter ${name} was already defined`), - E.TEText(`New definition:`), - E.TECode(next), - E.TEText(`Previously defined at:`), - E.TECode(prev), + Ast.TEText(`Contract parameter ${name} was already defined`), + Ast.TEText(`New definition:`), + Ast.TECode(next), + Ast.TEText(`Previously defined at:`), + Ast.TECode(prev), ], }); const ENoInitializerParams = ( loc: Ast.Loc, -): E.TcError => ({ +): Ast.TcError => ({ loc, descr: [ - E.TEText(`Contract parameters cannot have an initializer`), + Ast.TEText(`Contract parameters cannot have an initializer`), ], }); const ENoInitializerEmpty = ( loc: Ast.Loc, -): E.TcError => ({ +): Ast.TcError => ({ loc, descr: [ - E.TEText(`When there is no init() or contract parameters, all fields must have an initializer`), + Ast.TEText(`When there is no init() or contract parameters, all fields must have an initializer`), ], }); @@ -216,7 +215,7 @@ function* getMethodsFromContract( traits: readonly Ast.Decl[], methods: readonly Ast.Method[], scopeRef: () => Ast.Scope -): E.WithLog>>> { +): Ast.WithLog>>> { const res = yield* getMethodsGeneral( Lazy, contractSig, @@ -253,7 +252,7 @@ function* getFieldishFromContract( constants: readonly Ast.FieldConstant[], fields: readonly Ast.FieldDecl[], scopeRef: () => Ast.Scope, -): E.WithLog>>>>> { +): Ast.WithLog>>>>> { const res = yield* getFieldishGeneral( Lazy, contractSig, @@ -303,21 +302,21 @@ function* getFieldishFromContract( } const EFieldsTwice = ( loc: Ast.Loc, -): E.TcError => ({ +): Ast.TcError => ({ loc, descr: [ - E.TEText(`Cannot define other fields when using contract parameters`), + Ast.TEText(`Cannot define other fields when using contract parameters`), ], }); const EAbstract = ( kind: string, name: string, next: Ast.ViaMember, -): E.TcError => ({ +): Ast.TcError => ({ loc: next.defLoc, descr: [ - E.TEText(`Contract ${kind} "${name}" must have an initializer`), - E.TEViaMember(next), + Ast.TEText(`Contract ${kind} "${name}" must have an initializer`), + Ast.TEViaMember(next), ], }); diff --git a/src/next/types/effects.ts b/src/next/types/effects.ts index c72bf0bab8..33089b2e04 100644 --- a/src/next/types/effects.ts +++ b/src/next/types/effects.ts @@ -1,5 +1,4 @@ import * as Ast from "@/next/ast"; -import * as E from "@/next/types/errors"; export const emptyEff: Ast.Effects = Object.freeze({ returnOrThrow: false, @@ -18,7 +17,7 @@ export const mergeEff = (left: Ast.Effects, right: Ast.Effects): Ast.Effects => export function* setHadAssign( eff: Ast.Effects, lvalue: Ast.LValue, -): E.WithLog { +): Ast.WithLog { const setSelfPaths = new Set(eff.setSelfPaths); switch (lvalue.kind) { case "self": { @@ -39,10 +38,10 @@ export function* setHadAssign( } return Ast.Effects(eff.returnOrThrow, setSelfPaths); } -const ENoSelfAssign = (loc: Ast.Loc): E.TcError => ({ +const ENoSelfAssign = (loc: Ast.Loc): Ast.TcError => ({ loc, descr: [ - E.TEText(`Cannot assign to self`), + Ast.TEText(`Cannot assign to self`), ], }); @@ -52,7 +51,7 @@ export function* setHadExit( successful: boolean, required: undefined | ReadonlySet, returnLoc: Ast.Loc, -): E.WithLog { +): Ast.WithLog { if (successful && required) { const missing = [...required].filter(p => !eff.setSelfPaths.has(p)); for (const fieldName of missing) { @@ -61,9 +60,9 @@ export function* setHadExit( } return Ast.Effects(true, eff.setSelfPaths); } -const EMissingSelfInit = (name: string, loc: Ast.Loc): E.TcError => ({ +const EMissingSelfInit = (name: string, loc: Ast.Loc): Ast.TcError => ({ loc, descr: [ - E.TEText(`Field "self.${name}" is not initialized by this moment`), + Ast.TEText(`Field "self.${name}" is not initialized by this moment`), ], }); diff --git a/src/next/types/expr-eval.ts b/src/next/types/expr-eval.ts index d7a88f6e84..941f4afe50 100644 --- a/src/next/types/expr-eval.ts +++ b/src/next/types/expr-eval.ts @@ -1,11 +1,10 @@ /* eslint-disable require-yield */ /* eslint-disable @typescript-eslint/no-unused-vars */ import * as Ast from "@/next/ast"; -import type * as E from "@/next/types/errors"; export function* evalExpr( expr: Ast.DecodedExpression, scopeRef: () => Ast.Scope, -): E.WithLog { +): Ast.WithLog { return Ast.VNumber(0n, expr.loc); } diff --git a/src/next/types/expression.ts b/src/next/types/expression.ts index 1b3a3c581e..0fd2edf138 100644 --- a/src/next/types/expression.ts +++ b/src/next/types/expression.ts @@ -1,13 +1,12 @@ /* eslint-disable require-yield */ import * as Ast from "@/next/ast"; -import * as E from "@/next/types/errors"; import { throwInternal } from "@/error/errors"; import { Bool, builtinBinary, builtinFunctions, getStaticBuiltin, StateInit } from "@/next/types/builtins"; import { assignType, dealiasType, decodeDealiasTypeLazy, decodeTypeLazy, decodeTypeMap, checkFnCall, instantiateStruct, checkFnCallWithArgs, mgu, lookupMethod } from "@/next/types/type"; import { convertValueToExpr } from "@/next/types/value"; import { emptyTypeParams } from "@/next/types/type-params"; -type Decode = (node: T, ctx: Context) => E.WithLog +type Decode = (node: T, ctx: Context) => Ast.WithLog type Context = { readonly Lazy: Ast.ThunkBuilder, readonly scopeRef: () => Ast.Scope; @@ -23,7 +22,7 @@ export function decodeExpr( scopeRef: () => Ast.Scope, selfType: Ast.SelfType | undefined, localScopeRef: ReadonlyMap, -): E.WithLog { +): Ast.WithLog { return decodeExprCtx(node, { Lazy, typeParams, @@ -80,20 +79,20 @@ const decodeBooleanCons: Decode = function* (node) { } const decodeTupleCons: Decode = function* (node, ctx) { - const children = yield* E.mapLog(node.children, child => decodeExprCtx(child, ctx)); + const children = yield* Ast.mapLog(node.children, child => decodeExprCtx(child, ctx)); const args = children.map(child => child.computedType); return Ast.DTuple(children, Ast.DTypeTuple(args, node.loc), node.loc); } const decodeTensorCons: Decode = function* (node, ctx) { - const children = yield* E.mapLog(node.children, child => decodeExprCtx(child, ctx)); + const children = yield* Ast.mapLog(node.children, child => decodeExprCtx(child, ctx)); const args = children.map(child => child.computedType); return Ast.DTensor(children, Ast.DTypeTensor(args, node.loc), node.loc); } const decodeMapCons: Decode = function* (node, ctx) { const ascribed = yield* decodeTypeMap(ctx.typeParams, node.type, ctx.scopeRef); - const fields = yield* E.mapLog(node.fields, function* (field) { + const fields = yield* Ast.mapLog(node.fields, function* (field) { const key = yield* decodeExprCtx(field.key, ctx); yield* assignType(field.key.loc, emptyTypeParams, ascribed.key, key.computedType, false); const value = yield* decodeExprCtx(field.value, ctx); @@ -108,7 +107,7 @@ const decodeSetCons: Decode = function* () { } const decodeStructCons: Decode = function* (node, ctx) { - const typeArgs = yield* E.mapLog(node.typeArgs, function* (arg) { + const typeArgs = yield* Ast.mapLog(node.typeArgs, function* (arg) { return yield* decodeTypeLazy(ctx.Lazy, ctx.typeParams, arg, ctx.scopeRef)(); }); const instance = yield* instantiateStruct( @@ -193,28 +192,28 @@ function* checkFields( return Ast.Ordered([...map.keys()], map) } } -const EMissingField = (name: string, prev: Ast.Loc): E.TcError => ({ +const EMissingField = (name: string, prev: Ast.Loc): Ast.TcError => ({ loc: prev, descr: [ - E.TEText(`Value for field "${name}" is missing`), - E.TECode(prev), + Ast.TEText(`Value for field "${name}" is missing`), + Ast.TECode(prev), ], }); -const ENoSuchField = (name: string, next: Ast.Loc): E.TcError => ({ +const ENoSuchField = (name: string, next: Ast.Loc): Ast.TcError => ({ loc: next, descr: [ - E.TEText(`There is no field "${name}"`), - E.TECode(next), + Ast.TEText(`There is no field "${name}"`), + Ast.TECode(next), ], }); -const EDuplicateField = (name: string, prev: Ast.Loc, next: Ast.Loc): E.TcError => ({ +const EDuplicateField = (name: string, prev: Ast.Loc, next: Ast.Loc): Ast.TcError => ({ loc: prev, descr: [ - E.TEText(`Duplicate field "${name}"`), - E.TEText(`Defined at:`), - E.TECode(next), - E.TEText(`Previously defined at:`), - E.TECode(prev), + Ast.TEText(`Duplicate field "${name}"`), + Ast.TEText(`Defined at:`), + Ast.TECode(next), + Ast.TEText(`Previously defined at:`), + Ast.TECode(prev), ], }); @@ -229,17 +228,17 @@ const decodeVar: Decode = function* (node, ctx) { yield ENoSelf(node.loc); return Ast.DVar(node.name, Ast.TypeNull(node.loc), node.loc); }; -const ENoSelf = (loc: Ast.Loc): E.TcError => ({ +const ENoSelf = (loc: Ast.Loc): Ast.TcError => ({ loc, descr: [ - E.TEText(`"self" is not allowed here`), + Ast.TEText(`"self" is not allowed here`), ], }); function* lookupVar( name: string, loc: Ast.Loc, ctx: Context, -): E.WithLog { +): Ast.WithLog { const local = ctx.localScopeRef.get(name); if (local) { const [type] = local; @@ -252,10 +251,10 @@ function* lookupVar( yield EUndefined(name, loc); return Ast.DTypeRecover(); } -const EUndefined = (name: string, loc: Ast.Loc): E.TcError => ({ +const EUndefined = (name: string, loc: Ast.Loc): Ast.TcError => ({ loc, descr: [ - E.TEText(`Variable "${name}" not defined`), + Ast.TEText(`Variable "${name}" not defined`), ], }); @@ -285,10 +284,10 @@ const decodeBinary: Decode = function* (node, ctx) } return Ast.DOpBinary(node.op, left, right, typeArgMap, returnType, node.loc); } -const ENoEquality = (loc: Ast.Loc): E.TcError => ({ +const ENoEquality = (loc: Ast.Loc): Ast.TcError => ({ loc, descr: [ - E.TEText(`Equality on this type is not supported`), + Ast.TEText(`Equality on this type is not supported`), ], }); const supportsEquality = (common: Ast.DecodedType): boolean => { @@ -349,7 +348,7 @@ const decodeTernary: Decode = function* (node const decodeMethodCall: Decode = function* (node, ctx) { const self = yield* decodeExprCtx(node.self, ctx); - const args = yield* E.mapLog(node.args, arg => decodeExprCtx(arg, ctx)); + const args = yield* Ast.mapLog(node.args, arg => decodeExprCtx(arg, ctx)); const { typeDecls, extensions } = ctx.scopeRef(); const { returnType, typeArgMap } = yield* lookupMethod( @@ -366,7 +365,7 @@ const decodeMethodCall: Decode = function* (nod const decodeFunctionCall: Decode = function* (node, ctx) { const name = node.function; - const args = yield* E.mapLog(node.args, arg => decodeExprCtx(arg, ctx)); + const args = yield* Ast.mapLog(node.args, arg => decodeExprCtx(arg, ctx)); if (name.text === 'sha256') { const [arg] = args; @@ -388,7 +387,7 @@ const decodeFunctionCall: Decode ({ +const EMismatchSha256 = (loc: Ast.Loc): Ast.TcError => ({ loc, descr: [ - E.TEText(`sha256() takes either Slice or String`), + Ast.TEText(`sha256() takes either Slice or String`), ], }); @@ -416,7 +415,7 @@ const decodeStaticMethodCall: Decode 0) { yield EFunctionArity(node.loc); } - const args = yield* E.mapLog(node.args, arg => decodeExprCtx(arg, ctx)); + const args = yield* Ast.mapLog(node.args, arg => decodeExprCtx(arg, ctx)); const selfDecl = ctx.scopeRef().typeDecls.get(node.self.text); if (selfDecl?.decl.kind === 'struct' || selfDecl?.decl.kind === 'message') { const builtins = getStaticBuiltin(Ast.DTypeRef(node.self, selfDecl.decl, [], node.loc)); @@ -438,16 +437,16 @@ const decodeStaticMethodCall: Decode ({ +const EUndefinedStatic = (name: string, loc: Ast.Loc): Ast.TcError => ({ loc, descr: [ - E.TEText(`Static method ${name} doesn't exist`), + Ast.TEText(`Static method ${name} doesn't exist`), ], }); -const EFunctionArity = (loc: Ast.Loc): E.TcError => ({ +const EFunctionArity = (loc: Ast.Loc): Ast.TcError => ({ loc, descr: [ - E.TEText(`Function doesn't take any generic arguments`), + Ast.TEText(`Function doesn't take any generic arguments`), ], }); @@ -462,7 +461,7 @@ function* lookupField( selfType: Ast.DecodedType, fieldName: Ast.Id, scopeRef: () => Ast.Scope, -): E.WithLog { +): Ast.WithLog { switch (selfType.kind) { case "type_ref": { const decl = selfType.type; @@ -543,7 +542,7 @@ function* lookupField( } const decodeInitOf: Decode = function* (node, ctx) { - const args = yield* E.mapLog(node.args, arg => decodeExprCtx(arg, ctx)); + const args = yield* Ast.mapLog(node.args, arg => decodeExprCtx(arg, ctx)); const contract = ctx.scopeRef().typeDecls.get(node.contract.text); if (contract?.decl.kind !== 'contract') { yield ENotContract(node.contract.text, node.loc); @@ -558,7 +557,7 @@ const decodeInitOf: Decode = function* (node, ctx) { params, ctx.Lazy({ callback: function*() { return StateInit; }, - context: [E.TEText("checking initOf expression")], + context: [Ast.TEText("checking initOf expression")], loc: node.loc, recover: StateInit, }) @@ -603,9 +602,9 @@ const decodeCodeOf: Decode = function* (node, ctx) { } return Ast.DCodeOf(node.contract, Ast.TypeCell(Ast.SFDefault(node.loc), node.loc), node.loc); } -const ENotContract = (name: string, loc: Ast.Loc): E.TcError => ({ +const ENotContract = (name: string, loc: Ast.Loc): Ast.TcError => ({ loc, descr: [ - E.TEText(`"${name}" is not a contract`), + Ast.TEText(`"${name}" is not a contract`), ], }); diff --git a/src/next/types/extensions.ts b/src/next/types/extensions.ts index c60f12ae6c..9020ce45c0 100644 --- a/src/next/types/extensions.ts +++ b/src/next/types/extensions.ts @@ -1,5 +1,4 @@ import * as Ast from "@/next/ast"; -import * as E from "@/next/types/errors"; import { zip } from "@/utils/array"; import { throwInternal } from "@/error/errors"; import { decodeFnType } from "@/next/types/type-fn"; @@ -29,7 +28,7 @@ export function decodeExtensions( Ast.ViaImport(importedBy, ext.via), )); }, - context: [E.TEText(`importing extension method ${name}`)], + context: [Ast.TEText(`importing extension method ${name}`)], loc: Ast.Builtin(), recover: [], })); @@ -53,7 +52,7 @@ export function decodeExtensions( )]; }, context: [ - E.TEText(`defining extension method ${ext.fun.name.text}`) + Ast.TEText(`defining extension method ${ext.fun.name.text}`) ], loc: ext.fun.loc, recover: [], @@ -87,7 +86,7 @@ export function decodeExtensions( } return prevs; }, - context: [E.TEText(`merging extensions methods with name ${name}`)], + context: [Ast.TEText(`merging extensions methods with name ${name}`)], loc: Ast.Builtin(), recover: [], })); @@ -141,7 +140,7 @@ function* areCompatible( name: string, prevs: readonly Ast.Decl[], next: Ast.Decl, -): E.WithLog { +): Ast.WithLog { for (const prev of prevs) { const prevType = prev.decl.type; const nextType = next.decl.type; @@ -158,11 +157,11 @@ const EMethodOverlap = ( name: string, prev: Ast.Via, next: Ast.ViaUser, -): E.TcError => ({ - loc: E.viaToRange(next), +): Ast.TcError => ({ + loc: Ast.viaToRange(next), descr: [ - E.TEText(`Method "${name}" overlaps previously defined method`), - E.TEVia(prev), + Ast.TEText(`Method "${name}" overlaps previously defined method`), + Ast.TEVia(prev), ], }); @@ -231,7 +230,7 @@ function allEqual( function* decodeSelfType( type: Ast.DecodedType, scopeRef: () => Ast.Scope, -): E.WithLog { +): Ast.WithLog { switch (type.kind) { case "recover": { return undefined; @@ -385,7 +384,7 @@ function* decodeSelfType( function* toGroundType( type: Ast.DecodedType, scopeRef: () => Ast.Scope, -): E.WithLog { +): Ast.WithLog { switch (type.kind) { case "recover": { return undefined; @@ -445,14 +444,14 @@ function* toGroundType( return child && Ast.MGTypeMaybe(child, type.loc); } case "tuple_type": { - const children = yield* E.mapLog(type.typeArgs, function* (child) { + const children = yield* Ast.mapLog(type.typeArgs, function* (child) { const result = yield* toGroundType(child, scopeRef); return result ? [result] : []; }); return Ast.MGTypeTuple(children.flat(), type.loc); } case "tensor_type": { - const children = yield* E.mapLog(type.typeArgs, function* (child) { + const children = yield* Ast.mapLog(type.typeArgs, function* (child) { const result = yield* toGroundType(child, scopeRef); return result ? [result] : []; }); @@ -480,18 +479,18 @@ function* toGroundType( const EBadMethodType = ( loc: Ast.Loc, -): E.TcError => ({ +): Ast.TcError => ({ loc, descr: [ - E.TEText(`Type of self must either have no type parameters, or be a generic type with distinct type parameters`), + Ast.TEText(`Type of self must either have no type parameters, or be a generic type with distinct type parameters`), ], }); const ENoMethods = ( kind: string, loc: Ast.Loc, -): E.TcError => ({ +): Ast.TcError => ({ loc, descr: [ - E.TEText(`Cannot define methods on ${kind}`), + Ast.TEText(`Cannot define methods on ${kind}`), ], }); \ No newline at end of file diff --git a/src/next/types/fields.ts b/src/next/types/fields.ts index c847460c8c..db88cac1ed 100644 --- a/src/next/types/fields.ts +++ b/src/next/types/fields.ts @@ -1,7 +1,6 @@ /* eslint-disable require-yield */ /* eslint-disable @typescript-eslint/no-unused-vars */ import * as Ast from "@/next/ast"; -import * as E from "@/next/types/errors"; import { throwInternal } from "@/error/errors"; import { decodeTypeLazy } from "@/next/types/type"; import { checkFieldOverride } from "@/next/types/override"; @@ -19,7 +18,7 @@ export function* getFieldishGeneral( constants: readonly Ast.FieldConstant[], fields: readonly Ast.FieldDecl[], scopeRef: () => Ast.Scope, -): E.WithLog>>> { +): Ast.WithLog>>> { // collect all inherited fields and constants const inherited: Map>> = new Map(); for (const { via, decl: { fieldish } } of traits) { @@ -35,7 +34,7 @@ export function* getFieldishGeneral( ); const prev = inherited.get(name); if (prev) { - yield E.ERedefineMember(name, prev.via, nextVia); + yield Ast.ERedefineMember(name, prev.via, nextVia); } else { inherited.set(name, Ast.DeclMem(field.decl, nextVia)); } @@ -65,7 +64,7 @@ export function* getFieldishGeneral( const prev = all.get(name.text); if (prev) { // duplicate local field - yield E.ERedefineMember(name.text, prev.via, nextVia); + yield Ast.ERedefineMember(name.text, prev.via, nextVia); } // remember order of fields @@ -88,7 +87,7 @@ export function* getFieldishGeneral( if (prevInh.decl.kind !== 'field') { // cannot override constant with field - yield E.ERedefineMember(name.text, prevInh.via, nextVia); + yield Ast.ERedefineMember(name.text, prevInh.via, nextVia); } } } @@ -101,7 +100,7 @@ export function* getFieldishGeneral( const prev = all.get(name.text); if (prev) { // duplicate local constant - yield E.ERedefineMember(name.text, prev.via, nextVia); + yield Ast.ERedefineMember(name.text, prev.via, nextVia); } // we mostly need this for technical reasons: @@ -191,11 +190,11 @@ function decodeField( const EMustCopyField = ( name: string, prev: Ast.ViaMember, -): E.TcError => ({ +): Ast.TcError => ({ loc: prev.defLoc, descr: [ - E.TEText(`Field "${name}" was defined in parent trait, but never mentioned`), - E.TEViaMember(prev), + Ast.TEText(`Field "${name}" was defined in parent trait, but never mentioned`), + Ast.TEViaMember(prev), ], }); @@ -206,7 +205,7 @@ function* decodeConstant( nextVia: Ast.ViaMember, scopeRef: () => Ast.Scope, selfType: Ast.SelfType, -): E.WithLog>> { +): Ast.WithLog>> { if (init.kind === 'constant_decl') { const type = decodeTypeLazy(Lazy, emptyTypeParams, init.type, scopeRef); return Ast.DeclMem( diff --git a/src/next/types/functions.ts b/src/next/types/functions.ts index fd64c27f4a..5ecf0347aa 100644 --- a/src/next/types/functions.ts +++ b/src/next/types/functions.ts @@ -1,7 +1,6 @@ /* eslint-disable require-yield */ /* eslint-disable @typescript-eslint/no-unused-vars */ import * as Ast from "@/next/ast"; -import * as E from "@/next/types/errors"; import type { TactSource } from "@/next/imports/source"; import { builtinFunctions } from "@/next/types/builtins"; import { decodeFnType } from "@/next/types/type-fn"; @@ -14,7 +13,7 @@ export function* decodeFunctions( imported: readonly Ast.SourceCheckResult[], source: TactSource, scopeRef: () => Ast.Scope, -): E.WithLog>> { +): Ast.WithLog>> { const allFnSigs = [ // imported ...imported.flatMap(({ globals, importedBy }) => ( @@ -25,7 +24,7 @@ export function* decodeFunctions( ] as const) )), // local - ...yield* E.mapLog(source.items.functions, function* (fn) { + ...yield* Ast.mapLog(source.items.functions, function* (fn) { return [ fn.name.text, Ast.Decl( @@ -41,7 +40,7 @@ export function* decodeFunctions( for (const [name, sig] of allFnSigs) { const isBuiltin = builtinFunctions.has(name); if (isBuiltin) { - yield E.ERedefine(errorKind, name, Ast.ViaBuiltin(), sig.via); + yield Ast.ERedefine(errorKind, name, Ast.ViaBuiltin(), sig.via); continue; } const prev = filteredSigs.get(name); @@ -50,7 +49,7 @@ export function* decodeFunctions( continue; } if (prev.via.source !== sig.via.source) { - yield E.ERedefine(errorKind, name, sig.via, prev.via); + yield Ast.ERedefine(errorKind, name, sig.via, prev.via); } } return filteredSigs; diff --git a/src/next/types/lvalue.ts b/src/next/types/lvalue.ts index 4c76a56487..136b72099d 100644 --- a/src/next/types/lvalue.ts +++ b/src/next/types/lvalue.ts @@ -1,8 +1,7 @@ /* eslint-disable require-yield */ import * as Ast from "@/next/ast"; -import * as E from "@/next/types/errors"; -export function* convertExprToLValue(node: Ast.DecodedExpression): E.WithLog { +export function* convertExprToLValue(node: Ast.DecodedExpression): Ast.WithLog { switch (node.kind) { case "field_access": { const aggregate = yield* convertExprToLValue(node.aggregate); @@ -43,10 +42,10 @@ export function* convertExprToLValue(node: Ast.DecodedExpression): E.WithLog ({ +const ENotLValue = (prev: Ast.Loc): Ast.TcError => ({ loc: prev, descr: [ - E.TEText(`This expression cannot be used on the left side of assignment`), - E.TECode(prev), + Ast.TEText(`This expression cannot be used on the left side of assignment`), + Ast.TECode(prev), ], }); \ No newline at end of file diff --git a/src/next/types/message.ts b/src/next/types/message.ts index e31962c37e..9d5b22089e 100644 --- a/src/next/types/message.ts +++ b/src/next/types/message.ts @@ -3,7 +3,6 @@ import { throwInternal } from "@/error/errors"; import * as Ast from "@/next/ast"; import { Int } from "@/next/types/builtins"; -import * as E from "@/next/types/errors"; import { evalExpr } from "@/next/types/expr-eval"; import { decodeExpr } from "@/next/types/expression"; import { decodeFields } from "@/next/types/struct-fields"; @@ -15,7 +14,7 @@ export function* decodeMessage( Lazy: Ast.ThunkBuilder, message: Ast.MessageDecl, scopeRef: () => Ast.Scope, -): E.WithLog { +): Ast.WithLog { const fields = yield* decodeFields( Lazy, message.fields, @@ -41,7 +40,7 @@ export function* decodeMessage( } return opcode; }, - context: [E.TEText("computing opcode")], + context: [Ast.TEText("computing opcode")], loc: message.loc, recover: undefined, }); @@ -50,26 +49,26 @@ export function* decodeMessage( } const EZero = ( next: Ast.Loc, -): E.TcError => ({ +): Ast.TcError => ({ loc: next, descr: [ - E.TEText(`Zero opcode is reserved for text comments`), + Ast.TEText(`Zero opcode is reserved for text comments`), ], }); const ENegative = ( next: Ast.Loc, -): E.TcError => ({ +): Ast.TcError => ({ loc: next, descr: [ - E.TEText(`Opcode must be positive`), + Ast.TEText(`Opcode must be positive`), ], }); const ETooLarge = ( next: Ast.Loc, -): E.TcError => ({ +): Ast.TcError => ({ loc: next, descr: [ - E.TEText(`Opcode is too large`), + Ast.TEText(`Opcode is too large`), ], }); diff --git a/src/next/types/methods.ts b/src/next/types/methods.ts index 41502956e0..66d7a95fce 100644 --- a/src/next/types/methods.ts +++ b/src/next/types/methods.ts @@ -1,7 +1,6 @@ /* eslint-disable require-yield */ /* eslint-disable @typescript-eslint/no-unused-vars */ import * as Ast from "@/next/ast"; -import * as E from "@/next/types/errors"; import { decodeBody } from "@/next/types/body"; import { decodeFnType } from "@/next/types/type-fn"; import { checkMethodOverride } from "@/next/types/override"; @@ -19,7 +18,7 @@ export function* getMethodsGeneral( traits: readonly Ast.Decl[], methods: readonly Ast.Method[], scopeRef: () => Ast.Scope, -): E.WithLog>>> { +): Ast.WithLog>>> { // collect all inherited methods const inherited: Map>> = new Map(); for (const { via, decl: { methods } } of traits) { @@ -31,7 +30,7 @@ export function* getMethodsGeneral( ); const prev = inherited.get(name); if (prev) { - yield E.ERedefineMember(name, prev.via, nextVia); + yield Ast.ERedefineMember(name, prev.via, nextVia); } else { inherited.set(name, Ast.DeclMem( method.decl, @@ -117,10 +116,10 @@ export function* getMethodsGeneral( return all; } -const EGenericMethod = (loc: Ast.Loc): E.TcError => ({ +const EGenericMethod = (loc: Ast.Loc): Ast.TcError => ({ loc, descr: [ - E.TEText(`Method cannot be generic`), + Ast.TEText(`Method cannot be generic`), ], }); @@ -144,7 +143,7 @@ function decodeGetLazy( scopeRef, selfType, ), - context: [E.TEText("checking get() opcode")], + context: [Ast.TEText("checking get() opcode")], loc: get.loc, recover: undefined, }); @@ -157,7 +156,7 @@ function* decodeGet( get: Ast.GetAttribute, scopeRef: () => Ast.Scope, selfType: Ast.SelfType, -): E.WithLog { +): Ast.WithLog { if (get.methodId) { const expr = yield* decodeExpr( Lazy, @@ -212,21 +211,21 @@ function* checkMethodId(methodId: bigint, loc: Ast.Loc) { } } -const EBadId = (loc: Ast.Loc): E.TcError => ({ +const EBadId = (loc: Ast.Loc): Ast.TcError => ({ loc, descr: [ - E.TEText(`Method ids must fit 19-bit signed integer range`), + Ast.TEText(`Method ids must fit 19-bit signed integer range`), ], }); -const EReservedTvmId = (loc: Ast.Loc): E.TcError => ({ +const EReservedTvmId = (loc: Ast.Loc): Ast.TcError => ({ loc, descr: [ - E.TEText(`Method ids cannot overlap with the TVM reserved ids: -4, -3, -2, -1, 0 ... 2^14 - 1`), + Ast.TEText(`Method ids cannot overlap with the TVM reserved ids: -4, -3, -2, -1, 0 ... 2^14 - 1`), ], }); -const EReservedTactId = (loc: Ast.Loc, tactMethodIds: readonly bigint[]): E.TcError => ({ +const EReservedTactId = (loc: Ast.Loc, tactMethodIds: readonly bigint[]): Ast.TcError => ({ loc, descr: [ - E.TEText(`Method ids cannot overlap with Tact reserved method ids: ${tactMethodIds.map((n) => n.toString()).join(", ")}`), + Ast.TEText(`Method ids cannot overlap with Tact reserved method ids: ${tactMethodIds.map((n) => n.toString()).join(", ")}`), ], }); \ No newline at end of file diff --git a/src/next/types/override.ts b/src/next/types/override.ts index 802ff261e2..50d589cc60 100644 --- a/src/next/types/override.ts +++ b/src/next/types/override.ts @@ -1,5 +1,4 @@ -import type * as Ast from "@/next/ast"; -import * as E from "@/next/types/errors"; +import * as Ast from "@/next/ast"; import { assignMethodType, assignType } from "@/next/types/type"; import { emptyTypeParams } from "@/next/types/type-params"; @@ -11,11 +10,11 @@ export function* checkFieldOverride( nextType: Ast.Thunk, nextVia: Ast.ViaMember, override: boolean, -): E.WithLog { +): Ast.WithLog { if (prev) { if (prev.decl.kind !== 'constant') { // cannot override field with constant - yield E.ERedefineMember(name, prev.via, nextVia); + yield Ast.ERedefineMember(name, prev.via, nextVia); } else if (override) { // overriding without override yield ENeedOverride(name, prev.via, nextVia); @@ -48,7 +47,7 @@ export function* checkMethodOverride( nextType: Ast.DecodedMethodType, nextVia: Ast.ViaMember, override: boolean, -): E.WithLog { +): Ast.WithLog { if (prev) { if (override) { // overriding without override @@ -79,14 +78,14 @@ const ENeedOverride = ( name: string, prev: Ast.ViaMember, next: Ast.ViaMember, -): E.TcError => ({ +): Ast.TcError => ({ loc: next.defLoc, descr: [ - E.TEText(`Overriding "${name}" without "override"`), - E.TEText(`First defined at`), - E.TEViaMember(prev), - E.TEText(`Redefined at`), - E.TEViaMember(next), + Ast.TEText(`Overriding "${name}" without "override"`), + Ast.TEText(`First defined at`), + Ast.TEViaMember(prev), + Ast.TEText(`Redefined at`), + Ast.TEViaMember(next), ], }); @@ -94,24 +93,24 @@ const ENeedAbstract = ( name: string, prev: Ast.ViaMember, next: Ast.ViaMember, -): E.TcError => ({ +): Ast.TcError => ({ loc: next.defLoc, descr: [ - E.TEText(`To override "${name}" it has to be "virtual" or "abstract"`), - E.TEText(`First defined at`), - E.TEViaMember(prev), - E.TEText(`Redefined at`), - E.TEViaMember(next), + Ast.TEText(`To override "${name}" it has to be "virtual" or "abstract"`), + Ast.TEText(`First defined at`), + Ast.TEViaMember(prev), + Ast.TEText(`Redefined at`), + Ast.TEViaMember(next), ], }); const EEmptyOverride = ( name: string, next: Ast.ViaMember, -): E.TcError => ({ +): Ast.TcError => ({ loc: next.defLoc, descr: [ - E.TEText(`To override "${name}" it has to exist`), - E.TEViaMember(next), + Ast.TEText(`To override "${name}" it has to exist`), + Ast.TEViaMember(next), ], }); \ No newline at end of file diff --git a/src/next/types/receivers.ts b/src/next/types/receivers.ts index bd751f2590..99e9bb7eee 100644 --- a/src/next/types/receivers.ts +++ b/src/next/types/receivers.ts @@ -2,7 +2,6 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ import * as Ast from "@/next/ast"; import { Void } from "@/next/types/builtins"; -import * as E from "@/next/types/errors"; import { decodeStatementsLazy } from "@/next/types/statements"; import { decodeDealiasTypeLazy } from "@/next/types/type"; import { emptyTypeParams } from "@/next/types/type-params"; @@ -14,7 +13,7 @@ export function* getReceivers( traits: readonly Ast.Decl[], receivers: readonly Ast.Receiver[], scopeRef: () => Ast.Scope, -): E.WithLog { +): Ast.WithLog { const impExternals: Ast.Decl[] = []; const impInternals: Ast.Decl[] = []; const impBounces: Ast.Decl[] = []; @@ -80,7 +79,7 @@ function* mergeReceivers( imported: readonly Ast.Decl[], local: Ast.DeclMem[], scopeRef: () => Ast.Scope, -): E.WithLog { +): Ast.WithLog { const allMessage: Ast.DeclMem[] = []; let allMessageAny: undefined | Ast.DeclMem; let allStringAny: undefined | Ast.DeclMem; @@ -200,7 +199,7 @@ function* mergeBounce( imported: readonly Ast.Decl[], local: readonly Ast.DeclMem<[Ast.TypedParameter, readonly Ast.Statement[]]>[], scopeRef: () => Ast.Scope -): E.WithLog { +): Ast.WithLog { const allMessage: Ast.DeclMem[] = []; let allMessageAny: undefined | Ast.DeclMem; @@ -265,10 +264,10 @@ function* mergeBounce( const EInvalidRecv = ( loc: Ast.Loc, -): E.TcError => ({ +): Ast.TcError => ({ loc, descr: [ - E.TEText(`Receiver's parameter must be a message type, Slice, or String`), + Ast.TEText(`Receiver's parameter must be a message type, Slice, or String`), ], }); @@ -276,13 +275,13 @@ const ERedefineReceiver = ( kind: string, prev: Ast.ViaMember, next: Ast.ViaMember, -): E.TcError => ({ +): Ast.TcError => ({ loc: next.defLoc, descr: [ - E.TEText(`There already is a ${kind} receiver`), - E.TEText(`First defined at`), - E.TEViaMember(prev), - E.TEText(`Redefined at`), - E.TEViaMember(next), + Ast.TEText(`There already is a ${kind} receiver`), + Ast.TEText(`First defined at`), + Ast.TEViaMember(prev), + Ast.TEText(`Redefined at`), + Ast.TEViaMember(next), ], }); \ No newline at end of file diff --git a/src/next/types/statements.ts b/src/next/types/statements.ts index 84fbaac1e4..cbadc43c0b 100644 --- a/src/next/types/statements.ts +++ b/src/next/types/statements.ts @@ -2,7 +2,6 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ /* eslint-disable @typescript-eslint/no-unused-expressions */ import * as Ast from "@/next/ast"; -import * as E from "@/next/types/errors"; import { throwInternal } from "@/error/errors"; import { Bool, builtinAugmented, Int, Void } from "@/next/types/builtins"; import { decodeExprCtx } from "@/next/types/expression"; @@ -39,7 +38,7 @@ export function decodeStatementsLazy( const res = yield* decodeStmts(statements, ctx, emptyEff); return Ast.StatementsAux(res.node, res.effects); }, - context: [E.TEText("checking statements")], + context: [Ast.TEText("checking statements")], loc, recover: undefined, }); @@ -220,7 +219,7 @@ function* defineForVars( keyName: Ast.OptionalId, valueName: Ast.OptionalId, ctx: Context, -): E.WithLog { +): Ast.WithLog { if (type.kind === 'map_type') { const ctxKey = yield* defineVar(keyName, type.key, ctx); const ctxKV = yield* defineVar(valueName, type.value, ctxKey); @@ -242,7 +241,7 @@ function* defineForVars( const decodeDestruct: Decode = function* (node, ctx, eff) { const expr = yield* decodeExprCtx(node.expression, ctx); - const typeArgs = yield* E.mapLog(node.typeArgs, function* (arg) { + const typeArgs = yield* Ast.mapLog(node.typeArgs, function* (arg) { return yield* decodeTypeLazy(ctx.Lazy, ctx.typeParams, arg, ctx.scopeRef)(); }); @@ -271,7 +270,7 @@ function* checkFields( declFields: Ast.Ordered, ignoreUnspecifiedFields: boolean, ctx: Context, -): E.WithLog, Context]> { +): Ast.WithLog, Context]> { const order: string[] = []; const map: Map = new Map(); for (const [field, variable] of stmtFields) { @@ -316,28 +315,28 @@ function* checkFields( ); return [Ast.Ordered(order, result), ctx]; } -const EMissingField = (name: string, prev: Ast.Loc): E.TcError => ({ +const EMissingField = (name: string, prev: Ast.Loc): Ast.TcError => ({ loc: prev, descr: [ - E.TEText(`Value for field "${name}" is missing`), - E.TECode(prev), + Ast.TEText(`Value for field "${name}" is missing`), + Ast.TECode(prev), ], }); -const ENoSuchField = (name: string, next: Ast.Loc): E.TcError => ({ +const ENoSuchField = (name: string, next: Ast.Loc): Ast.TcError => ({ loc: next, descr: [ - E.TEText(`There is no field "${name}"`), - E.TECode(next), + Ast.TEText(`There is no field "${name}"`), + Ast.TECode(next), ], }); -const EDuplicateField = (name: string, prev: Ast.Loc, next: Ast.Loc): E.TcError => ({ +const EDuplicateField = (name: string, prev: Ast.Loc, next: Ast.Loc): Ast.TcError => ({ loc: prev, descr: [ - E.TEText(`Duplicate field "${name}"`), - E.TEText(`Defined at:`), - E.TECode(next), - E.TEText(`Previously defined at:`), - E.TECode(prev), + Ast.TEText(`Duplicate field "${name}"`), + Ast.TEText(`Defined at:`), + Ast.TECode(next), + Ast.TEText(`Previously defined at:`), + Ast.TECode(prev), ], }); function* findStruct( @@ -379,11 +378,11 @@ function* findStruct( } } } -const ENotDestructible = (name: string, prev: Ast.Loc): E.TcError => ({ +const ENotDestructible = (name: string, prev: Ast.Loc): Ast.TcError => ({ loc: prev, descr: [ - E.TEText(`Type "${name}" doesn't `), - E.TECode(prev), + Ast.TEText(`Type "${name}" doesn't `), + Ast.TECode(prev), ], }); @@ -396,7 +395,7 @@ type Decode = ( node: T, context: Context, effects: Ast.Effects, -) => E.WithLog> +) => Ast.WithLog> type Result = { readonly node: U; @@ -423,7 +422,7 @@ function* defineVar( node: Ast.OptionalId, type: Ast.DecodedType, ctx: Context, -): E.WithLog { +): Ast.WithLog { if (node.kind === 'wildcard') { // there is nothing to define for a wildcard return ctx; @@ -452,34 +451,34 @@ function* defineVar( localScopeRef.set(node.text, [type, node.loc]); return { ...ctx, localScopeRef }; } -const ENoDefineSelf = (loc: Ast.Loc): E.TcError => ({ +const ENoDefineSelf = (loc: Ast.Loc): Ast.TcError => ({ loc, descr: [ - E.TEText(`Cannot define a variable "self"`), + Ast.TEText(`Cannot define a variable "self"`), ], }); -const ERedefineVar = (name: string, prev: Ast.Loc, next: Ast.Loc): E.TcError => ({ +const ERedefineVar = (name: string, prev: Ast.Loc, next: Ast.Loc): Ast.TcError => ({ loc: next, descr: [ - E.TEText(`Variable ${name} is already defined`), - E.TEText(`Defined at:`), - E.TECode(next), - E.TEText(`Previously defined at:`), - E.TECode(prev), + Ast.TEText(`Variable ${name} is already defined`), + Ast.TEText(`Defined at:`), + Ast.TECode(next), + Ast.TEText(`Previously defined at:`), + Ast.TECode(prev), ], }); -const EShadowConst = (name: string, prev: Ast.Loc, next: Ast.Loc): E.TcError => ({ +const EShadowConst = (name: string, prev: Ast.Loc, next: Ast.Loc): Ast.TcError => ({ loc: next, descr: [ - E.TEText(`Variable ${name} shadows a global constant`), - E.TEText(`Defined at:`), - E.TECode(next), - E.TEText(`Previously defined at:`), - E.TECode(prev), + Ast.TEText(`Variable ${name} shadows a global constant`), + Ast.TEText(`Defined at:`), + Ast.TECode(next), + Ast.TEText(`Previously defined at:`), + Ast.TECode(prev), ], }); -function* getRequired(selfType: Ast.SelfType | undefined): E.WithLog> { +function* getRequired(selfType: Ast.SelfType | undefined): Ast.WithLog> { if (!selfType) { return new Set(); } diff --git a/src/next/types/struct-fields.ts b/src/next/types/struct-fields.ts index cd0607f2fd..445dc27102 100644 --- a/src/next/types/struct-fields.ts +++ b/src/next/types/struct-fields.ts @@ -1,7 +1,6 @@ /* eslint-disable require-yield */ /* eslint-disable @typescript-eslint/no-unused-vars */ import * as Ast from "@/next/ast"; -import * as E from "@/next/types/errors"; import { evalExpr } from "@/next/types/expr-eval"; import { decodeExpr } from "@/next/types/expression"; import { assignType, decodeTypeLazy } from "@/next/types/type"; @@ -78,7 +77,7 @@ export function decodeInitializerLazy( yield* assignType(expr.loc, emptyTypeParams, ascribed, computed, false); return yield* evalExpr(expr, scopeRef); }, - context: [E.TEText("evaluating initial field value")], + context: [Ast.TEText("evaluating initial field value")], loc, recover: undefined, }); @@ -88,13 +87,13 @@ const EDuplicateField = ( name: string, prev: Ast.Loc, next: Ast.Loc, -): E.TcError => ({ +): Ast.TcError => ({ loc: next, descr: [ - E.TEText(`Duplicate field ${name}`), - E.TEText(`New definition:`), - E.TECode(next), - E.TEText(`Previously defined at:`), - E.TECode(prev), + Ast.TEText(`Duplicate field ${name}`), + Ast.TEText(`New definition:`), + Ast.TECode(next), + Ast.TEText(`Previously defined at:`), + Ast.TECode(prev), ], }); \ No newline at end of file diff --git a/src/next/types/struct.ts b/src/next/types/struct.ts index 9ffc250510..8bb8f1ad57 100644 --- a/src/next/types/struct.ts +++ b/src/next/types/struct.ts @@ -1,7 +1,6 @@ /* eslint-disable require-yield */ /* eslint-disable @typescript-eslint/no-unused-vars */ import * as Ast from "@/next/ast"; -import type * as E from "@/next/types/errors"; import { decodeFields } from "@/next/types/struct-fields"; import { decodeTypeParams } from "@/next/types/type-params"; @@ -9,7 +8,7 @@ export function* decodeStruct( Lazy: Ast.ThunkBuilder, struct: Ast.StructDecl, scopeRef: () => Ast.Scope, -): E.WithLog { +): Ast.WithLog { const typeParams = yield* decodeTypeParams(struct.typeParams); const fields = yield* decodeFields( Lazy, diff --git a/src/next/types/trait.ts b/src/next/types/trait.ts index 36578b8a0f..9b0a392fc4 100644 --- a/src/next/types/trait.ts +++ b/src/next/types/trait.ts @@ -1,7 +1,6 @@ /* eslint-disable require-yield */ /* eslint-disable @typescript-eslint/no-unused-vars */ import * as Ast from "@/next/ast"; -import * as E from "@/next/types/errors"; import { getFieldishGeneral } from "@/next/types/fields"; import { getInheritedTraits } from "@/next/types/traits-scope"; import { getMethodsGeneral } from "@/next/types/methods"; @@ -11,7 +10,7 @@ export function* decodeTrait( Lazy: Ast.ThunkBuilder, trait: Ast.Trait, scopeRef: () => Ast.Scope, -): E.WithLog { +): Ast.WithLog { const { attributes, declarations, name, loc } = trait; const { constants, fields, methods, receivers } = declarations; @@ -60,7 +59,7 @@ export function* decodeTrait( return content; }, - context: [E.TEText("checking inner scope of trait")], + context: [Ast.TEText("checking inner scope of trait")], loc, recover, }); @@ -79,10 +78,10 @@ export function* decodeTrait( const ENoAttributes = ( loc: Ast.Loc, -): E.TcError => ({ +): Ast.TcError => ({ loc, descr: [ - E.TEText(`Traits cannot have attributes`), + Ast.TEText(`Traits cannot have attributes`), ], }); diff --git a/src/next/types/traits-scope.ts b/src/next/types/traits-scope.ts index 6005bb6785..8bd76a0633 100644 --- a/src/next/types/traits-scope.ts +++ b/src/next/types/traits-scope.ts @@ -1,12 +1,11 @@ /* eslint-disable require-yield */ /* eslint-disable @typescript-eslint/no-unused-vars */ import * as Ast from "@/next/ast"; -import * as E from "@/next/types/errors"; export function* getInheritedTraits( traits: readonly Ast.TypeId[], scopeRef: () => Ast.Scope, -): E.WithLog[]> { +): Ast.WithLog[]> { const decls = scopeRef().typeDecls; const prevTraits: Ast.Decl[] = []; for (const trait of traits) { @@ -32,18 +31,18 @@ export function* getInheritedTraits( const EUndefinedTrait = ( name: string, loc: Ast.Loc, -): E.TcError => ({ +): Ast.TcError => ({ loc, descr: [ - E.TEText(`Traits "${name}" is not defined`), + Ast.TEText(`Traits "${name}" is not defined`), ], }); const EOnlyTraits = ( loc: Ast.Loc, -): E.TcError => ({ +): Ast.TcError => ({ loc, descr: [ - E.TEText(`Can only inherit traits`), + Ast.TEText(`Can only inherit traits`), ], }); diff --git a/src/next/types/type-fn.ts b/src/next/types/type-fn.ts index e108258050..f0c3899da3 100644 --- a/src/next/types/type-fn.ts +++ b/src/next/types/type-fn.ts @@ -1,7 +1,6 @@ /* eslint-disable require-yield */ /* eslint-disable @typescript-eslint/no-unused-vars */ import * as Ast from "@/next/ast"; -import * as E from "@/next/types/errors"; import { decodeTypeParams } from "@/next/types/type-params"; import { decodeDealiasTypeLazy } from "@/next/types/type"; import { recoverName } from "@/next/types/name"; @@ -10,7 +9,7 @@ export function* decodeFnType( Lazy: Ast.ThunkBuilder, { typeParams, params, returnType }: Ast.FnType, scopeRef: () => Ast.Scope, -): E.WithLog { +): Ast.WithLog { const decodedTypeParams = yield* decodeTypeParams(typeParams); const dealias = (type: Ast.Type) => { return decodeDealiasTypeLazy(Lazy, decodedTypeParams, type, scopeRef); @@ -25,7 +24,7 @@ export function* decodeFnType( export function* decodeParams( dealias: (type: Ast.Type) => Ast.Thunk, params: readonly Ast.TypedParameter[], -): E.WithLog { +): Ast.WithLog { const order: Ast.Parameter[] = []; const set: Set = new Set(); for (const param of params) { @@ -45,7 +44,7 @@ export function* decodeParams( function* decodeParamName( node: Ast.OptionalId, set: ReadonlySet, -): E.WithLog { +): Ast.WithLog { if (node.kind === 'wildcard') { return undefined; } @@ -57,9 +56,9 @@ function* decodeParamName( return recoverName(name, set); } -const EDuplicateParam = (name: string, loc: Ast.Loc): E.TcError => ({ +const EDuplicateParam = (name: string, loc: Ast.Loc): Ast.TcError => ({ loc, descr: [ - E.TEText(`Duplicate parameter "${name}"`), + Ast.TEText(`Duplicate parameter "${name}"`), ], }); diff --git a/src/next/types/type-params.ts b/src/next/types/type-params.ts index 0ad38eacc6..c8113f7b10 100644 --- a/src/next/types/type-params.ts +++ b/src/next/types/type-params.ts @@ -1,10 +1,9 @@ import * as Ast from "@/next/ast"; -import * as E from "@/next/types/errors"; import { recoverName } from "@/next/types/name"; export const emptyTypeParams = Ast.TypeParams([], new Set()); -export function* decodeTypeParams(ids: readonly Ast.TypeId[]): E.WithLog { +export function* decodeTypeParams(ids: readonly Ast.TypeId[]): Ast.WithLog { const set: Set = new Set(); const order: Ast.TypeId[] = []; @@ -22,10 +21,10 @@ export function* decodeTypeParams(ids: readonly Ast.TypeId[]): E.WithLog ({ +const EDuplicateTypeParam = (name: string, loc: Ast.Loc): Ast.TcError => ({ loc, descr: [ - E.TEText(`Duplicate type parameter "${name}"`), + Ast.TEText(`Duplicate type parameter "${name}"`), ], }); diff --git a/src/next/types/type.ts b/src/next/types/type.ts index e5075f91be..85ecc844a6 100644 --- a/src/next/types/type.ts +++ b/src/next/types/type.ts @@ -3,7 +3,6 @@ import { throwInternal } from "@/error/errors"; import * as Ast from "@/next/ast"; import { messageBuiltin, structBuiltin } from "@/next/types/builtins"; -import * as E from "@/next/types/errors"; import { emptyTypeParams } from "@/next/types/type-params"; import { printType } from "@/next/types/type-print"; import { zip } from "@/utils/array"; @@ -19,7 +18,7 @@ export const decodeTypeLazy = ( type, scopeRef().typeDecls, ), - context: [E.TEText("checking type"), E.TECode(type.loc)], + context: [Ast.TEText("checking type"), Ast.TECode(type.loc)], loc: type.loc, recover: Ast.DTypeRecover(), }); @@ -41,7 +40,7 @@ export const decodeDealiasTypeLazy = ( scopeRef().typeDecls, ); }, - context: [E.TEText("checking type"), E.TECode(type.loc)], + context: [Ast.TEText("checking type"), Ast.TECode(type.loc)], loc: type.loc, recover: Ast.DTypeRecover(), }); @@ -86,7 +85,7 @@ export function decodeType( // decode all the types in an array function* recN( types: readonly Ast.Type[], - ): E.WithLog { + ): Ast.WithLog { const results: Ast.DecodedType[] = []; for (const type of types) { const result = yield* rec(type); @@ -98,7 +97,7 @@ export function decodeType( // decode a type function* rec( type: Ast.Type, - ): E.WithLog { + ): Ast.WithLog { switch (type.kind) { case "unit_type": case "TyInt": @@ -232,20 +231,20 @@ const getArity = (decl: Ast.TypeDeclSig): number => { const EBouncedMessage = ( loc: Ast.Loc, -): E.TcError => ({ +): Ast.TcError => ({ loc, descr: [ - E.TEText(`Only message types can be bounced<>`), + Ast.TEText(`Only message types can be bounced<>`), ], }); const ETypeNotFound = ( name: string, loc: Ast.Loc, -): E.TcError => ({ +): Ast.TcError => ({ loc, descr: [ - E.TEText(`Type "${name}" is not defined`), + Ast.TEText(`Type "${name}" is not defined`), ], }); @@ -254,7 +253,7 @@ function* matchArity( got: number, expected: number, loc: Ast.Loc, -): E.WithLog { +): Ast.WithLog { const result = got === expected; if (!result) { yield EArity(name, expected, got, loc); @@ -267,19 +266,19 @@ const EArity = ( expected: number, got: number, loc: Ast.Loc, -): E.TcError => ({ +): Ast.TcError => ({ loc, descr: [ - E.TEText(`Type "${name}" is expected to have ${expected} type arguments, got ${got}`), + Ast.TEText(`Type "${name}" is expected to have ${expected} type arguments, got ${got}`), ], }); const ETraitNotType = ( loc: Ast.Loc, -): E.TcError => ({ +): Ast.TcError => ({ loc, descr: [ - E.TEText(`Traits cannot be used as types`), + Ast.TEText(`Traits cannot be used as types`), ], }); @@ -287,13 +286,13 @@ const dealiasTypeAux = ( type: Ast.DecodedType, typeDecls: ReadonlyMap>, ) => { - function* rec(type: Ast.DecodedType): E.WithLog { + function* rec(type: Ast.DecodedType): Ast.WithLog { switch (type.kind) { case "recover": { return type; } case "type_ref": { - const args = yield* E.mapLog(type.typeArgs, rec); + const args = yield* Ast.mapLog(type.typeArgs, rec); return Ast.DTypeRef(type.name, type.type, args, type.loc); } case "TypeAlias": { @@ -306,7 +305,7 @@ const dealiasTypeAux = ( const decoded = yield* rec(substituteTypeArgs( yield* alias.decl.type(), alias.decl.typeParams, - yield* E.mapLog(type.typeArgs, rec), + yield* Ast.mapLog(type.typeArgs, rec), )); return Ast.DTypeAliasRef(decoded, type.name, type.typeArgs, type.loc); } @@ -323,11 +322,11 @@ const dealiasTypeAux = ( return Ast.DTypeMaybe(args, type.loc); } case "tuple_type": { - const args = yield* E.mapLog(type.typeArgs, rec); + const args = yield* Ast.mapLog(type.typeArgs, rec); return Ast.DTypeTuple(args, type.loc); } case "tensor_type": { - const args = yield* E.mapLog(type.typeArgs, rec); + const args = yield* Ast.mapLog(type.typeArgs, rec); return Ast.DTypeTensor(args, type.loc); } case "TyInt": @@ -436,7 +435,7 @@ export function* instantiateStruct( // NB! these are type params from enclosing scope typeParams: Ast.TypeParams, scopeRef: () => Ast.Scope, -): E.WithLog }> { +): Ast.WithLog }> { const decl = scopeRef().typeDecls.get(typeName.text); switch (decl?.decl.kind) { case undefined: { @@ -511,22 +510,22 @@ export function* instantiateStruct( } } } -const ENoSuchType = (name: string, loc: Ast.Loc): E.TcError => ({ +const ENoSuchType = (name: string, loc: Ast.Loc): Ast.TcError => ({ loc, descr: [ - E.TEText(`Type ${name} is not defined`), + Ast.TEText(`Type ${name} is not defined`), ], }); -const ENotInstantiable = (name: string, loc: Ast.Loc): E.TcError => ({ +const ENotInstantiable = (name: string, loc: Ast.Loc): Ast.TcError => ({ loc, descr: [ - E.TEText(`Cannot create value of type ${name}`), + Ast.TEText(`Cannot create value of type ${name}`), ], }); -const ETypeArity = (name: string, loc: Ast.Loc, declArity: number, useArity: number): E.TcError => ({ +const ETypeArity = (name: string, loc: Ast.Loc, declArity: number, useArity: number): Ast.TcError => ({ loc, descr: [ - E.TEText(`Type ${name} expects ${declArity} arguments, got ${useArity}`), + Ast.TEText(`Type ${name} expects ${declArity} arguments, got ${useArity}`), ], }); @@ -540,7 +539,7 @@ export function typeParamsToSubst(typeParams: Ast.TypeParams) { export function* substToTypeArgMap( loc: Ast.Loc, subst: Map -): E.WithLog { +): Ast.WithLog { const res = substToTypeArgMapAux(subst); if (res.ok) { return res.args; @@ -577,7 +576,7 @@ export function* assignType( to: Ast.DecodedType, from: Ast.DecodedType, strict: boolean, -): E.WithLog { +): Ast.WithLog { const subst = typeParamsToSubst(toFreeTypeParam); const result = assignTypeAux(to, from, subst, strict); if (result.kind === 'failure') { @@ -586,17 +585,17 @@ export function* assignType( } return yield* substToTypeArgMap(loc, subst); } -const EFreeTypeParam = (paramName: string, loc: Ast.Loc): E.TcError => ({ +const EFreeTypeParam = (paramName: string, loc: Ast.Loc): Ast.TcError => ({ loc, descr: [ - E.TEText(`No substitution for type parameter "${paramName}"`), + Ast.TEText(`No substitution for type parameter "${paramName}"`), ], }); -const EMismatch = (tree: E.MatchTree, loc: Ast.Loc): E.TcError => ({ +const EMismatch = (tree: Ast.MatchTree, loc: Ast.Loc): Ast.TcError => ({ loc, descr: [ - E.TEText(`Type mismatch`), - E.TEMismatch(tree), + Ast.TEText(`Type mismatch`), + Ast.TEMismatch(tree), ], }); @@ -607,11 +606,11 @@ type AssignSuccess = { const AssignSuccess = (): AssignSuccess => Object.freeze({ kind: 'success' }); type AssignFailure = { readonly kind: 'failure'; - readonly tree: E.MatchTree; + readonly tree: Ast.MatchTree; } -const AssignFailure = (tree: E.MatchTree): AssignFailure => Object.freeze({ kind: 'failure', tree }); +const AssignFailure = (tree: Ast.MatchTree): AssignFailure => Object.freeze({ kind: 'failure', tree }); -type Log = Generator; +type Log = Generator; export function assignTypeAux( to: Ast.DecodedType, @@ -653,7 +652,7 @@ export function assignTypeAux( from: Ast.DecodedType, ): AssignResult { const gen = check(to, from); - const results: E.MatchTree[] = []; + const results: Ast.MatchTree[] = []; for (; ;) { const res = gen.next(); if (!res.done) { @@ -671,7 +670,7 @@ export function assignTypeAux( // because it resulted from another error return AssignSuccess(); } - return AssignFailure(E.MatchTree(to, from, results)); + return AssignFailure(Ast.MatchTree(to, from, results)); } } @@ -758,11 +757,11 @@ export function* mgu( left: Ast.DecodedType, right: Ast.DecodedType, loc: Ast.Loc, -): E.WithLog { +): Ast.WithLog { function* rec( left: Ast.DecodedType, right: Ast.DecodedType, - ): E.WithLog { + ): Ast.WithLog { if (right.kind === 'TypeAlias') { if (right.type.kind === 'NotDealiased') { return throwInternal("Decoder returned aliased type"); @@ -797,11 +796,11 @@ export function* mgu( return yield* rec(left, right); } -const ENotUnifiable = (tree: E.MatchTree, loc: Ast.Loc): E.TcError => ({ +const ENotUnifiable = (tree: Ast.MatchTree, loc: Ast.Loc): Ast.TcError => ({ loc, descr: [ - E.TEText(`Branches of condition have mismatched types`), - E.TEMismatch(tree), + Ast.TEText(`Branches of condition have mismatched types`), + Ast.TEMismatch(tree), ], }); @@ -814,7 +813,7 @@ export function* checkFnCall( loc: Ast.Loc, fnType: Ast.DecodedFnType | Ast.DecodedMethodType, args: readonly (readonly [Ast.Loc, Ast.DecodedType])[], -): E.WithLog { +): Ast.WithLog { const { typeParams, params, returnType } = fnType; const subst = typeParamsToSubst(typeParams); @@ -872,11 +871,11 @@ export function* checkFnCall( return { returnType: retType, typeArgMap: typeArgsMap }; } -const EMismatchArg = (name: string, tree: E.MatchTree, loc: Ast.Loc): E.TcError => ({ +const EMismatchArg = (name: string, tree: Ast.MatchTree, loc: Ast.Loc): Ast.TcError => ({ loc, descr: [ - E.TEText(`Type doesn't match type of parameter ${name}`), - E.TEMismatch(tree), + Ast.TEText(`Type doesn't match type of parameter ${name}`), + Ast.TEMismatch(tree), ], }); @@ -889,10 +888,10 @@ const EFnArity = ( expected: number, got: number, loc: Ast.Loc, -): E.TcError => ({ +): Ast.TcError => ({ loc, descr: [ - E.TEText(`${kind} is expected to have ${expected} type arguments, got ${got}`), + Ast.TEText(`${kind} is expected to have ${expected} type arguments, got ${got}`), ], }); @@ -902,7 +901,7 @@ export function* checkFnCallWithArgs( fnType: Ast.DecodedFnType | undefined, ascribedTypeArgs: readonly Ast.DecodedType[], args: readonly (readonly [Ast.Loc, Ast.DecodedType])[], -): E.WithLog { +): Ast.WithLog { if (!fnType) { yield ENoFunction(loc); return { returnType: Ast.DTypeRecover(), typeArgMap: new Map() }; @@ -926,11 +925,11 @@ export function* checkFnCallWithArgs( ), }; } -const ENoFunction = (loc: Ast.Loc): E.TcError => ({ +const ENoFunction = (loc: Ast.Loc): Ast.TcError => ({ loc, descr: [ - E.TEText(`No such function`), - E.TECode(loc), + Ast.TEText(`No such function`), + Ast.TECode(loc), ], }); @@ -952,7 +951,7 @@ function substFnType( args, ); }, - context: [E.TEText(`substituting into parameter ${getParamName(param.name, index)}`)], + context: [Ast.TEText(`substituting into parameter ${getParamName(param.name, index)}`)], loc: param.loc, recover: Ast.DTypeRecover(), }), @@ -973,7 +972,7 @@ function substFnType( args, ); }, - context: [E.TEText(`substituting into return type`)], + context: [Ast.TEText(`substituting into return type`)], loc: fnLoc, recover: Ast.DTypeRecover(), }), @@ -987,7 +986,7 @@ export function* lookupMethod( args: readonly (readonly [Ast.Loc, Ast.DecodedType])[], typeDecls: ReadonlyMap>, extensions: ReadonlyMap[]>>, -): E.WithLog { +): Ast.WithLog { if (selfType.kind === 'recover') { return { returnType: Ast.DTypeRecover(), typeArgMap: new Map() }; } @@ -1129,11 +1128,11 @@ function typeArgsToParams( return result; } -const ENoMethod = (loc: Ast.Loc): E.TcError => ({ +const ENoMethod = (loc: Ast.Loc): Ast.TcError => ({ loc, descr: [ - E.TEText(`No such method`), - E.TECode(loc), + Ast.TEText(`No such method`), + Ast.TECode(loc), ], }); @@ -1142,7 +1141,7 @@ export function* assignMethodType( next: Ast.DecodedMethodType, prevVia: Ast.ViaMember, nextVia: Ast.ViaMember -): E.WithLog { +): Ast.WithLog { const result = assignTypeAux( yield* prev.returnType(), yield* next.returnType(), @@ -1178,26 +1177,26 @@ export function* assignMethodType( } } -const EMismatchReturn = (tree: E.MatchTree, prev: Ast.Loc, next: Ast.Loc): E.TcError => ({ +const EMismatchReturn = (tree: Ast.MatchTree, prev: Ast.Loc, next: Ast.Loc): Ast.TcError => ({ loc: next, descr: [ - E.TEText(`Return type doesn't match with inherited method`), - E.TEMismatch(tree), - E.TEText(`Inherited from:`), - E.TECode(prev), - E.TEText(`Override at:`), - E.TECode(next), + Ast.TEText(`Return type doesn't match with inherited method`), + Ast.TEMismatch(tree), + Ast.TEText(`Inherited from:`), + Ast.TECode(prev), + Ast.TEText(`Override at:`), + Ast.TECode(next), ], }); -const EMismatchParam = (name: string, tree: E.MatchTree, prev: Ast.Loc, next: Ast.Loc): E.TcError => ({ +const EMismatchParam = (name: string, tree: Ast.MatchTree, prev: Ast.Loc, next: Ast.Loc): Ast.TcError => ({ loc: next, descr: [ - E.TEText(`Type of parameter ${name} doesn't match with inherited method`), - E.TEMismatch(tree), - E.TEText(`Inherited from:`), - E.TECode(prev), - E.TEText(`Override at:`), - E.TECode(next), + Ast.TEText(`Type of parameter ${name} doesn't match with inherited method`), + Ast.TEMismatch(tree), + Ast.TEText(`Inherited from:`), + Ast.TECode(prev), + Ast.TEText(`Override at:`), + Ast.TECode(next), ], }); \ No newline at end of file diff --git a/src/next/types/typecheck.ts b/src/next/types/typecheck.ts index a273c73771..75957240de 100644 --- a/src/next/types/typecheck.ts +++ b/src/next/types/typecheck.ts @@ -2,7 +2,6 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ /* eslint-disable require-yield */ // import { logDeep } from "@/utils/log-deep.build"; -import * as E from "@/next/types/errors"; import * as Ast from "@/next/ast"; import { memo } from "@/utils/tricks"; import type { ResolvedImport, TactImport, TactSource } from "@/next/imports/source"; @@ -11,11 +10,11 @@ import { decodeFunctions } from "@/next/types/functions"; import { decodeConstants } from "@/next/types/constants"; import { decodeExtensions } from "@/next/types/extensions"; -export const typecheck = (root: TactSource): [Ast.Scope, E.TcError[]] => { - const allErrors: E.TcError[] = []; +export const typecheck = (root: TactSource): [Ast.Scope, Ast.TcError[]] => { + const allErrors: Ast.TcError[] = []; const recur = memo((source: TactSource): Ast.Scope => { - const [value, errors] = E.runLog(tcSource( + const [value, errors] = Ast.runLog(tcSource( // leave only imports of .tact onlyTactImports(source.imports) .map(importedBy => ({ @@ -51,7 +50,7 @@ function* tcSource( imported: readonly Ast.SourceCheckResult[], // source for current file source: TactSource, -): E.WithLog { +): Ast.WithLog { const Lazy = Ast.thunkBuilder; const scopeRef = () => scope; const scope: Ast.Scope = { diff --git a/src/next/types/typedecl.ts b/src/next/types/typedecl.ts index 15a7c22e1b..d2f512c68f 100644 --- a/src/next/types/typedecl.ts +++ b/src/next/types/typedecl.ts @@ -1,7 +1,6 @@ /* eslint-disable require-yield */ /* eslint-disable @typescript-eslint/no-unused-vars */ import * as Ast from "@/next/ast"; -import * as E from "@/next/types/errors"; import type { TactSource } from "@/next/imports/source"; import { builtinTypes } from "@/next/types/builtins"; import { decodeAlias } from "@/next/types/alias"; @@ -18,7 +17,7 @@ export function* decodeTypeDecls( imported: readonly Ast.SourceCheckResult[], source: TactSource, scopeRef: () => Ast.Scope, -): E.WithLog>> { +): Ast.WithLog>> { const importedSigs = imported.map(({ globals, importedBy }) => ( new Map( globals.typeDecls.entries() @@ -26,7 +25,7 @@ export function* decodeTypeDecls( ) )); - const localSigs = yield* E.mapLog( + const localSigs = yield* Ast.mapLog( source.items.types, function* (decl) { const via = Ast.ViaOrigin(decl.loc, source); @@ -46,7 +45,7 @@ export function* decodeTypeDecls( const prevItem = prev.get(name); // defined in compiler if (builtinTypes.has(name)) { - yield E.ERedefine(errorKind, name, Ast.ViaBuiltin(), nextItem.via); + yield Ast.ERedefine(errorKind, name, Ast.ViaBuiltin(), nextItem.via); continue; } // not defined yet; define it now @@ -56,7 +55,7 @@ export function* decodeTypeDecls( } // already defined, and it's not a diamond situation if (prevItem.via.source !== nextItem.via.source) { - yield E.ERedefine(errorKind, name, prevItem.via, nextItem.via); + yield Ast.ERedefine(errorKind, name, prevItem.via, nextItem.via); } } } @@ -67,7 +66,7 @@ function* decodeTypeDecl( Lazy: Ast.ThunkBuilder, decl: Ast.TypeDecl, scopeRef: () => Ast.Scope, -): E.WithLog { +): Ast.WithLog { switch (decl.kind) { case "alias_decl": { return yield* decodeAlias(Lazy, decl, scopeRef); diff --git a/src/next/types/union.ts b/src/next/types/union.ts index a6f496940e..1f58c2e5ea 100644 --- a/src/next/types/union.ts +++ b/src/next/types/union.ts @@ -1,7 +1,6 @@ /* eslint-disable require-yield */ /* eslint-disable @typescript-eslint/no-unused-vars */ import * as Ast from "@/next/ast"; -import * as E from "@/next/types/errors"; import { decodeInitializerLazy } from "@/next/types/struct-fields"; import { decodeTypeLazy } from "@/next/types/type"; import { decodeTypeParams } from "@/next/types/type-params"; @@ -15,7 +14,7 @@ export function* decodeUnion( Lazy: Ast.ThunkBuilder, union: Ast.UnionDecl, scopeRef: () => Ast.Scope, -): E.WithLog { +): Ast.WithLog { const typeParams = yield* decodeTypeParams(union.typeParams); const cases: Map = new Map(); @@ -68,14 +67,14 @@ const EDuplicateCons = ( name: string, prev: Ast.Loc, next: Ast.Loc, -): E.TcError => ({ +): Ast.TcError => ({ loc: next, descr: [ - E.TEText(`Duplicate union case "${name}"`), - E.TEText(`Defined at:`), - E.TECode(next), - E.TEText(`Previously defined at:`), - E.TECode(prev), + Ast.TEText(`Duplicate union case "${name}"`), + Ast.TEText(`Defined at:`), + Ast.TECode(next), + Ast.TEText(`Previously defined at:`), + Ast.TECode(prev), ], }); @@ -83,13 +82,13 @@ const EDuplicateField = ( name: string, prev: Ast.Loc, next: Ast.Loc, -): E.TcError => ({ +): Ast.TcError => ({ loc: next, descr: [ - E.TEText(`Duplicate field "${name}"`), - E.TEText(`Defined at:`), - E.TECode(next), - E.TEText(`Previously defined at:`), - E.TECode(prev), + Ast.TEText(`Duplicate field "${name}"`), + Ast.TEText(`Defined at:`), + Ast.TECode(next), + Ast.TEText(`Previously defined at:`), + Ast.TECode(prev), ], }); \ No newline at end of file From 0bede3ab11e7eea2870c3667a769258466258d0e Mon Sep 17 00:00:00 2001 From: verytactical <186486509+verytactical@users.noreply.github.com> Date: Mon, 2 Jun 2025 06:22:11 +0400 Subject: [PATCH 35/38] fmt --- src/next/ast/allocation.ts | 74 +- src/next/ast/checked-expr.ts | 17 +- src/next/ast/checked-stmt.ts | 2 +- src/next/ast/checked.ts | 116 +- src/next/ast/common.ts | 2 +- src/next/ast/dtype.ts | 44 +- src/next/ast/effects.ts | 2 +- src/next/ast/errors.ts | 84 +- src/next/ast/generated/checked-expr.ts | 510 ++-- src/next/ast/generated/checked-stmt.ts | 294 +- src/next/ast/generated/checked.ts | 546 ++-- src/next/ast/generated/common.ts | 11 +- src/next/ast/generated/dtype.ts | 172 +- src/next/ast/generated/effects.ts | 4 +- src/next/ast/generated/expression.ts | 26 +- src/next/ast/generated/mtype.ts | 196 +- src/next/ast/generated/root.ts | 614 ++-- src/next/ast/generated/type.ts | 153 +- src/next/ast/generated/value.ts | 11 +- src/next/ast/generated/via.ts | 26 +- src/next/ast/lazy.ts | 42 +- src/next/ast/lowered.ts | 239 ++ src/next/ast/mtype.ts | 50 +- src/next/ast/root.ts | 12 +- src/next/ast/type.ts | 44 +- src/next/ast/value.ts | 6 +- src/next/ast/via.ts | 12 +- src/next/fs/proxy-fs.ts | 6 +- src/next/grammar/errors.ts | 42 +- src/next/grammar/grammar.ts | 3578 +++++++++++++++++++----- src/next/grammar/index.ts | 244 +- src/next/imports/reader.ts | 27 +- src/next/imports/source.ts | 2 +- src/next/test/_cli.build.ts | 2 +- src/next/test/_run.test.ts | 23 +- src/next/test/_test.build.ts | 21 +- src/next/test/fun-shadow-1.snap.js | 77 +- src/next/test/fun-shadow-2.snap.js | 70 +- src/next/test/fun-shadow-3.snap.js | 95 +- src/next/test/fun-shadow-4.snap.js | 95 +- src/next/test/fun-shadow-5.snap.js | 70 +- src/next/test/to-code.ts | 97 +- src/next/types/body.ts | 106 +- src/next/types/builtins.ts | 85 +- src/next/types/constant-def.ts | 25 +- src/next/types/constants.ts | 60 +- src/next/types/contract.ts | 112 +- src/next/types/effects.ts | 21 +- src/next/types/expression.ts | 458 +-- src/next/types/extensions.ts | 269 +- src/next/types/fields.ts | 63 +- src/next/types/functions.ts | 26 +- src/next/types/lvalue.ts | 23 +- src/next/types/message.ts | 40 +- src/next/types/methods.ts | 82 +- src/next/types/override.ts | 21 +- src/next/types/receivers.ts | 233 +- src/next/types/statements.ts | 496 +++- src/next/types/struct-fields.ts | 10 +- src/next/types/struct.ts | 4 +- src/next/types/tlb.ts | 2 +- src/next/types/trait.ts | 26 +- src/next/types/traits-scope.ts | 24 +- src/next/types/type-fn.ts | 14 +- src/next/types/type-params.ts | 10 +- src/next/types/type-print.ts | 31 +- src/next/types/type.ts | 565 ++-- src/next/types/typecheck.ts | 29 +- src/next/types/typedecl.ts | 55 +- src/next/types/union.ts | 20 +- src/next/types/value.ts | 13 +- src/utils/array.ts | 5 +- src/utils/log-deep.build.ts | 10 +- src/utils/tricks.ts | 60 +- 74 files changed, 7272 insertions(+), 3484 deletions(-) create mode 100644 src/next/ast/lowered.ts diff --git a/src/next/ast/allocation.ts b/src/next/ast/allocation.ts index ae78e8b84b..acd2b857ad 100644 --- a/src/next/ast/allocation.ts +++ b/src/next/ast/allocation.ts @@ -14,9 +14,9 @@ export type TlbType = | TlbRef | TlbMaybe | TlbFields - | TlbUnion + | TlbUnion; -export type TlbTypeNoRef = +export type TlbTypeNoRef = | TlbInt | TlbVarInt | TlbBool @@ -25,97 +25,97 @@ export type TlbTypeNoRef = | TlbBits | TlbMaybeNoRef | TlbFieldsNoRef - | TlbUnionNoRef + | TlbUnionNoRef; export type TlbInt = { - readonly kind: 'int'; + readonly kind: "int"; readonly sign: Ast.Signedness; readonly width: number; -} +}; export type TlbVarInt = { - readonly kind: 'varint'; + readonly kind: "varint"; readonly sign: Ast.Signedness; readonly width: Ast.VarIntWidth; -} +}; export type TlbBool = { - readonly kind: 'bool'; -} + readonly kind: "bool"; +}; export type TlbAddress = { - readonly kind: 'address'; -} + readonly kind: "address"; +}; export type TlbString = { - readonly kind: 'string'; -} + readonly kind: "string"; +}; export type TlbUnknown = { // aka ^Cell - readonly kind: 'unknown'; -} + readonly kind: "unknown"; +}; export type TlbLiteral = { - readonly kind: 'literal'; + readonly kind: "literal"; readonly width: number; readonly value: bigint; -} +}; export type TlbBits = { - readonly kind: 'ref'; + readonly kind: "ref"; readonly width: number; -} +}; export type TlbRef = { - readonly kind: 'ref'; + readonly kind: "ref"; readonly type: TlbType; -} +}; export type TlbMap = { - readonly kind: 'map'; + readonly kind: "map"; readonly key: TlbTypeNoRef; readonly value: TlbType; -} +}; export type TlbMaybe = { - readonly kind: 'maybe'; + readonly kind: "maybe"; readonly type: TlbType; -} +}; export type TlbFields = { - readonly kind: 'fields'; + readonly kind: "fields"; readonly children: readonly TlbType[]; -} +}; export type TlbUnion = { - readonly kind: 'union'; + readonly kind: "union"; readonly prefixWidth: number; readonly children: readonly TlbCase[]; -} +}; export type TlbCase = { readonly prefix: bigint; readonly type: TlbType; -} +}; export type TlbMaybeNoRef = { - readonly kind: 'maybe'; + readonly kind: "maybe"; readonly type: TlbCaseNoRef; -} +}; export type TlbFieldsNoRef = { - readonly kind: 'fields'; + readonly kind: "fields"; readonly children: readonly TlbCaseNoRef[]; -} +}; export type TlbUnionNoRef = { - readonly kind: 'union'; + readonly kind: "union"; readonly prefixWidth: number; readonly children: readonly TlbCaseNoRef[]; -} +}; export type TlbCaseNoRef = { readonly prefix: bigint; readonly type: TlbCaseNoRef; -} \ No newline at end of file +}; diff --git a/src/next/ast/checked-expr.ts b/src/next/ast/checked-expr.ts index 2a66d332ca..e49d555ea4 100644 --- a/src/next/ast/checked-expr.ts +++ b/src/next/ast/checked-expr.ts @@ -1,7 +1,11 @@ import type { Ordered, Recover } from "@/next/ast/checked"; import type { Id, Loc, TypeId } from "@/next/ast/common"; import type * as D from "@/next/ast/dtype"; -import type { BinaryOperation, NumberBase, UnaryOperation } from "@/next/ast/expression"; +import type { + BinaryOperation, + NumberBase, + UnaryOperation, +} from "@/next/ast/expression"; import type { SelfType } from "@/next/ast/mtype"; export type TypeArgs = ReadonlyMap; @@ -30,16 +34,13 @@ export type DecodedExpression = | DMapLiteral | DSetLiteral; -export type LValue = - | LVar - | LSelf - | LFieldAccess +export type LValue = LVar | LSelf | LFieldAccess; export type LSelf = { readonly kind: "self"; readonly computedType: SelfType; readonly loc: Loc; -} +}; export type LVar = { readonly kind: "var"; @@ -60,7 +61,7 @@ export type DSelf = { readonly kind: "self"; readonly computedType: SelfType; readonly loc: Loc; -} +}; export type DVar = { readonly kind: "var"; @@ -141,7 +142,7 @@ export type DThrowCall = { readonly args: readonly DecodedExpression[]; readonly computedType: D.DecodedType; readonly loc: Loc; -} +}; // builtins or top-level (module) functions export type DStaticCall = { diff --git a/src/next/ast/checked-stmt.ts b/src/next/ast/checked-stmt.ts index 77771e05e2..15627d33ec 100644 --- a/src/next/ast/checked-stmt.ts +++ b/src/next/ast/checked-stmt.ts @@ -117,7 +117,7 @@ export type DStatementDestruct = { export type DestructPattern = { readonly field: Id; readonly variable: OptionalId; -} +}; export type DStatementBlock = { readonly kind: "statement_block"; diff --git a/src/next/ast/checked.ts b/src/next/ast/checked.ts index 6335c20e45..1edd8b57ba 100644 --- a/src/next/ast/checked.ts +++ b/src/next/ast/checked.ts @@ -4,7 +4,11 @@ import type { DecodedType, DTypeRef, DTypeBounced } from "@/next/ast/dtype"; import type { Effects } from "@/next/ast/effects"; import type { Thunk } from "@/next/ast/lazy"; import type { SelfType } from "@/next/ast/mtype"; -import type { AsmInstruction, AsmShuffle, ContractAttribute } from "@/next/ast/root"; +import type { + AsmInstruction, + AsmShuffle, + ContractAttribute, +} from "@/next/ast/root"; import type { Value } from "@/next/ast/value"; import type { ViaMember, ViaUser } from "@/next/ast/via"; import type { TactImport } from "@/next/imports/source"; @@ -14,21 +18,21 @@ export type SourceCheckResult = { readonly importedBy: TactImport; // scopes that were computed from this file readonly globals: Scope; -} +}; export type Scope = { readonly typeDecls: ReadonlyMap>; readonly functions: ReadonlyMap>; readonly constants: ReadonlyMap>; readonly extensions: ReadonlyMap[]>>; -} +}; export type Decl = { readonly decl: T; readonly via: ViaUser; -} +}; -export type Recover = T | undefined +export type Recover = T | undefined; export type TypeDeclSig = | AliasSig @@ -36,25 +40,25 @@ export type TypeDeclSig = | TraitSig | StructSig | MessageSig - | UnionSig + | UnionSig; export type TypeDeclRefable = | ContractSig | TraitSig | StructSig | MessageSig - | UnionSig + | UnionSig; export type ConstSig = { readonly initializer: Thunk>; readonly type: Thunk; -} +}; export type FnSig = { readonly type: DecodedFnType; readonly inline: boolean; readonly body: Body; -} +}; export type Statements = Thunk>; @@ -63,7 +67,7 @@ export type StatementsAux = { readonly effects: Effects; }; -export type Body = TactBody | FuncBody | FiftBody +export type Body = TactBody | FuncBody | FiftBody; export type TactBody = { readonly kind: "tact"; @@ -83,84 +87,78 @@ export type ExtSig = { readonly type: DecodedMethodType; readonly inline: boolean; readonly body: Body; -} +}; export type AliasSig = { - readonly kind: 'alias'; + readonly kind: "alias"; readonly typeParams: TypeParams; readonly type: Thunk; -} +}; -export type InitSig = - | InitEmpty - | InitSimple - | InitFn +export type InitSig = InitEmpty | InitSimple | InitFn; export type InitEmpty = { - readonly kind: 'empty'; + readonly kind: "empty"; // initOf() would take 0 parameters // values to fill all the fields readonly fill: Thunk>>>>; -} +}; export type InitSimple = { - readonly kind: 'simple'; + readonly kind: "simple"; // initOf() takes these parameters and // sets them into correspondingly named fields readonly fill: Ordered; readonly loc: Loc; -} +}; export type InitFn = { - readonly kind: 'function'; + readonly kind: "function"; // here we just specify the function readonly params: Parameters; readonly statements: Statements; -} +}; export type InitParam = { readonly type: Thunk; readonly init: undefined | Thunk>; readonly loc: Loc; -} +}; export type ContractSig = { - readonly kind: 'contract'; + readonly kind: "contract"; readonly attributes: readonly ContractAttribute[]; readonly init: InitSig; readonly content: Thunk; -} -export type ContractContent = CommonSig< - Thunk>, - Body -> +}; +export type ContractContent = CommonSig>, Body>; export type TraitSig = { - readonly kind: 'trait'; + readonly kind: "trait"; readonly content: Thunk; -} +}; export type TraitContent = CommonSig< Thunk> | undefined, Body | undefined -> +>; export type CommonSig = { readonly fieldish: Ordered>>; readonly methods: ReadonlyMap>>; readonly receivers: Receivers; -} +}; export type Receivers = { readonly bounce: BounceSig; readonly internal: RecvSig; readonly external: RecvSig; -} +}; export type Fieldish = InhFieldSig | FieldConstSig; export type InhFieldSig = { - readonly kind: 'field'; - readonly type: Thunk + readonly kind: "field"; + readonly type: Thunk; readonly init: Thunk> | undefined; -} +}; export type FieldConstSig = { - readonly kind: 'constant'; + readonly kind: "constant"; readonly overridable: boolean; readonly type: Thunk; readonly init: Expr; -} +}; export type MethodSig = { readonly overridable: boolean; @@ -168,13 +166,13 @@ export type MethodSig = { readonly inline: boolean; readonly body: Body; readonly getMethodId: Thunk> | undefined; -} +}; export type BounceSig = { // NB! can't compute opcodes until all receivers are present readonly message: readonly DeclMem[]; readonly messageAny: undefined | DeclMem; -} +}; export type RecvSig = { // NB! can't compute opcodes until all receivers are present @@ -182,7 +180,7 @@ export type RecvSig = { readonly messageAny: undefined | DeclMem; readonly stringAny: undefined | DeclMem; readonly empty: undefined | DeclMem; -} +}; export type OpcodeRecv = MessageRecv | StringRecv; export type MessageRecv = { @@ -190,53 +188,53 @@ export type MessageRecv = { readonly name: OptionalId; readonly type: DTypeRef | DTypeBounced; readonly statements: Statements; -} +}; export type MessageAnyRecv = { readonly name: OptionalId; readonly statements: Statements; -} +}; export type StringRecv = { readonly kind: "string"; readonly comment: string; readonly statements: Statements; -} +}; export type StringAnyRecv = { readonly name: OptionalId; readonly statements: Statements; -} +}; export type EmptyRecv = { readonly statements: Statements; -} +}; export type DeclMem = { readonly decl: T; readonly via: ViaMember; -} +}; export type StructSig = { readonly kind: "struct"; readonly typeParams: TypeParams; readonly fields: Ordered; -} +}; export type MessageSig = { readonly kind: "message"; readonly opcode: Thunk>; readonly fields: Ordered; -} +}; export type UnionSig = { readonly kind: "union"; readonly typeParams: TypeParams; readonly cases: ReadonlyMap>; -} +}; export type DecodedFnType = { readonly kind: "DecodedFnType"; readonly typeParams: TypeParams; readonly params: Parameters; - readonly returnType: Thunk, -} + readonly returnType: Thunk; +}; export type DecodedMethodType = { readonly kind: "DecodedMethodType"; @@ -244,8 +242,8 @@ export type DecodedMethodType = { readonly typeParams: TypeParams; readonly self: SelfType; readonly params: Parameters; - readonly returnType: Thunk, -} + readonly returnType: Thunk; +}; export type DecodedParameter = { readonly name: OptionalId; @@ -256,12 +254,12 @@ export type DecodedParameter = { export type Ordered = { readonly order: readonly string[]; readonly map: ReadonlyMap; -} +}; export type Parameters = { readonly order: readonly Parameter[]; readonly set: ReadonlySet; -} +}; export type Parameter = { readonly name: OptionalId; @@ -272,4 +270,4 @@ export type Parameter = { export type TypeParams = { readonly order: readonly TypeId[]; readonly set: ReadonlySet; -} +}; diff --git a/src/next/ast/common.ts b/src/next/ast/common.ts index 5fd8dbb8f6..80622a6e06 100644 --- a/src/next/ast/common.ts +++ b/src/next/ast/common.ts @@ -10,7 +10,7 @@ export type Range = { readonly end: number; readonly path: string; readonly code: string; -} +}; export type OptionalId = Id | Wildcard; diff --git a/src/next/ast/dtype.ts b/src/next/ast/dtype.ts index 689f8ac2df..1e2dc4d2c3 100644 --- a/src/next/ast/dtype.ts +++ b/src/next/ast/dtype.ts @@ -4,7 +4,7 @@ import type * as Ast from "@/next/ast/type"; export type DNotSet = { readonly kind: "not-set"; -} +}; export type DecodedType = | DTypeRecover @@ -29,26 +29,26 @@ export type DecodedType = | DTypeString | DTypeStringBuilder; -export type DTypeInt = Ast.TypeInt -export type DTypeSlice = Ast.TypeSlice -export type DTypeCell = Ast.TypeCell -export type DTypeBuilder = Ast.TypeBuilder -export type DTypeUnit = Ast.TypeUnit -export type DTypeVoid = Ast.TypeVoid -export type DTypeNull = Ast.TypeNull -export type DTypeBool = Ast.TypeBool -export type DTypeAddress = Ast.TypeAddress -export type DTypeString = Ast.TypeString -export type DTypeStringBuilder = Ast.TypeStringBuilder +export type DTypeInt = Ast.TypeInt; +export type DTypeSlice = Ast.TypeSlice; +export type DTypeCell = Ast.TypeCell; +export type DTypeBuilder = Ast.TypeBuilder; +export type DTypeUnit = Ast.TypeUnit; +export type DTypeVoid = Ast.TypeVoid; +export type DTypeNull = Ast.TypeNull; +export type DTypeBool = Ast.TypeBool; +export type DTypeAddress = Ast.TypeAddress; +export type DTypeString = Ast.TypeString; +export type DTypeStringBuilder = Ast.TypeStringBuilder; export type DTypeStateInit = Ast.TypeStateInit; export type DTypeRecover = { readonly kind: "recover"; -} +}; export type NotDealiased = { readonly kind: "NotDealiased"; -} +}; export type DTypeRef = { readonly kind: "type_ref"; @@ -61,31 +61,31 @@ export type DTypeRef = { }; export type DTypeAliasRef = { - readonly kind: "TypeAlias" + readonly kind: "TypeAlias"; readonly name: TypeId; readonly type: NotDealiased | DecodedType; readonly typeArgs: readonly DecodedType[]; readonly loc: Loc; -} +}; export type DTypeParamRef = { - readonly kind: "TypeParam" + readonly kind: "TypeParam"; readonly name: TypeId; readonly loc: Loc; -} +}; export type DTypeBounced = { - readonly kind: "TypeBounced" + readonly kind: "TypeBounced"; // name of the message type readonly name: TypeId; readonly loc: Loc; -} +}; export type DTypeMaybe = { - readonly kind: "TypeMaybe" + readonly kind: "TypeMaybe"; readonly type: DecodedType; readonly loc: Loc; -} +}; export type DTypeMap = { readonly kind: "map_type"; diff --git a/src/next/ast/effects.ts b/src/next/ast/effects.ts index 495635e7f5..c675759257 100644 --- a/src/next/ast/effects.ts +++ b/src/next/ast/effects.ts @@ -1,4 +1,4 @@ export type Effects = { readonly returnOrThrow: boolean; readonly setSelfPaths: ReadonlySet; -} +}; diff --git a/src/next/ast/errors.ts b/src/next/ast/errors.ts index 3807935913..cf76720533 100644 --- a/src/next/ast/errors.ts +++ b/src/next/ast/errors.ts @@ -3,9 +3,11 @@ import type { DecodedType } from "@/next/ast/dtype"; import type { Loc } from "@/next/ast/common"; import type * as V from "@/next/ast/via"; -export type WithLog = Generator +export type WithLog = Generator; -export function runLog(gen: Generator): readonly [R, readonly T[]] { +export function runLog( + gen: Generator, +): readonly [R, readonly T[]] { const yields: T[] = []; for (;;) { const result = gen.next(); @@ -17,7 +19,10 @@ export function runLog(gen: Generator): readonly [R, readon } } -export function* mapLog(xs: readonly T[], f: (x: T) => WithLog): WithLog { +export function* mapLog( + xs: readonly T[], + f: (x: T) => WithLog, +): WithLog { const result: U[] = []; for (const x of xs) { result.push(yield* f(x)); @@ -25,7 +30,11 @@ export function* mapLog(xs: readonly T[], f: (x: T) => WithLog): WithLo return result; } -export function* reduceLog(xs: readonly T[], init: U, f: (acc: U, x: T) => WithLog): WithLog { +export function* reduceLog( + xs: readonly T[], + init: U, + f: (acc: U, x: T) => WithLog, +): WithLog { let acc = init; for (const x of xs) { acc = yield* f(acc, x); @@ -33,7 +42,10 @@ export function* reduceLog(xs: readonly T[], init: U, f: (acc: U, x: T) => return acc; } -export function* filterLog(xs: readonly T[], f: (x: T) => WithLog): WithLog { +export function* filterLog( + xs: readonly T[], + f: (x: T) => WithLog, +): WithLog { const result: T[] = []; for (const x of xs) { const res = yield* f(x); @@ -65,45 +77,51 @@ export type TcError = { readonly loc: Loc; // text description readonly descr: readonly TELine[]; -} +}; export type TELine = TEText | TEVia | TEViaMember | TECode | TEMismatch; export type TEText = { - readonly kind: 'text'; + readonly kind: "text"; readonly text: string; -} -export const TEText = (text: string): TEText => ({ kind: 'text', text }); +}; +export const TEText = (text: string): TEText => ({ kind: "text", text }); export type TEVia = { - readonly kind: 'via'; + readonly kind: "via"; readonly via: V.Via; -} -export const TEVia = (via: V.Via): TEVia => ({ kind: 'via', via }); +}; +export const TEVia = (via: V.Via): TEVia => ({ kind: "via", via }); export type TEViaMember = { - readonly kind: 'via-member'; + readonly kind: "via-member"; readonly via: V.ViaMember; -} -export const TEViaMember = (via: V.ViaMember): TEViaMember => ({ kind: 'via-member', via }); +}; +export const TEViaMember = (via: V.ViaMember): TEViaMember => ({ + kind: "via-member", + via, +}); export type TECode = { - readonly kind: 'code'; + readonly kind: "code"; readonly loc: Loc; -} -export const TECode = (loc: Loc): TECode => ({ kind: 'code', loc }); +}; +export const TECode = (loc: Loc): TECode => ({ kind: "code", loc }); export type TEMismatch = { - readonly kind: 'mismatch'; + readonly kind: "mismatch"; readonly tree: MatchTree; -} -export const TEMismatch = (tree: MatchTree): TEMismatch => ({ kind: 'mismatch', tree }); +}; +export const TEMismatch = (tree: MatchTree): TEMismatch => ({ + kind: "mismatch", + tree, +}); export type MatchTree = { readonly expected: DecodedType; readonly got: DecodedType; readonly children: readonly MatchTree[]; -} +}; export const MatchTree = ( expected: DecodedType, got: DecodedType, @@ -112,22 +130,26 @@ export const MatchTree = ( export const viaToRange = ({ imports, defLoc: definedAt }: V.ViaUser): Loc => { const [head] = imports; - if (typeof head === 'undefined') { + if (typeof head === "undefined") { return definedAt; } const { loc } = head; - if (loc.kind === 'range') { + if (loc.kind === "range") { return loc; } - return throwInternal("Implicit import shadows something. Duplicates in stdlib?"); + return throwInternal( + "Implicit import shadows something. Duplicates in stdlib?", + ); }; -export const ERedefine = (kind: string, name: string, prev: V.Via, next: V.ViaUser): TcError => ({ +export const ERedefine = ( + kind: string, + name: string, + prev: V.Via, + next: V.ViaUser, +): TcError => ({ loc: viaToRange(next), - descr: [ - TEText(`There already is a ${kind} "${name}" from`), - TEVia(prev), - ], + descr: [TEText(`There already is a ${kind} "${name}" from`), TEVia(prev)], }); export const ERedefineMember = ( @@ -143,4 +165,4 @@ export const ERedefineMember = ( TEText(`Redefined at`), TEViaMember(next), ], -}); \ No newline at end of file +}); diff --git a/src/next/ast/generated/checked-expr.ts b/src/next/ast/generated/checked-expr.ts index a23609acbc..c2a30c6a35 100644 --- a/src/next/ast/generated/checked-expr.ts +++ b/src/next/ast/generated/checked-expr.ts @@ -7,227 +7,371 @@ import type * as $e from "@/next/ast/expression"; import type { SelfType } from "@/next/ast/mtype"; export type DCodeOf = $.DCodeOf; -export const DCodeOf = (contract: $c.TypeId, computedType: $d.DecodedType, loc: $c.Loc): $.DCodeOf => Object.freeze({ - kind: "code_of", - contract, - computedType, - loc -}); +export const DCodeOf = ( + contract: $c.TypeId, + computedType: $d.DecodedType, + loc: $c.Loc, +): $.DCodeOf => + Object.freeze({ + kind: "code_of", + contract, + computedType, + loc, + }); export const isDCodeOf = ($value: DCodeOf) => $value.kind === "code_of"; export type DNumber = $.DNumber; -export const DNumber = (base: $e.NumberBase, value: bigint, computedType: $d.DTypeInt, loc: $c.Loc): $.DNumber => Object.freeze({ - kind: "number", - base, - value, - computedType, - loc -}); +export const DNumber = ( + base: $e.NumberBase, + value: bigint, + computedType: $d.DTypeInt, + loc: $c.Loc, +): $.DNumber => + Object.freeze({ + kind: "number", + base, + value, + computedType, + loc, + }); export const isDNumber = ($value: DNumber) => $value.kind === "number"; export type DBoolean = $.DBoolean; -export const DBoolean = (value: boolean, computedType: $d.DTypeBool, loc: $c.Loc): $.DBoolean => Object.freeze({ - kind: "boolean", - value, - computedType, - loc -}); +export const DBoolean = ( + value: boolean, + computedType: $d.DTypeBool, + loc: $c.Loc, +): $.DBoolean => + Object.freeze({ + kind: "boolean", + value, + computedType, + loc, + }); export const isDBoolean = ($value: DBoolean) => $value.kind === "boolean"; export type DNull = $.DNull; -export const DNull = (computedType: $d.DTypeNull, loc: $c.Loc): $.DNull => Object.freeze({ - kind: "null", - computedType, - loc -}); +export const DNull = (computedType: $d.DTypeNull, loc: $c.Loc): $.DNull => + Object.freeze({ + kind: "null", + computedType, + loc, + }); export const isDNull = ($value: DNull) => $value.kind === "null"; export type DString = $.DString; -export const DString = (value: string, computedType: $d.DTypeString, loc: $c.Loc): $.DString => Object.freeze({ - kind: "string", - value, - computedType, - loc -}); +export const DString = ( + value: string, + computedType: $d.DTypeString, + loc: $c.Loc, +): $.DString => + Object.freeze({ + kind: "string", + value, + computedType, + loc, + }); export const isDString = ($value: DString) => $value.kind === "string"; export type DVar = $.DVar; -export const DVar = (name: string, computedType: $d.DecodedType, loc: $c.Loc): $.DVar => Object.freeze({ - kind: "var", - name, - computedType, - loc -}); +export const DVar = ( + name: string, + computedType: $d.DecodedType, + loc: $c.Loc, +): $.DVar => + Object.freeze({ + kind: "var", + name, + computedType, + loc, + }); export const isDVar = ($value: DVar) => $value.kind === "var"; export type DSelf = $.DSelf; -export const DSelf = (computedType: SelfType, loc: $c.Loc): $.DSelf => Object.freeze({ - kind: "self", - computedType, - loc -}); +export const DSelf = (computedType: SelfType, loc: $c.Loc): $.DSelf => + Object.freeze({ + kind: "self", + computedType, + loc, + }); export const isDSelf = ($value: DSelf) => $value.kind === "self"; export type DUnit = $.DUnit; -export const DUnit = (computedType: $d.DTypeUnit, loc: $c.Loc): $.DUnit => Object.freeze({ - kind: "unit", - computedType, - loc -}); +export const DUnit = (computedType: $d.DTypeUnit, loc: $c.Loc): $.DUnit => + Object.freeze({ + kind: "unit", + computedType, + loc, + }); export const isDUnit = ($value: DUnit) => $value.kind === "unit"; export type DSetLiteral = $.DSetLiteral; -export const DSetLiteral = (valueType: $d.DecodedType, computedType: $d.DecodedType, fields: readonly $.DecodedExpression[], loc: $c.Loc): $.DSetLiteral => Object.freeze({ - kind: "set_literal", - valueType, - fields, - computedType, - loc -}); -export const isDSetLiteral = ($value: DSetLiteral) => $value.kind === "set_literal"; +export const DSetLiteral = ( + valueType: $d.DecodedType, + computedType: $d.DecodedType, + fields: readonly $.DecodedExpression[], + loc: $c.Loc, +): $.DSetLiteral => + Object.freeze({ + kind: "set_literal", + valueType, + fields, + computedType, + loc, + }); +export const isDSetLiteral = ($value: DSetLiteral) => + $value.kind === "set_literal"; export type DMapField = $.DMapField; -export const DMapField = (key: $.DecodedExpression, value: $.DecodedExpression): $.DMapField => Object.freeze({ - key, - value -}); +export const DMapField = ( + key: $.DecodedExpression, + value: $.DecodedExpression, +): $.DMapField => + Object.freeze({ + key, + value, + }); export type DMapLiteral = $.DMapLiteral; -export const DMapLiteral = (computedType: $d.DTypeMap, fields: readonly $.DMapField[], loc: $c.Loc): $.DMapLiteral => Object.freeze({ - kind: "map_literal", - fields, - computedType, - loc -}); -export const isDMapLiteral = ($value: DMapLiteral) => $value.kind === "map_literal"; +export const DMapLiteral = ( + computedType: $d.DTypeMap, + fields: readonly $.DMapField[], + loc: $c.Loc, +): $.DMapLiteral => + Object.freeze({ + kind: "map_literal", + fields, + computedType, + loc, + }); +export const isDMapLiteral = ($value: DMapLiteral) => + $value.kind === "map_literal"; export type DTensor = $.DTensor; -export const DTensor = (children: readonly $.DecodedExpression[], computedType: $d.DTypeTensor, loc: $c.Loc): $.DTensor => Object.freeze({ - kind: "tensor", - children, - computedType, - loc -}); +export const DTensor = ( + children: readonly $.DecodedExpression[], + computedType: $d.DTypeTensor, + loc: $c.Loc, +): $.DTensor => + Object.freeze({ + kind: "tensor", + children, + computedType, + loc, + }); export const isDTensor = ($value: DTensor) => $value.kind === "tensor"; export type DTuple = $.DTuple; -export const DTuple = (children: readonly $.DecodedExpression[], computedType: $d.DTypeTuple, loc: $c.Loc): $.DTuple => Object.freeze({ - kind: "tuple", - children, - computedType, - loc -}); +export const DTuple = ( + children: readonly $.DecodedExpression[], + computedType: $d.DTypeTuple, + loc: $c.Loc, +): $.DTuple => + Object.freeze({ + kind: "tuple", + children, + computedType, + loc, + }); export const isDTuple = ($value: DTuple) => $value.kind === "tuple"; export type DInitOf = $.DInitOf; -export const DInitOf = (contract: $c.TypeId, args: readonly $.DecodedExpression[], computedType: $d.DecodedType, loc: $c.Loc): $.DInitOf => Object.freeze({ - kind: "init_of", - contract, - args, - computedType, - loc -}); +export const DInitOf = ( + contract: $c.TypeId, + args: readonly $.DecodedExpression[], + computedType: $d.DecodedType, + loc: $c.Loc, +): $.DInitOf => + Object.freeze({ + kind: "init_of", + contract, + args, + computedType, + loc, + }); export const isDInitOf = ($value: DInitOf) => $value.kind === "init_of"; export type DStructInstance = $.DStructInstance; -export const DStructInstance = (fields: Ordered, computedType: $d.DTypeRef | $d.DTypeRecover, loc: $c.Loc): $.DStructInstance => Object.freeze({ - kind: "struct_instance", - fields, - computedType, - loc -}); -export const isDStructInstance = ($value: DStructInstance) => $value.kind === "struct_instance"; +export const DStructInstance = ( + fields: Ordered, + computedType: $d.DTypeRef | $d.DTypeRecover, + loc: $c.Loc, +): $.DStructInstance => + Object.freeze({ + kind: "struct_instance", + fields, + computedType, + loc, + }); +export const isDStructInstance = ($value: DStructInstance) => + $value.kind === "struct_instance"; export type DFieldAccess = $.DFieldAccess; -export const DFieldAccess = (aggregate: $.DecodedExpression, field: $c.Id, computedType: $d.DecodedType, loc: $c.Loc): $.DFieldAccess => Object.freeze({ - kind: "field_access", - aggregate, - field, - computedType, - loc -}); -export const isDFieldAccess = ($value: DFieldAccess) => $value.kind === "field_access"; +export const DFieldAccess = ( + aggregate: $.DecodedExpression, + field: $c.Id, + computedType: $d.DecodedType, + loc: $c.Loc, +): $.DFieldAccess => + Object.freeze({ + kind: "field_access", + aggregate, + field, + computedType, + loc, + }); +export const isDFieldAccess = ($value: DFieldAccess) => + $value.kind === "field_access"; export type DStaticMethodCall = $.DStaticMethodCall; -export const DStaticMethodCall = (self: $c.TypeId, typeArgs: $.TypeArgs, function_: $c.Id, args: readonly $.DecodedExpression[], computedType: $d.DecodedType, loc: $c.Loc): $.DStaticMethodCall => Object.freeze({ - kind: "static_method_call", - self, - typeArgs, - function: function_, - args, - computedType, - loc -}); -export const isDStaticMethodCall = ($value: DStaticMethodCall) => $value.kind === "static_method_call"; -export type TypeArgs = $.TypeArgs +export const DStaticMethodCall = ( + self: $c.TypeId, + typeArgs: $.TypeArgs, + function_: $c.Id, + args: readonly $.DecodedExpression[], + computedType: $d.DecodedType, + loc: $c.Loc, +): $.DStaticMethodCall => + Object.freeze({ + kind: "static_method_call", + self, + typeArgs, + function: function_, + args, + computedType, + loc, + }); +export const isDStaticMethodCall = ($value: DStaticMethodCall) => + $value.kind === "static_method_call"; +export type TypeArgs = $.TypeArgs; export type DStaticCall = $.DStaticCall; -export const DStaticCall = (function_: $c.Id, typeArgs: $.TypeArgs, args: readonly $.DecodedExpression[], computedType: $d.DecodedType, loc: $c.Loc): $.DStaticCall => Object.freeze({ - kind: "static_call", - function: function_, - typeArgs, - args, - computedType, - loc -}); -export const isDStaticCall = ($value: DStaticCall) => $value.kind === "static_call"; +export const DStaticCall = ( + function_: $c.Id, + typeArgs: $.TypeArgs, + args: readonly $.DecodedExpression[], + computedType: $d.DecodedType, + loc: $c.Loc, +): $.DStaticCall => + Object.freeze({ + kind: "static_call", + function: function_, + typeArgs, + args, + computedType, + loc, + }); +export const isDStaticCall = ($value: DStaticCall) => + $value.kind === "static_call"; export type DMethodCall = $.DMethodCall; -export const DMethodCall = (self: $.DecodedExpression, method: $c.Id, args: readonly $.DecodedExpression[], typeArgs: $.TypeArgs, computedType: $d.DecodedType, loc: $c.Loc): $.DMethodCall => Object.freeze({ - kind: "method_call", - self, - method, - typeArgs, - args, - computedType, - loc -}); -export const isDMethodCall = ($value: DMethodCall) => $value.kind === "method_call"; +export const DMethodCall = ( + self: $.DecodedExpression, + method: $c.Id, + args: readonly $.DecodedExpression[], + typeArgs: $.TypeArgs, + computedType: $d.DecodedType, + loc: $c.Loc, +): $.DMethodCall => + Object.freeze({ + kind: "method_call", + self, + method, + typeArgs, + args, + computedType, + loc, + }); +export const isDMethodCall = ($value: DMethodCall) => + $value.kind === "method_call"; export type DConditional = $.DConditional; -export const DConditional = (condition: $.DecodedExpression, thenBranch: $.DecodedExpression, elseBranch: $.DecodedExpression, computedType: $d.DecodedType, loc: $c.Loc): $.DConditional => Object.freeze({ - kind: "conditional", - condition, - thenBranch, - elseBranch, - computedType, - loc -}); -export const isDConditional = ($value: DConditional) => $value.kind === "conditional"; +export const DConditional = ( + condition: $.DecodedExpression, + thenBranch: $.DecodedExpression, + elseBranch: $.DecodedExpression, + computedType: $d.DecodedType, + loc: $c.Loc, +): $.DConditional => + Object.freeze({ + kind: "conditional", + condition, + thenBranch, + elseBranch, + computedType, + loc, + }); +export const isDConditional = ($value: DConditional) => + $value.kind === "conditional"; export type DOpUnary = $.DOpUnary; -export const DOpUnary = (op: $e.UnaryOperation, operand: $.DecodedExpression, typeArgs: ReadonlyMap, computedType: $d.DecodedType, loc: $c.Loc): $.DOpUnary => Object.freeze({ - kind: "op_unary", - op, - operand, - typeArgs, - computedType, - loc -}); +export const DOpUnary = ( + op: $e.UnaryOperation, + operand: $.DecodedExpression, + typeArgs: ReadonlyMap, + computedType: $d.DecodedType, + loc: $c.Loc, +): $.DOpUnary => + Object.freeze({ + kind: "op_unary", + op, + operand, + typeArgs, + computedType, + loc, + }); export const isDOpUnary = ($value: DOpUnary) => $value.kind === "op_unary"; export type DOpBinary = $.DOpBinary; -export const DOpBinary = (op: $e.BinaryOperation, left: $.DecodedExpression, right: $.DecodedExpression, typeArgs: ReadonlyMap, computedType: $d.DecodedType, loc: $c.Loc): $.DOpBinary => Object.freeze({ - kind: "op_binary", - op, - left, - right, - typeArgs, - computedType, - loc -}); +export const DOpBinary = ( + op: $e.BinaryOperation, + left: $.DecodedExpression, + right: $.DecodedExpression, + typeArgs: ReadonlyMap, + computedType: $d.DecodedType, + loc: $c.Loc, +): $.DOpBinary => + Object.freeze({ + kind: "op_binary", + op, + left, + right, + typeArgs, + computedType, + loc, + }); export const isDOpBinary = ($value: DOpBinary) => $value.kind === "op_binary"; export type DecodedExpression = $.DecodedExpression; export type DThrowCall = $.DThrowCall; -export const DThrowCall = (function_: $c.Id, args: readonly $.DecodedExpression[], computedType: $d.DecodedType, loc: $c.Loc): $.DThrowCall => Object.freeze({ - kind: "throw_call", - function: function_, - args, - computedType, - loc, -}); -export const isDThrowCall = ($value: DThrowCall) => $value.kind === "throw_call"; +export const DThrowCall = ( + function_: $c.Id, + args: readonly $.DecodedExpression[], + computedType: $d.DecodedType, + loc: $c.Loc, +): $.DThrowCall => + Object.freeze({ + kind: "throw_call", + function: function_, + args, + computedType, + loc, + }); +export const isDThrowCall = ($value: DThrowCall) => + $value.kind === "throw_call"; export type LVar = $.LVar; -export const LVar = (name: string, computedType: $d.DecodedType, loc: $c.Loc): $.LVar => Object.freeze({ - kind: "var", - name, - computedType, - loc -}); +export const LVar = ( + name: string, + computedType: $d.DecodedType, + loc: $c.Loc, +): $.LVar => + Object.freeze({ + kind: "var", + name, + computedType, + loc, + }); export const isLVar = ($value: LVar) => $value.kind === "var"; export type LSelf = $.LSelf; -export const LSelf = (computedType: SelfType, loc: $c.Loc): $.LSelf => Object.freeze({ - kind: "self", - computedType, - loc -}); +export const LSelf = (computedType: SelfType, loc: $c.Loc): $.LSelf => + Object.freeze({ + kind: "self", + computedType, + loc, + }); export const isLSelf = ($value: LSelf) => $value.kind === "self"; export type LFieldAccess = $.LFieldAccess; -export const LFieldAccess = (aggregate: $.LValue, field: $c.Id, computedType: $d.DecodedType, loc: $c.Loc): $.LFieldAccess => Object.freeze({ - kind: "field_access", - aggregate, - field, - computedType, - loc -}); -export const isLFieldAccess = ($value: LFieldAccess) => $value.kind === "field_access"; -export type LValue = $.LValue; \ No newline at end of file +export const LFieldAccess = ( + aggregate: $.LValue, + field: $c.Id, + computedType: $d.DecodedType, + loc: $c.Loc, +): $.LFieldAccess => + Object.freeze({ + kind: "field_access", + aggregate, + field, + computedType, + loc, + }); +export const isLFieldAccess = ($value: LFieldAccess) => + $value.kind === "field_access"; +export type LValue = $.LValue; diff --git a/src/next/ast/generated/checked-stmt.ts b/src/next/ast/generated/checked-stmt.ts index ffd863cb91..640f16445e 100644 --- a/src/next/ast/generated/checked-stmt.ts +++ b/src/next/ast/generated/checked-stmt.ts @@ -6,121 +6,211 @@ import type * as $s from "@/next/ast/statement"; import type { Ordered } from "@/next/ast/checked"; export type DStatementLet = $.DStatementLet; -export const DStatementLet = (name: $c.OptionalId, expression: $e.DecodedExpression, loc: $c.Loc): $.DStatementLet => Object.freeze({ - kind: "statement_let", - name, - expression, - loc -}); -export const isDStatementLet = ($value: DStatementLet) => $value.kind === "statement_let"; +export const DStatementLet = ( + name: $c.OptionalId, + expression: $e.DecodedExpression, + loc: $c.Loc, +): $.DStatementLet => + Object.freeze({ + kind: "statement_let", + name, + expression, + loc, + }); +export const isDStatementLet = ($value: DStatementLet) => + $value.kind === "statement_let"; export type DStatementReturn = $.DStatementReturn; -export const DStatementReturn = (expression: $e.DecodedExpression | undefined, loc: $c.Loc): $.DStatementReturn => Object.freeze({ - kind: "statement_return", - expression, - loc -}); -export const isDStatementReturn = ($value: DStatementReturn) => $value.kind === "statement_return"; +export const DStatementReturn = ( + expression: $e.DecodedExpression | undefined, + loc: $c.Loc, +): $.DStatementReturn => + Object.freeze({ + kind: "statement_return", + expression, + loc, + }); +export const isDStatementReturn = ($value: DStatementReturn) => + $value.kind === "statement_return"; export type DStatementExpression = $.DStatementExpression; -export const DStatementExpression = (expression: $e.DecodedExpression, loc: $c.Loc): $.DStatementExpression => Object.freeze({ - kind: "statement_expression", - expression, - loc -}); -export const isDStatementExpression = ($value: DStatementExpression) => $value.kind === "statement_expression"; +export const DStatementExpression = ( + expression: $e.DecodedExpression, + loc: $c.Loc, +): $.DStatementExpression => + Object.freeze({ + kind: "statement_expression", + expression, + loc, + }); +export const isDStatementExpression = ($value: DStatementExpression) => + $value.kind === "statement_expression"; export type DStatementAssign = $.DStatementAssign; -export const DStatementAssign = (path: $e.LValue, expression: $e.DecodedExpression, loc: $c.Loc): $.DStatementAssign => Object.freeze({ - kind: "statement_assign", - path, - expression, - loc -}); -export const isDStatementAssign = ($value: DStatementAssign) => $value.kind === "statement_assign"; +export const DStatementAssign = ( + path: $e.LValue, + expression: $e.DecodedExpression, + loc: $c.Loc, +): $.DStatementAssign => + Object.freeze({ + kind: "statement_assign", + path, + expression, + loc, + }); +export const isDStatementAssign = ($value: DStatementAssign) => + $value.kind === "statement_assign"; export type DStatementAugmentedAssign = $.DStatementAugmentedAssign; -export const DStatementAugmentedAssign = (op: $s.AugmentedAssignOperation, path: $e.LValue, expression: $e.DecodedExpression, loc: $c.Loc): $.DStatementAugmentedAssign => Object.freeze({ - kind: "statement_augmentedassign", - op, - path, - expression, - loc -}); -export const isDStatementAugmentedAssign = ($value: DStatementAugmentedAssign) => $value.kind === "statement_augmentedassign"; +export const DStatementAugmentedAssign = ( + op: $s.AugmentedAssignOperation, + path: $e.LValue, + expression: $e.DecodedExpression, + loc: $c.Loc, +): $.DStatementAugmentedAssign => + Object.freeze({ + kind: "statement_augmentedassign", + op, + path, + expression, + loc, + }); +export const isDStatementAugmentedAssign = ( + $value: DStatementAugmentedAssign, +) => $value.kind === "statement_augmentedassign"; export type DestructPattern = $.DestructPattern; -export const DestructPattern = (field: $c.Id, variable: $c.OptionalId): $.DestructPattern => Object.freeze({ - field, - variable, -}); +export const DestructPattern = ( + field: $c.Id, + variable: $c.OptionalId, +): $.DestructPattern => + Object.freeze({ + field, + variable, + }); export type DStatementDestruct = $.DStatementDestruct; -export const DStatementDestruct = (type_: $c.TypeId, identifiers: Ordered<$.DestructPattern>, ignoreUnspecifiedFields: boolean, expression: $e.DecodedExpression, loc: $c.Loc): $.DStatementDestruct => Object.freeze({ - kind: "statement_destruct", - type: type_, - identifiers, - ignoreUnspecifiedFields, - expression, - loc -}); -export const isDStatementDestruct = ($value: DStatementDestruct) => $value.kind === "statement_destruct"; +export const DStatementDestruct = ( + type_: $c.TypeId, + identifiers: Ordered<$.DestructPattern>, + ignoreUnspecifiedFields: boolean, + expression: $e.DecodedExpression, + loc: $c.Loc, +): $.DStatementDestruct => + Object.freeze({ + kind: "statement_destruct", + type: type_, + identifiers, + ignoreUnspecifiedFields, + expression, + loc, + }); +export const isDStatementDestruct = ($value: DStatementDestruct) => + $value.kind === "statement_destruct"; export type DStatementBlock = $.DStatementBlock; -export const DStatementBlock = (statements: $.DStatementList, loc: $c.Loc): $.DStatementBlock => Object.freeze({ - kind: "statement_block", - statements, - loc -}); -export const isDStatementBlock = ($value: DStatementBlock) => $value.kind === "statement_block"; +export const DStatementBlock = ( + statements: $.DStatementList, + loc: $c.Loc, +): $.DStatementBlock => + Object.freeze({ + kind: "statement_block", + statements, + loc, + }); +export const isDStatementBlock = ($value: DStatementBlock) => + $value.kind === "statement_block"; export type DStatementForEach = $.DStatementForEach; -export const DStatementForEach = (keyName: $c.OptionalId, valueName: $c.OptionalId, map: $e.DecodedExpression, statements: $.DStatementList, loc: $c.Loc): $.DStatementForEach => Object.freeze({ - kind: "statement_foreach", - keyName, - valueName, - map, - statements, - loc -}); -export const isDStatementForEach = ($value: DStatementForEach) => $value.kind === "statement_foreach"; +export const DStatementForEach = ( + keyName: $c.OptionalId, + valueName: $c.OptionalId, + map: $e.DecodedExpression, + statements: $.DStatementList, + loc: $c.Loc, +): $.DStatementForEach => + Object.freeze({ + kind: "statement_foreach", + keyName, + valueName, + map, + statements, + loc, + }); +export const isDStatementForEach = ($value: DStatementForEach) => + $value.kind === "statement_foreach"; export type DCatchBlock = $.DCatchBlock; -export const DCatchBlock = (catchName: $c.OptionalId, catchStatements: $.DStatementList): $.DCatchBlock => Object.freeze({ - name: catchName, - statements: catchStatements -}); +export const DCatchBlock = ( + catchName: $c.OptionalId, + catchStatements: $.DStatementList, +): $.DCatchBlock => + Object.freeze({ + name: catchName, + statements: catchStatements, + }); export type DStatementTry = $.DStatementTry; -export const DStatementTry = (statements: $.DStatementList, catchBlock: $.DCatchBlock | undefined, loc: $c.Loc): $.DStatementTry => Object.freeze({ - kind: "statement_try", - statements, - catchBlock, - loc -}); -export const isDStatementTry = ($value: DStatementTry) => $value.kind === "statement_try"; +export const DStatementTry = ( + statements: $.DStatementList, + catchBlock: $.DCatchBlock | undefined, + loc: $c.Loc, +): $.DStatementTry => + Object.freeze({ + kind: "statement_try", + statements, + catchBlock, + loc, + }); +export const isDStatementTry = ($value: DStatementTry) => + $value.kind === "statement_try"; export type DStatementRepeat = $.DStatementRepeat; -export const DStatementRepeat = (iterations: $e.DecodedExpression, statements: $.DStatementList, loc: $c.Loc): $.DStatementRepeat => Object.freeze({ - kind: "statement_repeat", - iterations, - statements, - loc -}); -export const isDStatementRepeat = ($value: DStatementRepeat) => $value.kind === "statement_repeat"; +export const DStatementRepeat = ( + iterations: $e.DecodedExpression, + statements: $.DStatementList, + loc: $c.Loc, +): $.DStatementRepeat => + Object.freeze({ + kind: "statement_repeat", + iterations, + statements, + loc, + }); +export const isDStatementRepeat = ($value: DStatementRepeat) => + $value.kind === "statement_repeat"; export type DStatementUntil = $.DStatementUntil; -export const DStatementUntil = (condition: $e.DecodedExpression, statements: $.DStatementList, loc: $c.Loc): $.DStatementUntil => Object.freeze({ - kind: "statement_until", - condition, - statements, - loc -}); -export const isDStatementUntil = ($value: DStatementUntil) => $value.kind === "statement_until"; +export const DStatementUntil = ( + condition: $e.DecodedExpression, + statements: $.DStatementList, + loc: $c.Loc, +): $.DStatementUntil => + Object.freeze({ + kind: "statement_until", + condition, + statements, + loc, + }); +export const isDStatementUntil = ($value: DStatementUntil) => + $value.kind === "statement_until"; export type DStatementWhile = $.DStatementWhile; -export const DStatementWhile = (condition: $e.DecodedExpression, statements: $.DStatementList, loc: $c.Loc): $.DStatementWhile => Object.freeze({ - kind: "statement_while", - condition, - statements, - loc -}); -export const isDStatementWhile = ($value: DStatementWhile) => $value.kind === "statement_while"; +export const DStatementWhile = ( + condition: $e.DecodedExpression, + statements: $.DStatementList, + loc: $c.Loc, +): $.DStatementWhile => + Object.freeze({ + kind: "statement_while", + condition, + statements, + loc, + }); +export const isDStatementWhile = ($value: DStatementWhile) => + $value.kind === "statement_while"; export type DStatementList = $.DStatementList; export type DStatementCondition = $.DStatementCondition; -export const DStatementCondition = (condition: $e.DecodedExpression, trueStatements: $.DStatementList, falseStatements: $.DStatementList | undefined, loc: $c.Loc): $.DStatementCondition => Object.freeze({ - kind: "statement_condition", - condition, - trueStatements, - falseStatements, - loc -}); -export const isDStatementCondition = ($value: DStatementCondition) => $value.kind === "statement_condition"; +export const DStatementCondition = ( + condition: $e.DecodedExpression, + trueStatements: $.DStatementList, + falseStatements: $.DStatementList | undefined, + loc: $c.Loc, +): $.DStatementCondition => + Object.freeze({ + kind: "statement_condition", + condition, + trueStatements, + falseStatements, + loc, + }); +export const isDStatementCondition = ($value: DStatementCondition) => + $value.kind === "statement_condition"; export type DecodedStatement = $.DecodedStatement; diff --git a/src/next/ast/generated/checked.ts b/src/next/ast/generated/checked.ts index 5ebb9cca26..fd33518f23 100644 --- a/src/next/ast/generated/checked.ts +++ b/src/next/ast/generated/checked.ts @@ -6,259 +6,431 @@ import type * as $v from "@/next/ast/via"; import type * as $ from "@/next/ast/checked"; import type { TactImport } from "@/next/imports/source"; import type { Thunk } from "@/next/ast/lazy"; -import type { AsmInstruction, AsmShuffle, ContractAttribute } from "@/next/ast/root"; +import type { + AsmInstruction, + AsmShuffle, + ContractAttribute, +} from "@/next/ast/root"; import type { DecodedStatement } from "@/next/ast/checked-stmt"; import type { Value } from "@/next/ast/value"; import type { Effects } from "@/next/ast/effects"; export type TypeParams = $.TypeParams; -export const TypeParams = (order: readonly $c.TypeId[], set: ReadonlySet): TypeParams => Object.freeze({ - order, - set, -}); +export const TypeParams = ( + order: readonly $c.TypeId[], + set: ReadonlySet, +): TypeParams => + Object.freeze({ + order, + set, + }); export type AliasSig = $.AliasSig; -export const AliasSig = (typeParams: $.TypeParams, type_: Thunk<$d.DecodedType>): $.AliasSig => Object.freeze({ - kind: 'alias', - typeParams, - type: type_, -}); +export const AliasSig = ( + typeParams: $.TypeParams, + type_: Thunk<$d.DecodedType>, +): $.AliasSig => + Object.freeze({ + kind: "alias", + typeParams, + type: type_, + }); export type Ordered = $.Ordered; -export const Ordered = (order: readonly string[], map: ReadonlyMap): $.Ordered => Object.freeze({ - order, - map -}); +export const Ordered = ( + order: readonly string[], + map: ReadonlyMap, +): $.Ordered => + Object.freeze({ + order, + map, + }); export type DecodedFnType = $.DecodedFnType; -export const DecodedFnType = (typeParams: $.TypeParams, params: $.Parameters, returnType: Thunk<$d.DecodedType>): $.DecodedFnType => Object.freeze({ - kind: "DecodedFnType", - typeParams, - params, - returnType -}); +export const DecodedFnType = ( + typeParams: $.TypeParams, + params: $.Parameters, + returnType: Thunk<$d.DecodedType>, +): $.DecodedFnType => + Object.freeze({ + kind: "DecodedFnType", + typeParams, + params, + returnType, + }); export type BounceSig = $.BounceSig; -export const BounceSig = (message: readonly DeclMem[], messageAny: DeclMem<$.MessageAnyRecv> | undefined): $.BounceSig => Object.freeze({ - message, - messageAny -}); +export const BounceSig = ( + message: readonly DeclMem[], + messageAny: DeclMem<$.MessageAnyRecv> | undefined, +): $.BounceSig => + Object.freeze({ + message, + messageAny, + }); export type StructSig = $.StructSig; -export const StructSig = (typeParams: $.TypeParams, fields: $.Ordered<$.InhFieldSig>): $.StructSig => Object.freeze({ - kind: "struct", - typeParams, - fields, -}); +export const StructSig = ( + typeParams: $.TypeParams, + fields: $.Ordered<$.InhFieldSig>, +): $.StructSig => + Object.freeze({ + kind: "struct", + typeParams, + fields, + }); export const isStructSig = ($value: StructSig) => $value.kind === "struct"; export type UnionSig = $.UnionSig; -export const UnionSig = (typeParams: $.TypeParams, cases: ReadonlyMap>): $.UnionSig => Object.freeze({ - kind: "union", - typeParams, - cases, -}); +export const UnionSig = ( + typeParams: $.TypeParams, + cases: ReadonlyMap>, +): $.UnionSig => + Object.freeze({ + kind: "union", + typeParams, + cases, + }); export const isUnionSig = ($value: UnionSig) => $value.kind === "union"; export type TypeDeclSig = $.TypeDeclSig; export type ConstSig = $.ConstSig; -export const ConstSig = (init: Thunk, type_: Thunk<$d.DecodedType>): $.ConstSig => Object.freeze({ - initializer: init, - type: type_, -}); +export const ConstSig = ( + init: Thunk, + type_: Thunk<$d.DecodedType>, +): $.ConstSig => + Object.freeze({ + initializer: init, + type: type_, + }); export type ExtSig = $.ExtSig; -export const ExtSig = (type: $.DecodedMethodType, inline: boolean, body: $.Body): $.ExtSig => Object.freeze({ - type, - inline, - body, -}); +export const ExtSig = ( + type: $.DecodedMethodType, + inline: boolean, + body: $.Body, +): $.ExtSig => + Object.freeze({ + type, + inline, + body, + }); export type Scope = $.Scope; export type Decl = $.Decl; export const Decl = (decl: T, via: $v.ViaUser): Decl => ({ - decl, via -}); -export const Scope = (typeDecls: ReadonlyMap>, fnSigs: ReadonlyMap>, constSigs: ReadonlyMap>, extSigs: ReadonlyMap[]>>): $.Scope => Object.freeze({ - typeDecls, - functions: fnSigs, - constants: constSigs, - extensions: extSigs -}); + decl, + via, +}); +export const Scope = ( + typeDecls: ReadonlyMap>, + fnSigs: ReadonlyMap>, + constSigs: ReadonlyMap>, + extSigs: ReadonlyMap[]>>, +): $.Scope => + Object.freeze({ + typeDecls, + functions: fnSigs, + constants: constSigs, + extensions: extSigs, + }); export type DecodedMethodType = $.DecodedMethodType; -export const DecodedMethodType = (mutates: boolean, typeParams: $.TypeParams, self: $m.SelfType, params: $.Parameters, returnType: Thunk<$d.DecodedType>): $.DecodedMethodType => Object.freeze({ - kind: "DecodedMethodType", - mutates, - typeParams, - self, - params, - returnType -}); +export const DecodedMethodType = ( + mutates: boolean, + typeParams: $.TypeParams, + self: $m.SelfType, + params: $.Parameters, + returnType: Thunk<$d.DecodedType>, +): $.DecodedMethodType => + Object.freeze({ + kind: "DecodedMethodType", + mutates, + typeParams, + self, + params, + returnType, + }); export type DecodedParameter = $.DecodedParameter; -export const DecodedParameter = (name: $c.OptionalId, type_: Thunk<$d.DecodedType>, loc: $c.Loc): $.DecodedParameter => Object.freeze({ - name, - type: type_, - loc -}); +export const DecodedParameter = ( + name: $c.OptionalId, + type_: Thunk<$d.DecodedType>, + loc: $c.Loc, +): $.DecodedParameter => + Object.freeze({ + name, + type: type_, + loc, + }); export type SourceCheckResult = $.SourceCheckResult; -export const SourceCheckResult = (importedBy: TactImport, globals: $.Scope): $.SourceCheckResult => Object.freeze({ - importedBy, - globals -}); +export const SourceCheckResult = ( + importedBy: TactImport, + globals: $.Scope, +): $.SourceCheckResult => + Object.freeze({ + importedBy, + globals, + }); export type Parameter = $.Parameter; -export const Parameter = (name: $c.OptionalId, type_: Thunk<$d.DecodedType>, loc: $c.Loc): $.Parameter => Object.freeze({ - name, - type: type_, - loc -}); +export const Parameter = ( + name: $c.OptionalId, + type_: Thunk<$d.DecodedType>, + loc: $c.Loc, +): $.Parameter => + Object.freeze({ + name, + type: type_, + loc, + }); export type Recover = $.Recover; export type Parameters = $.Parameters; -export const Parameters = (order: readonly $.Parameter[], set: ReadonlySet): $.Parameters => Object.freeze({ - order, - set -}); +export const Parameters = ( + order: readonly $.Parameter[], + set: ReadonlySet, +): $.Parameters => + Object.freeze({ + order, + set, + }); export type TactBody = $.TactBody; -export const TactBody = (statements: Thunk): $.TactBody => Object.freeze({ - kind: "tact", - statements -}); +export const TactBody = ( + statements: Thunk, +): $.TactBody => + Object.freeze({ + kind: "tact", + statements, + }); export const isTactBody = ($value: TactBody) => $value.kind === "tact"; export type FuncBody = $.FuncBody; -export const FuncBody = (nativeName: $c.FuncId): $.FuncBody => Object.freeze({ - kind: "func", - nativeName -}); +export const FuncBody = (nativeName: $c.FuncId): $.FuncBody => + Object.freeze({ + kind: "func", + nativeName, + }); export const isFuncBody = ($value: FuncBody) => $value.kind === "func"; export type FiftBody = $.FiftBody; -export const FiftBody = (shuffle: Thunk, instructions: readonly AsmInstruction[]): $.FiftBody => Object.freeze({ - kind: "fift", - shuffle, - instructions -}); +export const FiftBody = ( + shuffle: Thunk, + instructions: readonly AsmInstruction[], +): $.FiftBody => + Object.freeze({ + kind: "fift", + shuffle, + instructions, + }); export const isFiftBody = ($value: FiftBody) => $value.kind === "fift"; export type Body = $.Body; export type FnSig = $.FnSig; -export const FnSig = (type_: $.DecodedFnType, inline: boolean, body: $.Body): $.FnSig => Object.freeze({ - type: type_, - inline, - body, -}); +export const FnSig = ( + type_: $.DecodedFnType, + inline: boolean, + body: $.Body, +): $.FnSig => + Object.freeze({ + type: type_, + inline, + body, + }); export type DeclMem = $.DeclMem; export const DeclMem = (decl: T, via: $v.ViaMember): DeclMem => ({ - decl, via + decl, + via, }); export type InhFieldSig = $.InhFieldSig; -export const InhFieldSig = (type_: Thunk<$d.DecodedType>, init: Thunk | undefined): $.InhFieldSig => Object.freeze({ - kind: "field", - type: type_, - init -}); +export const InhFieldSig = ( + type_: Thunk<$d.DecodedType>, + init: Thunk | undefined, +): $.InhFieldSig => + Object.freeze({ + kind: "field", + type: type_, + init, + }); export const isInhFieldSig = ($value: InhFieldSig) => $value.kind === "field"; export type FieldConstSig = $.FieldConstSig; -export const FieldConstSig = (overridable: boolean, type_: Thunk<$d.DecodedType>, init: Expr): $.FieldConstSig => Object.freeze({ - kind: "constant", - overridable, - type: type_, - init -}); -export const isFieldConstSig = ($value: FieldConstSig) => $value.kind === "constant"; +export const FieldConstSig = ( + overridable: boolean, + type_: Thunk<$d.DecodedType>, + init: Expr, +): $.FieldConstSig => + Object.freeze({ + kind: "constant", + overridable, + type: type_, + init, + }); +export const isFieldConstSig = ($value: FieldConstSig) => + $value.kind === "constant"; export type Fieldish = $.Fieldish; export type MethodSig = $.MethodSig; -export const MethodSig = (overridable: boolean, type_: $.DecodedMethodType, inline: boolean, body: Body, getMethodId: Thunk | undefined): $.MethodSig => Object.freeze({ - overridable, - type: type_, - inline, - body, - getMethodId -}); +export const MethodSig = ( + overridable: boolean, + type_: $.DecodedMethodType, + inline: boolean, + body: Body, + getMethodId: Thunk | undefined, +): $.MethodSig => + Object.freeze({ + overridable, + type: type_, + inline, + body, + getMethodId, + }); export type Receivers = $.Receivers; export type CommonSig = $.CommonSig; -export const CommonSig = (fieldish: $.Ordered<$.DeclMem<$.Fieldish>>, methods: ReadonlyMap>>, receivers: $.Receivers): $.CommonSig => Object.freeze({ - fieldish, - methods, - receivers -}); +export const CommonSig = ( + fieldish: $.Ordered<$.DeclMem<$.Fieldish>>, + methods: ReadonlyMap>>, + receivers: $.Receivers, +): $.CommonSig => + Object.freeze({ + fieldish, + methods, + receivers, + }); export type ContractContent = $.ContractContent; export type TraitContent = $.TraitContent; export type TraitSig = $.TraitSig; -export const TraitSig = (content: Thunk<$.CommonSig | undefined, $.Body | undefined>>): $.TraitSig => Object.freeze({ - kind: "trait", - content -}); +export const TraitSig = ( + content: Thunk< + $.CommonSig | undefined, $.Body | undefined> + >, +): $.TraitSig => + Object.freeze({ + kind: "trait", + content, + }); export const isTraitSig = ($value: TraitSig) => $value.kind === "trait"; export type MessageRecv = $.MessageRecv; -export const MessageRecv = (name: $c.OptionalId, type_: $d.DTypeRef | $d.DTypeBounced, statements: Thunk): $.MessageRecv => Object.freeze({ - kind: "binary", - name, - type: type_, - statements -}); +export const MessageRecv = ( + name: $c.OptionalId, + type_: $d.DTypeRef | $d.DTypeBounced, + statements: Thunk, +): $.MessageRecv => + Object.freeze({ + kind: "binary", + name, + type: type_, + statements, + }); export type MessageAnyRecv = $.MessageAnyRecv; -export const MessageAnyRecv = (name: $c.OptionalId, statements: Thunk): $.MessageAnyRecv => Object.freeze({ - name, - statements -}); +export const MessageAnyRecv = ( + name: $c.OptionalId, + statements: Thunk, +): $.MessageAnyRecv => + Object.freeze({ + name, + statements, + }); export type StringRecv = $.StringRecv; -export const StringRecv = (comment: string, statements: Thunk): $.StringRecv => Object.freeze({ - kind: "string", - comment, - statements -}); +export const StringRecv = ( + comment: string, + statements: Thunk, +): $.StringRecv => + Object.freeze({ + kind: "string", + comment, + statements, + }); export type StringAnyRecv = $.StringAnyRecv; -export const StringAnyRecv = (name: $c.OptionalId, statements: Thunk): $.StringAnyRecv => Object.freeze({ - name, - statements -}); +export const StringAnyRecv = ( + name: $c.OptionalId, + statements: Thunk, +): $.StringAnyRecv => + Object.freeze({ + name, + statements, + }); export type EmptyRecv = $.EmptyRecv; -export const EmptyRecv = (statements: Thunk): $.EmptyRecv => Object.freeze({ - statements -}); +export const EmptyRecv = ( + statements: Thunk, +): $.EmptyRecv => + Object.freeze({ + statements, + }); export type OpcodeRecv = $.OpcodeRecv; export type RecvSig = $.RecvSig; -export const RecvSig = (message: readonly DeclMem[], messageAny: $.DeclMem<$.MessageAnyRecv> | undefined, stringAny: $.DeclMem<$.StringAnyRecv> | undefined, empty: $.DeclMem<$.EmptyRecv> | undefined): $.RecvSig => Object.freeze({ - message, - messageAny, - stringAny, - empty -}); +export const RecvSig = ( + message: readonly DeclMem[], + messageAny: $.DeclMem<$.MessageAnyRecv> | undefined, + stringAny: $.DeclMem<$.StringAnyRecv> | undefined, + empty: $.DeclMem<$.EmptyRecv> | undefined, +): $.RecvSig => + Object.freeze({ + message, + messageAny, + stringAny, + empty, + }); export type MessageSig = $.MessageSig; -export const MessageSig = (opcode: Thunk, fields: $.Ordered<$.InhFieldSig>): $.MessageSig => Object.freeze({ - kind: "message", - opcode, - fields -}); +export const MessageSig = ( + opcode: Thunk, + fields: $.Ordered<$.InhFieldSig>, +): $.MessageSig => + Object.freeze({ + kind: "message", + opcode, + fields, + }); export const isMessageSig = ($value: MessageSig) => $value.kind === "message"; export type InitEmpty = $.InitEmpty; -export const InitEmpty = (fill: Thunk>>): $.InitEmpty => Object.freeze({ - kind: "empty", - fill -}); +export const InitEmpty = ( + fill: Thunk>>, +): $.InitEmpty => + Object.freeze({ + kind: "empty", + fill, + }); export const isInitEmpty = ($value: InitEmpty) => $value.kind === "empty"; export type InitParam = $.InitParam; -export const InitParam = (type_: Thunk<$d.DecodedType>, init: Thunk | undefined, loc: $c.Loc): $.InitParam => Object.freeze({ - type: type_, - init, - loc -}); +export const InitParam = ( + type_: Thunk<$d.DecodedType>, + init: Thunk | undefined, + loc: $c.Loc, +): $.InitParam => + Object.freeze({ + type: type_, + init, + loc, + }); export type InitSimple = $.InitSimple; -export const InitSimple = (fill: $.Ordered<$.InitParam>, loc: $c.Loc): $.InitSimple => Object.freeze({ - kind: "simple", - fill, - loc -}); +export const InitSimple = ( + fill: $.Ordered<$.InitParam>, + loc: $c.Loc, +): $.InitSimple => + Object.freeze({ + kind: "simple", + fill, + loc, + }); export const isInitSimple = ($value: InitSimple) => $value.kind === "simple"; -export type StatementsAux = $.StatementsAux -export const StatementsAux = (body: readonly DecodedStatement[], effects: Effects): $.StatementsAux => Object.freeze({ - body, effects, -}); +export type StatementsAux = $.StatementsAux; +export const StatementsAux = ( + body: readonly DecodedStatement[], + effects: Effects, +): $.StatementsAux => + Object.freeze({ + body, + effects, + }); export type InitFn = $.InitFn; -export const InitFn = (params: $.Parameters, statements: Thunk): $.InitFn => Object.freeze({ - kind: "function", - params, - statements -}); +export const InitFn = ( + params: $.Parameters, + statements: Thunk, +): $.InitFn => + Object.freeze({ + kind: "function", + params, + statements, + }); export const isInitFn = ($value: InitFn) => $value.kind === "function"; export type Statements = $.Statements; export type InitSig = $.InitSig; export type ContractSig = $.ContractSig; export type TypeDeclRefable = $.TypeDeclRefable; -export const ContractSig = (attributes: readonly ContractAttribute[], init: $.InitSig, content: Thunk<$.ContractContent>): $.ContractSig => Object.freeze({ - kind: "contract", - attributes, - init, - content -}); -export const isContractSig = ($value: ContractSig) => $value.kind === "contract"; +export const ContractSig = ( + attributes: readonly ContractAttribute[], + init: $.InitSig, + content: Thunk<$.ContractContent>, +): $.ContractSig => + Object.freeze({ + kind: "contract", + attributes, + init, + content, + }); +export const isContractSig = ($value: ContractSig) => + $value.kind === "contract"; diff --git a/src/next/ast/generated/common.ts b/src/next/ast/generated/common.ts index d47e5f94e9..738e23d63c 100644 --- a/src/next/ast/generated/common.ts +++ b/src/next/ast/generated/common.ts @@ -3,9 +3,10 @@ import type * as $ from "@/next/ast/common"; import { hideProperty } from "@/utils/tricks"; export type Loc = $.Loc; export type Builtin = $.Builtin; -export const Builtin = (): $.Builtin => Object.freeze({ - kind: "builtin" -}); +export const Builtin = (): $.Builtin => + Object.freeze({ + kind: "builtin", + }); export const isBuiltin = ($value: Builtin) => $value.kind === "builtin"; export type Range = $.Range; export const Range = ( @@ -21,8 +22,8 @@ export const Range = ( path, code, }; - hideProperty(result, 'code'); - hideProperty(result, 'path'); + hideProperty(result, "code"); + hideProperty(result, "path"); return Object.freeze(result); }; export type Id = $.Id; diff --git a/src/next/ast/generated/dtype.ts b/src/next/ast/generated/dtype.ts index 72294d1faf..e12d69550f 100644 --- a/src/next/ast/generated/dtype.ts +++ b/src/next/ast/generated/dtype.ts @@ -4,86 +4,126 @@ import type * as $c from "@/next/ast/common"; import type { TypeDeclRefable } from "@/next/ast/checked"; export type DTypeParamRef = $.DTypeParamRef; -export const DTypeParamRef = (name: $c.TypeId, loc: $c.Loc): $.DTypeParamRef => Object.freeze({ - kind: "TypeParam", - name, - loc -}); -export const isDTypeParamRef = ($value: DTypeParamRef) => $value.kind === "TypeParam"; +export const DTypeParamRef = (name: $c.TypeId, loc: $c.Loc): $.DTypeParamRef => + Object.freeze({ + kind: "TypeParam", + name, + loc, + }); +export const isDTypeParamRef = ($value: DTypeParamRef) => + $value.kind === "TypeParam"; export type DTypeTensor = $.DTypeTensor; -export const DTypeTensor = (typeArgs: readonly $.DecodedType[], loc: $c.Loc): $.DTypeTensor => Object.freeze({ - kind: "tensor_type", - typeArgs, - loc -}); -export const isDTypeTensor = ($value: DTypeTensor) => $value.kind === "tensor_type"; +export const DTypeTensor = ( + typeArgs: readonly $.DecodedType[], + loc: $c.Loc, +): $.DTypeTensor => + Object.freeze({ + kind: "tensor_type", + typeArgs, + loc, + }); +export const isDTypeTensor = ($value: DTypeTensor) => + $value.kind === "tensor_type"; export type DTypeTuple = $.DTypeTuple; -export const DTypeTuple = (typeArgs: readonly $.DecodedType[], loc: $c.Loc): $.DTypeTuple => Object.freeze({ - kind: "tuple_type", - typeArgs, - loc -}); -export const isDTypeTuple = ($value: DTypeTuple) => $value.kind === "tuple_type"; +export const DTypeTuple = ( + typeArgs: readonly $.DecodedType[], + loc: $c.Loc, +): $.DTypeTuple => + Object.freeze({ + kind: "tuple_type", + typeArgs, + loc, + }); +export const isDTypeTuple = ($value: DTypeTuple) => + $value.kind === "tuple_type"; export type DTypeMaybe = $.DTypeMaybe; -export const DTypeMaybe = (type_: $.DecodedType, loc: $c.Loc): $.DTypeMaybe => Object.freeze({ - kind: "TypeMaybe", - type: type_, - loc -}); +export const DTypeMaybe = (type_: $.DecodedType, loc: $c.Loc): $.DTypeMaybe => + Object.freeze({ + kind: "TypeMaybe", + type: type_, + loc, + }); export const isDTypeMaybe = ($value: DTypeMaybe) => $value.kind === "TypeMaybe"; export type DTypeBounced = $.DTypeBounced; -export const DTypeBounced = (name: $c.TypeId, loc: $c.Loc): $.DTypeBounced => Object.freeze({ - kind: "TypeBounced", - name, - loc -}); -export const isDTypeBounced = ($value: DTypeBounced) => $value.kind === "TypeBounced"; +export const DTypeBounced = (name: $c.TypeId, loc: $c.Loc): $.DTypeBounced => + Object.freeze({ + kind: "TypeBounced", + name, + loc, + }); +export const isDTypeBounced = ($value: DTypeBounced) => + $value.kind === "TypeBounced"; export type DTypeMap = $.DTypeMap; -export const DTypeMap = (key: $.DecodedType, value: $.DecodedType, loc: $c.Loc): $.DTypeMap => Object.freeze({ - kind: "map_type", - key, - value, - loc -}); +export const DTypeMap = ( + key: $.DecodedType, + value: $.DecodedType, + loc: $c.Loc, +): $.DTypeMap => + Object.freeze({ + kind: "map_type", + key, + value, + loc, + }); export const isDTypeMap = ($value: DTypeMap) => $value.kind === "map_type"; export type DTypeAliasRef = $.DTypeAliasRef; -export const DTypeAliasRef = (type: NotDealiased | DecodedType, name: $c.TypeId, typeArgs: readonly $.DecodedType[], loc: $c.Loc): $.DTypeAliasRef => Object.freeze({ - kind: "TypeAlias", - name, - type, - typeArgs, - loc -}); -export const isDTypeAliasRef = ($value: DTypeAliasRef) => $value.kind === "TypeAlias"; +export const DTypeAliasRef = ( + type: NotDealiased | DecodedType, + name: $c.TypeId, + typeArgs: readonly $.DecodedType[], + loc: $c.Loc, +): $.DTypeAliasRef => + Object.freeze({ + kind: "TypeAlias", + name, + type, + typeArgs, + loc, + }); +export const isDTypeAliasRef = ($value: DTypeAliasRef) => + $value.kind === "TypeAlias"; export type DTypeRef = $.DTypeRef; -export const DTypeRef = (name: $c.TypeId, type: TypeDeclRefable, typeArgs: readonly $.DecodedType[], loc: $c.Loc): $.DTypeRef => Object.freeze({ - kind: "type_ref", - name, - type, - typeArgs, - loc -}); +export const DTypeRef = ( + name: $c.TypeId, + type: TypeDeclRefable, + typeArgs: readonly $.DecodedType[], + loc: $c.Loc, +): $.DTypeRef => + Object.freeze({ + kind: "type_ref", + name, + type, + typeArgs, + loc, + }); export const isDTypeRef = ($value: DTypeRef) => $value.kind === "type_ref"; export type DecodedType = $.DecodedType; export type DTypeRecover = $.DTypeRecover; -export const DTypeRecover = (): $.DTypeRecover => Object.freeze({ - kind: "recover" -}); -export const isDTypeRecover = ($value: DTypeRecover) => $value.kind === "recover"; +export const DTypeRecover = (): $.DTypeRecover => + Object.freeze({ + kind: "recover", + }); +export const isDTypeRecover = ($value: DTypeRecover) => + $value.kind === "recover"; export type DTypeStateInit = $.DTypeStateInit; -export const DTypeStateInit = (loc: $c.Loc): $.DTypeStateInit => Object.freeze({ - kind: "TypeStateInit", - loc -}); -export const isDTypeStateInit = ($value: DTypeStateInit) => $value.kind === "TypeStateInit"; +export const DTypeStateInit = (loc: $c.Loc): $.DTypeStateInit => + Object.freeze({ + kind: "TypeStateInit", + loc, + }); +export const isDTypeStateInit = ($value: DTypeStateInit) => + $value.kind === "TypeStateInit"; export type NotDealiased = $.NotDealiased; -export const NotDealiased = (): $.NotDealiased => Object.freeze({ - kind: "NotDealiased" -}); -export const isNotDealiased = ($value: NotDealiased) => $value.kind === "NotDealiased"; +export const NotDealiased = (): $.NotDealiased => + Object.freeze({ + kind: "NotDealiased", + }); +export const isNotDealiased = ($value: NotDealiased) => + $value.kind === "NotDealiased"; export type DNotSet = $.DNotSet; -export const DNotSet = (): $.DNotSet => Object.freeze({ - kind: "not-set" -}); +export const DNotSet = (): $.DNotSet => + Object.freeze({ + kind: "not-set", + }); export const isDNotSet = ($value: DNotSet) => $value.kind === "not-set"; diff --git a/src/next/ast/generated/effects.ts b/src/next/ast/generated/effects.ts index 5fa59f98d1..63e4dfe52a 100644 --- a/src/next/ast/generated/effects.ts +++ b/src/next/ast/generated/effects.ts @@ -1,7 +1,7 @@ import type * as $ from "@/next/ast/effects"; -export type Effects = $.Effects +export type Effects = $.Effects; export const Effects = ( returnOrThrow: boolean, setSelfPaths: ReadonlySet, -): $.Effects => Object.freeze({ returnOrThrow, setSelfPaths }) +): $.Effects => Object.freeze({ returnOrThrow, setSelfPaths }); diff --git a/src/next/ast/generated/expression.ts b/src/next/ast/generated/expression.ts index a54d4763bc..453e7b0aab 100644 --- a/src/next/ast/generated/expression.ts +++ b/src/next/ast/generated/expression.ts @@ -286,12 +286,20 @@ export const SetLiteral = ( export const isSetLiteral = ($value: SetLiteral) => $value.kind === "set_literal"; export type StaticMethodCall = $.StaticMethodCall; -export const StaticMethodCall = (self: $c.TypeId, typeArgs: readonly $t.Type[], function_: $c.Id, args: readonly $.Expression[], loc: $c.Loc): $.StaticMethodCall => Object.freeze({ - kind: "static_method_call", - self, - typeArgs, - function: function_, - args, - loc -}); -export const isStaticMethodCall = ($value: StaticMethodCall) => $value.kind === "static_method_call"; +export const StaticMethodCall = ( + self: $c.TypeId, + typeArgs: readonly $t.Type[], + function_: $c.Id, + args: readonly $.Expression[], + loc: $c.Loc, +): $.StaticMethodCall => + Object.freeze({ + kind: "static_method_call", + self, + typeArgs, + function: function_, + args, + loc, + }); +export const isStaticMethodCall = ($value: StaticMethodCall) => + $value.kind === "static_method_call"; diff --git a/src/next/ast/generated/mtype.ts b/src/next/ast/generated/mtype.ts index 9428b34332..2c3cd97b18 100644 --- a/src/next/ast/generated/mtype.ts +++ b/src/next/ast/generated/mtype.ts @@ -16,90 +16,142 @@ export type MGTypeAddress = $.MGTypeAddress; export type MGTypeString = $.MGTypeString; export type MGTypeStringBuilder = $.MGTypeStringBuilder; export type MGTypeRef = $.MGTypeRef; -export const MGTypeRef = (name: $c.TypeId, type: TypeDeclRefable, typeArgs: readonly $.MethodGroundType[], loc: $c.Loc): $.MGTypeRef => Object.freeze({ - ground: "yes", - kind: "type_ref", - name, - type, - typeArgs, - loc -}); +export const MGTypeRef = ( + name: $c.TypeId, + type: TypeDeclRefable, + typeArgs: readonly $.MethodGroundType[], + loc: $c.Loc, +): $.MGTypeRef => + Object.freeze({ + ground: "yes", + kind: "type_ref", + name, + type, + typeArgs, + loc, + }); export const isMGTypeRef = ($value: MGTypeRef) => $value.kind === "type_ref"; export type MGTypeMaybe = $.MGTypeMaybe; -export const MGTypeMaybe = (type_: $.MethodGroundType, loc: $c.Loc): $.MGTypeMaybe => Object.freeze({ - ground: "yes", - kind: "TypeMaybe", - type: type_, - loc -}); -export const isMGTypeMaybe = ($value: MGTypeMaybe) => $value.kind === "TypeMaybe"; +export const MGTypeMaybe = ( + type_: $.MethodGroundType, + loc: $c.Loc, +): $.MGTypeMaybe => + Object.freeze({ + ground: "yes", + kind: "TypeMaybe", + type: type_, + loc, + }); +export const isMGTypeMaybe = ($value: MGTypeMaybe) => + $value.kind === "TypeMaybe"; export type MGTypeMap = $.MGTypeMap; -export const MGTypeMap = (key: $.MethodGroundType, value: $.MethodGroundType, loc: $c.Loc): $.MGTypeMap => Object.freeze({ - ground: "yes", - kind: "map_type", - key, - value, - loc -}); +export const MGTypeMap = ( + key: $.MethodGroundType, + value: $.MethodGroundType, + loc: $c.Loc, +): $.MGTypeMap => + Object.freeze({ + ground: "yes", + kind: "map_type", + key, + value, + loc, + }); export const isMGTypeMap = ($value: MGTypeMap) => $value.kind === "map_type"; export type MGTypeTuple = $.MGTypeTuple; -export const MGTypeTuple = (typeArgs: readonly $.MethodGroundType[], loc: $c.Loc): $.MGTypeTuple => Object.freeze({ - ground: "yes", - kind: "tuple_type", - typeArgs, - loc -}); -export const isMGTypeTuple = ($value: MGTypeTuple) => $value.kind === "tuple_type"; +export const MGTypeTuple = ( + typeArgs: readonly $.MethodGroundType[], + loc: $c.Loc, +): $.MGTypeTuple => + Object.freeze({ + ground: "yes", + kind: "tuple_type", + typeArgs, + loc, + }); +export const isMGTypeTuple = ($value: MGTypeTuple) => + $value.kind === "tuple_type"; export type MGTypeTensor = $.MGTypeTensor; -export const MGTypeTensor = (typeArgs: readonly $.MethodGroundType[], loc: $c.Loc): $.MGTypeTensor => Object.freeze({ - ground: "yes", - kind: "tensor_type", - typeArgs, - loc -}); -export const isMGTypeTensor = ($value: MGTypeTensor) => $value.kind === "tensor_type"; +export const MGTypeTensor = ( + typeArgs: readonly $.MethodGroundType[], + loc: $c.Loc, +): $.MGTypeTensor => + Object.freeze({ + ground: "yes", + kind: "tensor_type", + typeArgs, + loc, + }); +export const isMGTypeTensor = ($value: MGTypeTensor) => + $value.kind === "tensor_type"; export type MVTypeRef = $.MVTypeRef; -export const MVTypeRef = (name: $c.TypeId, type: TypeDeclRefable, typeArgs: readonly $d.DTypeParamRef[], loc: $c.Loc): $.MVTypeRef => Object.freeze({ - ground: "no", - kind: "type_ref", - name, - type, - typeArgs, - loc -}); +export const MVTypeRef = ( + name: $c.TypeId, + type: TypeDeclRefable, + typeArgs: readonly $d.DTypeParamRef[], + loc: $c.Loc, +): $.MVTypeRef => + Object.freeze({ + ground: "no", + kind: "type_ref", + name, + type, + typeArgs, + loc, + }); export const isMVTypeRef = ($value: MVTypeRef) => $value.kind === "type_ref"; export type MVTypeMaybe = $.MVTypeMaybe; -export const MVTypeMaybe = (type_: $d.DTypeParamRef, loc: $c.Loc): $.MVTypeMaybe => Object.freeze({ - ground: "no", - kind: "TypeMaybe", - type: type_, - loc -}); -export const isMVTypeMaybe = ($value: MVTypeMaybe) => $value.kind === "TypeMaybe"; +export const MVTypeMaybe = ( + type_: $d.DTypeParamRef, + loc: $c.Loc, +): $.MVTypeMaybe => + Object.freeze({ + ground: "no", + kind: "TypeMaybe", + type: type_, + loc, + }); +export const isMVTypeMaybe = ($value: MVTypeMaybe) => + $value.kind === "TypeMaybe"; export type MVTypeMap = $.MVTypeMap; -export const MVTypeMap = (key: $d.DTypeParamRef, value: $d.DTypeParamRef, loc: $c.Loc): $.MVTypeMap => Object.freeze({ - ground: "no", - kind: "map_type", - key, - value, - loc -}); +export const MVTypeMap = ( + key: $d.DTypeParamRef, + value: $d.DTypeParamRef, + loc: $c.Loc, +): $.MVTypeMap => + Object.freeze({ + ground: "no", + kind: "map_type", + key, + value, + loc, + }); export const isMVTypeMap = ($value: MVTypeMap) => $value.kind === "map_type"; export type MVTypeTuple = $.MVTypeTuple; -export const MVTypeTuple = (typeArgs: readonly $d.DTypeParamRef[], loc: $c.Loc): $.MVTypeTuple => Object.freeze({ - ground: "no", - kind: "tuple_type", - typeArgs, - loc -}); -export const isMVTypeTuple = ($value: MVTypeTuple) => $value.kind === "tuple_type"; +export const MVTypeTuple = ( + typeArgs: readonly $d.DTypeParamRef[], + loc: $c.Loc, +): $.MVTypeTuple => + Object.freeze({ + ground: "no", + kind: "tuple_type", + typeArgs, + loc, + }); +export const isMVTypeTuple = ($value: MVTypeTuple) => + $value.kind === "tuple_type"; export type MVTypeTensor = $.MVTypeTensor; -export const MVTypeTensor = (typeArgs: readonly $d.DTypeParamRef[], loc: $c.Loc): $.MVTypeTensor => Object.freeze({ - ground: "no", - kind: "tensor_type", - typeArgs, - loc -}); -export const isMVTypeTensor = ($value: MVTypeTensor) => $value.kind === "tensor_type"; +export const MVTypeTensor = ( + typeArgs: readonly $d.DTypeParamRef[], + loc: $c.Loc, +): $.MVTypeTensor => + Object.freeze({ + ground: "no", + kind: "tensor_type", + typeArgs, + loc, + }); +export const isMVTypeTensor = ($value: MVTypeTensor) => + $value.kind === "tensor_type"; export type SelfType = $.SelfType; export type MethodGroundType = $.MethodGroundType; diff --git a/src/next/ast/generated/root.ts b/src/next/ast/generated/root.ts index 8a5901912b..b19d23089b 100644 --- a/src/next/ast/generated/root.ts +++ b/src/next/ast/generated/root.ts @@ -8,278 +8,454 @@ import type * as $ from "@/next/ast/root"; export type ImportType = $.ImportType; export const allImportType: readonly $.ImportType[] = ["stdlib", "relative"]; export type ImportPath = $.ImportPath; -export const ImportPath = (path: $f.RelativePath, type_: $.ImportType, language: $c.Language): $.ImportPath => Object.freeze({ - path, - type: type_, - language -}); +export const ImportPath = ( + path: $f.RelativePath, + type_: $.ImportType, + language: $c.Language, +): $.ImportPath => + Object.freeze({ + path, + type: type_, + language, + }); export type Import = $.Import; -export const Import = (importPath: $.ImportPath, loc: $c.Loc): $.Import => Object.freeze({ - kind: "import", - importPath, - loc -}); +export const Import = (importPath: $.ImportPath, loc: $c.Loc): $.Import => + Object.freeze({ + kind: "import", + importPath, + loc, + }); export const isImport = ($value: Import) => $value.kind === "import"; export type RegularBody = $.RegularBody; -export const RegularBody = (statements: readonly $s.Statement[]): $.RegularBody => Object.freeze({ - kind: "regular_body", - statements -}); -export const isRegularBody = ($value: RegularBody) => $value.kind === "regular_body"; +export const RegularBody = ( + statements: readonly $s.Statement[], +): $.RegularBody => + Object.freeze({ + kind: "regular_body", + statements, + }); +export const isRegularBody = ($value: RegularBody) => + $value.kind === "regular_body"; export type AsmShuffle = $.AsmShuffle; -export const AsmShuffle = (args: readonly $c.Id[], ret: readonly $e.Number[]): $.AsmShuffle => Object.freeze({ - args, - ret -}); +export const AsmShuffle = ( + args: readonly $c.Id[], + ret: readonly $e.Number[], +): $.AsmShuffle => + Object.freeze({ + args, + ret, + }); export type AsmInstruction = $.AsmInstruction; export type AsmBody = $.AsmBody; -export const AsmBody = (shuffle: $.AsmShuffle, instructions: readonly $.AsmInstruction[]): $.AsmBody => Object.freeze({ - kind: "asm_body", - shuffle, - instructions -}); +export const AsmBody = ( + shuffle: $.AsmShuffle, + instructions: readonly $.AsmInstruction[], +): $.AsmBody => + Object.freeze({ + kind: "asm_body", + shuffle, + instructions, + }); export const isAsmBody = ($value: AsmBody) => $value.kind === "asm_body"; export type NativeBody = $.NativeBody; -export const NativeBody = (nativeName: $c.FuncId): $.NativeBody => Object.freeze({ - kind: "native_body", - nativeName -}); -export const isNativeBody = ($value: NativeBody) => $value.kind === "native_body"; +export const NativeBody = (nativeName: $c.FuncId): $.NativeBody => + Object.freeze({ + kind: "native_body", + nativeName, + }); +export const isNativeBody = ($value: NativeBody) => + $value.kind === "native_body"; export type AbstractBody = $.AbstractBody; -export const AbstractBody = (): $.AbstractBody => Object.freeze({ - kind: "abstract_body" -}); -export const isAbstractBody = ($value: AbstractBody) => $value.kind === "abstract_body"; +export const AbstractBody = (): $.AbstractBody => + Object.freeze({ + kind: "abstract_body", + }); +export const isAbstractBody = ($value: AbstractBody) => + $value.kind === "abstract_body"; export type FunctionalBody = $.FunctionalBody; export type Function = $.Function; -export const Function = (inline: boolean, name: $c.Id, type_: $t.FnType, body: $.FunctionalBody, loc: $c.Loc): $.Function => Object.freeze({ - kind: "function", - inline, - name, - type: type_, - body, - loc -}); +export const Function = ( + inline: boolean, + name: $c.Id, + type_: $t.FnType, + body: $.FunctionalBody, + loc: $c.Loc, +): $.Function => + Object.freeze({ + kind: "function", + inline, + name, + type: type_, + body, + loc, + }); export const isFunction = ($value: Function) => $value.kind === "function"; export type ConstantDef = $.ConstantDef; -export const ConstantDef = (type_: $t.Type | undefined, initializer: $e.Expression): $.ConstantDef => Object.freeze({ - kind: "constant_def", - type: type_, - initializer -}); -export const isConstantDef = ($value: ConstantDef) => $value.kind === "constant_def"; +export const ConstantDef = ( + type_: $t.Type | undefined, + initializer: $e.Expression, +): $.ConstantDef => + Object.freeze({ + kind: "constant_def", + type: type_, + initializer, + }); +export const isConstantDef = ($value: ConstantDef) => + $value.kind === "constant_def"; export type ConstantDecl = $.ConstantDecl; -export const ConstantDecl = (type_: $t.Type): $.ConstantDecl => Object.freeze({ - kind: "constant_decl", - type: type_ -}); -export const isConstantDecl = ($value: ConstantDecl) => $value.kind === "constant_decl"; +export const ConstantDecl = (type_: $t.Type): $.ConstantDecl => + Object.freeze({ + kind: "constant_decl", + type: type_, + }); +export const isConstantDecl = ($value: ConstantDecl) => + $value.kind === "constant_decl"; export type ConstantInit = $.ConstantInit; export type Constant = $.Constant; -export const Constant = (name: $c.Id, init: $.ConstantInit, loc: $c.Loc): $.Constant => Object.freeze({ - kind: "constant", - name, - init, - loc -}); +export const Constant = ( + name: $c.Id, + init: $.ConstantInit, + loc: $c.Loc, +): $.Constant => + Object.freeze({ + kind: "constant", + name, + init, + loc, + }); export const isConstant = ($value: Constant) => $value.kind === "constant"; export type Extension = $.Extension; -export const Extension = (mutates: boolean, fun: $.Function, selfType: $t.Type): $.Extension => Object.freeze({ - kind: "extension", - mutates, - fun, - selfType -}); +export const Extension = ( + mutates: boolean, + fun: $.Function, + selfType: $t.Type, +): $.Extension => + Object.freeze({ + kind: "extension", + mutates, + fun, + selfType, + }); export const isExtension = ($value: Extension) => $value.kind === "extension"; export type FieldDecl = $.FieldDecl; -export const FieldDecl = (name: $c.Id, type_: $t.Type, initializer: $e.Expression | undefined, loc: $c.Loc): $.FieldDecl => Object.freeze({ - kind: "field_decl", - name, - type: type_, - initializer, - loc -}); +export const FieldDecl = ( + name: $c.Id, + type_: $t.Type, + initializer: $e.Expression | undefined, + loc: $c.Loc, +): $.FieldDecl => + Object.freeze({ + kind: "field_decl", + name, + type: type_, + initializer, + loc, + }); export const isFieldDecl = ($value: FieldDecl) => $value.kind === "field_decl"; export type StructDecl = $.StructDecl; -export const StructDecl = (name: $c.TypeId, typeParams: readonly $c.TypeId[], fields: readonly $.FieldDecl[], loc: $c.Loc): $.StructDecl => Object.freeze({ - kind: "struct_decl", - name, - typeParams, - fields, - loc -}); -export const isStructDecl = ($value: StructDecl) => $value.kind === "struct_decl"; +export const StructDecl = ( + name: $c.TypeId, + typeParams: readonly $c.TypeId[], + fields: readonly $.FieldDecl[], + loc: $c.Loc, +): $.StructDecl => + Object.freeze({ + kind: "struct_decl", + name, + typeParams, + fields, + loc, + }); +export const isStructDecl = ($value: StructDecl) => + $value.kind === "struct_decl"; export type MessageDecl = $.MessageDecl; -export const MessageDecl = (name: $c.TypeId, opcode: $e.Expression | undefined, fields: readonly $.FieldDecl[], loc: $c.Loc): $.MessageDecl => Object.freeze({ - kind: "message_decl", - name, - opcode, - fields, - loc -}); -export const isMessageDecl = ($value: MessageDecl) => $value.kind === "message_decl"; +export const MessageDecl = ( + name: $c.TypeId, + opcode: $e.Expression | undefined, + fields: readonly $.FieldDecl[], + loc: $c.Loc, +): $.MessageDecl => + Object.freeze({ + kind: "message_decl", + name, + opcode, + fields, + loc, + }); +export const isMessageDecl = ($value: MessageDecl) => + $value.kind === "message_decl"; export type UnionCase = $.UnionCase; -export const UnionCase = (name: $c.TypeId, fields: readonly $.FieldDecl[]): $.UnionCase => Object.freeze({ - name, - fields -}); +export const UnionCase = ( + name: $c.TypeId, + fields: readonly $.FieldDecl[], +): $.UnionCase => + Object.freeze({ + name, + fields, + }); export type UnionDecl = $.UnionDecl; -export const UnionDecl = (name: $c.TypeId, typeParams: readonly $c.TypeId[], cases: readonly $.UnionCase[], loc: $c.Loc): $.UnionDecl => Object.freeze({ - kind: "union_decl", - name, - typeParams, - cases, - loc -}); +export const UnionDecl = ( + name: $c.TypeId, + typeParams: readonly $c.TypeId[], + cases: readonly $.UnionCase[], + loc: $c.Loc, +): $.UnionDecl => + Object.freeze({ + kind: "union_decl", + name, + typeParams, + cases, + loc, + }); export const isUnionDecl = ($value: UnionDecl) => $value.kind === "union_decl"; export type AliasDecl = $.AliasDecl; -export const AliasDecl = (name: $c.TypeId, typeParams: readonly $c.TypeId[], type_: $t.Type, loc: $c.Loc): $.AliasDecl => Object.freeze({ - kind: "alias_decl", - name, - typeParams, - type: type_, - loc -}); +export const AliasDecl = ( + name: $c.TypeId, + typeParams: readonly $c.TypeId[], + type_: $t.Type, + loc: $c.Loc, +): $.AliasDecl => + Object.freeze({ + kind: "alias_decl", + name, + typeParams, + type: type_, + loc, + }); export const isAliasDecl = ($value: AliasDecl) => $value.kind === "alias_decl"; export type InitFunction = $.InitFunction; -export const InitFunction = (params: readonly $t.TypedParameter[], statements: readonly $s.Statement[], loc: $c.Loc): $.InitFunction => Object.freeze({ - kind: "init_function", - params, - statements, - loc -}); -export const isInitFunction = ($value: InitFunction) => $value.kind === "init_function"; +export const InitFunction = ( + params: readonly $t.TypedParameter[], + statements: readonly $s.Statement[], + loc: $c.Loc, +): $.InitFunction => + Object.freeze({ + kind: "init_function", + params, + statements, + loc, + }); +export const isInitFunction = ($value: InitFunction) => + $value.kind === "init_function"; export type InitParams = $.InitParams; -export const InitParams = (params: readonly $.FieldDecl[], loc: $c.Loc): $.InitParams => Object.freeze({ - kind: "init_params", - params, - loc, -}); -export const isInitParams = ($value: InitParams) => $value.kind === "init_params"; +export const InitParams = ( + params: readonly $.FieldDecl[], + loc: $c.Loc, +): $.InitParams => + Object.freeze({ + kind: "init_params", + params, + loc, + }); +export const isInitParams = ($value: InitParams) => + $value.kind === "init_params"; export type Init = $.Init; export type ContractAttribute = $.ContractAttribute; -export const ContractAttribute = (name: string, loc: $c.Loc): $.ContractAttribute => Object.freeze({ - type: "interface", - name, - loc -}); +export const ContractAttribute = ( + name: string, + loc: $c.Loc, +): $.ContractAttribute => + Object.freeze({ + type: "interface", + name, + loc, + }); export type GetAttribute = $.GetAttribute; -export const GetAttribute = (methodId: $e.Expression | undefined, loc: $c.Loc): $.GetAttribute => Object.freeze({ - methodId, - loc -}); +export const GetAttribute = ( + methodId: $e.Expression | undefined, + loc: $c.Loc, +): $.GetAttribute => + Object.freeze({ + methodId, + loc, + }); export type Method = $.Method; -export const Method = (mutates: boolean, overridable: boolean, override: boolean, get: $.GetAttribute | undefined, fun: $.Function): $.Method => Object.freeze({ - kind: "method", - mutates, - overridable, - override, - get, - fun -}); +export const Method = ( + mutates: boolean, + overridable: boolean, + override: boolean, + get: $.GetAttribute | undefined, + fun: $.Function, +): $.Method => + Object.freeze({ + kind: "method", + mutates, + overridable, + override, + get, + fun, + }); export const isMethod = ($value: Method) => $value.kind === "method"; export type ReceiverSimple = $.ReceiverSimple; -export const ReceiverSimple = (param: $t.TypedParameter): $.ReceiverSimple => Object.freeze({ - kind: "simple", - param -}); -export const isReceiverSimple = ($value: ReceiverSimple) => $value.kind === "simple"; +export const ReceiverSimple = (param: $t.TypedParameter): $.ReceiverSimple => + Object.freeze({ + kind: "simple", + param, + }); +export const isReceiverSimple = ($value: ReceiverSimple) => + $value.kind === "simple"; export type ReceiverFallback = $.ReceiverFallback; -export const ReceiverFallback = (): $.ReceiverFallback => Object.freeze({ - kind: "fallback" -}); -export const isReceiverFallback = ($value: ReceiverFallback) => $value.kind === "fallback"; +export const ReceiverFallback = (): $.ReceiverFallback => + Object.freeze({ + kind: "fallback", + }); +export const isReceiverFallback = ($value: ReceiverFallback) => + $value.kind === "fallback"; export type ReceiverComment = $.ReceiverComment; -export const ReceiverComment = (comment: $e.String): $.ReceiverComment => Object.freeze({ - kind: "comment", - comment -}); -export const isReceiverComment = ($value: ReceiverComment) => $value.kind === "comment"; +export const ReceiverComment = (comment: $e.String): $.ReceiverComment => + Object.freeze({ + kind: "comment", + comment, + }); +export const isReceiverComment = ($value: ReceiverComment) => + $value.kind === "comment"; export type ReceiverSubKind = $.ReceiverSubKind; export type ReceiverInternal = $.ReceiverInternal; -export const ReceiverInternal = (subKind: $.ReceiverSubKind, loc: $c.Loc): $.ReceiverInternal => Object.freeze({ - kind: "internal", - subKind, - loc -}); -export const isReceiverInternal = ($value: ReceiverInternal) => $value.kind === "internal"; +export const ReceiverInternal = ( + subKind: $.ReceiverSubKind, + loc: $c.Loc, +): $.ReceiverInternal => + Object.freeze({ + kind: "internal", + subKind, + loc, + }); +export const isReceiverInternal = ($value: ReceiverInternal) => + $value.kind === "internal"; export type ReceiverExternal = $.ReceiverExternal; -export const ReceiverExternal = (subKind: $.ReceiverSubKind, loc: $c.Loc): $.ReceiverExternal => Object.freeze({ - kind: "external", - subKind, - loc -}); -export const isReceiverExternal = ($value: ReceiverExternal) => $value.kind === "external"; +export const ReceiverExternal = ( + subKind: $.ReceiverSubKind, + loc: $c.Loc, +): $.ReceiverExternal => + Object.freeze({ + kind: "external", + subKind, + loc, + }); +export const isReceiverExternal = ($value: ReceiverExternal) => + $value.kind === "external"; export type ReceiverBounce = $.ReceiverBounce; -export const ReceiverBounce = (param: $t.TypedParameter, loc: $c.Loc): $.ReceiverBounce => Object.freeze({ - kind: "bounce", - param, - loc -}); -export const isReceiverBounce = ($value: ReceiverBounce) => $value.kind === "bounce"; +export const ReceiverBounce = ( + param: $t.TypedParameter, + loc: $c.Loc, +): $.ReceiverBounce => + Object.freeze({ + kind: "bounce", + param, + loc, + }); +export const isReceiverBounce = ($value: ReceiverBounce) => + $value.kind === "bounce"; export type ReceiverKind = $.ReceiverKind; export type Receiver = $.Receiver; -export const Receiver = (selector: $.ReceiverKind, statements: readonly $s.Statement[], loc: $c.Loc): $.Receiver => Object.freeze({ - kind: "receiver", - selector, - statements, - loc -}); +export const Receiver = ( + selector: $.ReceiverKind, + statements: readonly $s.Statement[], + loc: $c.Loc, +): $.Receiver => + Object.freeze({ + kind: "receiver", + selector, + statements, + loc, + }); export const isReceiver = ($value: Receiver) => $value.kind === "receiver"; export type FieldConstant = $.FieldConstant; -export const FieldConstant = (overridable: boolean, override: boolean, body: $.Constant): $.FieldConstant => Object.freeze({ - kind: "field_const", - overridable, - override, - body -}); -export const isFieldConstant = ($value: FieldConstant) => $value.kind === "field_const"; +export const FieldConstant = ( + overridable: boolean, + override: boolean, + body: $.Constant, +): $.FieldConstant => + Object.freeze({ + kind: "field_const", + overridable, + override, + body, + }); +export const isFieldConstant = ($value: FieldConstant) => + $value.kind === "field_const"; export type LocalItems = $.LocalItems; -export const LocalItems = (fields: readonly $.FieldDecl[], methods: readonly $.Method[], receivers: readonly $.Receiver[], constants: readonly $.FieldConstant[]): $.LocalItems => Object.freeze({ - fields, - methods, - receivers, - constants -}); +export const LocalItems = ( + fields: readonly $.FieldDecl[], + methods: readonly $.Method[], + receivers: readonly $.Receiver[], + constants: readonly $.FieldConstant[], +): $.LocalItems => + Object.freeze({ + fields, + methods, + receivers, + constants, + }); export type Contract = $.Contract; -export const Contract = (init: $.Init | undefined, name: $c.TypeId, traits: readonly $c.TypeId[], attributes: readonly $.ContractAttribute[], declarations: $.LocalItems, loc: $c.Loc): $.Contract => Object.freeze({ - kind: "contract", - init, - name, - traits, - attributes, - declarations, - loc -}); +export const Contract = ( + init: $.Init | undefined, + name: $c.TypeId, + traits: readonly $c.TypeId[], + attributes: readonly $.ContractAttribute[], + declarations: $.LocalItems, + loc: $c.Loc, +): $.Contract => + Object.freeze({ + kind: "contract", + init, + name, + traits, + attributes, + declarations, + loc, + }); export const isContract = ($value: Contract) => $value.kind === "contract"; export type Trait = $.Trait; -export const Trait = (name: $c.TypeId, traits: readonly $c.TypeId[], attributes: readonly $.ContractAttribute[], declarations: $.LocalItems, loc: $c.Loc): $.Trait => Object.freeze({ - kind: "trait", - name, - traits, - attributes, - declarations, - loc -}); +export const Trait = ( + name: $c.TypeId, + traits: readonly $c.TypeId[], + attributes: readonly $.ContractAttribute[], + declarations: $.LocalItems, + loc: $c.Loc, +): $.Trait => + Object.freeze({ + kind: "trait", + name, + traits, + attributes, + declarations, + loc, + }); export const isTrait = ($value: Trait) => $value.kind === "trait"; export type TypeDecl = $.TypeDecl; export type ModuleItems = $.ModuleItems; -export const ModuleItems = (functions: readonly $.Function[], constants: readonly $.Constant[], extensions: readonly $.Extension[], types: readonly $.TypeDecl[]): $.ModuleItems => Object.freeze({ - functions, - constants, - extensions, - types -}); +export const ModuleItems = ( + functions: readonly $.Function[], + constants: readonly $.Constant[], + extensions: readonly $.Extension[], + types: readonly $.TypeDecl[], +): $.ModuleItems => + Object.freeze({ + functions, + constants, + extensions, + types, + }); export type Module = $.Module; -export const Module = (imports: readonly $.Import[], items: $.ModuleItems): $.Module => Object.freeze({ - kind: "module", - imports, - items -}); +export const Module = ( + imports: readonly $.Import[], + items: $.ModuleItems, +): $.Module => + Object.freeze({ + kind: "module", + imports, + items, + }); export const isModule = ($value: Module) => $value.kind === "module"; export type Source = $.Source; -export const Source = (file: string | undefined, contents: string, root: $.Module): $.Source => Object.freeze({ - file, - contents, - root -}); \ No newline at end of file +export const Source = ( + file: string | undefined, + contents: string, + root: $.Module, +): $.Source => + Object.freeze({ + file, + contents, + root, + }); diff --git a/src/next/ast/generated/type.ts b/src/next/ast/generated/type.ts index 912ab6ce7f..4987d48f9c 100644 --- a/src/next/ast/generated/type.ts +++ b/src/next/ast/generated/type.ts @@ -83,10 +83,7 @@ export const TypeCell = (format: $.RemFormat, loc: $c.Loc): $.TypeCell => }); export const isTypeCell = ($value: TypeCell) => $value.kind === "TyCell"; export type TypeBuilder = $.TypeBuilder; -export const TypeBuilder = ( - format: $.RemFormat, - loc: $c.Loc, -): $.TypeBuilder => +export const TypeBuilder = (format: $.RemFormat, loc: $c.Loc): $.TypeBuilder => Object.freeze({ kind: "TyBuilder", format, @@ -149,77 +146,107 @@ export const TypeMap = (key: $.Type, value: $.Type, loc: $c.Loc): $.TypeMap => export const isTypeMap = ($value: TypeMap) => $value.kind === "map_type"; export type TypeVoid = $.TypeVoid; -export const TypeVoid = (loc: $c.Loc): $.TypeVoid => Object.freeze({ - kind: "TypeVoid", - loc -}); +export const TypeVoid = (loc: $c.Loc): $.TypeVoid => + Object.freeze({ + kind: "TypeVoid", + loc, + }); export const isTypeVoid = ($value: TypeVoid) => $value.kind === "TypeVoid"; export type TypeNull = $.TypeNull; -export const TypeNull = (loc: $c.Loc): $.TypeNull => Object.freeze({ - kind: "TypeNull", - loc -}); +export const TypeNull = (loc: $c.Loc): $.TypeNull => + Object.freeze({ + kind: "TypeNull", + loc, + }); export const isTypeNull = ($value: TypeNull) => $value.kind === "TypeNull"; export type TypeBool = $.TypeBool; -export const TypeBool = (loc: $c.Loc): $.TypeBool => Object.freeze({ - kind: "TypeBool", - loc -}); +export const TypeBool = (loc: $c.Loc): $.TypeBool => + Object.freeze({ + kind: "TypeBool", + loc, + }); export const isTypeBool = ($value: TypeBool) => $value.kind === "TypeBool"; export type TypeAddress = $.TypeAddress; -export const TypeAddress = (loc: $c.Loc): $.TypeAddress => Object.freeze({ - kind: "TypeAddress", - loc -}); -export const isTypeAddress = ($value: TypeAddress) => $value.kind === "TypeAddress"; +export const TypeAddress = (loc: $c.Loc): $.TypeAddress => + Object.freeze({ + kind: "TypeAddress", + loc, + }); +export const isTypeAddress = ($value: TypeAddress) => + $value.kind === "TypeAddress"; export type TypeString = $.TypeString; -export const TypeString = (loc: $c.Loc): $.TypeString => Object.freeze({ - kind: "TypeString", - loc -}); -export const isTypeString = ($value: TypeString) => $value.kind === "TypeString"; +export const TypeString = (loc: $c.Loc): $.TypeString => + Object.freeze({ + kind: "TypeString", + loc, + }); +export const isTypeString = ($value: TypeString) => + $value.kind === "TypeString"; export type TypeStringBuilder = $.TypeStringBuilder; -export const TypeStringBuilder = (loc: $c.Loc): $.TypeStringBuilder => Object.freeze({ - kind: "TypeStringBuilder", - loc -}); -export const isTypeStringBuilder = ($value: TypeStringBuilder) => $value.kind === "TypeStringBuilder"; +export const TypeStringBuilder = (loc: $c.Loc): $.TypeStringBuilder => + Object.freeze({ + kind: "TypeStringBuilder", + loc, + }); +export const isTypeStringBuilder = ($value: TypeStringBuilder) => + $value.kind === "TypeStringBuilder"; export type TypeBounced = $.TypeBounced; -export const TypeBounced = (type_: $.Type, loc: $c.Loc): $.TypeBounced => Object.freeze({ - kind: "TypeBounced", - type: type_, - loc -}); -export const isTypeBounced = ($value: TypeBounced) => $value.kind === "TypeBounced"; +export const TypeBounced = (type_: $.Type, loc: $c.Loc): $.TypeBounced => + Object.freeze({ + kind: "TypeBounced", + type: type_, + loc, + }); +export const isTypeBounced = ($value: TypeBounced) => + $value.kind === "TypeBounced"; export type TypeMaybe = $.TypeMaybe; -export const TypeMaybe = (type_: $.Type, loc: $c.Loc): $.TypeMaybe => Object.freeze({ - kind: "TypeMaybe", - type: type_, - loc -}); +export const TypeMaybe = (type_: $.Type, loc: $c.Loc): $.TypeMaybe => + Object.freeze({ + kind: "TypeMaybe", + type: type_, + loc, + }); export const isTypeMaybe = ($value: TypeMaybe) => $value.kind === "TypeMaybe"; export type TypedParameter = $.TypedParameter; -export const TypedParameter = (name: $c.OptionalId, type_: $.Type, loc: $c.Loc): $.TypedParameter => Object.freeze({ - name, - type: type_, - loc -}); +export const TypedParameter = ( + name: $c.OptionalId, + type_: $.Type, + loc: $c.Loc, +): $.TypedParameter => + Object.freeze({ + name, + type: type_, + loc, + }); export type FnType = $.FnType; -export const FnType = (typeParams: readonly $c.TypeId[], params: readonly $.TypedParameter[], returnType: $.Type): $.FnType => Object.freeze({ - typeParams, - params, - returnType -}); +export const FnType = ( + typeParams: readonly $c.TypeId[], + params: readonly $.TypedParameter[], + returnType: $.Type, +): $.FnType => + Object.freeze({ + typeParams, + params, + returnType, + }); export type MethodFnType = $.MethodFnType; -export const MethodFnType = (typeParams: readonly $c.TypeId[], self: $.Type, args: readonly $.TypedParameter[], returnType: $.Type): $.MethodFnType => Object.freeze({ - typeParams, - self, - args, - returnType -}); +export const MethodFnType = ( + typeParams: readonly $c.TypeId[], + self: $.Type, + args: readonly $.TypedParameter[], + returnType: $.Type, +): $.MethodFnType => + Object.freeze({ + typeParams, + self, + args, + returnType, + }); export type TypeStateInit = $.TypeStateInit; -export const TypeStateInit = (loc: $c.Loc): $.TypeStateInit => Object.freeze({ - kind: "TypeStateInit", - loc -}); -export const isTypeStateInit = ($value: TypeStateInit) => $value.kind === "TypeStateInit"; +export const TypeStateInit = (loc: $c.Loc): $.TypeStateInit => + Object.freeze({ + kind: "TypeStateInit", + loc, + }); +export const isTypeStateInit = ($value: TypeStateInit) => + $value.kind === "TypeStateInit"; diff --git a/src/next/ast/generated/value.ts b/src/next/ast/generated/value.ts index 9d433c9995..1f75cce599 100644 --- a/src/next/ast/generated/value.ts +++ b/src/next/ast/generated/value.ts @@ -3,10 +3,11 @@ import type { Loc } from "@/next/ast/common"; import type * as $ from "@/next/ast/value"; export type VNumber = $.VNumber; -export const VNumber = (value: bigint, loc: Loc): $.VNumber => Object.freeze({ - kind: "number", - value, - loc -}); +export const VNumber = (value: bigint, loc: Loc): $.VNumber => + Object.freeze({ + kind: "number", + value, + loc, + }); export const isVNumber = ($value: VNumber) => $value.kind === "number"; export type Value = $.Value; diff --git a/src/next/ast/generated/via.ts b/src/next/ast/generated/via.ts index cba60e1793..6cd1e64a19 100644 --- a/src/next/ast/generated/via.ts +++ b/src/next/ast/generated/via.ts @@ -8,42 +8,46 @@ export type ViaBuiltin = $.ViaBuiltin; export type ViaUser = $.ViaUser; export type ViaMember = $.ViaMember; -export const ViaBuiltin = (): $.ViaBuiltin => ({ kind: 'builtin' }); +export const ViaBuiltin = (): $.ViaBuiltin => ({ kind: "builtin" }); // when something was just defined export const ViaOrigin = (defLoc: $c.Loc, source: TactSource): $.ViaUser => { const result: $.ViaUser = { - kind: 'user', + kind: "user", imports: [], defLoc, source, }; - hideProperty(result, 'source'); + hideProperty(result, "source"); return result; }; // when it came through an import -export const ViaImport = (throughImport: TactImport, via: $.ViaUser): $.ViaUser => { +export const ViaImport = ( + throughImport: TactImport, + via: $.ViaUser, +): $.ViaUser => { const result: $.ViaUser = { - kind: 'user', + kind: "user", imports: [throughImport, ...via.imports], defLoc: via.defLoc, source: via.source, }; - hideProperty(result, 'source'); + hideProperty(result, "source"); return result; }; export const ViaMemberOrigin = ( parentName: string, - defLoc: $c.Loc + defLoc: $c.Loc, ): $.ViaMember => ({ defLoc, parentName, traits: [] }); export const ViaMemberTrait = ( parentName: string, defLoc: $c.Loc, via: $.ViaMember, -): $.ViaMember => ({ defLoc, parentName, traits: [ - [via.parentName, via.defLoc], - ...via.traits -] }); +): $.ViaMember => ({ + defLoc, + parentName, + traits: [[via.parentName, via.defLoc], ...via.traits], +}); diff --git a/src/next/ast/lazy.ts b/src/next/ast/lazy.ts index f6c7f589cf..be2d2b7ef2 100644 --- a/src/next/ast/lazy.ts +++ b/src/next/ast/lazy.ts @@ -2,27 +2,27 @@ import type { Loc } from "@/next/ast/common"; import * as E from "@/next/ast/errors"; -type Result = 'waiting' | 'running' | readonly [T]; +type Result = "waiting" | "running" | readonly [T]; export const printSym = Symbol("print"); export type Thunk = { - [printSym]: () => Result -} & (() => E.WithLog) + [printSym]: () => Result; +} & (() => E.WithLog); function Thunk( force: () => E.WithLog, onOccurs: () => E.WithLog, ): Thunk { - let result: Result = 'waiting'; + let result: Result = "waiting"; function* delayed() { - if (typeof result !== 'string') { + if (typeof result !== "string") { return result[0]; } - if (result === 'running') { + if (result === "running") { return yield* onOccurs(); } - result = 'running'; + result = "running"; const output = yield* force(); result = [output]; return output; @@ -44,25 +44,22 @@ export const FakeThunk = (t: T): Thunk => { }; type Options = { - readonly loc: Loc, - readonly context: readonly E.TELine[], - readonly recover: T, - readonly callback: ( - builder: ThunkBuilder - ) => E.WithLog -} + readonly loc: Loc; + readonly context: readonly E.TELine[]; + readonly recover: T; + readonly callback: (builder: ThunkBuilder) => E.WithLog; +}; -export type ThunkBuilder = ( - options: Options -) => Thunk; +export type ThunkBuilder = (options: Options) => Thunk; const makeBuilder = (allContext: readonly E.TELine[]): ThunkBuilder => { return function addThunk(options: Options): Thunk { return Thunk( function force() { - const nextBuilder = makeBuilder( - [...options.context, ...allContext] - ); + const nextBuilder = makeBuilder([ + ...options.context, + ...allContext, + ]); return options.callback(nextBuilder); }, function* onOccurs() { @@ -75,10 +72,7 @@ const makeBuilder = (allContext: readonly E.TELine[]): ThunkBuilder => { const EOccurs = (loc: Loc, context: readonly E.TELine[]): E.TcError => ({ loc, - descr: [ - E.TEText(`Recursive definition`), - ...context, - ], + descr: [E.TEText(`Recursive definition`), ...context], }); export const thunkBuilder = makeBuilder([]); diff --git a/src/next/ast/lowered.ts b/src/next/ast/lowered.ts new file mode 100644 index 0000000000..a11c19ee5e --- /dev/null +++ b/src/next/ast/lowered.ts @@ -0,0 +1,239 @@ +import type { Effects } from "@/next/ast/effects"; +import type { DecodedStatement } from "@/next/ast/checked-stmt"; +import type { FuncId, Loc, OptionalId, TypeId } from "@/next/ast/common"; +import type { DecodedType, DTypeRef, DTypeBounced } from "@/next/ast/dtype"; +import type { SelfType } from "@/next/ast/mtype"; +import type { + AsmInstruction, + AsmShuffle, + ContractAttribute, +} from "@/next/ast/root"; +import type { Value } from "@/next/ast/value"; + +export type LAst = { + readonly typeDecls: ReadonlyMap; + readonly functions: ReadonlyMap; + readonly constants: ReadonlyMap; + readonly extensions: ReadonlyMap; +}; + +export type LTypeDeclSig = + | LAliasSig + | LContractSig + | LTraitSig + | LStructSig + | LMessageSig + | LUnionSig; + +export type LConstSig = { + readonly initializer: Value; + readonly type: DecodedType; +}; + +export type LFnSig = { + readonly type: LDecodedFnType; + readonly inline: boolean; + readonly body: LBody; +}; + +export type LStatements = { + readonly body: readonly DecodedStatement[]; + readonly effects: Effects; +}; + +export type LBody = LTactBody | LFuncBody | LFiftBody; + +export type LTactBody = { + readonly kind: "tact"; + readonly statements: LStatements; +}; +export type LFuncBody = { + readonly kind: "func"; + readonly nativeName: FuncId; +}; +export type LFiftBody = { + readonly kind: "fift"; + readonly shuffle: AsmShuffle; + readonly instructions: readonly AsmInstruction[]; +}; + +export type LExtSig = { + readonly type: LDecodedMethodType; + readonly inline: boolean; + readonly body: LBody; +}; + +export type LAliasSig = { + readonly kind: "alias"; + readonly typeParams: LTypeParams; + readonly type: DecodedType; +}; + +export type LInitSig = LInitEmpty | LInitSimple | LInitFn; +export type LInitEmpty = { + readonly kind: "empty"; + // initOf() would take 0 parameters + // values to fill all the fields + readonly fill: LOrdered; +}; +export type LInitSimple = { + readonly kind: "simple"; + // initOf() takes these parameters and + // sets them into correspondingly named fields + readonly fill: LOrdered; + readonly loc: Loc; +}; +export type LInitFn = { + readonly kind: "function"; + // here we just specify the function + readonly params: LParameters; + readonly statements: LStatements; +}; +export type LInitParam = { + readonly type: DecodedType; + readonly init: undefined | Value; + readonly loc: Loc; +}; + +export type LContractSig = { + readonly kind: "contract"; + readonly attributes: readonly ContractAttribute[]; + readonly init: LInitSig; + readonly content: LContractContent; +}; +export type LContractContent = LCommonSig; +export type LTraitSig = { + readonly kind: "trait"; + readonly content: LTraitContent; +}; +export type LTraitContent = LCommonSig; +export type LCommonSig = { + readonly fieldish: LOrdered>; + readonly methods: ReadonlyMap>; + readonly receivers: LReceivers; +}; +export type LReceivers = { + readonly bounce: LBounceSig; + readonly internal: LRecvSig; + readonly external: LRecvSig; +}; + +export type LFieldish = LInhFieldSig | LFieldConstSig; +export type LInhFieldSig = { + readonly kind: "field"; + readonly type: DecodedType; + readonly init: Value | undefined; +}; +export type LFieldConstSig = { + readonly kind: "constant"; + readonly overridable: boolean; + readonly type: DecodedType; + readonly init: Expr; +}; + +export type LMethodSig = { + readonly overridable: boolean; + readonly type: LDecodedMethodType; + readonly inline: boolean; + readonly body: Body; + readonly getMethodId: bigint | undefined; +}; + +export type LBounceSig = { + // NB! can't compute opcodes until all receivers are present + readonly message: readonly LMessageRecv[]; + readonly messageAny: undefined | LMessageAnyRecv; +}; + +export type LRecvSig = { + // NB! can't compute opcodes until all receivers are present + readonly message: readonly LOpcodeRecv[]; + readonly messageAny: undefined | LMessageAnyRecv; + readonly stringAny: undefined | LStringAnyRecv; + readonly empty: undefined | LEmptyRecv; +}; + +export type LOpcodeRecv = LMessageRecv | LStringRecv; +export type LMessageRecv = { + readonly kind: "binary"; + readonly name: OptionalId; + readonly type: DTypeRef | DTypeBounced; + readonly statements: LStatements; +}; +export type LMessageAnyRecv = { + readonly name: OptionalId; + readonly statements: LStatements; +}; +export type LStringRecv = { + readonly kind: "string"; + readonly comment: string; + readonly statements: LStatements; +}; +export type LStringAnyRecv = { + readonly name: OptionalId; + readonly statements: LStatements; +}; +export type LEmptyRecv = { + readonly statements: LStatements; +}; + +export type LStructSig = { + readonly kind: "struct"; + readonly typeParams: LTypeParams; + readonly fields: LOrdered; +}; + +export type LMessageSig = { + readonly kind: "message"; + readonly opcode: bigint; + readonly fields: LOrdered; +}; + +export type LUnionSig = { + readonly kind: "union"; + readonly typeParams: LTypeParams; + readonly cases: ReadonlyMap>; +}; + +export type LDecodedFnType = { + readonly kind: "DecodedFnType"; + readonly typeParams: LTypeParams; + readonly params: LParameters; + readonly returnType: DecodedType; +}; + +export type LDecodedMethodType = { + readonly kind: "DecodedMethodType"; + readonly mutates: boolean; + readonly typeParams: LTypeParams; + readonly self: SelfType; + readonly params: LParameters; + readonly returnType: DecodedType; +}; + +export type LDecodedParameter = { + readonly name: OptionalId; + readonly type: DecodedType; + readonly loc: Loc; +}; + +export type LOrdered = { + readonly order: readonly string[]; + readonly map: ReadonlyMap; +}; + +export type LParameters = { + readonly order: readonly LParameter[]; + readonly set: ReadonlySet; +}; + +export type LParameter = { + readonly name: OptionalId; + readonly type: DecodedType; + readonly loc: Loc; +}; + +export type LTypeParams = { + readonly order: readonly TypeId[]; + readonly set: ReadonlySet; +}; diff --git a/src/next/ast/mtype.ts b/src/next/ast/mtype.ts index 5f21889411..7804502bc5 100644 --- a/src/next/ast/mtype.ts +++ b/src/next/ast/mtype.ts @@ -31,24 +31,24 @@ export type MethodGroundType = | MGTypeStringBuilder; export type Ground = T & { - readonly ground: "yes", -} + readonly ground: "yes"; +}; -export type MGTypeInt = Ground -export type MGTypeSlice = Ground -export type MGTypeCell = Ground -export type MGTypeBuilder = Ground -export type MGTypeUnit = Ground -export type MGTypeVoid = Ground -export type MGTypeNull = Ground -export type MGTypeBool = Ground -export type MGTypeAddress = Ground -export type MGTypeStateInit = Ground -export type MGTypeString = Ground -export type MGTypeStringBuilder = Ground +export type MGTypeInt = Ground; +export type MGTypeSlice = Ground; +export type MGTypeCell = Ground; +export type MGTypeBuilder = Ground; +export type MGTypeUnit = Ground; +export type MGTypeVoid = Ground; +export type MGTypeNull = Ground; +export type MGTypeBool = Ground; +export type MGTypeAddress = Ground; +export type MGTypeStateInit = Ground; +export type MGTypeString = Ground; +export type MGTypeStringBuilder = Ground; export type MGTypeRef = { - readonly ground: "yes", + readonly ground: "yes"; readonly kind: "type_ref"; readonly name: TypeId; readonly type: TypeDeclRefable; @@ -58,10 +58,10 @@ export type MGTypeRef = { export type MGTypeMaybe = { readonly ground: "yes"; - readonly kind: "TypeMaybe" + readonly kind: "TypeMaybe"; readonly type: MethodGroundType; readonly loc: Loc; -} +}; export type MGTypeMap = { readonly ground: "yes"; @@ -85,10 +85,8 @@ export type MGTypeTensor = { readonly loc: Loc; }; - - export type MVTypeRef = { - readonly ground: "no", + readonly ground: "no"; readonly kind: "type_ref"; readonly name: TypeId; readonly type: TypeDeclRefable; @@ -97,14 +95,14 @@ export type MVTypeRef = { }; export type MVTypeMaybe = { - readonly ground: "no", - readonly kind: "TypeMaybe" + readonly ground: "no"; + readonly kind: "TypeMaybe"; readonly type: DTypeParamRef; readonly loc: Loc; -} +}; export type MVTypeMap = { - readonly ground: "no", + readonly ground: "no"; readonly kind: "map_type"; readonly key: DTypeParamRef; readonly value: DTypeParamRef; @@ -112,14 +110,14 @@ export type MVTypeMap = { }; export type MVTypeTuple = { - readonly ground: "no", + readonly ground: "no"; readonly kind: "tuple_type"; readonly typeArgs: readonly DTypeParamRef[]; readonly loc: Loc; }; export type MVTypeTensor = { - readonly ground: "no", + readonly ground: "no"; readonly kind: "tensor_type"; readonly typeArgs: readonly DTypeParamRef[]; readonly loc: Loc; diff --git a/src/next/ast/root.ts b/src/next/ast/root.ts index 8a70532908..9484165a38 100644 --- a/src/next/ast/root.ts +++ b/src/next/ast/root.ts @@ -1,10 +1,4 @@ -import type { - FuncId, - Id, - Loc, - TypeId, - Language, -} from "@/next/ast/common"; +import type { FuncId, Id, Loc, TypeId, Language } from "@/next/ast/common"; import type { Expression, Number, String } from "@/next/ast/expression"; import type { Statement } from "@/next/ast/statement"; import type { FnType, Type, TypedParameter } from "@/next/ast/type"; @@ -26,7 +20,7 @@ export type ModuleItems = { readonly constants: readonly Constant[]; readonly extensions: readonly Extension[]; readonly types: readonly TypeDecl[]; -} +}; export type TypeDecl = | StructDecl | MessageDecl @@ -154,7 +148,7 @@ export type FieldConstant = { readonly overridable: boolean; readonly override: boolean; readonly body: Constant; -} +}; export type Constant = { readonly kind: "constant"; readonly name: Id; diff --git a/src/next/ast/type.ts b/src/next/ast/type.ts index 0689d6b723..c16945f15b 100644 --- a/src/next/ast/type.ts +++ b/src/next/ast/type.ts @@ -3,15 +3,15 @@ import type { Loc, OptionalId, TypeId } from "@/next/ast/common"; export type FnType = { readonly typeParams: readonly TypeId[]; readonly params: readonly TypedParameter[]; - readonly returnType: Type, -} + readonly returnType: Type; +}; export type MethodFnType = { readonly typeParams: readonly TypeId[]; readonly self: Type; readonly args: readonly TypedParameter[]; - readonly returnType: Type, -} + readonly returnType: Type; +}; export type TypedParameter = { readonly name: OptionalId; @@ -47,51 +47,51 @@ export type TypeCons = { }; export type TypeVoid = { - readonly kind: "TypeVoid" + readonly kind: "TypeVoid"; readonly loc: Loc; -} +}; export type TypeNull = { - readonly kind: "TypeNull" + readonly kind: "TypeNull"; readonly loc: Loc; -} +}; export type TypeBool = { - readonly kind: "TypeBool" + readonly kind: "TypeBool"; readonly loc: Loc; -} +}; export type TypeAddress = { - readonly kind: "TypeAddress" + readonly kind: "TypeAddress"; readonly loc: Loc; -} +}; export type TypeStateInit = { - readonly kind: "TypeStateInit" + readonly kind: "TypeStateInit"; readonly loc: Loc; -} +}; export type TypeString = { - readonly kind: "TypeString" + readonly kind: "TypeString"; readonly loc: Loc; -} +}; export type TypeStringBuilder = { - readonly kind: "TypeStringBuilder" + readonly kind: "TypeStringBuilder"; readonly loc: Loc; -} +}; export type TypeBounced = { - readonly kind: "TypeBounced" + readonly kind: "TypeBounced"; readonly type: Type; readonly loc: Loc; -} +}; export type TypeMaybe = { - readonly kind: "TypeMaybe" + readonly kind: "TypeMaybe"; readonly type: Type; readonly loc: Loc; -} +}; export type TypeInt = { readonly kind: "TyInt"; diff --git a/src/next/ast/value.ts b/src/next/ast/value.ts index 90f5925b6d..9ba2f39770 100644 --- a/src/next/ast/value.ts +++ b/src/next/ast/value.ts @@ -1,10 +1,10 @@ import type { Loc } from "@/next/ast/common"; -export type Value = VNumber +export type Value = VNumber; export type VNumber = { - readonly kind: 'number'; + readonly kind: "number"; readonly value: bigint; // loc of expression that resulted in this value readonly loc: Loc; -} +}; diff --git a/src/next/ast/via.ts b/src/next/ast/via.ts index 176f3963c6..a7bf9e0876 100644 --- a/src/next/ast/via.ts +++ b/src/next/ast/via.ts @@ -3,25 +3,25 @@ import type { TactImport, TactSource } from "@/next/imports/source"; import type * as Ast from "@/next/ast"; // provenance for definition: where did it come from -export type Via = ViaUser | ViaBuiltin +export type Via = ViaUser | ViaBuiltin; // is defined in compiler, always was there export type ViaBuiltin = { - readonly kind: 'builtin'; -} + readonly kind: "builtin"; +}; export type ViaUser = { - readonly kind: 'user'; + readonly kind: "user"; // which imports it came through readonly imports: readonly TactImport[]; // where in the code it was defined readonly defLoc: Ast.Loc; // in which source readonly source: TactSource; -} +}; export type ViaMember = { readonly traits: readonly [string, Ast.Loc][]; readonly defLoc: Ast.Loc; readonly parentName: string; -} +}; diff --git a/src/next/fs/proxy-fs.ts b/src/next/fs/proxy-fs.ts index e39f9e396b..a97d27d608 100644 --- a/src/next/fs/proxy-fs.ts +++ b/src/next/fs/proxy-fs.ts @@ -19,7 +19,11 @@ type Options = { /** * Create file system that proxies requests to real file system */ -export function createProxyFs({ log, root, isReadonly }: Options): Cursor { +export function createProxyFs({ + log, + root, + isReadonly, +}: Options): Cursor { const errors = FsErrors(log); function builder(currPath: RelativePath): Cursor { diff --git a/src/next/grammar/errors.ts b/src/next/grammar/errors.ts index afcbf33789..b5df4ab185 100644 --- a/src/next/grammar/errors.ts +++ b/src/next/grammar/errors.ts @@ -57,7 +57,9 @@ export const SyntaxErrors = (l: SourceLogger) => ({ return l.at(loc).error(l.text`Expression is not callable`); }, noGenericMethods: () => (loc: Range) => { - return l.at(loc).error(l.text`Cannot pass type arguments to generic method`); + return l + .at(loc) + .error(l.text`Cannot pass type arguments to generic method`); }, noBouncedWithoutArg: () => (loc: Range) => { return l @@ -168,7 +170,9 @@ export const SyntaxErrors = (l: SourceLogger) => ({ return l.at(loc).error(l.text`"as" cannot be nested`); }, typeArity: (name: string, expected: number) => (loc: Range) => { - return l.at(loc).error(l.text`${name}<> expects ${String(expected)} arguments`); + return l + .at(loc) + .error(l.text`${name}<> expects ${String(expected)} arguments`); }, wrongVarIntSize: () => (loc: Range) => { return l.at(loc).error(l.text`Varint can only be 16 or 32 bits wide`); @@ -219,10 +223,18 @@ export const SyntaxErrors = (l: SourceLogger) => ({ return l.at(loc).error(l.text`set takes exactly one type argument`); }, abstractVirtual: () => (loc: Range) => { - return l.at(loc).error(l.text`"abstract" and "virtual" attributes cannot be used at the same time`); + return l + .at(loc) + .error( + l.text`"abstract" and "virtual" attributes cannot be used at the same time`, + ); }, abstractOverride: () => (loc: Range) => { - return l.at(loc).error(l.text`"abstract" and "override" attributes cannot be used at the same time`); + return l + .at(loc) + .error( + l.text`"abstract" and "override" attributes cannot be used at the same time`, + ); }, globalGetter: () => (loc: Range) => { return l @@ -263,11 +275,7 @@ export const SyntaxErrors = (l: SourceLogger) => ({ ); }, tooMuchInit: () => (loc: Range) => { - return l - .at(loc) - .error( - l.text`Init function was already defined`, - ); + return l.at(loc).error(l.text`Init function was already defined`); }, initFnAndParams: () => (loc: Range) => { return l @@ -277,25 +285,15 @@ export const SyntaxErrors = (l: SourceLogger) => ({ ); }, abstractWithBody: () => (loc: Range) => { - return l - .at(loc) - .error( - l.text`Abstract declaration cannot have a body`, - ); + return l.at(loc).error(l.text`Abstract declaration cannot have a body`); }, noBodyNoAbstract: () => (loc: Range) => { return l .at(loc) - .error( - l.text`Declaration without a body must be abstract`, - ); + .error(l.text`Declaration without a body must be abstract`); }, mustBeGeneric: () => (loc: Range) => { - return l - .at(loc) - .error( - l.text`This type must be generic`, - ); + return l.at(loc).error(l.text`This type must be generic`); }, }); diff --git a/src/next/grammar/grammar.ts b/src/next/grammar/grammar.ts index e9fa4bda9f..c37d653f2b 100644 --- a/src/next/grammar/grammar.ts +++ b/src/next/grammar/grammar.ts @@ -6,653 +6,2947 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ import * as $ from "@tonstudio/parser-runtime"; export namespace $ast { - export type Module = $.Located<{ - readonly $: "Module"; - readonly imports: readonly Import[]; - readonly items: readonly moduleItem[]; - }>; - export type Import = $.Located<{ - readonly $: "Import"; - readonly path: StringLiteral; - }>; - export type PrimitiveTypeDecl = $.Located<{ - readonly $: "PrimitiveTypeDecl"; - readonly name: TypeId; - }>; - export type $Function = $.Located<{ - readonly $: "Function"; - readonly attributes: readonly FunctionAttribute[]; - readonly name: Id; - readonly typeParams: typeParams | undefined; - readonly parameters: parameterList; - readonly returnType: ascription | undefined; - readonly body: FunctionDefinition | FunctionDeclaration; - }>; - export type AsmFunction = $.Located<{ - readonly $: "AsmFunction"; - readonly shuffle: shuffle | undefined; - readonly attributes: readonly FunctionAttribute[]; - readonly name: Id; - readonly typeParams: typeParams | undefined; - readonly parameters: parameterList; - readonly returnType: ascription | undefined; - readonly instructions: assembly; - }>; - export type NativeFunctionDecl = $.Located<{ - readonly $: "NativeFunctionDecl"; - readonly nativeName: FuncId; - readonly attributes: readonly FunctionAttribute[]; - readonly name: Id; - readonly typeParams: typeParams | undefined; - readonly parameters: parameterList; - readonly returnType: ascription | undefined; - }>; - export type Constant = $.Located<{ - readonly $: "Constant"; - readonly attributes: readonly ConstantAttribute[]; - readonly name: Id; - readonly type: ascription | undefined; - readonly body: ConstantDefinition | ConstantDeclaration; - }>; - export type StructDecl = $.Located<{ - readonly $: "StructDecl"; - readonly name: TypeId; - readonly typeParams: typeParams | undefined; - readonly fields: structFields; - }>; - export type MessageDecl = $.Located<{ - readonly $: "MessageDecl"; - readonly opcode: expression | undefined; - readonly name: TypeId; - readonly fields: structFields; - }>; - export type UnionDecl = $.Located<{ - readonly $: "UnionDecl"; - readonly name: TypeId; - readonly typeParams: typeParams | undefined; - readonly cases: readonly Case[]; - }>; - export type AliasDecl = $.Located<{ - readonly $: "AliasDecl"; - readonly name: TypeId; - readonly typeParams: typeParams | undefined; - readonly type: $type; - }>; - export type Contract = $.Located<{ - readonly $: "Contract"; - readonly attributes: readonly ContractAttribute[]; - readonly name: TypeId; - readonly parameters: ParameterList | undefined; - readonly traits: inheritedTraits | undefined; - readonly declarations: readonly contractItemDecl[]; - }>; - export type Trait = $.Located<{ - readonly $: "Trait"; - readonly attributes: readonly ContractAttribute[]; - readonly name: TypeId; - readonly traits: inheritedTraits | undefined; - readonly declarations: readonly traitItemDecl[]; - }>; - export type moduleItem = PrimitiveTypeDecl | $Function | AsmFunction | NativeFunctionDecl | Constant | StructDecl | MessageDecl | UnionDecl | AliasDecl | Contract | Trait; - export type ContractInit = $.Located<{ - readonly $: "ContractInit"; - readonly parameters: parameterList; - readonly body: statements; - }>; - export type Receiver = $.Located<{ - readonly $: "Receiver"; - readonly type: ReceiverType; - readonly param: receiverParam; - readonly body: statements; - }>; - export type FieldDecl = $.Located<{ - readonly $: "FieldDecl"; - readonly name: Id; - readonly type: ascription; - readonly expression: expression | undefined; - }>; - export type semicolon = ";" | "}"; - export type storageVar = FieldDecl; - export type contractItemDecl = ContractInit | Receiver | $Function | AsmFunction | Constant | storageVar; - export type traitItemDecl = Receiver | $Function | AsmFunction | Constant | storageVar; - export type FunctionDefinition = $.Located<{ - readonly $: "FunctionDefinition"; - readonly body: statements; - }>; - export type FunctionDeclaration = $.Located<{ - readonly $: "FunctionDeclaration"; - }>; - export type Id = $.Located<{ - readonly $: "Id"; - readonly name: string; - }>; - export type IntegerLiteralDec = $.Located<{ - readonly $: "IntegerLiteralDec"; - readonly digits: underscored; - }>; - export type shuffle = { - readonly ids: readonly Id[]; - readonly to: readonly IntegerLiteralDec[] | undefined; - }; - export type ConstantAttribute = $.Located<{ - readonly $: "ConstantAttribute"; - readonly name: keyword<"virtual"> | keyword<"override"> | keyword<"abstract">; - }>; - export type ConstantDefinition = $.Located<{ - readonly $: "ConstantDefinition"; - readonly expression: expression; - }>; - export type ConstantDeclaration = $.Located<{ - readonly $: "ConstantDeclaration"; - }>; - export type Case = $.Located<{ - readonly $: "Case"; - readonly name: TypeId; - readonly fields: structFields; - }>; - export type inter = { - readonly head: A; - readonly tail: readonly { - readonly op: B; - readonly right: A; - }[]; - }; - export type structFields = inter | undefined; - export type keyword = T; - export type commaList = inter; - export type TypeId = $.Located<{ - readonly $: "TypeId"; - readonly name: string; - }>; - export type inheritedTraits = commaList; - export type ContractAttribute = $.Located<{ - readonly $: "ContractAttribute"; - readonly name: StringLiteral; - }>; - export type FunctionAttribute = $.Located<{ - readonly $: "FunctionAttribute"; - readonly name: GetAttribute | keyword<"mutates"> | keyword<"extends"> | keyword<"virtual"> | keyword<"override"> | keyword<"inline"> | keyword<"abstract">; - }>; - export type GetAttribute = $.Located<{ - readonly $: "GetAttribute"; - readonly methodId: expression | undefined; - }>; - export type ReceiverType = $.Located<{ - readonly $: "ReceiverType"; - readonly name: "bounced" | keyword<"receive"> | keyword<"external">; - }>; - export type Parameter = $.Located<{ - readonly $: "Parameter"; - readonly name: Id; - readonly type: ascription; - }>; - export type StringLiteral = $.Located<{ - readonly $: "StringLiteral"; - readonly value: string; - }>; - export type receiverParam = Parameter | StringLiteral | undefined; - export type assembly = string; - export type multiLineComment = string; - export type singleLineComment = string; - export type comment = multiLineComment | singleLineComment; - export type assemblyItem = {} | comment | {} | readonly {}[]; - export type assemblySequence = readonly assemblyItem[]; - export type TypeAs = $.Located<{ - readonly $: "TypeAs"; - readonly type: TypeOptional; - readonly as: readonly storage[]; - }>; - export type $type = TypeAs; - export type ascription = $type; - export type TypeOptional = $.Located<{ - readonly $: "TypeOptional"; - readonly type: typePrimary; - readonly optionals: readonly Optional[]; - }>; - export type Optional = $.Located<{ - readonly $: "Optional"; - }>; - export type TypeGeneric = $.Located<{ - readonly $: "TypeGeneric"; - readonly name: MapKeyword | Bounced | TypeId; - readonly args: typeArgs; - }>; - export type TypeRegular = $.Located<{ - readonly $: "TypeRegular"; - readonly child: TypeId; - }>; - export type TypeStorage = $.Located<{ - readonly $: "TypeStorage"; - readonly child: storage; - }>; - export type TypeTuple = $.Located<{ - readonly $: "TypeTuple"; - readonly types: commaList<$type> | undefined; - }>; - export type TypeTensor = $.Located<{ - readonly $: "TypeTensor"; - readonly head: $type; - readonly tail: readonly $type[]; - }>; - export type TypeUnit = $.Located<{ - readonly $: "TypeUnit"; - }>; - export type typeParens = $type; - export type typePrimary = TypeGeneric | TypeRegular | TypeStorage | TypeTuple | TypeTensor | TypeUnit | typeParens; - export type MapKeyword = $.Located<{ - readonly $: "MapKeyword"; - }>; - export type Bounced = $.Located<{ - readonly $: "Bounced"; - }>; - export type IntStorage = $.Located<{ - readonly $: "IntStorage"; - readonly isVar: "var" | undefined; - readonly isUnsigned: "u" | undefined; - readonly width: string; - }>; - export type CoinsStorage = $.Located<{ - readonly $: "CoinsStorage"; - }>; - export type RemainingStorage = $.Located<{ - readonly $: "RemainingStorage"; - }>; - export type BytesStorage = $.Located<{ - readonly $: "BytesStorage"; - readonly width: string; - }>; - export type storage = IntStorage | CoinsStorage | RemainingStorage | BytesStorage; - export type generic = commaList | undefined; - export type typeParams = generic; - export type typeArgs = generic<$type>; - export type StatementLet = $.Located<{ - readonly $: "StatementLet"; - readonly name: Id; - readonly type: ascription | undefined; - readonly init: expression; - }>; - export type StatementDestruct = $.Located<{ - readonly $: "StatementDestruct"; - readonly type: TypeId; - readonly typeArgs: typeArgs | undefined; - readonly fields: inter; - readonly rest: optionalRest; - readonly init: expression; - }>; - export type StatementBlock = $.Located<{ - readonly $: "StatementBlock"; - readonly body: statements; - }>; - export type StatementReturn = $.Located<{ - readonly $: "StatementReturn"; - readonly expression: expression | undefined; - }>; - export type StatementCondition = $.Located<{ - readonly $: "StatementCondition"; - readonly condition: expression; - readonly trueBranch: statements; - readonly falseBranch: FalseBranch | StatementCondition | undefined; - }>; - export type StatementWhile = $.Located<{ - readonly $: "StatementWhile"; - readonly condition: parens; - readonly body: statements; - }>; - export type StatementRepeat = $.Located<{ - readonly $: "StatementRepeat"; - readonly condition: parens; - readonly body: statements; - }>; - export type StatementUntil = $.Located<{ - readonly $: "StatementUntil"; - readonly body: statements; - readonly condition: parens; - }>; - export type StatementTry = $.Located<{ - readonly $: "StatementTry"; - readonly body: statements; - readonly handler: { - readonly name: Id; - readonly body: statements; - } | undefined; - }>; - export type StatementForEach = $.Located<{ - readonly $: "StatementForEach"; - readonly key: Id; - readonly value: Id; - readonly expression: expression; - readonly body: statements; - }>; - export type StatementExpression = $.Located<{ - readonly $: "StatementExpression"; - readonly expression: expression; - }>; - export type StatementAssign = $.Located<{ - readonly $: "StatementAssign"; - readonly left: expression; - readonly operator: augmentedOp | "="; - readonly right: expression; - }>; - export type statement = StatementLet | StatementDestruct | StatementBlock | StatementReturn | StatementCondition | StatementWhile | StatementRepeat | StatementUntil | StatementTry | StatementForEach | StatementExpression | StatementAssign; - export type statements = readonly statement[]; - export type augmentedOp = "||=" | "&&=" | ">>=" | "<<=" | "-=" | "+=" | "*=" | "/=" | "%=" | "|=" | "&=" | "^="; - export type FalseBranch = $.Located<{ - readonly $: "FalseBranch"; - readonly body: statements; - }>; - export type RegularField = $.Located<{ - readonly $: "RegularField"; - readonly fieldName: Id; - readonly varName: Id; - }>; - export type PunnedField = $.Located<{ - readonly $: "PunnedField"; - readonly name: Id; - }>; - export type destructItem = RegularField | PunnedField; - export type RestArgument = $.Located<{ - readonly $: "RestArgument"; - }>; - export type NoRestArgument = $.Located<{ - readonly $: "NoRestArgument"; - }>; - export type optionalRest = RestArgument | NoRestArgument; - export type Conditional = $.Located<{ - readonly $: "Conditional"; - readonly head: or; - readonly tail: { - readonly thenBranch: or; - readonly elseBranch: Conditional; - } | undefined; - }>; - export type expression = Conditional; - export type Binary = $.Located<{ - readonly $: "Binary"; - readonly exprs: inter>; - }>; - export type Unary = $.Located<{ - readonly $: "Unary"; - readonly prefixes: readonly Operator<"-" | "+" | "!" | "~">[]; - readonly expression: Suffix; - }>; - export type mul = Binary; - export type add = Binary; - export type bitwiseShift = Binary>">; - export type compare = Binary=" | ">">; - export type equality = Binary; - export type bitwiseXor = Binary; - export type bitwiseOr = Binary; - export type and = Binary; - export type or = Binary; - export type Suffix = $.Located<{ - readonly $: "Suffix"; - readonly expression: primary; - readonly suffixes: readonly suffix[]; - }>; - export type Operator = $.Located<{ - readonly $: "Operator"; - readonly name: U; - }>; - export type SuffixUnboxNotNull = $.Located<{ - readonly $: "SuffixUnboxNotNull"; - }>; - export type SuffixCall = $.Located<{ - readonly $: "SuffixCall"; - readonly typeArgs: typeArgs | undefined; - readonly params: parameterList; - }>; - export type SuffixFieldAccess = $.Located<{ - readonly $: "SuffixFieldAccess"; - readonly name: Id; - }>; - export type suffix = SuffixUnboxNotNull | SuffixCall | SuffixFieldAccess; - export type Unit = $.Located<{ - readonly $: "Unit"; - }>; - export type Tensor = $.Located<{ - readonly $: "Tensor"; - readonly head: expression; - readonly tail: readonly expression[]; - }>; - export type Tuple = $.Located<{ - readonly $: "Tuple"; - readonly types: commaList | undefined; - }>; - export type Parens = $.Located<{ - readonly $: "Parens"; - readonly child: parens; - }>; - export type MapLiteral = $.Located<{ - readonly $: "MapLiteral"; - readonly typeArgs: typeArgs; - readonly fields: commaList | undefined; - }>; - export type SetLiteral = $.Located<{ - readonly $: "SetLiteral"; - readonly typeArgs: typeArgs; - readonly fields: commaList | undefined; - }>; - export type StructInstance = $.Located<{ - readonly $: "StructInstance"; - readonly type: TypeId; - readonly typeArgs: typeArgs | undefined; - readonly fields: commaList | undefined; - }>; - export type StaticCall = $.Located<{ - readonly $: "StaticCall"; - readonly type: TypeId; - readonly typeArgs: typeArgs | undefined; - readonly name: Id; - readonly args: parameterList; - }>; - export type IntegerLiteral = $.Located<{ - readonly $: "IntegerLiteral"; - readonly value: IntegerLiteralHex | IntegerLiteralBin | IntegerLiteralOct | IntegerLiteralDec; - }>; - export type BoolLiteral = $.Located<{ - readonly $: "BoolLiteral"; - readonly value: "true" | "false"; - }>; - export type InitOf = $.Located<{ - readonly $: "InitOf"; - readonly name: TypeId; - readonly params: parameterList; - }>; - export type CodeOf = $.Located<{ - readonly $: "CodeOf"; - readonly name: TypeId; - }>; - export type Null = $.Located<{ - readonly $: "Null"; - }>; - export type primary = Unit | Tensor | Tuple | Parens | MapLiteral | SetLiteral | StructInstance | StaticCall | IntegerLiteral | BoolLiteral | InitOf | CodeOf | Null | StringLiteral | Id; - export type parens = expression; - export type StructFieldInitializer = $.Located<{ - readonly $: "StructFieldInitializer"; - readonly name: Id; - readonly init: expression | undefined; - }>; - export type mapField = { - readonly key: expression; - readonly value: expression; - }; - export type ParameterList = $.Located<{ - readonly $: "ParameterList"; - readonly values: commaList | undefined; - }>; - export type parameterList = commaList | undefined; - export type IntegerLiteralHex = $.Located<{ - readonly $: "IntegerLiteralHex"; - readonly digits: underscored; - }>; - export type IntegerLiteralBin = $.Located<{ - readonly $: "IntegerLiteralBin"; - readonly digits: underscored<"0" | "1">; - }>; - export type IntegerLiteralOct = $.Located<{ - readonly $: "IntegerLiteralOct"; - readonly digits: underscored; - }>; - export type underscored = string; - export type digit = string; - export type idPart = string | string | string | "_"; - export type FuncId = $.Located<{ - readonly $: "FuncId"; - readonly accessor: "." | "~" | undefined; - readonly id: string; - }>; - export type hexDigit = string | string | string; - export type escapeChar = "\\" | "\"" | "n" | "r" | "t" | "v" | "b" | "f" | string | string | string; - export type reservedWord = keyword<"extend" | "public" | "fun" | "let" | "return" | "receive" | "native" | "primitive" | "null" | "if" | "else" | "while" | "repeat" | "do" | "until" | "try" | "catch" | "foreach" | "as" | "map" | "mutates" | "extends" | "external" | "import" | "with" | "trait" | "initOf" | "override" | "abstract" | "virtual" | "inline" | "const">; - export type space = " " | "\t" | "\r" | "\n" | comment; - export type JustImports = $.Located<{ - readonly $: "JustImports"; - readonly imports: readonly Import[]; - }>; + export type Module = $.Located<{ + readonly $: "Module"; + readonly imports: readonly Import[]; + readonly items: readonly moduleItem[]; + }>; + export type Import = $.Located<{ + readonly $: "Import"; + readonly path: StringLiteral; + }>; + export type PrimitiveTypeDecl = $.Located<{ + readonly $: "PrimitiveTypeDecl"; + readonly name: TypeId; + }>; + export type $Function = $.Located<{ + readonly $: "Function"; + readonly attributes: readonly FunctionAttribute[]; + readonly name: Id; + readonly typeParams: typeParams | undefined; + readonly parameters: parameterList; + readonly returnType: ascription | undefined; + readonly body: FunctionDefinition | FunctionDeclaration; + }>; + export type AsmFunction = $.Located<{ + readonly $: "AsmFunction"; + readonly shuffle: shuffle | undefined; + readonly attributes: readonly FunctionAttribute[]; + readonly name: Id; + readonly typeParams: typeParams | undefined; + readonly parameters: parameterList; + readonly returnType: ascription | undefined; + readonly instructions: assembly; + }>; + export type NativeFunctionDecl = $.Located<{ + readonly $: "NativeFunctionDecl"; + readonly nativeName: FuncId; + readonly attributes: readonly FunctionAttribute[]; + readonly name: Id; + readonly typeParams: typeParams | undefined; + readonly parameters: parameterList; + readonly returnType: ascription | undefined; + }>; + export type Constant = $.Located<{ + readonly $: "Constant"; + readonly attributes: readonly ConstantAttribute[]; + readonly name: Id; + readonly type: ascription | undefined; + readonly body: ConstantDefinition | ConstantDeclaration; + }>; + export type StructDecl = $.Located<{ + readonly $: "StructDecl"; + readonly name: TypeId; + readonly typeParams: typeParams | undefined; + readonly fields: structFields; + }>; + export type MessageDecl = $.Located<{ + readonly $: "MessageDecl"; + readonly opcode: expression | undefined; + readonly name: TypeId; + readonly fields: structFields; + }>; + export type UnionDecl = $.Located<{ + readonly $: "UnionDecl"; + readonly name: TypeId; + readonly typeParams: typeParams | undefined; + readonly cases: readonly Case[]; + }>; + export type AliasDecl = $.Located<{ + readonly $: "AliasDecl"; + readonly name: TypeId; + readonly typeParams: typeParams | undefined; + readonly type: $type; + }>; + export type Contract = $.Located<{ + readonly $: "Contract"; + readonly attributes: readonly ContractAttribute[]; + readonly name: TypeId; + readonly parameters: ParameterList | undefined; + readonly traits: inheritedTraits | undefined; + readonly declarations: readonly contractItemDecl[]; + }>; + export type Trait = $.Located<{ + readonly $: "Trait"; + readonly attributes: readonly ContractAttribute[]; + readonly name: TypeId; + readonly traits: inheritedTraits | undefined; + readonly declarations: readonly traitItemDecl[]; + }>; + export type moduleItem = + | PrimitiveTypeDecl + | $Function + | AsmFunction + | NativeFunctionDecl + | Constant + | StructDecl + | MessageDecl + | UnionDecl + | AliasDecl + | Contract + | Trait; + export type ContractInit = $.Located<{ + readonly $: "ContractInit"; + readonly parameters: parameterList; + readonly body: statements; + }>; + export type Receiver = $.Located<{ + readonly $: "Receiver"; + readonly type: ReceiverType; + readonly param: receiverParam; + readonly body: statements; + }>; + export type FieldDecl = $.Located<{ + readonly $: "FieldDecl"; + readonly name: Id; + readonly type: ascription; + readonly expression: expression | undefined; + }>; + export type semicolon = ";" | "}"; + export type storageVar = FieldDecl; + export type contractItemDecl = + | ContractInit + | Receiver + | $Function + | AsmFunction + | Constant + | storageVar; + export type traitItemDecl = + | Receiver + | $Function + | AsmFunction + | Constant + | storageVar; + export type FunctionDefinition = $.Located<{ + readonly $: "FunctionDefinition"; + readonly body: statements; + }>; + export type FunctionDeclaration = $.Located<{ + readonly $: "FunctionDeclaration"; + }>; + export type Id = $.Located<{ + readonly $: "Id"; + readonly name: string; + }>; + export type IntegerLiteralDec = $.Located<{ + readonly $: "IntegerLiteralDec"; + readonly digits: underscored; + }>; + export type shuffle = { + readonly ids: readonly Id[]; + readonly to: readonly IntegerLiteralDec[] | undefined; + }; + export type ConstantAttribute = $.Located<{ + readonly $: "ConstantAttribute"; + readonly name: + | keyword<"virtual"> + | keyword<"override"> + | keyword<"abstract">; + }>; + export type ConstantDefinition = $.Located<{ + readonly $: "ConstantDefinition"; + readonly expression: expression; + }>; + export type ConstantDeclaration = $.Located<{ + readonly $: "ConstantDeclaration"; + }>; + export type Case = $.Located<{ + readonly $: "Case"; + readonly name: TypeId; + readonly fields: structFields; + }>; + export type inter = { + readonly head: A; + readonly tail: readonly { + readonly op: B; + readonly right: A; + }[]; + }; + export type structFields = inter | undefined; + export type keyword = T; + export type commaList = inter; + export type TypeId = $.Located<{ + readonly $: "TypeId"; + readonly name: string; + }>; + export type inheritedTraits = commaList; + export type ContractAttribute = $.Located<{ + readonly $: "ContractAttribute"; + readonly name: StringLiteral; + }>; + export type FunctionAttribute = $.Located<{ + readonly $: "FunctionAttribute"; + readonly name: + | GetAttribute + | keyword<"mutates"> + | keyword<"extends"> + | keyword<"virtual"> + | keyword<"override"> + | keyword<"inline"> + | keyword<"abstract">; + }>; + export type GetAttribute = $.Located<{ + readonly $: "GetAttribute"; + readonly methodId: expression | undefined; + }>; + export type ReceiverType = $.Located<{ + readonly $: "ReceiverType"; + readonly name: "bounced" | keyword<"receive"> | keyword<"external">; + }>; + export type Parameter = $.Located<{ + readonly $: "Parameter"; + readonly name: Id; + readonly type: ascription; + }>; + export type StringLiteral = $.Located<{ + readonly $: "StringLiteral"; + readonly value: string; + }>; + export type receiverParam = Parameter | StringLiteral | undefined; + export type assembly = string; + export type multiLineComment = string; + export type singleLineComment = string; + export type comment = multiLineComment | singleLineComment; + export type assemblyItem = {} | comment | {} | readonly {}[]; + export type assemblySequence = readonly assemblyItem[]; + export type TypeAs = $.Located<{ + readonly $: "TypeAs"; + readonly type: TypeOptional; + readonly as: readonly storage[]; + }>; + export type $type = TypeAs; + export type ascription = $type; + export type TypeOptional = $.Located<{ + readonly $: "TypeOptional"; + readonly type: typePrimary; + readonly optionals: readonly Optional[]; + }>; + export type Optional = $.Located<{ + readonly $: "Optional"; + }>; + export type TypeGeneric = $.Located<{ + readonly $: "TypeGeneric"; + readonly name: MapKeyword | Bounced | TypeId; + readonly args: typeArgs; + }>; + export type TypeRegular = $.Located<{ + readonly $: "TypeRegular"; + readonly child: TypeId; + }>; + export type TypeStorage = $.Located<{ + readonly $: "TypeStorage"; + readonly child: storage; + }>; + export type TypeTuple = $.Located<{ + readonly $: "TypeTuple"; + readonly types: commaList<$type> | undefined; + }>; + export type TypeTensor = $.Located<{ + readonly $: "TypeTensor"; + readonly head: $type; + readonly tail: readonly $type[]; + }>; + export type TypeUnit = $.Located<{ + readonly $: "TypeUnit"; + }>; + export type typeParens = $type; + export type typePrimary = + | TypeGeneric + | TypeRegular + | TypeStorage + | TypeTuple + | TypeTensor + | TypeUnit + | typeParens; + export type MapKeyword = $.Located<{ + readonly $: "MapKeyword"; + }>; + export type Bounced = $.Located<{ + readonly $: "Bounced"; + }>; + export type IntStorage = $.Located<{ + readonly $: "IntStorage"; + readonly isVar: "var" | undefined; + readonly isUnsigned: "u" | undefined; + readonly width: string; + }>; + export type CoinsStorage = $.Located<{ + readonly $: "CoinsStorage"; + }>; + export type RemainingStorage = $.Located<{ + readonly $: "RemainingStorage"; + }>; + export type BytesStorage = $.Located<{ + readonly $: "BytesStorage"; + readonly width: string; + }>; + export type storage = + | IntStorage + | CoinsStorage + | RemainingStorage + | BytesStorage; + export type generic = commaList | undefined; + export type typeParams = generic; + export type typeArgs = generic<$type>; + export type StatementLet = $.Located<{ + readonly $: "StatementLet"; + readonly name: Id; + readonly type: ascription | undefined; + readonly init: expression; + }>; + export type StatementDestruct = $.Located<{ + readonly $: "StatementDestruct"; + readonly type: TypeId; + readonly typeArgs: typeArgs | undefined; + readonly fields: inter; + readonly rest: optionalRest; + readonly init: expression; + }>; + export type StatementBlock = $.Located<{ + readonly $: "StatementBlock"; + readonly body: statements; + }>; + export type StatementReturn = $.Located<{ + readonly $: "StatementReturn"; + readonly expression: expression | undefined; + }>; + export type StatementCondition = $.Located<{ + readonly $: "StatementCondition"; + readonly condition: expression; + readonly trueBranch: statements; + readonly falseBranch: FalseBranch | StatementCondition | undefined; + }>; + export type StatementWhile = $.Located<{ + readonly $: "StatementWhile"; + readonly condition: parens; + readonly body: statements; + }>; + export type StatementRepeat = $.Located<{ + readonly $: "StatementRepeat"; + readonly condition: parens; + readonly body: statements; + }>; + export type StatementUntil = $.Located<{ + readonly $: "StatementUntil"; + readonly body: statements; + readonly condition: parens; + }>; + export type StatementTry = $.Located<{ + readonly $: "StatementTry"; + readonly body: statements; + readonly handler: + | { + readonly name: Id; + readonly body: statements; + } + | undefined; + }>; + export type StatementForEach = $.Located<{ + readonly $: "StatementForEach"; + readonly key: Id; + readonly value: Id; + readonly expression: expression; + readonly body: statements; + }>; + export type StatementExpression = $.Located<{ + readonly $: "StatementExpression"; + readonly expression: expression; + }>; + export type StatementAssign = $.Located<{ + readonly $: "StatementAssign"; + readonly left: expression; + readonly operator: augmentedOp | "="; + readonly right: expression; + }>; + export type statement = + | StatementLet + | StatementDestruct + | StatementBlock + | StatementReturn + | StatementCondition + | StatementWhile + | StatementRepeat + | StatementUntil + | StatementTry + | StatementForEach + | StatementExpression + | StatementAssign; + export type statements = readonly statement[]; + export type augmentedOp = + | "||=" + | "&&=" + | ">>=" + | "<<=" + | "-=" + | "+=" + | "*=" + | "/=" + | "%=" + | "|=" + | "&=" + | "^="; + export type FalseBranch = $.Located<{ + readonly $: "FalseBranch"; + readonly body: statements; + }>; + export type RegularField = $.Located<{ + readonly $: "RegularField"; + readonly fieldName: Id; + readonly varName: Id; + }>; + export type PunnedField = $.Located<{ + readonly $: "PunnedField"; + readonly name: Id; + }>; + export type destructItem = RegularField | PunnedField; + export type RestArgument = $.Located<{ + readonly $: "RestArgument"; + }>; + export type NoRestArgument = $.Located<{ + readonly $: "NoRestArgument"; + }>; + export type optionalRest = RestArgument | NoRestArgument; + export type Conditional = $.Located<{ + readonly $: "Conditional"; + readonly head: or; + readonly tail: + | { + readonly thenBranch: or; + readonly elseBranch: Conditional; + } + | undefined; + }>; + export type expression = Conditional; + export type Binary = $.Located<{ + readonly $: "Binary"; + readonly exprs: inter>; + }>; + export type Unary = $.Located<{ + readonly $: "Unary"; + readonly prefixes: readonly Operator<"-" | "+" | "!" | "~">[]; + readonly expression: Suffix; + }>; + export type mul = Binary; + export type add = Binary; + export type bitwiseShift = Binary>">; + export type compare = Binary=" | ">">; + export type equality = Binary; + export type bitwiseXor = Binary; + export type bitwiseOr = Binary; + export type and = Binary; + export type or = Binary; + export type Suffix = $.Located<{ + readonly $: "Suffix"; + readonly expression: primary; + readonly suffixes: readonly suffix[]; + }>; + export type Operator = $.Located<{ + readonly $: "Operator"; + readonly name: U; + }>; + export type SuffixUnboxNotNull = $.Located<{ + readonly $: "SuffixUnboxNotNull"; + }>; + export type SuffixCall = $.Located<{ + readonly $: "SuffixCall"; + readonly typeArgs: typeArgs | undefined; + readonly params: parameterList; + }>; + export type SuffixFieldAccess = $.Located<{ + readonly $: "SuffixFieldAccess"; + readonly name: Id; + }>; + export type suffix = SuffixUnboxNotNull | SuffixCall | SuffixFieldAccess; + export type Unit = $.Located<{ + readonly $: "Unit"; + }>; + export type Tensor = $.Located<{ + readonly $: "Tensor"; + readonly head: expression; + readonly tail: readonly expression[]; + }>; + export type Tuple = $.Located<{ + readonly $: "Tuple"; + readonly types: commaList | undefined; + }>; + export type Parens = $.Located<{ + readonly $: "Parens"; + readonly child: parens; + }>; + export type MapLiteral = $.Located<{ + readonly $: "MapLiteral"; + readonly typeArgs: typeArgs; + readonly fields: commaList | undefined; + }>; + export type SetLiteral = $.Located<{ + readonly $: "SetLiteral"; + readonly typeArgs: typeArgs; + readonly fields: commaList | undefined; + }>; + export type StructInstance = $.Located<{ + readonly $: "StructInstance"; + readonly type: TypeId; + readonly typeArgs: typeArgs | undefined; + readonly fields: commaList | undefined; + }>; + export type StaticCall = $.Located<{ + readonly $: "StaticCall"; + readonly type: TypeId; + readonly typeArgs: typeArgs | undefined; + readonly name: Id; + readonly args: parameterList; + }>; + export type IntegerLiteral = $.Located<{ + readonly $: "IntegerLiteral"; + readonly value: + | IntegerLiteralHex + | IntegerLiteralBin + | IntegerLiteralOct + | IntegerLiteralDec; + }>; + export type BoolLiteral = $.Located<{ + readonly $: "BoolLiteral"; + readonly value: "true" | "false"; + }>; + export type InitOf = $.Located<{ + readonly $: "InitOf"; + readonly name: TypeId; + readonly params: parameterList; + }>; + export type CodeOf = $.Located<{ + readonly $: "CodeOf"; + readonly name: TypeId; + }>; + export type Null = $.Located<{ + readonly $: "Null"; + }>; + export type primary = + | Unit + | Tensor + | Tuple + | Parens + | MapLiteral + | SetLiteral + | StructInstance + | StaticCall + | IntegerLiteral + | BoolLiteral + | InitOf + | CodeOf + | Null + | StringLiteral + | Id; + export type parens = expression; + export type StructFieldInitializer = $.Located<{ + readonly $: "StructFieldInitializer"; + readonly name: Id; + readonly init: expression | undefined; + }>; + export type mapField = { + readonly key: expression; + readonly value: expression; + }; + export type ParameterList = $.Located<{ + readonly $: "ParameterList"; + readonly values: commaList | undefined; + }>; + export type parameterList = commaList | undefined; + export type IntegerLiteralHex = $.Located<{ + readonly $: "IntegerLiteralHex"; + readonly digits: underscored; + }>; + export type IntegerLiteralBin = $.Located<{ + readonly $: "IntegerLiteralBin"; + readonly digits: underscored<"0" | "1">; + }>; + export type IntegerLiteralOct = $.Located<{ + readonly $: "IntegerLiteralOct"; + readonly digits: underscored; + }>; + export type underscored = string; + export type digit = string; + export type idPart = string | string | string | "_"; + export type FuncId = $.Located<{ + readonly $: "FuncId"; + readonly accessor: "." | "~" | undefined; + readonly id: string; + }>; + export type hexDigit = string | string | string; + export type escapeChar = + | "\\" + | '"' + | "n" + | "r" + | "t" + | "v" + | "b" + | "f" + | string + | string + | string; + export type reservedWord = keyword< + | "extend" + | "public" + | "fun" + | "let" + | "return" + | "receive" + | "native" + | "primitive" + | "null" + | "if" + | "else" + | "while" + | "repeat" + | "do" + | "until" + | "try" + | "catch" + | "foreach" + | "as" + | "map" + | "mutates" + | "extends" + | "external" + | "import" + | "with" + | "trait" + | "initOf" + | "override" + | "abstract" + | "virtual" + | "inline" + | "const" + >; + export type space = " " | "\t" | "\r" | "\n" | comment; + export type JustImports = $.Located<{ + readonly $: "JustImports"; + readonly imports: readonly Import[]; + }>; } -export const Module: $.Parser<$ast.Module> = $.loc($.field($.pure("Module"), "$", $.field($.star($.lazy(() => Import)), "imports", $.field($.star($.lazy(() => moduleItem)), "items", $.eps)))); -export const Import: $.Parser<$ast.Import> = $.loc($.field($.pure("Import"), "$", $.right($.lazy(() => keyword($.str("import"))), $.field($.lazy(() => StringLiteral), "path", $.right($.str(";"), $.eps))))); -export const PrimitiveTypeDecl: $.Parser<$ast.PrimitiveTypeDecl> = $.loc($.field($.pure("PrimitiveTypeDecl"), "$", $.right($.lazy(() => keyword($.str("primitive"))), $.field($.lazy(() => TypeId), "name", $.right($.str(";"), $.eps))))); -export const $Function: $.Parser<$ast.$Function> = $.loc($.field($.pure("Function"), "$", $.field($.star($.lazy(() => FunctionAttribute)), "attributes", $.right($.lazy(() => keyword($.str("fun"))), $.field($.lazy(() => Id), "name", $.field($.opt($.lazy(() => typeParams)), "typeParams", $.field($.lazy(() => parameterList($.lazy(() => Parameter))), "parameters", $.field($.opt($.lazy(() => ascription)), "returnType", $.field($.alt($.lazy(() => FunctionDefinition), $.lazy(() => FunctionDeclaration)), "body", $.eps))))))))); -export const AsmFunction: $.Parser<$ast.AsmFunction> = $.loc($.field($.pure("AsmFunction"), "$", $.right($.str("asm"), $.field($.opt($.lazy(() => shuffle)), "shuffle", $.field($.star($.lazy(() => FunctionAttribute)), "attributes", $.right($.lazy(() => keyword($.str("fun"))), $.field($.lazy(() => Id), "name", $.field($.opt($.lazy(() => typeParams)), "typeParams", $.field($.lazy(() => parameterList($.lazy(() => Parameter))), "parameters", $.field($.opt($.lazy(() => ascription)), "returnType", $.right($.str("{"), $.field($.lazy(() => assembly), "instructions", $.right($.str("}"), $.eps))))))))))))); -export const NativeFunctionDecl: $.Parser<$ast.NativeFunctionDecl> = $.loc($.field($.pure("NativeFunctionDecl"), "$", $.right($.str("@name"), $.right($.str("("), $.field($.lex($.lazy(() => FuncId)), "nativeName", $.right($.str(")"), $.field($.star($.lazy(() => FunctionAttribute)), "attributes", $.right($.lazy(() => keyword($.str("native"))), $.field($.lazy(() => Id), "name", $.field($.opt($.lazy(() => typeParams)), "typeParams", $.field($.lazy(() => parameterList($.lazy(() => Parameter))), "parameters", $.field($.opt($.lazy(() => ascription)), "returnType", $.right($.str(";"), $.eps))))))))))))); -export const Constant: $.Parser<$ast.Constant> = $.loc($.field($.pure("Constant"), "$", $.field($.star($.lazy(() => ConstantAttribute)), "attributes", $.right($.lazy(() => keyword($.str("const"))), $.field($.lazy(() => Id), "name", $.field($.opt($.lazy(() => ascription)), "type", $.field($.alt($.lazy(() => ConstantDefinition), $.lazy(() => ConstantDeclaration)), "body", $.eps))))))); -export const StructDecl: $.Parser<$ast.StructDecl> = $.loc($.field($.pure("StructDecl"), "$", $.right($.str("struct"), $.field($.lazy(() => TypeId), "name", $.field($.opt($.lazy(() => typeParams)), "typeParams", $.right($.str("{"), $.field($.lazy(() => structFields), "fields", $.right($.str("}"), $.eps)))))))); -export const MessageDecl: $.Parser<$ast.MessageDecl> = $.loc($.field($.pure("MessageDecl"), "$", $.right($.str("message"), $.field($.opt($.right($.str("("), $.left($.lazy(() => expression), $.str(")")))), "opcode", $.field($.lazy(() => TypeId), "name", $.right($.str("{"), $.field($.lazy(() => structFields), "fields", $.right($.str("}"), $.eps)))))))); -export const UnionDecl: $.Parser<$ast.UnionDecl> = $.loc($.field($.pure("UnionDecl"), "$", $.right($.str("union"), $.field($.lazy(() => TypeId), "name", $.field($.opt($.lazy(() => typeParams)), "typeParams", $.right($.str("{"), $.field($.star($.lazy(() => Case)), "cases", $.right($.str("}"), $.eps)))))))); -export const AliasDecl: $.Parser<$ast.AliasDecl> = $.loc($.field($.pure("AliasDecl"), "$", $.right($.str("type"), $.field($.lazy(() => TypeId), "name", $.field($.opt($.lazy(() => typeParams)), "typeParams", $.right($.str("="), $.field($.lazy(() => $type), "type", $.right($.str(";"), $.eps)))))))); -export const Contract: $.Parser<$ast.Contract> = $.loc($.field($.pure("Contract"), "$", $.field($.star($.lazy(() => ContractAttribute)), "attributes", $.right($.lazy(() => keyword($.str("contract"))), $.field($.lazy(() => TypeId), "name", $.field($.opt($.lazy(() => ParameterList($.lazy(() => Parameter)))), "parameters", $.field($.opt($.lazy(() => inheritedTraits)), "traits", $.right($.str("{"), $.field($.star($.lazy(() => contractItemDecl)), "declarations", $.right($.str("}"), $.eps)))))))))); -export const Trait: $.Parser<$ast.Trait> = $.loc($.field($.pure("Trait"), "$", $.field($.star($.lazy(() => ContractAttribute)), "attributes", $.right($.lazy(() => keyword($.str("trait"))), $.field($.lazy(() => TypeId), "name", $.field($.opt($.lazy(() => inheritedTraits)), "traits", $.right($.str("{"), $.field($.star($.lazy(() => traitItemDecl)), "declarations", $.right($.str("}"), $.eps))))))))); -export const moduleItem: $.Parser<$ast.moduleItem> = $.alt(PrimitiveTypeDecl, $.alt($Function, $.alt(AsmFunction, $.alt(NativeFunctionDecl, $.alt(Constant, $.alt(StructDecl, $.alt(MessageDecl, $.alt(UnionDecl, $.alt(AliasDecl, $.alt(Contract, Trait)))))))))); -export const ContractInit: $.Parser<$ast.ContractInit> = $.loc($.field($.pure("ContractInit"), "$", $.right($.str("init"), $.field($.lazy(() => parameterList($.lazy(() => Parameter))), "parameters", $.field($.lazy(() => statements), "body", $.eps))))); -export const Receiver: $.Parser<$ast.Receiver> = $.loc($.field($.pure("Receiver"), "$", $.field($.lazy(() => ReceiverType), "type", $.right($.str("("), $.field($.lazy(() => receiverParam), "param", $.right($.str(")"), $.field($.lazy(() => statements), "body", $.eps))))))); -export const FieldDecl: $.Parser<$ast.FieldDecl> = $.loc($.field($.pure("FieldDecl"), "$", $.field($.lazy(() => Id), "name", $.field($.lazy(() => ascription), "type", $.field($.opt($.right($.str("="), $.lazy(() => expression))), "expression", $.eps))))); -export const semicolon: $.Parser<$ast.semicolon> = $.alt($.str(";"), $.lookPos($.str("}"))); -export const storageVar: $.Parser<$ast.storageVar> = $.left(FieldDecl, semicolon); -export const contractItemDecl: $.Parser<$ast.contractItemDecl> = $.alt(ContractInit, $.alt(Receiver, $.alt($Function, $.alt(AsmFunction, $.alt(Constant, storageVar))))); -export const traitItemDecl: $.Parser<$ast.traitItemDecl> = $.alt(Receiver, $.alt($Function, $.alt(AsmFunction, $.alt(Constant, storageVar)))); -export const FunctionDefinition: $.Parser<$ast.FunctionDefinition> = $.loc($.field($.pure("FunctionDefinition"), "$", $.field($.lazy(() => statements), "body", $.eps))); -export const FunctionDeclaration: $.Parser<$ast.FunctionDeclaration> = $.loc($.field($.pure("FunctionDeclaration"), "$", $.right(semicolon, $.eps))); -export const Id: $.Parser<$ast.Id> = $.named("identifier", $.loc($.field($.pure("Id"), "$", $.field($.lex($.stry($.right($.lookNeg($.lazy(() => reservedWord)), $.right($.alt($.right($.regex("a-zA-Z_", [$.ExpRange("a", "z"), $.ExpRange("A", "Z"), $.ExpString("_")]), $.right($.star($.lazy(() => idPart)), $.eps)), $.str("$")), $.eps)))), "name", $.eps)))); -export const IntegerLiteralDec: $.Parser<$ast.IntegerLiteralDec> = $.loc($.field($.pure("IntegerLiteralDec"), "$", $.field($.lex($.lazy(() => underscored($.lazy(() => digit)))), "digits", $.eps))); -export const shuffle: $.Parser<$ast.shuffle> = $.right($.str("("), $.field($.star(Id), "ids", $.field($.opt($.right($.str("->"), $.plus(IntegerLiteralDec))), "to", $.right($.str(")"), $.eps)))); -export const ConstantAttribute: $.Parser<$ast.ConstantAttribute> = $.loc($.field($.pure("ConstantAttribute"), "$", $.field($.alt($.lazy(() => keyword($.str("virtual"))), $.alt($.lazy(() => keyword($.str("override"))), $.lazy(() => keyword($.str("abstract"))))), "name", $.eps))); -export const ConstantDefinition: $.Parser<$ast.ConstantDefinition> = $.loc($.field($.pure("ConstantDefinition"), "$", $.right($.str("="), $.field($.lazy(() => expression), "expression", $.right(semicolon, $.eps))))); -export const ConstantDeclaration: $.Parser<$ast.ConstantDeclaration> = $.loc($.field($.pure("ConstantDeclaration"), "$", $.right(semicolon, $.eps))); -export const Case: $.Parser<$ast.Case> = $.loc($.field($.pure("Case"), "$", $.field($.lazy(() => TypeId), "name", $.right($.str("{"), $.field($.lazy(() => structFields), "fields", $.right($.str("}"), $.eps)))))); -export const inter = (A: $.Parser, B: $.Parser): $.Parser<$ast.inter> => $.field($.lazy(() => A), "head", $.field($.star($.field($.lazy(() => B), "op", $.field($.lazy(() => A), "right", $.eps))), "tail", $.eps)); -export const structFields: $.Parser<$ast.structFields> = $.left($.opt(inter(FieldDecl, $.str(";"))), $.opt($.str(";"))); -export const keyword = (T: $.Parser): $.Parser<$ast.keyword> => $.lex($.left($.lazy(() => T), $.lookNeg($.lazy(() => idPart)))); -export const commaList = (T: $.Parser): $.Parser<$ast.commaList> => $.left(inter($.lazy(() => T), $.str(",")), $.opt($.str(","))); -export const TypeId: $.Parser<$ast.TypeId> = $.named("capitalized identifier", $.loc($.field($.pure("TypeId"), "$", $.field($.lex($.stry($.right($.regex("A-Z", [$.ExpRange("A", "Z")]), $.right($.star($.regex("a-zA-Z0-9_", [$.ExpRange("a", "z"), $.ExpRange("A", "Z"), $.ExpRange("0", "9"), $.ExpString("_")])), $.eps)))), "name", $.eps)))); -export const inheritedTraits: $.Parser<$ast.inheritedTraits> = $.right(keyword($.str("with")), commaList(TypeId)); -export const ContractAttribute: $.Parser<$ast.ContractAttribute> = $.loc($.field($.pure("ContractAttribute"), "$", $.right($.str("@interface"), $.right($.str("("), $.field($.lazy(() => StringLiteral), "name", $.right($.str(")"), $.eps)))))); -export const FunctionAttribute: $.Parser<$ast.FunctionAttribute> = $.loc($.field($.pure("FunctionAttribute"), "$", $.field($.alt($.lazy(() => GetAttribute), $.alt(keyword($.str("mutates")), $.alt(keyword($.str("extends")), $.alt(keyword($.str("virtual")), $.alt(keyword($.str("override")), $.alt(keyword($.str("inline")), keyword($.str("abstract")))))))), "name", $.eps))); -export const GetAttribute: $.Parser<$ast.GetAttribute> = $.loc($.field($.pure("GetAttribute"), "$", $.right($.str("get"), $.field($.opt($.right($.str("("), $.left($.lazy(() => expression), $.str(")")))), "methodId", $.eps)))); -export const ReceiverType: $.Parser<$ast.ReceiverType> = $.loc($.field($.pure("ReceiverType"), "$", $.field($.alt($.str("bounced"), $.alt(keyword($.str("receive")), keyword($.str("external")))), "name", $.eps))); -export const Parameter: $.Parser<$ast.Parameter> = $.loc($.field($.pure("Parameter"), "$", $.field(Id, "name", $.field($.lazy(() => ascription), "type", $.eps)))); -export const StringLiteral: $.Parser<$ast.StringLiteral> = $.loc($.field($.pure("StringLiteral"), "$", $.field($.lex($.right($.str("\""), $.left($.stry($.star($.alt($.regex<"\"" | "\\">("^\"\\\\", $.negateExps([$.ExpString("\""), $.ExpString("\\")])), $.right($.str("\\"), $.lazy(() => escapeChar))))), $.str("\"")))), "value", $.eps))); -export const receiverParam: $.Parser<$ast.receiverParam> = $.opt($.alt(Parameter, StringLiteral)); -export const assembly: $.Parser<$ast.assembly> = $.lex($.stry($.lazy(() => assemblySequence))); -export const multiLineComment: $.Parser<$ast.multiLineComment> = $.right($.str("/*"), $.left($.stry($.star($.right($.lookNeg($.str("*/")), $.right($.any, $.eps)))), $.str("*/"))); -export const singleLineComment: $.Parser<$ast.singleLineComment> = $.right($.str("//"), $.stry($.star($.regex<"\r" | "\n">("^\\r\\n", $.negateExps([$.ExpString("\r"), $.ExpString("\n")]))))); -export const comment: $.Parser<$ast.comment> = $.alt(multiLineComment, singleLineComment); -export const assemblyItem: $.Parser<$ast.assemblyItem> = $.alt($.right($.str("{"), $.right($.lazy(() => assemblySequence), $.right($.str("}"), $.eps))), $.alt(comment, $.alt($.right($.str("\""), $.right($.star($.regex<"\"">("^\"", $.negateExps([$.ExpString("\"")]))), $.right($.str("\""), $.eps))), $.plus($.right($.lookNeg($.alt($.regex<"\"" | "{" | "}">("\"{}", [$.ExpString("\""), $.ExpString("{"), $.ExpString("}")]), $.alt($.str("//"), $.str("/*")))), $.right($.any, $.eps)))))); -export const assemblySequence: $.Parser<$ast.assemblySequence> = $.star(assemblyItem); -export const TypeAs: $.Parser<$ast.TypeAs> = $.loc($.field($.pure("TypeAs"), "$", $.field($.lazy(() => TypeOptional), "type", $.field($.star($.right(keyword($.str("as")), $.lex($.lazy(() => storage)))), "as", $.eps)))); +export const Module: $.Parser<$ast.Module> = $.loc( + $.field( + $.pure("Module"), + "$", + $.field( + $.star($.lazy(() => Import)), + "imports", + $.field($.star($.lazy(() => moduleItem)), "items", $.eps), + ), + ), +); +export const Import: $.Parser<$ast.Import> = $.loc( + $.field( + $.pure("Import"), + "$", + $.right( + $.lazy(() => keyword($.str("import"))), + $.field( + $.lazy(() => StringLiteral), + "path", + $.right($.str(";"), $.eps), + ), + ), + ), +); +export const PrimitiveTypeDecl: $.Parser<$ast.PrimitiveTypeDecl> = $.loc( + $.field( + $.pure("PrimitiveTypeDecl"), + "$", + $.right( + $.lazy(() => keyword($.str("primitive"))), + $.field( + $.lazy(() => TypeId), + "name", + $.right($.str(";"), $.eps), + ), + ), + ), +); +export const $Function: $.Parser<$ast.$Function> = $.loc( + $.field( + $.pure("Function"), + "$", + $.field( + $.star($.lazy(() => FunctionAttribute)), + "attributes", + $.right( + $.lazy(() => keyword($.str("fun"))), + $.field( + $.lazy(() => Id), + "name", + $.field( + $.opt($.lazy(() => typeParams)), + "typeParams", + $.field( + $.lazy(() => + parameterList($.lazy(() => Parameter)), + ), + "parameters", + $.field( + $.opt($.lazy(() => ascription)), + "returnType", + $.field( + $.alt( + $.lazy(() => FunctionDefinition), + $.lazy(() => FunctionDeclaration), + ), + "body", + $.eps, + ), + ), + ), + ), + ), + ), + ), + ), +); +export const AsmFunction: $.Parser<$ast.AsmFunction> = $.loc( + $.field( + $.pure("AsmFunction"), + "$", + $.right( + $.str("asm"), + $.field( + $.opt($.lazy(() => shuffle)), + "shuffle", + $.field( + $.star($.lazy(() => FunctionAttribute)), + "attributes", + $.right( + $.lazy(() => keyword($.str("fun"))), + $.field( + $.lazy(() => Id), + "name", + $.field( + $.opt($.lazy(() => typeParams)), + "typeParams", + $.field( + $.lazy(() => + parameterList($.lazy(() => Parameter)), + ), + "parameters", + $.field( + $.opt($.lazy(() => ascription)), + "returnType", + $.right( + $.str("{"), + $.field( + $.lazy(() => assembly), + "instructions", + $.right($.str("}"), $.eps), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), +); +export const NativeFunctionDecl: $.Parser<$ast.NativeFunctionDecl> = $.loc( + $.field( + $.pure("NativeFunctionDecl"), + "$", + $.right( + $.str("@name"), + $.right( + $.str("("), + $.field( + $.lex($.lazy(() => FuncId)), + "nativeName", + $.right( + $.str(")"), + $.field( + $.star($.lazy(() => FunctionAttribute)), + "attributes", + $.right( + $.lazy(() => keyword($.str("native"))), + $.field( + $.lazy(() => Id), + "name", + $.field( + $.opt($.lazy(() => typeParams)), + "typeParams", + $.field( + $.lazy(() => + parameterList( + $.lazy(() => Parameter), + ), + ), + "parameters", + $.field( + $.opt($.lazy(() => ascription)), + "returnType", + $.right($.str(";"), $.eps), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), +); +export const Constant: $.Parser<$ast.Constant> = $.loc( + $.field( + $.pure("Constant"), + "$", + $.field( + $.star($.lazy(() => ConstantAttribute)), + "attributes", + $.right( + $.lazy(() => keyword($.str("const"))), + $.field( + $.lazy(() => Id), + "name", + $.field( + $.opt($.lazy(() => ascription)), + "type", + $.field( + $.alt( + $.lazy(() => ConstantDefinition), + $.lazy(() => ConstantDeclaration), + ), + "body", + $.eps, + ), + ), + ), + ), + ), + ), +); +export const StructDecl: $.Parser<$ast.StructDecl> = $.loc( + $.field( + $.pure("StructDecl"), + "$", + $.right( + $.str("struct"), + $.field( + $.lazy(() => TypeId), + "name", + $.field( + $.opt($.lazy(() => typeParams)), + "typeParams", + $.right( + $.str("{"), + $.field( + $.lazy(() => structFields), + "fields", + $.right($.str("}"), $.eps), + ), + ), + ), + ), + ), + ), +); +export const MessageDecl: $.Parser<$ast.MessageDecl> = $.loc( + $.field( + $.pure("MessageDecl"), + "$", + $.right( + $.str("message"), + $.field( + $.opt( + $.right( + $.str("("), + $.left( + $.lazy(() => expression), + $.str(")"), + ), + ), + ), + "opcode", + $.field( + $.lazy(() => TypeId), + "name", + $.right( + $.str("{"), + $.field( + $.lazy(() => structFields), + "fields", + $.right($.str("}"), $.eps), + ), + ), + ), + ), + ), + ), +); +export const UnionDecl: $.Parser<$ast.UnionDecl> = $.loc( + $.field( + $.pure("UnionDecl"), + "$", + $.right( + $.str("union"), + $.field( + $.lazy(() => TypeId), + "name", + $.field( + $.opt($.lazy(() => typeParams)), + "typeParams", + $.right( + $.str("{"), + $.field( + $.star($.lazy(() => Case)), + "cases", + $.right($.str("}"), $.eps), + ), + ), + ), + ), + ), + ), +); +export const AliasDecl: $.Parser<$ast.AliasDecl> = $.loc( + $.field( + $.pure("AliasDecl"), + "$", + $.right( + $.str("type"), + $.field( + $.lazy(() => TypeId), + "name", + $.field( + $.opt($.lazy(() => typeParams)), + "typeParams", + $.right( + $.str("="), + $.field( + $.lazy(() => $type), + "type", + $.right($.str(";"), $.eps), + ), + ), + ), + ), + ), + ), +); +export const Contract: $.Parser<$ast.Contract> = $.loc( + $.field( + $.pure("Contract"), + "$", + $.field( + $.star($.lazy(() => ContractAttribute)), + "attributes", + $.right( + $.lazy(() => keyword($.str("contract"))), + $.field( + $.lazy(() => TypeId), + "name", + $.field( + $.opt( + $.lazy(() => + ParameterList($.lazy(() => Parameter)), + ), + ), + "parameters", + $.field( + $.opt($.lazy(() => inheritedTraits)), + "traits", + $.right( + $.str("{"), + $.field( + $.star($.lazy(() => contractItemDecl)), + "declarations", + $.right($.str("}"), $.eps), + ), + ), + ), + ), + ), + ), + ), + ), +); +export const Trait: $.Parser<$ast.Trait> = $.loc( + $.field( + $.pure("Trait"), + "$", + $.field( + $.star($.lazy(() => ContractAttribute)), + "attributes", + $.right( + $.lazy(() => keyword($.str("trait"))), + $.field( + $.lazy(() => TypeId), + "name", + $.field( + $.opt($.lazy(() => inheritedTraits)), + "traits", + $.right( + $.str("{"), + $.field( + $.star($.lazy(() => traitItemDecl)), + "declarations", + $.right($.str("}"), $.eps), + ), + ), + ), + ), + ), + ), + ), +); +export const moduleItem: $.Parser<$ast.moduleItem> = $.alt( + PrimitiveTypeDecl, + $.alt( + $Function, + $.alt( + AsmFunction, + $.alt( + NativeFunctionDecl, + $.alt( + Constant, + $.alt( + StructDecl, + $.alt( + MessageDecl, + $.alt( + UnionDecl, + $.alt(AliasDecl, $.alt(Contract, Trait)), + ), + ), + ), + ), + ), + ), + ), +); +export const ContractInit: $.Parser<$ast.ContractInit> = $.loc( + $.field( + $.pure("ContractInit"), + "$", + $.right( + $.str("init"), + $.field( + $.lazy(() => parameterList($.lazy(() => Parameter))), + "parameters", + $.field( + $.lazy(() => statements), + "body", + $.eps, + ), + ), + ), + ), +); +export const Receiver: $.Parser<$ast.Receiver> = $.loc( + $.field( + $.pure("Receiver"), + "$", + $.field( + $.lazy(() => ReceiverType), + "type", + $.right( + $.str("("), + $.field( + $.lazy(() => receiverParam), + "param", + $.right( + $.str(")"), + $.field( + $.lazy(() => statements), + "body", + $.eps, + ), + ), + ), + ), + ), + ), +); +export const FieldDecl: $.Parser<$ast.FieldDecl> = $.loc( + $.field( + $.pure("FieldDecl"), + "$", + $.field( + $.lazy(() => Id), + "name", + $.field( + $.lazy(() => ascription), + "type", + $.field( + $.opt( + $.right( + $.str("="), + $.lazy(() => expression), + ), + ), + "expression", + $.eps, + ), + ), + ), + ), +); +export const semicolon: $.Parser<$ast.semicolon> = $.alt( + $.str(";"), + $.lookPos($.str("}")), +); +export const storageVar: $.Parser<$ast.storageVar> = $.left( + FieldDecl, + semicolon, +); +export const contractItemDecl: $.Parser<$ast.contractItemDecl> = $.alt( + ContractInit, + $.alt( + Receiver, + $.alt($Function, $.alt(AsmFunction, $.alt(Constant, storageVar))), + ), +); +export const traitItemDecl: $.Parser<$ast.traitItemDecl> = $.alt( + Receiver, + $.alt($Function, $.alt(AsmFunction, $.alt(Constant, storageVar))), +); +export const FunctionDefinition: $.Parser<$ast.FunctionDefinition> = $.loc( + $.field( + $.pure("FunctionDefinition"), + "$", + $.field( + $.lazy(() => statements), + "body", + $.eps, + ), + ), +); +export const FunctionDeclaration: $.Parser<$ast.FunctionDeclaration> = $.loc( + $.field($.pure("FunctionDeclaration"), "$", $.right(semicolon, $.eps)), +); +export const Id: $.Parser<$ast.Id> = $.named( + "identifier", + $.loc( + $.field( + $.pure("Id"), + "$", + $.field( + $.lex( + $.stry( + $.right( + $.lookNeg($.lazy(() => reservedWord)), + $.right( + $.alt( + $.right( + $.regex( + "a-zA-Z_", + [ + $.ExpRange("a", "z"), + $.ExpRange("A", "Z"), + $.ExpString("_"), + ], + ), + $.right( + $.star($.lazy(() => idPart)), + $.eps, + ), + ), + $.str("$"), + ), + $.eps, + ), + ), + ), + ), + "name", + $.eps, + ), + ), + ), +); +export const IntegerLiteralDec: $.Parser<$ast.IntegerLiteralDec> = $.loc( + $.field( + $.pure("IntegerLiteralDec"), + "$", + $.field( + $.lex($.lazy(() => underscored($.lazy(() => digit)))), + "digits", + $.eps, + ), + ), +); +export const shuffle: $.Parser<$ast.shuffle> = $.right( + $.str("("), + $.field( + $.star(Id), + "ids", + $.field( + $.opt($.right($.str("->"), $.plus(IntegerLiteralDec))), + "to", + $.right($.str(")"), $.eps), + ), + ), +); +export const ConstantAttribute: $.Parser<$ast.ConstantAttribute> = $.loc( + $.field( + $.pure("ConstantAttribute"), + "$", + $.field( + $.alt( + $.lazy(() => keyword($.str("virtual"))), + $.alt( + $.lazy(() => keyword($.str("override"))), + $.lazy(() => keyword($.str("abstract"))), + ), + ), + "name", + $.eps, + ), + ), +); +export const ConstantDefinition: $.Parser<$ast.ConstantDefinition> = $.loc( + $.field( + $.pure("ConstantDefinition"), + "$", + $.right( + $.str("="), + $.field( + $.lazy(() => expression), + "expression", + $.right(semicolon, $.eps), + ), + ), + ), +); +export const ConstantDeclaration: $.Parser<$ast.ConstantDeclaration> = $.loc( + $.field($.pure("ConstantDeclaration"), "$", $.right(semicolon, $.eps)), +); +export const Case: $.Parser<$ast.Case> = $.loc( + $.field( + $.pure("Case"), + "$", + $.field( + $.lazy(() => TypeId), + "name", + $.right( + $.str("{"), + $.field( + $.lazy(() => structFields), + "fields", + $.right($.str("}"), $.eps), + ), + ), + ), + ), +); +export const inter = ( + A: $.Parser, + B: $.Parser, +): $.Parser<$ast.inter> => + $.field( + $.lazy(() => A), + "head", + $.field( + $.star( + $.field( + $.lazy(() => B), + "op", + $.field( + $.lazy(() => A), + "right", + $.eps, + ), + ), + ), + "tail", + $.eps, + ), + ); +export const structFields: $.Parser<$ast.structFields> = $.left( + $.opt(inter(FieldDecl, $.str(";"))), + $.opt($.str(";")), +); +export const keyword = (T: $.Parser): $.Parser<$ast.keyword> => + $.lex( + $.left( + $.lazy(() => T), + $.lookNeg($.lazy(() => idPart)), + ), + ); +export const commaList = (T: $.Parser): $.Parser<$ast.commaList> => + $.left( + inter( + $.lazy(() => T), + $.str(","), + ), + $.opt($.str(",")), + ); +export const TypeId: $.Parser<$ast.TypeId> = $.named( + "capitalized identifier", + $.loc( + $.field( + $.pure("TypeId"), + "$", + $.field( + $.lex( + $.stry( + $.right( + $.regex("A-Z", [$.ExpRange("A", "Z")]), + $.right( + $.star( + $.regex( + "a-zA-Z0-9_", + [ + $.ExpRange("a", "z"), + $.ExpRange("A", "Z"), + $.ExpRange("0", "9"), + $.ExpString("_"), + ], + ), + ), + $.eps, + ), + ), + ), + ), + "name", + $.eps, + ), + ), + ), +); +export const inheritedTraits: $.Parser<$ast.inheritedTraits> = $.right( + keyword($.str("with")), + commaList(TypeId), +); +export const ContractAttribute: $.Parser<$ast.ContractAttribute> = $.loc( + $.field( + $.pure("ContractAttribute"), + "$", + $.right( + $.str("@interface"), + $.right( + $.str("("), + $.field( + $.lazy(() => StringLiteral), + "name", + $.right($.str(")"), $.eps), + ), + ), + ), + ), +); +export const FunctionAttribute: $.Parser<$ast.FunctionAttribute> = $.loc( + $.field( + $.pure("FunctionAttribute"), + "$", + $.field( + $.alt( + $.lazy(() => GetAttribute), + $.alt( + keyword($.str("mutates")), + $.alt( + keyword($.str("extends")), + $.alt( + keyword($.str("virtual")), + $.alt( + keyword($.str("override")), + $.alt( + keyword($.str("inline")), + keyword($.str("abstract")), + ), + ), + ), + ), + ), + ), + "name", + $.eps, + ), + ), +); +export const GetAttribute: $.Parser<$ast.GetAttribute> = $.loc( + $.field( + $.pure("GetAttribute"), + "$", + $.right( + $.str("get"), + $.field( + $.opt( + $.right( + $.str("("), + $.left( + $.lazy(() => expression), + $.str(")"), + ), + ), + ), + "methodId", + $.eps, + ), + ), + ), +); +export const ReceiverType: $.Parser<$ast.ReceiverType> = $.loc( + $.field( + $.pure("ReceiverType"), + "$", + $.field( + $.alt( + $.str("bounced"), + $.alt(keyword($.str("receive")), keyword($.str("external"))), + ), + "name", + $.eps, + ), + ), +); +export const Parameter: $.Parser<$ast.Parameter> = $.loc( + $.field( + $.pure("Parameter"), + "$", + $.field( + Id, + "name", + $.field( + $.lazy(() => ascription), + "type", + $.eps, + ), + ), + ), +); +export const StringLiteral: $.Parser<$ast.StringLiteral> = $.loc( + $.field( + $.pure("StringLiteral"), + "$", + $.field( + $.lex( + $.right( + $.str('"'), + $.left( + $.stry( + $.star( + $.alt( + $.regex<'"' | "\\">( + '^"\\\\', + $.negateExps([ + $.ExpString('"'), + $.ExpString("\\"), + ]), + ), + $.right( + $.str("\\"), + $.lazy(() => escapeChar), + ), + ), + ), + ), + $.str('"'), + ), + ), + ), + "value", + $.eps, + ), + ), +); +export const receiverParam: $.Parser<$ast.receiverParam> = $.opt( + $.alt(Parameter, StringLiteral), +); +export const assembly: $.Parser<$ast.assembly> = $.lex( + $.stry($.lazy(() => assemblySequence)), +); +export const multiLineComment: $.Parser<$ast.multiLineComment> = $.right( + $.str("/*"), + $.left( + $.stry($.star($.right($.lookNeg($.str("*/")), $.right($.any, $.eps)))), + $.str("*/"), + ), +); +export const singleLineComment: $.Parser<$ast.singleLineComment> = $.right( + $.str("//"), + $.stry( + $.star( + $.regex<"\r" | "\n">( + "^\\r\\n", + $.negateExps([$.ExpString("\r"), $.ExpString("\n")]), + ), + ), + ), +); +export const comment: $.Parser<$ast.comment> = $.alt( + multiLineComment, + singleLineComment, +); +export const assemblyItem: $.Parser<$ast.assemblyItem> = $.alt( + $.right( + $.str("{"), + $.right( + $.lazy(() => assemblySequence), + $.right($.str("}"), $.eps), + ), + ), + $.alt( + comment, + $.alt( + $.right( + $.str('"'), + $.right( + $.star( + $.regex<'"'>('^"', $.negateExps([$.ExpString('"')])), + ), + $.right($.str('"'), $.eps), + ), + ), + $.plus( + $.right( + $.lookNeg( + $.alt( + $.regex<'"' | "{" | "}">('"{}', [ + $.ExpString('"'), + $.ExpString("{"), + $.ExpString("}"), + ]), + $.alt($.str("//"), $.str("/*")), + ), + ), + $.right($.any, $.eps), + ), + ), + ), + ), +); +export const assemblySequence: $.Parser<$ast.assemblySequence> = + $.star(assemblyItem); +export const TypeAs: $.Parser<$ast.TypeAs> = $.loc( + $.field( + $.pure("TypeAs"), + "$", + $.field( + $.lazy(() => TypeOptional), + "type", + $.field( + $.star( + $.right(keyword($.str("as")), $.lex($.lazy(() => storage))), + ), + "as", + $.eps, + ), + ), + ), +); export const $type: $.Parser<$ast.$type> = TypeAs; export const ascription: $.Parser<$ast.ascription> = $.right($.str(":"), $type); -export const TypeOptional: $.Parser<$ast.TypeOptional> = $.loc($.field($.pure("TypeOptional"), "$", $.field($.lazy(() => typePrimary), "type", $.field($.star($.lazy(() => Optional)), "optionals", $.eps)))); -export const Optional: $.Parser<$ast.Optional> = $.loc($.field($.pure("Optional"), "$", $.right($.str("?"), $.eps))); -export const TypeGeneric: $.Parser<$ast.TypeGeneric> = $.loc($.field($.pure("TypeGeneric"), "$", $.field($.alt($.lazy(() => MapKeyword), $.alt($.lazy(() => Bounced), TypeId)), "name", $.field($.lazy(() => typeArgs), "args", $.eps)))); -export const TypeRegular: $.Parser<$ast.TypeRegular> = $.loc($.field($.pure("TypeRegular"), "$", $.field(TypeId, "child", $.eps))); -export const TypeStorage: $.Parser<$ast.TypeStorage> = $.loc($.field($.pure("TypeStorage"), "$", $.field($.lazy(() => storage), "child", $.eps))); -export const TypeTuple: $.Parser<$ast.TypeTuple> = $.loc($.field($.pure("TypeTuple"), "$", $.right($.str("["), $.field($.opt(commaList($type)), "types", $.right($.str("]"), $.eps))))); -export const TypeTensor: $.Parser<$ast.TypeTensor> = $.loc($.field($.pure("TypeTensor"), "$", $.right($.str("("), $.field($type, "head", $.field($.plus($.right($.str(","), $type)), "tail", $.right($.opt($.str(",")), $.right($.str(")"), $.eps))))))); -export const TypeUnit: $.Parser<$ast.TypeUnit> = $.loc($.field($.pure("TypeUnit"), "$", $.right($.right($.str("("), $.right($.str(")"), $.eps)), $.eps))); -export const typeParens: $.Parser<$ast.typeParens> = $.right($.str("("), $.left($type, $.str(")"))); -export const typePrimary: $.Parser<$ast.typePrimary> = $.alt(TypeGeneric, $.alt(TypeRegular, $.alt(TypeStorage, $.alt(TypeTuple, $.alt(TypeTensor, $.alt(TypeUnit, typeParens)))))); -export const MapKeyword: $.Parser<$ast.MapKeyword> = $.loc($.field($.pure("MapKeyword"), "$", $.right(keyword($.str("map")), $.eps))); -export const Bounced: $.Parser<$ast.Bounced> = $.loc($.field($.pure("Bounced"), "$", $.right($.str("bounced"), $.eps))); -export const IntStorage: $.Parser<$ast.IntStorage> = $.loc($.field($.pure("IntStorage"), "$", $.field($.opt($.str("var")), "isVar", $.field($.opt($.str("u")), "isUnsigned", $.right($.str("int"), $.field($.stry($.plus($.lazy(() => digit))), "width", $.eps)))))); -export const CoinsStorage: $.Parser<$ast.CoinsStorage> = $.loc($.field($.pure("CoinsStorage"), "$", $.right($.str("coins"), $.eps))); -export const RemainingStorage: $.Parser<$ast.RemainingStorage> = $.loc($.field($.pure("RemainingStorage"), "$", $.right($.str("remaining"), $.eps))); -export const BytesStorage: $.Parser<$ast.BytesStorage> = $.loc($.field($.pure("BytesStorage"), "$", $.right($.str("bytes"), $.field($.stry($.plus($.lazy(() => digit))), "width", $.eps)))); -export const storage: $.Parser<$ast.storage> = $.alt(IntStorage, $.alt(CoinsStorage, $.alt(RemainingStorage, BytesStorage))); -export const generic = (T: $.Parser): $.Parser<$ast.generic> => $.right($.str("<"), $.left($.opt(commaList($.lazy(() => T))), $.str(">"))); +export const TypeOptional: $.Parser<$ast.TypeOptional> = $.loc( + $.field( + $.pure("TypeOptional"), + "$", + $.field( + $.lazy(() => typePrimary), + "type", + $.field($.star($.lazy(() => Optional)), "optionals", $.eps), + ), + ), +); +export const Optional: $.Parser<$ast.Optional> = $.loc( + $.field($.pure("Optional"), "$", $.right($.str("?"), $.eps)), +); +export const TypeGeneric: $.Parser<$ast.TypeGeneric> = $.loc( + $.field( + $.pure("TypeGeneric"), + "$", + $.field( + $.alt( + $.lazy(() => MapKeyword), + $.alt( + $.lazy(() => Bounced), + TypeId, + ), + ), + "name", + $.field( + $.lazy(() => typeArgs), + "args", + $.eps, + ), + ), + ), +); +export const TypeRegular: $.Parser<$ast.TypeRegular> = $.loc( + $.field($.pure("TypeRegular"), "$", $.field(TypeId, "child", $.eps)), +); +export const TypeStorage: $.Parser<$ast.TypeStorage> = $.loc( + $.field( + $.pure("TypeStorage"), + "$", + $.field( + $.lazy(() => storage), + "child", + $.eps, + ), + ), +); +export const TypeTuple: $.Parser<$ast.TypeTuple> = $.loc( + $.field( + $.pure("TypeTuple"), + "$", + $.right( + $.str("["), + $.field( + $.opt(commaList($type)), + "types", + $.right($.str("]"), $.eps), + ), + ), + ), +); +export const TypeTensor: $.Parser<$ast.TypeTensor> = $.loc( + $.field( + $.pure("TypeTensor"), + "$", + $.right( + $.str("("), + $.field( + $type, + "head", + $.field( + $.plus($.right($.str(","), $type)), + "tail", + $.right($.opt($.str(",")), $.right($.str(")"), $.eps)), + ), + ), + ), + ), +); +export const TypeUnit: $.Parser<$ast.TypeUnit> = $.loc( + $.field( + $.pure("TypeUnit"), + "$", + $.right($.right($.str("("), $.right($.str(")"), $.eps)), $.eps), + ), +); +export const typeParens: $.Parser<$ast.typeParens> = $.right( + $.str("("), + $.left($type, $.str(")")), +); +export const typePrimary: $.Parser<$ast.typePrimary> = $.alt( + TypeGeneric, + $.alt( + TypeRegular, + $.alt( + TypeStorage, + $.alt(TypeTuple, $.alt(TypeTensor, $.alt(TypeUnit, typeParens))), + ), + ), +); +export const MapKeyword: $.Parser<$ast.MapKeyword> = $.loc( + $.field($.pure("MapKeyword"), "$", $.right(keyword($.str("map")), $.eps)), +); +export const Bounced: $.Parser<$ast.Bounced> = $.loc( + $.field($.pure("Bounced"), "$", $.right($.str("bounced"), $.eps)), +); +export const IntStorage: $.Parser<$ast.IntStorage> = $.loc( + $.field( + $.pure("IntStorage"), + "$", + $.field( + $.opt($.str("var")), + "isVar", + $.field( + $.opt($.str("u")), + "isUnsigned", + $.right( + $.str("int"), + $.field( + $.stry($.plus($.lazy(() => digit))), + "width", + $.eps, + ), + ), + ), + ), + ), +); +export const CoinsStorage: $.Parser<$ast.CoinsStorage> = $.loc( + $.field($.pure("CoinsStorage"), "$", $.right($.str("coins"), $.eps)), +); +export const RemainingStorage: $.Parser<$ast.RemainingStorage> = $.loc( + $.field( + $.pure("RemainingStorage"), + "$", + $.right($.str("remaining"), $.eps), + ), +); +export const BytesStorage: $.Parser<$ast.BytesStorage> = $.loc( + $.field( + $.pure("BytesStorage"), + "$", + $.right( + $.str("bytes"), + $.field($.stry($.plus($.lazy(() => digit))), "width", $.eps), + ), + ), +); +export const storage: $.Parser<$ast.storage> = $.alt( + IntStorage, + $.alt(CoinsStorage, $.alt(RemainingStorage, BytesStorage)), +); +export const generic = (T: $.Parser): $.Parser<$ast.generic> => + $.right($.str("<"), $.left($.opt(commaList($.lazy(() => T))), $.str(">"))); export const typeParams: $.Parser<$ast.typeParams> = generic(TypeId); export const typeArgs: $.Parser<$ast.typeArgs> = generic($type); -export const StatementLet: $.Parser<$ast.StatementLet> = $.loc($.field($.pure("StatementLet"), "$", $.right(keyword($.str("let")), $.field(Id, "name", $.field($.opt(ascription), "type", $.right($.str("="), $.field($.lazy(() => expression), "init", $.right(semicolon, $.eps)))))))); -export const StatementDestruct: $.Parser<$ast.StatementDestruct> = $.loc($.field($.pure("StatementDestruct"), "$", $.right(keyword($.str("let")), $.field(TypeId, "type", $.field($.opt(typeArgs), "typeArgs", $.right($.str("{"), $.field(inter($.lazy(() => destructItem), $.str(",")), "fields", $.field($.lazy(() => optionalRest), "rest", $.right($.str("}"), $.right($.str("="), $.field($.lazy(() => expression), "init", $.right(semicolon, $.eps)))))))))))); -export const StatementBlock: $.Parser<$ast.StatementBlock> = $.loc($.field($.pure("StatementBlock"), "$", $.field($.lazy(() => statements), "body", $.eps))); -export const StatementReturn: $.Parser<$ast.StatementReturn> = $.loc($.field($.pure("StatementReturn"), "$", $.right(keyword($.str("return")), $.field($.opt($.lazy(() => expression)), "expression", $.right(semicolon, $.eps))))); -export const StatementCondition: $.Parser<$ast.StatementCondition> = $.loc($.field($.pure("StatementCondition"), "$", $.right(keyword($.str("if")), $.field($.lazy(() => expression), "condition", $.field($.lazy(() => statements), "trueBranch", $.field($.opt($.right(keyword($.str("else")), $.alt($.lazy(() => FalseBranch), $.lazy(() => StatementCondition)))), "falseBranch", $.eps)))))); -export const StatementWhile: $.Parser<$ast.StatementWhile> = $.loc($.field($.pure("StatementWhile"), "$", $.right(keyword($.str("while")), $.field($.lazy(() => parens), "condition", $.field($.lazy(() => statements), "body", $.eps))))); -export const StatementRepeat: $.Parser<$ast.StatementRepeat> = $.loc($.field($.pure("StatementRepeat"), "$", $.right(keyword($.str("repeat")), $.field($.lazy(() => parens), "condition", $.field($.lazy(() => statements), "body", $.eps))))); -export const StatementUntil: $.Parser<$ast.StatementUntil> = $.loc($.field($.pure("StatementUntil"), "$", $.right(keyword($.str("do")), $.field($.lazy(() => statements), "body", $.right(keyword($.str("until")), $.field($.lazy(() => parens), "condition", $.right(semicolon, $.eps))))))); -export const StatementTry: $.Parser<$ast.StatementTry> = $.loc($.field($.pure("StatementTry"), "$", $.right(keyword($.str("try")), $.field($.lazy(() => statements), "body", $.field($.opt($.right(keyword($.str("catch")), $.right($.str("("), $.field(Id, "name", $.right($.str(")"), $.field($.lazy(() => statements), "body", $.eps)))))), "handler", $.eps))))); -export const StatementForEach: $.Parser<$ast.StatementForEach> = $.loc($.field($.pure("StatementForEach"), "$", $.right(keyword($.str("foreach")), $.right($.str("("), $.field(Id, "key", $.right($.str(","), $.field(Id, "value", $.right($.str("in"), $.field($.lazy(() => expression), "expression", $.right($.str(")"), $.field($.lazy(() => statements), "body", $.eps))))))))))); -export const StatementExpression: $.Parser<$ast.StatementExpression> = $.loc($.field($.pure("StatementExpression"), "$", $.field($.lazy(() => expression), "expression", $.right(semicolon, $.eps)))); -export const StatementAssign: $.Parser<$ast.StatementAssign> = $.loc($.field($.pure("StatementAssign"), "$", $.field($.lazy(() => expression), "left", $.field($.alt($.lazy(() => augmentedOp), $.str("=")), "operator", $.field($.lazy(() => expression), "right", $.right(semicolon, $.eps)))))); -export const statement: $.Parser<$ast.statement> = $.alt(StatementLet, $.alt(StatementDestruct, $.alt(StatementBlock, $.alt(StatementReturn, $.alt(StatementCondition, $.alt(StatementWhile, $.alt(StatementRepeat, $.alt(StatementUntil, $.alt(StatementTry, $.alt(StatementForEach, $.alt(StatementExpression, StatementAssign))))))))))); -export const statements: $.Parser<$ast.statements> = $.right($.str("{"), $.left($.star(statement), $.str("}"))); -export const augmentedOp: $.Parser<$ast.augmentedOp> = $.alt($.str("||="), $.alt($.str("&&="), $.alt($.str(">>="), $.alt($.str("<<="), $.alt($.str("-="), $.alt($.str("+="), $.alt($.str("*="), $.alt($.str("/="), $.alt($.str("%="), $.alt($.str("|="), $.alt($.str("&="), $.str("^=")))))))))))); -export const FalseBranch: $.Parser<$ast.FalseBranch> = $.loc($.field($.pure("FalseBranch"), "$", $.field(statements, "body", $.eps))); -export const RegularField: $.Parser<$ast.RegularField> = $.loc($.field($.pure("RegularField"), "$", $.field(Id, "fieldName", $.right($.str(":"), $.field(Id, "varName", $.eps))))); -export const PunnedField: $.Parser<$ast.PunnedField> = $.loc($.field($.pure("PunnedField"), "$", $.field(Id, "name", $.eps))); -export const destructItem: $.Parser<$ast.destructItem> = $.alt(RegularField, PunnedField); -export const RestArgument: $.Parser<$ast.RestArgument> = $.loc($.field($.pure("RestArgument"), "$", $.right($.str(".."), $.eps))); -export const NoRestArgument: $.Parser<$ast.NoRestArgument> = $.loc($.field($.pure("NoRestArgument"), "$", $.right($.opt($.str(",")), $.eps))); -export const optionalRest: $.Parser<$ast.optionalRest> = $.alt($.right($.str(","), RestArgument), NoRestArgument); -export const Conditional: $.Parser<$ast.Conditional> = $.loc($.field($.pure("Conditional"), "$", $.field($.lazy(() => or), "head", $.field($.opt($.right($.str("?"), $.field($.lazy(() => or), "thenBranch", $.right($.str(":"), $.field($.lazy(() => Conditional), "elseBranch", $.eps))))), "tail", $.eps)))); +export const StatementLet: $.Parser<$ast.StatementLet> = $.loc( + $.field( + $.pure("StatementLet"), + "$", + $.right( + keyword($.str("let")), + $.field( + Id, + "name", + $.field( + $.opt(ascription), + "type", + $.right( + $.str("="), + $.field( + $.lazy(() => expression), + "init", + $.right(semicolon, $.eps), + ), + ), + ), + ), + ), + ), +); +export const StatementDestruct: $.Parser<$ast.StatementDestruct> = $.loc( + $.field( + $.pure("StatementDestruct"), + "$", + $.right( + keyword($.str("let")), + $.field( + TypeId, + "type", + $.field( + $.opt(typeArgs), + "typeArgs", + $.right( + $.str("{"), + $.field( + inter( + $.lazy(() => destructItem), + $.str(","), + ), + "fields", + $.field( + $.lazy(() => optionalRest), + "rest", + $.right( + $.str("}"), + $.right( + $.str("="), + $.field( + $.lazy(() => expression), + "init", + $.right(semicolon, $.eps), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), +); +export const StatementBlock: $.Parser<$ast.StatementBlock> = $.loc( + $.field( + $.pure("StatementBlock"), + "$", + $.field( + $.lazy(() => statements), + "body", + $.eps, + ), + ), +); +export const StatementReturn: $.Parser<$ast.StatementReturn> = $.loc( + $.field( + $.pure("StatementReturn"), + "$", + $.right( + keyword($.str("return")), + $.field( + $.opt($.lazy(() => expression)), + "expression", + $.right(semicolon, $.eps), + ), + ), + ), +); +export const StatementCondition: $.Parser<$ast.StatementCondition> = $.loc( + $.field( + $.pure("StatementCondition"), + "$", + $.right( + keyword($.str("if")), + $.field( + $.lazy(() => expression), + "condition", + $.field( + $.lazy(() => statements), + "trueBranch", + $.field( + $.opt( + $.right( + keyword($.str("else")), + $.alt( + $.lazy(() => FalseBranch), + $.lazy(() => StatementCondition), + ), + ), + ), + "falseBranch", + $.eps, + ), + ), + ), + ), + ), +); +export const StatementWhile: $.Parser<$ast.StatementWhile> = $.loc( + $.field( + $.pure("StatementWhile"), + "$", + $.right( + keyword($.str("while")), + $.field( + $.lazy(() => parens), + "condition", + $.field( + $.lazy(() => statements), + "body", + $.eps, + ), + ), + ), + ), +); +export const StatementRepeat: $.Parser<$ast.StatementRepeat> = $.loc( + $.field( + $.pure("StatementRepeat"), + "$", + $.right( + keyword($.str("repeat")), + $.field( + $.lazy(() => parens), + "condition", + $.field( + $.lazy(() => statements), + "body", + $.eps, + ), + ), + ), + ), +); +export const StatementUntil: $.Parser<$ast.StatementUntil> = $.loc( + $.field( + $.pure("StatementUntil"), + "$", + $.right( + keyword($.str("do")), + $.field( + $.lazy(() => statements), + "body", + $.right( + keyword($.str("until")), + $.field( + $.lazy(() => parens), + "condition", + $.right(semicolon, $.eps), + ), + ), + ), + ), + ), +); +export const StatementTry: $.Parser<$ast.StatementTry> = $.loc( + $.field( + $.pure("StatementTry"), + "$", + $.right( + keyword($.str("try")), + $.field( + $.lazy(() => statements), + "body", + $.field( + $.opt( + $.right( + keyword($.str("catch")), + $.right( + $.str("("), + $.field( + Id, + "name", + $.right( + $.str(")"), + $.field( + $.lazy(() => statements), + "body", + $.eps, + ), + ), + ), + ), + ), + ), + "handler", + $.eps, + ), + ), + ), + ), +); +export const StatementForEach: $.Parser<$ast.StatementForEach> = $.loc( + $.field( + $.pure("StatementForEach"), + "$", + $.right( + keyword($.str("foreach")), + $.right( + $.str("("), + $.field( + Id, + "key", + $.right( + $.str(","), + $.field( + Id, + "value", + $.right( + $.str("in"), + $.field( + $.lazy(() => expression), + "expression", + $.right( + $.str(")"), + $.field( + $.lazy(() => statements), + "body", + $.eps, + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), +); +export const StatementExpression: $.Parser<$ast.StatementExpression> = $.loc( + $.field( + $.pure("StatementExpression"), + "$", + $.field( + $.lazy(() => expression), + "expression", + $.right(semicolon, $.eps), + ), + ), +); +export const StatementAssign: $.Parser<$ast.StatementAssign> = $.loc( + $.field( + $.pure("StatementAssign"), + "$", + $.field( + $.lazy(() => expression), + "left", + $.field( + $.alt( + $.lazy(() => augmentedOp), + $.str("="), + ), + "operator", + $.field( + $.lazy(() => expression), + "right", + $.right(semicolon, $.eps), + ), + ), + ), + ), +); +export const statement: $.Parser<$ast.statement> = $.alt( + StatementLet, + $.alt( + StatementDestruct, + $.alt( + StatementBlock, + $.alt( + StatementReturn, + $.alt( + StatementCondition, + $.alt( + StatementWhile, + $.alt( + StatementRepeat, + $.alt( + StatementUntil, + $.alt( + StatementTry, + $.alt( + StatementForEach, + $.alt( + StatementExpression, + StatementAssign, + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), +); +export const statements: $.Parser<$ast.statements> = $.right( + $.str("{"), + $.left($.star(statement), $.str("}")), +); +export const augmentedOp: $.Parser<$ast.augmentedOp> = $.alt( + $.str("||="), + $.alt( + $.str("&&="), + $.alt( + $.str(">>="), + $.alt( + $.str("<<="), + $.alt( + $.str("-="), + $.alt( + $.str("+="), + $.alt( + $.str("*="), + $.alt( + $.str("/="), + $.alt( + $.str("%="), + $.alt( + $.str("|="), + $.alt($.str("&="), $.str("^=")), + ), + ), + ), + ), + ), + ), + ), + ), + ), +); +export const FalseBranch: $.Parser<$ast.FalseBranch> = $.loc( + $.field($.pure("FalseBranch"), "$", $.field(statements, "body", $.eps)), +); +export const RegularField: $.Parser<$ast.RegularField> = $.loc( + $.field( + $.pure("RegularField"), + "$", + $.field( + Id, + "fieldName", + $.right($.str(":"), $.field(Id, "varName", $.eps)), + ), + ), +); +export const PunnedField: $.Parser<$ast.PunnedField> = $.loc( + $.field($.pure("PunnedField"), "$", $.field(Id, "name", $.eps)), +); +export const destructItem: $.Parser<$ast.destructItem> = $.alt( + RegularField, + PunnedField, +); +export const RestArgument: $.Parser<$ast.RestArgument> = $.loc( + $.field($.pure("RestArgument"), "$", $.right($.str(".."), $.eps)), +); +export const NoRestArgument: $.Parser<$ast.NoRestArgument> = $.loc( + $.field($.pure("NoRestArgument"), "$", $.right($.opt($.str(",")), $.eps)), +); +export const optionalRest: $.Parser<$ast.optionalRest> = $.alt( + $.right($.str(","), RestArgument), + NoRestArgument, +); +export const Conditional: $.Parser<$ast.Conditional> = $.loc( + $.field( + $.pure("Conditional"), + "$", + $.field( + $.lazy(() => or), + "head", + $.field( + $.opt( + $.right( + $.str("?"), + $.field( + $.lazy(() => or), + "thenBranch", + $.right( + $.str(":"), + $.field( + $.lazy(() => Conditional), + "elseBranch", + $.eps, + ), + ), + ), + ), + ), + "tail", + $.eps, + ), + ), + ), +); export const expression: $.Parser<$ast.expression> = Conditional; -export const Binary = (T: $.Parser, U: $.Parser): $.Parser<$ast.Binary> => $.loc($.field($.pure("Binary"), "$", $.field(inter($.lazy(() => T), $.lazy(() => Operator($.lazy(() => U)))), "exprs", $.eps))); -export const Unary: $.Parser<$ast.Unary> = $.loc($.field($.pure("Unary"), "$", $.field($.star($.lazy(() => Operator($.regex<"-" | "+" | "!" | "~">("-+!~", [$.ExpString("-"), $.ExpString("+"), $.ExpString("!"), $.ExpString("~")])))), "prefixes", $.field($.lazy(() => Suffix), "expression", $.eps)))); -export const mul: $.Parser<$ast.mul> = Binary(Unary, $.regex<"*" | "/" | "%">("*/%", [$.ExpString("*"), $.ExpString("/"), $.ExpString("%")])); -export const add: $.Parser<$ast.add> = Binary(mul, $.alt($.str("+"), $.str("-"))); -export const bitwiseShift: $.Parser<$ast.bitwiseShift> = Binary(add, $.alt($.str("<<"), $.str(">>"))); -export const compare: $.Parser<$ast.compare> = Binary(bitwiseShift, $.alt($.str("<="), $.alt($.str("<"), $.alt($.str(">="), $.str(">"))))); -export const equality: $.Parser<$ast.equality> = Binary(compare, $.alt($.str("!="), $.str("=="))); -export const bitwiseAnd: $.Parser<$ast.bitwiseAnd> = Binary(equality, $.str("&")); -export const bitwiseXor: $.Parser<$ast.bitwiseXor> = Binary(bitwiseAnd, $.str("^")); -export const bitwiseOr: $.Parser<$ast.bitwiseOr> = Binary(bitwiseXor, $.str("|")); +export const Binary = ( + T: $.Parser, + U: $.Parser, +): $.Parser<$ast.Binary> => + $.loc( + $.field( + $.pure("Binary"), + "$", + $.field( + inter( + $.lazy(() => T), + $.lazy(() => Operator($.lazy(() => U))), + ), + "exprs", + $.eps, + ), + ), + ); +export const Unary: $.Parser<$ast.Unary> = $.loc( + $.field( + $.pure("Unary"), + "$", + $.field( + $.star( + $.lazy(() => + Operator( + $.regex<"-" | "+" | "!" | "~">("-+!~", [ + $.ExpString("-"), + $.ExpString("+"), + $.ExpString("!"), + $.ExpString("~"), + ]), + ), + ), + ), + "prefixes", + $.field( + $.lazy(() => Suffix), + "expression", + $.eps, + ), + ), + ), +); +export const mul: $.Parser<$ast.mul> = Binary( + Unary, + $.regex<"*" | "/" | "%">("*/%", [ + $.ExpString("*"), + $.ExpString("/"), + $.ExpString("%"), + ]), +); +export const add: $.Parser<$ast.add> = Binary( + mul, + $.alt($.str("+"), $.str("-")), +); +export const bitwiseShift: $.Parser<$ast.bitwiseShift> = Binary( + add, + $.alt($.str("<<"), $.str(">>")), +); +export const compare: $.Parser<$ast.compare> = Binary( + bitwiseShift, + $.alt($.str("<="), $.alt($.str("<"), $.alt($.str(">="), $.str(">")))), +); +export const equality: $.Parser<$ast.equality> = Binary( + compare, + $.alt($.str("!="), $.str("==")), +); +export const bitwiseAnd: $.Parser<$ast.bitwiseAnd> = Binary( + equality, + $.str("&"), +); +export const bitwiseXor: $.Parser<$ast.bitwiseXor> = Binary( + bitwiseAnd, + $.str("^"), +); +export const bitwiseOr: $.Parser<$ast.bitwiseOr> = Binary( + bitwiseXor, + $.str("|"), +); export const and: $.Parser<$ast.and> = Binary(bitwiseOr, $.str("&&")); export const or: $.Parser<$ast.or> = Binary(and, $.str("||")); -export const Suffix: $.Parser<$ast.Suffix> = $.loc($.field($.pure("Suffix"), "$", $.field($.lazy(() => primary), "expression", $.field($.star($.lazy(() => suffix)), "suffixes", $.eps)))); -export const Operator = (U: $.Parser): $.Parser<$ast.Operator> => $.loc($.field($.pure("Operator"), "$", $.field($.lazy(() => U), "name", $.eps))); -export const SuffixUnboxNotNull: $.Parser<$ast.SuffixUnboxNotNull> = $.loc($.field($.pure("SuffixUnboxNotNull"), "$", $.right($.str("!!"), $.eps))); -export const SuffixCall: $.Parser<$ast.SuffixCall> = $.loc($.field($.pure("SuffixCall"), "$", $.field($.opt(typeArgs), "typeArgs", $.field($.lazy(() => parameterList(expression)), "params", $.eps)))); -export const SuffixFieldAccess: $.Parser<$ast.SuffixFieldAccess> = $.loc($.field($.pure("SuffixFieldAccess"), "$", $.right($.str("."), $.field(Id, "name", $.eps)))); -export const suffix: $.Parser<$ast.suffix> = $.alt(SuffixUnboxNotNull, $.alt(SuffixCall, SuffixFieldAccess)); -export const Unit: $.Parser<$ast.Unit> = $.loc($.field($.pure("Unit"), "$", $.right($.right($.str("("), $.right($.str(")"), $.eps)), $.eps))); -export const Tensor: $.Parser<$ast.Tensor> = $.loc($.field($.pure("Tensor"), "$", $.right($.str("("), $.field(expression, "head", $.field($.plus($.right($.str(","), expression)), "tail", $.right($.opt($.str(",")), $.right($.str(")"), $.eps))))))); -export const Tuple: $.Parser<$ast.Tuple> = $.loc($.field($.pure("Tuple"), "$", $.right($.str("["), $.field($.opt(commaList(expression)), "types", $.right($.str("]"), $.eps))))); -export const Parens: $.Parser<$ast.Parens> = $.loc($.field($.pure("Parens"), "$", $.field($.lazy(() => parens), "child", $.eps))); -export const MapLiteral: $.Parser<$ast.MapLiteral> = $.loc($.field($.pure("MapLiteral"), "$", $.right(keyword($.str("map")), $.field(typeArgs, "typeArgs", $.right($.str("{"), $.field($.opt(commaList($.lazy(() => mapField))), "fields", $.right($.str("}"), $.eps))))))); -export const SetLiteral: $.Parser<$ast.SetLiteral> = $.loc($.field($.pure("SetLiteral"), "$", $.right($.str("set"), $.field(typeArgs, "typeArgs", $.right($.str("{"), $.field($.opt(commaList(expression)), "fields", $.right($.str("}"), $.eps))))))); -export const StructInstance: $.Parser<$ast.StructInstance> = $.loc($.field($.pure("StructInstance"), "$", $.field(TypeId, "type", $.field($.opt(typeArgs), "typeArgs", $.right($.str("{"), $.field($.opt(commaList($.lazy(() => StructFieldInitializer))), "fields", $.right($.str("}"), $.eps))))))); -export const StaticCall: $.Parser<$ast.StaticCall> = $.loc($.field($.pure("StaticCall"), "$", $.field(TypeId, "type", $.field($.opt(typeArgs), "typeArgs", $.right($.str("."), $.field(Id, "name", $.field($.lazy(() => parameterList(expression)), "args", $.eps))))))); -export const IntegerLiteral: $.Parser<$ast.IntegerLiteral> = $.loc($.field($.pure("IntegerLiteral"), "$", $.field($.alt($.lazy(() => IntegerLiteralHex), $.alt($.lazy(() => IntegerLiteralBin), $.alt($.lazy(() => IntegerLiteralOct), IntegerLiteralDec))), "value", $.eps))); -export const BoolLiteral: $.Parser<$ast.BoolLiteral> = $.loc($.field($.pure("BoolLiteral"), "$", $.field($.alt($.str("true"), $.str("false")), "value", $.right($.lookNeg($.lazy(() => idPart)), $.eps)))); -export const InitOf: $.Parser<$ast.InitOf> = $.loc($.field($.pure("InitOf"), "$", $.right(keyword($.str("initOf")), $.field(TypeId, "name", $.field($.lazy(() => parameterList(expression)), "params", $.eps))))); -export const CodeOf: $.Parser<$ast.CodeOf> = $.loc($.field($.pure("CodeOf"), "$", $.right($.str("codeOf"), $.field(TypeId, "name", $.eps)))); -export const Null: $.Parser<$ast.Null> = $.loc($.field($.pure("Null"), "$", $.right(keyword($.str("null")), $.eps))); -export const primary: $.Parser<$ast.primary> = $.alt(Unit, $.alt(Tensor, $.alt(Tuple, $.alt(Parens, $.alt(MapLiteral, $.alt(SetLiteral, $.alt(StructInstance, $.alt(StaticCall, $.alt(IntegerLiteral, $.alt(BoolLiteral, $.alt(InitOf, $.alt(CodeOf, $.alt(Null, $.alt(StringLiteral, Id)))))))))))))); -export const parens: $.Parser<$ast.parens> = $.right($.str("("), $.left(expression, $.str(")"))); -export const StructFieldInitializer: $.Parser<$ast.StructFieldInitializer> = $.loc($.field($.pure("StructFieldInitializer"), "$", $.field(Id, "name", $.field($.opt($.right($.str(":"), expression)), "init", $.eps)))); -export const mapField: $.Parser<$ast.mapField> = $.field(expression, "key", $.right($.str(":"), $.field(expression, "value", $.eps))); -export const ParameterList = (T: $.Parser): $.Parser<$ast.ParameterList> => $.loc($.field($.pure("ParameterList"), "$", $.right($.str("("), $.field($.opt(commaList($.lazy(() => T))), "values", $.right($.str(")"), $.eps))))); -export const parameterList = (T: $.Parser): $.Parser<$ast.parameterList> => $.right($.str("("), $.left($.opt(commaList($.lazy(() => T))), $.str(")"))); -export const IntegerLiteralHex: $.Parser<$ast.IntegerLiteralHex> = $.loc($.field($.pure("IntegerLiteralHex"), "$", $.field($.lex($.right($.str("0"), $.right($.regex<"x" | "X">("xX", [$.ExpString("x"), $.ExpString("X")]), $.lazy(() => underscored($.lazy(() => hexDigit)))))), "digits", $.eps))); -export const IntegerLiteralBin: $.Parser<$ast.IntegerLiteralBin> = $.loc($.field($.pure("IntegerLiteralBin"), "$", $.field($.lex($.right($.str("0"), $.right($.regex<"b" | "B">("bB", [$.ExpString("b"), $.ExpString("B")]), $.lazy(() => underscored($.regex<"0" | "1">("01", [$.ExpString("0"), $.ExpString("1")])))))), "digits", $.eps))); -export const IntegerLiteralOct: $.Parser<$ast.IntegerLiteralOct> = $.loc($.field($.pure("IntegerLiteralOct"), "$", $.field($.lex($.right($.str("0"), $.right($.regex<"o" | "O">("oO", [$.ExpString("o"), $.ExpString("O")]), $.lazy(() => underscored($.regex("0-7", [$.ExpRange("0", "7")])))))), "digits", $.eps))); -export const underscored = (T: $.Parser): $.Parser<$ast.underscored> => $.stry($.right($.lazy(() => T), $.right($.star($.right($.opt($.str("_")), $.right($.lazy(() => T), $.eps))), $.eps))); -export const digit: $.Parser<$ast.digit> = $.named("digit", $.regex("0-9", [$.ExpRange("0", "9")])); -export const idPart: $.Parser<$ast.idPart> = $.named("identifier character", $.regex("a-zA-Z0-9_", [$.ExpRange("a", "z"), $.ExpRange("A", "Z"), $.ExpRange("0", "9"), $.ExpString("_")])); -export const FuncId: $.Parser<$ast.FuncId> = $.named("FunC identifier", $.loc($.field($.pure("FuncId"), "$", $.field($.opt($.regex<"." | "~">(".~", [$.ExpString("."), $.ExpString("~")])), "accessor", $.field($.stry($.alt($.right($.str("`"), $.right($.plus($.regex<"`" | "\r" | "\n">("^`\\r\\n", $.negateExps([$.ExpString("`"), $.ExpString("\r"), $.ExpString("\n")]))), $.right($.str("`"), $.eps))), $.plus($.regex<" " | "\t" | "\r" | "\n" | "(" | ")" | "[" | string | "," | "." | ";" | "~">("^ \\t\\r\\n()[\\],.;~", $.negateExps([$.ExpString(" "), $.ExpString("\t"), $.ExpString("\r"), $.ExpString("\n"), $.ExpString("("), $.ExpString(")"), $.ExpString("["), $.ExpString("\"\\]\""), $.ExpString(","), $.ExpString("."), $.ExpString(";"), $.ExpString("~")]))))), "id", $.eps))))); -export const hexDigit: $.Parser<$ast.hexDigit> = $.named("hexadecimal digit", $.regex("0-9a-fA-F", [$.ExpRange("0", "9"), $.ExpRange("a", "f"), $.ExpRange("A", "F")])); -export const escapeChar: $.Parser<$ast.escapeChar> = $.alt($.regex<"\\" | "\"" | "n" | "r" | "t" | "v" | "b" | "f">("\\\\\"nrtvbf", [$.ExpString("\\"), $.ExpString("\""), $.ExpString("n"), $.ExpString("r"), $.ExpString("t"), $.ExpString("v"), $.ExpString("b"), $.ExpString("f")]), $.alt($.right($.str("u{"), $.left($.stry($.right(hexDigit, $.right($.opt(hexDigit), $.right($.opt(hexDigit), $.right($.opt(hexDigit), $.right($.opt(hexDigit), $.right($.opt(hexDigit), $.eps))))))), $.str("}"))), $.alt($.right($.str("u"), $.stry($.right(hexDigit, $.right(hexDigit, $.right(hexDigit, $.right(hexDigit, $.eps)))))), $.right($.str("x"), $.stry($.right(hexDigit, $.right(hexDigit, $.eps))))))); -export const reservedWord: $.Parser<$ast.reservedWord> = $.named("reserved word", keyword($.alt($.str("extend"), $.alt($.str("public"), $.alt($.str("fun"), $.alt($.str("let"), $.alt($.str("return"), $.alt($.str("receive"), $.alt($.str("native"), $.alt($.str("primitive"), $.alt($.str("null"), $.alt($.str("if"), $.alt($.str("else"), $.alt($.str("while"), $.alt($.str("repeat"), $.alt($.str("do"), $.alt($.str("until"), $.alt($.str("try"), $.alt($.str("catch"), $.alt($.str("foreach"), $.alt($.str("as"), $.alt($.str("map"), $.alt($.str("mutates"), $.alt($.str("extends"), $.alt($.str("external"), $.alt($.str("import"), $.alt($.str("with"), $.alt($.str("trait"), $.alt($.str("initOf"), $.alt($.str("override"), $.alt($.str("abstract"), $.alt($.str("virtual"), $.alt($.str("inline"), $.str("const")))))))))))))))))))))))))))))))))); -export const space: $.Parser<$ast.space> = $.named("space", $.alt($.regex<" " | "\t" | "\r" | "\n">(" \\t\\r\\n", [$.ExpString(" "), $.ExpString("\t"), $.ExpString("\r"), $.ExpString("\n")]), comment)); -export const JustImports: $.Parser<$ast.JustImports> = $.loc($.field($.pure("JustImports"), "$", $.field($.star(Import), "imports", $.right($.star($.any), $.eps)))); \ No newline at end of file +export const Suffix: $.Parser<$ast.Suffix> = $.loc( + $.field( + $.pure("Suffix"), + "$", + $.field( + $.lazy(() => primary), + "expression", + $.field($.star($.lazy(() => suffix)), "suffixes", $.eps), + ), + ), +); +export const Operator = (U: $.Parser): $.Parser<$ast.Operator> => + $.loc( + $.field( + $.pure("Operator"), + "$", + $.field( + $.lazy(() => U), + "name", + $.eps, + ), + ), + ); +export const SuffixUnboxNotNull: $.Parser<$ast.SuffixUnboxNotNull> = $.loc( + $.field($.pure("SuffixUnboxNotNull"), "$", $.right($.str("!!"), $.eps)), +); +export const SuffixCall: $.Parser<$ast.SuffixCall> = $.loc( + $.field( + $.pure("SuffixCall"), + "$", + $.field( + $.opt(typeArgs), + "typeArgs", + $.field( + $.lazy(() => parameterList(expression)), + "params", + $.eps, + ), + ), + ), +); +export const SuffixFieldAccess: $.Parser<$ast.SuffixFieldAccess> = $.loc( + $.field( + $.pure("SuffixFieldAccess"), + "$", + $.right($.str("."), $.field(Id, "name", $.eps)), + ), +); +export const suffix: $.Parser<$ast.suffix> = $.alt( + SuffixUnboxNotNull, + $.alt(SuffixCall, SuffixFieldAccess), +); +export const Unit: $.Parser<$ast.Unit> = $.loc( + $.field( + $.pure("Unit"), + "$", + $.right($.right($.str("("), $.right($.str(")"), $.eps)), $.eps), + ), +); +export const Tensor: $.Parser<$ast.Tensor> = $.loc( + $.field( + $.pure("Tensor"), + "$", + $.right( + $.str("("), + $.field( + expression, + "head", + $.field( + $.plus($.right($.str(","), expression)), + "tail", + $.right($.opt($.str(",")), $.right($.str(")"), $.eps)), + ), + ), + ), + ), +); +export const Tuple: $.Parser<$ast.Tuple> = $.loc( + $.field( + $.pure("Tuple"), + "$", + $.right( + $.str("["), + $.field( + $.opt(commaList(expression)), + "types", + $.right($.str("]"), $.eps), + ), + ), + ), +); +export const Parens: $.Parser<$ast.Parens> = $.loc( + $.field( + $.pure("Parens"), + "$", + $.field( + $.lazy(() => parens), + "child", + $.eps, + ), + ), +); +export const MapLiteral: $.Parser<$ast.MapLiteral> = $.loc( + $.field( + $.pure("MapLiteral"), + "$", + $.right( + keyword($.str("map")), + $.field( + typeArgs, + "typeArgs", + $.right( + $.str("{"), + $.field( + $.opt(commaList($.lazy(() => mapField))), + "fields", + $.right($.str("}"), $.eps), + ), + ), + ), + ), + ), +); +export const SetLiteral: $.Parser<$ast.SetLiteral> = $.loc( + $.field( + $.pure("SetLiteral"), + "$", + $.right( + $.str("set"), + $.field( + typeArgs, + "typeArgs", + $.right( + $.str("{"), + $.field( + $.opt(commaList(expression)), + "fields", + $.right($.str("}"), $.eps), + ), + ), + ), + ), + ), +); +export const StructInstance: $.Parser<$ast.StructInstance> = $.loc( + $.field( + $.pure("StructInstance"), + "$", + $.field( + TypeId, + "type", + $.field( + $.opt(typeArgs), + "typeArgs", + $.right( + $.str("{"), + $.field( + $.opt(commaList($.lazy(() => StructFieldInitializer))), + "fields", + $.right($.str("}"), $.eps), + ), + ), + ), + ), + ), +); +export const StaticCall: $.Parser<$ast.StaticCall> = $.loc( + $.field( + $.pure("StaticCall"), + "$", + $.field( + TypeId, + "type", + $.field( + $.opt(typeArgs), + "typeArgs", + $.right( + $.str("."), + $.field( + Id, + "name", + $.field( + $.lazy(() => parameterList(expression)), + "args", + $.eps, + ), + ), + ), + ), + ), + ), +); +export const IntegerLiteral: $.Parser<$ast.IntegerLiteral> = $.loc( + $.field( + $.pure("IntegerLiteral"), + "$", + $.field( + $.alt( + $.lazy(() => IntegerLiteralHex), + $.alt( + $.lazy(() => IntegerLiteralBin), + $.alt( + $.lazy(() => IntegerLiteralOct), + IntegerLiteralDec, + ), + ), + ), + "value", + $.eps, + ), + ), +); +export const BoolLiteral: $.Parser<$ast.BoolLiteral> = $.loc( + $.field( + $.pure("BoolLiteral"), + "$", + $.field( + $.alt($.str("true"), $.str("false")), + "value", + $.right($.lookNeg($.lazy(() => idPart)), $.eps), + ), + ), +); +export const InitOf: $.Parser<$ast.InitOf> = $.loc( + $.field( + $.pure("InitOf"), + "$", + $.right( + keyword($.str("initOf")), + $.field( + TypeId, + "name", + $.field( + $.lazy(() => parameterList(expression)), + "params", + $.eps, + ), + ), + ), + ), +); +export const CodeOf: $.Parser<$ast.CodeOf> = $.loc( + $.field( + $.pure("CodeOf"), + "$", + $.right($.str("codeOf"), $.field(TypeId, "name", $.eps)), + ), +); +export const Null: $.Parser<$ast.Null> = $.loc( + $.field($.pure("Null"), "$", $.right(keyword($.str("null")), $.eps)), +); +export const primary: $.Parser<$ast.primary> = $.alt( + Unit, + $.alt( + Tensor, + $.alt( + Tuple, + $.alt( + Parens, + $.alt( + MapLiteral, + $.alt( + SetLiteral, + $.alt( + StructInstance, + $.alt( + StaticCall, + $.alt( + IntegerLiteral, + $.alt( + BoolLiteral, + $.alt( + InitOf, + $.alt( + CodeOf, + $.alt( + Null, + $.alt(StringLiteral, Id), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), +); +export const parens: $.Parser<$ast.parens> = $.right( + $.str("("), + $.left(expression, $.str(")")), +); +export const StructFieldInitializer: $.Parser<$ast.StructFieldInitializer> = + $.loc( + $.field( + $.pure("StructFieldInitializer"), + "$", + $.field( + Id, + "name", + $.field($.opt($.right($.str(":"), expression)), "init", $.eps), + ), + ), + ); +export const mapField: $.Parser<$ast.mapField> = $.field( + expression, + "key", + $.right($.str(":"), $.field(expression, "value", $.eps)), +); +export const ParameterList = ( + T: $.Parser, +): $.Parser<$ast.ParameterList> => + $.loc( + $.field( + $.pure("ParameterList"), + "$", + $.right( + $.str("("), + $.field( + $.opt(commaList($.lazy(() => T))), + "values", + $.right($.str(")"), $.eps), + ), + ), + ), + ); +export const parameterList = ( + T: $.Parser, +): $.Parser<$ast.parameterList> => + $.right($.str("("), $.left($.opt(commaList($.lazy(() => T))), $.str(")"))); +export const IntegerLiteralHex: $.Parser<$ast.IntegerLiteralHex> = $.loc( + $.field( + $.pure("IntegerLiteralHex"), + "$", + $.field( + $.lex( + $.right( + $.str("0"), + $.right( + $.regex<"x" | "X">("xX", [ + $.ExpString("x"), + $.ExpString("X"), + ]), + $.lazy(() => underscored($.lazy(() => hexDigit))), + ), + ), + ), + "digits", + $.eps, + ), + ), +); +export const IntegerLiteralBin: $.Parser<$ast.IntegerLiteralBin> = $.loc( + $.field( + $.pure("IntegerLiteralBin"), + "$", + $.field( + $.lex( + $.right( + $.str("0"), + $.right( + $.regex<"b" | "B">("bB", [ + $.ExpString("b"), + $.ExpString("B"), + ]), + $.lazy(() => + underscored( + $.regex<"0" | "1">("01", [ + $.ExpString("0"), + $.ExpString("1"), + ]), + ), + ), + ), + ), + ), + "digits", + $.eps, + ), + ), +); +export const IntegerLiteralOct: $.Parser<$ast.IntegerLiteralOct> = $.loc( + $.field( + $.pure("IntegerLiteralOct"), + "$", + $.field( + $.lex( + $.right( + $.str("0"), + $.right( + $.regex<"o" | "O">("oO", [ + $.ExpString("o"), + $.ExpString("O"), + ]), + $.lazy(() => + underscored( + $.regex("0-7", [$.ExpRange("0", "7")]), + ), + ), + ), + ), + ), + "digits", + $.eps, + ), + ), +); +export const underscored = (T: $.Parser): $.Parser<$ast.underscored> => + $.stry( + $.right( + $.lazy(() => T), + $.right( + $.star( + $.right( + $.opt($.str("_")), + $.right( + $.lazy(() => T), + $.eps, + ), + ), + ), + $.eps, + ), + ), + ); +export const digit: $.Parser<$ast.digit> = $.named( + "digit", + $.regex("0-9", [$.ExpRange("0", "9")]), +); +export const idPart: $.Parser<$ast.idPart> = $.named( + "identifier character", + $.regex("a-zA-Z0-9_", [ + $.ExpRange("a", "z"), + $.ExpRange("A", "Z"), + $.ExpRange("0", "9"), + $.ExpString("_"), + ]), +); +export const FuncId: $.Parser<$ast.FuncId> = $.named( + "FunC identifier", + $.loc( + $.field( + $.pure("FuncId"), + "$", + $.field( + $.opt( + $.regex<"." | "~">(".~", [ + $.ExpString("."), + $.ExpString("~"), + ]), + ), + "accessor", + $.field( + $.stry( + $.alt( + $.right( + $.str("`"), + $.right( + $.plus( + $.regex<"`" | "\r" | "\n">( + "^`\\r\\n", + $.negateExps([ + $.ExpString("`"), + $.ExpString("\r"), + $.ExpString("\n"), + ]), + ), + ), + $.right($.str("`"), $.eps), + ), + ), + $.plus( + $.regex< + | " " + | "\t" + | "\r" + | "\n" + | "(" + | ")" + | "[" + | string + | "," + | "." + | ";" + | "~" + >( + "^ \\t\\r\\n()[\\],.;~", + $.negateExps([ + $.ExpString(" "), + $.ExpString("\t"), + $.ExpString("\r"), + $.ExpString("\n"), + $.ExpString("("), + $.ExpString(")"), + $.ExpString("["), + $.ExpString('"\\]"'), + $.ExpString(","), + $.ExpString("."), + $.ExpString(";"), + $.ExpString("~"), + ]), + ), + ), + ), + ), + "id", + $.eps, + ), + ), + ), + ), +); +export const hexDigit: $.Parser<$ast.hexDigit> = $.named( + "hexadecimal digit", + $.regex("0-9a-fA-F", [ + $.ExpRange("0", "9"), + $.ExpRange("a", "f"), + $.ExpRange("A", "F"), + ]), +); +export const escapeChar: $.Parser<$ast.escapeChar> = $.alt( + $.regex<"\\" | '"' | "n" | "r" | "t" | "v" | "b" | "f">('\\\\"nrtvbf', [ + $.ExpString("\\"), + $.ExpString('"'), + $.ExpString("n"), + $.ExpString("r"), + $.ExpString("t"), + $.ExpString("v"), + $.ExpString("b"), + $.ExpString("f"), + ]), + $.alt( + $.right( + $.str("u{"), + $.left( + $.stry( + $.right( + hexDigit, + $.right( + $.opt(hexDigit), + $.right( + $.opt(hexDigit), + $.right( + $.opt(hexDigit), + $.right( + $.opt(hexDigit), + $.right($.opt(hexDigit), $.eps), + ), + ), + ), + ), + ), + ), + $.str("}"), + ), + ), + $.alt( + $.right( + $.str("u"), + $.stry( + $.right( + hexDigit, + $.right( + hexDigit, + $.right(hexDigit, $.right(hexDigit, $.eps)), + ), + ), + ), + ), + $.right( + $.str("x"), + $.stry($.right(hexDigit, $.right(hexDigit, $.eps))), + ), + ), + ), +); +export const reservedWord: $.Parser<$ast.reservedWord> = $.named( + "reserved word", + keyword( + $.alt( + $.str("extend"), + $.alt( + $.str("public"), + $.alt( + $.str("fun"), + $.alt( + $.str("let"), + $.alt( + $.str("return"), + $.alt( + $.str("receive"), + $.alt( + $.str("native"), + $.alt( + $.str("primitive"), + $.alt( + $.str("null"), + $.alt( + $.str("if"), + $.alt( + $.str("else"), + $.alt( + $.str("while"), + $.alt( + $.str("repeat"), + $.alt( + $.str("do"), + $.alt( + $.str( + "until", + ), + $.alt( + $.str( + "try", + ), + $.alt( + $.str( + "catch", + ), + $.alt( + $.str( + "foreach", + ), + $.alt( + $.str( + "as", + ), + $.alt( + $.str( + "map", + ), + $.alt( + $.str( + "mutates", + ), + $.alt( + $.str( + "extends", + ), + $.alt( + $.str( + "external", + ), + $.alt( + $.str( + "import", + ), + $.alt( + $.str( + "with", + ), + $.alt( + $.str( + "trait", + ), + $.alt( + $.str( + "initOf", + ), + $.alt( + $.str( + "override", + ), + $.alt( + $.str( + "abstract", + ), + $.alt( + $.str( + "virtual", + ), + $.alt( + $.str( + "inline", + ), + $.str( + "const", + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), + ), +); +export const space: $.Parser<$ast.space> = $.named( + "space", + $.alt( + $.regex<" " | "\t" | "\r" | "\n">(" \\t\\r\\n", [ + $.ExpString(" "), + $.ExpString("\t"), + $.ExpString("\r"), + $.ExpString("\n"), + ]), + comment, + ), +); +export const JustImports: $.Parser<$ast.JustImports> = $.loc( + $.field( + $.pure("JustImports"), + "$", + $.field($.star(Import), "imports", $.right($.star($.any), $.eps)), + ), +); diff --git a/src/next/grammar/index.ts b/src/next/grammar/index.ts index 6adb9e4659..b4dc043b16 100644 --- a/src/next/grammar/index.ts +++ b/src/next/grammar/index.ts @@ -272,7 +272,9 @@ export function replaceEscapeSequences( if (unicodeCodePoint) { const codePoint = parseInt(unicodeCodePoint, 16); if (codePoint > 0x10ffff) { - ctx.err.undefinedUnicodeCodepoint()(ctx.toRange(loc)); + ctx.err.undefinedUnicodeCodepoint()( + ctx.toRange(loc), + ); return match; } return String.fromCodePoint(codePoint); @@ -345,7 +347,7 @@ const parseBouncedArgs = const [head] = args; // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (args.length !== 1 || !head) { - ctx.err.typeArity('bounced', 1)(range); + ctx.err.typeArity("bounced", 1)(range); return Ast.TypeBounced( Ast.TypeCons(Ast.TypeId("ERROR", range), [], range), range, @@ -361,7 +363,7 @@ const parseMaybeArgs = const [head] = args; // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (args.length !== 1 || !head) { - ctx.err.typeArity('Maybe', 1)(range); + ctx.err.typeArity("Maybe", 1)(range); return Ast.TypeMaybe( Ast.TypeCons(Ast.TypeId("ERROR", range), [], range), range, @@ -620,15 +622,23 @@ const parseTuple = ); }; -const parseStaticCall = ({ type, name, typeArgs, args, loc }: $ast.StaticCall): Handler => ctx => { - return Ast.StaticMethodCall( - parseTypeId(type)(ctx), - map(parseList(typeArgs), parseType)(ctx), - parseId(name)(ctx), - map(parseList(args), parseExpression)(ctx), - ctx.toRange(loc), - ); -}; +const parseStaticCall = + ({ + type, + name, + typeArgs, + args, + loc, + }: $ast.StaticCall): Handler => + (ctx) => { + return Ast.StaticMethodCall( + parseTypeId(type)(ctx), + map(parseList(typeArgs), parseType)(ctx), + parseId(name)(ctx), + map(parseList(args), parseExpression)(ctx), + ctx.toRange(loc), + ); + }; const parseParens = ({ child }: $ast.Parens): Handler => { return parseExpression(child); @@ -1076,7 +1086,11 @@ const parseTypeStorage = }; const applyFormat = - (type: Ast.Type, storage: $ast.storage, asLoc: Ast.Range): Handler => + ( + type: Ast.Type, + storage: $ast.storage, + asLoc: Ast.Range, + ): Handler => (ctx) => { const fallback = Ast.TypeCons(Ast.TypeId("ERROR", asLoc), [], asLoc); if (type.kind === "TyInt") { @@ -1179,8 +1193,8 @@ const applyFormat = return Ast.TypeCons(type.name, [result], type.loc); } else { // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition - if (type.loc.kind !== 'range') { - return throwInternal("Non-range in parser") + if (type.loc.kind !== "range") { + return throwInternal("Non-range in parser"); } ctx.err.cannotHaveFormat()(type.loc); return fallback; @@ -1213,9 +1227,9 @@ const parseTypeGeneric = const range = ctx.toRange(loc); if (name.$ === "Bounced") { return parseBouncedArgs(args, range)(ctx); - } else if (name.$ === "MapKeyword" || name.name === 'Map') { + } else if (name.$ === "MapKeyword" || name.name === "Map") { return parseMapArgs(args, range)(ctx); - } else if (name.name === 'Maybe') { + } else if (name.name === "Maybe") { return parseMaybeArgs(args, range)(ctx); } else if (builtinTypes.has(name.name)) { ctx.err.typeArity(name.name, 0)(range); @@ -1273,7 +1287,7 @@ const parseTypeRegular = ctx.err.mustBeGeneric()(range); return Ast.TypeCons(Ast.TypeId("ERROR", range), [], range); default: - return Ast.TypeCons(parseTypeId(child)(ctx), [], range); + return Ast.TypeCons(parseTypeId(child)(ctx), [], range); } }; @@ -1413,7 +1427,10 @@ const parseReceiverBounced = } return Ast.Receiver( - Ast.ReceiverBounce(parseParameter(param)(ctx), ctx.toRange(type.loc)), + Ast.ReceiverBounce( + parseParameter(param)(ctx), + ctx.toRange(type.loc), + ), map(body, parseStatement)(ctx), ctx.toRange(loc), ); @@ -1460,7 +1477,9 @@ const parseAsmFunctionRaw = Ast.FnType( map(parseList(node.typeParams), parseTypeId)(ctx), map(parseList(node.parameters), parseParameter)(ctx), - node.returnType ? parseType(node.returnType)(ctx) : Ast.TypeVoid(range), + node.returnType + ? parseType(node.returnType)(ctx) + : Ast.TypeVoid(range), ), Ast.AsmBody(parseAsmShuffle(node.shuffle)(ctx), [ node.instructions.trim(), @@ -1469,46 +1488,50 @@ const parseAsmFunctionRaw = ); }; -const checkNoGlobalAttrs = ( - attrs: readonly ($ast.FunctionAttribute | $ast.ConstantAttribute)[], - range: Ast.Range, -): Handler => ctx => { - const isVirtual = parseNamedAttr("virtual")(attrs)(ctx); - const isOverride = parseNamedAttr("override")(attrs)(ctx); - const isAbstract = parseNamedAttr("abstract")(attrs)(ctx); - if (isVirtual || isOverride || isAbstract) { - ctx.err.globalWithAttr()(range); - } -}; - -const parseInheritance = ( - hasBody: boolean, - attrs: readonly ($ast.FunctionAttribute | $ast.ConstantAttribute)[], - range: Ast.Range, -): Handler<{ override: boolean, overridable: boolean }> => ctx => { - const isVirtual = parseNamedAttr("virtual")(attrs)(ctx); - const isOverride = parseNamedAttr("override")(attrs)(ctx); - const isAbstract = parseNamedAttr("abstract")(attrs)(ctx); - if (isAbstract) { - if (isVirtual) { - ctx.err.abstractVirtual()(isVirtual); - } - if (isOverride) { - ctx.err.abstractOverride()(isOverride); - } - if (hasBody) { - ctx.err.abstractWithBody()(isAbstract); +const checkNoGlobalAttrs = + ( + attrs: readonly ($ast.FunctionAttribute | $ast.ConstantAttribute)[], + range: Ast.Range, + ): Handler => + (ctx) => { + const isVirtual = parseNamedAttr("virtual")(attrs)(ctx); + const isOverride = parseNamedAttr("override")(attrs)(ctx); + const isAbstract = parseNamedAttr("abstract")(attrs)(ctx); + if (isVirtual || isOverride || isAbstract) { + ctx.err.globalWithAttr()(range); } - } else { - if (!hasBody) { - ctx.err.noBodyNoAbstract()(range); + }; + +const parseInheritance = + ( + hasBody: boolean, + attrs: readonly ($ast.FunctionAttribute | $ast.ConstantAttribute)[], + range: Ast.Range, + ): Handler<{ override: boolean; overridable: boolean }> => + (ctx) => { + const isVirtual = parseNamedAttr("virtual")(attrs)(ctx); + const isOverride = parseNamedAttr("override")(attrs)(ctx); + const isAbstract = parseNamedAttr("abstract")(attrs)(ctx); + if (isAbstract) { + if (isVirtual) { + ctx.err.abstractVirtual()(isVirtual); + } + if (isOverride) { + ctx.err.abstractOverride()(isOverride); + } + if (hasBody) { + ctx.err.abstractWithBody()(isAbstract); + } + } else { + if (!hasBody) { + ctx.err.noBodyNoAbstract()(range); + } } - } - return { - override: !!isOverride, - overridable: !!isVirtual || !!isAbstract, + return { + override: !!isOverride, + overridable: !!isVirtual || !!isAbstract, + }; }; -}; const parseConstant = (node: $ast.Constant): Handler => @@ -1519,13 +1542,15 @@ const parseConstant = if (node.body.$ === "ConstantDefinition") { return Ast.ConstantDef( node.type ? parseType(node.type)(ctx) : undefined, - parseExpression(node.body.expression)(ctx) + parseExpression(node.body.expression)(ctx), ); } else if (node.type) { return Ast.ConstantDecl(parseType(node.type)(ctx)); } else { ctx.err.constDeclNoType()(range); - return Ast.ConstantDecl(Ast.TypeCons(Ast.TypeId("ERROR", range), [], range)); + return Ast.ConstantDecl( + Ast.TypeCons(Ast.TypeId("ERROR", range), [], range), + ); } })(); return Ast.Constant(name, type, range); @@ -1543,7 +1568,7 @@ const parseFieldConstant = (ctx) => { const body = parseConstant(node)(ctx); const inh = parseInheritance( - body.init.kind === 'constant_def', + body.init.kind === "constant_def", node.attributes, ctx.toRange(node.loc), )(ctx); @@ -1575,7 +1600,7 @@ const parseContract = const initFns: $ast.ContractInit[] = []; const locals: $ast.traitItemDecl[] = []; for (const decl of declarations) { - if (decl.$ === 'ContractInit') { + if (decl.$ === "ContractInit") { initFns.push(decl); } else { locals.push(decl); @@ -1593,7 +1618,7 @@ const parseContract = ctx.err.initFnAndParams()(ctx.toRange(initFn.loc)); } return Ast.InitParams(params, ctx.toRange(loc)); - // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition } else if (initFn) { return Ast.InitFunction( map(parseList(initFn.parameters), parseParameter)(ctx), @@ -1646,7 +1671,7 @@ const parseExtension = const get = parseGetAttribute(node.attributes)(ctx); if (get) { // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition - if (get.loc.kind !== 'range') { + if (get.loc.kind !== "range") { return throwInternal("Non-range in parser"); } ctx.err.globalGetter()(get.loc); @@ -1690,7 +1715,7 @@ const parseMethod = const fn = parseFunction(node)(ctx); const get = parseGetAttribute(node.attributes)(ctx); const inh = parseInheritance( - fn.body.kind !== 'abstract_body', + fn.body.kind !== "abstract_body", node.attributes, ctx.toRange(node.loc), )(ctx); @@ -1699,13 +1724,7 @@ const parseMethod = if (isExtends) { ctx.err.localExtends()(ctx.toRange(node.loc)); } - return Ast.Method( - !!isMutates, - inh.overridable, - inh.override, - get, - fn, - ); + return Ast.Method(!!isMutates, inh.overridable, inh.override, get, fn); }; const parseMessageDecl = @@ -1742,9 +1761,7 @@ const parseNativeFunctionDecl = Ast.FnType( map(parseList(typeParams), parseTypeId)(ctx), map(parseList(parameters), parseParameter)(ctx), - returnType - ? parseType(returnType)(ctx) - : Ast.TypeVoid(range), + returnType ? parseType(returnType)(ctx) : Ast.TypeVoid(range), ), Ast.NativeBody(parseFuncId(nativeName)(ctx)), range, @@ -1830,47 +1847,48 @@ const parseTrait = ); }; -type LocalItem = Ast.FieldDecl | Ast.Receiver | Ast.Method | Ast.FieldConstant -const parseLocalItem: ( - input: $ast.traitItemDecl, -) => Handler = makeVisitor<$ast.traitItemDecl>()({ - FieldDecl: parseFieldDecl, - Receiver: parseReceiver, - Function: parseMethod(parseFunctionRaw), - AsmFunction: parseMethod(parseAsmFunctionRaw), - Constant: parseFieldConstant, -}); +type LocalItem = Ast.FieldDecl | Ast.Receiver | Ast.Method | Ast.FieldConstant; +const parseLocalItem: (input: $ast.traitItemDecl) => Handler = + makeVisitor<$ast.traitItemDecl>()({ + FieldDecl: parseFieldDecl, + Receiver: parseReceiver, + Function: parseMethod(parseFunctionRaw), + AsmFunction: parseMethod(parseAsmFunctionRaw), + Constant: parseFieldConstant, + }); -const parseLocalItems = (items: readonly $ast.traitItemDecl[]): Handler => ctx => { - const locals = map(items, parseLocalItem)(ctx); +const parseLocalItems = + (items: readonly $ast.traitItemDecl[]): Handler => + (ctx) => { + const locals = map(items, parseLocalItem)(ctx); - const fields: Ast.FieldDecl[] = []; - const methods: Ast.Method[] = []; - const receivers: Ast.Receiver[] = []; - const constants: Ast.FieldConstant[] = []; + const fields: Ast.FieldDecl[] = []; + const methods: Ast.Method[] = []; + const receivers: Ast.Receiver[] = []; + const constants: Ast.FieldConstant[] = []; - for (const item of locals) { - switch (item.kind) { - case "field_decl": { - fields.push(item); - continue; - } - case "receiver": { - receivers.push(item); - continue; - } - case "method": { - methods.push(item); - continue; - } - case "field_const": { - constants.push(item); - continue; + for (const item of locals) { + switch (item.kind) { + case "field_decl": { + fields.push(item); + continue; + } + case "receiver": { + receivers.push(item); + continue; + } + case "method": { + methods.push(item); + continue; + } + case "field_const": { + constants.push(item); + continue; + } } } - } - return { fields, methods, receivers, constants }; -}; + return { fields, methods, receivers, constants }; + }; type ModuleItemAux = Exclude<$ast.moduleItem, $ast.PrimitiveTypeDecl>; @@ -1888,11 +1906,7 @@ const parseModuleItemAux: (input: ModuleItemAux) => Handler = AliasDecl: parseAlias, }); -type ModuleItem = - | Ast.Function - | Ast.Extension - | Ast.Constant - | Ast.TypeDecl +type ModuleItem = Ast.Function | Ast.Extension | Ast.Constant | Ast.TypeDecl; const parseModuleItem = (node: $ast.moduleItem): Handler => diff --git a/src/next/imports/reader.ts b/src/next/imports/reader.ts index bbb4c7902a..f379af588a 100644 --- a/src/next/imports/reader.ts +++ b/src/next/imports/reader.ts @@ -4,7 +4,13 @@ import { parentPath, createMemoryFs, createProxyFs } from "@/next/fs"; import { getFiles } from "@/next/stdlib"; import type { Cursor } from "@/next/fs"; import type { AnyLogger, Logger, SourceLogger } from "@/error/logger-util"; -import type { FuncImport, Implicit, ResolvedImport, TactImport, TactSource } from "@/next/imports/source"; +import type { + FuncImport, + Implicit, + ResolvedImport, + TactImport, + TactSource, +} from "@/next/imports/source"; import type { ModuleItems, Loc } from "@/next/ast"; import { hideProperty } from "@/utils/tricks"; @@ -61,7 +67,7 @@ export const readSource = async ({ imports.push(FuncImport(code, loc)); } } - return { kind: 'tact', path, code, imports, items }; + return { kind: "tact", path, code, imports, items }; }; const resolveSource = async ( @@ -132,7 +138,7 @@ export const ProjectReader = async (log: Logger) => { kind: "tact", source: stdStd, loc: { - kind: 'implicit', + kind: "implicit", }, }, ]; @@ -150,18 +156,23 @@ export const ProjectReader = async (log: Logger) => { const TactImport = (source: TactSource, loc: Loc | Implicit) => { const result: TactImport = { kind: "tact", source, loc }; - hideProperty(result, 'source'); + hideProperty(result, "source"); return result; }; const FuncImport = (code: string, loc: Loc) => { const result: FuncImport = { kind: "func", code, loc }; - hideProperty(result, 'code'); + hideProperty(result, "code"); return result; }; -const TactSource = (path: string, code: string, imports: readonly ResolvedImport[], items: ModuleItems) => { - const result: TactSource = { kind: 'tact', path, code, imports, items }; - hideProperty(result, 'code'); +const TactSource = ( + path: string, + code: string, + imports: readonly ResolvedImport[], + items: ModuleItems, +) => { + const result: TactSource = { kind: "tact", path, code, imports, items }; + hideProperty(result, "code"); return result; }; diff --git a/src/next/imports/source.ts b/src/next/imports/source.ts index e96af2067d..6232c21fc1 100644 --- a/src/next/imports/source.ts +++ b/src/next/imports/source.ts @@ -22,4 +22,4 @@ export type FuncImport = { export type Implicit = { readonly kind: "implicit"; -} +}; diff --git a/src/next/test/_cli.build.ts b/src/next/test/_cli.build.ts index 507d079706..b7aa496b73 100644 --- a/src/next/test/_cli.build.ts +++ b/src/next/test/_cli.build.ts @@ -2,7 +2,7 @@ import { resolve } from "path"; import { runTest } from "@/next/test/_test.build"; const main = async () => { - const path = resolve(process.argv[2] ?? ''); + const path = resolve(process.argv[2] ?? ""); console.log(await runTest(path)); }; diff --git a/src/next/test/_run.test.ts b/src/next/test/_run.test.ts index f39344e6ff..0dc76b9dd2 100644 --- a/src/next/test/_run.test.ts +++ b/src/next/test/_run.test.ts @@ -6,31 +6,34 @@ import { runTest } from "@/next/test/_test.build"; const root = __dirname; const listCases = (): readonly string[] => { - return fs.readdirSync(root) - .filter(file => file.endsWith(".tact")) - .map(file => join(root, file)); + return fs + .readdirSync(root) + .filter((file) => file.endsWith(".tact")) + .map((file) => join(root, file)); }; const readFileOpt = async (path: string): Promise => { try { - return await readFile(path, 'utf8'); + return await readFile(path, "utf8"); } catch (err) { // eslint-disable-next-line @typescript-eslint/no-explicit-any - if (err && (err as any).code === 'ENOENT') return undefined; + if (err && (err as any).code === "ENOENT") return undefined; throw err; } }; it.each(listCases())("%s", async (path) => { const newText = await runTest(path); - const snapPath = join(dirname(path), basename(path, extname(path)) + '.snap.js'); - const isUpdate = expect.getState().snapshotState._updateSnapshot === 'all'; + const snapPath = join( + dirname(path), + basename(path, extname(path)) + ".snap.js", + ); + const isUpdate = expect.getState().snapshotState._updateSnapshot === "all"; const oldText = await readFileOpt(snapPath); - if (isUpdate || typeof oldText === 'undefined') { - await writeFile(snapPath, newText, 'utf-8'); + if (isUpdate || typeof oldText === "undefined") { + await writeFile(snapPath, newText, "utf-8"); expect(newText).toBe(newText); } else { expect(newText).toBe(oldText); } }); - diff --git a/src/next/test/_test.build.ts b/src/next/test/_test.build.ts index 56b406d164..d7cd753806 100644 --- a/src/next/test/_test.build.ts +++ b/src/next/test/_test.build.ts @@ -24,24 +24,15 @@ export const runTest = async (path: string): Promise => { return toJs(types); }; -export const buildE2E = async ( - log: Logger, - path: string, -) => { +export const buildE2E = async (log: Logger, path: string) => { const reader = await ProjectReader(log); if (!reader) { return; } - return await reader.read( - dirname(path), - basename(path), - ); -} + return await reader.read(dirname(path), basename(path)); +}; -export const buildNoStdlib = async ( - log: Logger, - path: string, -) => { +export const buildNoStdlib = async (log: Logger, path: string) => { const project = createProxyFs({ log, root: dirname(path), @@ -55,9 +46,9 @@ export const buildNoStdlib = async ( log, files: new Map(), isReadonly: true, - root: fromString('.'), + root: fromString("."), }), implicits, root: basename(path), }); -}; \ No newline at end of file +}; diff --git a/src/next/test/fun-shadow-1.snap.js b/src/next/test/fun-shadow-1.snap.js index bd2ea137dc..4a14bd2eb1 100644 --- a/src/next/test/fun-shadow-1.snap.js +++ b/src/next/test/fun-shadow-1.snap.js @@ -1,43 +1,46 @@ const x1 = { - kind: "range", - start: 32, - end: 44, + kind: "range", + start: 32, + end: 44, }; export default { - types: { - scope: { - functions: new Map([ - ["foo", { - value: { - kind: "function", - inline: false, - name: { - kind: "id", - text: "foo", - loc: { - kind: "range", - start: 36, - end: 39, - }, - }, - typeParams: [], - returnType: undefined, - params: [], - body: { - kind: "regular_body", - statements: [], - }, - loc: x1, - }, - via: { - kind: "user", - imports: [], - defLoc: x1, - }, - }], - ]), + types: { + scope: { + functions: new Map([ + [ + "foo", + { + value: { + kind: "function", + inline: false, + name: { + kind: "id", + text: "foo", + loc: { + kind: "range", + start: 36, + end: 39, + }, + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: "regular_body", + statements: [], + }, + loc: x1, + }, + via: { + kind: "user", + imports: [], + defLoc: x1, + }, + }, + ], + ]), + }, }, - }, - result: [], + result: [], }; diff --git a/src/next/test/fun-shadow-2.snap.js b/src/next/test/fun-shadow-2.snap.js index 1ef9a5432c..568edc5647 100644 --- a/src/next/test/fun-shadow-2.snap.js +++ b/src/next/test/fun-shadow-2.snap.js @@ -1,41 +1,41 @@ export default { - types: { - errors: [ - { - loc: { - kind: "range", - start: 82, - end: 94, - }, - descr: [ - { - kind: "text", - text: "There already is a function \"foo\" from", - }, - { - kind: "via", - via: { - kind: "user", - imports: [ - { - kind: "tact", - loc: { + types: { + errors: [ + { + loc: { kind: "range", - start: 56, - end: 80, - }, + start: 82, + end: 94, }, - ], - defLoc: { - kind: "range", - start: 32, - end: 44, - }, + descr: [ + { + kind: "text", + text: 'There already is a function "foo" from', + }, + { + kind: "via", + via: { + kind: "user", + imports: [ + { + kind: "tact", + loc: { + kind: "range", + start: 56, + end: 80, + }, + }, + ], + defLoc: { + kind: "range", + start: 32, + end: 44, + }, + }, + }, + ], }, - }, ], - }, - ], - }, - result: [], + }, + result: [], }; diff --git a/src/next/test/fun-shadow-3.snap.js b/src/next/test/fun-shadow-3.snap.js index c0c5f152ff..57e2d875aa 100644 --- a/src/next/test/fun-shadow-3.snap.js +++ b/src/next/test/fun-shadow-3.snap.js @@ -1,52 +1,55 @@ const x1 = { - kind: "range", - start: 32, - end: 44, + kind: "range", + start: 32, + end: 44, }; export default { - types: { - scope: { - functions: new Map([ - ["foo", { - value: { - kind: "function", - inline: false, - name: { - kind: "id", - text: "foo", - loc: { - kind: "range", - start: 36, - end: 39, - }, - }, - typeParams: [], - returnType: undefined, - params: [], - body: { - kind: "regular_body", - statements: [], - }, - loc: x1, - }, - via: { - kind: "user", - imports: [ - { - kind: "tact", - loc: { - kind: "range", - start: 47, - end: 71, - }, - }, - ], - defLoc: x1, - }, - }], - ]), + types: { + scope: { + functions: new Map([ + [ + "foo", + { + value: { + kind: "function", + inline: false, + name: { + kind: "id", + text: "foo", + loc: { + kind: "range", + start: 36, + end: 39, + }, + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: "regular_body", + statements: [], + }, + loc: x1, + }, + via: { + kind: "user", + imports: [ + { + kind: "tact", + loc: { + kind: "range", + start: 47, + end: 71, + }, + }, + ], + defLoc: x1, + }, + }, + ], + ]), + }, }, - }, - result: [], + result: [], }; diff --git a/src/next/test/fun-shadow-4.snap.js b/src/next/test/fun-shadow-4.snap.js index a76fab8e70..e32bb706b2 100644 --- a/src/next/test/fun-shadow-4.snap.js +++ b/src/next/test/fun-shadow-4.snap.js @@ -1,52 +1,55 @@ const x1 = { - kind: "range", - start: 32, - end: 44, + kind: "range", + start: 32, + end: 44, }; export default { - types: { - scope: { - functions: new Map([ - ["foo", { - value: { - kind: "function", - inline: false, - name: { - kind: "id", - text: "foo", - loc: { - kind: "range", - start: 36, - end: 39, - }, - }, - typeParams: [], - returnType: undefined, - params: [], - body: { - kind: "regular_body", - statements: [], - }, - loc: x1, - }, - via: { - kind: "user", - imports: [ - { - kind: "tact", - loc: { - kind: "range", - start: 90, - end: 114, - }, - }, - ], - defLoc: x1, - }, - }], - ]), + types: { + scope: { + functions: new Map([ + [ + "foo", + { + value: { + kind: "function", + inline: false, + name: { + kind: "id", + text: "foo", + loc: { + kind: "range", + start: 36, + end: 39, + }, + }, + typeParams: [], + returnType: undefined, + params: [], + body: { + kind: "regular_body", + statements: [], + }, + loc: x1, + }, + via: { + kind: "user", + imports: [ + { + kind: "tact", + loc: { + kind: "range", + start: 90, + end: 114, + }, + }, + ], + defLoc: x1, + }, + }, + ], + ]), + }, }, - }, - result: [], + result: [], }; diff --git a/src/next/test/fun-shadow-5.snap.js b/src/next/test/fun-shadow-5.snap.js index e62c55d34a..82f0ac7a86 100644 --- a/src/next/test/fun-shadow-5.snap.js +++ b/src/next/test/fun-shadow-5.snap.js @@ -1,41 +1,41 @@ export default { - types: { - errors: [ - { - loc: { - kind: "range", - start: 136, - end: 148, - }, - descr: [ - { - kind: "text", - text: "There already is a function \"foo\" from", - }, - { - kind: "via", - via: { - kind: "user", - imports: [ - { - kind: "tact", - loc: { + types: { + errors: [ + { + loc: { kind: "range", - start: 85, - end: 109, - }, + start: 136, + end: 148, }, - ], - defLoc: { - kind: "range", - start: 32, - end: 44, - }, + descr: [ + { + kind: "text", + text: 'There already is a function "foo" from', + }, + { + kind: "via", + via: { + kind: "user", + imports: [ + { + kind: "tact", + loc: { + kind: "range", + start: 85, + end: 109, + }, + }, + ], + defLoc: { + kind: "range", + start: 32, + end: 44, + }, + }, + }, + ], }, - }, ], - }, - ], - }, - result: [], + }, + result: [], }; diff --git a/src/next/test/to-code.ts b/src/next/test/to-code.ts index f509aa2d6b..20ceb01d8d 100644 --- a/src/next/test/to-code.ts +++ b/src/next/test/to-code.ts @@ -4,14 +4,14 @@ function isValidId(key: string) { return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(key); } -const pad = (s: readonly string[]) => s.map(s => " " + s); +const pad = (s: readonly string[]) => s.map((s) => " " + s); function concat(s: readonly string[], t: readonly string[]): readonly string[] { const [last, ...init] = [...s].reverse(); const [head, ...tail] = t; - if (typeof last === 'undefined') { + if (typeof last === "undefined") { return t; - } else if (typeof head === 'undefined') { + } else if (typeof head === "undefined") { return s; } else { return [...init.reverse(), last + head, ...tail]; @@ -28,26 +28,33 @@ const braced = (l: string, code: readonly string[], r: string) => { }; export function toJs(value: unknown): string { - const counts: Map = new Map(); + const counts: Map = new Map(); const order: Map = new Map(); let nextId = 0; function countUsages(val: unknown) { - if (typeof val !== 'object' || val === null || val instanceof Date || val instanceof RegExp) { + if ( + typeof val !== "object" || + val === null || + val instanceof Date || + val instanceof RegExp + ) { return; } const newCount = counts.get(val); if (!newCount) { - counts.set(val, 'exists'); - const items = - Array.isArray(val) ? val : - val instanceof Map ? val.entries().flatMap((kv) => kv) : - val instanceof Set ? [...val] : - Object.entries(val) - + counts.set(val, "exists"); + const items = Array.isArray(val) + ? val + : val instanceof Map + ? val.entries().flatMap((kv) => kv) + : val instanceof Set + ? [...val] + : Object.entries(val); + for (const item of items) { countUsages(item); } - } else if (newCount === 'exists') { + } else if (newCount === "exists") { const name = `x${++nextId}`; counts.set(val, { name }); } @@ -55,7 +62,7 @@ export function toJs(value: unknown): string { function show(val: unknown): readonly string[] { const count = counts.get(val); - if (typeof count !== 'object') { + if (typeof count !== "object") { return showAny(val); } if (!order.has(count.name)) { @@ -69,14 +76,26 @@ export function toJs(value: unknown): string { function showAny(val: unknown): readonly string[] { switch (typeof val) { - case "string": return [JSON.stringify(val)]; - case "number": return [String(val)]; - case "boolean": return [String(val)]; - case "bigint": return [val.toString() + 'n']; - case "symbol": return [val.description ? `Symbol(${JSON.stringify(val.description)})` : 'Symbol()']; - case "undefined": return ['undefined']; - case "object": return val === null ? ["null"] : showObject(val); - case "function": return showFunction(val); + case "string": + return [JSON.stringify(val)]; + case "number": + return [String(val)]; + case "boolean": + return [String(val)]; + case "bigint": + return [val.toString() + "n"]; + case "symbol": + return [ + val.description + ? `Symbol(${JSON.stringify(val.description)})` + : "Symbol()", + ]; + case "undefined": + return ["undefined"]; + case "object": + return val === null ? ["null"] : showObject(val); + case "function": + return showFunction(val); } } @@ -86,9 +105,9 @@ export function toJs(value: unknown): string { return [`new Function(${val.toString()})`]; } const result = val[printSym](); - if (result === 'waiting') { + if (result === "waiting") { return [`Waiting()`]; - } else if (result === 'running') { + } else if (result === "running") { return [`Running()`]; } else { return show(result); @@ -104,51 +123,49 @@ export function toJs(value: unknown): string { } if (Array.isArray(val)) { return braced( - '[', + "[", val.flatMap((item) => { return concat(show(item), [","]); }), - ']', + "]", ); } if (val instanceof Map) { return braced( - 'new Map([', + "new Map([", [...val.entries()].flatMap(([k, v]) => { return concatAll([["["], show(k), [", "], show(v), ["],"]]); }), - '])', + "])", ); } if (val instanceof Set) { return braced( - 'new Set([', + "new Set([", [...val].flatMap((k) => { return concat(show(k), [","]); }), - '])', + "])", ); } return braced( - '{', + "{", Object.entries(val).flatMap(([k, v]) => { const keyRep = isValidId(k) ? k : JSON.stringify(k); return concatAll([[keyRep], [": "], show(v), [","]]); }), - '}', + "}", ); }; countUsages(value); const res = show(value); - const code = [...order.entries()].flatMap(([varName, code]) => { - return concatAll([ - [`const ${varName} = `], - code, - [";"], - ]); - }).join('\n'); + const code = [...order.entries()] + .flatMap(([varName, code]) => { + return concatAll([[`const ${varName} = `], code, [";"]]); + }) + .join("\n"); - return `${code ? `${code}\n\n` : ''}export default ${res.join('\n')};\n`; + return `${code ? `${code}\n\n` : ""}export default ${res.join("\n")};\n`; } diff --git a/src/next/types/body.ts b/src/next/types/body.ts index e6cfad3f8d..8214ee618f 100644 --- a/src/next/types/body.ts +++ b/src/next/types/body.ts @@ -13,40 +13,42 @@ export function* decodeBody( ): Ast.WithLog { switch (node.kind) { case "abstract_body": { - yield ENoBody(loc) - return Ast.TactBody(Lazy({ - callback: function* () { return undefined; }, - context: [Ast.TEText("checking body of function")], - loc, - recover: undefined, - })); + yield ENoBody(loc); + return Ast.TactBody( + Lazy({ + callback: function* () { + return undefined; + }, + context: [Ast.TEText("checking body of function")], + loc, + recover: undefined, + }), + ); } case "regular_body": { const selfTypeRef = () => { - return fnType.kind === 'DecodedMethodType' + return fnType.kind === "DecodedMethodType" ? fnType.self : undefined; }; - return Ast.TactBody(decodeStatementsLazy( - Lazy, - loc, - node.statements, - fnType.typeParams, - selfTypeRef, - fnType.returnType, - true, - scopeRef, - )); + return Ast.TactBody( + decodeStatementsLazy( + Lazy, + loc, + node.statements, + fnType.typeParams, + selfTypeRef, + fnType.returnType, + true, + scopeRef, + ), + ); } case "asm_body": { return Ast.FiftBody( Lazy({ - callback: () => checkShuffle( - node.shuffle, - fnType, - loc, - scopeRef, - ), + callback: () => + checkShuffle(node.shuffle, fnType, loc, scopeRef), context: [Ast.TEText("checking shuffle")], loc, recover: undefined, @@ -60,13 +62,9 @@ export function* decodeBody( } } -const ENoBody = ( - loc: Ast.Loc, -): Ast.TcError => ({ +const ENoBody = (loc: Ast.Loc): Ast.TcError => ({ loc, - descr: [ - Ast.TEText(`Function must have a body`), - ], + descr: [Ast.TEText(`Function must have a body`)], }); function* checkShuffle( @@ -107,15 +105,14 @@ function* checkShuffle( if (shuffleRetSet.size !== ret.length) { yield EDuplicateRet(loc); } - - const retTupleSize = yield* getRetTupleSize( - fnType, - scopeRef, - ); - if (typeof retTupleSize !== 'undefined') { + const retTupleSize = yield* getRetTupleSize(fnType, scopeRef); + + if (typeof retTupleSize !== "undefined") { const returnValueSet = new Set([ - ...Array(retTupleSize).keys().map(x => BigInt(x)) + ...Array(retTupleSize) + .keys() + .map((x) => BigInt(x)), ]); if (!isSubsetOf(returnValueSet, shuffleRetSet)) { @@ -127,7 +124,7 @@ function* checkShuffle( } } } - + return shuffle; } @@ -137,16 +134,13 @@ function* getRetTupleSize( ): Ast.WithLog { const type = yield* returnType(); const baseSize = yield* getTypeTupleSize(type, scopeRef); - if (typeof baseSize === 'undefined') { + if (typeof baseSize === "undefined") { return undefined; } - return baseSize + (kind === 'DecodedMethodType' ? 1 : 0); + return baseSize + (kind === "DecodedMethodType" ? 1 : 0); } -function* getTypeTupleSize( - type: Ast.DecodedType, - scopeRef: () => Ast.Scope, -) { +function* getTypeTupleSize(type: Ast.DecodedType, scopeRef: () => Ast.Scope) { switch (type.kind) { case "recover": { return undefined; @@ -225,37 +219,35 @@ function* getTypeTupleSize( const EDuplicateArgs = (loc: Ast.Loc): Ast.TcError => ({ loc, - descr: [ - Ast.TEText(`Argument rearrangement cannot have duplicates`), - ], + descr: [Ast.TEText(`Argument rearrangement cannot have duplicates`)], }); const EWildcardArgs = (loc: Ast.Loc): Ast.TcError => ({ loc, - descr: [ - Ast.TEText(`Argument rearrangement cannot use wildcards`), - ], + descr: [Ast.TEText(`Argument rearrangement cannot use wildcards`)], }); const EMissingArgs = (loc: Ast.Loc): Ast.TcError => ({ loc, descr: [ - Ast.TEText(`Argument rearrangement must mention all function parameters`), + Ast.TEText( + `Argument rearrangement must mention all function parameters`, + ), ], }); const EExtraArgs = (loc: Ast.Loc): Ast.TcError => ({ loc, descr: [ - Ast.TEText(`Argument rearrangement must mention only function parameters`), + Ast.TEText( + `Argument rearrangement must mention only function parameters`, + ), ], }); const EDuplicateRet = (loc: Ast.Loc): Ast.TcError => ({ loc, - descr: [ - Ast.TEText(`Return rearrangement cannot have duplicates`), - ], + descr: [Ast.TEText(`Return rearrangement cannot have duplicates`)], }); const EMissingRet = (loc: Ast.Loc): Ast.TcError => ({ @@ -268,6 +260,8 @@ const EMissingRet = (loc: Ast.Loc): Ast.TcError => ({ const EExtraRet = (loc: Ast.Loc): Ast.TcError => ({ loc, descr: [ - Ast.TEText(`Return rearrangement must mention only function parameters`), + Ast.TEText( + `Return rearrangement must mention only function parameters`, + ), ], }); diff --git a/src/next/types/builtins.ts b/src/next/types/builtins.ts index 152c684852..9b6839959f 100644 --- a/src/next/types/builtins.ts +++ b/src/next/types/builtins.ts @@ -9,7 +9,7 @@ export const tactMethodIds = [113617n, 115390n, 121275n]; const r = Ast.Builtin(); const TypeParams = (typeParams: readonly string[]): Ast.TypeParams => { - const arr = typeParams.map(name => Ast.TypeId(name, r)); + const arr = typeParams.map((name) => Ast.TypeId(name, r)); return Ast.TypeParams(arr, new Set(typeParams)); }; @@ -29,24 +29,44 @@ const Ref = (name: string): Ast.DTypeParamRef => { const mapType = Ast.MVTypeMap(Ref("K"), Ref("V"), r); -const GenericFn = (name: string, typeParams: readonly string[], params: Record, returnType: Ast.DecodedType): [string, Ast.DecodedFnType] => { - return [name, Ast.DecodedFnType( - TypeParams(typeParams), - Params(params), - Ast.FakeThunk(returnType), - )]; +const GenericFn = ( + name: string, + typeParams: readonly string[], + params: Record, + returnType: Ast.DecodedType, +): [string, Ast.DecodedFnType] => { + return [ + name, + Ast.DecodedFnType( + TypeParams(typeParams), + Params(params), + Ast.FakeThunk(returnType), + ), + ]; }; -const Fn = (name: string, params: Record, returnType: Ast.DecodedType): [string, Ast.DecodedFnType] => { +const Fn = ( + name: string, + params: Record, + returnType: Ast.DecodedType, +): [string, Ast.DecodedFnType] => { return GenericFn(name, [], params, returnType); }; -const MapMethod = (name: string, mutates: boolean, params: Record, returnType: Ast.DecodedType): [string, Ast.DecodedMethodType] => { - return [name, Ast.DecodedMethodType( - mutates, - TypeParams(["K", "V"]), - mapType, - Params(params), - Ast.FakeThunk(returnType), - )]; +const MapMethod = ( + name: string, + mutates: boolean, + params: Record, + returnType: Ast.DecodedType, +): [string, Ast.DecodedMethodType] => { + return [ + name, + Ast.DecodedMethodType( + mutates, + TypeParams(["K", "V"]), + mapType, + Params(params), + Ast.FakeThunk(returnType), + ), + ]; }; export const Int = Ast.TypeInt(Ast.IFInt("signed", 257, r), r); @@ -59,15 +79,28 @@ export const Bool = Ast.TypeBool(r); export const Address = Ast.TypeAddress(r); export const String = Ast.TypeString(r); export const StringBuilder = Ast.TypeStringBuilder(r); -export const MapType = (k: Ast.DecodedType, v: Ast.DecodedType) => Ast.DTypeMap(k, v, r); -export const Maybe = (t: Ast.DecodedType) => Ast.DTypeMaybe(t, r) +export const MapType = (k: Ast.DecodedType, v: Ast.DecodedType) => + Ast.DTypeMap(k, v, r); +export const Maybe = (t: Ast.DecodedType) => Ast.DTypeMaybe(t, r); export const Unit = Ast.TypeUnit(r); export const StateInit = Ast.DTypeStateInit(r); -export const builtinTypes = new Map([ - "Int", "Slice", "Cell", "Builder", "Void", "Null", "Bool", - "Address", "String", "StringBuilder", "Map", "Maybe" -].map(s => [s, s])); +export const builtinTypes = new Map( + [ + "Int", + "Slice", + "Cell", + "Builder", + "Void", + "Null", + "Bool", + "Address", + "String", + "StringBuilder", + "Map", + "Maybe", + ].map((s) => [s, s]), +); const ArithBin = (name: string) => { return Fn(name, { left: Int, right: Int }, Int); @@ -187,13 +220,15 @@ export const builtinAugmented: Map = new Map([ BoolAssign("||="), ]); -export const getStaticBuiltin = (type: Ast.DecodedType): Map => { +export const getStaticBuiltin = ( + type: Ast.DecodedType, +): Map => { return new Map([ // Foo.fromSlice(slice: Slice) Fn("fromSlice", { slice: Slice }, type), // Foo.fromSlice(cell: Cell) Fn("fromCell", { cell: Cell }, type), - ]) + ]); }; export const structBuiltin = new Map([ @@ -209,5 +244,5 @@ export const messageBuiltin = new Map([ // Foo.toCell(): Cell Fn("toCell", {}, Cell), // Foo.opcode(): Int - Fn("opcode", {}, Int) + Fn("opcode", {}, Int), ]); diff --git a/src/next/types/constant-def.ts b/src/next/types/constant-def.ts index 6b1e3956b4..9c54d379de 100644 --- a/src/next/types/constant-def.ts +++ b/src/next/types/constant-def.ts @@ -29,7 +29,13 @@ export function decodeConstantDef( ); const computed = expr.computedType; const ascribed = yield* ascribedType(); - yield* assignType(defLoc, emptyTypeParams, ascribed, computed, false); + yield* assignType( + defLoc, + emptyTypeParams, + ascribed, + computed, + false, + ); return yield* evalExpr(expr, scopeRef); } const lazyExpr = Lazy({ @@ -42,14 +48,15 @@ export function decodeConstantDef( } else { // first we decode expression const expr = Lazy({ - callback: (Lazy) => decodeExpr( - Lazy, - typeParams, - initializer, - scopeRef, - selfType, - new Map(), - ), + callback: (Lazy) => + decodeExpr( + Lazy, + typeParams, + initializer, + scopeRef, + selfType, + new Map(), + ), context: [Ast.TEText("parsing expression")], loc: defLoc, recover: undefined, diff --git a/src/next/types/constants.ts b/src/next/types/constants.ts index a936981b5f..1b007ab567 100644 --- a/src/next/types/constants.ts +++ b/src/next/types/constants.ts @@ -15,29 +15,37 @@ export function* decodeConstants( ): Ast.WithLog>> { const allConstSigs = [ // imported - ...imported.flatMap(({ globals, importedBy }) => ( - [...globals.constants] - .map(([name, s]) => [name, Ast.Decl(s.decl, Ast.ViaImport(importedBy, s.via))] as const) - )), + ...imported.flatMap(({ globals, importedBy }) => + [...globals.constants].map( + ([name, s]) => + [ + name, + Ast.Decl(s.decl, Ast.ViaImport(importedBy, s.via)), + ] as const, + ), + ), // local - ...yield* Ast.mapLog(source.items.constants, function* (c) { + ...(yield* Ast.mapLog(source.items.constants, function* (c) { return [ - c.name.text, + c.name.text, Ast.Decl( yield* decodeConstant(Lazy, c, scopeRef), - Ast.ViaOrigin(c.loc, source) + Ast.ViaOrigin(c.loc, source), ), ] as const; - }), + })), ]; // remove builtins - const filteredSigs = yield* Ast.filterLog(allConstSigs, function* ([name, { via }]) { - const isBuiltin = builtinFunctions.has(name); - if (isBuiltin) { - yield Ast.ERedefine(errorKind, name, Ast.ViaBuiltin(), via); - } - return !isBuiltin; - }); + const filteredSigs = yield* Ast.filterLog( + allConstSigs, + function* ([name, { via }]) { + const isBuiltin = builtinFunctions.has(name); + if (isBuiltin) { + yield Ast.ERedefine(errorKind, name, Ast.ViaBuiltin(), via); + } + return !isBuiltin; + }, + ); return yield* Ast.toMap(errorKind, filteredSigs); } @@ -51,15 +59,25 @@ function* decodeConstant( yield ETopLevelDecl(loc); const type = Lazy({ loc: constant.loc, - context: [Ast.TEText("defining constant"), Ast.TECode(constant.loc)], + context: [ + Ast.TEText("defining constant"), + Ast.TECode(constant.loc), + ], recover: Ast.DTypeRecover(), - callback: function*() { return Ast.DTypeRecover(); }, + callback: function* () { + return Ast.DTypeRecover(); + }, }); const expr = Lazy({ loc: constant.loc, - context: [Ast.TEText("defining constant"), Ast.TECode(constant.loc)], + context: [ + Ast.TEText("defining constant"), + Ast.TECode(constant.loc), + ], recover: Ast.VNumber(0n, constant.loc), - callback: function*() { return Ast.VNumber(0n, constant.loc); }, + callback: function* () { + return Ast.VNumber(0n, constant.loc); + }, }); return Ast.ConstSig(expr, type); } else { @@ -77,7 +95,5 @@ function* decodeConstant( const ETopLevelDecl = (loc: Ast.Loc): Ast.TcError => ({ loc, - descr: [ - Ast.TEText(`Top-level constant must have a body`), - ], + descr: [Ast.TEText(`Top-level constant must have a body`)], }); diff --git a/src/next/types/contract.ts b/src/next/types/contract.ts index 87921f5f3a..baa46b7392 100644 --- a/src/next/types/contract.ts +++ b/src/next/types/contract.ts @@ -37,11 +37,8 @@ export function* decodeContract( // delayed until we get all traits and init const contentLazy: Ast.Thunk = Lazy({ callback: function* (Lazy) { - const traits = yield* getInheritedTraits( - contract.traits, - scopeRef, - ); - + const traits = yield* getInheritedTraits(contract.traits, scopeRef); + // const contentRef = () => content; const content: Ast.ContractContent = { fieldish: yield* getFieldishFromContract( @@ -71,7 +68,7 @@ export function* decodeContract( scopeRef, ), }; - + return content; }, context: [Ast.TEText("checking scope of contract")], @@ -104,14 +101,17 @@ function* decodeInit( const lazyInit = Lazy({ callback: function* () { const order: string[] = []; - const map: Map>> = new Map(); + const map: Map< + string, + Ast.Thunk> + > = new Map(); const { fieldish } = yield* contentLazy()(); for (const name of fieldish.order) { const f = fieldish.map.get(name); if (!f) { return throwInternal("Missing field"); } - if (f.decl.kind === 'field') { + if (f.decl.kind === "field") { const init = f.decl.init; if (init) { order.push(name); @@ -128,7 +128,7 @@ function* decodeInit( recover: undefined, }); return Ast.InitEmpty(lazyInit); - } else if (init.kind === 'init_params') { + } else if (init.kind === "init_params") { const order: string[] = []; const paramMap: Map = new Map(); for (const param of init.params) { @@ -144,7 +144,12 @@ function* decodeInit( const map: Map = new Map(); for (const [name, param] of paramMap) { - const decoded = decodeTypeLazy(Lazy, emptyTypeParams, param.type, scopeRef) + const decoded = decodeTypeLazy( + Lazy, + emptyTypeParams, + param.type, + scopeRef, + ); if (!param.initializer) { yield ENoInitializerParams(param.loc); } @@ -165,7 +170,9 @@ function* decodeInit( emptyTypeParams, selfTypeRef, Lazy({ - callback: function* () { return Void; }, + callback: function* () { + return Void; + }, context: [], loc: init.loc, recover: Void, @@ -191,20 +198,16 @@ const EDuplicateParam = ( Ast.TECode(prev), ], }); -const ENoInitializerParams = ( - loc: Ast.Loc, -): Ast.TcError => ({ +const ENoInitializerParams = (loc: Ast.Loc): Ast.TcError => ({ loc, - descr: [ - Ast.TEText(`Contract parameters cannot have an initializer`), - ], + descr: [Ast.TEText(`Contract parameters cannot have an initializer`)], }); -const ENoInitializerEmpty = ( - loc: Ast.Loc, -): Ast.TcError => ({ +const ENoInitializerEmpty = (loc: Ast.Loc): Ast.TcError => ({ loc, descr: [ - Ast.TEText(`When there is no init() or contract parameters, all fields must have an initializer`), + Ast.TEText( + `When there is no init() or contract parameters, all fields must have an initializer`, + ), ], }); @@ -214,14 +217,14 @@ function* getMethodsFromContract( typeName: Ast.TypeId, traits: readonly Ast.Decl[], methods: readonly Ast.Method[], - scopeRef: () => Ast.Scope + scopeRef: () => Ast.Scope, ): Ast.WithLog>>> { const res = yield* getMethodsGeneral( Lazy, contractSig, - typeName, - traits, - methods, + typeName, + traits, + methods, scopeRef, ); @@ -230,10 +233,7 @@ function* getMethodsFromContract( if (method.body) { // have to recreate DeclMem, because TS doesn't // narrow here - map.set(name, Ast.DeclMem( - { ...method, body: method.body }, - via, - )); + map.set(name, Ast.DeclMem({ ...method, body: method.body }, via)); } else { // field/constant doesn't have initializer yield EAbstract("method", name, via); @@ -252,19 +252,24 @@ function* getFieldishFromContract( constants: readonly Ast.FieldConstant[], fields: readonly Ast.FieldDecl[], scopeRef: () => Ast.Scope, -): Ast.WithLog>>>>> { +): Ast.WithLog< + Ast.Ordered>>>> +> { const res = yield* getFieldishGeneral( Lazy, contractSig, - typeName, - traits, - constants, - fields, + typeName, + traits, + constants, + fields, scopeRef, ); - + const order: string[] = []; - const map: Map>>>> = new Map(); + const map: Map< + string, + Ast.DeclMem>>> + > = new Map(); for (const name of res.order) { const field = res.map.get(name); if (!field) { @@ -273,36 +278,43 @@ function* getFieldishFromContract( if (field.decl.init) { // have to recreate DeclMem, because TS doesn't // narrow here - map.set(name, Ast.DeclMem( - { ...field.decl, init: field.decl.init }, - field.via, - )); + map.set( + name, + Ast.DeclMem( + { ...field.decl, init: field.decl.init }, + field.via, + ), + ); } else { // field/constant doesn't have initializer yield EAbstract("field", name, field.via); } } - if (init.kind === 'simple') { - const map: Map>>>> = new Map(); + if (init.kind === "simple") { + const map: Map< + string, + Ast.DeclMem>>> + > = new Map(); if (order.length !== 0) { yield EFieldsTwice(init.loc); } for (const [name, param] of init.fill.map) { order.push(name); - map.set(name, Ast.DeclMem( - Ast.InhFieldSig(param.type, param.init), - Ast.ViaMemberOrigin(typeName.text, param.loc), - )); + map.set( + name, + Ast.DeclMem( + Ast.InhFieldSig(param.type, param.init), + Ast.ViaMemberOrigin(typeName.text, param.loc), + ), + ); } return { order: init.fill.order, map }; } else { return { order, map }; } } -const EFieldsTwice = ( - loc: Ast.Loc, -): Ast.TcError => ({ +const EFieldsTwice = (loc: Ast.Loc): Ast.TcError => ({ loc, descr: [ Ast.TEText(`Cannot define other fields when using contract parameters`), @@ -341,4 +353,4 @@ const recover: Ast.ContractContent = { stringAny: undefined, }, }, -}; \ No newline at end of file +}; diff --git a/src/next/types/effects.ts b/src/next/types/effects.ts index 33089b2e04..82223b54b5 100644 --- a/src/next/types/effects.ts +++ b/src/next/types/effects.ts @@ -6,10 +6,15 @@ export const emptyEff: Ast.Effects = Object.freeze({ }); // when two branches merge -export const mergeEff = (left: Ast.Effects, right: Ast.Effects): Ast.Effects => { +export const mergeEff = ( + left: Ast.Effects, + right: Ast.Effects, +): Ast.Effects => { return Ast.Effects( left.returnOrThrow && right.returnOrThrow, - new Set([...left.setSelfPaths].filter(p => right.setSelfPaths.has(p))) + new Set( + [...left.setSelfPaths].filter((p) => right.setSelfPaths.has(p)), + ), ); }; @@ -26,7 +31,7 @@ export function* setHadAssign( break; } case "field_access": { - if (lvalue.aggregate.kind === 'self') { + if (lvalue.aggregate.kind === "self") { // self.x = ...; setSelfPaths.add(lvalue.field.text); } @@ -40,20 +45,18 @@ export function* setHadAssign( } const ENoSelfAssign = (loc: Ast.Loc): Ast.TcError => ({ loc, - descr: [ - Ast.TEText(`Cannot assign to self`), - ], + descr: [Ast.TEText(`Cannot assign to self`)], }); // on every return or throw export function* setHadExit( - eff: Ast.Effects, - successful: boolean, + eff: Ast.Effects, + successful: boolean, required: undefined | ReadonlySet, returnLoc: Ast.Loc, ): Ast.WithLog { if (successful && required) { - const missing = [...required].filter(p => !eff.setSelfPaths.has(p)); + const missing = [...required].filter((p) => !eff.setSelfPaths.has(p)); for (const fieldName of missing) { yield EMissingSelfInit(fieldName, returnLoc); } diff --git a/src/next/types/expression.ts b/src/next/types/expression.ts index 0fd2edf138..3ec3317757 100644 --- a/src/next/types/expression.ts +++ b/src/next/types/expression.ts @@ -1,19 +1,36 @@ /* eslint-disable require-yield */ import * as Ast from "@/next/ast"; import { throwInternal } from "@/error/errors"; -import { Bool, builtinBinary, builtinFunctions, getStaticBuiltin, StateInit } from "@/next/types/builtins"; -import { assignType, dealiasType, decodeDealiasTypeLazy, decodeTypeLazy, decodeTypeMap, checkFnCall, instantiateStruct, checkFnCallWithArgs, mgu, lookupMethod } from "@/next/types/type"; +import { + Bool, + builtinBinary, + builtinFunctions, + getStaticBuiltin, + StateInit, +} from "@/next/types/builtins"; +import { + assignType, + dealiasType, + decodeDealiasTypeLazy, + decodeTypeLazy, + decodeTypeMap, + checkFnCall, + instantiateStruct, + checkFnCallWithArgs, + mgu, + lookupMethod, +} from "@/next/types/type"; import { convertValueToExpr } from "@/next/types/value"; import { emptyTypeParams } from "@/next/types/type-params"; -type Decode = (node: T, ctx: Context) => Ast.WithLog +type Decode = (node: T, ctx: Context) => Ast.WithLog; type Context = { - readonly Lazy: Ast.ThunkBuilder, + readonly Lazy: Ast.ThunkBuilder; readonly scopeRef: () => Ast.Scope; readonly selfType: Ast.SelfType | undefined; readonly typeParams: Ast.TypeParams; readonly localScopeRef: ReadonlyMap; -} +}; export function decodeExpr( Lazy: Ast.ThunkBuilder, @@ -32,103 +49,163 @@ export function decodeExpr( }); } -export const decodeExprCtx: Decode = (node, ctx) => { +export const decodeExprCtx: Decode = ( + node, + ctx, +) => { switch (node.kind) { - case "null": return decodeNullCons(node, ctx); - case "unit": return decodeUnitCons(node, ctx); - case "string": return decodeStringCons(node, ctx); - case "number": return decodeNumberCons(node, ctx); - case "boolean": return decodeBooleanCons(node, ctx); - case "tuple": return decodeTupleCons(node, ctx); - case "tensor": return decodeTensorCons(node, ctx); - case "map_literal": return decodeMapCons(node, ctx); - case "set_literal": return decodeSetCons(node, ctx); - case "struct_instance": return decodeStructCons(node, ctx); - - case "var": return decodeVar(node, ctx); - case "op_binary": return decodeBinary(node, ctx); - case "op_unary": return decodeUnary(node, ctx); - case "conditional": return decodeTernary(node, ctx); - case "method_call": return decodeMethodCall(node, ctx); - case "static_call": return decodeFunctionCall(node, ctx); - case "static_method_call": return decodeStaticMethodCall(node, ctx); - case "field_access": return decodeFieldAccess(node, ctx); - case "init_of": return decodeInitOf(node, ctx); - case "code_of": return decodeCodeOf(node, ctx); + case "null": + return decodeNullCons(node, ctx); + case "unit": + return decodeUnitCons(node, ctx); + case "string": + return decodeStringCons(node, ctx); + case "number": + return decodeNumberCons(node, ctx); + case "boolean": + return decodeBooleanCons(node, ctx); + case "tuple": + return decodeTupleCons(node, ctx); + case "tensor": + return decodeTensorCons(node, ctx); + case "map_literal": + return decodeMapCons(node, ctx); + case "set_literal": + return decodeSetCons(node, ctx); + case "struct_instance": + return decodeStructCons(node, ctx); + + case "var": + return decodeVar(node, ctx); + case "op_binary": + return decodeBinary(node, ctx); + case "op_unary": + return decodeUnary(node, ctx); + case "conditional": + return decodeTernary(node, ctx); + case "method_call": + return decodeMethodCall(node, ctx); + case "static_call": + return decodeFunctionCall(node, ctx); + case "static_method_call": + return decodeStaticMethodCall(node, ctx); + case "field_access": + return decodeFieldAccess(node, ctx); + case "init_of": + return decodeInitOf(node, ctx); + case "code_of": + return decodeCodeOf(node, ctx); } -} +}; const decodeNullCons: Decode = function* (node) { return Ast.DNull(Ast.TypeNull(node.loc), node.loc); -} +}; const decodeUnitCons: Decode = function* (node) { return Ast.DUnit(Ast.TypeUnit(node.loc), node.loc); -} +}; const decodeStringCons: Decode = function* (node) { return Ast.DString(node.value, Ast.TypeString(node.loc), node.loc); -} +}; const decodeNumberCons: Decode = function* (node) { - return Ast.DNumber(node.base, node.value, Ast.TypeInt(Ast.IFInt('signed', 257, node.loc), node.loc), node.loc); -} + return Ast.DNumber( + node.base, + node.value, + Ast.TypeInt(Ast.IFInt("signed", 257, node.loc), node.loc), + node.loc, + ); +}; const decodeBooleanCons: Decode = function* (node) { return Ast.DBoolean(node.value, Ast.TypeBool(node.loc), node.loc); -} +}; const decodeTupleCons: Decode = function* (node, ctx) { - const children = yield* Ast.mapLog(node.children, child => decodeExprCtx(child, ctx)); - const args = children.map(child => child.computedType); + const children = yield* Ast.mapLog(node.children, (child) => + decodeExprCtx(child, ctx), + ); + const args = children.map((child) => child.computedType); return Ast.DTuple(children, Ast.DTypeTuple(args, node.loc), node.loc); -} +}; -const decodeTensorCons: Decode = function* (node, ctx) { - const children = yield* Ast.mapLog(node.children, child => decodeExprCtx(child, ctx)); - const args = children.map(child => child.computedType); +const decodeTensorCons: Decode = function* ( + node, + ctx, +) { + const children = yield* Ast.mapLog(node.children, (child) => + decodeExprCtx(child, ctx), + ); + const args = children.map((child) => child.computedType); return Ast.DTensor(children, Ast.DTypeTensor(args, node.loc), node.loc); -} +}; -const decodeMapCons: Decode = function* (node, ctx) { - const ascribed = yield* decodeTypeMap(ctx.typeParams, node.type, ctx.scopeRef); +const decodeMapCons: Decode = function* ( + node, + ctx, +) { + const ascribed = yield* decodeTypeMap( + ctx.typeParams, + node.type, + ctx.scopeRef, + ); const fields = yield* Ast.mapLog(node.fields, function* (field) { const key = yield* decodeExprCtx(field.key, ctx); - yield* assignType(field.key.loc, emptyTypeParams, ascribed.key, key.computedType, false); + yield* assignType( + field.key.loc, + emptyTypeParams, + ascribed.key, + key.computedType, + false, + ); const value = yield* decodeExprCtx(field.value, ctx); - yield* assignType(field.value.loc, emptyTypeParams, ascribed.value, value.computedType, false); + yield* assignType( + field.value.loc, + emptyTypeParams, + ascribed.value, + value.computedType, + false, + ); return Ast.DMapField(key, value); }); return Ast.DMapLiteral(ascribed, fields, node.loc); -} +}; const decodeSetCons: Decode = function* () { return throwInternal("Set literals must have been declined before"); -} +}; -const decodeStructCons: Decode = function* (node, ctx) { - const typeArgs = yield* Ast.mapLog(node.typeArgs, function* (arg) { - return yield* decodeTypeLazy(ctx.Lazy, ctx.typeParams, arg, ctx.scopeRef)(); - }); - const instance = yield* instantiateStruct( - node.type, - typeArgs, - ctx.typeParams, - ctx.scopeRef, - ); - // see checkFields in statement.ts - const fields = yield* checkFields( - instance?.fields, - node.args, - node.loc, - ctx, - ); - return Ast.DStructInstance( - fields, - instance?.type ?? Ast.DTypeRecover(), - node.loc - ); -} +const decodeStructCons: Decode = + function* (node, ctx) { + const typeArgs = yield* Ast.mapLog(node.typeArgs, function* (arg) { + return yield* decodeTypeLazy( + ctx.Lazy, + ctx.typeParams, + arg, + ctx.scopeRef, + )(); + }); + const instance = yield* instantiateStruct( + node.type, + typeArgs, + ctx.typeParams, + ctx.scopeRef, + ); + // see checkFields in statement.ts + const fields = yield* checkFields( + instance?.fields, + node.args, + node.loc, + ctx, + ); + return Ast.DStructInstance( + fields, + instance?.type ?? Ast.DTypeRecover(), + node.loc, + ); + }; function* checkFields( typeFields: Ast.Ordered | undefined, args: readonly Ast.StructFieldInitializer[], @@ -165,11 +242,14 @@ function* checkFields( } if (typeFields) { - const result: Map> = new Map(); + const result: Map< + string, + Ast.Recover + > = new Map(); for (const fieldName of typeFields.order) { const field = typeFields.map.get(fieldName); if (!field) { - return throwInternal("Ordered<>: lost fields") + return throwInternal("Ordered<>: lost fields"); } const fieldInst = map.get(fieldName); if (fieldInst) { @@ -187,9 +267,9 @@ function* checkFields( result.set(fieldName, undefined); } } - return Ast.Ordered(typeFields.order, result) + return Ast.Ordered(typeFields.order, result); } else { - return Ast.Ordered([...map.keys()], map) + return Ast.Ordered([...map.keys()], map); } } const EMissingField = (name: string, prev: Ast.Loc): Ast.TcError => ({ @@ -201,12 +281,13 @@ const EMissingField = (name: string, prev: Ast.Loc): Ast.TcError => ({ }); const ENoSuchField = (name: string, next: Ast.Loc): Ast.TcError => ({ loc: next, - descr: [ - Ast.TEText(`There is no field "${name}"`), - Ast.TECode(next), - ], + descr: [Ast.TEText(`There is no field "${name}"`), Ast.TECode(next)], }); -const EDuplicateField = (name: string, prev: Ast.Loc, next: Ast.Loc): Ast.TcError => ({ +const EDuplicateField = ( + name: string, + prev: Ast.Loc, + next: Ast.Loc, +): Ast.TcError => ({ loc: prev, descr: [ Ast.TEText(`Duplicate field "${name}"`), @@ -218,7 +299,7 @@ const EDuplicateField = (name: string, prev: Ast.Loc, next: Ast.Loc): Ast.TcErro }); const decodeVar: Decode = function* (node, ctx) { - if (node.name !== 'self') { + if (node.name !== "self") { const type = yield* lookupVar(node.name, node.loc, ctx); return Ast.DVar(node.name, type, node.loc); } @@ -230,9 +311,7 @@ const decodeVar: Decode = function* (node, ctx) { }; const ENoSelf = (loc: Ast.Loc): Ast.TcError => ({ loc, - descr: [ - Ast.TEText(`"self" is not allowed here`), - ], + descr: [Ast.TEText(`"self" is not allowed here`)], }); function* lookupVar( name: string, @@ -253,42 +332,46 @@ function* lookupVar( } const EUndefined = (name: string, loc: Ast.Loc): Ast.TcError => ({ loc, - descr: [ - Ast.TEText(`Variable "${name}" not defined`), - ], + descr: [Ast.TEText(`Variable "${name}" not defined`)], }); -const decodeBinary: Decode = function* (node, ctx) { +const decodeBinary: Decode = function* ( + node, + ctx, +) { const left = yield* decodeExprCtx(node.left, ctx); const right = yield* decodeExprCtx(node.right, ctx); const fnType = builtinBinary.get(node.op); if (!fnType) { return throwInternal("Builtin operator is not in the map"); } - const { returnType, typeArgMap } = yield* checkFnCall( - node.loc, - fnType, - [ - [left.loc, left.computedType], - [right.loc, right.computedType] - ], - ); - if (node.op === '==' || node.op === '!=') { + const { returnType, typeArgMap } = yield* checkFnCall(node.loc, fnType, [ + [left.loc, left.computedType], + [right.loc, right.computedType], + ]); + if (node.op === "==" || node.op === "!=") { const typeArg = typeArgMap.get("T"); if (!typeArg) { - return throwInternal("getCallResult produced incorrect substitution"); + return throwInternal( + "getCallResult produced incorrect substitution", + ); } - if (typeArg.kind !== 'recover' && !supportsEquality(typeArg)) { + if (typeArg.kind !== "recover" && !supportsEquality(typeArg)) { yield ENoEquality(node.loc); } } - return Ast.DOpBinary(node.op, left, right, typeArgMap, returnType, node.loc); -} + return Ast.DOpBinary( + node.op, + left, + right, + typeArgMap, + returnType, + node.loc, + ); +}; const ENoEquality = (loc: Ast.Loc): Ast.TcError => ({ loc, - descr: [ - Ast.TEText(`Equality on this type is not supported`), - ], + descr: [Ast.TEText(`Equality on this type is not supported`)], }); const supportsEquality = (common: Ast.DecodedType): boolean => { switch (common.kind) { @@ -328,50 +411,84 @@ const decodeUnary: Decode = function* (node, ctx) { if (!fnType) { return throwInternal("Builtin operator is not in the map"); } - const { returnType, typeArgMap } = yield* checkFnCall( - node.loc, - fnType, - [[operand.loc, operand.computedType]], - ); - + const { returnType, typeArgMap } = yield* checkFnCall(node.loc, fnType, [ + [operand.loc, operand.computedType], + ]); + return Ast.DOpUnary(node.op, operand, typeArgMap, returnType, node.loc); -} +}; -const decodeTernary: Decode = function* (node, ctx) { +const decodeTernary: Decode = function* ( + node, + ctx, +) { const condition = yield* decodeExprCtx(node.condition, ctx); - yield* assignType(condition.loc, emptyTypeParams, Bool, condition.computedType, false); + yield* assignType( + condition.loc, + emptyTypeParams, + Bool, + condition.computedType, + false, + ); const thenBranch = yield* decodeExprCtx(node.thenBranch, ctx); const elseBranch = yield* decodeExprCtx(node.elseBranch, ctx); - const commonType = yield* mgu(thenBranch.computedType, elseBranch.computedType, node.loc); - return Ast.DConditional(condition, thenBranch, elseBranch, commonType, node.loc); -} + const commonType = yield* mgu( + thenBranch.computedType, + elseBranch.computedType, + node.loc, + ); + return Ast.DConditional( + condition, + thenBranch, + elseBranch, + commonType, + node.loc, + ); +}; -const decodeMethodCall: Decode = function* (node, ctx) { +const decodeMethodCall: Decode = function* ( + node, + ctx, +) { const self = yield* decodeExprCtx(node.self, ctx); - const args = yield* Ast.mapLog(node.args, arg => decodeExprCtx(arg, ctx)); + const args = yield* Ast.mapLog(node.args, (arg) => decodeExprCtx(arg, ctx)); const { typeDecls, extensions } = ctx.scopeRef(); const { returnType, typeArgMap } = yield* lookupMethod( ctx.Lazy, self.computedType, node.method, - args.map(child => [child.loc, child.computedType]), + args.map((child) => [child.loc, child.computedType]), typeDecls, extensions, ); - return Ast.DMethodCall(self, node.method, args, typeArgMap, returnType, node.loc); -} + return Ast.DMethodCall( + self, + node.method, + args, + typeArgMap, + returnType, + node.loc, + ); +}; -const decodeFunctionCall: Decode = function* (node, ctx) { +const decodeFunctionCall: Decode< + Ast.StaticCall, + Ast.DStaticCall | Ast.DThrowCall | Ast.DNumber +> = function* (node, ctx) { const name = node.function; - const args = yield* Ast.mapLog(node.args, arg => decodeExprCtx(arg, ctx)); + const args = yield* Ast.mapLog(node.args, (arg) => decodeExprCtx(arg, ctx)); - if (name.text === 'sha256') { + if (name.text === "sha256") { const [arg] = args; - const int = Ast.TypeInt(Ast.IFInt('signed', 257, node.loc), node.loc); + const int = Ast.TypeInt(Ast.IFInt("signed", 257, node.loc), node.loc); // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition - if (args.length !== 1 || arg?.computedType.kind !== 'TySlice' && arg?.computedType.kind !== 'TypeString') { + if ( + args.length !== 1 || + (arg?.computedType.kind !== "TySlice" && + arg?.computedType.kind !== "TypeString") + ) { yield EMismatchSha256(node.loc); return Ast.DNumber("10", 0n, int, node.loc); } else { @@ -390,35 +507,38 @@ const decodeFunctionCall: Decode [child.loc, child.computedType]), + args.map((child) => [child.loc, child.computedType]), ); - if (name.text === 'throw' || name.text === 'nativeThrow') { + if (name.text === "throw" || name.text === "nativeThrow") { return Ast.DThrowCall(name, args, returnType, node.loc); } else { return Ast.DStaticCall(name, typeArgMap, args, returnType, node.loc); } -} +}; const EMismatchSha256 = (loc: Ast.Loc): Ast.TcError => ({ loc, - descr: [ - Ast.TEText(`sha256() takes either Slice or String`), - ], + descr: [Ast.TEText(`sha256() takes either Slice or String`)], }); -const decodeStaticMethodCall: Decode = function* (node, ctx) { +const decodeStaticMethodCall: Decode< + Ast.StaticMethodCall, + Ast.DStaticMethodCall | Ast.DNull +> = function* (node, ctx) { if (node.typeArgs.length > 0) { yield EFunctionArity(node.loc); } - const args = yield* Ast.mapLog(node.args, arg => decodeExprCtx(arg, ctx)); + const args = yield* Ast.mapLog(node.args, (arg) => decodeExprCtx(arg, ctx)); const selfDecl = ctx.scopeRef().typeDecls.get(node.self.text); - if (selfDecl?.decl.kind === 'struct' || selfDecl?.decl.kind === 'message') { - const builtins = getStaticBuiltin(Ast.DTypeRef(node.self, selfDecl.decl, [], node.loc)); + if (selfDecl?.decl.kind === "struct" || selfDecl?.decl.kind === "message") { + const builtins = getStaticBuiltin( + Ast.DTypeRef(node.self, selfDecl.decl, [], node.loc), + ); const builtin = builtins.get(node.function.text); if (!builtin) { yield EUndefinedStatic(node.function.text, node.loc); @@ -429,33 +549,39 @@ const decodeStaticMethodCall: Decode [child.loc, child.computedType]), + args.map((child) => [child.loc, child.computedType]), + ); + return Ast.DStaticMethodCall( + node.self, + typeArgMap, + node.function, + args, + returnType, + node.loc, ); - return Ast.DStaticMethodCall(node.self, typeArgMap, node.function, args, returnType, node.loc); } else { yield EUndefinedStatic(node.function.text, node.loc); return Ast.DNull(Ast.TypeNull(node.loc), node.loc); } -} +}; const EUndefinedStatic = (name: string, loc: Ast.Loc): Ast.TcError => ({ loc, - descr: [ - Ast.TEText(`Static method ${name} doesn't exist`), - ], + descr: [Ast.TEText(`Static method ${name} doesn't exist`)], }); const EFunctionArity = (loc: Ast.Loc): Ast.TcError => ({ loc, - descr: [ - Ast.TEText(`Function doesn't take any generic arguments`), - ], + descr: [Ast.TEText(`Function doesn't take any generic arguments`)], }); -const decodeFieldAccess: Decode = function* (node, ctx) { +const decodeFieldAccess: Decode = function* ( + node, + ctx, +) { const expr = yield* decodeExprCtx(node.aggregate, ctx); const selfType = expr.computedType; const returnType = yield* lookupField(selfType, node.field, ctx.scopeRef); return Ast.DFieldAccess(expr, node.field, returnType, node.loc); -} +}; function* lookupField( selfType: Ast.DecodedType, @@ -495,7 +621,7 @@ function* lookupField( } case "TypeMaybe": { const type = yield* lookupField(selfType.type, fieldName, scopeRef); - if (type.kind === 'recover') { + if (type.kind === "recover") { return type; } else { return Ast.DTypeMaybe(type, fieldName.loc); @@ -503,7 +629,7 @@ function* lookupField( } case "TypeBounced": { const decl = scopeRef().typeDecls.get(selfType.name.text); - if (!decl || decl.decl.kind !== 'message') { + if (!decl || decl.decl.kind !== "message") { yield ENoSuchField(fieldName.text, fieldName.loc); return Ast.DTypeRecover(); } @@ -542,9 +668,9 @@ function* lookupField( } const decodeInitOf: Decode = function* (node, ctx) { - const args = yield* Ast.mapLog(node.args, arg => decodeExprCtx(arg, ctx)); + const args = yield* Ast.mapLog(node.args, (arg) => decodeExprCtx(arg, ctx)); const contract = ctx.scopeRef().typeDecls.get(node.contract.text); - if (contract?.decl.kind !== 'contract') { + if (contract?.decl.kind !== "contract") { yield ENotContract(node.contract.text, node.loc); return Ast.DInitOf(node.contract, args, StateInit, node.loc); } @@ -553,20 +679,22 @@ const decodeInitOf: Decode = function* (node, ctx) { ctx.Lazy, node.loc, Ast.DecodedFnType( - emptyTypeParams, + emptyTypeParams, params, ctx.Lazy({ - callback: function*() { return StateInit; }, + callback: function* () { + return StateInit; + }, context: [Ast.TEText("checking initOf expression")], loc: node.loc, recover: StateInit, - }) + }), ), [], - args.map(child => [child.loc, child.computedType]), + args.map((child) => [child.loc, child.computedType]), ); return Ast.DInitOf(node.contract, args, StateInit, node.loc); -} +}; function* initParams(init: Ast.InitSig) { switch (init.kind) { case "function": { @@ -597,14 +725,16 @@ function* initParams(init: Ast.InitSig) { const decodeCodeOf: Decode = function* (node, ctx) { const contract = ctx.scopeRef().typeDecls.get(node.contract.text); - if (contract?.decl.kind !== 'contract') { + if (contract?.decl.kind !== "contract") { yield ENotContract(node.contract.text, node.loc); } - return Ast.DCodeOf(node.contract, Ast.TypeCell(Ast.SFDefault(node.loc), node.loc), node.loc); -} + return Ast.DCodeOf( + node.contract, + Ast.TypeCell(Ast.SFDefault(node.loc), node.loc), + node.loc, + ); +}; const ENotContract = (name: string, loc: Ast.Loc): Ast.TcError => ({ loc, - descr: [ - Ast.TEText(`"${name}" is not a contract`), - ], + descr: [Ast.TEText(`"${name}" is not a contract`)], }); diff --git a/src/next/types/extensions.ts b/src/next/types/extensions.ts index 9020ce45c0..c88d90026b 100644 --- a/src/next/types/extensions.ts +++ b/src/next/types/extensions.ts @@ -13,25 +13,30 @@ export function decodeExtensions( source: TactSource, scopeRef: () => Ast.Scope, ): ReadonlyMap[]>> { - const allExts: Map[]>[]> = new Map(); + const allExts: Map[]>[]> = + new Map(); // imported for (const { globals, importedBy } of imported) { for (const [name, lazyExts] of globals.extensions) { const map = allExts.get(name) ?? []; allExts.set(name, map); - map.push(Lazy({ - callback: function* () { - const exts = yield* lazyExts(); - return exts.map(ext => Ast.Decl( - ext.decl, - Ast.ViaImport(importedBy, ext.via), - )); - }, - context: [Ast.TEText(`importing extension method ${name}`)], - loc: Ast.Builtin(), - recover: [], - })); + map.push( + Lazy({ + callback: function* () { + const exts = yield* lazyExts(); + return exts.map((ext) => + Ast.Decl( + ext.decl, + Ast.ViaImport(importedBy, ext.via), + ), + ); + }, + context: [Ast.TEText(`importing extension method ${name}`)], + loc: Ast.Builtin(), + recover: [], + }), + ); } } @@ -40,56 +45,68 @@ export function decodeExtensions( const name = ext.fun.name.text; const map = allExts.get(name) ?? []; allExts.set(name, map); - map.push(Lazy({ - callback: function* (Lazy) { - const decoded = yield* decodeExt(Lazy, ext, scopeRef); - if (!decoded) { - return []; - } - return [Ast.Decl( - decoded, - Ast.ViaOrigin(ext.fun.loc, source), - )]; - }, - context: [ - Ast.TEText(`defining extension method ${ext.fun.name.text}`) - ], - loc: ext.fun.loc, - recover: [], - })); + map.push( + Lazy({ + callback: function* (Lazy) { + const decoded = yield* decodeExt(Lazy, ext, scopeRef); + if (!decoded) { + return []; + } + return [ + Ast.Decl(decoded, Ast.ViaOrigin(ext.fun.loc, source)), + ]; + }, + context: [ + Ast.TEText( + `defining extension method ${ext.fun.name.text}`, + ), + ], + loc: ext.fun.loc, + recover: [], + }), + ); } const result: Map[]>> = new Map(); for (const [name, exts] of allExts) { // checking method overlap is only possible when all the types // can be resolved - result.set(name, Lazy({ - callback: function* () { - // force all thunks - const all: Ast.Decl[] = []; - for (const lazyExt of exts) { - const exts = yield* lazyExt(); - all.push(...exts); - } - - // check overlap and deduplicate - const prevs: Ast.Decl[] = []; - for (const ext of all) { - const builtin = builtinMethods.get(name); - if (builtin && !isCompatible(builtin, ext.decl.type)) { - yield EMethodOverlap(name, Ast.ViaBuiltin(), ext.via); - continue; + result.set( + name, + Lazy({ + callback: function* () { + // force all thunks + const all: Ast.Decl[] = []; + for (const lazyExt of exts) { + const exts = yield* lazyExt(); + all.push(...exts); } - if (yield* areCompatible(name, prevs, ext)) { - prevs.push(ext); + + // check overlap and deduplicate + const prevs: Ast.Decl[] = []; + for (const ext of all) { + const builtin = builtinMethods.get(name); + if (builtin && !isCompatible(builtin, ext.decl.type)) { + yield EMethodOverlap( + name, + Ast.ViaBuiltin(), + ext.via, + ); + continue; + } + if (yield* areCompatible(name, prevs, ext)) { + prevs.push(ext); + } } - } - return prevs; - }, - context: [Ast.TEText(`merging extensions methods with name ${name}`)], - loc: Ast.Builtin(), - recover: [], - })); + return prevs; + }, + context: [ + Ast.TEText(`merging extensions methods with name ${name}`), + ], + loc: Ast.Builtin(), + recover: [], + }), + ); } return result; @@ -102,7 +119,7 @@ function* decodeExt( ) { const { selfType, mutates, fun } = node; const { type, body, inline, loc } = fun; - + const decodedFn = yield* decodeFnType(Lazy, type, scopeRef); const lazySelf = decodeDealiasTypeLazy( @@ -116,7 +133,7 @@ function* decodeExt( if (!self) { return undefined; } - + const methodType = Ast.DecodedMethodType( mutates, decodedFn.typeParams, @@ -171,15 +188,17 @@ function isCompatible( ) { const prevSelf = prev.self; const nextSelf = next.self; - return prevSelf.kind !== nextSelf.kind || - prevSelf.ground === 'yes' && - nextSelf.ground === 'yes' && - !areEqual(prevSelf, nextSelf); + return ( + prevSelf.kind !== nextSelf.kind || + (prevSelf.ground === "yes" && + nextSelf.ground === "yes" && + !areEqual(prevSelf, nextSelf)) + ); } function areEqual( prevSelf: Ast.MethodGroundType, - nextSelf: Ast.MethodGroundType + nextSelf: Ast.MethodGroundType, ): boolean { switch (prevSelf.kind) { case "TyInt": @@ -197,25 +216,33 @@ function areEqual( return prevSelf.kind === nextSelf.kind; } case "type_ref": { - return prevSelf.kind === nextSelf.kind && + return ( + prevSelf.kind === nextSelf.kind && prevSelf.name.text === nextSelf.name.text && - allEqual(prevSelf.typeArgs, nextSelf.typeArgs); + allEqual(prevSelf.typeArgs, nextSelf.typeArgs) + ); } case "map_type": { - return prevSelf.kind === nextSelf.kind && + return ( + prevSelf.kind === nextSelf.kind && allEqual( [prevSelf.key, prevSelf.value], [nextSelf.key, nextSelf.value], - ); + ) + ); } case "TypeMaybe": { - return prevSelf.kind === nextSelf.kind && - areEqual(prevSelf.type, prevSelf.type); + return ( + prevSelf.kind === nextSelf.kind && + areEqual(prevSelf.type, prevSelf.type) + ); } case "tuple_type": case "tensor_type": { - return prevSelf.kind === nextSelf.kind && - allEqual(prevSelf.typeArgs, nextSelf.typeArgs); + return ( + prevSelf.kind === nextSelf.kind && + allEqual(prevSelf.typeArgs, nextSelf.typeArgs) + ); } } } @@ -238,11 +265,11 @@ function* decodeSelfType( case "type_ref": { const def = scopeRef().typeDecls.get(type.name.text); if (!def) { - return throwInternal("Decoder returned broken reference") + return throwInternal("Decoder returned broken reference"); } switch (def.decl.kind) { case "alias": { - return throwInternal("Decoder returned broken reference") + return throwInternal("Decoder returned broken reference"); } case "contract": case "trait": { @@ -252,11 +279,13 @@ function* decodeSelfType( case "struct": case "message": case "union": { - const allVars = type.typeArgs.filter(arg => { - return arg.kind === 'TypeParam'; + const allVars = type.typeArgs.filter((arg) => { + return arg.kind === "TypeParam"; }); if (type.typeArgs.length === allVars.length) { - const argNames = new Set(allVars.map(v => v.name.text)); + const argNames = new Set( + allVars.map((v) => v.name.text), + ); if (argNames.size !== allVars.length) { // type variables are not distinct yield EBadMethodType(type.loc); @@ -267,7 +296,7 @@ function* decodeSelfType( def.decl, allVars, type.loc, - ); + ); } if (type.typeArgs.length > 0 && allVars.length > 0) { // has vars, but it's not all the parameters @@ -283,12 +312,7 @@ function* decodeSelfType( } ground.push(result); } - return Ast.MGTypeRef( - type.name, - def.decl, - ground, - type.loc, - ); + return Ast.MGTypeRef(type.name, def.decl, ground, type.loc); } } // somehow typescript wants this @@ -302,12 +326,11 @@ function* decodeSelfType( return undefined; } case "map_type": { - if (type.key.kind === 'TypeParam' && type.value.kind === 'TypeParam') { - return Ast.MVTypeMap( - type.key, - type.value, - type.loc, - ); + if ( + type.key.kind === "TypeParam" && + type.value.kind === "TypeParam" + ) { + return Ast.MVTypeMap(type.key, type.value, type.loc); } const ground = yield* toGroundType(type, scopeRef); if (!ground) { @@ -321,11 +344,8 @@ function* decodeSelfType( return undefined; } case "TypeMaybe": { - if (type.type.kind === 'TypeParam') { - return Ast.MVTypeMaybe( - type.type, - type.loc, - ); + if (type.type.kind === "TypeParam") { + return Ast.MVTypeMaybe(type.type, type.loc); } const ground = yield* toGroundType(type, scopeRef); if (!ground) { @@ -334,25 +354,21 @@ function* decodeSelfType( } return ground; } - case "tensor_type": + case "tensor_type": case "tuple_type": { - const mvCons = type.kind === 'tuple_type' - ? Ast.MVTypeTuple - : Ast.MVTypeTensor; - const allVars = type.typeArgs.filter(arg => { - return arg.kind === 'TypeParam'; + const mvCons = + type.kind === "tuple_type" ? Ast.MVTypeTuple : Ast.MVTypeTensor; + const allVars = type.typeArgs.filter((arg) => { + return arg.kind === "TypeParam"; }); if (type.typeArgs.length === allVars.length) { - const argNames = new Set(allVars.map(v => v.name.text)); + const argNames = new Set(allVars.map((v) => v.name.text)); if (argNames.size !== allVars.length) { // type variables are not distinct yield EBadMethodType(type.loc); return undefined; } - return mvCons( - allVars, - type.loc, - ); + return mvCons(allVars, type.loc); } const ground = yield* toGroundType(type, scopeRef); if (!ground) { @@ -392,7 +408,7 @@ function* toGroundType( case "type_ref": { const typeDecl = scopeRef().typeDecls.get(type.name.text); if (!typeDecl) { - return throwInternal("Decoder returned broken reference") + return throwInternal("Decoder returned broken reference"); } switch (typeDecl.decl.kind) { case "contract": @@ -401,7 +417,7 @@ function* toGroundType( return undefined; } case "alias": { - return throwInternal("Decoder returned broken reference") + return throwInternal("Decoder returned broken reference"); } case "struct": case "message": @@ -444,17 +460,23 @@ function* toGroundType( return child && Ast.MGTypeMaybe(child, type.loc); } case "tuple_type": { - const children = yield* Ast.mapLog(type.typeArgs, function* (child) { - const result = yield* toGroundType(child, scopeRef); - return result ? [result] : []; - }); + const children = yield* Ast.mapLog( + type.typeArgs, + function* (child) { + const result = yield* toGroundType(child, scopeRef); + return result ? [result] : []; + }, + ); return Ast.MGTypeTuple(children.flat(), type.loc); } case "tensor_type": { - const children = yield* Ast.mapLog(type.typeArgs, function* (child) { - const result = yield* toGroundType(child, scopeRef); - return result ? [result] : []; - }); + const children = yield* Ast.mapLog( + type.typeArgs, + function* (child) { + const result = yield* toGroundType(child, scopeRef); + return result ? [result] : []; + }, + ); return Ast.MGTypeTensor(children.flat(), type.loc); } case "TyInt": @@ -477,20 +499,15 @@ function* toGroundType( } } -const EBadMethodType = ( - loc: Ast.Loc, -): Ast.TcError => ({ +const EBadMethodType = (loc: Ast.Loc): Ast.TcError => ({ loc, descr: [ - Ast.TEText(`Type of self must either have no type parameters, or be a generic type with distinct type parameters`), + Ast.TEText( + `Type of self must either have no type parameters, or be a generic type with distinct type parameters`, + ), ], }); -const ENoMethods = ( - kind: string, - loc: Ast.Loc, -): Ast.TcError => ({ +const ENoMethods = (kind: string, loc: Ast.Loc): Ast.TcError => ({ loc, - descr: [ - Ast.TEText(`Cannot define methods on ${kind}`), - ], -}); \ No newline at end of file + descr: [Ast.TEText(`Cannot define methods on ${kind}`)], +}); diff --git a/src/next/types/fields.ts b/src/next/types/fields.ts index db88cac1ed..908eb33cc1 100644 --- a/src/next/types/fields.ts +++ b/src/next/types/fields.ts @@ -8,7 +8,7 @@ import { decodeConstantDef } from "@/next/types/constant-def"; import { emptyTypeParams } from "@/next/types/type-params"; import { decodeInitializerLazy } from "@/next/types/struct-fields"; -type MaybeExpr = Ast.Thunk | undefined +type MaybeExpr = Ast.Thunk | undefined; export function* getFieldishGeneral( Lazy: Ast.ThunkBuilder, @@ -20,18 +20,20 @@ export function* getFieldishGeneral( scopeRef: () => Ast.Scope, ): Ast.WithLog>>> { // collect all inherited fields and constants - const inherited: Map>> = new Map(); - for (const { via, decl: { fieldish } } of traits) { + const inherited: Map< + string, + Ast.DeclMem> + > = new Map(); + for (const { + via, + decl: { fieldish }, + } of traits) { for (const name of fieldish.order) { const field = fieldish.map.get(name); if (!field) { return throwInternal("Field was lost"); } - const nextVia = Ast.ViaMemberTrait( - name, - via.defLoc, - field.via, - ); + const nextVia = Ast.ViaMemberTrait(name, via.defLoc, field.via); const prev = inherited.get(name); if (prev) { yield Ast.ERedefineMember(name, prev.via, nextVia); @@ -41,12 +43,7 @@ export function* getFieldishGeneral( } } - const selfType = Ast.MVTypeRef( - typeName, - traitSigRef, - [], - typeName.loc, - ) + const selfType = Ast.MVTypeRef(typeName, traitSigRef, [], typeName.loc); // in which order fields were defined const order: string[] = []; @@ -71,13 +68,10 @@ export function* getFieldishGeneral( order.push(name.text); // decode field - all.set(name.text, decodeField( - Lazy, - typeName.text, - field, - scopeRef, - selfType, - )); + all.set( + name.text, + decodeField(Lazy, typeName.text, field, scopeRef, selfType), + ); // check if this field was inherited const prevInh = inherited.get(name.text); @@ -85,7 +79,7 @@ export function* getFieldishGeneral( // remember that this inherited field was handled overridden.add(name.text); - if (prevInh.decl.kind !== 'field') { + if (prevInh.decl.kind !== "field") { // cannot override constant with field yield Ast.ERedefineMember(name.text, prevInh.via, nextVia); } @@ -124,7 +118,7 @@ export function* getFieldishGeneral( scopeRef, selfType, ); - + // check that override/abstract/virtual modifiers are correct yield* checkFieldOverride( name.text, @@ -143,7 +137,7 @@ export function* getFieldishGeneral( if (overridden.has(name)) { continue; } - if (field.decl.kind === 'field') { + if (field.decl.kind === "field") { // fields must always be redefined yield EMustCopyField(name, field.via); } else { @@ -181,19 +175,15 @@ function decodeField( ); // decode field - return Ast.DeclMem( - Ast.InhFieldSig(decoded, init), - nextVia, - ); + return Ast.DeclMem(Ast.InhFieldSig(decoded, init), nextVia); } -const EMustCopyField = ( - name: string, - prev: Ast.ViaMember, -): Ast.TcError => ({ +const EMustCopyField = (name: string, prev: Ast.ViaMember): Ast.TcError => ({ loc: prev.defLoc, descr: [ - Ast.TEText(`Field "${name}" was defined in parent trait, but never mentioned`), + Ast.TEText( + `Field "${name}" was defined in parent trait, but never mentioned`, + ), Ast.TEViaMember(prev), ], }); @@ -206,7 +196,7 @@ function* decodeConstant( scopeRef: () => Ast.Scope, selfType: Ast.SelfType, ): Ast.WithLog>> { - if (init.kind === 'constant_decl') { + if (init.kind === "constant_decl") { const type = decodeTypeLazy(Lazy, emptyTypeParams, init.type, scopeRef); return Ast.DeclMem( Ast.FieldConstSig(overridable, type, undefined), @@ -221,9 +211,6 @@ function* decodeConstant( scopeRef, selfType, ); - return Ast.DeclMem( - Ast.FieldConstSig(overridable, type, expr), - nextVia, - ); + return Ast.DeclMem(Ast.FieldConstSig(overridable, type, expr), nextVia); } } diff --git a/src/next/types/functions.ts b/src/next/types/functions.ts index 5ecf0347aa..340ad80327 100644 --- a/src/next/types/functions.ts +++ b/src/next/types/functions.ts @@ -16,23 +16,25 @@ export function* decodeFunctions( ): Ast.WithLog>> { const allFnSigs = [ // imported - ...imported.flatMap(({ globals, importedBy }) => ( - [...globals.functions] - .map(([name, fn]) => [ - name, - Ast.Decl(fn.decl, Ast.ViaImport(importedBy, fn.via)), - ] as const) - )), + ...imported.flatMap(({ globals, importedBy }) => + [...globals.functions].map( + ([name, fn]) => + [ + name, + Ast.Decl(fn.decl, Ast.ViaImport(importedBy, fn.via)), + ] as const, + ), + ), // local - ...yield* Ast.mapLog(source.items.functions, function* (fn) { + ...(yield* Ast.mapLog(source.items.functions, function* (fn) { return [ - fn.name.text, + fn.name.text, Ast.Decl( yield* decodeFunction(Lazy, fn, scopeRef), - Ast.ViaOrigin(fn.loc, source) - ) + Ast.ViaOrigin(fn.loc, source), + ), ] as const; - }), + })), ]; // remove duplicates and builtins diff --git a/src/next/types/lvalue.ts b/src/next/types/lvalue.ts index 136b72099d..8c65dbb857 100644 --- a/src/next/types/lvalue.ts +++ b/src/next/types/lvalue.ts @@ -1,16 +1,21 @@ /* eslint-disable require-yield */ import * as Ast from "@/next/ast"; -export function* convertExprToLValue(node: Ast.DecodedExpression): Ast.WithLog { +export function* convertExprToLValue( + node: Ast.DecodedExpression, +): Ast.WithLog { switch (node.kind) { case "field_access": { const aggregate = yield* convertExprToLValue(node.aggregate); // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition - return aggregate && Ast.LFieldAccess( - aggregate, - node.field, - node.computedType, - node.loc, + return ( + aggregate && + Ast.LFieldAccess( + aggregate, + node.field, + node.computedType, + node.loc, + ) ); } case "var": @@ -45,7 +50,9 @@ export function* convertExprToLValue(node: Ast.DecodedExpression): Ast.WithLog ({ loc: prev, descr: [ - Ast.TEText(`This expression cannot be used on the left side of assignment`), + Ast.TEText( + `This expression cannot be used on the left side of assignment`, + ), Ast.TECode(prev), ], -}); \ No newline at end of file +}); diff --git a/src/next/types/message.ts b/src/next/types/message.ts index 9d5b22089e..c169292293 100644 --- a/src/next/types/message.ts +++ b/src/next/types/message.ts @@ -17,8 +17,8 @@ export function* decodeMessage( ): Ast.WithLog { const fields = yield* decodeFields( Lazy, - message.fields, - emptyTypeParams, + message.fields, + emptyTypeParams, scopeRef, ); const lazyExpr = Lazy({ @@ -47,34 +47,22 @@ export function* decodeMessage( return Ast.MessageSig(lazyExpr, fields); } -const EZero = ( - next: Ast.Loc, -): Ast.TcError => ({ +const EZero = (next: Ast.Loc): Ast.TcError => ({ loc: next, - descr: [ - Ast.TEText(`Zero opcode is reserved for text comments`), - ], + descr: [Ast.TEText(`Zero opcode is reserved for text comments`)], }); -const ENegative = ( - next: Ast.Loc, -): Ast.TcError => ({ +const ENegative = (next: Ast.Loc): Ast.TcError => ({ loc: next, - descr: [ - Ast.TEText(`Opcode must be positive`), - ], + descr: [Ast.TEText(`Opcode must be positive`)], }); -const ETooLarge = ( - next: Ast.Loc, -): Ast.TcError => ({ +const ETooLarge = (next: Ast.Loc): Ast.TcError => ({ loc: next, - descr: [ - Ast.TEText(`Opcode is too large`), - ], + descr: [Ast.TEText(`Opcode is too large`)], }); function* decodeOpcode( Lazy: Ast.ThunkBuilder, - typeParams: Ast.TypeParams, + typeParams: Ast.TypeParams, opcode: Ast.Expression | undefined, messageName: string, fieldsNames: readonly string[], @@ -90,13 +78,15 @@ function* decodeOpcode( new Map(), ); const computed = expr.computedType; - if (yield* assignType(opcode.loc, emptyTypeParams, Int, computed, false)) { + if ( + yield* assignType(opcode.loc, emptyTypeParams, Int, computed, false) + ) { const result = yield* evalExpr(expr, scopeRef); // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition - if (result.kind === 'number') { - return result.value + if (result.kind === "number") { + return result.value; } else { - return throwInternal("Const eval returned non-number for Int") + return throwInternal("Const eval returned non-number for Int"); } } } diff --git a/src/next/types/methods.ts b/src/next/types/methods.ts index 66d7a95fce..06a8a26bda 100644 --- a/src/next/types/methods.ts +++ b/src/next/types/methods.ts @@ -18,30 +18,34 @@ export function* getMethodsGeneral( traits: readonly Ast.Decl[], methods: readonly Ast.Method[], scopeRef: () => Ast.Scope, -): Ast.WithLog>>> { +): Ast.WithLog< + ReadonlyMap>> +> { // collect all inherited methods - const inherited: Map>> = new Map(); - for (const { via, decl: { methods } } of traits) { + const inherited: Map< + string, + Ast.DeclMem> + > = new Map(); + for (const { + via, + decl: { methods }, + } of traits) { for (const [name, method] of methods) { - const nextVia = Ast.ViaMemberTrait( - name, - via.defLoc, - method.via, - ); + const nextVia = Ast.ViaMemberTrait(name, via.defLoc, method.via); const prev = inherited.get(name); if (prev) { yield Ast.ERedefineMember(name, prev.via, nextVia); } else { - inherited.set(name, Ast.DeclMem( - method.decl, - nextVia, - )); + inherited.set(name, Ast.DeclMem(method.decl, nextVia)); } } } // collection of all defined methods - const all: Map>> = new Map(); + const all: Map< + string, + Ast.DeclMem> + > = new Map(); // whether inherited field/constant was defined locally const overridden: Set = new Set(); @@ -60,15 +64,10 @@ export function* getMethodsGeneral( decodedFn.params, decodedFn.returnType, ); - const decodedBody = body.kind !== 'abstract_body' - ? yield* decodeBody( - Lazy, - body, - methodType, - loc, - scopeRef, - ) - : undefined; + const decodedBody = + body.kind !== "abstract_body" + ? yield* decodeBody(Lazy, body, methodType, loc, scopeRef) + : undefined; const getMethodId = decodeGetLazy( Lazy, emptyTypeParams, @@ -118,14 +117,12 @@ export function* getMethodsGeneral( } const EGenericMethod = (loc: Ast.Loc): Ast.TcError => ({ loc, - descr: [ - Ast.TEText(`Method cannot be generic`), - ], + descr: [Ast.TEText(`Method cannot be generic`)], }); function decodeGetLazy( Lazy: Ast.ThunkBuilder, - typeParams: Ast.TypeParams, + typeParams: Ast.TypeParams, fnName: Ast.Id, get: Ast.GetAttribute | undefined, scopeRef: () => Ast.Scope, @@ -135,14 +132,8 @@ function decodeGetLazy( return undefined; } return Lazy({ - callback: (Lazy) => decodeGet( - Lazy, - typeParams, - fnName, - get, - scopeRef, - selfType, - ), + callback: (Lazy) => + decodeGet(Lazy, typeParams, fnName, get, scopeRef, selfType), context: [Ast.TEText("checking get() opcode")], loc: get.loc, recover: undefined, @@ -171,8 +162,8 @@ function* decodeGet( const methodId = yield* evalExpr(expr, scopeRef); if ( // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition - methodId.kind === 'number' && - (yield* checkMethodId(methodId.value, expr.loc)) + methodId.kind === "number" && + (yield* checkMethodId(methodId.value, expr.loc)) ) { return methodId.value; } @@ -213,19 +204,24 @@ function* checkMethodId(methodId: bigint, loc: Ast.Loc) { const EBadId = (loc: Ast.Loc): Ast.TcError => ({ loc, - descr: [ - Ast.TEText(`Method ids must fit 19-bit signed integer range`), - ], + descr: [Ast.TEText(`Method ids must fit 19-bit signed integer range`)], }); const EReservedTvmId = (loc: Ast.Loc): Ast.TcError => ({ loc, descr: [ - Ast.TEText(`Method ids cannot overlap with the TVM reserved ids: -4, -3, -2, -1, 0 ... 2^14 - 1`), + Ast.TEText( + `Method ids cannot overlap with the TVM reserved ids: -4, -3, -2, -1, 0 ... 2^14 - 1`, + ), ], }); -const EReservedTactId = (loc: Ast.Loc, tactMethodIds: readonly bigint[]): Ast.TcError => ({ +const EReservedTactId = ( + loc: Ast.Loc, + tactMethodIds: readonly bigint[], +): Ast.TcError => ({ loc, descr: [ - Ast.TEText(`Method ids cannot overlap with Tact reserved method ids: ${tactMethodIds.map((n) => n.toString()).join(", ")}`), + Ast.TEText( + `Method ids cannot overlap with Tact reserved method ids: ${tactMethodIds.map((n) => n.toString()).join(", ")}`, + ), ], -}); \ No newline at end of file +}); diff --git a/src/next/types/override.ts b/src/next/types/override.ts index 50d589cc60..c478d19c95 100644 --- a/src/next/types/override.ts +++ b/src/next/types/override.ts @@ -4,15 +4,17 @@ import { emptyTypeParams } from "@/next/types/type-params"; export function* checkFieldOverride( name: string, - prev: Ast.DeclMem> | undefined - >> | undefined, + prev: + | Ast.DeclMem< + Ast.Fieldish> | undefined> + > + | undefined, nextType: Ast.Thunk, nextVia: Ast.ViaMember, override: boolean, ): Ast.WithLog { if (prev) { - if (prev.decl.kind !== 'constant') { + if (prev.decl.kind !== "constant") { // cannot override field with constant yield Ast.ERedefineMember(name, prev.via, nextVia); } else if (override) { @@ -96,7 +98,9 @@ const ENeedAbstract = ( ): Ast.TcError => ({ loc: next.defLoc, descr: [ - Ast.TEText(`To override "${name}" it has to be "virtual" or "abstract"`), + Ast.TEText( + `To override "${name}" it has to be "virtual" or "abstract"`, + ), Ast.TEText(`First defined at`), Ast.TEViaMember(prev), Ast.TEText(`Redefined at`), @@ -104,13 +108,10 @@ const ENeedAbstract = ( ], }); -const EEmptyOverride = ( - name: string, - next: Ast.ViaMember, -): Ast.TcError => ({ +const EEmptyOverride = (name: string, next: Ast.ViaMember): Ast.TcError => ({ loc: next.defLoc, descr: [ Ast.TEText(`To override "${name}" it has to exist`), Ast.TEViaMember(next), ], -}); \ No newline at end of file +}); diff --git a/src/next/types/receivers.ts b/src/next/types/receivers.ts index 99e9bb7eee..5fba23b057 100644 --- a/src/next/types/receivers.ts +++ b/src/next/types/receivers.ts @@ -24,49 +24,58 @@ export function* getReceivers( impBounces.push(Ast.Decl(bounce, via)); } - const localInternals: Ast.DeclMem<[Ast.ReceiverSubKind, readonly Ast.Statement[]]>[] = []; - const localExternals: Ast.DeclMem<[Ast.ReceiverSubKind, readonly Ast.Statement[]]>[] = []; - const localBounces: Ast.DeclMem<[Ast.TypedParameter, readonly Ast.Statement[]]>[] = []; + const localInternals: Ast.DeclMem< + [Ast.ReceiverSubKind, readonly Ast.Statement[]] + >[] = []; + const localExternals: Ast.DeclMem< + [Ast.ReceiverSubKind, readonly Ast.Statement[]] + >[] = []; + const localBounces: Ast.DeclMem< + [Ast.TypedParameter, readonly Ast.Statement[]] + >[] = []; for (const receiver of receivers) { const { selector, statements, loc } = receiver; const via = Ast.ViaMemberOrigin(typeName.text, loc); switch (selector.kind) { case "internal": case "external": { - const arr = selector.kind === 'internal' - ? localInternals - : localExternals; + const arr = + selector.kind === "internal" + ? localInternals + : localExternals; arr.push(Ast.DeclMem([selector.subKind, statements], via)); continue; } case "bounce": { - localBounces.push(Ast.DeclMem([selector.param, statements], via)); + localBounces.push( + Ast.DeclMem([selector.param, statements], via), + ); } } } return { bounce: yield* mergeBounce( Lazy, - selfTypeRef, - typeName, - impBounces, - localBounces, + selfTypeRef, + typeName, + impBounces, + localBounces, scopeRef, ), external: yield* mergeReceivers( Lazy, - selfTypeRef, - typeName, - impExternals, - localExternals, + selfTypeRef, + typeName, + impExternals, + localExternals, scopeRef, ), internal: yield* mergeReceivers( Lazy, - selfTypeRef, - typeName, - impInternals, - localInternals, + selfTypeRef, + typeName, + impInternals, + localInternals, scopeRef, ), }; @@ -77,7 +86,9 @@ function* mergeReceivers( selfTypeRef: () => Ast.SelfType, typeName: Ast.TypeId, imported: readonly Ast.Decl[], - local: Ast.DeclMem[], + local: Ast.DeclMem< + readonly [Ast.ReceiverSubKind, readonly Ast.Statement[]] + >[], scopeRef: () => Ast.Scope, ): Ast.WithLog { const allMessage: Ast.DeclMem[] = []; @@ -89,27 +100,51 @@ function* mergeReceivers( for (const { via: viaTrait, decl } of imported) { const { message, messageAny, stringAny, empty } = decl; for (const { via, decl } of message) { - const nextVia = Ast.ViaMemberTrait(typeName.text, viaTrait.defLoc, via); + const nextVia = Ast.ViaMemberTrait( + typeName.text, + viaTrait.defLoc, + via, + ); // we don't check for duplicates in receivers here, because // the thing that matters is they have different opcodes allMessage.push(Ast.DeclMem(decl, nextVia)); } if (messageAny) { - const nextVia = Ast.ViaMemberTrait(typeName.text, viaTrait.defLoc, messageAny.via); + const nextVia = Ast.ViaMemberTrait( + typeName.text, + viaTrait.defLoc, + messageAny.via, + ); if (allMessageAny) { - yield ERedefineReceiver("fallback binary", allMessageAny.via, nextVia); + yield ERedefineReceiver( + "fallback binary", + allMessageAny.via, + nextVia, + ); } allMessageAny = Ast.DeclMem(messageAny.decl, nextVia); } if (stringAny) { - const nextVia = Ast.ViaMemberTrait(typeName.text, viaTrait.defLoc, stringAny.via); + const nextVia = Ast.ViaMemberTrait( + typeName.text, + viaTrait.defLoc, + stringAny.via, + ); if (allStringAny) { - yield ERedefineReceiver("fallback string", allStringAny.via, nextVia); + yield ERedefineReceiver( + "fallback string", + allStringAny.via, + nextVia, + ); } allStringAny = Ast.DeclMem(stringAny.decl, nextVia); } if (empty) { - const nextVia = Ast.ViaMemberTrait(typeName.text, viaTrait.defLoc, empty.via); + const nextVia = Ast.ViaMemberTrait( + typeName.text, + viaTrait.defLoc, + empty.via, + ); if (allEmpty) { yield ERedefineReceiver("empty", allEmpty.via, nextVia); } @@ -118,7 +153,10 @@ function* mergeReceivers( } // local - for (const { via, decl: [subKind, body] } of local) { + for (const { + via, + decl: [subKind, body], + } of local) { const statements = decodeStatementsLazy( Lazy, via.defLoc, @@ -126,7 +164,9 @@ function* mergeReceivers( emptyTypeParams, selfTypeRef, Lazy({ - callback: function* () { return Void; }, + callback: function* () { + return Void; + }, context: [], loc: via.defLoc, recover: Void, @@ -137,28 +177,43 @@ function* mergeReceivers( switch (subKind.kind) { case "simple": { const { name, type } = subKind.param; - const decoded = yield* decodeDealiasTypeLazy(Lazy, emptyTypeParams, type, scopeRef)(); - if (decoded.kind === 'TySlice') { + const decoded = yield* decodeDealiasTypeLazy( + Lazy, + emptyTypeParams, + type, + scopeRef, + )(); + if (decoded.kind === "TySlice") { if (allMessageAny) { - yield ERedefineReceiver("fallback binary", allMessageAny.via, via); + yield ERedefineReceiver( + "fallback binary", + allMessageAny.via, + via, + ); } allMessageAny = Ast.DeclMem( Ast.MessageAnyRecv(name, statements), via, ); - } else if (decoded.kind === 'TypeString') { + } else if (decoded.kind === "TypeString") { if (allStringAny) { - yield ERedefineReceiver("fallback string", allStringAny.via, via); + yield ERedefineReceiver( + "fallback string", + allStringAny.via, + via, + ); } allStringAny = Ast.DeclMem( Ast.StringAnyRecv(name, statements), via, ); - } else if (decoded.kind === 'type_ref') { - allMessage.push(Ast.DeclMem( - Ast.MessageRecv(name, decoded, statements), - via, - )); + } else if (decoded.kind === "type_ref") { + allMessage.push( + Ast.DeclMem( + Ast.MessageRecv(name, decoded, statements), + via, + ), + ); } else { yield EInvalidRecv(via.defLoc); } @@ -166,19 +221,22 @@ function* mergeReceivers( } case "fallback": { if (allEmpty) { - yield ERedefineReceiver("fallback string", allEmpty.via, via); + yield ERedefineReceiver( + "fallback string", + allEmpty.via, + via, + ); } - allEmpty = Ast.DeclMem( - Ast.EmptyRecv(statements), - via, - ); + allEmpty = Ast.DeclMem(Ast.EmptyRecv(statements), via); continue; } case "comment": { - allMessage.push(Ast.DeclMem( - Ast.StringRecv(subKind.comment.value, statements), - via, - )); + allMessage.push( + Ast.DeclMem( + Ast.StringRecv(subKind.comment.value, statements), + via, + ), + ); continue; } } @@ -197,31 +255,51 @@ function* mergeBounce( selfTypeRef: () => Ast.SelfType, typeName: Ast.TypeId, imported: readonly Ast.Decl[], - local: readonly Ast.DeclMem<[Ast.TypedParameter, readonly Ast.Statement[]]>[], - scopeRef: () => Ast.Scope + local: readonly Ast.DeclMem< + [Ast.TypedParameter, readonly Ast.Statement[]] + >[], + scopeRef: () => Ast.Scope, ): Ast.WithLog { const allMessage: Ast.DeclMem[] = []; let allMessageAny: undefined | Ast.DeclMem; - + // imported - for (const { via: viaTrait, decl: { message, messageAny } } of imported) { + for (const { + via: viaTrait, + decl: { message, messageAny }, + } of imported) { for (const { via, decl } of message) { - const nextVia = Ast.ViaMemberTrait(typeName.text, viaTrait.defLoc, via); + const nextVia = Ast.ViaMemberTrait( + typeName.text, + viaTrait.defLoc, + via, + ); // we don't check for duplicates in receivers here, because // the thing that matters is they have different opcodes allMessage.push(Ast.DeclMem(decl, nextVia)); } if (messageAny) { - const nextVia = Ast.ViaMemberTrait(typeName.text, viaTrait.defLoc, messageAny.via); + const nextVia = Ast.ViaMemberTrait( + typeName.text, + viaTrait.defLoc, + messageAny.via, + ); if (allMessageAny) { - yield ERedefineReceiver("fallback binary", allMessageAny.via, nextVia); + yield ERedefineReceiver( + "fallback binary", + allMessageAny.via, + nextVia, + ); } allMessageAny = Ast.DeclMem(messageAny.decl, nextVia); } } - + // local - for (const { via, decl: [{ name, type }, body] } of local) { + for (const { + via, + decl: [{ name, type }, body], + } of local) { const statements = decodeStatementsLazy( Lazy, via.defLoc, @@ -229,7 +307,9 @@ function* mergeBounce( emptyTypeParams, selfTypeRef, Lazy({ - callback: function* () { return Void; }, + callback: function* () { + return Void; + }, context: [], loc: via.defLoc, recover: Void, @@ -237,37 +317,48 @@ function* mergeBounce( true, scopeRef, ); - const decoded = yield* decodeDealiasTypeLazy(Lazy, emptyTypeParams, type, scopeRef)(); - if (decoded.kind === 'TySlice') { + const decoded = yield* decodeDealiasTypeLazy( + Lazy, + emptyTypeParams, + type, + scopeRef, + )(); + if (decoded.kind === "TySlice") { if (allMessageAny) { - yield ERedefineReceiver("fallback binary", allMessageAny.via, via); + yield ERedefineReceiver( + "fallback binary", + allMessageAny.via, + via, + ); } allMessageAny = Ast.DeclMem( Ast.MessageAnyRecv(name, statements), via, ); - } else if (decoded.kind === 'type_ref' || decoded.kind === 'TypeBounced') { - allMessage.push(Ast.DeclMem( - Ast.MessageRecv(name, decoded, statements), - via, - )); + } else if ( + decoded.kind === "type_ref" || + decoded.kind === "TypeBounced" + ) { + allMessage.push( + Ast.DeclMem(Ast.MessageRecv(name, decoded, statements), via), + ); } else { yield EInvalidRecv(via.defLoc); } } - + return { message: allMessage, messageAny: allMessageAny, }; } -const EInvalidRecv = ( - loc: Ast.Loc, -): Ast.TcError => ({ +const EInvalidRecv = (loc: Ast.Loc): Ast.TcError => ({ loc, descr: [ - Ast.TEText(`Receiver's parameter must be a message type, Slice, or String`), + Ast.TEText( + `Receiver's parameter must be a message type, Slice, or String`, + ), ], }); @@ -284,4 +375,4 @@ const ERedefineReceiver = ( Ast.TEText(`Redefined at`), Ast.TEViaMember(next), ], -}); \ No newline at end of file +}); diff --git a/src/next/types/statements.ts b/src/next/types/statements.ts index cbadc43c0b..ebe13650dd 100644 --- a/src/next/types/statements.ts +++ b/src/next/types/statements.ts @@ -6,8 +6,19 @@ import { throwInternal } from "@/error/errors"; import { Bool, builtinAugmented, Int, Void } from "@/next/types/builtins"; import { decodeExprCtx } from "@/next/types/expression"; import { convertExprToLValue } from "@/next/types/lvalue"; -import { assignType, dealiasType, decodeType, decodeTypeLazy, checkFnCall } from "@/next/types/type"; -import { emptyEff, mergeEff, setHadAssign, setHadExit } from "@/next/types/effects"; +import { + assignType, + dealiasType, + decodeType, + decodeTypeLazy, + checkFnCall, +} from "@/next/types/type"; +import { + emptyEff, + mergeEff, + setHadAssign, + setHadExit, +} from "@/next/types/effects"; import { emptyTypeParams } from "@/next/types/type-params"; export function decodeStatementsLazy( @@ -23,9 +34,7 @@ export function decodeStatementsLazy( return Lazy({ callback: function* (Lazy) { const selfType = selfTypeRef(); - const required = isInit - ? yield* getRequired(selfType) - : undefined; + const required = isInit ? yield* getRequired(selfType) : undefined; const ctx: Context = { Lazy, localScopeRef: new Map(), @@ -59,30 +68,61 @@ const decodeStmts: Decode< return Result(results, context, effects); }; -const decodeStatement: Decode = function (stmt, ctx, eff) { +const decodeStatement: Decode = function ( + stmt, + ctx, + eff, +) { switch (stmt.kind) { - case "statement_let": return decodeLet(stmt, ctx, eff); - case "statement_return": return decodeReturn(stmt, ctx, eff); - case "statement_expression": return decodeExpression(stmt, ctx, eff); - case "statement_assign": return decodeAssign(stmt, ctx, eff); - case "statement_augmentedassign": return decodeAssignAugmented(stmt, ctx, eff); - case "statement_condition": return decodeCondition(stmt, ctx, eff); - case "statement_while": return decodeWhile(stmt, ctx, eff); - case "statement_until": return decodeUntil(stmt, ctx, eff); - case "statement_repeat": return decodeRepeat(stmt, ctx, eff); - case "statement_try": return decodeTry(stmt, ctx, eff); - case "statement_foreach": return decodeForeach(stmt, ctx, eff); - case "statement_destruct": return decodeDestruct(stmt, ctx, eff); - case "statement_block": return decodeBlock(stmt, ctx, eff); + case "statement_let": + return decodeLet(stmt, ctx, eff); + case "statement_return": + return decodeReturn(stmt, ctx, eff); + case "statement_expression": + return decodeExpression(stmt, ctx, eff); + case "statement_assign": + return decodeAssign(stmt, ctx, eff); + case "statement_augmentedassign": + return decodeAssignAugmented(stmt, ctx, eff); + case "statement_condition": + return decodeCondition(stmt, ctx, eff); + case "statement_while": + return decodeWhile(stmt, ctx, eff); + case "statement_until": + return decodeUntil(stmt, ctx, eff); + case "statement_repeat": + return decodeRepeat(stmt, ctx, eff); + case "statement_try": + return decodeTry(stmt, ctx, eff); + case "statement_foreach": + return decodeForeach(stmt, ctx, eff); + case "statement_destruct": + return decodeDestruct(stmt, ctx, eff); + case "statement_block": + return decodeBlock(stmt, ctx, eff); } -} +}; -const decodeLet: Decode = function* (node, ctx, eff) { +const decodeLet: Decode = function* ( + node, + ctx, + eff, +) { const expr = yield* decodeExprCtx(node.expression, ctx); const result = Ast.DStatementLet(node.name, expr, node.loc); if (node.type) { - const ascribed = yield* decodeType(ctx.typeParams, node.type, ctx.scopeRef().typeDecls) - yield* assignType(expr.loc, emptyTypeParams, ascribed, expr.computedType, false); + const ascribed = yield* decodeType( + ctx.typeParams, + node.type, + ctx.scopeRef().typeDecls, + ); + yield* assignType( + expr.loc, + emptyTypeParams, + ascribed, + expr.computedType, + false, + ); const newCtx = yield* defineVar(node.name, ascribed, ctx); return Result(result, newCtx, eff); } else { @@ -91,21 +131,41 @@ const decodeLet: Decode = function* (node, } }; -const decodeReturn: Decode = function* (node, ctx, eff) { - const newEff = yield* setHadExit(eff, true, ctx.required, node.loc); - if (node.expression) { - const expr = yield* decodeExprCtx(node.expression, ctx); - yield* assignType(expr.loc, emptyTypeParams, ctx.returnType, expr.computedType, false); - return Result(Ast.DStatementReturn(expr, node.loc), ctx, newEff); - } else { - yield* assignType(node.loc, emptyTypeParams, ctx.returnType, Void, false); - return Result(Ast.DStatementReturn(undefined, node.loc), ctx, newEff); - } -}; +const decodeReturn: Decode = + function* (node, ctx, eff) { + const newEff = yield* setHadExit(eff, true, ctx.required, node.loc); + if (node.expression) { + const expr = yield* decodeExprCtx(node.expression, ctx); + yield* assignType( + expr.loc, + emptyTypeParams, + ctx.returnType, + expr.computedType, + false, + ); + return Result(Ast.DStatementReturn(expr, node.loc), ctx, newEff); + } else { + yield* assignType( + node.loc, + emptyTypeParams, + ctx.returnType, + Void, + false, + ); + return Result( + Ast.DStatementReturn(undefined, node.loc), + ctx, + newEff, + ); + } + }; -const decodeExpression: Decode = function* (node, ctx, eff) { +const decodeExpression: Decode< + Ast.StatementExpression, + Ast.DStatementExpression +> = function* (node, ctx, eff) { const expr = yield* decodeExprCtx(node.expression, ctx); - if (expr.kind === 'throw_call') { + if (expr.kind === "throw_call") { const newEff = yield* setHadExit(eff, true, ctx.required, node.loc); return Result(Ast.DStatementExpression(expr, node.loc), ctx, newEff); } else { @@ -113,12 +173,21 @@ const decodeExpression: Decode = function* (node, ctx, eff) { - const right = yield* decodeExprCtx(node.expression, ctx); +const decodeAssign: Decode< + Ast.StatementAssign, + Ast.DStatementAssign | Ast.DStatementExpression +> = function* (node, ctx, eff) { + const right = yield* decodeExprCtx(node.expression, ctx); const left = yield* decodeExprCtx(node.path, ctx); const path = yield* convertExprToLValue(left); if (path) { - yield* assignType(path.loc, emptyTypeParams, path.computedType, right.computedType, false); + yield* assignType( + path.loc, + emptyTypeParams, + path.computedType, + right.computedType, + false, + ); const newEff = yield* setHadAssign(eff, path); return Result(Ast.DStatementAssign(path, right, node.loc), ctx, newEff); } else { @@ -126,108 +195,202 @@ const decodeAssign: Decode = function* (node, ctx, eff) { - const right = yield* decodeExprCtx(node.expression, ctx); +const decodeAssignAugmented: Decode< + Ast.StatementAugmentedAssign, + Ast.DStatementAugmentedAssign | Ast.DStatementExpression +> = function* (node, ctx, eff) { + const right = yield* decodeExprCtx(node.expression, ctx); const left = yield* decodeExprCtx(node.path, ctx); const path = yield* convertExprToLValue(left); const fnType = builtinAugmented.get(node.op); if (!fnType) { return throwInternal("Builtin operator is not in the map"); } - yield* checkFnCall( - node.loc, - fnType, - [ - [left.loc, left.computedType], - [right.loc, right.computedType], - ], - ); + yield* checkFnCall(node.loc, fnType, [ + [left.loc, left.computedType], + [right.loc, right.computedType], + ]); if (path) { const newEff = yield* setHadAssign(eff, path); - return Result(Ast.DStatementAugmentedAssign(node.op, path, right, node.loc), ctx, newEff); + return Result( + Ast.DStatementAugmentedAssign(node.op, path, right, node.loc), + ctx, + newEff, + ); } else { return Result(Ast.DStatementExpression(right, node.loc), ctx, eff); } }; -const decodeCondition: Decode = function* (node, ctx, eff) { - const condition = yield* decodeExprCtx(node.condition, ctx); - yield* assignType(condition.loc, emptyTypeParams, Bool, condition.computedType, false); - const trueRes = yield* decodeStmts(node.trueStatements, ctx, eff); - if (node.falseStatements) { - const falseRes = yield* decodeStmts(node.falseStatements, ctx, eff); - const newEff = mergeEff(trueRes.effects, falseRes.effects); - return Result(Ast.DStatementCondition(condition, trueRes.node, falseRes.node, node.loc), ctx, newEff); - } else { - const newEff = mergeEff(trueRes.effects, eff); - return Result(Ast.DStatementCondition(condition, trueRes.node, undefined, node.loc), ctx, newEff); - } -}; +const decodeCondition: Decode = + function* (node, ctx, eff) { + const condition = yield* decodeExprCtx(node.condition, ctx); + yield* assignType( + condition.loc, + emptyTypeParams, + Bool, + condition.computedType, + false, + ); + const trueRes = yield* decodeStmts(node.trueStatements, ctx, eff); + if (node.falseStatements) { + const falseRes = yield* decodeStmts(node.falseStatements, ctx, eff); + const newEff = mergeEff(trueRes.effects, falseRes.effects); + return Result( + Ast.DStatementCondition( + condition, + trueRes.node, + falseRes.node, + node.loc, + ), + ctx, + newEff, + ); + } else { + const newEff = mergeEff(trueRes.effects, eff); + return Result( + Ast.DStatementCondition( + condition, + trueRes.node, + undefined, + node.loc, + ), + ctx, + newEff, + ); + } + }; -const decodeWhile: Decode = function* (node, ctx, eff) { +const decodeWhile: Decode = function* ( + node, + ctx, + eff, +) { const condition = yield* decodeExprCtx(node.condition, ctx); - yield* assignType(condition.loc, emptyTypeParams, Bool, condition.computedType, false); + yield* assignType( + condition.loc, + emptyTypeParams, + Bool, + condition.computedType, + false, + ); const result = yield* decodeStmts(node.statements, ctx, eff); // might be executed zero times, so it doesn't matter // if it always returns, or assigns to `self` - return Result(Ast.DStatementWhile(condition, result.node, node.loc), ctx, eff); + return Result( + Ast.DStatementWhile(condition, result.node, node.loc), + ctx, + eff, + ); }; -const decodeUntil: Decode = function* (node, ctx, eff) { +const decodeUntil: Decode = function* ( + node, + ctx, + eff, +) { const condition = yield* decodeExprCtx(node.condition, ctx); - yield* assignType(condition.loc, emptyTypeParams, Bool, condition.computedType, false); + yield* assignType( + condition.loc, + emptyTypeParams, + Bool, + condition.computedType, + false, + ); const result = yield* decodeStmts(node.statements, ctx, eff); // until executes its body at least once - return Result(Ast.DStatementUntil(condition, result.node, node.loc), ctx, result.effects); + return Result( + Ast.DStatementUntil(condition, result.node, node.loc), + ctx, + result.effects, + ); }; -const decodeRepeat: Decode = function* (node, ctx, eff) { - const iterations = yield* decodeExprCtx(node.iterations, ctx); - yield* assignType(iterations.loc, emptyTypeParams, Int, iterations.computedType, false); - const result = yield* decodeStmts(node.statements, ctx, eff); - // might be executed zero times, so it doesn't matter - // if it always returns, or assigns to `self` - return Result(Ast.DStatementRepeat(iterations, result.node, node.loc), ctx, eff); -}; +const decodeRepeat: Decode = + function* (node, ctx, eff) { + const iterations = yield* decodeExprCtx(node.iterations, ctx); + yield* assignType( + iterations.loc, + emptyTypeParams, + Int, + iterations.computedType, + false, + ); + const result = yield* decodeStmts(node.statements, ctx, eff); + // might be executed zero times, so it doesn't matter + // if it always returns, or assigns to `self` + return Result( + Ast.DStatementRepeat(iterations, result.node, node.loc), + ctx, + eff, + ); + }; -const decodeTry: Decode = function* (node, ctx, eff) { +const decodeTry: Decode = function* ( + node, + ctx, + eff, +) { const tryRes = yield* decodeStmts(node.statements, ctx, eff); if (node.catchBlock) { const newCtx = yield* defineVar(node.catchBlock.name, Int, ctx); - const catchRes = yield* decodeStmts(node.catchBlock.statements, newCtx, eff); + const catchRes = yield* decodeStmts( + node.catchBlock.statements, + newCtx, + eff, + ); const catchBlock = Ast.DCatchBlock(node.catchBlock.name, catchRes.node); const newEff = mergeEff(tryRes.effects, catchRes.effects); - return Result(Ast.DStatementTry(tryRes.node, catchBlock, node.loc), ctx, newEff); + return Result( + Ast.DStatementTry(tryRes.node, catchBlock, node.loc), + ctx, + newEff, + ); } else { - return Result(Ast.DStatementTry(tryRes.node, undefined, node.loc), ctx, tryRes.effects); + return Result( + Ast.DStatementTry(tryRes.node, undefined, node.loc), + ctx, + tryRes.effects, + ); } }; -const decodeForeach: Decode = function* (node, ctx, eff) { - const map = yield* decodeExprCtx(node.map, ctx); - const innerCtx = yield* defineForVars( - map.computedType, - node.keyName, - node.valueName, - ctx, - ); - const result = yield* decodeStmts(node.statements, innerCtx, eff); - return Result(Ast.DStatementForEach(node.keyName, node.valueName, map, result.node, node.loc), ctx, eff); -}; +const decodeForeach: Decode = + function* (node, ctx, eff) { + const map = yield* decodeExprCtx(node.map, ctx); + const innerCtx = yield* defineForVars( + map.computedType, + node.keyName, + node.valueName, + ctx, + ); + const result = yield* decodeStmts(node.statements, innerCtx, eff); + return Result( + Ast.DStatementForEach( + node.keyName, + node.valueName, + map, + result.node, + node.loc, + ), + ctx, + eff, + ); + }; function* defineForVars( type: Ast.DecodedType, keyName: Ast.OptionalId, valueName: Ast.OptionalId, ctx: Context, ): Ast.WithLog { - if (type.kind === 'map_type') { + if (type.kind === "map_type") { const ctxKey = yield* defineVar(keyName, type.key, ctx); const ctxKV = yield* defineVar(valueName, type.value, ctxKey); return ctxKV; - } else if (type.kind === 'TypeAlias') { + } else if (type.kind === "TypeAlias") { const childType = type.type; // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition - if (childType.kind === 'NotDealiased') { + if (childType.kind === "NotDealiased") { return throwInternal("Non-dealiased type in foreach"); } return yield* defineForVars(childType, keyName, valueName, ctx); @@ -238,11 +401,19 @@ function* defineForVars( } } -const decodeDestruct: Decode = function* (node, ctx, eff) { +const decodeDestruct: Decode< + Ast.StatementDestruct, + Ast.DStatementDestruct | Ast.DStatementExpression +> = function* (node, ctx, eff) { const expr = yield* decodeExprCtx(node.expression, ctx); const typeArgs = yield* Ast.mapLog(node.typeArgs, function* (arg) { - return yield* decodeTypeLazy(ctx.Lazy, ctx.typeParams, arg, ctx.scopeRef)(); + return yield* decodeTypeLazy( + ctx.Lazy, + ctx.typeParams, + arg, + ctx.scopeRef, + )(); }); const decl = yield* findStruct(node.type, typeArgs, ctx.scopeRef); @@ -251,18 +422,34 @@ const decodeDestruct: Decode [name, pattern]) + [...map].map(([name, [pattern]]) => [name, pattern]), ); return [Ast.Ordered(order, result), ctx]; } @@ -324,12 +504,13 @@ const EMissingField = (name: string, prev: Ast.Loc): Ast.TcError => ({ }); const ENoSuchField = (name: string, next: Ast.Loc): Ast.TcError => ({ loc: next, - descr: [ - Ast.TEText(`There is no field "${name}"`), - Ast.TECode(next), - ], + descr: [Ast.TEText(`There is no field "${name}"`), Ast.TECode(next)], }); -const EDuplicateField = (name: string, prev: Ast.Loc, next: Ast.Loc): Ast.TcError => ({ +const EDuplicateField = ( + name: string, + prev: Ast.Loc, + next: Ast.Loc, +): Ast.TcError => ({ loc: prev, descr: [ Ast.TEText(`Duplicate field "${name}"`), @@ -351,15 +532,13 @@ function* findStruct( switch (decl.decl.kind) { case "alias": { const type = yield* dealiasType( - Ast.DTypeAliasRef( - Ast.NotDealiased(), - id, - typeArgs, - id.loc, - ), + Ast.DTypeAliasRef(Ast.NotDealiased(), id, typeArgs, id.loc), scopeRef, ); - if (type.kind === 'type_ref' && (type.type.kind === 'struct' || type.type.kind === 'message')) { + if ( + type.kind === "type_ref" && + (type.type.kind === "struct" || type.type.kind === "message") + ) { return type.type; } else { yield ENotDestructible(id.text, id.loc); @@ -380,28 +559,33 @@ function* findStruct( } const ENotDestructible = (name: string, prev: Ast.Loc): Ast.TcError => ({ loc: prev, - descr: [ - Ast.TEText(`Type "${name}" doesn't `), - Ast.TECode(prev), - ], + descr: [Ast.TEText(`Type "${name}" doesn't `), Ast.TECode(prev)], }); -const decodeBlock: Decode = function* (node, ctx, eff) { +const decodeBlock: Decode = function* ( + node, + ctx, + eff, +) { const result = yield* decodeStmts(node.statements, ctx, eff); - return Result(Ast.DStatementBlock(result.node, node.loc), ctx, result.effects); + return Result( + Ast.DStatementBlock(result.node, node.loc), + ctx, + result.effects, + ); }; type Decode = ( node: T, - context: Context, + context: Context, effects: Ast.Effects, -) => Ast.WithLog> +) => Ast.WithLog>; type Result = { readonly node: U; readonly context: Context; readonly effects: Ast.Effects; -} +}; const Result = ( node: U, context: Context, @@ -409,30 +593,30 @@ const Result = ( ): Result => Object.freeze({ node, context, effects }); type Context = { - readonly Lazy: Ast.ThunkBuilder, + readonly Lazy: Ast.ThunkBuilder; readonly scopeRef: () => Ast.Scope; readonly selfType: Ast.SelfType | undefined; readonly required: undefined | ReadonlySet; readonly typeParams: Ast.TypeParams; readonly returnType: Ast.DecodedType; readonly localScopeRef: ReadonlyMap; -} +}; function* defineVar( - node: Ast.OptionalId, - type: Ast.DecodedType, + node: Ast.OptionalId, + type: Ast.DecodedType, ctx: Context, ): Ast.WithLog { - if (node.kind === 'wildcard') { + if (node.kind === "wildcard") { // there is nothing to define for a wildcard return ctx; } - - if (node.text === 'self') { + + if (node.text === "self") { yield ENoDefineSelf(node.loc); return ctx; } - + const prev = ctx.localScopeRef.get(node.text); if (prev) { const [, prevLoc] = prev; @@ -453,11 +637,13 @@ function* defineVar( } const ENoDefineSelf = (loc: Ast.Loc): Ast.TcError => ({ loc, - descr: [ - Ast.TEText(`Cannot define a variable "self"`), - ], + descr: [Ast.TEText(`Cannot define a variable "self"`)], }); -const ERedefineVar = (name: string, prev: Ast.Loc, next: Ast.Loc): Ast.TcError => ({ +const ERedefineVar = ( + name: string, + prev: Ast.Loc, + next: Ast.Loc, +): Ast.TcError => ({ loc: next, descr: [ Ast.TEText(`Variable ${name} is already defined`), @@ -467,7 +653,11 @@ const ERedefineVar = (name: string, prev: Ast.Loc, next: Ast.Loc): Ast.TcError = Ast.TECode(prev), ], }); -const EShadowConst = (name: string, prev: Ast.Loc, next: Ast.Loc): Ast.TcError => ({ +const EShadowConst = ( + name: string, + prev: Ast.Loc, + next: Ast.Loc, +): Ast.TcError => ({ loc: next, descr: [ Ast.TEText(`Variable ${name} shadows a global constant`), @@ -478,7 +668,9 @@ const EShadowConst = (name: string, prev: Ast.Loc, next: Ast.Loc): Ast.TcError = ], }); -function* getRequired(selfType: Ast.SelfType | undefined): Ast.WithLog> { +function* getRequired( + selfType: Ast.SelfType | undefined, +): Ast.WithLog> { if (!selfType) { return new Set(); } @@ -488,10 +680,10 @@ function* getRequired(selfType: Ast.SelfType | undefined): Ast.WithLog content; const content: Ast.TraitContent = { fieldish: yield* getFieldishGeneral( @@ -56,7 +53,7 @@ export function* decodeTrait( scopeRef, ), }; - + return content; }, context: [Ast.TEText("checking inner scope of trait")], @@ -66,23 +63,14 @@ export function* decodeTrait( const traitSig = Ast.TraitSig(contentLazy); - const selfType = Ast.MVTypeRef( - trait.name, - traitSig, - [], - trait.loc, - ); + const selfType = Ast.MVTypeRef(trait.name, traitSig, [], trait.loc); return traitSig; } -const ENoAttributes = ( - loc: Ast.Loc, -): Ast.TcError => ({ +const ENoAttributes = (loc: Ast.Loc): Ast.TcError => ({ loc, - descr: [ - Ast.TEText(`Traits cannot have attributes`), - ], + descr: [Ast.TEText(`Traits cannot have attributes`)], }); const recover: Ast.TraitContent = { @@ -106,4 +94,4 @@ const recover: Ast.TraitContent = { empty: undefined, }, }, -}; \ No newline at end of file +}; diff --git a/src/next/types/traits-scope.ts b/src/next/types/traits-scope.ts index 8bd76a0633..38e48d2d6f 100644 --- a/src/next/types/traits-scope.ts +++ b/src/next/types/traits-scope.ts @@ -16,33 +16,21 @@ export function* getInheritedTraits( continue; } const { via, decl: traitDecl } = decl; - if (traitDecl.kind !== 'trait') { + if (traitDecl.kind !== "trait") { yield EOnlyTraits(trait.loc); continue; } - prevTraits.push(Ast.Decl( - yield* traitDecl.content(), - via, - )); + prevTraits.push(Ast.Decl(yield* traitDecl.content(), via)); } return prevTraits; } -const EUndefinedTrait = ( - name: string, - loc: Ast.Loc, -): Ast.TcError => ({ +const EUndefinedTrait = (name: string, loc: Ast.Loc): Ast.TcError => ({ loc, - descr: [ - Ast.TEText(`Traits "${name}" is not defined`), - ], + descr: [Ast.TEText(`Traits "${name}" is not defined`)], }); -const EOnlyTraits = ( - loc: Ast.Loc, -): Ast.TcError => ({ +const EOnlyTraits = (loc: Ast.Loc): Ast.TcError => ({ loc, - descr: [ - Ast.TEText(`Can only inherit traits`), - ], + descr: [Ast.TEText(`Can only inherit traits`)], }); diff --git a/src/next/types/type-fn.ts b/src/next/types/type-fn.ts index f0c3899da3..fe17296766 100644 --- a/src/next/types/type-fn.ts +++ b/src/next/types/type-fn.ts @@ -29,12 +29,8 @@ export function* decodeParams( const set: Set = new Set(); for (const param of params) { const name = yield* decodeParamName(param.name, set); - order.push(Ast.Parameter( - param.name, - dealias(param.type), - param.loc, - )); - if (typeof name !== 'undefined') { + order.push(Ast.Parameter(param.name, dealias(param.type), param.loc)); + if (typeof name !== "undefined") { set.add(name); } } @@ -45,7 +41,7 @@ function* decodeParamName( node: Ast.OptionalId, set: ReadonlySet, ): Ast.WithLog { - if (node.kind === 'wildcard') { + if (node.kind === "wildcard") { return undefined; } const name = node.text; @@ -58,7 +54,5 @@ function* decodeParamName( const EDuplicateParam = (name: string, loc: Ast.Loc): Ast.TcError => ({ loc, - descr: [ - Ast.TEText(`Duplicate parameter "${name}"`), - ], + descr: [Ast.TEText(`Duplicate parameter "${name}"`)], }); diff --git a/src/next/types/type-params.ts b/src/next/types/type-params.ts index c8113f7b10..50de57a885 100644 --- a/src/next/types/type-params.ts +++ b/src/next/types/type-params.ts @@ -3,7 +3,9 @@ import { recoverName } from "@/next/types/name"; export const emptyTypeParams = Ast.TypeParams([], new Set()); -export function* decodeTypeParams(ids: readonly Ast.TypeId[]): Ast.WithLog { +export function* decodeTypeParams( + ids: readonly Ast.TypeId[], +): Ast.WithLog { const set: Set = new Set(); const order: Ast.TypeId[] = []; @@ -23,9 +25,5 @@ export function* decodeTypeParams(ids: readonly Ast.TypeId[]): Ast.WithLog ({ loc, - descr: [ - Ast.TEText(`Duplicate type parameter "${name}"`), - ], + descr: [Ast.TEText(`Duplicate type parameter "${name}"`)], }); - - diff --git a/src/next/types/type-print.ts b/src/next/types/type-print.ts index 9634678c40..c54eff1aed 100644 --- a/src/next/types/type-print.ts +++ b/src/next/types/type-print.ts @@ -11,13 +11,13 @@ export function printType(node: Ast.DecodedType, allowRecover: boolean) { return undefined; } } - return results.join(', '); + return results.join(", "); } function rec(node: Ast.DecodedType): undefined | string { switch (node.kind) { case "recover": { - return allowRecover ? '$ERROR' : undefined; + return allowRecover ? "$ERROR" : undefined; } case "type_ref": case "TypeAlias": { @@ -50,7 +50,7 @@ export function printType(node: Ast.DecodedType, allowRecover: boolean) { return typeArgs && `[${typeArgs}]`; } case "TyInt": { - return `Int${printIntFormat(node.format)}` + return `Int${printIntFormat(node.format)}`; } case "TySlice": { return `Slice${printSliceFormat(node.format)}`; @@ -92,16 +92,23 @@ export function printType(node: Ast.DecodedType, allowRecover: boolean) { } const printIntFormat = (format: Ast.IntFormat): string => { - if (format.kind === 'FInt' && format.sign === 'signed' && format.width === 257) { - return ''; + if ( + format.kind === "FInt" && + format.sign === "signed" && + format.width === 257 + ) { + return ""; } - return " as " + (format.kind === 'FVarInt' ? "var" : "") - + (format.sign === 'unsigned' ? 'uint' : 'int') - + (format.kind === 'FVarInt' ? format.width : format.width.toString()); + return ( + " as " + + (format.kind === "FVarInt" ? "var" : "") + + (format.sign === "unsigned" ? "uint" : "int") + + (format.kind === "FVarInt" ? format.width : format.width.toString()) + ); }; const printSliceFormat = (format: Ast.SliceFormat): string => { - if (format.kind === 'SFBits') { + if (format.kind === "SFBits") { // FIXME: bits not divisible by 8 return ` as bytes${format.bits >> 3}`; } else { @@ -111,7 +118,9 @@ const printSliceFormat = (format: Ast.SliceFormat): string => { const printRemFormat = (format: Ast.RemFormat): string => { switch (format.kind) { - case "SFRemaining": return ` as remaining`; - case "SFDefault": return ``; + case "SFRemaining": + return ` as remaining`; + case "SFDefault": + return ``; } }; diff --git a/src/next/types/type.ts b/src/next/types/type.ts index 85ecc844a6..853851bfc2 100644 --- a/src/next/types/type.ts +++ b/src/next/types/type.ts @@ -12,47 +12,36 @@ export const decodeTypeLazy = ( typeParams: Ast.TypeParams, type: Ast.Type, scopeRef: () => Ast.Scope, -) => Lazy({ - callback: () => decodeType( - typeParams, - type, - scopeRef().typeDecls, - ), - context: [Ast.TEText("checking type"), Ast.TECode(type.loc)], - loc: type.loc, - recover: Ast.DTypeRecover(), -}); +) => + Lazy({ + callback: () => decodeType(typeParams, type, scopeRef().typeDecls), + context: [Ast.TEText("checking type"), Ast.TECode(type.loc)], + loc: type.loc, + recover: Ast.DTypeRecover(), + }); export const decodeDealiasTypeLazy = ( Lazy: Ast.ThunkBuilder, typeParams: Ast.TypeParams, type: Ast.Type, scopeRef: () => Ast.Scope, -) => Lazy({ - callback: function* () { - const decoded = yield* decodeType( - typeParams, - type, - scopeRef().typeDecls, - ); - return yield* dealiasTypeAux( - decoded, - scopeRef().typeDecls, - ); - }, - context: [Ast.TEText("checking type"), Ast.TECode(type.loc)], - loc: type.loc, - recover: Ast.DTypeRecover(), -}); - -export function* dealiasType( - type: Ast.DecodedType, - scopeRef: () => Ast.Scope, -) { - return yield* dealiasTypeAux( - type, - scopeRef().typeDecls, - ); +) => + Lazy({ + callback: function* () { + const decoded = yield* decodeType( + typeParams, + type, + scopeRef().typeDecls, + ); + return yield* dealiasTypeAux(decoded, scopeRef().typeDecls); + }, + context: [Ast.TEText("checking type"), Ast.TECode(type.loc)], + loc: type.loc, + recover: Ast.DTypeRecover(), + }); + +export function* dealiasType(type: Ast.DecodedType, scopeRef: () => Ast.Scope) { + return yield* dealiasTypeAux(type, scopeRef().typeDecls); } export function* decodeTypeMap( @@ -95,9 +84,7 @@ export function decodeType( } // decode a type - function* rec( - type: Ast.Type, - ): Ast.WithLog { + function* rec(type: Ast.Type): Ast.WithLog { switch (type.kind) { case "unit_type": case "TyInt": @@ -129,7 +116,7 @@ export function decodeType( } case "TypeBounced": { const child = yield* rec(type.type); - if (child.kind !== 'type_ref' || child.typeArgs.length > 0) { + if (child.kind !== "type_ref" || child.typeArgs.length > 0) { yield EBouncedMessage(type.loc); return Ast.DTypeRecover(); } @@ -137,7 +124,7 @@ export function decodeType( if (!typeEntry) { yield EBouncedMessage(type.loc); return Ast.DTypeRecover(); - } else if (typeEntry.decl.kind === 'message') { + } else if (typeEntry.decl.kind === "message") { return Ast.DTypeBounced(child.name, type.loc); } else { yield EBouncedMessage(type.loc); @@ -165,10 +152,7 @@ export function decodeType( if (!(yield* matchArity(name, arity, 0, type.loc))) { return Ast.DTypeRecover(); } - return Ast.DTypeParamRef( - type.name, - type.loc, - ); + return Ast.DTypeParamRef(type.name, type.loc); } const typeEntry = typeDecls.get(name); @@ -180,12 +164,14 @@ export function decodeType( } // check number of type arguments does match - if (!(yield* matchArity( - name, - arity, - getArity(typeEntry.decl), - type.loc, - ))) { + if ( + !(yield* matchArity( + name, + arity, + getArity(typeEntry.decl), + type.loc, + )) + ) { return Ast.DTypeRecover(); } @@ -196,17 +182,32 @@ export function decodeType( } case "contract": { // this is a ground type reference - return Ast.DTypeRef(type.name, typeEntry.decl, [], type.loc); + return Ast.DTypeRef( + type.name, + typeEntry.decl, + [], + type.loc, + ); } case "struct": case "message": case "union": { // this is a ground type reference - return Ast.DTypeRef(type.name, typeEntry.decl, args, type.loc); + return Ast.DTypeRef( + type.name, + typeEntry.decl, + args, + type.loc, + ); } case "alias": { // this is an alias reference - return Ast.DTypeAliasRef(Ast.NotDealiased(), type.name, args, type.loc); + return Ast.DTypeAliasRef( + Ast.NotDealiased(), + type.name, + args, + type.loc, + ); } } } @@ -227,25 +228,16 @@ const getArity = (decl: Ast.TypeDeclSig): number => { case "message": return 0; } -} +}; -const EBouncedMessage = ( - loc: Ast.Loc, -): Ast.TcError => ({ +const EBouncedMessage = (loc: Ast.Loc): Ast.TcError => ({ loc, - descr: [ - Ast.TEText(`Only message types can be bounced<>`), - ], + descr: [Ast.TEText(`Only message types can be bounced<>`)], }); -const ETypeNotFound = ( - name: string, - loc: Ast.Loc, -): Ast.TcError => ({ +const ETypeNotFound = (name: string, loc: Ast.Loc): Ast.TcError => ({ loc, - descr: [ - Ast.TEText(`Type "${name}" is not defined`), - ], + descr: [Ast.TEText(`Type "${name}" is not defined`)], }); function* matchArity( @@ -269,17 +261,15 @@ const EArity = ( ): Ast.TcError => ({ loc, descr: [ - Ast.TEText(`Type "${name}" is expected to have ${expected} type arguments, got ${got}`), + Ast.TEText( + `Type "${name}" is expected to have ${expected} type arguments, got ${got}`, + ), ], }); -const ETraitNotType = ( - loc: Ast.Loc, -): Ast.TcError => ({ +const ETraitNotType = (loc: Ast.Loc): Ast.TcError => ({ loc, - descr: [ - Ast.TEText(`Traits cannot be used as types`), - ], + descr: [Ast.TEText(`Traits cannot be used as types`)], }); const dealiasTypeAux = ( @@ -297,17 +287,26 @@ const dealiasTypeAux = ( } case "TypeAlias": { const alias = typeDecls.get(type.name.text); - if (!alias || alias.decl.kind !== 'alias') { - return throwInternal("Type decoder must not return types with dangling references"); + if (!alias || alias.decl.kind !== "alias") { + return throwInternal( + "Type decoder must not return types with dangling references", + ); } // NB! if we could decode alias once, there might be // a nested one too - const decoded = yield* rec(substituteTypeArgs( - yield* alias.decl.type(), - alias.decl.typeParams, - yield* Ast.mapLog(type.typeArgs, rec), - )); - return Ast.DTypeAliasRef(decoded, type.name, type.typeArgs, type.loc); + const decoded = yield* rec( + substituteTypeArgs( + yield* alias.decl.type(), + alias.decl.typeParams, + yield* Ast.mapLog(type.typeArgs, rec), + ), + ); + return Ast.DTypeAliasRef( + decoded, + type.name, + type.typeArgs, + type.loc, + ); } case "TypeParam": { return type; @@ -360,12 +359,16 @@ export const substituteTypeArgs = ( return throwInternal("Decoder didn't check alias arity"); } - const substMap = new Map(zip(params.order, args).map(([param, arg]) => { - return [param.text, arg]; - })); + const substMap = new Map( + zip(params.order, args).map(([param, arg]) => { + return [param.text, arg]; + }), + ); - const recN = (types: readonly Ast.DecodedType[]): readonly Ast.DecodedType[] => { - return types.map(type => rec(type)); + const recN = ( + types: readonly Ast.DecodedType[], + ): readonly Ast.DecodedType[] => { + return types.map((type) => rec(type)); }; const rec = (type: Ast.DecodedType): Ast.DecodedType => { @@ -373,7 +376,9 @@ export const substituteTypeArgs = ( case "TypeParam": { const arg = substMap.get(type.name.text); if (!arg) { - return throwInternal("Decoder didn't scope alias's type args"); + return throwInternal( + "Decoder didn't scope alias's type args", + ); } return arg; } @@ -382,12 +387,22 @@ export const substituteTypeArgs = ( return Ast.DTypeRef(type.name, type.type, args, type.loc); } case "TypeAlias": { - if (type.type.kind === 'NotDealiased') { + if (type.type.kind === "NotDealiased") { const args = recN(type.typeArgs); - return Ast.DTypeAliasRef(type.type, type.name, args, type.loc); + return Ast.DTypeAliasRef( + type.type, + type.name, + args, + type.loc, + ); } else { const args = recN(type.typeArgs); // ?? - return Ast.DTypeAliasRef(rec(type.type), type.name, args, type.loc); + return Ast.DTypeAliasRef( + rec(type.type), + type.name, + args, + type.loc, + ); } } case "map_type": { @@ -435,7 +450,9 @@ export function* instantiateStruct( // NB! these are type params from enclosing scope typeParams: Ast.TypeParams, scopeRef: () => Ast.Scope, -): Ast.WithLog }> { +): Ast.WithLog< + undefined | { type: Ast.DTypeRef; fields: Ast.Ordered } +> { const decl = scopeRef().typeDecls.get(typeName.text); switch (decl?.decl.kind) { case undefined: { @@ -453,9 +470,10 @@ export function* instantiateStruct( } case "struct": case "message": { - const declArity = decl.decl.kind === "message" - ? 0 - : decl.decl.typeParams.order.length; + const declArity = + decl.decl.kind === "message" + ? 0 + : decl.decl.typeParams.order.length; const useArity = typeArgs.length; if (declArity !== useArity) { yield ETypeArity( @@ -467,13 +485,8 @@ export function* instantiateStruct( return undefined; } return { - type: Ast.DTypeRef( - typeName, - decl.decl, - typeArgs, - typeName.loc, - ), - fields: decl.decl.fields + type: Ast.DTypeRef(typeName, decl.decl, typeArgs, typeName.loc), + fields: decl.decl.fields, }; } case "alias": { @@ -497,7 +510,7 @@ export function* instantiateStruct( ), scopeRef, ); - if (type.kind !== 'type_ref') { + if (type.kind !== "type_ref") { yield ENotInstantiable(typeName.text, typeName.loc); return undefined; } @@ -512,33 +525,36 @@ export function* instantiateStruct( } const ENoSuchType = (name: string, loc: Ast.Loc): Ast.TcError => ({ loc, - descr: [ - Ast.TEText(`Type ${name} is not defined`), - ], + descr: [Ast.TEText(`Type ${name} is not defined`)], }); const ENotInstantiable = (name: string, loc: Ast.Loc): Ast.TcError => ({ loc, - descr: [ - Ast.TEText(`Cannot create value of type ${name}`), - ], + descr: [Ast.TEText(`Cannot create value of type ${name}`)], }); -const ETypeArity = (name: string, loc: Ast.Loc, declArity: number, useArity: number): Ast.TcError => ({ +const ETypeArity = ( + name: string, + loc: Ast.Loc, + declArity: number, + useArity: number, +): Ast.TcError => ({ loc, descr: [ - Ast.TEText(`Type ${name} expects ${declArity} arguments, got ${useArity}`), + Ast.TEText( + `Type ${name} expects ${declArity} arguments, got ${useArity}`, + ), ], }); export function typeParamsToSubst(typeParams: Ast.TypeParams) { const subst: Map = new Map( - typeParams.order.map(name => [name.text, Ast.DNotSet()]) + typeParams.order.map((name) => [name.text, Ast.DNotSet()]), ); return subst; } export function* substToTypeArgMap( loc: Ast.Loc, - subst: Map + subst: Map, ): Ast.WithLog { const res = substToTypeArgMapAux(subst); if (res.ok) { @@ -552,12 +568,12 @@ export function* substToTypeArgMap( } function substToTypeArgMapAux( - subst: Map -): { ok: true, args: Ast.TypeArgs} | { ok: false, names: readonly string[] } { + subst: Map, +): { ok: true; args: Ast.TypeArgs } | { ok: false; names: readonly string[] } { const args: Map = new Map(); const names: string[] = []; for (const [name, type] of subst) { - if (type.kind === 'not-set') { + if (type.kind === "not-set") { names.push(name); } else { args.set(name, type); @@ -579,7 +595,7 @@ export function* assignType( ): Ast.WithLog { const subst = typeParamsToSubst(toFreeTypeParam); const result = assignTypeAux(to, from, subst, strict); - if (result.kind === 'failure') { + if (result.kind === "failure") { yield EMismatch(result.tree, loc); return undefined; } @@ -587,28 +603,24 @@ export function* assignType( } const EFreeTypeParam = (paramName: string, loc: Ast.Loc): Ast.TcError => ({ loc, - descr: [ - Ast.TEText(`No substitution for type parameter "${paramName}"`), - ], + descr: [Ast.TEText(`No substitution for type parameter "${paramName}"`)], }); const EMismatch = (tree: Ast.MatchTree, loc: Ast.Loc): Ast.TcError => ({ loc, - descr: [ - Ast.TEText(`Type mismatch`), - Ast.TEMismatch(tree), - ], + descr: [Ast.TEText(`Type mismatch`), Ast.TEMismatch(tree)], }); -type AssignResult = AssignSuccess | AssignFailure +type AssignResult = AssignSuccess | AssignFailure; type AssignSuccess = { - readonly kind: 'success'; -} -const AssignSuccess = (): AssignSuccess => Object.freeze({ kind: 'success' }); + readonly kind: "success"; +}; +const AssignSuccess = (): AssignSuccess => Object.freeze({ kind: "success" }); type AssignFailure = { - readonly kind: 'failure'; + readonly kind: "failure"; readonly tree: Ast.MatchTree; -} -const AssignFailure = (tree: Ast.MatchTree): AssignFailure => Object.freeze({ kind: 'failure', tree }); +}; +const AssignFailure = (tree: Ast.MatchTree): AssignFailure => + Object.freeze({ kind: "failure", tree }); type Log = Generator; @@ -623,7 +635,9 @@ export function assignTypeAux( froms: readonly Ast.DecodedType[], ): Log { if (tos.length !== froms.length) { - return throwInternal("Arg count does not match after type decoding"); + return throwInternal( + "Arg count does not match after type decoding", + ); } let result = true; for (const [to, from] of zip(tos, froms)) { @@ -635,12 +649,9 @@ export function assignTypeAux( return result; } - function* rec( - to: Ast.DecodedType, - from: Ast.DecodedType, - ): Log { + function* rec(to: Ast.DecodedType, from: Ast.DecodedType): Log { const result = collectMismatches(to, from); - if (result.kind === 'failure') { + if (result.kind === "failure") { yield result.tree; return false; } @@ -653,7 +664,7 @@ export function assignTypeAux( ): AssignResult { const gen = check(to, from); const results: Ast.MatchTree[] = []; - for (; ;) { + for (;;) { const res = gen.next(); if (!res.done) { // collect all errors (if any) @@ -674,12 +685,9 @@ export function assignTypeAux( } } - function* check( - to: Ast.DecodedType, - from: Ast.DecodedType, - ): Log { - if (from.kind === 'TypeAlias') { - if (from.type.kind === 'NotDealiased') { + function* check(to: Ast.DecodedType, from: Ast.DecodedType): Log { + if (from.kind === "TypeAlias") { + if (from.type.kind === "NotDealiased") { return throwInternal("Decoder returned aliased type"); } from = from.type; @@ -690,7 +698,7 @@ export function assignTypeAux( return true; } case "TypeAlias": { - if (to.type.kind === 'NotDealiased') { + if (to.type.kind === "NotDealiased") { return throwInternal("Decoder returned aliased type"); } to = to.type; @@ -699,10 +707,12 @@ export function assignTypeAux( case "type_ref": { const typeVar = subst.get(to.name.text); if (!typeVar) { - return to.kind === from.kind && + return ( + to.kind === from.kind && to.name.text === from.name.text && - (yield* recN(to.typeArgs, from.typeArgs)); - } else if (typeVar.kind === 'not-set') { + (yield* recN(to.typeArgs, from.typeArgs)) + ); + } else if (typeVar.kind === "not-set") { subst.set(to.name.text, from); return true; } else { @@ -711,27 +721,30 @@ export function assignTypeAux( } case "tuple_type": case "tensor_type": { - return to.kind === from.kind && - (yield* recN(to.typeArgs, from.typeArgs)); + return ( + to.kind === from.kind && + (yield* recN(to.typeArgs, from.typeArgs)) + ); } case "TypeParam": { - return to.kind === from.kind && - to.name.text === from.name.text; + return to.kind === from.kind && to.name.text === from.name.text; } case "TypeBounced": { - return to.kind === from.kind && - to.name.text === from.name.text; + return to.kind === from.kind && to.name.text === from.name.text; } case "TypeMaybe": { - return !strict && from.kind === 'TypeNull' || - to.kind === from.kind && - (yield* rec(to.type, from.type)); + return ( + (!strict && from.kind === "TypeNull") || + (to.kind === from.kind && (yield* rec(to.type, from.type))) + ); } case "map_type": { - return !strict && from.kind === 'TypeNull' || - to.kind === from.kind && - (yield* rec(to.key, from.key)) && - (yield* rec(to.value, from.value)); + return ( + (!strict && from.kind === "TypeNull") || + (to.kind === from.kind && + (yield* rec(to.key, from.key)) && + (yield* rec(to.value, from.value))) + ); } case "TyInt": case "TySlice": @@ -762,32 +775,32 @@ export function* mgu( left: Ast.DecodedType, right: Ast.DecodedType, ): Ast.WithLog { - if (right.kind === 'TypeAlias') { - if (right.type.kind === 'NotDealiased') { + if (right.kind === "TypeAlias") { + if (right.type.kind === "NotDealiased") { return throwInternal("Decoder returned aliased type"); } right = right.type; return yield* rec(left, right); } - if (left.kind === 'TypeAlias') { - if (left.type.kind === 'NotDealiased') { + if (left.kind === "TypeAlias") { + if (left.type.kind === "NotDealiased") { return throwInternal("Decoder returned aliased type"); } left = left.type; return yield* rec(left, left); } const resultL = assignTypeAux(left, right, new Map(), false); - if (resultL.kind === 'success') { + if (resultL.kind === "success") { return left; } const resultR = assignTypeAux(right, left, new Map(), false); - if (resultR.kind === 'success') { + if (resultR.kind === "success") { return right; } - if (right.kind === 'TypeNull') { + if (right.kind === "TypeNull") { return Ast.DTypeMaybe(left, loc); } - if (left.kind === 'TypeNull') { + if (left.kind === "TypeNull") { return Ast.DTypeMaybe(right, loc); } yield ENotUnifiable(resultL.tree, loc); @@ -807,7 +820,7 @@ const ENotUnifiable = (tree: Ast.MatchTree, loc: Ast.Loc): Ast.TcError => ({ export type CallResult = { readonly returnType: Ast.DecodedType; readonly typeArgMap: Ast.TypeArgs; -} +}; export function* checkFnCall( loc: Ast.Loc, @@ -825,24 +838,15 @@ export function* checkFnCall( break; } const [argLoc, arg] = pair; - const result = assignTypeAux( - yield* type(), - arg, - subst, - false, - ); - if (result.kind === 'failure') { - yield EMismatchArg( - getParamName(name, index), - result.tree, - argLoc, - ); + const result = assignTypeAux(yield* type(), arg, subst, false); + if (result.kind === "failure") { + yield EMismatchArg(getParamName(name, index), result.tree, argLoc); } } // not enough or too many args if (params.order.length !== args.length) { - yield EFnArity('Function', params.order.length, args.length, loc); + yield EFnArity("Function", params.order.length, args.length, loc); } const typeArgsMap = yield* substToTypeArgMap(loc, subst); @@ -871,7 +875,11 @@ export function* checkFnCall( return { returnType: retType, typeArgMap: typeArgsMap }; } -const EMismatchArg = (name: string, tree: Ast.MatchTree, loc: Ast.Loc): Ast.TcError => ({ +const EMismatchArg = ( + name: string, + tree: Ast.MatchTree, + loc: Ast.Loc, +): Ast.TcError => ({ loc, descr: [ Ast.TEText(`Type doesn't match type of parameter ${name}`), @@ -880,7 +888,7 @@ const EMismatchArg = (name: string, tree: Ast.MatchTree, loc: Ast.Loc): Ast.TcEr }); function getParamName(name: Ast.OptionalId, index: number) { - return name.kind === 'id' ? name.text : `#${index + 1}`; + return name.kind === "id" ? name.text : `#${index + 1}`; } const EFnArity = ( @@ -891,7 +899,9 @@ const EFnArity = ( ): Ast.TcError => ({ loc, descr: [ - Ast.TEText(`${kind} is expected to have ${expected} type arguments, got ${got}`), + Ast.TEText( + `${kind} is expected to have ${expected} type arguments, got ${got}`, + ), ], }); @@ -907,7 +917,7 @@ export function* checkFnCallWithArgs( return { returnType: Ast.DTypeRecover(), typeArgMap: new Map() }; } if (ascribedTypeArgs.length === 0) { - return yield* checkFnCall(loc, fnType, args) + return yield* checkFnCall(loc, fnType, args); } if (fnType.typeParams.order.length !== ascribedTypeArgs.length) { return { returnType: Ast.DTypeRecover(), typeArgMap: new Map() }; @@ -920,50 +930,56 @@ export function* checkFnCallWithArgs( return { returnType: result.returnType, typeArgMap: new Map( - zip(fnType.typeParams.order, args) - .map(([name, [, type]]) => [name.text, type]), + zip(fnType.typeParams.order, args).map(([name, [, type]]) => [ + name.text, + type, + ]), ), }; } const ENoFunction = (loc: Ast.Loc): Ast.TcError => ({ loc, - descr: [ - Ast.TEText(`No such function`), - Ast.TECode(loc), - ], + descr: [Ast.TEText(`No such function`), Ast.TECode(loc)], }); function substFnType( Lazy: Ast.ThunkBuilder, fnLoc: Ast.Loc, - { typeParams, params, returnType }: Ast.DecodedFnType | Ast.DecodedMethodType, + { + typeParams, + params, + returnType, + }: Ast.DecodedFnType | Ast.DecodedMethodType, args: readonly Ast.DecodedType[], ) { const order: Ast.Parameter[] = []; for (const [index, param] of params.order.entries()) { - order.push(Ast.Parameter( - param.name, - Lazy({ - callback: function* () { - return substituteTypeArgs( - yield* param.type(), - typeParams, - args, - ); - }, - context: [Ast.TEText(`substituting into parameter ${getParamName(param.name, index)}`)], - loc: param.loc, - recover: Ast.DTypeRecover(), - }), - param.loc, - )); + order.push( + Ast.Parameter( + param.name, + Lazy({ + callback: function* () { + return substituteTypeArgs( + yield* param.type(), + typeParams, + args, + ); + }, + context: [ + Ast.TEText( + `substituting into parameter ${getParamName(param.name, index)}`, + ), + ], + loc: param.loc, + recover: Ast.DTypeRecover(), + }), + param.loc, + ), + ); } return Ast.DecodedFnType( emptyTypeParams, - Ast.Parameters( - order, - params.set - ), + Ast.Parameters(order, params.set), Lazy({ callback: function* () { return substituteTypeArgs( @@ -986,13 +1002,13 @@ export function* lookupMethod( args: readonly (readonly [Ast.Loc, Ast.DecodedType])[], typeDecls: ReadonlyMap>, extensions: ReadonlyMap[]>>, -): Ast.WithLog { - if (selfType.kind === 'recover') { +): Ast.WithLog { + if (selfType.kind === "recover") { return { returnType: Ast.DTypeRecover(), typeArgMap: new Map() }; } - if (selfType.kind === 'TypeAlias') { - if (selfType.type.kind === 'NotDealiased') { - return throwInternal("Calling method on non-dealiased type") + if (selfType.kind === "TypeAlias") { + if (selfType.type.kind === "NotDealiased") { + return throwInternal("Calling method on non-dealiased type"); } return yield* lookupMethod( @@ -1005,14 +1021,8 @@ export function* lookupMethod( ); } - if (selfType.kind !== 'type_ref') { - return yield* lookupExts( - Lazy, - selfType, - method, - args, - extensions, - ); + if (selfType.kind !== "type_ref") { + return yield* lookupExts(Lazy, selfType, method, args, extensions); } const selfDecl = typeDecls.get(selfType.name.text); @@ -1020,36 +1030,25 @@ export function* lookupMethod( yield ENoMethod(method.loc); return { returnType: Ast.DTypeRecover(), typeArgMap: new Map() }; } - - if (selfDecl.decl.kind === 'struct' || selfDecl.decl.kind === 'message') { - const builtinMap = selfDecl.decl.kind === 'struct' - ? structBuiltin - : messageBuiltin; + + if (selfDecl.decl.kind === "struct" || selfDecl.decl.kind === "message") { + const builtinMap = + selfDecl.decl.kind === "struct" ? structBuiltin : messageBuiltin; const builtin = builtinMap.get(method.text); if (builtin) { return yield* checkFnCall(method.loc, builtin, args); } - return yield* lookupExts( - Lazy, - selfType, - method, - args, - extensions, - ); + return yield* lookupExts(Lazy, selfType, method, args, extensions); } - - if (selfDecl.decl.kind === 'contract' || selfDecl.decl.kind === 'trait') { + + if (selfDecl.decl.kind === "contract" || selfDecl.decl.kind === "trait") { const content = yield* selfDecl.decl.content(); const met = content.methods.get(method.text); if (!met) { yield ENoMethod(method.loc); return { returnType: Ast.DTypeRecover(), typeArgMap: new Map() }; } - return yield* checkFnCall( - method.loc, - met.decl.type, - args - ); + return yield* checkFnCall(method.loc, met.decl.type, args); } yield ENoMethod(method.loc); @@ -1069,21 +1068,19 @@ function* lookupExts( return { returnType: Ast.DTypeRecover(), typeArgMap: new Map() }; } const exts = yield* lazyExts(); - const grounds: [Ast.DecodedMethodType, Ast.TypeArgs][] = [] - const withVars: [Ast.DecodedMethodType, Ast.TypeArgs][] = [] + const grounds: [Ast.DecodedMethodType, Ast.TypeArgs][] = []; + const withVars: [Ast.DecodedMethodType, Ast.TypeArgs][] = []; for (const { decl } of exts) { const subst = typeParamsToSubst(decl.type.typeParams); const result = assignTypeAux(decl.type.self, selfType, subst, true); - if (result.kind !== 'success') { + if (result.kind !== "success") { continue; } const res = substToTypeArgMapAux(subst); if (!res.ok) { continue; } - const into = decl.type.self.ground - ? grounds - : withVars; + const into = decl.type.self.ground ? grounds : withVars; into.push([decl.type, res.args]); } if (grounds.length > 1 || withVars.length > 1) { @@ -1105,7 +1102,7 @@ function* lookupExts( methodType, typeArgsToParams(typeArgs, methodType.typeParams), ), - args + args, ); return { returnType: result.returnType, @@ -1113,10 +1110,7 @@ function* lookupExts( }; } -function typeArgsToParams( - args: Ast.TypeArgs, - params: Ast.TypeParams, -) { +function typeArgsToParams(args: Ast.TypeArgs, params: Ast.TypeParams) { const result: Ast.DecodedType[] = []; for (const name of params.order) { const arg = args.get(name.text); @@ -1130,54 +1124,58 @@ function typeArgsToParams( const ENoMethod = (loc: Ast.Loc): Ast.TcError => ({ loc, - descr: [ - Ast.TEText(`No such method`), - Ast.TECode(loc), - ], + descr: [Ast.TEText(`No such method`), Ast.TECode(loc)], }); export function* assignMethodType( prev: Ast.DecodedMethodType, next: Ast.DecodedMethodType, prevVia: Ast.ViaMember, - nextVia: Ast.ViaMember + nextVia: Ast.ViaMember, ): Ast.WithLog { const result = assignTypeAux( - yield* prev.returnType(), - yield* next.returnType(), - new Map(), - true + yield* prev.returnType(), + yield* next.returnType(), + new Map(), + true, ); - if (result.kind === 'failure') { + if (result.kind === "failure") { yield EMismatchReturn(result.tree, prevVia.defLoc, nextVia.defLoc); return undefined; } const prevArity = prev.params.order.length; const nextArity = next.params.order.length; - for (const [index, [prevParam, nextParam]] of zip(prev.params.order, next.params.order).entries()) { + for (const [index, [prevParam, nextParam]] of zip( + prev.params.order, + next.params.order, + ).entries()) { const result = assignTypeAux( - yield* prevParam.type(), - yield* nextParam.type(), - new Map(), - true + yield* prevParam.type(), + yield* nextParam.type(), + new Map(), + true, ); - if (result.kind === 'failure') { + if (result.kind === "failure") { yield EMismatchParam( getParamName(nextParam.name, index), - result.tree, - prevVia.defLoc, + result.tree, + prevVia.defLoc, nextVia.defLoc, ); } } if (prevArity !== nextArity) { - yield EFnArity('Method', prevArity, nextArity, nextVia.defLoc) + yield EFnArity("Method", prevArity, nextArity, nextVia.defLoc); } } -const EMismatchReturn = (tree: Ast.MatchTree, prev: Ast.Loc, next: Ast.Loc): Ast.TcError => ({ +const EMismatchReturn = ( + tree: Ast.MatchTree, + prev: Ast.Loc, + next: Ast.Loc, +): Ast.TcError => ({ loc: next, descr: [ Ast.TEText(`Return type doesn't match with inherited method`), @@ -1189,14 +1187,21 @@ const EMismatchReturn = (tree: Ast.MatchTree, prev: Ast.Loc, next: Ast.Loc): Ast ], }); -const EMismatchParam = (name: string, tree: Ast.MatchTree, prev: Ast.Loc, next: Ast.Loc): Ast.TcError => ({ +const EMismatchParam = ( + name: string, + tree: Ast.MatchTree, + prev: Ast.Loc, + next: Ast.Loc, +): Ast.TcError => ({ loc: next, descr: [ - Ast.TEText(`Type of parameter ${name} doesn't match with inherited method`), + Ast.TEText( + `Type of parameter ${name} doesn't match with inherited method`, + ), Ast.TEMismatch(tree), Ast.TEText(`Inherited from:`), Ast.TECode(prev), Ast.TEText(`Override at:`), Ast.TECode(next), ], -}); \ No newline at end of file +}); diff --git a/src/next/types/typecheck.ts b/src/next/types/typecheck.ts index 75957240de..fb2932b8f2 100644 --- a/src/next/types/typecheck.ts +++ b/src/next/types/typecheck.ts @@ -4,7 +4,11 @@ // import { logDeep } from "@/utils/log-deep.build"; import * as Ast from "@/next/ast"; import { memo } from "@/utils/tricks"; -import type { ResolvedImport, TactImport, TactSource } from "@/next/imports/source"; +import type { + ResolvedImport, + TactImport, + TactSource, +} from "@/next/imports/source"; import { decodeTypeDecls } from "@/next/types/typedecl"; import { decodeFunctions } from "@/next/types/functions"; import { decodeConstants } from "@/next/types/constants"; @@ -14,15 +18,16 @@ export const typecheck = (root: TactSource): [Ast.Scope, Ast.TcError[]] => { const allErrors: Ast.TcError[] = []; const recur = memo((source: TactSource): Ast.Scope => { - const [value, errors] = Ast.runLog(tcSource( - // leave only imports of .tact - onlyTactImports(source.imports) - .map(importedBy => ({ + const [value, errors] = Ast.runLog( + tcSource( + // leave only imports of .tact + onlyTactImports(source.imports).map((importedBy) => ({ globals: recur(importedBy.source), importedBy, })), - source, - )); + source, + ), + ); // `recur` is called only once on every source // this ensures errors from every source get counted // only once @@ -33,12 +38,14 @@ export const typecheck = (root: TactSource): [Ast.Scope, Ast.TcError[]] => { return [recur(root), allErrors]; }; -const onlyTactImports = (imports: readonly ResolvedImport[]): readonly TactImport[] => { +const onlyTactImports = ( + imports: readonly ResolvedImport[], +): readonly TactImport[] => { // typescript narrowing doesn't properly apply to filter, // so we need this helper const result: TactImport[] = []; for (const imp of imports) { - if (imp.kind === 'tact') { + if (imp.kind === "tact") { result.push(imp); } } @@ -58,6 +65,6 @@ function* tcSource( functions: yield* decodeFunctions(Lazy, imported, source, scopeRef), constants: yield* decodeConstants(Lazy, imported, source, scopeRef), extensions: decodeExtensions(Lazy, imported, source, scopeRef), - } + }; return scope; -} \ No newline at end of file +} diff --git a/src/next/types/typedecl.ts b/src/next/types/typedecl.ts index d2f512c68f..d04ae2881c 100644 --- a/src/next/types/typedecl.ts +++ b/src/next/types/typedecl.ts @@ -10,7 +10,7 @@ import { decodeStruct } from "@/next/types/struct"; import { decodeMessage } from "@/next/types/message"; import { decodeUnion } from "@/next/types/union"; -const errorKind = 'type'; +const errorKind = "type"; export function* decodeTypeDecls( Lazy: Ast.ThunkBuilder, @@ -18,26 +18,27 @@ export function* decodeTypeDecls( source: TactSource, scopeRef: () => Ast.Scope, ): Ast.WithLog>> { - const importedSigs = imported.map(({ globals, importedBy }) => ( - new Map( - globals.typeDecls.entries() - .map(([name, s]) => [name, Ast.Decl(s.decl, Ast.ViaImport(importedBy, s.via))]) - ) - )); + const importedSigs = imported.map( + ({ globals, importedBy }) => + new Map( + globals.typeDecls + .entries() + .map(([name, s]) => [ + name, + Ast.Decl(s.decl, Ast.ViaImport(importedBy, s.via)), + ]), + ), + ); - const localSigs = yield* Ast.mapLog( - source.items.types, - function* (decl) { - const via = Ast.ViaOrigin(decl.loc, source); - return new Map([[ + const localSigs = yield* Ast.mapLog(source.items.types, function* (decl) { + const via = Ast.ViaOrigin(decl.loc, source); + return new Map([ + [ decl.name.text, - Ast.Decl( - yield* decodeTypeDecl(Lazy, decl, scopeRef), - via, - ), - ]]); - }, - ); + Ast.Decl(yield* decodeTypeDecl(Lazy, decl, scopeRef), via), + ], + ]); + }); const prev: Map> = new Map(); for (const next of [...importedSigs, ...localSigs]) { @@ -45,17 +46,27 @@ export function* decodeTypeDecls( const prevItem = prev.get(name); // defined in compiler if (builtinTypes.has(name)) { - yield Ast.ERedefine(errorKind, name, Ast.ViaBuiltin(), nextItem.via); + yield Ast.ERedefine( + errorKind, + name, + Ast.ViaBuiltin(), + nextItem.via, + ); continue; } // not defined yet; define it now - if (typeof prevItem === 'undefined') { + if (typeof prevItem === "undefined") { prev.set(name, nextItem); continue; } // already defined, and it's not a diamond situation if (prevItem.via.source !== nextItem.via.source) { - yield Ast.ERedefine(errorKind, name, prevItem.via, nextItem.via); + yield Ast.ERedefine( + errorKind, + name, + prevItem.via, + nextItem.via, + ); } } } diff --git a/src/next/types/union.ts b/src/next/types/union.ts index 1f58c2e5ea..5d4c7621b5 100644 --- a/src/next/types/union.ts +++ b/src/next/types/union.ts @@ -2,13 +2,13 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ import * as Ast from "@/next/ast"; import { decodeInitializerLazy } from "@/next/types/struct-fields"; -import { decodeTypeLazy } from "@/next/types/type"; +import { decodeTypeLazy } from "@/next/types/type"; import { decodeTypeParams } from "@/next/types/type-params"; type Cons = { readonly fields: ReadonlyMap; readonly loc: Ast.Loc; -} +}; export function* decodeUnion( Lazy: Ast.ThunkBuilder, @@ -16,13 +16,13 @@ export function* decodeUnion( scopeRef: () => Ast.Scope, ): Ast.WithLog { const typeParams = yield* decodeTypeParams(union.typeParams); - + const cases: Map = new Map(); for (const cons of union.cases) { const caseName = cons.name.text; const prevCons = cases.get(caseName); if (prevCons) { - yield EDuplicateCons(caseName, prevCons.loc, cons.name.loc) + yield EDuplicateCons(caseName, prevCons.loc, cons.name.loc); continue; } const fields: Map = new Map(); @@ -31,12 +31,12 @@ export function* decodeUnion( const prevField = fields.get(fieldName); if (prevField) { const [, prevFieldLoc] = prevField; - yield EDuplicateField(fieldName, prevFieldLoc, field.name.loc) + yield EDuplicateField(fieldName, prevFieldLoc, field.name.loc); } const ascribedType = decodeTypeLazy( Lazy, - typeParams, - field.type, + typeParams, + field.type, scopeRef, ); @@ -51,12 +51,12 @@ export function* decodeUnion( ); const decoded = Ast.InhFieldSig(ascribedType, lazyExpr); - fields.set(fieldName, [decoded, field.name.loc]) + fields.set(fieldName, [decoded, field.name.loc]); } cases.set(caseName, { fields: new Map([...fields].map(([name, [type]]) => [name, type])), loc: cons.name.loc, - }) + }); } const map = new Map([...cases].map(([name, { fields }]) => [name, fields])); @@ -91,4 +91,4 @@ const EDuplicateField = ( Ast.TEText(`Previously defined at:`), Ast.TECode(prev), ], -}); \ No newline at end of file +}); diff --git a/src/next/types/value.ts b/src/next/types/value.ts index 57880e8b0a..37a7d41c1b 100644 --- a/src/next/types/value.ts +++ b/src/next/types/value.ts @@ -2,21 +2,16 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ import * as Ast from "@/next/ast"; -export function convertValueToExpr( - node: Ast.Value -): Ast.DecodedExpression { +export function convertValueToExpr(node: Ast.Value): Ast.DecodedExpression { switch (node.kind) { // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition - case 'number': { + case "number": { return Ast.DNumber( "10", node.value, - Ast.TypeInt( - Ast.IFInt("signed", 257, node.loc), - node.loc - ), + Ast.TypeInt(Ast.IFInt("signed", 257, node.loc), node.loc), node.loc, ); } } -} \ No newline at end of file +} diff --git a/src/utils/array.ts b/src/utils/array.ts index 50a25d1a89..9cf0dfd66e 100644 --- a/src/utils/array.ts +++ b/src/utils/array.ts @@ -1,4 +1,7 @@ -export const mapValues = (map: Map, f: (a: A) => B): Map => { +export const mapValues = ( + map: Map, + f: (a: A) => B, +): Map => { const result: [K, B][] = []; for (const [k, a] of map) { result.push([k, f(a)]); diff --git a/src/utils/log-deep.build.ts b/src/utils/log-deep.build.ts index 1b2fd9900b..1182f46e9a 100644 --- a/src/utils/log-deep.build.ts +++ b/src/utils/log-deep.build.ts @@ -2,8 +2,10 @@ import { inspect } from "util"; // log json to terminal without shortening export const logDeep = (obj: unknown, colors = true) => { - console.log(inspect(obj, { - colors, - depth: Infinity, - })); + console.log( + inspect(obj, { + colors, + depth: Infinity, + }), + ); }; diff --git a/src/utils/tricks.ts b/src/utils/tricks.ts index ea43b6d97c..2445308e03 100644 --- a/src/utils/tricks.ts +++ b/src/utils/tricks.ts @@ -26,9 +26,9 @@ interface NonExhaustiveBug { type End = [I] extends [never] ? EndInternal : { - otherwise: (handle: (...input: I) => DO) => O | DO; - end: NonExhaustiveBug; - }; + otherwise: (handle: (...input: I) => DO) => O | DO; + end: NonExhaustiveBug; + }; type MV = End & On; type OnInternal = { @@ -75,14 +75,14 @@ export const match = ( otherwise: (handler) => handler(...(args as unknown as I)), on: (...match: DI) => - (handler: (...args: Extract>) => DO) => - rec>, O | DO>(() => - deepMatch(args, match) - ? handler( - ...(args as unknown as Extract>), - ) - : end(), - ), + (handler: (...args: Extract>) => DO) => + rec>, O | DO>(() => + deepMatch(args, match) + ? handler( + ...(args as unknown as Extract>), + ) + : end(), + ), }); return rec, never>(() => { throw new Error("Not exhaustive"); @@ -108,8 +108,8 @@ export type Unwrap = T extends infer R ? { [K in keyof R]: R[K] } : never; type Inputs = I extends { [Z in T]: infer K } ? K extends string - ? Record unknown> - : never + ? Record unknown> + : never : never; type Outputs = { [K in keyof O]: (input: never) => O[K] }; type Handlers = Unwrap>> & @@ -117,22 +117,22 @@ type Handlers = Unwrap>> & export const makeMakeVisitor = (tag: T) => - () => - (handlers: Handlers) => - (input: Extract): O[keyof O] => { - const handler = (handlers as Record O[keyof O]>)[ - input[tag] - ]; - - // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition - if (handler) { - return handler(input); - } else { - throwInternalCompilerError( - `Reached impossible case: ${input[tag]}`, - ); - } - }; + () => + (handlers: Handlers) => + (input: Extract): O[keyof O] => { + const handler = (handlers as Record O[keyof O]>)[ + input[tag] + ]; + + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + if (handler) { + return handler(input); + } else { + throwInternalCompilerError( + `Reached impossible case: ${input[tag]}`, + ); + } + }; /** * Make visitor for disjoint union (tagged union, discriminated union) @@ -153,7 +153,7 @@ export const memo = (f: (a: A) => B) => { const cache: Map = new Map(); return (a: A): B => { const mem = cache.get(a); - if (typeof mem !== 'undefined') { + if (typeof mem !== "undefined") { return mem; } const b = f(a); From 9808d375908b1b5317a49664c2ef46e6d954c672 Mon Sep 17 00:00:00 2001 From: verytactical <186486509+verytactical@users.noreply.github.com> Date: Thu, 5 Jun 2025 05:48:31 +0400 Subject: [PATCH 36/38] 1 --- spell/cspell-list.txt | 1 + src/next/ast/checked-expr.ts | 61 ++-- src/next/ast/checked-type.ts | 89 +++++ src/next/ast/checked.ts | 234 +++++++------ src/next/ast/dtype.ts | 107 ------ src/next/ast/effects.ts | 19 +- src/next/ast/errors.ts | 10 +- src/next/ast/expression.ts | 4 +- src/next/ast/generated/checked-expr.ts | 70 ++-- src/next/ast/generated/checked-type.ts | 129 +++++++ src/next/ast/generated/checked.ts | 354 +++++++++----------- src/next/ast/generated/dtype.ts | 129 ------- src/next/ast/generated/effects.ts | 13 +- src/next/ast/generated/expression.ts | 2 +- src/next/ast/generated/lowered.ts | 254 ++++++++++++++ src/next/ast/generated/mtype.ts | 157 --------- src/next/ast/generated/root.ts | 2 +- src/next/ast/generated/type-basic.ts | 131 ++++++++ src/next/ast/generated/type-self.ts | 142 ++++++++ src/next/ast/generated/type.ts | 204 ++--------- src/next/ast/index.ts | 12 +- src/next/ast/lowered-expr.ts | 228 +++++++++++++ src/next/ast/lowered-stmt.ts | 125 +++++++ src/next/ast/lowered-type.ts | 80 +++++ src/next/ast/lowered.ts | 30 +- src/next/ast/mtype.ts | 124 ------- src/next/ast/root.ts | 4 +- src/next/ast/type-basic.ts | 107 ++++++ src/next/ast/type-self.ts | 103 ++++++ src/next/ast/type.ts | 141 ++------ src/next/grammar/index.ts | 322 +++++++++--------- src/next/types/alias.ts | 6 +- src/next/types/body.ts | 60 ++-- src/next/types/builtins.ts | 85 ++--- src/next/types/constant-def.ts | 16 +- src/next/types/constants.ts | 14 +- src/next/types/contract.ts | 54 +-- src/next/types/effects.ts | 126 +++---- src/next/types/expr-eval.ts | 2 +- src/next/types/expression.ts | 447 ++++++++++++++++--------- src/next/types/extensions.ts | 120 +++---- src/next/types/fields.ts | 26 +- src/next/types/functions.ts | 10 +- src/next/types/lvalue.ts | 17 +- src/next/types/message.ts | 14 +- src/next/types/methods.ts | 36 +- src/next/types/override.ts | 8 +- src/next/types/receivers.ts | 56 ++-- src/next/types/statements.ts | 322 +++++++++--------- src/next/types/struct-fields.ts | 20 +- src/next/types/struct.ts | 6 +- src/next/types/trait.ts | 12 +- src/next/types/traits-scope.ts | 6 +- src/next/types/type-fn.ts | 18 +- src/next/types/type-params.ts | 6 +- src/next/types/type-print.ts | 84 ++--- src/next/types/type.ts | 333 +++++++++--------- src/next/types/typecheck.ts | 12 +- src/next/types/typedecl.ts | 10 +- src/next/types/union.ts | 12 +- src/next/types/value.ts | 2 +- 61 files changed, 3027 insertions(+), 2301 deletions(-) create mode 100644 src/next/ast/checked-type.ts delete mode 100644 src/next/ast/dtype.ts create mode 100644 src/next/ast/generated/checked-type.ts delete mode 100644 src/next/ast/generated/dtype.ts create mode 100644 src/next/ast/generated/lowered.ts delete mode 100644 src/next/ast/generated/mtype.ts create mode 100644 src/next/ast/generated/type-basic.ts create mode 100644 src/next/ast/generated/type-self.ts create mode 100644 src/next/ast/lowered-expr.ts create mode 100644 src/next/ast/lowered-stmt.ts create mode 100644 src/next/ast/lowered-type.ts delete mode 100644 src/next/ast/mtype.ts create mode 100644 src/next/ast/type-basic.ts create mode 100644 src/next/ast/type-self.ts diff --git a/spell/cspell-list.txt b/spell/cspell-list.txt index f9ba1418f3..59f431d75f 100644 --- a/spell/cspell-list.txt +++ b/spell/cspell-list.txt @@ -216,6 +216,7 @@ Topup Tradoor Trunov typechecker +typedecl udict uintptr uints diff --git a/src/next/ast/checked-expr.ts b/src/next/ast/checked-expr.ts index e49d555ea4..763d4cf6bb 100644 --- a/src/next/ast/checked-expr.ts +++ b/src/next/ast/checked-expr.ts @@ -1,21 +1,20 @@ import type { Ordered, Recover } from "@/next/ast/checked"; import type { Id, Loc, TypeId } from "@/next/ast/common"; -import type * as D from "@/next/ast/dtype"; +import type * as D from "@/next/ast/checked-type"; import type { BinaryOperation, NumberBase, UnaryOperation, } from "@/next/ast/expression"; -import type { SelfType } from "@/next/ast/mtype"; +import type { SelfType } from "@/next/ast/type-self"; -export type TypeArgs = ReadonlyMap; +export type TypeArgs = ReadonlyMap; export type DecodedExpression = | DOpBinary | DOpUnary | DConditional | DMethodCall - | DThrowCall | DStaticCall | DStaticMethodCall | DFieldAccess @@ -45,7 +44,7 @@ export type LSelf = { export type LVar = { readonly kind: "var"; readonly name: string; - readonly computedType: D.DecodedType; + readonly computedType: D.CType; readonly loc: Loc; }; @@ -53,7 +52,7 @@ export type LFieldAccess = { readonly kind: "field_access"; readonly aggregate: LValue; readonly field: Id; - readonly computedType: D.DecodedType; + readonly computedType: D.CType; readonly loc: Loc; }; @@ -66,7 +65,7 @@ export type DSelf = { export type DVar = { readonly kind: "var"; readonly name: string; - readonly computedType: D.DecodedType; + readonly computedType: D.CType; readonly loc: Loc; }; @@ -74,27 +73,27 @@ export type DNumber = { readonly kind: "number"; readonly base: NumberBase; readonly value: bigint; - readonly computedType: D.DTypeInt; + readonly computedType: D.CTBasic; readonly loc: Loc; }; export type DBoolean = { readonly kind: "boolean"; readonly value: boolean; - readonly computedType: D.DTypeBool; + readonly computedType: D.CTBasic; readonly loc: Loc; }; export type DString = { readonly kind: "string"; readonly value: string; - readonly computedType: D.DTypeString; + readonly computedType: D.CTBasic; readonly loc: Loc; }; export type DNull = { readonly kind: "null"; - readonly computedType: D.DTypeNull; + readonly computedType: D.CTBasic; readonly loc: Loc; }; @@ -104,7 +103,7 @@ export type DOpBinary = { readonly left: DecodedExpression; readonly right: DecodedExpression; readonly typeArgs: TypeArgs; - readonly computedType: D.DecodedType; + readonly computedType: D.CType; readonly loc: Loc; }; @@ -113,7 +112,7 @@ export type DOpUnary = { readonly op: UnaryOperation; readonly operand: DecodedExpression; readonly typeArgs: TypeArgs; - readonly computedType: D.DecodedType; + readonly computedType: D.CType; readonly loc: Loc; }; @@ -121,7 +120,7 @@ export type DFieldAccess = { readonly kind: "field_access"; readonly aggregate: DecodedExpression; readonly field: Id; - readonly computedType: D.DecodedType; + readonly computedType: D.CType; readonly loc: Loc; }; @@ -132,15 +131,7 @@ export type DMethodCall = { // NB! these are substitutions to self type readonly args: readonly DecodedExpression[]; readonly typeArgs: TypeArgs; - readonly computedType: D.DecodedType; - readonly loc: Loc; -}; - -export type DThrowCall = { - readonly kind: "throw_call"; - readonly function: Id; - readonly args: readonly DecodedExpression[]; - readonly computedType: D.DecodedType; + readonly computedType: D.CType; readonly loc: Loc; }; @@ -150,7 +141,7 @@ export type DStaticCall = { readonly function: Id; readonly typeArgs: TypeArgs; readonly args: readonly DecodedExpression[]; - readonly computedType: D.DecodedType; + readonly computedType: D.CType; readonly loc: Loc; }; @@ -160,21 +151,21 @@ export type DStaticMethodCall = { readonly typeArgs: TypeArgs; readonly function: Id; readonly args: readonly DecodedExpression[]; - readonly computedType: D.DecodedType; + readonly computedType: D.CType; readonly loc: Loc; }; export type DStructInstance = { readonly kind: "struct_instance"; readonly fields: Ordered>; - readonly computedType: D.DTypeRef | D.DTypeRecover; + readonly computedType: D.CTRef | D.CTRecover; readonly loc: Loc; }; export type DMapLiteral = { readonly kind: "map_literal"; readonly fields: readonly DMapField[]; - readonly computedType: D.DTypeMap; + readonly computedType: D.CTMap; readonly loc: Loc; }; @@ -185,9 +176,9 @@ export type DMapField = { export type DSetLiteral = { readonly kind: "set_literal"; - readonly valueType: D.DecodedType; + readonly valueType: D.CType; readonly fields: readonly DecodedExpression[]; - readonly computedType: D.DecodedType; + readonly computedType: D.CType; readonly loc: Loc; }; @@ -195,14 +186,14 @@ export type DInitOf = { readonly kind: "init_of"; readonly contract: TypeId; readonly args: readonly DecodedExpression[]; - readonly computedType: D.DecodedType; + readonly computedType: D.CType; readonly loc: Loc; }; export type DCodeOf = { readonly kind: "code_of"; readonly contract: TypeId; - readonly computedType: D.DecodedType; + readonly computedType: D.CType; readonly loc: Loc; }; @@ -211,26 +202,26 @@ export type DConditional = { readonly condition: DecodedExpression; readonly thenBranch: DecodedExpression; readonly elseBranch: DecodedExpression; - readonly computedType: D.DecodedType; + readonly computedType: D.CType; readonly loc: Loc; }; export type DUnit = { readonly kind: "unit"; - readonly computedType: D.DTypeUnit; + readonly computedType: D.CTBasic; readonly loc: Loc; }; export type DTuple = { readonly kind: "tuple"; readonly children: readonly DecodedExpression[]; - readonly computedType: D.DTypeTuple; + readonly computedType: D.CTTuple; readonly loc: Loc; }; export type DTensor = { readonly kind: "tensor"; readonly children: readonly DecodedExpression[]; - readonly computedType: D.DTypeTensor; + readonly computedType: D.CTTensor; readonly loc: Loc; }; diff --git a/src/next/ast/checked-type.ts b/src/next/ast/checked-type.ts new file mode 100644 index 0000000000..cbcc67a662 --- /dev/null +++ b/src/next/ast/checked-type.ts @@ -0,0 +1,89 @@ +import type { CTypeDeclRefable } from "@/next/ast/checked"; +import type { Loc, TypeId } from "@/next/ast/common"; +import type { BasicType } from "@/next/ast/type-basic"; + +export type DNotSet = { + readonly kind: "not-set"; +}; + +export type CType = + | CTRecover + | CTRef + | CTAliasRef + | CTParamRef + | CTMap + | CTBounced + | CTMaybe + | CTTuple + | CTTensor + | CTBasic; + +export type CTBasic = { + readonly kind: "basic"; + readonly type: BasicType; + readonly loc: Loc; +}; + +export type CTRecover = { + readonly kind: "recover"; +}; + +export type CNotDealiased = { + readonly kind: "NotDealiased"; +}; + +export type CTRef = { + readonly kind: "type_ref"; + readonly name: TypeId; + readonly type: CTypeDeclRefable; + readonly typeArgs: readonly CType[]; + // readonly funcType: Lazy; + // readonly alloc: Lazy + readonly loc: Loc; +}; + +export type CTAliasRef = { + readonly kind: "TypeAlias"; + readonly name: TypeId; + readonly type: CNotDealiased | CType; + readonly typeArgs: readonly CType[]; + readonly loc: Loc; +}; + +export type CTParamRef = { + readonly kind: "TypeParam"; + readonly name: TypeId; + readonly loc: Loc; +}; + +export type CTBounced = { + readonly kind: "TypeBounced"; + // name of the message type + readonly name: TypeId; + readonly loc: Loc; +}; + +export type CTMaybe = { + readonly kind: "TypeMaybe"; + readonly type: CType; + readonly loc: Loc; +}; + +export type CTMap = { + readonly kind: "map_type"; + readonly key: CType; + readonly value: CType; + readonly loc: Loc; +}; + +export type CTTuple = { + readonly kind: "tuple_type"; + readonly typeArgs: readonly CType[]; + readonly loc: Loc; +}; + +export type CTTensor = { + readonly kind: "tensor_type"; + readonly typeArgs: readonly CType[]; + readonly loc: Loc; +}; diff --git a/src/next/ast/checked.ts b/src/next/ast/checked.ts index 1edd8b57ba..95453d8c94 100644 --- a/src/next/ast/checked.ts +++ b/src/next/ast/checked.ts @@ -1,9 +1,9 @@ import type { DecodedStatement } from "@/next/ast/checked-stmt"; import type { FuncId, Loc, OptionalId, TypeId } from "@/next/ast/common"; -import type { DecodedType, DTypeRef, DTypeBounced } from "@/next/ast/dtype"; +import type { CType, CTRef, CTBounced } from "@/next/ast/checked-type"; import type { Effects } from "@/next/ast/effects"; import type { Thunk } from "@/next/ast/lazy"; -import type { SelfType } from "@/next/ast/mtype"; +import type { SelfType } from "@/next/ast/type-self"; import type { AsmInstruction, AsmShuffle, @@ -17,14 +17,14 @@ export type SourceCheckResult = { // import that lead to reading this file readonly importedBy: TactImport; // scopes that were computed from this file - readonly globals: Scope; + readonly globals: CSource; }; -export type Scope = { - readonly typeDecls: ReadonlyMap>; - readonly functions: ReadonlyMap>; - readonly constants: ReadonlyMap>; - readonly extensions: ReadonlyMap[]>>; +export type CSource = { + readonly typeDecls: ReadonlyMap>; + readonly functions: ReadonlyMap>; + readonly constants: ReadonlyMap>; + readonly extensions: ReadonlyMap[]>>; }; export type Decl = { @@ -34,176 +34,176 @@ export type Decl = { export type Recover = T | undefined; -export type TypeDeclSig = - | AliasSig - | ContractSig - | TraitSig - | StructSig - | MessageSig - | UnionSig; - -export type TypeDeclRefable = - | ContractSig - | TraitSig - | StructSig - | MessageSig - | UnionSig; - -export type ConstSig = { +export type CTypeDecl = + | CAlias + | CContract + | CTraitSig + | CStruct + | CMessage + | CUnion; + +export type CTypeDeclRefable = + | CContract + | CTraitSig + | CStruct + | CMessage + | CUnion; + +export type CConstant = { readonly initializer: Thunk>; - readonly type: Thunk; + readonly type: Thunk; }; -export type FnSig = { - readonly type: DecodedFnType; +export type CFunction = { + readonly type: CTypeFunction; readonly inline: boolean; - readonly body: Body; + readonly body: CBody; }; -export type Statements = Thunk>; +export type CStatements = Thunk>; -export type StatementsAux = { +export type CStatementsAux = { readonly body: readonly DecodedStatement[]; readonly effects: Effects; }; -export type Body = TactBody | FuncBody | FiftBody; +export type CBody = CTactBody | CFuncBody | CFiftBody; -export type TactBody = { +export type CTactBody = { readonly kind: "tact"; - readonly statements: Statements; + readonly statements: CStatements; }; -export type FuncBody = { +export type CFuncBody = { readonly kind: "func"; readonly nativeName: FuncId; }; -export type FiftBody = { +export type CFiftBody = { readonly kind: "fift"; readonly shuffle: Thunk>; readonly instructions: readonly AsmInstruction[]; }; -export type ExtSig = { - readonly type: DecodedMethodType; +export type CExtension = { + readonly type: CTypeMethod; readonly inline: boolean; - readonly body: Body; + readonly body: CBody; }; -export type AliasSig = { +export type CAlias = { readonly kind: "alias"; - readonly typeParams: TypeParams; - readonly type: Thunk; + readonly typeParams: CTypeParams; + readonly type: Thunk; }; -export type InitSig = InitEmpty | InitSimple | InitFn; -export type InitEmpty = { +export type CInitSig = CInitEmpty | CInitSimple | CInitFn; +export type CInitEmpty = { readonly kind: "empty"; // initOf() would take 0 parameters // values to fill all the fields readonly fill: Thunk>>>>; }; -export type InitSimple = { +export type CInitSimple = { readonly kind: "simple"; // initOf() takes these parameters and // sets them into correspondingly named fields - readonly fill: Ordered; + readonly fill: Ordered; readonly loc: Loc; }; -export type InitFn = { +export type CInitFn = { readonly kind: "function"; // here we just specify the function - readonly params: Parameters; - readonly statements: Statements; + readonly params: CParameters; + readonly statements: CStatements; }; -export type InitParam = { - readonly type: Thunk; +export type CInitParam = { + readonly type: Thunk; readonly init: undefined | Thunk>; readonly loc: Loc; }; -export type ContractSig = { +export type CContract = { readonly kind: "contract"; readonly attributes: readonly ContractAttribute[]; - readonly init: InitSig; - readonly content: Thunk; + readonly init: CInitSig; + readonly content: Thunk; }; -export type ContractContent = CommonSig>, Body>; -export type TraitSig = { +export type CContractMembers = CMembers>, CBody>; +export type CTraitSig = { readonly kind: "trait"; - readonly content: Thunk; + readonly content: Thunk; }; -export type TraitContent = CommonSig< +export type CTraitMembers = CMembers< Thunk> | undefined, - Body | undefined + CBody | undefined >; -export type CommonSig = { - readonly fieldish: Ordered>>; - readonly methods: ReadonlyMap>>; - readonly receivers: Receivers; +export type CMembers = { + readonly fieldish: Ordered>>; + readonly methods: ReadonlyMap>>; + readonly receivers: CReceivers; }; -export type Receivers = { - readonly bounce: BounceSig; - readonly internal: RecvSig; - readonly external: RecvSig; +export type CReceivers = { + readonly bounce: CBounce; + readonly internal: CReceiver; + readonly external: CReceiver; }; -export type Fieldish = InhFieldSig | FieldConstSig; -export type InhFieldSig = { +export type CFieldish = CField | CFieldConstant; +export type CField = { readonly kind: "field"; - readonly type: Thunk; + readonly type: Thunk; readonly init: Thunk> | undefined; }; -export type FieldConstSig = { +export type CFieldConstant = { readonly kind: "constant"; readonly overridable: boolean; - readonly type: Thunk; + readonly type: Thunk; readonly init: Expr; }; -export type MethodSig = { +export type CMethod = { readonly overridable: boolean; - readonly type: DecodedMethodType; + readonly type: CTypeMethod; readonly inline: boolean; readonly body: Body; readonly getMethodId: Thunk> | undefined; }; -export type BounceSig = { +export type CBounce = { // NB! can't compute opcodes until all receivers are present - readonly message: readonly DeclMem[]; - readonly messageAny: undefined | DeclMem; + readonly message: readonly DeclMem[]; + readonly messageAny: undefined | DeclMem; }; -export type RecvSig = { +export type CReceiver = { // NB! can't compute opcodes until all receivers are present - readonly message: readonly DeclMem[]; - readonly messageAny: undefined | DeclMem; - readonly stringAny: undefined | DeclMem; - readonly empty: undefined | DeclMem; + readonly message: readonly DeclMem[]; + readonly messageAny: undefined | DeclMem; + readonly stringAny: undefined | DeclMem; + readonly empty: undefined | DeclMem; }; -export type OpcodeRecv = MessageRecv | StringRecv; -export type MessageRecv = { +export type CReceiverOpcode = CReceiverMessage | CReceiverString; +export type CReceiverMessage = { readonly kind: "binary"; readonly name: OptionalId; - readonly type: DTypeRef | DTypeBounced; - readonly statements: Statements; + readonly type: CTRef | CTBounced; + readonly statements: CStatements; }; -export type MessageAnyRecv = { +export type CReceiverMessageAny = { readonly name: OptionalId; - readonly statements: Statements; + readonly statements: CStatements; }; -export type StringRecv = { +export type CReceiverString = { readonly kind: "string"; readonly comment: string; - readonly statements: Statements; + readonly statements: CStatements; }; -export type StringAnyRecv = { +export type CReceiverStringAny = { readonly name: OptionalId; - readonly statements: Statements; + readonly statements: CStatements; }; -export type EmptyRecv = { - readonly statements: Statements; +export type CReceiverEmpty = { + readonly statements: CStatements; }; export type DeclMem = { @@ -211,43 +211,43 @@ export type DeclMem = { readonly via: ViaMember; }; -export type StructSig = { +export type CStruct = { readonly kind: "struct"; - readonly typeParams: TypeParams; - readonly fields: Ordered; + readonly typeParams: CTypeParams; + readonly fields: Ordered; }; -export type MessageSig = { +export type CMessage = { readonly kind: "message"; readonly opcode: Thunk>; - readonly fields: Ordered; + readonly fields: Ordered; }; -export type UnionSig = { +export type CUnion = { readonly kind: "union"; - readonly typeParams: TypeParams; - readonly cases: ReadonlyMap>; + readonly typeParams: CTypeParams; + readonly cases: ReadonlyMap>; }; -export type DecodedFnType = { +export type CTypeFunction = { readonly kind: "DecodedFnType"; - readonly typeParams: TypeParams; - readonly params: Parameters; - readonly returnType: Thunk; + readonly typeParams: CTypeParams; + readonly params: CParameters; + readonly returnType: Thunk; }; -export type DecodedMethodType = { +export type CTypeMethod = { readonly kind: "DecodedMethodType"; readonly mutates: boolean; - readonly typeParams: TypeParams; + readonly typeParams: CTypeParams; readonly self: SelfType; - readonly params: Parameters; - readonly returnType: Thunk; + readonly params: CParameters; + readonly returnType: Thunk; }; -export type DecodedParameter = { +export type CParameter = { readonly name: OptionalId; - readonly type: Thunk; + readonly type: Thunk; readonly loc: Loc; }; @@ -256,18 +256,12 @@ export type Ordered = { readonly map: ReadonlyMap; }; -export type Parameters = { - readonly order: readonly Parameter[]; +export type CParameters = { + readonly order: readonly CParameter[]; readonly set: ReadonlySet; }; -export type Parameter = { - readonly name: OptionalId; - readonly type: Thunk; - readonly loc: Loc; -}; - -export type TypeParams = { +export type CTypeParams = { readonly order: readonly TypeId[]; readonly set: ReadonlySet; }; diff --git a/src/next/ast/dtype.ts b/src/next/ast/dtype.ts deleted file mode 100644 index 1e2dc4d2c3..0000000000 --- a/src/next/ast/dtype.ts +++ /dev/null @@ -1,107 +0,0 @@ -import type { TypeDeclRefable } from "@/next/ast/checked"; -import type { Loc, TypeId } from "@/next/ast/common"; -import type * as Ast from "@/next/ast/type"; - -export type DNotSet = { - readonly kind: "not-set"; -}; - -export type DecodedType = - | DTypeRecover - | DTypeRef - | DTypeAliasRef - | DTypeParamRef - | DTypeMap - | DTypeBounced - | DTypeMaybe - | DTypeTuple - | DTypeTensor - | DTypeInt - | DTypeSlice - | DTypeCell - | DTypeBuilder - | DTypeUnit - | DTypeVoid - | DTypeNull - | DTypeBool - | DTypeAddress - | DTypeStateInit - | DTypeString - | DTypeStringBuilder; - -export type DTypeInt = Ast.TypeInt; -export type DTypeSlice = Ast.TypeSlice; -export type DTypeCell = Ast.TypeCell; -export type DTypeBuilder = Ast.TypeBuilder; -export type DTypeUnit = Ast.TypeUnit; -export type DTypeVoid = Ast.TypeVoid; -export type DTypeNull = Ast.TypeNull; -export type DTypeBool = Ast.TypeBool; -export type DTypeAddress = Ast.TypeAddress; -export type DTypeString = Ast.TypeString; -export type DTypeStringBuilder = Ast.TypeStringBuilder; -export type DTypeStateInit = Ast.TypeStateInit; - -export type DTypeRecover = { - readonly kind: "recover"; -}; - -export type NotDealiased = { - readonly kind: "NotDealiased"; -}; - -export type DTypeRef = { - readonly kind: "type_ref"; - readonly name: TypeId; - readonly type: TypeDeclRefable; - readonly typeArgs: readonly DecodedType[]; - // readonly funcType: Lazy; - // readonly alloc: Lazy - readonly loc: Loc; -}; - -export type DTypeAliasRef = { - readonly kind: "TypeAlias"; - readonly name: TypeId; - readonly type: NotDealiased | DecodedType; - readonly typeArgs: readonly DecodedType[]; - readonly loc: Loc; -}; - -export type DTypeParamRef = { - readonly kind: "TypeParam"; - readonly name: TypeId; - readonly loc: Loc; -}; - -export type DTypeBounced = { - readonly kind: "TypeBounced"; - // name of the message type - readonly name: TypeId; - readonly loc: Loc; -}; - -export type DTypeMaybe = { - readonly kind: "TypeMaybe"; - readonly type: DecodedType; - readonly loc: Loc; -}; - -export type DTypeMap = { - readonly kind: "map_type"; - readonly key: DecodedType; - readonly value: DecodedType; - readonly loc: Loc; -}; - -export type DTypeTuple = { - readonly kind: "tuple_type"; - readonly typeArgs: readonly DecodedType[]; - readonly loc: Loc; -}; - -export type DTypeTensor = { - readonly kind: "tensor_type"; - readonly typeArgs: readonly DecodedType[]; - readonly loc: Loc; -}; diff --git a/src/next/ast/effects.ts b/src/next/ast/effects.ts index c675759257..cb616eefe2 100644 --- a/src/next/ast/effects.ts +++ b/src/next/ast/effects.ts @@ -1,4 +1,17 @@ +import type { Loc } from "@/next/ast"; + export type Effects = { - readonly returnOrThrow: boolean; - readonly setSelfPaths: ReadonlySet; -}; + // throws at all times + readonly mustThrow: boolean; + // maybe reads from storage + readonly mayRead: boolean; + // maybe writes to storage + readonly mayWrite: boolean; + // which self.* were assigned to + readonly mustSetSelf: ReadonlySet; +} + +export type Returns = { + readonly selfSet: ReadonlySet; + readonly loc: Loc +} diff --git a/src/next/ast/errors.ts b/src/next/ast/errors.ts index cf76720533..4d10459f16 100644 --- a/src/next/ast/errors.ts +++ b/src/next/ast/errors.ts @@ -1,5 +1,5 @@ import { throwInternal } from "@/error/errors"; -import type { DecodedType } from "@/next/ast/dtype"; +import type { CType } from "@/next/ast/checked-type"; import type { Loc } from "@/next/ast/common"; import type * as V from "@/next/ast/via"; @@ -118,13 +118,13 @@ export const TEMismatch = (tree: MatchTree): TEMismatch => ({ }); export type MatchTree = { - readonly expected: DecodedType; - readonly got: DecodedType; + readonly expected: CType; + readonly got: CType; readonly children: readonly MatchTree[]; }; export const MatchTree = ( - expected: DecodedType, - got: DecodedType, + expected: CType, + got: CType, children: readonly MatchTree[], ): MatchTree => ({ expected, got, children }); diff --git a/src/next/ast/expression.ts b/src/next/ast/expression.ts index c413f38aa3..e045231b96 100644 --- a/src/next/ast/expression.ts +++ b/src/next/ast/expression.ts @@ -1,5 +1,5 @@ import type { Id, Loc, TypeId } from "@/next/ast/common"; -import type { Type, TypeMap } from "@/next/ast/type"; +import type { Type, TMap } from "@/next/ast/type"; export type Expression = | OpBinary @@ -146,7 +146,7 @@ export type StructFieldInitializer = { export type MapLiteral = { readonly kind: "map_literal"; - readonly type: TypeMap; + readonly type: TMap; readonly fields: readonly MapField[]; readonly loc: Loc; }; diff --git a/src/next/ast/generated/checked-expr.ts b/src/next/ast/generated/checked-expr.ts index c2a30c6a35..a3bbfdf366 100644 --- a/src/next/ast/generated/checked-expr.ts +++ b/src/next/ast/generated/checked-expr.ts @@ -2,14 +2,14 @@ import type { Ordered } from "@/next/ast/checked"; import type * as $ from "@/next/ast/checked-expr"; import type * as $c from "@/next/ast/common"; -import type * as $d from "@/next/ast/dtype"; +import type * as $d from "@/next/ast/checked-type"; import type * as $e from "@/next/ast/expression"; -import type { SelfType } from "@/next/ast/mtype"; +import type { SelfType } from "@/next/ast/type-self"; export type DCodeOf = $.DCodeOf; export const DCodeOf = ( contract: $c.TypeId, - computedType: $d.DecodedType, + computedType: $d.CType, loc: $c.Loc, ): $.DCodeOf => Object.freeze({ @@ -23,7 +23,7 @@ export type DNumber = $.DNumber; export const DNumber = ( base: $e.NumberBase, value: bigint, - computedType: $d.DTypeInt, + computedType: $d.CTBasic, loc: $c.Loc, ): $.DNumber => Object.freeze({ @@ -37,7 +37,7 @@ export const isDNumber = ($value: DNumber) => $value.kind === "number"; export type DBoolean = $.DBoolean; export const DBoolean = ( value: boolean, - computedType: $d.DTypeBool, + computedType: $d.CTBasic, loc: $c.Loc, ): $.DBoolean => Object.freeze({ @@ -48,7 +48,7 @@ export const DBoolean = ( }); export const isDBoolean = ($value: DBoolean) => $value.kind === "boolean"; export type DNull = $.DNull; -export const DNull = (computedType: $d.DTypeNull, loc: $c.Loc): $.DNull => +export const DNull = (computedType: $d.CTBasic, loc: $c.Loc): $.DNull => Object.freeze({ kind: "null", computedType, @@ -58,7 +58,7 @@ export const isDNull = ($value: DNull) => $value.kind === "null"; export type DString = $.DString; export const DString = ( value: string, - computedType: $d.DTypeString, + computedType: $d.CTBasic, loc: $c.Loc, ): $.DString => Object.freeze({ @@ -71,7 +71,7 @@ export const isDString = ($value: DString) => $value.kind === "string"; export type DVar = $.DVar; export const DVar = ( name: string, - computedType: $d.DecodedType, + computedType: $d.CType, loc: $c.Loc, ): $.DVar => Object.freeze({ @@ -90,7 +90,7 @@ export const DSelf = (computedType: SelfType, loc: $c.Loc): $.DSelf => }); export const isDSelf = ($value: DSelf) => $value.kind === "self"; export type DUnit = $.DUnit; -export const DUnit = (computedType: $d.DTypeUnit, loc: $c.Loc): $.DUnit => +export const DUnit = (computedType: $d.CTBasic, loc: $c.Loc): $.DUnit => Object.freeze({ kind: "unit", computedType, @@ -99,8 +99,8 @@ export const DUnit = (computedType: $d.DTypeUnit, loc: $c.Loc): $.DUnit => export const isDUnit = ($value: DUnit) => $value.kind === "unit"; export type DSetLiteral = $.DSetLiteral; export const DSetLiteral = ( - valueType: $d.DecodedType, - computedType: $d.DecodedType, + valueType: $d.CType, + computedType: $d.CType, fields: readonly $.DecodedExpression[], loc: $c.Loc, ): $.DSetLiteral => @@ -124,7 +124,7 @@ export const DMapField = ( }); export type DMapLiteral = $.DMapLiteral; export const DMapLiteral = ( - computedType: $d.DTypeMap, + computedType: $d.CTMap, fields: readonly $.DMapField[], loc: $c.Loc, ): $.DMapLiteral => @@ -139,7 +139,7 @@ export const isDMapLiteral = ($value: DMapLiteral) => export type DTensor = $.DTensor; export const DTensor = ( children: readonly $.DecodedExpression[], - computedType: $d.DTypeTensor, + computedType: $d.CTTensor, loc: $c.Loc, ): $.DTensor => Object.freeze({ @@ -152,7 +152,7 @@ export const isDTensor = ($value: DTensor) => $value.kind === "tensor"; export type DTuple = $.DTuple; export const DTuple = ( children: readonly $.DecodedExpression[], - computedType: $d.DTypeTuple, + computedType: $d.CTTuple, loc: $c.Loc, ): $.DTuple => Object.freeze({ @@ -166,7 +166,7 @@ export type DInitOf = $.DInitOf; export const DInitOf = ( contract: $c.TypeId, args: readonly $.DecodedExpression[], - computedType: $d.DecodedType, + computedType: $d.CType, loc: $c.Loc, ): $.DInitOf => Object.freeze({ @@ -180,7 +180,7 @@ export const isDInitOf = ($value: DInitOf) => $value.kind === "init_of"; export type DStructInstance = $.DStructInstance; export const DStructInstance = ( fields: Ordered, - computedType: $d.DTypeRef | $d.DTypeRecover, + computedType: $d.CTRef | $d.CTRecover, loc: $c.Loc, ): $.DStructInstance => Object.freeze({ @@ -195,7 +195,7 @@ export type DFieldAccess = $.DFieldAccess; export const DFieldAccess = ( aggregate: $.DecodedExpression, field: $c.Id, - computedType: $d.DecodedType, + computedType: $d.CType, loc: $c.Loc, ): $.DFieldAccess => Object.freeze({ @@ -213,7 +213,7 @@ export const DStaticMethodCall = ( typeArgs: $.TypeArgs, function_: $c.Id, args: readonly $.DecodedExpression[], - computedType: $d.DecodedType, + computedType: $d.CType, loc: $c.Loc, ): $.DStaticMethodCall => Object.freeze({ @@ -233,7 +233,7 @@ export const DStaticCall = ( function_: $c.Id, typeArgs: $.TypeArgs, args: readonly $.DecodedExpression[], - computedType: $d.DecodedType, + computedType: $d.CType, loc: $c.Loc, ): $.DStaticCall => Object.freeze({ @@ -252,7 +252,7 @@ export const DMethodCall = ( method: $c.Id, args: readonly $.DecodedExpression[], typeArgs: $.TypeArgs, - computedType: $d.DecodedType, + computedType: $d.CType, loc: $c.Loc, ): $.DMethodCall => Object.freeze({ @@ -271,7 +271,7 @@ export const DConditional = ( condition: $.DecodedExpression, thenBranch: $.DecodedExpression, elseBranch: $.DecodedExpression, - computedType: $d.DecodedType, + computedType: $d.CType, loc: $c.Loc, ): $.DConditional => Object.freeze({ @@ -288,8 +288,8 @@ export type DOpUnary = $.DOpUnary; export const DOpUnary = ( op: $e.UnaryOperation, operand: $.DecodedExpression, - typeArgs: ReadonlyMap, - computedType: $d.DecodedType, + typeArgs: ReadonlyMap, + computedType: $d.CType, loc: $c.Loc, ): $.DOpUnary => Object.freeze({ @@ -306,8 +306,8 @@ export const DOpBinary = ( op: $e.BinaryOperation, left: $.DecodedExpression, right: $.DecodedExpression, - typeArgs: ReadonlyMap, - computedType: $d.DecodedType, + typeArgs: ReadonlyMap, + computedType: $d.CType, loc: $c.Loc, ): $.DOpBinary => Object.freeze({ @@ -321,26 +321,10 @@ export const DOpBinary = ( }); export const isDOpBinary = ($value: DOpBinary) => $value.kind === "op_binary"; export type DecodedExpression = $.DecodedExpression; -export type DThrowCall = $.DThrowCall; -export const DThrowCall = ( - function_: $c.Id, - args: readonly $.DecodedExpression[], - computedType: $d.DecodedType, - loc: $c.Loc, -): $.DThrowCall => - Object.freeze({ - kind: "throw_call", - function: function_, - args, - computedType, - loc, - }); -export const isDThrowCall = ($value: DThrowCall) => - $value.kind === "throw_call"; export type LVar = $.LVar; export const LVar = ( name: string, - computedType: $d.DecodedType, + computedType: $d.CType, loc: $c.Loc, ): $.LVar => Object.freeze({ @@ -362,7 +346,7 @@ export type LFieldAccess = $.LFieldAccess; export const LFieldAccess = ( aggregate: $.LValue, field: $c.Id, - computedType: $d.DecodedType, + computedType: $d.CType, loc: $c.Loc, ): $.LFieldAccess => Object.freeze({ diff --git a/src/next/ast/generated/checked-type.ts b/src/next/ast/generated/checked-type.ts new file mode 100644 index 0000000000..714d0b4de5 --- /dev/null +++ b/src/next/ast/generated/checked-type.ts @@ -0,0 +1,129 @@ +/* eslint-disable @typescript-eslint/no-unnecessary-condition */ +import type * as $ from "@/next/ast/checked-type"; +import type * as $c from "@/next/ast/common"; +import type { CTypeDeclRefable } from "@/next/ast/checked"; +import type { BasicType } from "@/next/ast/type-basic"; + +export type CTBasic = $.CTBasic; +export const CTBasic = (type: BasicType, loc: $c.Loc): $.CTBasic => + Object.freeze({ + kind: "basic", + type, + loc, + }); +export type CTypeParamRef = $.CTParamRef; +export const CTypeParamRef = (name: $c.TypeId, loc: $c.Loc): $.CTParamRef => + Object.freeze({ + kind: "TypeParam", + name, + loc, + }); +export const isCTypeParamRef = ($value: CTypeParamRef) => + $value.kind === "TypeParam"; +export type CTypeTensor = $.CTTensor; +export const CTypeTensor = ( + typeArgs: readonly $.CType[], + loc: $c.Loc, +): $.CTTensor => + Object.freeze({ + kind: "tensor_type", + typeArgs, + loc, + }); +export const isCTypeTensor = ($value: CTypeTensor) => + $value.kind === "tensor_type"; +export type CTypeTuple = $.CTTuple; +export const CTypeTuple = ( + typeArgs: readonly $.CType[], + loc: $c.Loc, +): $.CTTuple => + Object.freeze({ + kind: "tuple_type", + typeArgs, + loc, + }); +export const isCTypeTuple = ($value: CTypeTuple) => + $value.kind === "tuple_type"; +export type CTypeMaybe = $.CTMaybe; +export const CTypeMaybe = (type_: $.CType, loc: $c.Loc): $.CTMaybe => + Object.freeze({ + kind: "TypeMaybe", + type: type_, + loc, + }); +export const isCTypeMaybe = ($value: CTypeMaybe) => $value.kind === "TypeMaybe"; +export type CTypeBounced = $.CTBounced; +export const CTypeBounced = (name: $c.TypeId, loc: $c.Loc): $.CTBounced => + Object.freeze({ + kind: "TypeBounced", + name, + loc, + }); +export const isCTypeBounced = ($value: CTypeBounced) => + $value.kind === "TypeBounced"; +export type CTypeMap = $.CTMap; +export const CTypeMap = ( + key: $.CType, + value: $.CType, + loc: $c.Loc, +): $.CTMap => + Object.freeze({ + kind: "map_type", + key, + value, + loc, + }); +export const isCTypeMap = ($value: CTypeMap) => $value.kind === "map_type"; +export type CTypeAliasRef = $.CTAliasRef; +export const CTypeAliasRef = ( + type: CNotDealiased | CType, + name: $c.TypeId, + typeArgs: readonly $.CType[], + loc: $c.Loc, +): $.CTAliasRef => + Object.freeze({ + kind: "TypeAlias", + name, + type, + typeArgs, + loc, + }); +export const isCTypeAliasRef = ($value: CTypeAliasRef) => + $value.kind === "TypeAlias"; +export type DTypeRef = $.CTRef; +export const DTypeRef = ( + name: $c.TypeId, + type: CTypeDeclRefable, + typeArgs: readonly $.CType[], + loc: $c.Loc, +): $.CTRef => + Object.freeze({ + kind: "type_ref", + name, + type, + typeArgs, + loc, + }); +export const isCTypeRef = ($value: DTypeRef) => $value.kind === "type_ref"; +export type CType = $.CType; +export type CTypeRecover = $.CTRecover; +export const CTypeRecover = (): $.CTRecover => + Object.freeze({ + kind: "recover", + }); +export const isCTypeRecover = ($value: CTypeRecover) => + $value.kind === "recover"; + +export type CNotDealiased = $.CNotDealiased; +export const CNotDealiased = (): $.CNotDealiased => + Object.freeze({ + kind: "NotDealiased", + }); +export const isCNotDealiased = ($value: CNotDealiased) => + $value.kind === "NotDealiased"; +export type CNotSet = $.DNotSet; +export const CNotSet = (): $.DNotSet => + Object.freeze({ + kind: "not-set", + }); +export const isCNotSet = ($value: CNotSet) => $value.kind === "not-set"; diff --git a/src/next/ast/generated/checked.ts b/src/next/ast/generated/checked.ts index fd33518f23..1f625aa010 100644 --- a/src/next/ast/generated/checked.ts +++ b/src/next/ast/generated/checked.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-unnecessary-condition */ import type * as $c from "@/next/ast/common"; -import type * as $d from "@/next/ast/dtype"; -import type * as $m from "@/next/ast/mtype"; +import type * as $d from "@/next/ast/checked-type"; +import type * as $m from "@/next/ast/type-self"; import type * as $v from "@/next/ast/via"; import type * as $ from "@/next/ast/checked"; import type { TactImport } from "@/next/imports/source"; @@ -15,20 +15,20 @@ import type { DecodedStatement } from "@/next/ast/checked-stmt"; import type { Value } from "@/next/ast/value"; import type { Effects } from "@/next/ast/effects"; -export type TypeParams = $.TypeParams; -export const TypeParams = ( +export type CTypeParams = $.CTypeParams; +export const CTypeParams = ( order: readonly $c.TypeId[], set: ReadonlySet, -): TypeParams => +): CTypeParams => Object.freeze({ order, set, }); -export type AliasSig = $.AliasSig; -export const AliasSig = ( - typeParams: $.TypeParams, - type_: Thunk<$d.DecodedType>, -): $.AliasSig => +export type CAlias = $.CAlias; +export const CAlias = ( + typeParams: $.CTypeParams, + type_: Thunk<$d.CType>, +): $.CAlias => Object.freeze({ kind: "alias", typeParams, @@ -44,97 +44,95 @@ export const Ordered = ( map, }); -export type DecodedFnType = $.DecodedFnType; -export const DecodedFnType = ( - typeParams: $.TypeParams, - params: $.Parameters, - returnType: Thunk<$d.DecodedType>, -): $.DecodedFnType => +export type CTypeFunction = $.CTypeFunction; +export const CTypeFunction = ( + typeParams: $.CTypeParams, + params: $.CParameters, + returnType: Thunk<$d.CType>, +): $.CTypeFunction => Object.freeze({ kind: "DecodedFnType", typeParams, params, returnType, }); -export type BounceSig = $.BounceSig; -export const BounceSig = ( - message: readonly DeclMem[], - messageAny: DeclMem<$.MessageAnyRecv> | undefined, -): $.BounceSig => +export type CBounce = $.CBounce; +export const CBounce = ( + message: readonly DeclMem[], + messageAny: DeclMem<$.CReceiverMessageAny> | undefined, +): $.CBounce => Object.freeze({ message, messageAny, }); -export type StructSig = $.StructSig; -export const StructSig = ( - typeParams: $.TypeParams, - fields: $.Ordered<$.InhFieldSig>, -): $.StructSig => +export type CStruct = $.CStruct; +export const CStruct = ( + typeParams: $.CTypeParams, + fields: $.Ordered<$.CField>, +): $.CStruct => Object.freeze({ kind: "struct", typeParams, fields, }); -export const isStructSig = ($value: StructSig) => $value.kind === "struct"; -export type UnionSig = $.UnionSig; -export const UnionSig = ( - typeParams: $.TypeParams, - cases: ReadonlyMap>, -): $.UnionSig => +export type CUnion = $.CUnion; +export const CUnion = ( + typeParams: $.CTypeParams, + cases: ReadonlyMap>, +): $.CUnion => Object.freeze({ kind: "union", typeParams, cases, }); -export const isUnionSig = ($value: UnionSig) => $value.kind === "union"; -export type TypeDeclSig = $.TypeDeclSig; -export type ConstSig = $.ConstSig; -export const ConstSig = ( +export type CTypeDecl = $.CTypeDecl; +export type CConstant = $.CConstant; +export const CConstant = ( init: Thunk, - type_: Thunk<$d.DecodedType>, -): $.ConstSig => + type_: Thunk<$d.CType>, +): $.CConstant => Object.freeze({ initializer: init, type: type_, }); -export type ExtSig = $.ExtSig; -export const ExtSig = ( - type: $.DecodedMethodType, +export type CExtension = $.CExtension; +export const CExtension = ( + type: $.CTypeMethod, inline: boolean, - body: $.Body, -): $.ExtSig => + body: $.CBody, +): $.CExtension => Object.freeze({ type, inline, body, }); -export type Scope = $.Scope; +export type CSource = $.CSource; export type Decl = $.Decl; export const Decl = (decl: T, via: $v.ViaUser): Decl => ({ decl, via, }); -export const Scope = ( - typeDecls: ReadonlyMap>, - fnSigs: ReadonlyMap>, - constSigs: ReadonlyMap>, - extSigs: ReadonlyMap[]>>, -): $.Scope => +export const CSource = ( + typeDecls: ReadonlyMap>, + fnSigs: ReadonlyMap>, + constSigs: ReadonlyMap>, + extSigs: ReadonlyMap[]>>, +): $.CSource => Object.freeze({ typeDecls, functions: fnSigs, constants: constSigs, extensions: extSigs, }); -export type DecodedMethodType = $.DecodedMethodType; -export const DecodedMethodType = ( +export type CTypeMethod = $.CTypeMethod; +export const CTypeMethod = ( mutates: boolean, - typeParams: $.TypeParams, + typeParams: $.CTypeParams, self: $m.SelfType, - params: $.Parameters, - returnType: Thunk<$d.DecodedType>, -): $.DecodedMethodType => + params: $.CParameters, + returnType: Thunk<$d.CType>, +): $.CTypeMethod => Object.freeze({ kind: "DecodedMethodType", mutates, @@ -143,12 +141,12 @@ export const DecodedMethodType = ( params, returnType, }); -export type DecodedParameter = $.DecodedParameter; -export const DecodedParameter = ( +export type CParameter = $.CParameter; +export const CParameter = ( name: $c.OptionalId, - type_: Thunk<$d.DecodedType>, + type_: Thunk<$d.CType>, loc: $c.Loc, -): $.DecodedParameter => +): $.CParameter => Object.freeze({ name, type: type_, @@ -157,67 +155,53 @@ export const DecodedParameter = ( export type SourceCheckResult = $.SourceCheckResult; export const SourceCheckResult = ( importedBy: TactImport, - globals: $.Scope, + globals: $.CSource, ): $.SourceCheckResult => Object.freeze({ importedBy, globals, }); -export type Parameter = $.Parameter; -export const Parameter = ( - name: $c.OptionalId, - type_: Thunk<$d.DecodedType>, - loc: $c.Loc, -): $.Parameter => - Object.freeze({ - name, - type: type_, - loc, - }); export type Recover = $.Recover; -export type Parameters = $.Parameters; -export const Parameters = ( - order: readonly $.Parameter[], +export type CParameters = $.CParameters; +export const CParameters = ( + order: readonly $.CParameter[], set: ReadonlySet, -): $.Parameters => +): $.CParameters => Object.freeze({ order, set, }); -export type TactBody = $.TactBody; -export const TactBody = ( - statements: Thunk, -): $.TactBody => +export type CTactBody = $.CTactBody; +export const CTactBody = ( + statements: Thunk, +): $.CTactBody => Object.freeze({ kind: "tact", statements, }); -export const isTactBody = ($value: TactBody) => $value.kind === "tact"; -export type FuncBody = $.FuncBody; -export const FuncBody = (nativeName: $c.FuncId): $.FuncBody => +export type CFuncBody = $.CFuncBody; +export const CFuncBody = (nativeName: $c.FuncId): $.CFuncBody => Object.freeze({ kind: "func", nativeName, }); -export const isFuncBody = ($value: FuncBody) => $value.kind === "func"; -export type FiftBody = $.FiftBody; -export const FiftBody = ( +export type CFiftBody = $.CFiftBody; +export const CFiftBody = ( shuffle: Thunk, instructions: readonly AsmInstruction[], -): $.FiftBody => +): $.CFiftBody => Object.freeze({ kind: "fift", shuffle, instructions, }); -export const isFiftBody = ($value: FiftBody) => $value.kind === "fift"; -export type Body = $.Body; -export type FnSig = $.FnSig; -export const FnSig = ( - type_: $.DecodedFnType, +export type CBody = $.CBody; +export type CFunction = $.CFunction; +export const CFunction = ( + type_: $.CTypeFunction, inline: boolean, - body: $.Body, -): $.FnSig => + body: $.CBody, +): $.CFunction => Object.freeze({ type: type_, inline, @@ -228,40 +212,37 @@ export const DeclMem = (decl: T, via: $v.ViaMember): DeclMem => ({ decl, via, }); -export type InhFieldSig = $.InhFieldSig; -export const InhFieldSig = ( - type_: Thunk<$d.DecodedType>, +export type CField = $.CField; +export const CField = ( + type_: Thunk<$d.CType>, init: Thunk | undefined, -): $.InhFieldSig => +): $.CField => Object.freeze({ kind: "field", type: type_, init, }); -export const isInhFieldSig = ($value: InhFieldSig) => $value.kind === "field"; -export type FieldConstSig = $.FieldConstSig; -export const FieldConstSig = ( +export type CFieldConstant = $.CFieldConstant; +export const CFieldConstant = ( overridable: boolean, - type_: Thunk<$d.DecodedType>, + type_: Thunk<$d.CType>, init: Expr, -): $.FieldConstSig => +): $.CFieldConstant => Object.freeze({ kind: "constant", overridable, type: type_, init, }); -export const isFieldConstSig = ($value: FieldConstSig) => - $value.kind === "constant"; -export type Fieldish = $.Fieldish; -export type MethodSig = $.MethodSig; -export const MethodSig = ( +export type CFieldish = $.CFieldish; +export type CMethod = $.CMethod; +export const CMethod = ( overridable: boolean, - type_: $.DecodedMethodType, + type_: $.CTypeMethod, inline: boolean, body: Body, getMethodId: Thunk | undefined, -): $.MethodSig => +): $.CMethod => Object.freeze({ overridable, type: type_, @@ -269,168 +250,161 @@ export const MethodSig = ( body, getMethodId, }); -export type Receivers = $.Receivers; -export type CommonSig = $.CommonSig; -export const CommonSig = ( - fieldish: $.Ordered<$.DeclMem<$.Fieldish>>, - methods: ReadonlyMap>>, - receivers: $.Receivers, -): $.CommonSig => +export type CReceivers = $.CReceivers; +export type CMembers = $.CMembers; +export const CMembers = ( + fieldish: $.Ordered<$.DeclMem<$.CFieldish>>, + methods: ReadonlyMap>>, + receivers: $.CReceivers, +): $.CMembers => Object.freeze({ fieldish, methods, receivers, }); -export type ContractContent = $.ContractContent; -export type TraitContent = $.TraitContent; -export type TraitSig = $.TraitSig; -export const TraitSig = ( +export type CContractMembers = $.CContractMembers; +export type CTraitMembers = $.CTraitMembers; +export type CTraitSig = $.CTraitSig; +export const CTraitSig = ( content: Thunk< - $.CommonSig | undefined, $.Body | undefined> + $.CMembers | undefined, $.CBody | undefined> >, -): $.TraitSig => +): $.CTraitSig => Object.freeze({ kind: "trait", content, }); -export const isTraitSig = ($value: TraitSig) => $value.kind === "trait"; -export type MessageRecv = $.MessageRecv; -export const MessageRecv = ( +export type CReceiverMessage = $.CReceiverMessage; +export const CReceiverMessage = ( name: $c.OptionalId, - type_: $d.DTypeRef | $d.DTypeBounced, - statements: Thunk, -): $.MessageRecv => + type_: $d.CTRef | $d.CTBounced, + statements: Thunk, +): $.CReceiverMessage => Object.freeze({ kind: "binary", name, type: type_, statements, }); -export type MessageAnyRecv = $.MessageAnyRecv; -export const MessageAnyRecv = ( +export type CReceiverMessageAny = $.CReceiverMessageAny; +export const CReceiverMessageAny = ( name: $c.OptionalId, - statements: Thunk, -): $.MessageAnyRecv => + statements: Thunk, +): $.CReceiverMessageAny => Object.freeze({ name, statements, }); -export type StringRecv = $.StringRecv; -export const StringRecv = ( +export type CReceiverString = $.CReceiverString; +export const CReceiverString = ( comment: string, - statements: Thunk, -): $.StringRecv => + statements: Thunk, +): $.CReceiverString => Object.freeze({ kind: "string", comment, statements, }); -export type StringAnyRecv = $.StringAnyRecv; -export const StringAnyRecv = ( +export type CReceiverStringAny = $.CReceiverStringAny; +export const CReceiverStringAny = ( name: $c.OptionalId, - statements: Thunk, -): $.StringAnyRecv => + statements: Thunk, +): $.CReceiverStringAny => Object.freeze({ name, statements, }); -export type EmptyRecv = $.EmptyRecv; -export const EmptyRecv = ( - statements: Thunk, -): $.EmptyRecv => +export type CReceiverEmpty = $.CReceiverEmpty; +export const CReceiverEmpty = ( + statements: Thunk, +): $.CReceiverEmpty => Object.freeze({ statements, }); -export type OpcodeRecv = $.OpcodeRecv; -export type RecvSig = $.RecvSig; -export const RecvSig = ( - message: readonly DeclMem[], - messageAny: $.DeclMem<$.MessageAnyRecv> | undefined, - stringAny: $.DeclMem<$.StringAnyRecv> | undefined, - empty: $.DeclMem<$.EmptyRecv> | undefined, -): $.RecvSig => +export type CReceiverOpcode = $.CReceiverOpcode; +export type CReceiver = $.CReceiver; +export const CReceiver = ( + message: readonly DeclMem[], + messageAny: $.DeclMem<$.CReceiverMessageAny> | undefined, + stringAny: $.DeclMem<$.CReceiverStringAny> | undefined, + empty: $.DeclMem<$.CReceiverEmpty> | undefined, +): $.CReceiver => Object.freeze({ message, messageAny, stringAny, empty, }); -export type MessageSig = $.MessageSig; -export const MessageSig = ( +export type CMessage = $.CMessage; +export const CMessage = ( opcode: Thunk, - fields: $.Ordered<$.InhFieldSig>, -): $.MessageSig => + fields: $.Ordered<$.CField>, +): $.CMessage => Object.freeze({ kind: "message", opcode, fields, }); -export const isMessageSig = ($value: MessageSig) => $value.kind === "message"; -export type InitEmpty = $.InitEmpty; -export const InitEmpty = ( +export type CInitEmpty = $.CInitEmpty; +export const CInitEmpty = ( fill: Thunk>>, -): $.InitEmpty => +): $.CInitEmpty => Object.freeze({ kind: "empty", fill, }); -export const isInitEmpty = ($value: InitEmpty) => $value.kind === "empty"; -export type InitParam = $.InitParam; -export const InitParam = ( - type_: Thunk<$d.DecodedType>, +export type CInitParam = $.CInitParam; +export const CInitParam = ( + type_: Thunk<$d.CType>, init: Thunk | undefined, loc: $c.Loc, -): $.InitParam => +): $.CInitParam => Object.freeze({ type: type_, init, loc, }); -export type InitSimple = $.InitSimple; -export const InitSimple = ( - fill: $.Ordered<$.InitParam>, +export type CInitSimple = $.CInitSimple; +export const CInitSimple = ( + fill: $.Ordered<$.CInitParam>, loc: $c.Loc, -): $.InitSimple => +): $.CInitSimple => Object.freeze({ kind: "simple", fill, loc, }); -export const isInitSimple = ($value: InitSimple) => $value.kind === "simple"; -export type StatementsAux = $.StatementsAux; -export const StatementsAux = ( +export type CStatementsAux = $.CStatementsAux; +export const CStatementsAux = ( body: readonly DecodedStatement[], effects: Effects, -): $.StatementsAux => +): $.CStatementsAux => Object.freeze({ body, effects, }); -export type InitFn = $.InitFn; -export const InitFn = ( - params: $.Parameters, - statements: Thunk, -): $.InitFn => +export type CInitFn = $.CInitFn; +export const CInitFn = ( + params: $.CParameters, + statements: Thunk, +): $.CInitFn => Object.freeze({ kind: "function", params, statements, }); -export const isInitFn = ($value: InitFn) => $value.kind === "function"; -export type Statements = $.Statements; -export type InitSig = $.InitSig; -export type ContractSig = $.ContractSig; -export type TypeDeclRefable = $.TypeDeclRefable; -export const ContractSig = ( +export type CStatements = $.CStatements; +export type CInitSig = $.CInitSig; +export type CContract = $.CContract; +export type CTypeDeclRefable = $.CTypeDeclRefable; +export const CContract = ( attributes: readonly ContractAttribute[], - init: $.InitSig, - content: Thunk<$.ContractContent>, -): $.ContractSig => + init: $.CInitSig, + content: Thunk<$.CContractMembers>, +): $.CContract => Object.freeze({ kind: "contract", attributes, init, content, }); -export const isContractSig = ($value: ContractSig) => - $value.kind === "contract"; diff --git a/src/next/ast/generated/dtype.ts b/src/next/ast/generated/dtype.ts deleted file mode 100644 index e12d69550f..0000000000 --- a/src/next/ast/generated/dtype.ts +++ /dev/null @@ -1,129 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unnecessary-condition */ -import type * as $ from "@/next/ast/dtype"; -import type * as $c from "@/next/ast/common"; -import type { TypeDeclRefable } from "@/next/ast/checked"; - -export type DTypeParamRef = $.DTypeParamRef; -export const DTypeParamRef = (name: $c.TypeId, loc: $c.Loc): $.DTypeParamRef => - Object.freeze({ - kind: "TypeParam", - name, - loc, - }); -export const isDTypeParamRef = ($value: DTypeParamRef) => - $value.kind === "TypeParam"; -export type DTypeTensor = $.DTypeTensor; -export const DTypeTensor = ( - typeArgs: readonly $.DecodedType[], - loc: $c.Loc, -): $.DTypeTensor => - Object.freeze({ - kind: "tensor_type", - typeArgs, - loc, - }); -export const isDTypeTensor = ($value: DTypeTensor) => - $value.kind === "tensor_type"; -export type DTypeTuple = $.DTypeTuple; -export const DTypeTuple = ( - typeArgs: readonly $.DecodedType[], - loc: $c.Loc, -): $.DTypeTuple => - Object.freeze({ - kind: "tuple_type", - typeArgs, - loc, - }); -export const isDTypeTuple = ($value: DTypeTuple) => - $value.kind === "tuple_type"; -export type DTypeMaybe = $.DTypeMaybe; -export const DTypeMaybe = (type_: $.DecodedType, loc: $c.Loc): $.DTypeMaybe => - Object.freeze({ - kind: "TypeMaybe", - type: type_, - loc, - }); -export const isDTypeMaybe = ($value: DTypeMaybe) => $value.kind === "TypeMaybe"; -export type DTypeBounced = $.DTypeBounced; -export const DTypeBounced = (name: $c.TypeId, loc: $c.Loc): $.DTypeBounced => - Object.freeze({ - kind: "TypeBounced", - name, - loc, - }); -export const isDTypeBounced = ($value: DTypeBounced) => - $value.kind === "TypeBounced"; -export type DTypeMap = $.DTypeMap; -export const DTypeMap = ( - key: $.DecodedType, - value: $.DecodedType, - loc: $c.Loc, -): $.DTypeMap => - Object.freeze({ - kind: "map_type", - key, - value, - loc, - }); -export const isDTypeMap = ($value: DTypeMap) => $value.kind === "map_type"; -export type DTypeAliasRef = $.DTypeAliasRef; -export const DTypeAliasRef = ( - type: NotDealiased | DecodedType, - name: $c.TypeId, - typeArgs: readonly $.DecodedType[], - loc: $c.Loc, -): $.DTypeAliasRef => - Object.freeze({ - kind: "TypeAlias", - name, - type, - typeArgs, - loc, - }); -export const isDTypeAliasRef = ($value: DTypeAliasRef) => - $value.kind === "TypeAlias"; -export type DTypeRef = $.DTypeRef; -export const DTypeRef = ( - name: $c.TypeId, - type: TypeDeclRefable, - typeArgs: readonly $.DecodedType[], - loc: $c.Loc, -): $.DTypeRef => - Object.freeze({ - kind: "type_ref", - name, - type, - typeArgs, - loc, - }); -export const isDTypeRef = ($value: DTypeRef) => $value.kind === "type_ref"; -export type DecodedType = $.DecodedType; -export type DTypeRecover = $.DTypeRecover; -export const DTypeRecover = (): $.DTypeRecover => - Object.freeze({ - kind: "recover", - }); -export const isDTypeRecover = ($value: DTypeRecover) => - $value.kind === "recover"; -export type DTypeStateInit = $.DTypeStateInit; -export const DTypeStateInit = (loc: $c.Loc): $.DTypeStateInit => - Object.freeze({ - kind: "TypeStateInit", - loc, - }); -export const isDTypeStateInit = ($value: DTypeStateInit) => - $value.kind === "TypeStateInit"; - -export type NotDealiased = $.NotDealiased; -export const NotDealiased = (): $.NotDealiased => - Object.freeze({ - kind: "NotDealiased", - }); -export const isNotDealiased = ($value: NotDealiased) => - $value.kind === "NotDealiased"; -export type DNotSet = $.DNotSet; -export const DNotSet = (): $.DNotSet => - Object.freeze({ - kind: "not-set", - }); -export const isDNotSet = ($value: DNotSet) => $value.kind === "not-set"; diff --git a/src/next/ast/generated/effects.ts b/src/next/ast/generated/effects.ts index 63e4dfe52a..8a4aa06a07 100644 --- a/src/next/ast/generated/effects.ts +++ b/src/next/ast/generated/effects.ts @@ -2,6 +2,13 @@ import type * as $ from "@/next/ast/effects"; export type Effects = $.Effects; export const Effects = ( - returnOrThrow: boolean, - setSelfPaths: ReadonlySet, -): $.Effects => Object.freeze({ returnOrThrow, setSelfPaths }); + mayRead: boolean, + mayWrite: boolean, + mustThrow: boolean, + mustSetSelf: ReadonlySet, +): $.Effects => Object.freeze({ + mayRead, + mayWrite, + mustThrow, + mustSetSelf, +}); diff --git a/src/next/ast/generated/expression.ts b/src/next/ast/generated/expression.ts index 453e7b0aab..c8dd3b5a5b 100644 --- a/src/next/ast/generated/expression.ts +++ b/src/next/ast/generated/expression.ts @@ -259,7 +259,7 @@ export const MapField = (key: $.Expression, value: $.Expression): $.MapField => }); export type MapLiteral = $.MapLiteral; export const MapLiteral = ( - type_: $t.TypeMap, + type_: $t.TMap, fields: readonly $.MapField[], loc: $c.Loc, ): $.MapLiteral => diff --git a/src/next/ast/generated/lowered.ts b/src/next/ast/generated/lowered.ts new file mode 100644 index 0000000000..d6e6e9bec2 --- /dev/null +++ b/src/next/ast/generated/lowered.ts @@ -0,0 +1,254 @@ +import type * as $ from "@/next/ast/lowered"; +import type * as $c from "@/next/ast/common"; +import type * as $d from "@/next/ast/checked-type"; +import type * as $v from "@/next/ast/value"; +import type { DecodedStatement } from "@/next/ast/checked-stmt"; +import type { Effects } from "@/next/ast/generated/effects"; +import type { SelfType } from "@/next/ast/type-self"; +import type { AsmShuffle, ContractAttribute } from "@/next/ast/generated/root"; +import type { AsmInstruction } from "@/next/ast/root"; + +export type LTypeParams = $.LTypeParams; +export const LTypeParams = (order: readonly $c.TypeId[], set: ReadonlySet): $.LTypeParams => Object.freeze({ + order, + set +}); +export type LAliasSig = $.LAliasSig; +export const LAliasSig = (typeParams: $.LTypeParams, type_: $d.CType): $.LAliasSig => Object.freeze({ + kind: "alias", + typeParams, + type: type_ +}); +export const isLAliasSig = ($value: LAliasSig) => $value.kind === "alias"; +export type LOrdered = $.LOrdered; +export const LOrdered = (order: readonly string[], map: ReadonlyMap): $.LOrdered => Object.freeze({ + order, + map +}); +export type LInitEmpty = $.LInitEmpty; +export const LInitEmpty = (fill: $.LOrdered<$v.Value>): $.LInitEmpty => Object.freeze({ + kind: "empty", + fill +}); +export const isLInitEmpty = ($value: LInitEmpty) => $value.kind === "empty"; +export type LInitParam = $.LInitParam; +export const LInitParam = (type_: $d.CType, init: $v.Value | undefined, loc: $c.Loc): $.LInitParam => Object.freeze({ + type: type_, + init, + loc +}); +export type LInitSimple = $.LInitSimple; +export const LInitSimple = (fill: $.LOrdered<$.LInitParam>, loc: $c.Loc): $.LInitSimple => Object.freeze({ + kind: "simple", + fill, + loc +}); +export const isLInitSimple = ($value: LInitSimple) => $value.kind === "simple"; +export type LParameter = $.LParameter; +export const LParameter = (name: $c.OptionalId, type_: $d.CType, loc: $c.Loc): $.LParameter => Object.freeze({ + name, + type: type_, + loc +}); +export type LParameters = $.LParameters; +export const LParameters = (order: readonly $.LParameter[], set: ReadonlySet): $.LParameters => Object.freeze({ + order, + set +}); +export type LStatements = $.LStatements; +export const LStatements = (body: readonly DecodedStatement[], effects: Effects): $.LStatements => Object.freeze({ + body, + effects +}); +export type LInitFn = $.LInitFn; +export const LInitFn = (params: $.LParameters, statements: $.LStatements): $.LInitFn => Object.freeze({ + kind: "function", + params, + statements +}); +export const isLInitFn = ($value: LInitFn) => $value.kind === "function"; +export type LInitSig = $.LInitSig; +export type LInhFieldSig = $.LInhFieldSig; +export const LInhFieldSig = (type_: $d.CType, init: $v.Value | undefined): $.LInhFieldSig => Object.freeze({ + kind: "field", + type: type_, + init +}); +export const isLInhFieldSig = ($value: LInhFieldSig) => $value.kind === "field"; +export type LFieldConstSig = $.LFieldConstSig; +export const LFieldConstSig = (overridable: boolean, type_: $d.CType, init: Expr): $.LFieldConstSig => Object.freeze({ + kind: "constant", + overridable, + type: type_, + init +}); +export const isLFieldConstSig = ($value: LFieldConstSig) => $value.kind === "constant"; +export type LFieldish = $.LFieldish; +export type LDecodedMethodType = $.LDecodedMethodType; +export const LDecodedMethodType = (mutates: boolean, typeParams: $.LTypeParams, self: SelfType, params: $.LParameters, returnType: $d.CType): $.LDecodedMethodType => Object.freeze({ + kind: "DecodedMethodType", + mutates, + typeParams, + self, + params, + returnType +}); +export const isLDecodedMethodType = ($value: LDecodedMethodType) => $value.kind === "DecodedMethodType"; +export type LMethodSig = $.LMethodSig; +export const LMethodSig = (overridable: boolean, type_: $.LDecodedMethodType, inline: boolean, body: Body, getMethodId: bigint | undefined): $.LMethodSig => Object.freeze({ + overridable, + type: type_, + inline, + body, + getMethodId +}); +export type LMessageRecv = $.LMessageRecv; +export const LMessageRecv = (name: $c.OptionalId, type_: $d.CTRef, statements: $.LStatements): $.LMessageRecv => Object.freeze({ + kind: "binary", + name, + type: type_, + statements +}); +export const isLMessageRecv = ($value: LMessageRecv) => $value.kind === "binary"; +export type LMessageAnyRecv = $.LMessageAnyRecv; +export const LMessageAnyRecv = (name: $c.OptionalId, statements: $.LStatements): $.LMessageAnyRecv => Object.freeze({ + name, + statements +}); +export type LBounceSig = $.LBounceSig; +export const LBounceSig = (message: readonly $.LMessageRecv[], messageAny: $.LMessageAnyRecv | undefined): $.LBounceSig => Object.freeze({ + message, + messageAny +}); +export type LStringRecv = $.LStringRecv; +export const LStringRecv = (comment: string, statements: $.LStatements): $.LStringRecv => Object.freeze({ + kind: "string", + comment, + statements +}); +export const isLStringRecv = ($value: LStringRecv) => $value.kind === "string"; +export type LOpcodeRecv = $.LOpcodeRecv; +export type LStringAnyRecv = $.LStringAnyRecv; +export const LStringAnyRecv = (name: $c.OptionalId, statements: $.LStatements): $.LStringAnyRecv => Object.freeze({ + name, + statements +}); +export type LEmptyRecv = $.LEmptyRecv; +export const LEmptyRecv = (statements: $.LStatements): $.LEmptyRecv => Object.freeze({ + statements +}); +export type LRecvSig = $.LRecvSig; +export const LRecvSig = (message: readonly $.LOpcodeRecv[], messageAny: $.LMessageAnyRecv | undefined, stringAny: $.LStringAnyRecv | undefined, empty: $.LEmptyRecv | undefined): $.LRecvSig => Object.freeze({ + message, + messageAny, + stringAny, + empty +}); +export type LReceivers = $.LReceivers; +export const LReceivers = (bounce: $.LBounceSig, internal: $.LRecvSig, external: $.LRecvSig): $.LReceivers => Object.freeze({ + bounce, + internal, + external +}); +export type LCommonSig = $.LCommonSig; +export const LCommonSig = (fieldish: $.LOrdered<$.LFieldish>, methods: ReadonlyMap>, receivers: $.LReceivers): $.LCommonSig => Object.freeze({ + fieldish, + methods, + receivers +}); +export type LTactBody = $.LTactBody; +export const LTactBody = (statements: $.LStatements): $.LTactBody => Object.freeze({ + kind: "tact", + statements +}); +export const isLTactBody = ($value: LTactBody) => $value.kind === "tact"; +export type LFuncBody = $.LFuncBody; +export const LFuncBody = (nativeName: $c.FuncId): $.LFuncBody => Object.freeze({ + kind: "func", + nativeName +}); +export const isLFuncBody = ($value: LFuncBody) => $value.kind === "func"; +export type LFiftBody = $.LFiftBody; +export const LFiftBody = (shuffle: AsmShuffle, instructions: readonly AsmInstruction[]): $.LFiftBody => Object.freeze({ + kind: "fift", + shuffle, + instructions +}); +export const isLFiftBody = ($value: LFiftBody) => $value.kind === "fift"; +export type LBody = $.LBody; +export type LContractContent = $.LContractContent; +export type LContractSig = $.LContractSig; +export const LContractSig = (attributes: readonly ContractAttribute[], init: $.LInitSig, content: $.LContractContent): $.LContractSig => Object.freeze({ + kind: "contract", + attributes, + init, + content +}); +export const isLContractSig = ($value: LContractSig) => $value.kind === "contract"; +export type LTraitContent = $.LTraitContent; +export type LTraitSig = $.LTraitSig; +export const LTraitSig = (content: $.LTraitContent): $.LTraitSig => Object.freeze({ + kind: "trait", + content +}); +export const isLTraitSig = ($value: LTraitSig) => $value.kind === "trait"; +export type LStructSig = $.LStructSig; +export const LStructSig = (typeParams: $.LTypeParams, fields: $.LOrdered<$.LInhFieldSig>): $.LStructSig => Object.freeze({ + kind: "struct", + typeParams, + fields +}); +export const isLStructSig = ($value: LStructSig) => $value.kind === "struct"; +export type LMessageSig = $.LMessageSig; +export const LMessageSig = (opcode: bigint, fields: $.LOrdered<$.LInhFieldSig>): $.LMessageSig => Object.freeze({ + kind: "message", + opcode, + fields +}); +export const isLMessageSig = ($value: LMessageSig) => $value.kind === "message"; +export type LUnionSig = $.LUnionSig; +export const LUnionSig = (typeParams: $.LTypeParams, cases: ReadonlyMap>): $.LUnionSig => Object.freeze({ + kind: "union", + typeParams, + cases +}); +export const isLUnionSig = ($value: LUnionSig) => $value.kind === "union"; +export type LTypeDeclSig = $.LTypeDeclSig; +export type LDecodedFnType = $.LDecodedFnType; +export const LDecodedFnType = (typeParams: $.LTypeParams, params: $.LParameters, returnType: $d.CType): $.LDecodedFnType => Object.freeze({ + kind: "DecodedFnType", + typeParams, + params, + returnType +}); +export const isLDecodedFnType = ($value: LDecodedFnType) => $value.kind === "DecodedFnType"; +export type LFnSig = $.LFnSig; +export const LFnSig = (type_: $.LDecodedFnType, inline: boolean, body: $.LBody): $.LFnSig => Object.freeze({ + type: type_, + inline, + body +}); +export type LConstSig = $.LConstSig; +export const LConstSig = (initializer: $v.Value, type_: $d.CType): $.LConstSig => Object.freeze({ + initializer, + type: type_ +}); +export type LExtSig = $.LExtSig; +export const LExtSig = (type_: $.LDecodedMethodType, inline: boolean, body: $.LBody): $.LExtSig => Object.freeze({ + type: type_, + inline, + body +}); +export type LoweredSource = $.LSource; +export const LoweredSource = (typeDecls: ReadonlyMap, functions: ReadonlyMap, constants: ReadonlyMap, extensions: ReadonlyMap): $.LSource => Object.freeze({ + typeDecls, + functions, + constants, + extensions +}); +export type LDecodedParameter = $.LDecodedParameter; +export const LDecodedParameter = (name: $c.OptionalId, type_: $d.CType, loc: $c.Loc): $.LDecodedParameter => Object.freeze({ + name, + type: type_, + loc +}); \ No newline at end of file diff --git a/src/next/ast/generated/mtype.ts b/src/next/ast/generated/mtype.ts deleted file mode 100644 index 2c3cd97b18..0000000000 --- a/src/next/ast/generated/mtype.ts +++ /dev/null @@ -1,157 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unnecessary-condition */ -import type * as $ from "@/next/ast/mtype"; -import type * as $c from "@/next/ast/common"; -import type * as $d from "@/next/ast/dtype"; -import type { TypeDeclRefable } from "@/next/ast/checked"; - -export type MGTypeInt = $.MGTypeInt; -export type MGTypeSlice = $.MGTypeSlice; -export type MGTypeCell = $.MGTypeCell; -export type MGTypeBuilder = $.MGTypeBuilder; -export type MGTypeUnit = $.MGTypeUnit; -export type MGTypeVoid = $.MGTypeVoid; -export type MGTypeNull = $.MGTypeNull; -export type MGTypeBool = $.MGTypeBool; -export type MGTypeAddress = $.MGTypeAddress; -export type MGTypeString = $.MGTypeString; -export type MGTypeStringBuilder = $.MGTypeStringBuilder; -export type MGTypeRef = $.MGTypeRef; -export const MGTypeRef = ( - name: $c.TypeId, - type: TypeDeclRefable, - typeArgs: readonly $.MethodGroundType[], - loc: $c.Loc, -): $.MGTypeRef => - Object.freeze({ - ground: "yes", - kind: "type_ref", - name, - type, - typeArgs, - loc, - }); -export const isMGTypeRef = ($value: MGTypeRef) => $value.kind === "type_ref"; -export type MGTypeMaybe = $.MGTypeMaybe; -export const MGTypeMaybe = ( - type_: $.MethodGroundType, - loc: $c.Loc, -): $.MGTypeMaybe => - Object.freeze({ - ground: "yes", - kind: "TypeMaybe", - type: type_, - loc, - }); -export const isMGTypeMaybe = ($value: MGTypeMaybe) => - $value.kind === "TypeMaybe"; -export type MGTypeMap = $.MGTypeMap; -export const MGTypeMap = ( - key: $.MethodGroundType, - value: $.MethodGroundType, - loc: $c.Loc, -): $.MGTypeMap => - Object.freeze({ - ground: "yes", - kind: "map_type", - key, - value, - loc, - }); -export const isMGTypeMap = ($value: MGTypeMap) => $value.kind === "map_type"; -export type MGTypeTuple = $.MGTypeTuple; -export const MGTypeTuple = ( - typeArgs: readonly $.MethodGroundType[], - loc: $c.Loc, -): $.MGTypeTuple => - Object.freeze({ - ground: "yes", - kind: "tuple_type", - typeArgs, - loc, - }); -export const isMGTypeTuple = ($value: MGTypeTuple) => - $value.kind === "tuple_type"; -export type MGTypeTensor = $.MGTypeTensor; -export const MGTypeTensor = ( - typeArgs: readonly $.MethodGroundType[], - loc: $c.Loc, -): $.MGTypeTensor => - Object.freeze({ - ground: "yes", - kind: "tensor_type", - typeArgs, - loc, - }); -export const isMGTypeTensor = ($value: MGTypeTensor) => - $value.kind === "tensor_type"; -export type MVTypeRef = $.MVTypeRef; -export const MVTypeRef = ( - name: $c.TypeId, - type: TypeDeclRefable, - typeArgs: readonly $d.DTypeParamRef[], - loc: $c.Loc, -): $.MVTypeRef => - Object.freeze({ - ground: "no", - kind: "type_ref", - name, - type, - typeArgs, - loc, - }); -export const isMVTypeRef = ($value: MVTypeRef) => $value.kind === "type_ref"; -export type MVTypeMaybe = $.MVTypeMaybe; -export const MVTypeMaybe = ( - type_: $d.DTypeParamRef, - loc: $c.Loc, -): $.MVTypeMaybe => - Object.freeze({ - ground: "no", - kind: "TypeMaybe", - type: type_, - loc, - }); -export const isMVTypeMaybe = ($value: MVTypeMaybe) => - $value.kind === "TypeMaybe"; -export type MVTypeMap = $.MVTypeMap; -export const MVTypeMap = ( - key: $d.DTypeParamRef, - value: $d.DTypeParamRef, - loc: $c.Loc, -): $.MVTypeMap => - Object.freeze({ - ground: "no", - kind: "map_type", - key, - value, - loc, - }); -export const isMVTypeMap = ($value: MVTypeMap) => $value.kind === "map_type"; -export type MVTypeTuple = $.MVTypeTuple; -export const MVTypeTuple = ( - typeArgs: readonly $d.DTypeParamRef[], - loc: $c.Loc, -): $.MVTypeTuple => - Object.freeze({ - ground: "no", - kind: "tuple_type", - typeArgs, - loc, - }); -export const isMVTypeTuple = ($value: MVTypeTuple) => - $value.kind === "tuple_type"; -export type MVTypeTensor = $.MVTypeTensor; -export const MVTypeTensor = ( - typeArgs: readonly $d.DTypeParamRef[], - loc: $c.Loc, -): $.MVTypeTensor => - Object.freeze({ - ground: "no", - kind: "tensor_type", - typeArgs, - loc, - }); -export const isMVTypeTensor = ($value: MVTypeTensor) => - $value.kind === "tensor_type"; -export type SelfType = $.SelfType; -export type MethodGroundType = $.MethodGroundType; diff --git a/src/next/ast/generated/root.ts b/src/next/ast/generated/root.ts index b19d23089b..41a20f641c 100644 --- a/src/next/ast/generated/root.ts +++ b/src/next/ast/generated/root.ts @@ -77,7 +77,7 @@ export type Function = $.Function; export const Function = ( inline: boolean, name: $c.Id, - type_: $t.FnType, + type_: $t.TFunction, body: $.FunctionalBody, loc: $c.Loc, ): $.Function => diff --git a/src/next/ast/generated/type-basic.ts b/src/next/ast/generated/type-basic.ts new file mode 100644 index 0000000000..ecffa4b0d9 --- /dev/null +++ b/src/next/ast/generated/type-basic.ts @@ -0,0 +1,131 @@ +/* eslint-disable @typescript-eslint/no-unnecessary-condition */ +import type * as $c from "@/next/ast/common"; +import type * as $ from "@/next/ast/type-basic"; + +export type BasicType = $.BasicType +export type Signedness = $.Signedness; +export const allSignedness: readonly $.Signedness[] = ["signed", "unsigned"]; +export type IFInt = $.IFInt; +export const IFInt = ( + sign: $.Signedness, + width: number, + loc: $c.Loc, +): $.IFInt => + Object.freeze({ + kind: "FInt", + sign, + width, + loc, + }); +export type VarIntWidth = $.VarIntWidth; +export const allVarIntWidth: readonly $.VarIntWidth[] = ["16", "32"]; +export type IFVarInt = $.IFVarInt; +export const IFVarInt = ( + sign: $.Signedness, + width: $.VarIntWidth, + loc: $c.Loc, +): $.IFVarInt => + Object.freeze({ + kind: "FVarInt", + sign, + width, + loc, + }); +export type IntFormat = $.IntFormat; +export type TInt = $.TInt; +export const TInt = (format: $.IntFormat, loc: $c.Loc): $.TInt => + Object.freeze({ + kind: "TyInt", + format, + loc, + }); +export type SFBits = $.SFBits; +export const SFBits = (bits: number, loc: $c.Loc): $.SFBits => + Object.freeze({ + kind: "SFBits", + bits, + loc, + }); +export type SFRemaining = $.SFRemaining; +export const SFRemaining = (loc: $c.Loc): $.SFRemaining => + Object.freeze({ + kind: "SFRemaining", + loc, + }); +export type SFDefault = $.SFDefault; +export const SFDefault = (loc: $c.Loc): $.SFDefault => + Object.freeze({ + kind: "SFDefault", + loc, + }); +export type SliceFormat = $.SliceFormat; +export type TSlice = $.TSlice; +export const TSlice = (format: $.SliceFormat, loc: $c.Loc): $.TSlice => + Object.freeze({ + kind: "TySlice", + format, + loc, + }); +export type RemFormat = $.RemFormat; +export type TCell = $.TCell; +export const TCell = (format: $.RemFormat, loc: $c.Loc): $.TCell => + Object.freeze({ + kind: "TyCell", + format, + loc, + }); +export type TBuilder = $.TBuilder; +export const TBuilder = (format: $.RemFormat, loc: $c.Loc): $.TBuilder => + Object.freeze({ + kind: "TyBuilder", + format, + loc, + }); +export type TUnit = $.TUnit; +export const TUnit = (loc: $c.Loc): $.TUnit => + Object.freeze({ + kind: "unit_type", + loc, + }); +export type TVoid = $.TVoid; +export const TVoid = (loc: $c.Loc): $.TVoid => + Object.freeze({ + kind: "TypeVoid", + loc, + }); +export type TNull = $.TNull; +export const TNull = (loc: $c.Loc): $.TNull => + Object.freeze({ + kind: "TypeNull", + loc, + }); +export type TBool = $.TBool; +export const TBool = (loc: $c.Loc): $.TBool => + Object.freeze({ + kind: "TypeBool", + loc, + }); +export type TAddress = $.TAddress; +export const TAddress = (loc: $c.Loc): $.TAddress => + Object.freeze({ + kind: "TypeAddress", + loc, + }); +export type TString = $.TString; +export const TString = (loc: $c.Loc): $.TString => + Object.freeze({ + kind: "TypeString", + loc, + }); +export type TStringBuilder = $.TStringBuilder; +export const TStringBuilder = (loc: $c.Loc): $.TStringBuilder => + Object.freeze({ + kind: "TypeStringBuilder", + loc, + }); +export type TStateInit = $.TStateInit; +export const TStateInit = (loc: $c.Loc): $.TStateInit => + Object.freeze({ + kind: "TypeStateInit", + loc, + }); diff --git a/src/next/ast/generated/type-self.ts b/src/next/ast/generated/type-self.ts new file mode 100644 index 0000000000..d7107fdabb --- /dev/null +++ b/src/next/ast/generated/type-self.ts @@ -0,0 +1,142 @@ +/* eslint-disable @typescript-eslint/no-unnecessary-condition */ +import type * as $ from "@/next/ast/type-self"; +import type * as $c from "@/next/ast/common"; +import type * as $d from "@/next/ast/checked-type"; +import type { CTypeDeclRefable } from "@/next/ast/checked"; +import type { BasicType } from "@/next/ast/type-basic"; + +export type SGTBasic = $.SGTRef; +export const SGTBasic = ( + type: BasicType, + loc: $c.Loc, +): $.SGTBasic => + Object.freeze({ + ground: "yes", + kind: "basic", + type, + loc, + }); +export type SGTRef = $.SGTRef; +export const SGTRef = ( + name: $c.TypeId, + type: CTypeDeclRefable, + typeArgs: readonly $.SelfTypeGround[], + loc: $c.Loc, +): $.SGTRef => + Object.freeze({ + ground: "yes", + kind: "type_ref", + name, + type, + typeArgs, + loc, + }); +export type SGTMaybe = $.SGTMaybe; +export const SGTMaybe = ( + type_: $.SelfTypeGround, + loc: $c.Loc, +): $.SGTMaybe => + Object.freeze({ + ground: "yes", + kind: "TypeMaybe", + type: type_, + loc, + }); +export type SGTMap = $.SGTMap; +export const SGTMap = ( + key: $.SelfTypeGround, + value: $.SelfTypeGround, + loc: $c.Loc, +): $.SGTMap => + Object.freeze({ + ground: "yes", + kind: "map_type", + key, + value, + loc, + }); +export type SGTTuple = $.SGTTuple; +export const SGTTuple = ( + typeArgs: readonly $.SelfTypeGround[], + loc: $c.Loc, +): $.SGTTuple => + Object.freeze({ + ground: "yes", + kind: "tuple_type", + typeArgs, + loc, + }); +export type SGTTensor = $.SGTTensor; +export const SGTTensor = ( + typeArgs: readonly $.SelfTypeGround[], + loc: $c.Loc, +): $.SGTTensor => + Object.freeze({ + ground: "yes", + kind: "tensor_type", + typeArgs, + loc, + }); +export type SVTRef = $.SVTRef; +export const SVTRef = ( + name: $c.TypeId, + type: CTypeDeclRefable, + typeArgs: readonly $d.CTParamRef[], + loc: $c.Loc, +): $.SVTRef => + Object.freeze({ + ground: "no", + kind: "type_ref", + name, + type, + typeArgs, + loc, + }); +export type SVTMaybe = $.SVTMaybe; +export const SVTMaybe = ( + type_: $d.CTParamRef, + loc: $c.Loc, +): $.SVTMaybe => + Object.freeze({ + ground: "no", + kind: "TypeMaybe", + type: type_, + loc, + }); +export type SVTMap = $.SVTMap; +export const SVTMap = ( + key: $d.CTParamRef, + value: $d.CTParamRef, + loc: $c.Loc, +): $.SVTMap => + Object.freeze({ + ground: "no", + kind: "map_type", + key, + value, + loc, + }); +export type SVTTuple = $.SVTTuple; +export const SVTTuple = ( + typeArgs: readonly $d.CTParamRef[], + loc: $c.Loc, +): $.SVTTuple => + Object.freeze({ + ground: "no", + kind: "tuple_type", + typeArgs, + loc, + }); +export type SVTTensor = $.SVTTensor; +export const SVTTensor = ( + typeArgs: readonly $d.CTParamRef[], + loc: $c.Loc, +): $.SVTTensor => + Object.freeze({ + ground: "no", + kind: "tensor_type", + typeArgs, + loc, + }); +export type SelfType = $.SelfType; +export type SelfTypeGround = $.SelfTypeGround; diff --git a/src/next/ast/generated/type.ts b/src/next/ast/generated/type.ts index 4987d48f9c..7aadcd0b85 100644 --- a/src/next/ast/generated/type.ts +++ b/src/next/ast/generated/type.ts @@ -1,212 +1,74 @@ /* eslint-disable @typescript-eslint/no-unnecessary-condition */ import type * as $c from "@/next/ast/common"; import type * as $ from "@/next/ast/type"; +import type { BasicType } from "@/next/ast/type-basic"; -export type Signedness = $.Signedness; -export const allSignedness: readonly $.Signedness[] = ["signed", "unsigned"]; -export type IFInt = $.IFInt; -export const IFInt = ( - sign: $.Signedness, - width: number, +export type TBasic = $.TTensor; +export const TBasic = ( + type: BasicType, loc: $c.Loc, -): $.IFInt => +): $.TBasic => Object.freeze({ - kind: "FInt", - sign, - width, + kind: "basic", + type, loc, }); -export const isIFInt = ($value: IFInt) => $value.kind === "FInt"; -export type VarIntWidth = $.VarIntWidth; -export const allVarIntWidth: readonly $.VarIntWidth[] = ["16", "32"]; -export type IFVarInt = $.IFVarInt; -export const IFVarInt = ( - sign: $.Signedness, - width: $.VarIntWidth, - loc: $c.Loc, -): $.IFVarInt => - Object.freeze({ - kind: "FVarInt", - sign, - width, - loc, - }); -export const isIFVarInt = ($value: IFVarInt) => $value.kind === "FVarInt"; -export type IntFormat = $.IntFormat; -export type TypeInt = $.TypeInt; -export const TypeInt = (format: $.IntFormat, loc: $c.Loc): $.TypeInt => - Object.freeze({ - kind: "TyInt", - format, - loc, - }); -export const isTypeInt = ($value: TypeInt) => $value.kind === "TyInt"; -export type SFBits = $.SFBits; -export const SFBits = (bits: number, loc: $c.Loc): $.SFBits => - Object.freeze({ - kind: "SFBits", - bits, - loc, - }); -export const isSFBits = ($value: SFBits) => $value.kind === "SFBits"; -export type SFRemaining = $.SFRemaining; -export const SFRemaining = (loc: $c.Loc): $.SFRemaining => - Object.freeze({ - kind: "SFRemaining", - loc, - }); -export const isSFRemaining = ($value: SFRemaining) => - $value.kind === "SFRemaining"; -export type SFDefault = $.SFDefault; -export const SFDefault = (loc: $c.Loc): $.SFDefault => - Object.freeze({ - kind: "SFDefault", - loc, - }); -export const isSFDefault = ($value: SFDefault) => $value.kind === "SFDefault"; -export type SliceFormat = $.SliceFormat; -export type TypeSlice = $.TypeSlice; -export const TypeSlice = (format: $.SliceFormat, loc: $c.Loc): $.TypeSlice => - Object.freeze({ - kind: "TySlice", - format, - loc, - }); -export const isTypeSlice = ($value: TypeSlice) => $value.kind === "TySlice"; -export type RemFormat = $.RemFormat; -export type TypeCell = $.TypeCell; -export const TypeCell = (format: $.RemFormat, loc: $c.Loc): $.TypeCell => - Object.freeze({ - kind: "TyCell", - format, - loc, - }); -export const isTypeCell = ($value: TypeCell) => $value.kind === "TyCell"; -export type TypeBuilder = $.TypeBuilder; -export const TypeBuilder = (format: $.RemFormat, loc: $c.Loc): $.TypeBuilder => - Object.freeze({ - kind: "TyBuilder", - format, - loc, - }); -export const isTypeBuilder = ($value: TypeBuilder) => - $value.kind === "TyBuilder"; -export type TypeUnit = $.TypeUnit; -export const TypeUnit = (loc: $c.Loc): $.TypeUnit => - Object.freeze({ - kind: "unit_type", - loc, - }); -export const isTypeUnit = ($value: TypeUnit) => $value.kind === "unit_type"; -export type TypeTensor = $.TypeTensor; -export const TypeTensor = ( +export type TTensor = $.TTensor; +export const TTensor = ( typeArgs: readonly $.Type[], loc: $c.Loc, -): $.TypeTensor => +): $.TTensor => Object.freeze({ kind: "tensor_type", typeArgs, loc, }); -export const isTypeTensor = ($value: TypeTensor) => - $value.kind === "tensor_type"; -export type TypeTuple = $.TypeTuple; -export const TypeTuple = ( +export type TTuple = $.TTuple; +export const TTuple = ( typeArgs: readonly $.Type[], loc: $c.Loc, -): $.TypeTuple => +): $.TTuple => Object.freeze({ kind: "tuple_type", typeArgs, loc, }); -export const isTypeTuple = ($value: TypeTuple) => $value.kind === "tuple_type"; -export type TypeCons = $.TypeCons; -export const TypeCons = ( +export type TCons = $.TCons; +export const TCons = ( name: $c.TypeId, typeArgs: readonly $.Type[], loc: $c.Loc, -): $.TypeCons => +): $.TCons => Object.freeze({ kind: "cons_type", name, typeArgs, loc, }); -export const isTypeCons = ($value: TypeCons) => $value.kind === "cons_type"; export type Type = $.Type; -export type TypeMap = $.TypeMap; -export const TypeMap = (key: $.Type, value: $.Type, loc: $c.Loc): $.TypeMap => +export type TMap = $.TMap; +export const TMap = (key: $.Type, value: $.Type, loc: $c.Loc): $.TMap => Object.freeze({ kind: "map_type", key, value, loc, }); -export const isTypeMap = ($value: TypeMap) => $value.kind === "map_type"; -export type TypeVoid = $.TypeVoid; -export const TypeVoid = (loc: $c.Loc): $.TypeVoid => - Object.freeze({ - kind: "TypeVoid", - loc, - }); -export const isTypeVoid = ($value: TypeVoid) => $value.kind === "TypeVoid"; -export type TypeNull = $.TypeNull; -export const TypeNull = (loc: $c.Loc): $.TypeNull => - Object.freeze({ - kind: "TypeNull", - loc, - }); -export const isTypeNull = ($value: TypeNull) => $value.kind === "TypeNull"; -export type TypeBool = $.TypeBool; -export const TypeBool = (loc: $c.Loc): $.TypeBool => - Object.freeze({ - kind: "TypeBool", - loc, - }); -export const isTypeBool = ($value: TypeBool) => $value.kind === "TypeBool"; -export type TypeAddress = $.TypeAddress; -export const TypeAddress = (loc: $c.Loc): $.TypeAddress => - Object.freeze({ - kind: "TypeAddress", - loc, - }); -export const isTypeAddress = ($value: TypeAddress) => - $value.kind === "TypeAddress"; -export type TypeString = $.TypeString; -export const TypeString = (loc: $c.Loc): $.TypeString => - Object.freeze({ - kind: "TypeString", - loc, - }); -export const isTypeString = ($value: TypeString) => - $value.kind === "TypeString"; -export type TypeStringBuilder = $.TypeStringBuilder; -export const TypeStringBuilder = (loc: $c.Loc): $.TypeStringBuilder => - Object.freeze({ - kind: "TypeStringBuilder", - loc, - }); -export const isTypeStringBuilder = ($value: TypeStringBuilder) => - $value.kind === "TypeStringBuilder"; -export type TypeBounced = $.TypeBounced; -export const TypeBounced = (type_: $.Type, loc: $c.Loc): $.TypeBounced => +export type TBounced = $.TBounced; +export const TBounced = (type_: $.Type, loc: $c.Loc): $.TBounced => Object.freeze({ kind: "TypeBounced", type: type_, loc, }); -export const isTypeBounced = ($value: TypeBounced) => - $value.kind === "TypeBounced"; -export type TypeMaybe = $.TypeMaybe; -export const TypeMaybe = (type_: $.Type, loc: $c.Loc): $.TypeMaybe => +export type TMaybe = $.TMaybe; +export const TMaybe = (type_: $.Type, loc: $c.Loc): $.TMaybe => Object.freeze({ kind: "TypeMaybe", type: type_, loc, }); -export const isTypeMaybe = ($value: TypeMaybe) => $value.kind === "TypeMaybe"; export type TypedParameter = $.TypedParameter; export const TypedParameter = ( name: $c.OptionalId, @@ -218,35 +80,27 @@ export const TypedParameter = ( type: type_, loc, }); -export type FnType = $.FnType; -export const FnType = ( +export type TFunction = $.TFunction; +export const TFunction = ( typeParams: readonly $c.TypeId[], params: readonly $.TypedParameter[], returnType: $.Type, -): $.FnType => +): $.TFunction => Object.freeze({ typeParams, params, returnType, }); -export type MethodFnType = $.MethodFnType; -export const MethodFnType = ( +export type TMethod = $.TMethod; +export const TMethod = ( typeParams: readonly $c.TypeId[], self: $.Type, args: readonly $.TypedParameter[], returnType: $.Type, -): $.MethodFnType => +): $.TMethod => Object.freeze({ typeParams, self, args, returnType, - }); -export type TypeStateInit = $.TypeStateInit; -export const TypeStateInit = (loc: $c.Loc): $.TypeStateInit => - Object.freeze({ - kind: "TypeStateInit", - loc, - }); -export const isTypeStateInit = ($value: TypeStateInit) => - $value.kind === "TypeStateInit"; + }); \ No newline at end of file diff --git a/src/next/ast/index.ts b/src/next/ast/index.ts index 02e21e13db..cf136c094b 100644 --- a/src/next/ast/index.ts +++ b/src/next/ast/index.ts @@ -1,14 +1,18 @@ export * from "@/next/ast/generated/common"; +export * from "@/next/ast/generated/type-basic"; + +export * from "@/next/ast/generated/root"; export * from "@/next/ast/generated/expression"; export * from "@/next/ast/generated/statement"; export * from "@/next/ast/generated/type"; -export * from "@/next/ast/generated/dtype"; -export * from "@/next/ast/generated/mtype"; -export * from "@/next/ast/generated/via"; +export * from "@/next/ast/generated/type-self"; + export * from "@/next/ast/generated/checked"; export * from "@/next/ast/generated/checked-expr"; +export * from "@/next/ast/generated/checked-type"; export * from "@/next/ast/generated/checked-stmt"; -export * from "@/next/ast/generated/root"; + +export * from "@/next/ast/generated/via"; export * from "@/next/ast/generated/value"; export * from "@/next/ast/generated/effects"; export * from "@/next/ast/lazy"; diff --git a/src/next/ast/lowered-expr.ts b/src/next/ast/lowered-expr.ts new file mode 100644 index 0000000000..089bf00bef --- /dev/null +++ b/src/next/ast/lowered-expr.ts @@ -0,0 +1,228 @@ +import type { Id, Loc, TypeId } from "@/next/ast/common"; +import type { + BinaryOperation, + NumberBase, + UnaryOperation, +} from "@/next/ast/expression"; +import type { Ordered } from "@/next/ast/checked"; +// TODO: this seems incorrect +import type { SelfType } from "@/next/ast/type-self"; +import type { LTBasic, LType, LTypeMap, LTypeRef, LTypeTensor, LTypeTuple } from "@/next/ast/lowered-type"; + +export type LTypeArgs = ReadonlyMap; + +export type LExpr = + | LOpBinary + | LOpUnary + | LConditional + | LMethodCall + | LStaticCall + | LStaticMethodCall + | LFieldAccess + | LStructInstance + | LInitOf + | LCodeOf + | LNumber + | LBoolean + | LNull + | LString + | LVar + | LSelf + | LUnit + | LTuple + | LTensor + | LMapLiteral + | LSetLiteral; + +export type LLValue = LLVar | LLSelf | LLFieldAccess; + +export type LLSelf = { + readonly kind: "self"; + readonly computedType: SelfType; + readonly loc: Loc; +}; + +export type LLVar = { + readonly kind: "var"; + readonly name: string; + readonly computedType: LType; + readonly loc: Loc; +}; + +export type LLFieldAccess = { + readonly kind: "field_access"; + readonly aggregate: LLValue; + readonly field: Id; + readonly computedType: LType; + readonly loc: Loc; +}; + +export type LSelf = { + readonly kind: "self"; + readonly computedType: SelfType; + readonly loc: Loc; +}; + +export type LVar = { + readonly kind: "var"; + readonly name: string; + readonly computedType: LType; + readonly loc: Loc; +}; + +export type LNumber = { + readonly kind: "number"; + readonly base: NumberBase; + readonly value: bigint; + readonly computedType: LTBasic; + readonly loc: Loc; +}; + +export type LBoolean = { + readonly kind: "boolean"; + readonly value: boolean; + readonly computedType: LTBasic; + readonly loc: Loc; +}; + +export type LString = { + readonly kind: "string"; + readonly value: string; + readonly computedType: LTBasic; + readonly loc: Loc; +}; + +export type LNull = { + readonly kind: "null"; + readonly computedType: LTBasic; + readonly loc: Loc; +}; + +export type LOpBinary = { + readonly kind: "op_binary"; + readonly op: BinaryOperation; + readonly left: LExpr; + readonly right: LExpr; + readonly typeArgs: LTypeArgs; + readonly computedType: LType; + readonly loc: Loc; +}; + +export type LOpUnary = { + readonly kind: "op_unary"; + readonly op: UnaryOperation; + readonly operand: LExpr; + readonly typeArgs: LTypeArgs; + readonly computedType: LType; + readonly loc: Loc; +}; + +export type LFieldAccess = { + readonly kind: "field_access"; + readonly aggregate: LExpr; + readonly field: Id; + readonly computedType: LType; + readonly loc: Loc; +}; + +export type LMethodCall = { + readonly kind: "method_call"; + readonly self: LExpr; + readonly method: Id; + // NB! these are substitutions to self type + readonly args: readonly LExpr[]; + readonly typeArgs: LTypeArgs; + readonly computedType: LType; + readonly loc: Loc; +}; + +// builtins or top-level (module) functions +export type LStaticCall = { + readonly kind: "static_call"; + readonly function: Id; + readonly typeArgs: LTypeArgs; + readonly args: readonly LExpr[]; + readonly computedType: LType; + readonly loc: Loc; +}; + +export type LStaticMethodCall = { + readonly kind: "static_method_call"; + readonly self: TypeId; + readonly typeArgs: LTypeArgs; + readonly function: Id; + readonly args: readonly LExpr[]; + readonly computedType: LType; + readonly loc: Loc; +}; + +export type LStructInstance = { + readonly kind: "struct_instance"; + readonly fields: Ordered; + readonly computedType: LTypeRef; + readonly loc: Loc; +}; + +export type LMapLiteral = { + readonly kind: "map_literal"; + readonly fields: readonly DMapField[]; + readonly computedType: LTypeMap; + readonly loc: Loc; +}; + +export type DMapField = { + readonly key: LExpr; + readonly value: LExpr; +}; + +export type LSetLiteral = { + readonly kind: "set_literal"; + readonly valueType: LType; + readonly fields: readonly LExpr[]; + readonly computedType: LType; + readonly loc: Loc; +}; + +export type LInitOf = { + readonly kind: "init_of"; + readonly contract: TypeId; + readonly args: readonly LExpr[]; + readonly computedType: LType; + readonly loc: Loc; +}; + +export type LCodeOf = { + readonly kind: "code_of"; + readonly contract: TypeId; + readonly computedType: LType; + readonly loc: Loc; +}; + +export type LConditional = { + readonly kind: "conditional"; + readonly condition: LExpr; + readonly thenBranch: LExpr; + readonly elseBranch: LExpr; + readonly computedType: LType; + readonly loc: Loc; +}; + +export type LUnit = { + readonly kind: "unit"; + readonly computedType: LTBasic; + readonly loc: Loc; +}; + +export type LTuple = { + readonly kind: "tuple"; + readonly children: readonly LExpr[]; + readonly computedType: LTypeTuple; + readonly loc: Loc; +}; + +export type LTensor = { + readonly kind: "tensor"; + readonly children: readonly LExpr[]; + readonly computedType: LTypeTensor; + readonly loc: Loc; +}; diff --git a/src/next/ast/lowered-stmt.ts b/src/next/ast/lowered-stmt.ts new file mode 100644 index 0000000000..2d9caf627c --- /dev/null +++ b/src/next/ast/lowered-stmt.ts @@ -0,0 +1,125 @@ +import type { Ordered } from "@/next/ast/checked"; +import type { LExpr, LLValue } from "@/next/ast/lowered-expr"; +import type { Id, Loc, OptionalId, TypeId } from "@/next/ast/common"; +import type { AugmentedAssignOperation } from "@/next/ast/statement"; + +export type LStmt = + | LStmtLet + | LStmtReturn + | LStmtExpression + | LStmtAssign + | LStmtAugmentedAssign + | LStmtCondition + | LStmtWhile + | LStmtUntil + | LStmtRepeat + | LStmtTry + | LStmtForEach + | LStmtDestruct + | LStmtBlock; + +export type LStmtList = readonly LStmt[]; + +export type LStmtLet = { + readonly kind: "let"; + readonly name: OptionalId; + readonly expression: LExpr; + readonly loc: Loc; +}; + +export type LStmtReturn = { + readonly kind: "return"; + readonly expression: LExpr | undefined; + readonly loc: Loc; +}; + +export type LStmtExpression = { + readonly kind: "expression"; + readonly expression: LExpr; + readonly loc: Loc; +}; + +export type LStmtAssign = { + readonly kind: "assign"; + readonly path: LLValue; + readonly expression: LExpr; + readonly loc: Loc; +}; + +export type LStmtAugmentedAssign = { + readonly kind: "augmentedassign"; + readonly op: AugmentedAssignOperation; + readonly path: LLValue; + readonly expression: LExpr; + readonly loc: Loc; +}; + +export type LStmtCondition = { + readonly kind: "condition"; + readonly condition: LExpr; + readonly trueStatements: LStmtList; + readonly falseStatements: LStmtList | undefined; + readonly loc: Loc; +}; + +export type LStmtWhile = { + readonly kind: "while"; + readonly condition: LExpr; + readonly statements: LStmtList; + readonly loc: Loc; +}; + +export type LStmtUntil = { + readonly kind: "until"; + readonly condition: LExpr; + readonly statements: LStmtList; + readonly loc: Loc; +}; + +export type LStmtRepeat = { + readonly kind: "repeat"; + readonly iterations: LExpr; + readonly statements: LStmtList; + readonly loc: Loc; +}; + +export type LStmtTry = { + readonly kind: "try"; + readonly statements: LStmtList; + readonly catchBlock: DCatchBlock | undefined; + readonly loc: Loc; +}; + +export type DCatchBlock = { + readonly name: OptionalId; + readonly statements: LStmtList; +}; + +export type LStmtForEach = { + readonly kind: "foreach"; + readonly keyName: OptionalId; + readonly valueName: OptionalId; + readonly map: LExpr; + readonly statements: LStmtList; + readonly loc: Loc; +}; + +export type LStmtDestruct = { + readonly kind: "destruct"; + readonly type: TypeId; + readonly identifiers: Ordered; + readonly ignoreUnspecifiedFields: boolean; + readonly expression: LExpr; + readonly loc: Loc; +}; + +export type DestructPattern = { + readonly field: Id; + readonly variable: OptionalId; +}; + +export type LStmtBlock = { + readonly kind: "block"; + readonly statements: LStmtList; + readonly loc: Loc; +}; diff --git a/src/next/ast/lowered-type.ts b/src/next/ast/lowered-type.ts new file mode 100644 index 0000000000..34e482dd5a --- /dev/null +++ b/src/next/ast/lowered-type.ts @@ -0,0 +1,80 @@ +import type { CTypeDeclRefable } from "@/next/ast/checked"; +import type { Loc, TypeId } from "@/next/ast/common"; +import type { BasicType } from "@/next/ast/type-basic"; + +export type LNotSet = { + readonly kind: "not-set"; +}; + +export type LType = + | LTypeRef + | LTypeAliasRef + | LTypeParamRef + | LTypeMap + | LTypeBounced + | LTypeMaybe + | LTypeTuple + | LTypeTensor + | LTBasic; + +export type LTBasic = { + readonly kind: "basic"; + readonly type: BasicType; + readonly loc: Loc; +}; + +export type LTypeRef = { + readonly kind: "type_ref"; + readonly name: TypeId; + readonly type: CTypeDeclRefable; + readonly typeArgs: readonly LType[]; + // readonly funcType: Lazy; + // readonly alloc: Lazy + readonly loc: Loc; +}; + +export type LTypeAliasRef = { + readonly kind: "TypeAlias"; + readonly name: TypeId; + readonly type: LType; + readonly typeArgs: readonly LType[]; + readonly loc: Loc; +}; + +export type LTypeParamRef = { + readonly kind: "TypeParam"; + readonly name: TypeId; + readonly loc: Loc; +}; + +export type LTypeBounced = { + readonly kind: "TypeBounced"; + // name of the message type + readonly name: TypeId; + readonly loc: Loc; +}; + +export type LTypeMaybe = { + readonly kind: "TypeMaybe"; + readonly type: LType; + readonly loc: Loc; +}; + +export type LTypeMap = { + readonly kind: "map_type"; + readonly key: LType; + readonly value: LType; + readonly loc: Loc; +}; + +export type LTypeTuple = { + readonly kind: "tuple_type"; + readonly typeArgs: readonly LType[]; + readonly loc: Loc; +}; + +export type LTypeTensor = { + readonly kind: "tensor_type"; + readonly typeArgs: readonly LType[]; + readonly loc: Loc; +}; diff --git a/src/next/ast/lowered.ts b/src/next/ast/lowered.ts index a11c19ee5e..3ac43f4246 100644 --- a/src/next/ast/lowered.ts +++ b/src/next/ast/lowered.ts @@ -1,8 +1,8 @@ import type { Effects } from "@/next/ast/effects"; -import type { DecodedStatement } from "@/next/ast/checked-stmt"; +import type { LStmt } from "@/next/ast/lowered-stmt"; import type { FuncId, Loc, OptionalId, TypeId } from "@/next/ast/common"; -import type { DecodedType, DTypeRef, DTypeBounced } from "@/next/ast/dtype"; -import type { SelfType } from "@/next/ast/mtype"; +import type { LType, LTypeRef, LTypeBounced } from "@/next/ast/lowered-type"; +import type { SelfType } from "@/next/ast/type-self"; import type { AsmInstruction, AsmShuffle, @@ -10,7 +10,7 @@ import type { } from "@/next/ast/root"; import type { Value } from "@/next/ast/value"; -export type LAst = { +export type LSource = { readonly typeDecls: ReadonlyMap; readonly functions: ReadonlyMap; readonly constants: ReadonlyMap; @@ -27,7 +27,7 @@ export type LTypeDeclSig = export type LConstSig = { readonly initializer: Value; - readonly type: DecodedType; + readonly type: LType; }; export type LFnSig = { @@ -37,7 +37,7 @@ export type LFnSig = { }; export type LStatements = { - readonly body: readonly DecodedStatement[]; + readonly body: readonly LStmt[]; readonly effects: Effects; }; @@ -66,7 +66,7 @@ export type LExtSig = { export type LAliasSig = { readonly kind: "alias"; readonly typeParams: LTypeParams; - readonly type: DecodedType; + readonly type: LType; }; export type LInitSig = LInitEmpty | LInitSimple | LInitFn; @@ -90,7 +90,7 @@ export type LInitFn = { readonly statements: LStatements; }; export type LInitParam = { - readonly type: DecodedType; + readonly type: LType; readonly init: undefined | Value; readonly loc: Loc; }; @@ -121,13 +121,13 @@ export type LReceivers = { export type LFieldish = LInhFieldSig | LFieldConstSig; export type LInhFieldSig = { readonly kind: "field"; - readonly type: DecodedType; + readonly type: LType; readonly init: Value | undefined; }; export type LFieldConstSig = { readonly kind: "constant"; readonly overridable: boolean; - readonly type: DecodedType; + readonly type: LType; readonly init: Expr; }; @@ -157,7 +157,7 @@ export type LOpcodeRecv = LMessageRecv | LStringRecv; export type LMessageRecv = { readonly kind: "binary"; readonly name: OptionalId; - readonly type: DTypeRef | DTypeBounced; + readonly type: LTypeRef | LTypeBounced; readonly statements: LStatements; }; export type LMessageAnyRecv = { @@ -199,7 +199,7 @@ export type LDecodedFnType = { readonly kind: "DecodedFnType"; readonly typeParams: LTypeParams; readonly params: LParameters; - readonly returnType: DecodedType; + readonly returnType: LType; }; export type LDecodedMethodType = { @@ -208,12 +208,12 @@ export type LDecodedMethodType = { readonly typeParams: LTypeParams; readonly self: SelfType; readonly params: LParameters; - readonly returnType: DecodedType; + readonly returnType: LType; }; export type LDecodedParameter = { readonly name: OptionalId; - readonly type: DecodedType; + readonly type: LType; readonly loc: Loc; }; @@ -229,7 +229,7 @@ export type LParameters = { export type LParameter = { readonly name: OptionalId; - readonly type: DecodedType; + readonly type: LType; readonly loc: Loc; }; diff --git a/src/next/ast/mtype.ts b/src/next/ast/mtype.ts deleted file mode 100644 index 7804502bc5..0000000000 --- a/src/next/ast/mtype.ts +++ /dev/null @@ -1,124 +0,0 @@ -import type { TypeDeclRefable } from "@/next/ast/checked"; -import type { Loc, TypeId } from "@/next/ast/common"; -import type { DTypeParamRef } from "@/next/ast/dtype"; -import type * as Ast from "@/next/ast/type"; - -export type SelfType = - | MethodGroundType - | MVTypeRef - | MVTypeMap - | MVTypeMaybe - | MVTypeTuple - | MVTypeTensor; - -export type MethodGroundType = - | MGTypeRef - | MGTypeMap - | MGTypeMaybe - | MGTypeTuple - | MGTypeTensor - | MGTypeInt - | MGTypeSlice - | MGTypeCell - | MGTypeBuilder - | MGTypeUnit - | MGTypeVoid - | MGTypeNull - | MGTypeBool - | MGTypeAddress - | MGTypeString - | MGTypeStateInit - | MGTypeStringBuilder; - -export type Ground = T & { - readonly ground: "yes"; -}; - -export type MGTypeInt = Ground; -export type MGTypeSlice = Ground; -export type MGTypeCell = Ground; -export type MGTypeBuilder = Ground; -export type MGTypeUnit = Ground; -export type MGTypeVoid = Ground; -export type MGTypeNull = Ground; -export type MGTypeBool = Ground; -export type MGTypeAddress = Ground; -export type MGTypeStateInit = Ground; -export type MGTypeString = Ground; -export type MGTypeStringBuilder = Ground; - -export type MGTypeRef = { - readonly ground: "yes"; - readonly kind: "type_ref"; - readonly name: TypeId; - readonly type: TypeDeclRefable; - readonly typeArgs: readonly MethodGroundType[]; - readonly loc: Loc; -}; - -export type MGTypeMaybe = { - readonly ground: "yes"; - readonly kind: "TypeMaybe"; - readonly type: MethodGroundType; - readonly loc: Loc; -}; - -export type MGTypeMap = { - readonly ground: "yes"; - readonly kind: "map_type"; - readonly key: MethodGroundType; - readonly value: MethodGroundType; - readonly loc: Loc; -}; - -export type MGTypeTuple = { - readonly ground: "yes"; - readonly kind: "tuple_type"; - readonly typeArgs: readonly MethodGroundType[]; - readonly loc: Loc; -}; - -export type MGTypeTensor = { - readonly ground: "yes"; - readonly kind: "tensor_type"; - readonly typeArgs: readonly MethodGroundType[]; - readonly loc: Loc; -}; - -export type MVTypeRef = { - readonly ground: "no"; - readonly kind: "type_ref"; - readonly name: TypeId; - readonly type: TypeDeclRefable; - readonly typeArgs: readonly DTypeParamRef[]; - readonly loc: Loc; -}; - -export type MVTypeMaybe = { - readonly ground: "no"; - readonly kind: "TypeMaybe"; - readonly type: DTypeParamRef; - readonly loc: Loc; -}; - -export type MVTypeMap = { - readonly ground: "no"; - readonly kind: "map_type"; - readonly key: DTypeParamRef; - readonly value: DTypeParamRef; - readonly loc: Loc; -}; - -export type MVTypeTuple = { - readonly ground: "no"; - readonly kind: "tuple_type"; - readonly typeArgs: readonly DTypeParamRef[]; - readonly loc: Loc; -}; - -export type MVTypeTensor = { - readonly ground: "no"; - readonly kind: "tensor_type"; - readonly typeArgs: readonly DTypeParamRef[]; - readonly loc: Loc; -}; diff --git a/src/next/ast/root.ts b/src/next/ast/root.ts index 9484165a38..648c406d1c 100644 --- a/src/next/ast/root.ts +++ b/src/next/ast/root.ts @@ -1,7 +1,7 @@ import type { FuncId, Id, Loc, TypeId, Language } from "@/next/ast/common"; import type { Expression, Number, String } from "@/next/ast/expression"; import type { Statement } from "@/next/ast/statement"; -import type { FnType, Type, TypedParameter } from "@/next/ast/type"; +import type { TFunction, Type, TypedParameter } from "@/next/ast/type"; import type { RelativePath } from "@/next/fs"; export type Source = { @@ -115,7 +115,7 @@ export type Function = { readonly kind: "function"; readonly inline: boolean; readonly name: Id; - readonly type: FnType; + readonly type: TFunction; readonly body: FunctionalBody; readonly loc: Loc; }; diff --git a/src/next/ast/type-basic.ts b/src/next/ast/type-basic.ts new file mode 100644 index 0000000000..f9c060b5b8 --- /dev/null +++ b/src/next/ast/type-basic.ts @@ -0,0 +1,107 @@ +import type { Loc } from "@/next/ast/common"; + +export type BasicType = TInt + | TSlice + | TCell + | TBuilder + | TUnit + | TVoid + | TNull + | TBool + | TAddress + | TStateInit + | TString + | TStringBuilder + +export type TUnit = { + readonly kind: "unit_type"; + readonly loc: Loc; +}; + +export type TInt = { + readonly kind: "TyInt"; + readonly format: IntFormat; + readonly loc: Loc; +}; +export type IntFormat = IFInt | IFVarInt; +export type IFInt = { + readonly kind: "FInt"; + readonly sign: Signedness; + readonly width: number; + readonly loc: Loc; +}; +export type IFVarInt = { + readonly kind: "FVarInt"; + readonly sign: Signedness; + readonly width: VarIntWidth; + readonly loc: Loc; +}; +export type VarIntWidth = "16" | "32"; +export type Signedness = "signed" | "unsigned"; + +export type TSlice = { + readonly kind: "TySlice"; + readonly format: SliceFormat; + readonly loc: Loc; +}; +export type SliceFormat = SFBits | SFRemaining | SFDefault; +export type SFBits = { + readonly kind: "SFBits"; + readonly bits: number; + readonly loc: Loc; +}; +export type SFRemaining = { + readonly kind: "SFRemaining"; + readonly loc: Loc; +}; +export type SFDefault = { + readonly kind: "SFDefault"; + readonly loc: Loc; +}; + +export type TCell = { + readonly kind: "TyCell"; + readonly format: RemFormat; + readonly loc: Loc; +}; +export type TBuilder = { + readonly kind: "TyBuilder"; + readonly format: RemFormat; + readonly loc: Loc; +}; +export type RemFormat = SFRemaining | SFDefault; + +export type TVoid = { + readonly kind: "TypeVoid"; + readonly loc: Loc; +}; + +export type TNull = { + readonly kind: "TypeNull"; + readonly loc: Loc; +}; + +export type TBool = { + readonly kind: "TypeBool"; + readonly loc: Loc; +}; + +export type TAddress = { + readonly kind: "TypeAddress"; + readonly loc: Loc; +}; + +export type TStateInit = { + readonly kind: "TypeStateInit"; + readonly loc: Loc; +}; + +export type TString = { + readonly kind: "TypeString"; + readonly loc: Loc; +}; + +export type TStringBuilder = { + readonly kind: "TypeStringBuilder"; + readonly loc: Loc; +}; \ No newline at end of file diff --git a/src/next/ast/type-self.ts b/src/next/ast/type-self.ts new file mode 100644 index 0000000000..2fbdabe0f0 --- /dev/null +++ b/src/next/ast/type-self.ts @@ -0,0 +1,103 @@ +import type { CTypeDeclRefable } from "@/next/ast/checked"; +import type { Loc, TypeId } from "@/next/ast/common"; +import type { CTParamRef } from "@/next/ast/checked-type"; +import type { BasicType } from "@/next/ast/type-basic"; + +export type SelfType = + | SelfTypeGround + | SVTRef + | SVTMap + | SVTMaybe + | SVTTuple + | SVTTensor; + +export type SelfTypeGround = + | SGTRef + | SGTMap + | SGTMaybe + | SGTTuple + | SGTTensor + | SGTBasic; + +export type SGTBasic = { + readonly ground: "yes"; + readonly kind: "basic"; + readonly type: BasicType; + readonly loc: Loc; +}; + +export type SGTRef = { + readonly ground: "yes"; + readonly kind: "type_ref"; + readonly name: TypeId; + readonly type: CTypeDeclRefable; + readonly typeArgs: readonly SelfTypeGround[]; + readonly loc: Loc; +}; + +export type SGTMaybe = { + readonly ground: "yes"; + readonly kind: "TypeMaybe"; + readonly type: SelfTypeGround; + readonly loc: Loc; +}; + +export type SGTMap = { + readonly ground: "yes"; + readonly kind: "map_type"; + readonly key: SelfTypeGround; + readonly value: SelfTypeGround; + readonly loc: Loc; +}; + +export type SGTTuple = { + readonly ground: "yes"; + readonly kind: "tuple_type"; + readonly typeArgs: readonly SelfTypeGround[]; + readonly loc: Loc; +}; + +export type SGTTensor = { + readonly ground: "yes"; + readonly kind: "tensor_type"; + readonly typeArgs: readonly SelfTypeGround[]; + readonly loc: Loc; +}; + +export type SVTRef = { + readonly ground: "no"; + readonly kind: "type_ref"; + readonly name: TypeId; + readonly type: CTypeDeclRefable; + readonly typeArgs: readonly CTParamRef[]; + readonly loc: Loc; +}; + +export type SVTMaybe = { + readonly ground: "no"; + readonly kind: "TypeMaybe"; + readonly type: CTParamRef; + readonly loc: Loc; +}; + +export type SVTMap = { + readonly ground: "no"; + readonly kind: "map_type"; + readonly key: CTParamRef; + readonly value: CTParamRef; + readonly loc: Loc; +}; + +export type SVTTuple = { + readonly ground: "no"; + readonly kind: "tuple_type"; + readonly typeArgs: readonly CTParamRef[]; + readonly loc: Loc; +}; + +export type SVTTensor = { + readonly ground: "no"; + readonly kind: "tensor_type"; + readonly typeArgs: readonly CTParamRef[]; + readonly loc: Loc; +}; diff --git a/src/next/ast/type.ts b/src/next/ast/type.ts index c16945f15b..d59d2ab63e 100644 --- a/src/next/ast/type.ts +++ b/src/next/ast/type.ts @@ -1,12 +1,13 @@ import type { Loc, OptionalId, TypeId } from "@/next/ast/common"; +import type { BasicType } from "@/next/ast/type-basic"; -export type FnType = { +export type TFunction = { readonly typeParams: readonly TypeId[]; readonly params: readonly TypedParameter[]; readonly returnType: Type; }; -export type MethodFnType = { +export type TMethod = { readonly typeParams: readonly TypeId[]; readonly self: Type; readonly args: readonly TypedParameter[]; @@ -20,150 +21,52 @@ export type TypedParameter = { }; export type Type = - | TypeMap - | TypeCons - | TypeInt - | TypeSlice - | TypeCell - | TypeBuilder - | TypeTuple - | TypeUnit - | TypeTensor - | TypeVoid - | TypeNull - | TypeBool - | TypeAddress - | TypeStateInit - | TypeString - | TypeStringBuilder - | TypeBounced - | TypeMaybe; + | TMap + | TCons + | TTuple + | TTensor + | TBounced + | TMaybe + | TBasic; -export type TypeCons = { - readonly kind: "cons_type"; - readonly name: TypeId; - readonly typeArgs: readonly Type[]; - readonly loc: Loc; -}; - -export type TypeVoid = { - readonly kind: "TypeVoid"; - readonly loc: Loc; -}; - -export type TypeNull = { - readonly kind: "TypeNull"; - readonly loc: Loc; -}; - -export type TypeBool = { - readonly kind: "TypeBool"; +export type TBasic = { + readonly kind: "basic"; + readonly type: BasicType; readonly loc: Loc; }; -export type TypeAddress = { - readonly kind: "TypeAddress"; - readonly loc: Loc; -}; - -export type TypeStateInit = { - readonly kind: "TypeStateInit"; - readonly loc: Loc; -}; - -export type TypeString = { - readonly kind: "TypeString"; - readonly loc: Loc; -}; - -export type TypeStringBuilder = { - readonly kind: "TypeStringBuilder"; +export type TCons = { + readonly kind: "cons_type"; + readonly name: TypeId; + readonly typeArgs: readonly Type[]; readonly loc: Loc; }; -export type TypeBounced = { +export type TBounced = { readonly kind: "TypeBounced"; readonly type: Type; readonly loc: Loc; }; -export type TypeMaybe = { +export type TMaybe = { readonly kind: "TypeMaybe"; readonly type: Type; readonly loc: Loc; }; -export type TypeInt = { - readonly kind: "TyInt"; - readonly format: IntFormat; - readonly loc: Loc; -}; -export type IntFormat = IFInt | IFVarInt; -export type IFInt = { - readonly kind: "FInt"; - readonly sign: Signedness; - readonly width: number; - readonly loc: Loc; -}; -export type IFVarInt = { - readonly kind: "FVarInt"; - readonly sign: Signedness; - readonly width: VarIntWidth; - readonly loc: Loc; -}; -export type VarIntWidth = "16" | "32"; -export type Signedness = "signed" | "unsigned"; - -export type TypeSlice = { - readonly kind: "TySlice"; - readonly format: SliceFormat; - readonly loc: Loc; -}; -export type SliceFormat = SFBits | SFRemaining | SFDefault; -export type SFBits = { - readonly kind: "SFBits"; - readonly bits: number; - readonly loc: Loc; -}; -export type SFRemaining = { - readonly kind: "SFRemaining"; - readonly loc: Loc; -}; -export type SFDefault = { - readonly kind: "SFDefault"; - readonly loc: Loc; -}; - -export type TypeCell = { - readonly kind: "TyCell"; - readonly format: RemFormat; - readonly loc: Loc; -}; -export type TypeBuilder = { - readonly kind: "TyBuilder"; - readonly format: RemFormat; - readonly loc: Loc; -}; -export type RemFormat = SFRemaining | SFDefault; - -export type TypeTuple = { +export type TTuple = { readonly kind: "tuple_type"; readonly typeArgs: readonly Type[]; readonly loc: Loc; }; -export type TypeUnit = { - readonly kind: "unit_type"; - readonly loc: Loc; -}; - -export type TypeTensor = { +export type TTensor = { readonly kind: "tensor_type"; readonly typeArgs: readonly Type[]; readonly loc: Loc; }; -export type TypeMap = { +export type TMap = { readonly kind: "map_type"; readonly key: Type; // any type except tensor readonly value: Type; // any type except tensor diff --git a/src/next/grammar/index.ts b/src/next/grammar/index.ts index b4dc043b16..3d0178bfab 100644 --- a/src/next/grammar/index.ts +++ b/src/next/grammar/index.ts @@ -341,52 +341,52 @@ const parseStructInstance = }; const parseBouncedArgs = - (typeArgs: $ast.typeArgs, range: Ast.Range): Handler => + (typeArgs: $ast.typeArgs, range: Ast.Range): Handler => (ctx) => { const args = parseList(typeArgs); const [head] = args; // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (args.length !== 1 || !head) { ctx.err.typeArity("bounced", 1)(range); - return Ast.TypeBounced( - Ast.TypeCons(Ast.TypeId("ERROR", range), [], range), + return Ast.TBounced( + Ast.TCons(Ast.TypeId("ERROR", range), [], range), range, ); } - return Ast.TypeBounced(parseType(head)(ctx), range); + return Ast.TBounced(parseType(head)(ctx), range); }; const parseMaybeArgs = - (typeArgs: $ast.typeArgs, range: Ast.Range): Handler => + (typeArgs: $ast.typeArgs, range: Ast.Range): Handler => (ctx) => { const args = parseList(typeArgs); const [head] = args; // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (args.length !== 1 || !head) { ctx.err.typeArity("Maybe", 1)(range); - return Ast.TypeMaybe( - Ast.TypeCons(Ast.TypeId("ERROR", range), [], range), + return Ast.TMaybe( + Ast.TCons(Ast.TypeId("ERROR", range), [], range), range, ); } - return Ast.TypeMaybe(parseType(head)(ctx), range); + return Ast.TMaybe(parseType(head)(ctx), range); }; const parseMapArgs = - (typeArgs: $ast.typeArgs, range: Ast.Range): Handler => + (typeArgs: $ast.typeArgs, range: Ast.Range): Handler => (ctx) => { const args = parseList(typeArgs); const [keyType, valueType] = args; // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (args.length !== 2 || !keyType || !valueType) { ctx.err.mapArgCount()(range); - return Ast.TypeMap( - Ast.TypeCons(Ast.TypeId("ERROR", range), [], range), - Ast.TypeCons(Ast.TypeId("ERROR", range), [], range), + return Ast.TMap( + Ast.TCons(Ast.TypeId("ERROR", range), [], range), + Ast.TCons(Ast.TypeId("ERROR", range), [], range), range, ); } - return Ast.TypeMap( + return Ast.TMap( parseType(keyType)(ctx), parseType(valueType)(ctx), range, @@ -414,22 +414,22 @@ const parseMapField = }; const parseSetArgs = - (typeArgs: $ast.typeArgs, range: Ast.Range): Handler => + (typeArgs: $ast.typeArgs, range: Ast.Range): Handler => (ctx) => { const args = parseList(typeArgs); const [valueType] = args; // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (args.length !== 1 || !valueType) { ctx.err.setArgCount()(range); - return Ast.TypeMap( - Ast.TypeCons(Ast.TypeId("ERROR", range), [], range), - Ast.TypeUnit(range), + return Ast.TMap( + Ast.TCons(Ast.TypeId("ERROR", range), [], range), + Ast.TBasic(Ast.TUnit(range), range), range, ); } - return Ast.TypeMap( + return Ast.TMap( parseType(valueType)(ctx), - Ast.TypeUnit(range), + Ast.TBasic(Ast.TUnit(range), range), range, ); }; @@ -1011,17 +1011,17 @@ const parseTypeStorage = ({ child: storage, loc }: $ast.TypeStorage): Handler => (ctx) => { const range = ctx.toRange(loc); - const fallback = Ast.TypeCons(Ast.TypeId("ERROR", range), [], range); + const fallback = Ast.TCons(Ast.TypeId("ERROR", range), [], range); if (storage.$ === "CoinsStorage") { - return Ast.TypeInt( + return Ast.TBasic(Ast.TInt( Ast.IFVarInt("unsigned", "16", ctx.toRange(storage.loc)), range, - ); + ), range); } else if (storage.$ === "IntStorage") { const width = parseInt(storage.width, 10); if (storage.isVar) { if (width === 16) { - return Ast.TypeInt( + return Ast.TBasic(Ast.TInt( Ast.IFVarInt( typeof storage.isUnsigned === "undefined" ? "signed" @@ -1030,9 +1030,9 @@ const parseTypeStorage = ctx.toRange(storage.loc), ), range, - ); + ), range); } else if (width === 32) { - return Ast.TypeInt( + return Ast.TBasic(Ast.TInt( Ast.IFVarInt( typeof storage.isUnsigned === "undefined" ? "signed" @@ -1041,27 +1041,27 @@ const parseTypeStorage = ctx.toRange(storage.loc), ), range, - ); + ), range); } else { ctx.err.wrongVarIntSize()(range); return fallback; } } else if (storage.isUnsigned) { if (1 <= width && width <= 256) { - return Ast.TypeInt( + return Ast.TBasic(Ast.TInt( Ast.IFInt("unsigned", width, range), range, - ); + ), range); } else { ctx.err.wrongUIntSize()(range); return fallback; } } else { if (1 <= width && width <= 257) { - return Ast.TypeInt( + return Ast.TBasic(Ast.TInt( Ast.IFInt("signed", width, range), range, - ); + ), range); } else { ctx.err.wrongIntSize()(range); return fallback; @@ -1069,12 +1069,12 @@ const parseTypeStorage = } } else if (storage.$ === "RemainingStorage") { ctx.err.rawRemaining()(range); - return Ast.TypeSlice(Ast.SFRemaining(range), range); + return Ast.TBasic(Ast.TSlice(Ast.SFRemaining(range), range), range); // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition } else if (storage.$ === "BytesStorage") { const width = parseInt(storage.width, 10); if (width === 32 || width === 64) { - return Ast.TypeSlice(Ast.SFBits(width * 8, range), range); + return Ast.TBasic(Ast.TSlice(Ast.SFBits(width * 8, range), range), range); } else { ctx.err.wrongSliceSize()(range); return fallback; @@ -1092,96 +1092,10 @@ const applyFormat = asLoc: Ast.Range, ): Handler => (ctx) => { - const fallback = Ast.TypeCons(Ast.TypeId("ERROR", asLoc), [], asLoc); - if (type.kind === "TyInt") { - if (storage.$ === "CoinsStorage") { - return Ast.TypeInt( - Ast.IFVarInt("unsigned", "16", ctx.toRange(storage.loc)), - type.loc, - ); - } else if (storage.$ === "IntStorage") { - const width = parseInt(storage.width, 10); - if (storage.isVar) { - if (width === 16) { - return Ast.TypeInt( - Ast.IFVarInt( - typeof storage.isUnsigned === "undefined" - ? "signed" - : "unsigned", - "16", - ctx.toRange(storage.loc), - ), - type.loc, - ); - } else if (width === 32) { - return Ast.TypeInt( - Ast.IFVarInt( - typeof storage.isUnsigned === "undefined" - ? "signed" - : "unsigned", - "32", - ctx.toRange(storage.loc), - ), - type.loc, - ); - } else { - ctx.err.wrongVarIntSize()(asLoc); - return fallback; - } - } else if (storage.isUnsigned) { - if (1 <= width && width <= 256) { - return Ast.TypeInt( - Ast.IFInt("unsigned", width, asLoc), - type.loc, - ); - } else { - ctx.err.wrongUIntSize()(asLoc); - return fallback; - } - } else { - if (1 <= width && width <= 257) { - return Ast.TypeInt( - Ast.IFInt("signed", width, asLoc), - type.loc, - ); - } else { - ctx.err.wrongIntSize()(asLoc); - return fallback; - } - } - } else { - ctx.err.wrongFormat("Integer")(asLoc); - return fallback; - } - } else if (type.kind === "TySlice") { - if (storage.$ === "RemainingStorage") { - return Ast.TypeSlice(Ast.SFRemaining(asLoc), type.loc); - } else if (storage.$ === "BytesStorage") { - const width = parseInt(storage.width, 10); - if (width === 32 || width === 64) { - return Ast.TypeSlice( - Ast.SFBits(width * 8, asLoc), - type.loc, - ); - } else { - ctx.err.wrongSliceSize()(asLoc); - return fallback; - } - } else { - ctx.err.wrongFormat("Slice")(asLoc); - return fallback; - } - } else if (type.kind === "TyCell" || type.kind === "TyBuilder") { - if (storage.$ === "RemainingStorage") { - const Type = - type.kind === "TyCell" ? Ast.TypeCell : Ast.TypeBuilder; - return Type(Ast.SFRemaining(asLoc), type.loc); - } else { - ctx.err.wrongFormat( - type.kind === "TyCell" ? "Cell" : "Builder", - )(asLoc); - return fallback; - } + const fallback = Ast.TCons(Ast.TypeId("ERROR", asLoc), [], asLoc); + if (type.kind === "basic") { + const basic = applyBasic(type.type, storage, asLoc)(ctx); + return basic ? Ast.TBasic(basic, type.loc) : fallback; } else if (type.kind === "cons_type" && type.name.text === "Maybe") { // NB! Compatibility with old code that allowed `Int? as int32` // instead of `(Int as int32)?` @@ -1190,7 +1104,7 @@ const applyFormat = return throwInternal("Maybe can only have one argument"); } const result = applyFormat(arg, storage, asLoc)(ctx); - return Ast.TypeCons(type.name, [result], type.loc); + return Ast.TCons(type.name, [result], type.loc); } else { // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (type.loc.kind !== "range") { @@ -1201,6 +1115,111 @@ const applyFormat = } }; +const applyBasic = ( + type: Ast.BasicType, + storage: $ast.storage, + asLoc: Ast.Range, +): Handler => +(ctx) => { + if (type.kind === "TyInt") { + if (storage.$ === "CoinsStorage") { + return Ast.TInt( + Ast.IFVarInt("unsigned", "16", ctx.toRange(storage.loc)), + type.loc, + ); + } else if (storage.$ === "IntStorage") { + const width = parseInt(storage.width, 10); + if (storage.isVar) { + if (width === 16) { + return Ast.TInt( + Ast.IFVarInt( + typeof storage.isUnsigned === "undefined" + ? "signed" + : "unsigned", + "16", + ctx.toRange(storage.loc), + ), + type.loc, + ); + } else if (width === 32) { + return Ast.TInt( + Ast.IFVarInt( + typeof storage.isUnsigned === "undefined" + ? "signed" + : "unsigned", + "32", + ctx.toRange(storage.loc), + ), + type.loc, + ); + } else { + ctx.err.wrongVarIntSize()(asLoc); + return undefined; + } + } else if (storage.isUnsigned) { + if (1 <= width && width <= 256) { + return Ast.TInt( + Ast.IFInt("unsigned", width, asLoc), + type.loc, + ); + } else { + ctx.err.wrongUIntSize()(asLoc); + return undefined; + } + } else { + if (1 <= width && width <= 257) { + return Ast.TInt( + Ast.IFInt("signed", width, asLoc), + type.loc, + ); + } else { + ctx.err.wrongIntSize()(asLoc); + return undefined; + } + } + } else { + ctx.err.wrongFormat("Integer")(asLoc); + return undefined; + } + } else if (type.kind === "TySlice") { + if (storage.$ === "RemainingStorage") { + return Ast.TSlice(Ast.SFRemaining(asLoc), type.loc); + } else if (storage.$ === "BytesStorage") { + const width = parseInt(storage.width, 10); + if (width === 32 || width === 64) { + return Ast.TSlice( + Ast.SFBits(width * 8, asLoc), + type.loc, + ); + } else { + ctx.err.wrongSliceSize()(asLoc); + return undefined; + } + } else { + ctx.err.wrongFormat("Slice")(asLoc); + return undefined; + } + } else if (type.kind === "TyCell" || type.kind === "TyBuilder") { + if (storage.$ === "RemainingStorage") { + const Type = + type.kind === "TyCell" ? Ast.TCell : Ast.TBuilder; + return Type(Ast.SFRemaining(asLoc), type.loc); + } else { + ctx.err.wrongFormat( + type.kind === "TyCell" ? "Cell" : "Builder", + )(asLoc); + return undefined; + } + } else { + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + if (type.loc.kind !== "range") { + return throwInternal("Non-range in parser"); + } + ctx.err.cannotHaveFormat()(type.loc); + return undefined; + } +}; + const parseTypeAs = ({ type, as, loc }: $ast.TypeAs): Handler => (ctx) => { @@ -1210,7 +1229,7 @@ const parseTypeAs = } if (as.length > 1) { ctx.err.duplicateAs()(ctx.toRange(loc)); - return Ast.TypeCons( + return Ast.TCons( Ast.TypeId("ERROR", ctx.toRange(loc)), [], ctx.toRange(loc), @@ -1233,9 +1252,9 @@ const parseTypeGeneric = return parseMaybeArgs(args, range)(ctx); } else if (builtinTypes.has(name.name)) { ctx.err.typeArity(name.name, 0)(range); - return Ast.TypeCons(Ast.TypeId("ERROR", range), [], range); + return Ast.TCons(Ast.TypeId("ERROR", range), [], range); } else { - return Ast.TypeCons( + return Ast.TCons( Ast.TypeId(name.name, ctx.toRange(name.loc)), map(parseList(args), parseTypeAs)(ctx), range, @@ -1247,7 +1266,7 @@ const parseTypeOptional = ({ type, optionals }: $ast.TypeOptional): Handler => (ctx) => { return optionals.reduce((acc, optional) => { - return Ast.TypeCons( + return Ast.TCons( Ast.TypeId("Maybe", ctx.toRange(optional.loc)), [acc], ctx.toRange(optional.loc), @@ -1261,40 +1280,40 @@ const parseTypeRegular = const range = ctx.toRange(child.loc); switch (child.name) { case "Int": - return Ast.TypeInt(Ast.IFInt("signed", 257, range), range); + return Ast.TBasic(Ast.TInt(Ast.IFInt("signed", 257, range), range), range); case "Slice": - return Ast.TypeSlice(Ast.SFDefault(range), range); + return Ast.TBasic(Ast.TSlice(Ast.SFDefault(range), range), range); case "Cell": - return Ast.TypeCell(Ast.SFDefault(range), range); + return Ast.TBasic(Ast.TCell(Ast.SFDefault(range), range), range); case "Builder": - return Ast.TypeBuilder(Ast.SFDefault(range), range); + return Ast.TBasic(Ast.TBuilder(Ast.SFDefault(range), range), range); case "Void": - return Ast.TypeVoid(range); + return Ast.TBasic(Ast.TVoid(range), range); case "Null": - return Ast.TypeNull(range); + return Ast.TBasic(Ast.TNull(range), range); case "Bool": - return Ast.TypeBool(range); + return Ast.TBasic(Ast.TBool(range), range); case "Address": - return Ast.TypeAddress(range); + return Ast.TBasic(Ast.TAddress(range), range); case "String": - return Ast.TypeString(range); + return Ast.TBasic(Ast.TString(range), range); case "StringBuilder": - return Ast.TypeStringBuilder(range); + return Ast.TBasic(Ast.TStringBuilder(range), range); case "Bounced": ctx.err.mustBeGeneric()(range); - return Ast.TypeCons(Ast.TypeId("ERROR", range), [], range); + return Ast.TCons(Ast.TypeId("ERROR", range), [], range); case "Maybe": ctx.err.mustBeGeneric()(range); - return Ast.TypeCons(Ast.TypeId("ERROR", range), [], range); + return Ast.TCons(Ast.TypeId("ERROR", range), [], range); default: - return Ast.TypeCons(parseTypeId(child)(ctx), [], range); + return Ast.TCons(parseTypeId(child)(ctx), [], range); } }; const parseTypeTensor = ({ head, tail, loc }: $ast.TypeTensor): Handler => (ctx) => { - return Ast.TypeTensor( + return Ast.TTensor( map([head, ...tail], parseType)(ctx), ctx.toRange(loc), ); @@ -1303,7 +1322,7 @@ const parseTypeTensor = const parseTypeTuple = ({ types, loc }: $ast.TypeTuple): Handler => (ctx) => { - return Ast.TypeTuple( + return Ast.TTuple( map(parseList(types), parseType)(ctx), ctx.toRange(loc), ); @@ -1312,7 +1331,8 @@ const parseTypeTuple = const parseTypeUnit = ({ loc }: $ast.TypeUnit): Handler => (ctx) => { - return Ast.TypeUnit(ctx.toRange(loc)); + const range = ctx.toRange(loc); + return Ast.TBasic(Ast.TUnit(range), range); }; type RawType = @@ -1474,12 +1494,12 @@ const parseAsmFunctionRaw = return Ast.Function( !!parseNamedAttr("inline")(node.attributes)(ctx), parseId(node.name)(ctx), - Ast.FnType( + Ast.TFunction( map(parseList(node.typeParams), parseTypeId)(ctx), map(parseList(node.parameters), parseParameter)(ctx), node.returnType ? parseType(node.returnType)(ctx) - : Ast.TypeVoid(range), + : Ast.TBasic(Ast.TVoid(range), range), ), Ast.AsmBody(parseAsmShuffle(node.shuffle)(ctx), [ node.instructions.trim(), @@ -1549,7 +1569,7 @@ const parseConstant = } else { ctx.err.constDeclNoType()(range); return Ast.ConstantDecl( - Ast.TypeCons(Ast.TypeId("ERROR", range), [], range), + Ast.TCons(Ast.TypeId("ERROR", range), [], range), ); } })(); @@ -1647,12 +1667,12 @@ const parseFunctionRaw = return Ast.Function( !!parseNamedAttr("inline")(node.attributes)(ctx), parseId(node.name)(ctx), - Ast.FnType( + Ast.TFunction( map(parseList(node.typeParams), parseTypeId)(ctx), map(parseList(node.parameters), parseParameter)(ctx), node.returnType ? parseType(node.returnType)(ctx) - : Ast.TypeVoid(range), + : Ast.TBasic(Ast.TVoid(range), range), ), node.body.$ === "FunctionDeclaration" ? Ast.AbstractBody() @@ -1695,7 +1715,7 @@ const parseExtension = ) { const range = ctx.toRange(node.loc); ctx.err.extendsSelf()(range); - return Ast.TypeCons(Ast.TypeId("ERROR", range), [], range); + return Ast.TCons(Ast.TypeId("ERROR", range), [], range); } return first.type; })(); @@ -1758,10 +1778,10 @@ const parseNativeFunctionDecl = return Ast.Function( !!parseNamedAttr("inline")(attributes)(ctx), parseId(name)(ctx), - Ast.FnType( + Ast.TFunction( map(parseList(typeParams), parseTypeId)(ctx), map(parseList(parameters), parseParameter)(ctx), - returnType ? parseType(returnType)(ctx) : Ast.TypeVoid(range), + returnType ? parseType(returnType)(ctx) : Ast.TBasic(Ast.TVoid(range), range), ), Ast.NativeBody(parseFuncId(nativeName)(ctx)), range, diff --git a/src/next/types/alias.ts b/src/next/types/alias.ts index 9c2b1da445..c1de48ec6a 100644 --- a/src/next/types/alias.ts +++ b/src/next/types/alias.ts @@ -7,10 +7,10 @@ import { decodeTypeLazy } from "@/next/types/type"; export function* decodeAlias( Lazy: Ast.ThunkBuilder, { typeParams, type }: Ast.AliasDecl, - scopeRef: () => Ast.Scope, -): Ast.WithLog { + scopeRef: () => Ast.CSource, +): Ast.WithLog { const decodedParams = yield* decodeTypeParams(typeParams); - return Ast.AliasSig( + return Ast.CAlias( decodedParams, decodeTypeLazy(Lazy, decodedParams, type, scopeRef), ); diff --git a/src/next/types/body.ts b/src/next/types/body.ts index 8214ee618f..a1ba6a7ca4 100644 --- a/src/next/types/body.ts +++ b/src/next/types/body.ts @@ -7,14 +7,14 @@ import { decodeStatementsLazy } from "@/next/types/statements"; export function* decodeBody( Lazy: Ast.ThunkBuilder, node: Ast.FunctionalBody, - fnType: Ast.DecodedFnType | Ast.DecodedMethodType, + fnType: Ast.CTypeFunction | Ast.CTypeMethod, loc: Ast.Loc, - scopeRef: () => Ast.Scope, -): Ast.WithLog { + scopeRef: () => Ast.CSource, +): Ast.WithLog { switch (node.kind) { case "abstract_body": { yield ENoBody(loc); - return Ast.TactBody( + return Ast.CTactBody( Lazy({ callback: function* () { return undefined; @@ -31,7 +31,7 @@ export function* decodeBody( ? fnType.self : undefined; }; - return Ast.TactBody( + return Ast.CTactBody( decodeStatementsLazy( Lazy, loc, @@ -45,7 +45,7 @@ export function* decodeBody( ); } case "asm_body": { - return Ast.FiftBody( + return Ast.CFiftBody( Lazy({ callback: () => checkShuffle(node.shuffle, fnType, loc, scopeRef), @@ -57,7 +57,7 @@ export function* decodeBody( ); } case "native_body": { - return Ast.FuncBody(node.nativeName); + return Ast.CFuncBody(node.nativeName); } } } @@ -69,9 +69,9 @@ const ENoBody = (loc: Ast.Loc): Ast.TcError => ({ function* checkShuffle( shuffle: Ast.AsmShuffle, - fnType: Ast.DecodedFnType | Ast.DecodedMethodType, + fnType: Ast.CTypeFunction | Ast.CTypeMethod, loc: Ast.Loc, - scopeRef: () => Ast.Scope, + scopeRef: () => Ast.CSource, ) { const { args, ret } = shuffle; if (args.length !== 0) { @@ -129,8 +129,8 @@ function* checkShuffle( } function* getRetTupleSize( - { kind, returnType }: Ast.DecodedFnType | Ast.DecodedMethodType, - scopeRef: () => Ast.Scope, + { kind, returnType }: Ast.CTypeFunction | Ast.CTypeMethod, + scopeRef: () => Ast.CSource, ): Ast.WithLog { const type = yield* returnType(); const baseSize = yield* getTypeTupleSize(type, scopeRef); @@ -140,7 +140,7 @@ function* getRetTupleSize( return baseSize + (kind === "DecodedMethodType" ? 1 : 0); } -function* getTypeTupleSize(type: Ast.DecodedType, scopeRef: () => Ast.Scope) { +function* getTypeTupleSize(type: Ast.CType, scopeRef: () => Ast.CSource) { switch (type.kind) { case "recover": { return undefined; @@ -198,21 +198,27 @@ function* getTypeTupleSize(type: Ast.DecodedType, scopeRef: () => Ast.Scope) { case "tensor_type": { return type.typeArgs.length; } - case "TyInt": - case "TySlice": - case "TyCell": - case "TyBuilder": - case "unit_type": - case "TypeBool": - case "TypeAddress": - case "TypeString": - case "TypeStateInit": - case "TypeStringBuilder": - case "TypeNull": { - return 1; - } - case "TypeVoid": { - return 0; + case "basic": { + switch (type.type.kind) { + case "TypeStateInit": { + return 2; + } + case "TyInt": + case "TySlice": + case "TyCell": + case "TyBuilder": + case "unit_type": + case "TypeBool": + case "TypeAddress": + case "TypeString": + case "TypeStringBuilder": + case "TypeNull": { + return 1; + } + case "TypeVoid": { + return 0; + } + } } } } diff --git a/src/next/types/builtins.ts b/src/next/types/builtins.ts index 9b6839959f..badda0657d 100644 --- a/src/next/types/builtins.ts +++ b/src/next/types/builtins.ts @@ -8,36 +8,36 @@ export const tactMethodIds = [113617n, 115390n, 121275n]; const r = Ast.Builtin(); -const TypeParams = (typeParams: readonly string[]): Ast.TypeParams => { +const TypeParams = (typeParams: readonly string[]): Ast.CTypeParams => { const arr = typeParams.map((name) => Ast.TypeId(name, r)); - return Ast.TypeParams(arr, new Set(typeParams)); + return Ast.CTypeParams(arr, new Set(typeParams)); }; -const Params = (params: Record): Ast.Parameters => { - const order: Ast.Parameter[] = []; +const Params = (params: Record): Ast.CParameters => { + const order: Ast.CParameter[] = []; const set: Set = new Set(); for (const [name, type] of Object.entries(params)) { - order.push(Ast.Parameter(Ast.Id(name, r), Ast.FakeThunk(type), r)); + order.push(Ast.CParameter(Ast.Id(name, r), Ast.FakeThunk(type), r)); set.add(name); } - return Ast.Parameters(order, set); + return Ast.CParameters(order, set); }; -const Ref = (name: string): Ast.DTypeParamRef => { - return Ast.DTypeParamRef(Ast.TypeId(name, r), r); +const Ref = (name: string): Ast.CTypeParamRef => { + return Ast.CTypeParamRef(Ast.TypeId(name, r), r); }; -const mapType = Ast.MVTypeMap(Ref("K"), Ref("V"), r); +const mapType = Ast.SVTMap(Ref("K"), Ref("V"), r); const GenericFn = ( name: string, typeParams: readonly string[], - params: Record, - returnType: Ast.DecodedType, -): [string, Ast.DecodedFnType] => { + params: Record, + returnType: Ast.CType, +): [string, Ast.CTypeFunction] => { return [ name, - Ast.DecodedFnType( + Ast.CTypeFunction( TypeParams(typeParams), Params(params), Ast.FakeThunk(returnType), @@ -46,20 +46,20 @@ const GenericFn = ( }; const Fn = ( name: string, - params: Record, - returnType: Ast.DecodedType, -): [string, Ast.DecodedFnType] => { + params: Record, + returnType: Ast.CType, +): [string, Ast.CTypeFunction] => { return GenericFn(name, [], params, returnType); }; const MapMethod = ( name: string, mutates: boolean, - params: Record, - returnType: Ast.DecodedType, -): [string, Ast.DecodedMethodType] => { + params: Record, + returnType: Ast.CType, +): [string, Ast.CTypeMethod] => { return [ name, - Ast.DecodedMethodType( + Ast.CTypeMethod( mutates, TypeParams(["K", "V"]), mapType, @@ -69,21 +69,21 @@ const MapMethod = ( ]; }; -export const Int = Ast.TypeInt(Ast.IFInt("signed", 257, r), r); -export const Slice = Ast.TypeSlice(Ast.SFDefault(r), r); -export const Cell = Ast.TypeCell(Ast.SFDefault(r), r); -export const Builder = Ast.TypeBuilder(Ast.SFDefault(r), r); -export const Void = Ast.TypeVoid(r); -export const Null = Ast.TypeNull(r); -export const Bool = Ast.TypeBool(r); -export const Address = Ast.TypeAddress(r); -export const String = Ast.TypeString(r); -export const StringBuilder = Ast.TypeStringBuilder(r); -export const MapType = (k: Ast.DecodedType, v: Ast.DecodedType) => - Ast.DTypeMap(k, v, r); -export const Maybe = (t: Ast.DecodedType) => Ast.DTypeMaybe(t, r); -export const Unit = Ast.TypeUnit(r); -export const StateInit = Ast.DTypeStateInit(r); +export const Int = Ast.CTBasic(Ast.TInt(Ast.IFInt("signed", 257, r), r), r); +export const Slice = Ast.CTBasic(Ast.TSlice(Ast.SFDefault(r), r), r); +export const Cell = Ast.CTBasic(Ast.TCell(Ast.SFDefault(r), r), r); +export const Builder = Ast.CTBasic(Ast.TBuilder(Ast.SFDefault(r), r), r); +export const Void = Ast.CTBasic(Ast.TVoid(r), r); +export const Null = Ast.CTBasic(Ast.TNull(r), r); +export const Bool = Ast.CTBasic(Ast.TBool(r), r); +export const Address = Ast.CTBasic(Ast.TAddress(r), r); +export const String = Ast.CTBasic(Ast.TString(r), r); +export const StringBuilder = Ast.CTBasic(Ast.TStringBuilder(r), r); +export const MapType = (k: Ast.CType, v: Ast.CType) => + Ast.CTypeMap(k, v, r); +export const Maybe = (t: Ast.CType) => Ast.CTypeMaybe(t, r); +export const Unit = Ast.TUnit(r); +export const StateInit = Ast.CTBasic(Ast.TStateInit(r), r); export const builtinTypes = new Map( [ @@ -121,7 +121,7 @@ const BoolAssign = (name: string) => { return Fn(name, { left: Bool, right: Bool }, Void); }; -export const builtinFunctions: Map = new Map([ +export const builtinFunctions: Map = new Map([ // dump(arg: T): Void GenericFn("dump", ["T"], { data: Ref("T") }, Void), // ton(value: String): Int @@ -149,7 +149,7 @@ export const builtinFunctions: Map = new Map([ // sha256(data: Slice | String): Int ]); -export const builtinMethods: Map = new Map([ +export const builtinMethods: Map = new Map([ // set(key: K, value: V): void MapMethod("set", true, { key: Ref("K"), value: Ref("V") }, Void), // get(key: K): Maybe @@ -170,7 +170,7 @@ export const builtinMethods: Map = new Map([ MapMethod("replaceGet", true, { key: Ref("K"), value: Ref("V") }, mapType), ]); -export const builtinUnary: Map = new Map([ +export const builtinUnary: Map = new Map([ Fn("+", { arg: Int }, Int), Fn("-", { arg: Int }, Int), Fn("~", { arg: Int }, Int), @@ -178,7 +178,7 @@ export const builtinUnary: Map = new Map([ GenericFn("!!", ["T"], { arg: Maybe(Ref("T")) }, Ref("T")), ]); -export const builtinBinary: Map = new Map([ +export const builtinBinary: Map = new Map([ // (left: Int, right: Int): Int ArithBin("+"), ArithBin("-"), @@ -203,7 +203,7 @@ export const builtinBinary: Map = new Map([ BoolBin("||"), ]); -export const builtinAugmented: Map = new Map([ +export const builtinAugmented: Map = new Map([ // (left: Int, right: Int): Void; ArithAssign("+="), ArithAssign("-="), @@ -221,8 +221,8 @@ export const builtinAugmented: Map = new Map([ ]); export const getStaticBuiltin = ( - type: Ast.DecodedType, -): Map => { + type: Ast.CType, +): Map => { return new Map([ // Foo.fromSlice(slice: Slice) Fn("fromSlice", { slice: Slice }, type), @@ -231,6 +231,7 @@ export const getStaticBuiltin = ( ]); }; +// TODO: convert into methods, use `mutates` from them in `lookupMethod` export const structBuiltin = new Map([ // Foo.toSlice(): Slice Fn("toSlice", {}, Slice), diff --git a/src/next/types/constant-def.ts b/src/next/types/constant-def.ts index 9c54d379de..5bdda71ed7 100644 --- a/src/next/types/constant-def.ts +++ b/src/next/types/constant-def.ts @@ -8,11 +8,11 @@ import { emptyTypeParams } from "@/next/types/type-params"; export function decodeConstantDef( Lazy: Ast.ThunkBuilder, defLoc: Ast.Loc, - typeParams: Ast.TypeParams, + typeParams: Ast.CTypeParams, { type, initializer }: Ast.ConstantDef, - scopeRef: () => Ast.Scope, + scopeRef: () => Ast.CSource, selfType: undefined | Ast.SelfType, -): [Ast.Thunk, Ast.Thunk] { +): [Ast.Thunk, Ast.Thunk] { if (type) { // if there is an ascribed type, that's the one we return const ascribedType = decodeTypeLazy(Lazy, typeParams, type, scopeRef); @@ -27,7 +27,7 @@ export function decodeConstantDef( selfType, new Map(), ); - const computed = expr.computedType; + const computed = expr.value.computedType; const ascribed = yield* ascribedType(); yield* assignType( defLoc, @@ -36,7 +36,7 @@ export function decodeConstantDef( computed, false, ); - return yield* evalExpr(expr, scopeRef); + return yield* evalExpr(expr.value, scopeRef); } const lazyExpr = Lazy({ loc: defLoc, @@ -65,7 +65,7 @@ export function decodeConstantDef( const lazyExpr = Lazy({ callback: function* () { const ast = yield* expr(); - return ast && (yield* evalExpr(ast, scopeRef)); + return ast && (yield* evalExpr(ast.value, scopeRef)); }, context: [Ast.TEText("evaluating expression")], loc: defLoc, @@ -74,11 +74,11 @@ export function decodeConstantDef( // resulting type is whatever the type expression has const computedType = Lazy({ callback: function* () { - return (yield* expr())?.computedType ?? Ast.DTypeRecover(); + return (yield* expr())?.value.computedType ?? Ast.CTypeRecover(); }, context: [], loc: defLoc, - recover: Ast.DTypeRecover(), + recover: Ast.CTypeRecover(), }); return [computedType, lazyExpr]; } diff --git a/src/next/types/constants.ts b/src/next/types/constants.ts index 1b007ab567..c9dc4a8110 100644 --- a/src/next/types/constants.ts +++ b/src/next/types/constants.ts @@ -11,8 +11,8 @@ export function* decodeConstants( Lazy: Ast.ThunkBuilder, imported: readonly Ast.SourceCheckResult[], source: TactSource, - scopeRef: () => Ast.Scope, -): Ast.WithLog>> { + scopeRef: () => Ast.CSource, +): Ast.WithLog>> { const allConstSigs = [ // imported ...imported.flatMap(({ globals, importedBy }) => @@ -52,7 +52,7 @@ export function* decodeConstants( function* decodeConstant( Lazy: Ast.ThunkBuilder, constant: Ast.Constant, - scopeRef: () => Ast.Scope, + scopeRef: () => Ast.CSource, ) { const { init, loc } = constant; if (init.kind === "constant_decl") { @@ -63,9 +63,9 @@ function* decodeConstant( Ast.TEText("defining constant"), Ast.TECode(constant.loc), ], - recover: Ast.DTypeRecover(), + recover: Ast.CTypeRecover(), callback: function* () { - return Ast.DTypeRecover(); + return Ast.CTypeRecover(); }, }); const expr = Lazy({ @@ -79,7 +79,7 @@ function* decodeConstant( return Ast.VNumber(0n, constant.loc); }, }); - return Ast.ConstSig(expr, type); + return Ast.CConstant(expr, type); } else { const [type, expr] = decodeConstantDef( Lazy, @@ -89,7 +89,7 @@ function* decodeConstant( scopeRef, undefined, ); - return Ast.ConstSig(expr, type); + return Ast.CConstant(expr, type); } } diff --git a/src/next/types/contract.ts b/src/next/types/contract.ts index baa46b7392..ba840c93cb 100644 --- a/src/next/types/contract.ts +++ b/src/next/types/contract.ts @@ -15,7 +15,7 @@ import { emptyTypeParams } from "@/next/types/type-params"; export function* decodeContract( Lazy: Ast.ThunkBuilder, contract: Ast.Contract, - scopeRef: () => Ast.Scope, + scopeRef: () => Ast.CSource, ) { const { name, attributes, declarations, init } = contract; const { constants, fields, methods, receivers } = declarations; @@ -35,12 +35,12 @@ export function* decodeContract( ); // delayed until we get all traits and init - const contentLazy: Ast.Thunk = Lazy({ + const contentLazy: Ast.Thunk = Lazy({ callback: function* (Lazy) { const traits = yield* getInheritedTraits(contract.traits, scopeRef); // const contentRef = () => content; - const content: Ast.ContractContent = { + const content: Ast.CContractMembers = { fieldish: yield* getFieldishFromContract( Lazy, contractSig, @@ -76,9 +76,9 @@ export function* decodeContract( recover, }); - const contractSig = Ast.ContractSig(attributes, decodedInit, contentLazy); + const contractSig = Ast.CContract(attributes, decodedInit, contentLazy); - const selfType = Ast.MVTypeRef( + const selfType = Ast.SVTRef( contract.name, contractSig, [], @@ -93,9 +93,9 @@ function* decodeInit( contractLoc: Ast.Loc, selfTypeRef: () => Ast.SelfType, init: Ast.Init | undefined, - contentLazy: () => Ast.Thunk, - scopeRef: () => Ast.Scope, -): Ast.WithLog { + contentLazy: () => Ast.Thunk, + scopeRef: () => Ast.CSource, +): Ast.WithLog { if (!init) { // no init const lazyInit = Lazy({ @@ -127,7 +127,7 @@ function* decodeInit( loc: contractLoc, recover: undefined, }); - return Ast.InitEmpty(lazyInit); + return Ast.CInitEmpty(lazyInit); } else if (init.kind === "init_params") { const order: string[] = []; const paramMap: Map = new Map(); @@ -142,7 +142,7 @@ function* decodeInit( } } - const map: Map = new Map(); + const map: Map = new Map(); for (const [name, param] of paramMap) { const decoded = decodeTypeLazy( Lazy, @@ -153,9 +153,9 @@ function* decodeInit( if (!param.initializer) { yield ENoInitializerParams(param.loc); } - map.set(name, Ast.InitParam(decoded, undefined, param.loc)); + map.set(name, Ast.CInitParam(decoded, undefined, param.loc)); } - return Ast.InitSimple(Ast.Ordered(order, map), init.loc); + return Ast.CInitSimple(Ast.Ordered(order, map), init.loc); } else { const { params, statements } = init; @@ -181,7 +181,7 @@ function* decodeInit( scopeRef, ); - return Ast.InitFn(decodedParams, body); + return Ast.CInitFn(decodedParams, body); } } const EDuplicateParam = ( @@ -213,12 +213,12 @@ const ENoInitializerEmpty = (loc: Ast.Loc): Ast.TcError => ({ function* getMethodsFromContract( Lazy: Ast.ThunkBuilder, - contractSig: Ast.ContractSig, + contractSig: Ast.CContract, typeName: Ast.TypeId, - traits: readonly Ast.Decl[], + traits: readonly Ast.Decl[], methods: readonly Ast.Method[], - scopeRef: () => Ast.Scope, -): Ast.WithLog>>> { + scopeRef: () => Ast.CSource, +): Ast.WithLog>>> { const res = yield* getMethodsGeneral( Lazy, contractSig, @@ -228,7 +228,7 @@ function* getMethodsFromContract( scopeRef, ); - const map: Map>> = new Map(); + const map: Map>> = new Map(); for (const [name, { via, decl: method }] of res) { if (method.body) { // have to recreate DeclMem, because TS doesn't @@ -245,15 +245,15 @@ function* getMethodsFromContract( function* getFieldishFromContract( Lazy: Ast.ThunkBuilder, - contractSig: Ast.ContractSig, + contractSig: Ast.CContract, typeName: Ast.TypeId, - traits: readonly Ast.Decl[], - init: Ast.InitSig, + traits: readonly Ast.Decl[], + init: Ast.CInitSig, constants: readonly Ast.FieldConstant[], fields: readonly Ast.FieldDecl[], - scopeRef: () => Ast.Scope, + scopeRef: () => Ast.CSource, ): Ast.WithLog< - Ast.Ordered>>>> + Ast.Ordered>>>> > { const res = yield* getFieldishGeneral( Lazy, @@ -268,7 +268,7 @@ function* getFieldishFromContract( const order: string[] = []; const map: Map< string, - Ast.DeclMem>>> + Ast.DeclMem>>> > = new Map(); for (const name of res.order) { const field = res.map.get(name); @@ -294,7 +294,7 @@ function* getFieldishFromContract( if (init.kind === "simple") { const map: Map< string, - Ast.DeclMem>>> + Ast.DeclMem>>> > = new Map(); if (order.length !== 0) { yield EFieldsTwice(init.loc); @@ -304,7 +304,7 @@ function* getFieldishFromContract( map.set( name, Ast.DeclMem( - Ast.InhFieldSig(param.type, param.init), + Ast.CField(param.type, param.init), Ast.ViaMemberOrigin(typeName.text, param.loc), ), ); @@ -332,7 +332,7 @@ const EAbstract = ( ], }); -const recover: Ast.ContractContent = { +const recover: Ast.CContractMembers = { fieldish: Ast.Ordered([], new Map()), methods: new Map(), receivers: { diff --git a/src/next/types/effects.ts b/src/next/types/effects.ts index 82223b54b5..58464cef82 100644 --- a/src/next/types/effects.ts +++ b/src/next/types/effects.ts @@ -1,71 +1,73 @@ import * as Ast from "@/next/ast"; +// import { hasStorageAccess } from "@/next/types/expression"; -export const emptyEff: Ast.Effects = Object.freeze({ - returnOrThrow: false, - setSelfPaths: new Set(), -}); +// op read/write throw +// 42 empty false false +// a ? b : c a prod (b sum c) a | b | c a | (b & c) +// f(a, b) a prod b a | b a | b +// a && b a cond b a | b a +// a || b a cond b a | b a -// when two branches merge -export const mergeEff = ( +// true true a b +// true false a b +// false true a +// false false a + +export const emptyEff = Ast.Effects( + false, + false, + false, + new Set(), +); + +export const allEff = ( + effs: readonly Ast.Effects[], +) => Ast.Effects( + effs.some(eff => eff.mayRead), + effs.some(eff => eff.mayWrite), + // if any of args throws, expr throws + effs.some(eff => eff.mustThrow), + new Set(effs.flatMap(eff => [...eff.mustSetSelf])), +); + +export const anyEff = ( + effs: readonly Ast.Effects[], +) => Ast.Effects( + effs.some(eff => eff.mayRead), + effs.some(eff => eff.mayWrite), + // if all of branches throw, expr throws + effs.every(eff => eff.mustThrow), + new Set(effs.flatMap(eff => [...eff.mustSetSelf])), +); + +export const shortCircuitEff = ( left: Ast.Effects, right: Ast.Effects, -): Ast.Effects => { - return Ast.Effects( - left.returnOrThrow && right.returnOrThrow, - new Set( - [...left.setSelfPaths].filter((p) => right.setSelfPaths.has(p)), - ), - ); -}; +) => Ast.Effects( + left.mayRead || right.mayRead, + left.mayWrite || right.mayWrite, + // only if condition throws, we know it must throw + // if condition doesn't throw, we can never evaluate second arg, + // and it's not guaranteed to throw + left.mustThrow, + new Set([...left.mustSetSelf, ...right.mustSetSelf]), +); -// on every assign -export function* setHadAssign( - eff: Ast.Effects, - lvalue: Ast.LValue, -): Ast.WithLog { - const setSelfPaths = new Set(eff.setSelfPaths); - switch (lvalue.kind) { - case "self": { - // self = ...; - yield ENoSelfAssign(lvalue.loc); - break; - } - case "field_access": { - if (lvalue.aggregate.kind === "self") { - // self.x = ...; - setSelfPaths.add(lvalue.field.text); - } - break; - } - case "var": { - // x = ...; - } - } - return Ast.Effects(eff.returnOrThrow, setSelfPaths); -} -const ENoSelfAssign = (loc: Ast.Loc): Ast.TcError => ({ - loc, - descr: [Ast.TEText(`Cannot assign to self`)], -}); +export const exitEff = (eff: Ast.Effects): Ast.Effects => ({ ...eff, mustThrow: true }); +export const assignEff = (eff: Ast.Effects): Ast.Effects => ({ ...eff, mustThrow: true }); -// on every return or throw -export function* setHadExit( - eff: Ast.Effects, - successful: boolean, - required: undefined | ReadonlySet, - returnLoc: Ast.Loc, -): Ast.WithLog { - if (successful && required) { - const missing = [...required].filter((p) => !eff.setSelfPaths.has(p)); - for (const fieldName of missing) { - yield EMissingSelfInit(fieldName, returnLoc); - } +export function hasStorageAccess(node: Ast.DecodedExpression, selfType: Ast.SelfType | undefined): boolean { + // looking for `self.x.y.z` + if (node.kind === 'field_access') { + return hasStorageAccess(node.aggregate, selfType); + } else if (node.kind === 'self') { + return Boolean( + selfType && + selfType.kind === 'type_ref' && + (selfType.type.kind === 'contract' || selfType.type.kind === 'trait') + ); + } else { + return false; } - return Ast.Effects(true, eff.setSelfPaths); } -const EMissingSelfInit = (name: string, loc: Ast.Loc): Ast.TcError => ({ - loc, - descr: [ - Ast.TEText(`Field "self.${name}" is not initialized by this moment`), - ], -}); + diff --git a/src/next/types/expr-eval.ts b/src/next/types/expr-eval.ts index 941f4afe50..5cce2aba8a 100644 --- a/src/next/types/expr-eval.ts +++ b/src/next/types/expr-eval.ts @@ -4,7 +4,7 @@ import * as Ast from "@/next/ast"; export function* evalExpr( expr: Ast.DecodedExpression, - scopeRef: () => Ast.Scope, + scopeRef: () => Ast.CSource, ): Ast.WithLog { return Ast.VNumber(0n, expr.loc); } diff --git a/src/next/types/expression.ts b/src/next/types/expression.ts index 3ec3317757..f617fd6ef2 100644 --- a/src/next/types/expression.ts +++ b/src/next/types/expression.ts @@ -22,31 +22,46 @@ import { } from "@/next/types/type"; import { convertValueToExpr } from "@/next/types/value"; import { emptyTypeParams } from "@/next/types/type-params"; +import { emptyEff, allEff, shortCircuitEff, anyEff, hasStorageAccess } from "@/next/types/effects"; + +type Decode = ( + node: T, + ctx: Context, +) => Ast.WithLog>; + +type Result = { + readonly value: U; + readonly eff: Ast.Effects; +} +const Result = ( + value: U, + eff: Ast.Effects, +): Result => ({ value, eff }); -type Decode = (node: T, ctx: Context) => Ast.WithLog; type Context = { readonly Lazy: Ast.ThunkBuilder; - readonly scopeRef: () => Ast.Scope; + readonly scopeRef: () => Ast.CSource; readonly selfType: Ast.SelfType | undefined; - readonly typeParams: Ast.TypeParams; - readonly localScopeRef: ReadonlyMap; + readonly typeParams: Ast.CTypeParams; + readonly localScopeRef: ReadonlyMap; }; -export function decodeExpr( +export function* decodeExpr( Lazy: Ast.ThunkBuilder, - typeParams: Ast.TypeParams, + typeParams: Ast.CTypeParams, node: Ast.Expression, - scopeRef: () => Ast.Scope, + scopeRef: () => Ast.CSource, selfType: Ast.SelfType | undefined, - localScopeRef: ReadonlyMap, -): Ast.WithLog { - return decodeExprCtx(node, { + localScopeRef: ReadonlyMap, +) { + const result = yield* decodeExprCtx(node, { Lazy, typeParams, scopeRef, selfType, localScopeRef, }); + return { value: result.value, eff: result.eff }; } export const decodeExprCtx: Decode = ( @@ -99,36 +114,38 @@ export const decodeExprCtx: Decode = ( }; const decodeNullCons: Decode = function* (node) { - return Ast.DNull(Ast.TypeNull(node.loc), node.loc); + return Result(Ast.DNull(Ast.TBasic(Ast.TNull(node.loc), node.loc), node.loc), emptyEff); }; const decodeUnitCons: Decode = function* (node) { - return Ast.DUnit(Ast.TypeUnit(node.loc), node.loc); + return Result(Ast.DUnit(Ast.TBasic(Ast.TUnit(node.loc), node.loc), node.loc), emptyEff); }; const decodeStringCons: Decode = function* (node) { - return Ast.DString(node.value, Ast.TypeString(node.loc), node.loc); + return Result(Ast.DString(node.value, Ast.TBasic(Ast.TString(node.loc), node.loc), node.loc), emptyEff); }; const decodeNumberCons: Decode = function* (node) { - return Ast.DNumber( + return Result(Ast.DNumber( node.base, node.value, - Ast.TypeInt(Ast.IFInt("signed", 257, node.loc), node.loc), + Ast.TBasic(Ast.TInt(Ast.IFInt("signed", 257, node.loc), node.loc), node.loc), node.loc, - ); + ), emptyEff); }; const decodeBooleanCons: Decode = function* (node) { - return Ast.DBoolean(node.value, Ast.TypeBool(node.loc), node.loc); + return Result(Ast.DBoolean(node.value, Ast.TBasic(Ast.TBool(node.loc), node.loc), node.loc), emptyEff); }; const decodeTupleCons: Decode = function* (node, ctx) { const children = yield* Ast.mapLog(node.children, (child) => decodeExprCtx(child, ctx), ); - const args = children.map((child) => child.computedType); - return Ast.DTuple(children, Ast.DTypeTuple(args, node.loc), node.loc); + const exprs = children.map((child) => child.value); + const argTypes = exprs.map((expr) => expr.computedType); + const newEff = allEff(children.map((child) => child.eff)); + return Result(Ast.DTuple(exprs, Ast.CTypeTuple(argTypes, node.loc), node.loc), newEff); }; const decodeTensorCons: Decode = function* ( @@ -138,8 +155,10 @@ const decodeTensorCons: Decode = function* ( const children = yield* Ast.mapLog(node.children, (child) => decodeExprCtx(child, ctx), ); - const args = children.map((child) => child.computedType); - return Ast.DTensor(children, Ast.DTypeTensor(args, node.loc), node.loc); + const exprs = children.map((child) => child.value); + const argTypes = exprs.map((expr) => expr.computedType); + const newEff = allEff(children.map((child) => child.eff)); + return Result(Ast.DTensor(exprs, Ast.CTypeTensor(argTypes, node.loc), node.loc), newEff); }; const decodeMapCons: Decode = function* ( @@ -157,7 +176,7 @@ const decodeMapCons: Decode = function* ( field.key.loc, emptyTypeParams, ascribed.key, - key.computedType, + key.value.computedType, false, ); const value = yield* decodeExprCtx(field.value, ctx); @@ -165,12 +184,23 @@ const decodeMapCons: Decode = function* ( field.value.loc, emptyTypeParams, ascribed.value, - value.computedType, + value.value.computedType, false, ); - return Ast.DMapField(key, value); + return Result( + Ast.DMapField(key.value, value.value), + allEff([key.eff, value.eff]), + ); }); - return Ast.DMapLiteral(ascribed, fields, node.loc); + + return Result( + Ast.DMapLiteral( + ascribed, + fields.map(field => field.value), + node.loc, + ), + allEff(fields.map(field => field.eff)), + ); }; const decodeSetCons: Decode = function* () { @@ -200,25 +230,28 @@ const decodeStructCons: Decode = node.loc, ctx, ); - return Ast.DStructInstance( - fields, - instance?.type ?? Ast.DTypeRecover(), - node.loc, + return Result( + Ast.DStructInstance( + fields.value, + instance?.type ?? Ast.CTypeRecover(), + node.loc, + ), + fields.eff, ); }; function* checkFields( - typeFields: Ast.Ordered | undefined, + typeFields: Ast.Ordered | undefined, args: readonly Ast.StructFieldInitializer[], loc: Ast.Loc, ctx: Context, -) { - const map: Map = new Map(); +): Ast.WithLog>>> { + const map: Map> = new Map(); for (const arg of args) { const fieldName = arg.field.text; const prev = map.get(fieldName); if (prev) { - yield EDuplicateField(fieldName, prev.loc, arg.loc); + yield EDuplicateField(fieldName, prev.value.loc, arg.loc); continue; } const expr = yield* decodeExprCtx(arg.initializer, ctx); @@ -227,10 +260,10 @@ function* checkFields( const typeField = typeFields.map.get(fieldName); if (typeField) { yield* assignType( - expr.loc, + expr.value.loc, emptyTypeParams, yield* typeField.type(), - expr.computedType, + expr.value.computedType, false, ); } else { @@ -242,6 +275,7 @@ function* checkFields( } if (typeFields) { + const effects: Ast.Effects[] = []; const result: Map< string, Ast.Recover @@ -253,7 +287,8 @@ function* checkFields( } const fieldInst = map.get(fieldName); if (fieldInst) { - result.set(fieldName, fieldInst); + effects.push(fieldInst.eff); + result.set(fieldName, fieldInst.value); } else if (field.init) { const value = yield* field.init(); if (value) { @@ -267,9 +302,18 @@ function* checkFields( result.set(fieldName, undefined); } } - return Ast.Ordered(typeFields.order, result); + return Result( + Ast.Ordered(typeFields.order, result), + allEff(effects) + ); } else { - return Ast.Ordered([...map.keys()], map); + return Result( + Ast.Ordered( + [...map.keys()], + new Map([...map].map(([name, { value }]) => [name, value])), + ), + allEff([...map].map(([, { eff }]) => eff)), + ); } } const EMissingField = (name: string, prev: Ast.Loc): Ast.TcError => ({ @@ -301,13 +345,22 @@ const EDuplicateField = ( const decodeVar: Decode = function* (node, ctx) { if (node.name !== "self") { const type = yield* lookupVar(node.name, node.loc, ctx); - return Ast.DVar(node.name, type, node.loc); + return Result( + Ast.DVar(node.name, type, node.loc), + emptyEff, + ); } if (ctx.selfType) { - return Ast.DSelf(ctx.selfType, node.loc); + return Result( + Ast.DSelf(ctx.selfType, node.loc), + emptyEff, + ); } yield ENoSelf(node.loc); - return Ast.DVar(node.name, Ast.TypeNull(node.loc), node.loc); + return Result( + Ast.DVar(node.name, Ast.TBasic(Ast.TNull(node.loc), node.loc), node.loc), + emptyEff, + ); }; const ENoSelf = (loc: Ast.Loc): Ast.TcError => ({ loc, @@ -317,7 +370,7 @@ function* lookupVar( name: string, loc: Ast.Loc, ctx: Context, -): Ast.WithLog { +): Ast.WithLog { const local = ctx.localScopeRef.get(name); if (local) { const [type] = local; @@ -328,7 +381,7 @@ function* lookupVar( return yield* global.decl.type(); } yield EUndefined(name, loc); - return Ast.DTypeRecover(); + return Ast.CTypeRecover(); } const EUndefined = (name: string, loc: Ast.Loc): Ast.TcError => ({ loc, @@ -346,8 +399,8 @@ const decodeBinary: Decode = function* ( return throwInternal("Builtin operator is not in the map"); } const { returnType, typeArgMap } = yield* checkFnCall(node.loc, fnType, [ - [left.loc, left.computedType], - [right.loc, right.computedType], + [left.value.loc, left.value.computedType], + [right.value.loc, right.value.computedType], ]); if (node.op === "==" || node.op === "!=") { const typeArg = typeArgMap.get("T"); @@ -360,29 +413,27 @@ const decodeBinary: Decode = function* ( yield ENoEquality(node.loc); } } - return Ast.DOpBinary( - node.op, - left, - right, - typeArgMap, - returnType, - node.loc, + const newEff = node.op === '&&' || node.op === '||' + ? shortCircuitEff(left.eff, right.eff) + : allEff([left.eff, right.eff]); + return Result( + Ast.DOpBinary( + node.op, + left.value, + right.value, + typeArgMap, + returnType, + node.loc, + ), + newEff, ); }; const ENoEquality = (loc: Ast.Loc): Ast.TcError => ({ loc, descr: [Ast.TEText(`Equality on this type is not supported`)], }); -const supportsEquality = (common: Ast.DecodedType): boolean => { +const supportsEquality = (common: Ast.CType): boolean => { switch (common.kind) { - case "unit_type": - case "TyInt": - case "TySlice": - case "TyCell": - case "TypeNull": - case "TypeBool": - case "TypeAddress": - case "TypeString": case "map_type": { return true; } @@ -391,12 +442,31 @@ const supportsEquality = (common: Ast.DecodedType): boolean => { } case "recover": case "type_ref": - case "TypeVoid": case "TypeAlias": case "TypeParam": case "TypeBounced": case "tuple_type": - case "tensor_type": + case "tensor_type": { + return false; + } + case "basic": { + return supportsEqualityBasic(common.type); + } + } +}; +const supportsEqualityBasic = (common: Ast.BasicType): boolean => { + switch (common.kind) { + case "unit_type": + case "TyInt": + case "TySlice": + case "TyCell": + case "TypeNull": + case "TypeBool": + case "TypeAddress": + case "TypeString": { + return true; + } + case "TypeVoid": case "TyBuilder": case "TypeStateInit": case "TypeStringBuilder": { @@ -405,6 +475,7 @@ const supportsEquality = (common: Ast.DecodedType): boolean => { } }; + const decodeUnary: Decode = function* (node, ctx) { const operand = yield* decodeExprCtx(node.operand, ctx); const fnType = builtinBinary.get(node.op); @@ -412,10 +483,19 @@ const decodeUnary: Decode = function* (node, ctx) { return throwInternal("Builtin operator is not in the map"); } const { returnType, typeArgMap } = yield* checkFnCall(node.loc, fnType, [ - [operand.loc, operand.computedType], + [operand.value.loc, operand.value.computedType], ]); - return Ast.DOpUnary(node.op, operand, typeArgMap, returnType, node.loc); + return Result( + Ast.DOpUnary( + node.op, + operand.value, + typeArgMap, + returnType, + node.loc, + ), + operand.eff, + ); }; const decodeTernary: Decode = function* ( @@ -424,25 +504,34 @@ const decodeTernary: Decode = function* ( ) { const condition = yield* decodeExprCtx(node.condition, ctx); yield* assignType( - condition.loc, + condition.value.loc, emptyTypeParams, Bool, - condition.computedType, + condition.value.computedType, false, ); const thenBranch = yield* decodeExprCtx(node.thenBranch, ctx); const elseBranch = yield* decodeExprCtx(node.elseBranch, ctx); const commonType = yield* mgu( - thenBranch.computedType, - elseBranch.computedType, + thenBranch.value.computedType, + elseBranch.value.computedType, node.loc, ); - return Ast.DConditional( - condition, - thenBranch, - elseBranch, - commonType, - node.loc, + return Result( + Ast.DConditional( + condition.value, + thenBranch.value, + elseBranch.value, + commonType, + node.loc, + ), + allEff([ + condition.eff, + anyEff([ + thenBranch.eff, + elseBranch.eff, + ]), + ]), ); }; @@ -454,27 +543,40 @@ const decodeMethodCall: Decode = function* ( const args = yield* Ast.mapLog(node.args, (arg) => decodeExprCtx(arg, ctx)); const { typeDecls, extensions } = ctx.scopeRef(); - const { returnType, typeArgMap } = yield* lookupMethod( + const { returnType, typeArgMap, mutates } = yield* lookupMethod( ctx.Lazy, - self.computedType, + self.value.computedType, node.method, - args.map((child) => [child.loc, child.computedType]), + args.map((child) => [child.value.loc, child.value.computedType]), typeDecls, extensions, ); - return Ast.DMethodCall( - self, - node.method, - args, - typeArgMap, - returnType, - node.loc, + + const isCallOnStorage = hasStorageAccess(self.value, ctx.selfType); + + const selfArgsEff = allEff([self.eff, ...args.map(arg => arg.eff)]); + + return Result( + Ast.DMethodCall( + self.value, + node.method, + args.map(arg => arg.value), + typeArgMap, + returnType, + node.loc, + ), + { + mayRead: isCallOnStorage || selfArgsEff.mayRead, + mayWrite: mutates && isCallOnStorage || selfArgsEff.mayWrite, + mustThrow: selfArgsEff.mustThrow, + mustSetSelf: new Set(), + }, ); }; const decodeFunctionCall: Decode< Ast.StaticCall, - Ast.DStaticCall | Ast.DThrowCall | Ast.DNumber + Ast.DStaticCall | Ast.DNumber > = function* (node, ctx) { const name = node.function; @@ -482,17 +584,27 @@ const decodeFunctionCall: Decode< if (name.text === "sha256") { const [arg] = args; - const int = Ast.TypeInt(Ast.IFInt("signed", 257, node.loc), node.loc); + const int = Ast.TBasic(Ast.TInt(Ast.IFInt("signed", 257, node.loc), node.loc), node.loc); // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if ( args.length !== 1 || - (arg?.computedType.kind !== "TySlice" && - arg?.computedType.kind !== "TypeString") + !arg || + (arg.value.computedType.kind !== "basic") || + ( + arg.value.computedType.type.kind !== "TySlice" && + arg.value.computedType.type.kind !== "TypeString" + ) ) { yield EMismatchSha256(node.loc); - return Ast.DNumber("10", 0n, int, node.loc); + return Result( + Ast.DNumber("10", 0n, int, node.loc), + emptyEff, + ); } else { - return Ast.DStaticCall(name, new Map(), args, int, node.loc); + return Result( + Ast.DStaticCall(name, new Map(), [arg.value], int, node.loc), + arg.eff, + ); } } @@ -512,13 +624,22 @@ const decodeFunctionCall: Decode< ctx.scopeRef, )(); }), - args.map((child) => [child.loc, child.computedType]), + args.map((child) => [child.value.loc, child.value.computedType]), ); + const exprs = args.map(arg => arg.value); + const newEffs = allEff(args.map(arg => arg.eff)); + if (name.text === "throw" || name.text === "nativeThrow") { - return Ast.DThrowCall(name, args, returnType, node.loc); + return Result( + Ast.DStaticCall(name, typeArgMap, exprs, returnType, node.loc), + { + ...newEffs, + mustThrow: true, + }, + ); } else { - return Ast.DStaticCall(name, typeArgMap, args, returnType, node.loc); + return Result(Ast.DStaticCall(name, typeArgMap, exprs, returnType, node.loc), newEffs); } }; const EMismatchSha256 = (loc: Ast.Loc): Ast.TcError => ({ @@ -535,34 +656,37 @@ const decodeStaticMethodCall: Decode< } const args = yield* Ast.mapLog(node.args, (arg) => decodeExprCtx(arg, ctx)); const selfDecl = ctx.scopeRef().typeDecls.get(node.self.text); - if (selfDecl?.decl.kind === "struct" || selfDecl?.decl.kind === "message") { - const builtins = getStaticBuiltin( - Ast.DTypeRef(node.self, selfDecl.decl, [], node.loc), - ); - const builtin = builtins.get(node.function.text); - if (!builtin) { - yield EUndefinedStatic(node.function.text, node.loc); - return Ast.DNull(Ast.TypeNull(node.loc), node.loc); - } - const { returnType, typeArgMap } = yield* checkFnCallWithArgs( - ctx.Lazy, - node.loc, - builtin, - [], - args.map((child) => [child.loc, child.computedType]), - ); - return Ast.DStaticMethodCall( + if (!(selfDecl?.decl.kind === "struct" || selfDecl?.decl.kind === "message")) { + yield EUndefinedStatic(node.function.text, node.loc); + return Result(Ast.DNull(Ast.TBasic(Ast.TNull(node.loc), node.loc), node.loc), emptyEff); + } + const builtins = getStaticBuiltin( + Ast.DTypeRef(node.self, selfDecl.decl, [], node.loc), + ); + const builtin = builtins.get(node.function.text); + if (!builtin) { + yield EUndefinedStatic(node.function.text, node.loc); + return Result(Ast.DNull(Ast.TBasic(Ast.TNull(node.loc), node.loc), node.loc), emptyEff); + } + const { returnType, typeArgMap } = yield* checkFnCallWithArgs( + ctx.Lazy, + node.loc, + builtin, + [], + args.map((child) => [child.value.loc, child.value.computedType]), + ); + const newEffs = allEff(args.map(arg => arg.eff)); + return Result( + Ast.DStaticMethodCall( node.self, typeArgMap, node.function, - args, + args.map(arg => arg.value), returnType, node.loc, - ); - } else { - yield EUndefinedStatic(node.function.text, node.loc); - return Ast.DNull(Ast.TypeNull(node.loc), node.loc); - } + ), + newEffs, + ); }; const EUndefinedStatic = (name: string, loc: Ast.Loc): Ast.TcError => ({ loc, @@ -578,16 +702,22 @@ const decodeFieldAccess: Decode = function* ( ctx, ) { const expr = yield* decodeExprCtx(node.aggregate, ctx); - const selfType = expr.computedType; + const selfType = expr.value.computedType; const returnType = yield* lookupField(selfType, node.field, ctx.scopeRef); - return Ast.DFieldAccess(expr, node.field, returnType, node.loc); + return Result( + Ast.DFieldAccess(expr.value, node.field, returnType, node.loc), + { + ...expr.eff, + mayRead: hasStorageAccess(expr.value, ctx.selfType) || expr.eff.mayRead, + }, + ); }; function* lookupField( - selfType: Ast.DecodedType, + selfType: Ast.CType, fieldName: Ast.Id, - scopeRef: () => Ast.Scope, -): Ast.WithLog { + scopeRef: () => Ast.CSource, +): Ast.WithLog { switch (selfType.kind) { case "type_ref": { const decl = selfType.type; @@ -598,7 +728,7 @@ function* lookupField( const field = fields.map.get(fieldName.text); if (!field) { yield ENoSuchField(fieldName.text, fieldName.loc); - return Ast.DTypeRecover(); + return Ast.CTypeRecover(); } return yield* field.decl.type(); } @@ -607,13 +737,13 @@ function* lookupField( const field = decl.fields.map.get(fieldName.text); if (!field) { yield ENoSuchField(fieldName.text, fieldName.loc); - return Ast.DTypeRecover(); + return Ast.CTypeRecover(); } return yield* field.type(); } case "union": { yield ENoSuchField(fieldName.text, fieldName.loc); - return Ast.DTypeRecover(); + return Ast.CTypeRecover(); } } // linter asks for this unreachable code @@ -624,19 +754,19 @@ function* lookupField( if (type.kind === "recover") { return type; } else { - return Ast.DTypeMaybe(type, fieldName.loc); + return Ast.CTypeMaybe(type, fieldName.loc); } } case "TypeBounced": { const decl = scopeRef().typeDecls.get(selfType.name.text); if (!decl || decl.decl.kind !== "message") { yield ENoSuchField(fieldName.text, fieldName.loc); - return Ast.DTypeRecover(); + return Ast.CTypeRecover(); } const field = decl.decl.fields.map.get(fieldName.text); if (!field) { yield ENoSuchField(fieldName.text, fieldName.loc); - return Ast.DTypeRecover(); + return Ast.CTypeRecover(); } return yield* field.type(); } @@ -649,20 +779,9 @@ function* lookupField( case "map_type": case "tuple_type": case "tensor_type": - case "TyInt": - case "TySlice": - case "TyCell": - case "TyBuilder": - case "unit_type": - case "TypeVoid": - case "TypeNull": - case "TypeBool": - case "TypeAddress": - case "TypeString": - case "TypeStateInit": - case "TypeStringBuilder": { + case "basic": { yield ENoSuchField(fieldName.text, fieldName.loc); - return Ast.DTypeRecover(); + return Ast.CTypeRecover(); } } } @@ -672,13 +791,23 @@ const decodeInitOf: Decode = function* (node, ctx) { const contract = ctx.scopeRef().typeDecls.get(node.contract.text); if (contract?.decl.kind !== "contract") { yield ENotContract(node.contract.text, node.loc); - return Ast.DInitOf(node.contract, args, StateInit, node.loc); + return Result( + Ast.DInitOf( + node.contract, + args.map(arg => arg.value), + StateInit, + node.loc, + ), + allEff(args.map(arg => arg.eff)), + ); } + const params = yield* initParams(contract.decl.init); + yield* checkFnCallWithArgs( ctx.Lazy, node.loc, - Ast.DecodedFnType( + Ast.CTypeFunction( emptyTypeParams, params, ctx.Lazy({ @@ -691,20 +820,29 @@ const decodeInitOf: Decode = function* (node, ctx) { }), ), [], - args.map((child) => [child.loc, child.computedType]), + args.map((child) => [child.value.loc, child.value.computedType]), + ); + + return Result( + Ast.DInitOf( + node.contract, + args.map(arg => arg.value), + StateInit, + node.loc, + ), + allEff(args.map(arg => arg.eff)), ); - return Ast.DInitOf(node.contract, args, StateInit, node.loc); }; -function* initParams(init: Ast.InitSig) { +function* initParams(init: Ast.CInitSig) { switch (init.kind) { case "function": { return init.params; } case "empty": { - return Ast.Parameters([], new Set()); + return Ast.CParameters([], new Set()); } case "simple": { - const order: Ast.Parameter[] = []; + const order: Ast.CParameter[] = []; const set: Set = new Set(); for (const name of init.fill.order) { const param = init.fill.map.get(name); @@ -718,7 +856,7 @@ function* initParams(init: Ast.InitSig) { loc: param.loc, }); } - return Ast.Parameters(order, set); + return Ast.CParameters(order, set); } } } @@ -728,10 +866,13 @@ const decodeCodeOf: Decode = function* (node, ctx) { if (contract?.decl.kind !== "contract") { yield ENotContract(node.contract.text, node.loc); } - return Ast.DCodeOf( - node.contract, - Ast.TypeCell(Ast.SFDefault(node.loc), node.loc), - node.loc, + return Result( + Ast.DCodeOf( + node.contract, + Ast.TBasic(Ast.TCell(Ast.SFDefault(node.loc), node.loc), node.loc), + node.loc, + ), + emptyEff, ); }; const ENotContract = (name: string, loc: Ast.Loc): Ast.TcError => ({ diff --git a/src/next/types/extensions.ts b/src/next/types/extensions.ts index c88d90026b..3fc1ba20b3 100644 --- a/src/next/types/extensions.ts +++ b/src/next/types/extensions.ts @@ -11,9 +11,9 @@ export function decodeExtensions( Lazy: Ast.ThunkBuilder, imported: readonly Ast.SourceCheckResult[], source: TactSource, - scopeRef: () => Ast.Scope, -): ReadonlyMap[]>> { - const allExts: Map[]>[]> = + scopeRef: () => Ast.CSource, +): ReadonlyMap[]>> { + const allExts: Map[]>[]> = new Map(); // imported @@ -67,7 +67,7 @@ export function decodeExtensions( ); } - const result: Map[]>> = new Map(); + const result: Map[]>> = new Map(); for (const [name, exts] of allExts) { // checking method overlap is only possible when all the types // can be resolved @@ -76,14 +76,14 @@ export function decodeExtensions( Lazy({ callback: function* () { // force all thunks - const all: Ast.Decl[] = []; + const all: Ast.Decl[] = []; for (const lazyExt of exts) { const exts = yield* lazyExt(); all.push(...exts); } // check overlap and deduplicate - const prevs: Ast.Decl[] = []; + const prevs: Ast.Decl[] = []; for (const ext of all) { const builtin = builtinMethods.get(name); if (builtin && !isCompatible(builtin, ext.decl.type)) { @@ -115,7 +115,7 @@ export function decodeExtensions( function* decodeExt( Lazy: Ast.ThunkBuilder, node: Ast.Extension, - scopeRef: () => Ast.Scope, + scopeRef: () => Ast.CSource, ) { const { selfType, mutates, fun } = node; const { type, body, inline, loc } = fun; @@ -134,7 +134,7 @@ function* decodeExt( return undefined; } - const methodType = Ast.DecodedMethodType( + const methodType = Ast.CTypeMethod( mutates, decodedFn.typeParams, self, @@ -150,13 +150,13 @@ function* decodeExt( scopeRef, ); - return Ast.ExtSig(methodType, inline, decodedBody); + return Ast.CExtension(methodType, inline, decodedBody); } function* areCompatible( name: string, - prevs: readonly Ast.Decl[], - next: Ast.Decl, + prevs: readonly Ast.Decl[], + next: Ast.Decl, ): Ast.WithLog { for (const prev of prevs) { const prevType = prev.decl.type; @@ -183,8 +183,8 @@ const EMethodOverlap = ( }); function isCompatible( - prev: Ast.DecodedMethodType, - next: Ast.DecodedMethodType, + prev: Ast.CTypeMethod, + next: Ast.CTypeMethod, ) { const prevSelf = prev.self; const nextSelf = next.self; @@ -197,23 +197,13 @@ function isCompatible( } function areEqual( - prevSelf: Ast.MethodGroundType, - nextSelf: Ast.MethodGroundType, + prevSelf: Ast.SelfTypeGround, + nextSelf: Ast.SelfTypeGround, ): boolean { switch (prevSelf.kind) { - case "TyInt": - case "TySlice": - case "TyCell": - case "TyBuilder": - case "unit_type": - case "TypeVoid": - case "TypeNull": - case "TypeBool": - case "TypeAddress": - case "TypeString": - case "TypeStateInit": - case "TypeStringBuilder": { - return prevSelf.kind === nextSelf.kind; + case "basic": { + return prevSelf.kind === nextSelf.kind && + prevSelf.type.kind === nextSelf.type.kind; } case "type_ref": { return ( @@ -248,15 +238,15 @@ function areEqual( } function allEqual( - prevs: readonly Ast.MethodGroundType[], - nexts: readonly Ast.MethodGroundType[], + prevs: readonly Ast.SelfTypeGround[], + nexts: readonly Ast.SelfTypeGround[], ): boolean { return zip(prevs, nexts).every(([prev, next]) => areEqual(prev, next)); } function* decodeSelfType( - type: Ast.DecodedType, - scopeRef: () => Ast.Scope, + type: Ast.CType, + scopeRef: () => Ast.CSource, ): Ast.WithLog { switch (type.kind) { case "recover": { @@ -291,7 +281,7 @@ function* decodeSelfType( yield EBadMethodType(type.loc); return undefined; } - return Ast.MVTypeRef( + return Ast.SVTRef( type.name, def.decl, allVars, @@ -303,7 +293,7 @@ function* decodeSelfType( yield EBadMethodType(type.loc); return undefined; } - const ground: Ast.MethodGroundType[] = []; + const ground: Ast.SelfTypeGround[] = []; for (const arg of type.typeArgs) { const result = yield* toGroundType(arg, scopeRef); if (!result) { @@ -312,7 +302,7 @@ function* decodeSelfType( } ground.push(result); } - return Ast.MGTypeRef(type.name, def.decl, ground, type.loc); + return Ast.SGTRef(type.name, def.decl, ground, type.loc); } } // somehow typescript wants this @@ -330,7 +320,7 @@ function* decodeSelfType( type.key.kind === "TypeParam" && type.value.kind === "TypeParam" ) { - return Ast.MVTypeMap(type.key, type.value, type.loc); + return Ast.SVTMap(type.key, type.value, type.loc); } const ground = yield* toGroundType(type, scopeRef); if (!ground) { @@ -345,7 +335,7 @@ function* decodeSelfType( } case "TypeMaybe": { if (type.type.kind === "TypeParam") { - return Ast.MVTypeMaybe(type.type, type.loc); + return Ast.SVTMaybe(type.type, type.loc); } const ground = yield* toGroundType(type, scopeRef); if (!ground) { @@ -357,7 +347,7 @@ function* decodeSelfType( case "tensor_type": case "tuple_type": { const mvCons = - type.kind === "tuple_type" ? Ast.MVTypeTuple : Ast.MVTypeTensor; + type.kind === "tuple_type" ? Ast.SVTTuple : Ast.SVTTensor; const allVars = type.typeArgs.filter((arg) => { return arg.kind === "TypeParam"; }); @@ -377,30 +367,16 @@ function* decodeSelfType( } return ground; } - case "TyInt": - case "TySlice": - case "TyCell": - case "TyBuilder": - case "unit_type": - case "TypeVoid": - case "TypeNull": - case "TypeBool": - case "TypeAddress": - case "TypeString": - case "TypeStateInit": - case "TypeStringBuilder": { - return { - ground: "yes", - ...type, - }; + case "basic": { + return Ast.SGTBasic(type.type, type.loc); } } } function* toGroundType( - type: Ast.DecodedType, - scopeRef: () => Ast.Scope, -): Ast.WithLog { + type: Ast.CType, + scopeRef: () => Ast.CSource, +): Ast.WithLog { switch (type.kind) { case "recover": { return undefined; @@ -422,7 +398,7 @@ function* toGroundType( case "struct": case "message": case "union": { - const ground: Ast.MethodGroundType[] = []; + const ground: Ast.SelfTypeGround[] = []; for (const arg of type.typeArgs) { const result = yield* toGroundType(arg, scopeRef); if (!result) { @@ -430,7 +406,7 @@ function* toGroundType( } ground.push(result); } - return Ast.MGTypeRef( + return Ast.SGTRef( type.name, typeDecl.decl, ground, @@ -450,14 +426,14 @@ function* toGroundType( case "map_type": { const key = yield* toGroundType(type.key, scopeRef); const value = yield* toGroundType(type.value, scopeRef); - return key && value && Ast.MGTypeMap(key, value, type.loc); + return key && value && Ast.SGTMap(key, value, type.loc); } case "TypeBounced": { return undefined; } case "TypeMaybe": { const child = yield* toGroundType(type.type, scopeRef); - return child && Ast.MGTypeMaybe(child, type.loc); + return child && Ast.SGTMaybe(child, type.loc); } case "tuple_type": { const children = yield* Ast.mapLog( @@ -467,7 +443,7 @@ function* toGroundType( return result ? [result] : []; }, ); - return Ast.MGTypeTuple(children.flat(), type.loc); + return Ast.SGTTuple(children.flat(), type.loc); } case "tensor_type": { const children = yield* Ast.mapLog( @@ -477,24 +453,10 @@ function* toGroundType( return result ? [result] : []; }, ); - return Ast.MGTypeTensor(children.flat(), type.loc); + return Ast.SGTTensor(children.flat(), type.loc); } - case "TyInt": - case "TySlice": - case "TyCell": - case "TyBuilder": - case "unit_type": - case "TypeVoid": - case "TypeNull": - case "TypeBool": - case "TypeAddress": - case "TypeString": - case "TypeStateInit": - case "TypeStringBuilder": { - return { - ground: "yes", - ...type, - }; + case "basic": { + return Ast.SGTBasic(type.type, type.loc); } } } diff --git a/src/next/types/fields.ts b/src/next/types/fields.ts index 908eb33cc1..50c943362d 100644 --- a/src/next/types/fields.ts +++ b/src/next/types/fields.ts @@ -12,17 +12,17 @@ type MaybeExpr = Ast.Thunk | undefined; export function* getFieldishGeneral( Lazy: Ast.ThunkBuilder, - traitSigRef: Ast.TraitSig | Ast.ContractSig, + traitSigRef: Ast.CTraitSig | Ast.CContract, typeName: Ast.TypeId, - traits: readonly Ast.Decl[], + traits: readonly Ast.Decl[], constants: readonly Ast.FieldConstant[], fields: readonly Ast.FieldDecl[], - scopeRef: () => Ast.Scope, -): Ast.WithLog>>> { + scopeRef: () => Ast.CSource, +): Ast.WithLog>>> { // collect all inherited fields and constants const inherited: Map< string, - Ast.DeclMem> + Ast.DeclMem> > = new Map(); for (const { via, @@ -43,13 +43,13 @@ export function* getFieldishGeneral( } } - const selfType = Ast.MVTypeRef(typeName, traitSigRef, [], typeName.loc); + const selfType = Ast.SVTRef(typeName, traitSigRef, [], typeName.loc); // in which order fields were defined const order: string[] = []; // collection of all defined fields and constants - const all: Map>> = new Map(); + const all: Map>> = new Map(); // whether inherited field/constant was defined locally const overridden: Set = new Set(); @@ -156,7 +156,7 @@ function decodeField( Lazy: Ast.ThunkBuilder, typeName: string, field: Ast.FieldDecl, - scopeRef: () => Ast.Scope, + scopeRef: () => Ast.CSource, selfType: Ast.SelfType, ) { const { initializer, type, loc } = field; @@ -175,7 +175,7 @@ function decodeField( ); // decode field - return Ast.DeclMem(Ast.InhFieldSig(decoded, init), nextVia); + return Ast.DeclMem(Ast.CField(decoded, init), nextVia); } const EMustCopyField = (name: string, prev: Ast.ViaMember): Ast.TcError => ({ @@ -193,13 +193,13 @@ function* decodeConstant( init: Ast.ConstantInit, overridable: boolean, nextVia: Ast.ViaMember, - scopeRef: () => Ast.Scope, + scopeRef: () => Ast.CSource, selfType: Ast.SelfType, -): Ast.WithLog>> { +): Ast.WithLog>> { if (init.kind === "constant_decl") { const type = decodeTypeLazy(Lazy, emptyTypeParams, init.type, scopeRef); return Ast.DeclMem( - Ast.FieldConstSig(overridable, type, undefined), + Ast.CFieldConstant(overridable, type, undefined), nextVia, ); } else { @@ -211,6 +211,6 @@ function* decodeConstant( scopeRef, selfType, ); - return Ast.DeclMem(Ast.FieldConstSig(overridable, type, expr), nextVia); + return Ast.DeclMem(Ast.CFieldConstant(overridable, type, expr), nextVia); } } diff --git a/src/next/types/functions.ts b/src/next/types/functions.ts index 340ad80327..f2ac2d889f 100644 --- a/src/next/types/functions.ts +++ b/src/next/types/functions.ts @@ -12,8 +12,8 @@ export function* decodeFunctions( Lazy: Ast.ThunkBuilder, imported: readonly Ast.SourceCheckResult[], source: TactSource, - scopeRef: () => Ast.Scope, -): Ast.WithLog>> { + scopeRef: () => Ast.CSource, +): Ast.WithLog>> { const allFnSigs = [ // imported ...imported.flatMap(({ globals, importedBy }) => @@ -38,7 +38,7 @@ export function* decodeFunctions( ]; // remove duplicates and builtins - const filteredSigs: Map> = new Map(); + const filteredSigs: Map> = new Map(); for (const [name, sig] of allFnSigs) { const isBuiltin = builtinFunctions.has(name); if (isBuiltin) { @@ -60,11 +60,11 @@ export function* decodeFunctions( function* decodeFunction( Lazy: Ast.ThunkBuilder, fn: Ast.Function, - scopeRef: () => Ast.Scope, + scopeRef: () => Ast.CSource, ) { const { type, inline, body, loc } = fn; const fnType = yield* decodeFnType(Lazy, type, scopeRef); - return Ast.FnSig( + return Ast.CFunction( fnType, inline, yield* decodeBody(Lazy, body, fnType, loc, scopeRef), diff --git a/src/next/types/lvalue.ts b/src/next/types/lvalue.ts index 8c65dbb857..8ce1a5591a 100644 --- a/src/next/types/lvalue.ts +++ b/src/next/types/lvalue.ts @@ -3,6 +3,21 @@ import * as Ast from "@/next/ast"; export function* convertExprToLValue( node: Ast.DecodedExpression, +): Ast.WithLog { + const result = yield* convertExprToLValueAux(node); + if (result?.kind === 'self') { + yield ENoSelfAssign(node.loc); + return undefined; + } + return result; +} +const ENoSelfAssign = (loc: Ast.Loc): Ast.TcError => ({ + loc, + descr: [Ast.TEText(`Cannot assign to self`)], +}); + +function* convertExprToLValueAux( + node: Ast.DecodedExpression, ): Ast.WithLog { switch (node.kind) { case "field_access": { @@ -29,7 +44,6 @@ export function* convertExprToLValue( case "op_unary": case "conditional": case "method_call": - case "throw_call": case "static_call": case "static_method_call": case "struct_instance": @@ -46,7 +60,6 @@ export function* convertExprToLValue( } } } - const ENotLValue = (prev: Ast.Loc): Ast.TcError => ({ loc: prev, descr: [ diff --git a/src/next/types/message.ts b/src/next/types/message.ts index c169292293..d3e28de300 100644 --- a/src/next/types/message.ts +++ b/src/next/types/message.ts @@ -13,8 +13,8 @@ import { highest32ofSha256, sha256 } from "@/utils/sha256"; export function* decodeMessage( Lazy: Ast.ThunkBuilder, message: Ast.MessageDecl, - scopeRef: () => Ast.Scope, -): Ast.WithLog { + scopeRef: () => Ast.CSource, +): Ast.WithLog { const fields = yield* decodeFields( Lazy, message.fields, @@ -45,7 +45,7 @@ export function* decodeMessage( recover: undefined, }); - return Ast.MessageSig(lazyExpr, fields); + return Ast.CMessage(lazyExpr, fields); } const EZero = (next: Ast.Loc): Ast.TcError => ({ loc: next, @@ -62,11 +62,11 @@ const ETooLarge = (next: Ast.Loc): Ast.TcError => ({ function* decodeOpcode( Lazy: Ast.ThunkBuilder, - typeParams: Ast.TypeParams, + typeParams: Ast.CTypeParams, opcode: Ast.Expression | undefined, messageName: string, fieldsNames: readonly string[], - scopeRef: () => Ast.Scope, + scopeRef: () => Ast.CSource, ) { if (opcode) { const expr = yield* decodeExpr( @@ -77,11 +77,11 @@ function* decodeOpcode( undefined, new Map(), ); - const computed = expr.computedType; + const computed = expr.value.computedType; if ( yield* assignType(opcode.loc, emptyTypeParams, Int, computed, false) ) { - const result = yield* evalExpr(expr, scopeRef); + const result = yield* evalExpr(expr.value, scopeRef); // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (result.kind === "number") { return result.value; diff --git a/src/next/types/methods.ts b/src/next/types/methods.ts index 06a8a26bda..4132aa5b3d 100644 --- a/src/next/types/methods.ts +++ b/src/next/types/methods.ts @@ -13,18 +13,18 @@ import { emptyTypeParams } from "@/next/types/type-params"; export function* getMethodsGeneral( Lazy: Ast.ThunkBuilder, - declSig: Ast.TraitSig | Ast.ContractSig, + declSig: Ast.CTraitSig | Ast.CContract, typeName: Ast.TypeId, - traits: readonly Ast.Decl[], + traits: readonly Ast.Decl[], methods: readonly Ast.Method[], - scopeRef: () => Ast.Scope, + scopeRef: () => Ast.CSource, ): Ast.WithLog< - ReadonlyMap>> + ReadonlyMap>> > { // collect all inherited methods const inherited: Map< string, - Ast.DeclMem> + Ast.DeclMem> > = new Map(); for (const { via, @@ -44,7 +44,7 @@ export function* getMethodsGeneral( // collection of all defined methods const all: Map< string, - Ast.DeclMem> + Ast.DeclMem> > = new Map(); // whether inherited field/constant was defined locally @@ -56,9 +56,9 @@ export function* getMethodsGeneral( const nextVia = Ast.ViaMemberOrigin(typeName.text, loc); const decodedFn = yield* decodeFnType(Lazy, type, scopeRef); - const selfType = Ast.MVTypeRef(typeName, declSig, [], loc); - const methodType = Ast.DecodedMethodType( - mutates, + const selfType = Ast.SVTRef(typeName, declSig, [], loc); + const methodType = Ast.CTypeMethod( + true, // always mutates emptyTypeParams, selfType, decodedFn.params, @@ -94,7 +94,7 @@ export function* getMethodsGeneral( override, ); - const methodSig = Ast.MethodSig( + const methodSig = Ast.CMethod( overridable, methodType, inline, @@ -122,10 +122,10 @@ const EGenericMethod = (loc: Ast.Loc): Ast.TcError => ({ function decodeGetLazy( Lazy: Ast.ThunkBuilder, - typeParams: Ast.TypeParams, + typeParams: Ast.CTypeParams, fnName: Ast.Id, get: Ast.GetAttribute | undefined, - scopeRef: () => Ast.Scope, + scopeRef: () => Ast.CSource, selfType: Ast.SelfType, ): undefined | Ast.Thunk { if (!get) { @@ -142,10 +142,10 @@ function decodeGetLazy( function* decodeGet( Lazy: Ast.ThunkBuilder, - typeParams: Ast.TypeParams, + typeParams: Ast.CTypeParams, fnName: Ast.Id, get: Ast.GetAttribute, - scopeRef: () => Ast.Scope, + scopeRef: () => Ast.CSource, selfType: Ast.SelfType, ): Ast.WithLog { if (get.methodId) { @@ -157,13 +157,13 @@ function* decodeGet( selfType, new Map(), ); - const type = expr.computedType; - if (yield* assignType(expr.loc, emptyTypeParams, Int, type, false)) { - const methodId = yield* evalExpr(expr, scopeRef); + const type = expr.value.computedType; + if (yield* assignType(expr.value.loc, emptyTypeParams, Int, type, false)) { + const methodId = yield* evalExpr(expr.value, scopeRef); if ( // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition methodId.kind === "number" && - (yield* checkMethodId(methodId.value, expr.loc)) + (yield* checkMethodId(methodId.value, expr.value.loc)) ) { return methodId.value; } diff --git a/src/next/types/override.ts b/src/next/types/override.ts index c478d19c95..397a4ebb3e 100644 --- a/src/next/types/override.ts +++ b/src/next/types/override.ts @@ -6,10 +6,10 @@ export function* checkFieldOverride( name: string, prev: | Ast.DeclMem< - Ast.Fieldish> | undefined> + Ast.CFieldish> | undefined> > | undefined, - nextType: Ast.Thunk, + nextType: Ast.Thunk, nextVia: Ast.ViaMember, override: boolean, ): Ast.WithLog { @@ -45,8 +45,8 @@ export function* checkFieldOverride( export function* checkMethodOverride( name: string, - prev: Ast.DeclMem> | undefined, - nextType: Ast.DecodedMethodType, + prev: Ast.DeclMem> | undefined, + nextType: Ast.CTypeMethod, nextVia: Ast.ViaMember, override: boolean, ): Ast.WithLog { diff --git a/src/next/types/receivers.ts b/src/next/types/receivers.ts index 5fba23b057..5ab8a982d8 100644 --- a/src/next/types/receivers.ts +++ b/src/next/types/receivers.ts @@ -10,13 +10,13 @@ export function* getReceivers( Lazy: Ast.ThunkBuilder, selfTypeRef: () => Ast.SelfType, typeName: Ast.TypeId, - traits: readonly Ast.Decl[], + traits: readonly Ast.Decl[], receivers: readonly Ast.Receiver[], - scopeRef: () => Ast.Scope, -): Ast.WithLog { - const impExternals: Ast.Decl[] = []; - const impInternals: Ast.Decl[] = []; - const impBounces: Ast.Decl[] = []; + scopeRef: () => Ast.CSource, +): Ast.WithLog { + const impExternals: Ast.Decl[] = []; + const impInternals: Ast.Decl[] = []; + const impBounces: Ast.Decl[] = []; for (const { via, decl } of traits) { const { external, internal, bounce } = decl.receivers; impExternals.push(Ast.Decl(external, via)); @@ -85,16 +85,16 @@ function* mergeReceivers( Lazy: Ast.ThunkBuilder, selfTypeRef: () => Ast.SelfType, typeName: Ast.TypeId, - imported: readonly Ast.Decl[], + imported: readonly Ast.Decl[], local: Ast.DeclMem< readonly [Ast.ReceiverSubKind, readonly Ast.Statement[]] >[], - scopeRef: () => Ast.Scope, -): Ast.WithLog { - const allMessage: Ast.DeclMem[] = []; - let allMessageAny: undefined | Ast.DeclMem; - let allStringAny: undefined | Ast.DeclMem; - let allEmpty: undefined | Ast.DeclMem; + scopeRef: () => Ast.CSource, +): Ast.WithLog { + const allMessage: Ast.DeclMem[] = []; + let allMessageAny: undefined | Ast.DeclMem; + let allStringAny: undefined | Ast.DeclMem; + let allEmpty: undefined | Ast.DeclMem; // imported for (const { via: viaTrait, decl } of imported) { @@ -183,7 +183,7 @@ function* mergeReceivers( type, scopeRef, )(); - if (decoded.kind === "TySlice") { + if (decoded.kind === "basic" && decoded.type.kind === "TySlice") { if (allMessageAny) { yield ERedefineReceiver( "fallback binary", @@ -192,10 +192,10 @@ function* mergeReceivers( ); } allMessageAny = Ast.DeclMem( - Ast.MessageAnyRecv(name, statements), + Ast.CReceiverMessageAny(name, statements), via, ); - } else if (decoded.kind === "TypeString") { + } else if (decoded.kind === "basic" && decoded.type.kind === "TypeString") { if (allStringAny) { yield ERedefineReceiver( "fallback string", @@ -204,13 +204,13 @@ function* mergeReceivers( ); } allStringAny = Ast.DeclMem( - Ast.StringAnyRecv(name, statements), + Ast.CReceiverStringAny(name, statements), via, ); } else if (decoded.kind === "type_ref") { allMessage.push( Ast.DeclMem( - Ast.MessageRecv(name, decoded, statements), + Ast.CReceiverMessage(name, decoded, statements), via, ), ); @@ -227,13 +227,13 @@ function* mergeReceivers( via, ); } - allEmpty = Ast.DeclMem(Ast.EmptyRecv(statements), via); + allEmpty = Ast.DeclMem(Ast.CReceiverEmpty(statements), via); continue; } case "comment": { allMessage.push( Ast.DeclMem( - Ast.StringRecv(subKind.comment.value, statements), + Ast.CReceiverString(subKind.comment.value, statements), via, ), ); @@ -254,14 +254,14 @@ function* mergeBounce( Lazy: Ast.ThunkBuilder, selfTypeRef: () => Ast.SelfType, typeName: Ast.TypeId, - imported: readonly Ast.Decl[], + imported: readonly Ast.Decl[], local: readonly Ast.DeclMem< [Ast.TypedParameter, readonly Ast.Statement[]] >[], - scopeRef: () => Ast.Scope, -): Ast.WithLog { - const allMessage: Ast.DeclMem[] = []; - let allMessageAny: undefined | Ast.DeclMem; + scopeRef: () => Ast.CSource, +): Ast.WithLog { + const allMessage: Ast.DeclMem[] = []; + let allMessageAny: undefined | Ast.DeclMem; // imported for (const { @@ -323,7 +323,7 @@ function* mergeBounce( type, scopeRef, )(); - if (decoded.kind === "TySlice") { + if (decoded.kind === "basic" && decoded.type.kind === "TySlice") { if (allMessageAny) { yield ERedefineReceiver( "fallback binary", @@ -332,7 +332,7 @@ function* mergeBounce( ); } allMessageAny = Ast.DeclMem( - Ast.MessageAnyRecv(name, statements), + Ast.CReceiverMessageAny(name, statements), via, ); } else if ( @@ -340,7 +340,7 @@ function* mergeBounce( decoded.kind === "TypeBounced" ) { allMessage.push( - Ast.DeclMem(Ast.MessageRecv(name, decoded, statements), via), + Ast.DeclMem(Ast.CReceiverMessage(name, decoded, statements), via), ); } else { yield EInvalidRecv(via.defLoc); diff --git a/src/next/types/statements.ts b/src/next/types/statements.ts index ebe13650dd..5802a9e8c3 100644 --- a/src/next/types/statements.ts +++ b/src/next/types/statements.ts @@ -3,7 +3,7 @@ /* eslint-disable @typescript-eslint/no-unused-expressions */ import * as Ast from "@/next/ast"; import { throwInternal } from "@/error/errors"; -import { Bool, builtinAugmented, Int, Void } from "@/next/types/builtins"; +import { Bool, builtinAugmented, Int } from "@/next/types/builtins"; import { decodeExprCtx } from "@/next/types/expression"; import { convertExprToLValue } from "@/next/types/lvalue"; import { @@ -14,10 +14,11 @@ import { checkFnCall, } from "@/next/types/type"; import { + anyEff, + exitEff, emptyEff, - mergeEff, - setHadAssign, - setHadExit, + allEff, + hasStorageAccess as isStorageAccess, } from "@/next/types/effects"; import { emptyTypeParams } from "@/next/types/type-params"; @@ -25,11 +26,11 @@ export function decodeStatementsLazy( Lazy: Ast.ThunkBuilder, loc: Ast.Loc, statements: readonly Ast.Statement[], - typeParams: Ast.TypeParams, + typeParams: Ast.CTypeParams, selfTypeRef: () => undefined | Ast.SelfType, - returnType: Ast.Thunk, + returnType: Ast.Thunk, isInit: boolean, - scopeRef: () => Ast.Scope, + scopeRef: () => Ast.CSource, ) { return Lazy({ callback: function* (Lazy) { @@ -45,7 +46,7 @@ export function decodeStatementsLazy( typeParams, }; const res = yield* decodeStmts(statements, ctx, emptyEff); - return Ast.StatementsAux(res.node, res.effects); + return Ast.CStatementsAux(res.value, res.effects); }, context: [Ast.TEText("checking statements")], loc, @@ -61,8 +62,8 @@ const decodeStmts: Decode< let state = [ctx, eff] as const; for (const node of nodes) { const result = yield* decodeStatement(node, ctx, eff); - results.push(result.node); - state = [result.context, result.effects]; + results.push(result.value); + state = [result.context, allEff([eff, result.effects])]; } const [context, effects] = state; return Result(results, context, effects); @@ -109,7 +110,7 @@ const decodeLet: Decode = function* ( eff, ) { const expr = yield* decodeExprCtx(node.expression, ctx); - const result = Ast.DStatementLet(node.name, expr, node.loc); + const result = Ast.DStatementLet(node.name, expr.value, node.loc); if (node.type) { const ascribed = yield* decodeType( ctx.typeParams, @@ -117,60 +118,66 @@ const decodeLet: Decode = function* ( ctx.scopeRef().typeDecls, ); yield* assignType( - expr.loc, + expr.value.loc, emptyTypeParams, ascribed, - expr.computedType, + expr.value.computedType, false, ); const newCtx = yield* defineVar(node.name, ascribed, ctx); - return Result(result, newCtx, eff); + return Result(result, newCtx, expr.eff); } else { - const newCtx = yield* defineVar(node.name, expr.computedType, ctx); - return Result(result, newCtx, eff); + const newCtx = yield* defineVar(node.name, expr.value.computedType, ctx); + return Result(result, newCtx, expr.eff); } }; -const decodeReturn: Decode = - function* (node, ctx, eff) { - const newEff = yield* setHadExit(eff, true, ctx.required, node.loc); - if (node.expression) { - const expr = yield* decodeExprCtx(node.expression, ctx); - yield* assignType( - expr.loc, - emptyTypeParams, - ctx.returnType, - expr.computedType, - false, - ); - return Result(Ast.DStatementReturn(expr, node.loc), ctx, newEff); - } else { - yield* assignType( - node.loc, - emptyTypeParams, - ctx.returnType, - Void, - false, - ); - return Result( - Ast.DStatementReturn(undefined, node.loc), - ctx, - newEff, - ); +const decodeReturn: Decode = function* (node, ctx, eff) { + if (ctx.required) { + const missing = [...ctx.required].filter((p) => !eff.mustSetSelf.has(p)); + for (const fieldName of missing) { + yield EMissingSelfInit(fieldName, node.loc); } - }; + } + const expr = yield* checkReturnExpr(node.expression, ctx); + return Result( + Ast.DStatementReturn(expr?.value, node.loc), + ctx, + exitEff(expr ? expr.eff : emptyEff), + ); +}; +const EMissingSelfInit = (name: string, loc: Ast.Loc): Ast.TcError => ({ + loc, + descr: [ + Ast.TEText(`Field "self.${name}" is not initialized by this moment`), + ], +}); +function* checkReturnExpr(node: Ast.Expression | undefined, ctx: Context) { + if (!node) { + return undefined; + } + const expr = yield* decodeExprCtx(node, ctx); + yield* assignType( + expr.value.loc, + emptyTypeParams, + ctx.returnType, + expr.value.computedType, + false, + ); + return expr; +} + const decodeExpression: Decode< Ast.StatementExpression, Ast.DStatementExpression > = function* (node, ctx, eff) { const expr = yield* decodeExprCtx(node.expression, ctx); - if (expr.kind === "throw_call") { - const newEff = yield* setHadExit(eff, true, ctx.required, node.loc); - return Result(Ast.DStatementExpression(expr, node.loc), ctx, newEff); - } else { - return Result(Ast.DStatementExpression(expr, node.loc), ctx, eff); - } + return Result( + Ast.DStatementExpression(expr.value, node.loc), + ctx, + expr.eff, + ); }; const decodeAssign: Decode< @@ -179,20 +186,29 @@ const decodeAssign: Decode< > = function* (node, ctx, eff) { const right = yield* decodeExprCtx(node.expression, ctx); const left = yield* decodeExprCtx(node.path, ctx); - const path = yield* convertExprToLValue(left); - if (path) { - yield* assignType( - path.loc, - emptyTypeParams, - path.computedType, - right.computedType, - false, + const path = yield* convertExprToLValue(left.value); + if (!path) { + return Result( + Ast.DStatementExpression(right.value, node.loc), + ctx, + allEff([left.eff, right.eff]), ); - const newEff = yield* setHadAssign(eff, path); - return Result(Ast.DStatementAssign(path, right, node.loc), ctx, newEff); - } else { - return Result(Ast.DStatementExpression(right, node.loc), ctx, eff); } + + yield* assignType( + path.loc, + emptyTypeParams, + path.computedType, + right.value.computedType, + false, + ); + const argEffs = allEff([left.eff, right.eff]); + const isAssignToStorage = isStorageAccess(path, ctx.selfType); + const newEff: Ast.Effects = { + ...argEffs, + mayWrite: isAssignToStorage || argEffs.mayWrite, + }; + return Result(Ast.DStatementAssign(path, right.value, node.loc), ctx, newEff); }; const decodeAssignAugmented: Decode< @@ -201,66 +217,69 @@ const decodeAssignAugmented: Decode< > = function* (node, ctx, eff) { const right = yield* decodeExprCtx(node.expression, ctx); const left = yield* decodeExprCtx(node.path, ctx); - const path = yield* convertExprToLValue(left); + const path = yield* convertExprToLValue(left.value); + if (!path) { + return Result(Ast.DStatementExpression(right.value, node.loc), ctx, eff); + } + const fnType = builtinAugmented.get(node.op); if (!fnType) { return throwInternal("Builtin operator is not in the map"); } yield* checkFnCall(node.loc, fnType, [ - [left.loc, left.computedType], - [right.loc, right.computedType], + [left.value.loc, left.value.computedType], + [right.value.loc, right.value.computedType], ]); - if (path) { - const newEff = yield* setHadAssign(eff, path); - return Result( - Ast.DStatementAugmentedAssign(node.op, path, right, node.loc), - ctx, - newEff, - ); - } else { - return Result(Ast.DStatementExpression(right, node.loc), ctx, eff); - } + + const argEffs = allEff([left.eff, right.eff]); + const isAssignToStorage = isStorageAccess(path, ctx.selfType); + const newEff: Ast.Effects = { + ...argEffs, + mayRead: isAssignToStorage || argEffs.mayRead, + mayWrite: isAssignToStorage || argEffs.mayWrite, + }; + return Result( + Ast.DStatementAugmentedAssign(node.op, path, right.value, node.loc), + ctx, + newEff, + ); }; const decodeCondition: Decode = function* (node, ctx, eff) { const condition = yield* decodeExprCtx(node.condition, ctx); yield* assignType( - condition.loc, + condition.value.loc, emptyTypeParams, Bool, - condition.computedType, + condition.value.computedType, false, ); const trueRes = yield* decodeStmts(node.trueStatements, ctx, eff); - if (node.falseStatements) { - const falseRes = yield* decodeStmts(node.falseStatements, ctx, eff); - const newEff = mergeEff(trueRes.effects, falseRes.effects); - return Result( - Ast.DStatementCondition( - condition, - trueRes.node, - falseRes.node, - node.loc, - ), - ctx, - newEff, - ); - } else { - const newEff = mergeEff(trueRes.effects, eff); - return Result( - Ast.DStatementCondition( - condition, - trueRes.node, - undefined, - node.loc, - ), - ctx, - newEff, - ); - } + const falseRes = yield* checkElse(node.falseStatements, ctx, eff); + return Result( + Ast.DStatementCondition( + condition.value, + trueRes.value, + falseRes.value, + node.loc, + ), + ctx, + allEff([ + condition.eff, + anyEff([trueRes.effects, falseRes.effects])], + ), + ); }; - +const checkElse: Decode< + undefined | readonly Ast.Statement[], + undefined | readonly Ast.DecodedStatement[] +> = function* (node, ctx, eff) { + if (typeof node === 'undefined') { + return Result(undefined, ctx, emptyEff); + } + return yield* decodeStmts(node, ctx, eff); +} const decodeWhile: Decode = function* ( node, ctx, @@ -268,19 +287,19 @@ const decodeWhile: Decode = function* ( ) { const condition = yield* decodeExprCtx(node.condition, ctx); yield* assignType( - condition.loc, + condition.value.loc, emptyTypeParams, Bool, - condition.computedType, + condition.value.computedType, false, ); const result = yield* decodeStmts(node.statements, ctx, eff); // might be executed zero times, so it doesn't matter // if it always returns, or assigns to `self` return Result( - Ast.DStatementWhile(condition, result.node, node.loc), + Ast.DStatementWhile(condition.value, result.value, node.loc), ctx, - eff, + allEff([condition.eff, anyEff([result.effects, emptyEff])]), ); }; @@ -291,18 +310,17 @@ const decodeUntil: Decode = function* ( ) { const condition = yield* decodeExprCtx(node.condition, ctx); yield* assignType( - condition.loc, + condition.value.loc, emptyTypeParams, Bool, - condition.computedType, + condition.value.computedType, false, ); const result = yield* decodeStmts(node.statements, ctx, eff); - // until executes its body at least once return Result( - Ast.DStatementUntil(condition, result.node, node.loc), + Ast.DStatementUntil(condition.value, result.value, node.loc), ctx, - result.effects, + allEff([result.effects, condition.eff, anyEff([result.effects, emptyEff])]), ); }; @@ -310,19 +328,19 @@ const decodeRepeat: Decode = function* (node, ctx, eff) { const iterations = yield* decodeExprCtx(node.iterations, ctx); yield* assignType( - iterations.loc, + iterations.value.loc, emptyTypeParams, Int, - iterations.computedType, + iterations.value.computedType, false, ); const result = yield* decodeStmts(node.statements, ctx, eff); // might be executed zero times, so it doesn't matter // if it always returns, or assigns to `self` return Result( - Ast.DStatementRepeat(iterations, result.node, node.loc), + Ast.DStatementRepeat(iterations.value, result.value, node.loc), ctx, - eff, + allEff([iterations.eff, anyEff([result.effects, emptyEff])]), ); }; @@ -339,16 +357,15 @@ const decodeTry: Decode = function* ( newCtx, eff, ); - const catchBlock = Ast.DCatchBlock(node.catchBlock.name, catchRes.node); - const newEff = mergeEff(tryRes.effects, catchRes.effects); + const catchBlock = Ast.DCatchBlock(node.catchBlock.name, catchRes.value); return Result( - Ast.DStatementTry(tryRes.node, catchBlock, node.loc), + Ast.DStatementTry(tryRes.value, catchBlock, node.loc), ctx, - newEff, + anyEff([tryRes.effects, catchRes.effects]), ); } else { return Result( - Ast.DStatementTry(tryRes.node, undefined, node.loc), + Ast.DStatementTry(tryRes.value, undefined, node.loc), ctx, tryRes.effects, ); @@ -359,7 +376,7 @@ const decodeForeach: Decode = function* (node, ctx, eff) { const map = yield* decodeExprCtx(node.map, ctx); const innerCtx = yield* defineForVars( - map.computedType, + map.value.computedType, node.keyName, node.valueName, ctx, @@ -369,16 +386,16 @@ const decodeForeach: Decode = Ast.DStatementForEach( node.keyName, node.valueName, - map, - result.node, + map.value, + result.value, node.loc, ), ctx, - eff, + allEff([map.eff, anyEff([result.effects, emptyEff])]), ); }; function* defineForVars( - type: Ast.DecodedType, + type: Ast.CType, keyName: Ast.OptionalId, valueName: Ast.OptionalId, ctx: Context, @@ -395,8 +412,8 @@ function* defineForVars( } return yield* defineForVars(childType, keyName, valueName, ctx); } else { - const ctxKey = yield* defineVar(keyName, Ast.DTypeRecover(), ctx); - const ctxKV = yield* defineVar(valueName, Ast.DTypeRecover(), ctxKey); + const ctxKey = yield* defineVar(keyName, Ast.CTypeRecover(), ctx); + const ctxKV = yield* defineVar(valueName, Ast.CTypeRecover(), ctxKey); return ctxKV; } } @@ -418,7 +435,7 @@ const decodeDestruct: Decode< const decl = yield* findStruct(node.type, typeArgs, ctx.scopeRef); if (!decl) { - return Result(Ast.DStatementExpression(expr, node.loc), ctx, eff); + return Result(Ast.DStatementExpression(expr.value, node.loc), ctx, expr.eff); } const ascribed = Ast.DTypeRef(node.type, decl, typeArgs, node.loc); @@ -426,7 +443,7 @@ const decodeDestruct: Decode< node.loc, emptyTypeParams, ascribed, - expr.computedType, + expr.value.computedType, false, ); @@ -444,17 +461,17 @@ const decodeDestruct: Decode< node.type, fields, node.ignoreUnspecifiedFields, - expr, + expr.value, node.loc, ), newCtx, - eff, + expr.eff, ); }; function* checkFields( nodeLoc: Ast.Loc, stmtFields: readonly (readonly [Ast.Id, Ast.OptionalId])[], - declFields: Ast.Ordered, + declFields: Ast.Ordered, ignoreUnspecifiedFields: boolean, ctx: Context, ): Ast.WithLog, Context]> { @@ -522,8 +539,8 @@ const EDuplicateField = ( }); function* findStruct( id: Ast.TypeId, - typeArgs: Ast.DecodedType[], - scopeRef: () => Ast.Scope, + typeArgs: Ast.CType[], + scopeRef: () => Ast.CSource, ) { const decl = scopeRef().typeDecls.get(id.text); if (!decl) { @@ -532,7 +549,7 @@ function* findStruct( switch (decl.decl.kind) { case "alias": { const type = yield* dealiasType( - Ast.DTypeAliasRef(Ast.NotDealiased(), id, typeArgs, id.loc), + Ast.CTypeAliasRef(Ast.CNotDealiased(), id, typeArgs, id.loc), scopeRef, ); if ( @@ -569,7 +586,7 @@ const decodeBlock: Decode = function* ( ) { const result = yield* decodeStmts(node.statements, ctx, eff); return Result( - Ast.DStatementBlock(result.node, node.loc), + Ast.DStatementBlock(result.value, node.loc), ctx, result.effects, ); @@ -578,33 +595,33 @@ const decodeBlock: Decode = function* ( type Decode = ( node: T, context: Context, - effects: Ast.Effects, + effAbove: Ast.Effects, ) => Ast.WithLog>; type Result = { - readonly node: U; + readonly value: U; readonly context: Context; readonly effects: Ast.Effects; }; const Result = ( - node: U, + value: U, context: Context, effects: Ast.Effects, -): Result => Object.freeze({ node, context, effects }); +): Result => Object.freeze({ value, context, effects }); type Context = { readonly Lazy: Ast.ThunkBuilder; - readonly scopeRef: () => Ast.Scope; + readonly scopeRef: () => Ast.CSource; readonly selfType: Ast.SelfType | undefined; readonly required: undefined | ReadonlySet; - readonly typeParams: Ast.TypeParams; - readonly returnType: Ast.DecodedType; - readonly localScopeRef: ReadonlyMap; + readonly typeParams: Ast.CTypeParams; + readonly returnType: Ast.CType; + readonly localScopeRef: ReadonlyMap; }; function* defineVar( node: Ast.OptionalId, - type: Ast.DecodedType, + type: Ast.CType, ctx: Context, ): Ast.WithLog { if (node.kind === "wildcard") { @@ -703,18 +720,7 @@ function* getRequired( case "TypeMaybe": case "tuple_type": case "tensor_type": - case "TyInt": - case "TySlice": - case "TyCell": - case "TyBuilder": - case "unit_type": - case "TypeVoid": - case "TypeNull": - case "TypeBool": - case "TypeAddress": - case "TypeString": - case "TypeStateInit": - case "TypeStringBuilder": { + case "basic": { return undefined; } } diff --git a/src/next/types/struct-fields.ts b/src/next/types/struct-fields.ts index d2345880ef..98b8083d22 100644 --- a/src/next/types/struct-fields.ts +++ b/src/next/types/struct-fields.ts @@ -9,11 +9,11 @@ import { emptyTypeParams } from "@/next/types/type-params"; export function* decodeFields( Lazy: Ast.ThunkBuilder, fields: readonly Ast.FieldDecl[], - typeParams: Ast.TypeParams, - scopeRef: () => Ast.Scope, + typeParams: Ast.CTypeParams, + scopeRef: () => Ast.CSource, ) { const order: string[] = []; - const all: Map = new Map(); + const all: Map = new Map(); for (const field of fields) { const { initializer, loc } = field; const name = field.name.text; @@ -43,7 +43,7 @@ export function* decodeFields( ); order.push(name); - all.set(name, [loc, Ast.InhFieldSig(ascribedType, lazyExpr)]); + all.set(name, [loc, Ast.CField(ascribedType, lazyExpr)]); } const map = new Map([...all].map(([name, [, field]]) => [name, field])); @@ -53,11 +53,11 @@ export function* decodeFields( export function decodeInitializerLazy( Lazy: Ast.ThunkBuilder, loc: Ast.Loc, - typeParams: Ast.TypeParams, - ascribedType: Ast.Thunk, + typeParams: Ast.CTypeParams, + ascribedType: Ast.Thunk, initializer: Ast.Expression | undefined, selfType: undefined | Ast.SelfType, - scopeRef: () => Ast.Scope, + scopeRef: () => Ast.CSource, ) { if (!initializer) { return undefined; @@ -72,16 +72,16 @@ export function decodeInitializerLazy( selfType, new Map(), ); - const computed = expr.computedType; + const computed = expr.value.computedType; const ascribed = yield* ascribedType(); yield* assignType( - expr.loc, + expr.value.loc, emptyTypeParams, ascribed, computed, false, ); - return yield* evalExpr(expr, scopeRef); + return yield* evalExpr(expr.value, scopeRef); }, context: [Ast.TEText("evaluating initial field value")], loc, diff --git a/src/next/types/struct.ts b/src/next/types/struct.ts index 8303498de9..bbdce0ef3e 100644 --- a/src/next/types/struct.ts +++ b/src/next/types/struct.ts @@ -7,8 +7,8 @@ import { decodeTypeParams } from "@/next/types/type-params"; export function* decodeStruct( Lazy: Ast.ThunkBuilder, struct: Ast.StructDecl, - scopeRef: () => Ast.Scope, -): Ast.WithLog { + scopeRef: () => Ast.CSource, +): Ast.WithLog { const typeParams = yield* decodeTypeParams(struct.typeParams); const fields = yield* decodeFields( Lazy, @@ -16,5 +16,5 @@ export function* decodeStruct( typeParams, scopeRef, ); - return Ast.StructSig(typeParams, fields); + return Ast.CStruct(typeParams, fields); } diff --git a/src/next/types/trait.ts b/src/next/types/trait.ts index 13a383ffdc..73c5f3f18f 100644 --- a/src/next/types/trait.ts +++ b/src/next/types/trait.ts @@ -9,8 +9,8 @@ import { getReceivers } from "@/next/types/receivers"; export function* decodeTrait( Lazy: Ast.ThunkBuilder, trait: Ast.Trait, - scopeRef: () => Ast.Scope, -): Ast.WithLog { + scopeRef: () => Ast.CSource, +): Ast.WithLog { const { attributes, declarations, name, loc } = trait; const { constants, fields, methods, receivers } = declarations; @@ -26,7 +26,7 @@ export function* decodeTrait( const traits = yield* getInheritedTraits(trait.traits, scopeRef); // const contentRef = () => content; - const content: Ast.TraitContent = { + const content: Ast.CTraitMembers = { fieldish: yield* getFieldishGeneral( Lazy, traitSig, @@ -61,9 +61,9 @@ export function* decodeTrait( recover, }); - const traitSig = Ast.TraitSig(contentLazy); + const traitSig = Ast.CTraitSig(contentLazy); - const selfType = Ast.MVTypeRef(trait.name, traitSig, [], trait.loc); + const selfType = Ast.SVTRef(trait.name, traitSig, [], trait.loc); return traitSig; } @@ -73,7 +73,7 @@ const ENoAttributes = (loc: Ast.Loc): Ast.TcError => ({ descr: [Ast.TEText(`Traits cannot have attributes`)], }); -const recover: Ast.TraitContent = { +const recover: Ast.CTraitMembers = { fieldish: Ast.Ordered([], new Map()), methods: new Map(), receivers: { diff --git a/src/next/types/traits-scope.ts b/src/next/types/traits-scope.ts index 38e48d2d6f..c70c3ecdb6 100644 --- a/src/next/types/traits-scope.ts +++ b/src/next/types/traits-scope.ts @@ -4,10 +4,10 @@ import * as Ast from "@/next/ast"; export function* getInheritedTraits( traits: readonly Ast.TypeId[], - scopeRef: () => Ast.Scope, -): Ast.WithLog[]> { + scopeRef: () => Ast.CSource, +): Ast.WithLog[]> { const decls = scopeRef().typeDecls; - const prevTraits: Ast.Decl[] = []; + const prevTraits: Ast.Decl[] = []; for (const trait of traits) { const name = trait.text; const decl = decls.get(name); diff --git a/src/next/types/type-fn.ts b/src/next/types/type-fn.ts index fe17296766..20400ab0c8 100644 --- a/src/next/types/type-fn.ts +++ b/src/next/types/type-fn.ts @@ -7,14 +7,14 @@ import { recoverName } from "@/next/types/name"; export function* decodeFnType( Lazy: Ast.ThunkBuilder, - { typeParams, params, returnType }: Ast.FnType, - scopeRef: () => Ast.Scope, -): Ast.WithLog { + { typeParams, params, returnType }: Ast.TFunction, + scopeRef: () => Ast.CSource, +): Ast.WithLog { const decodedTypeParams = yield* decodeTypeParams(typeParams); const dealias = (type: Ast.Type) => { return decodeDealiasTypeLazy(Lazy, decodedTypeParams, type, scopeRef); }; - return Ast.DecodedFnType( + return Ast.CTypeFunction( decodedTypeParams, yield* decodeParams(dealias, params), dealias(returnType), @@ -22,19 +22,19 @@ export function* decodeFnType( } export function* decodeParams( - dealias: (type: Ast.Type) => Ast.Thunk, + dealias: (type: Ast.Type) => Ast.Thunk, params: readonly Ast.TypedParameter[], -): Ast.WithLog { - const order: Ast.Parameter[] = []; +): Ast.WithLog { + const order: Ast.CParameter[] = []; const set: Set = new Set(); for (const param of params) { const name = yield* decodeParamName(param.name, set); - order.push(Ast.Parameter(param.name, dealias(param.type), param.loc)); + order.push(Ast.CParameter(param.name, dealias(param.type), param.loc)); if (typeof name !== "undefined") { set.add(name); } } - return Ast.Parameters(order, set); + return Ast.CParameters(order, set); } function* decodeParamName( diff --git a/src/next/types/type-params.ts b/src/next/types/type-params.ts index 50de57a885..44e61bc3b0 100644 --- a/src/next/types/type-params.ts +++ b/src/next/types/type-params.ts @@ -1,11 +1,11 @@ import * as Ast from "@/next/ast"; import { recoverName } from "@/next/types/name"; -export const emptyTypeParams = Ast.TypeParams([], new Set()); +export const emptyTypeParams = Ast.CTypeParams([], new Set()); export function* decodeTypeParams( ids: readonly Ast.TypeId[], -): Ast.WithLog { +): Ast.WithLog { const set: Set = new Set(); const order: Ast.TypeId[] = []; @@ -20,7 +20,7 @@ export function* decodeTypeParams( } } - return Ast.TypeParams(ids, set); + return Ast.CTypeParams(ids, set); } const EDuplicateTypeParam = (name: string, loc: Ast.Loc): Ast.TcError => ({ diff --git a/src/next/types/type-print.ts b/src/next/types/type-print.ts index c54eff1aed..bba002262e 100644 --- a/src/next/types/type-print.ts +++ b/src/next/types/type-print.ts @@ -1,7 +1,7 @@ import type * as Ast from "@/next/ast"; -export function printType(node: Ast.DecodedType, allowRecover: boolean) { - function recN(nodes: readonly Ast.DecodedType[]): undefined | string { +export function printType(node: Ast.CType, allowRecover: boolean) { + function recN(nodes: readonly Ast.CType[]): undefined | string { const results: string[] = []; for (const node of nodes) { const result = rec(node); @@ -14,7 +14,7 @@ export function printType(node: Ast.DecodedType, allowRecover: boolean) { return results.join(", "); } - function rec(node: Ast.DecodedType): undefined | string { + function rec(node: Ast.CType): undefined | string { switch (node.kind) { case "recover": { return allowRecover ? "$ERROR" : undefined; @@ -49,41 +49,8 @@ export function printType(node: Ast.DecodedType, allowRecover: boolean) { const typeArgs = recN(node.typeArgs); return typeArgs && `[${typeArgs}]`; } - case "TyInt": { - return `Int${printIntFormat(node.format)}`; - } - case "TySlice": { - return `Slice${printSliceFormat(node.format)}`; - } - case "TyCell": { - return `Cell${printRemFormat(node.format)}`; - } - case "TyBuilder": { - return `Builder${printRemFormat(node.format)}`; - } - case "unit_type": { - return `()`; - } - case "TypeVoid": { - return `Void`; - } - case "TypeNull": { - return `Null`; - } - case "TypeBool": { - return `Bool`; - } - case "TypeAddress": { - return `Address`; - } - case "TypeStateInit": { - return `StateInit`; - } - case "TypeString": { - return `String`; - } - case "TypeStringBuilder": { - return `StringBuilder`; + case "basic": { + return printBasic(node.type) } } } @@ -91,6 +58,47 @@ export function printType(node: Ast.DecodedType, allowRecover: boolean) { return rec(node); } +const printBasic = (node: Ast.BasicType): string => { + switch (node.kind) { + case "TyInt": { + return `Int${printIntFormat(node.format)}`; + } + case "TySlice": { + return `Slice${printSliceFormat(node.format)}`; + } + case "TyCell": { + return `Cell${printRemFormat(node.format)}`; + } + case "TyBuilder": { + return `Builder${printRemFormat(node.format)}`; + } + case "unit_type": { + return `()`; + } + case "TypeVoid": { + return `Void`; + } + case "TypeNull": { + return `Null`; + } + case "TypeBool": { + return `Bool`; + } + case "TypeAddress": { + return `Address`; + } + case "TypeStateInit": { + return `StateInit`; + } + case "TypeString": { + return `String`; + } + case "TypeStringBuilder": { + return `StringBuilder`; + } + } +}; + const printIntFormat = (format: Ast.IntFormat): string => { if ( format.kind === "FInt" && diff --git a/src/next/types/type.ts b/src/next/types/type.ts index 853851bfc2..00e03b9573 100644 --- a/src/next/types/type.ts +++ b/src/next/types/type.ts @@ -9,22 +9,22 @@ import { zip } from "@/utils/array"; export const decodeTypeLazy = ( Lazy: Ast.ThunkBuilder, - typeParams: Ast.TypeParams, + typeParams: Ast.CTypeParams, type: Ast.Type, - scopeRef: () => Ast.Scope, + scopeRef: () => Ast.CSource, ) => Lazy({ callback: () => decodeType(typeParams, type, scopeRef().typeDecls), context: [Ast.TEText("checking type"), Ast.TECode(type.loc)], loc: type.loc, - recover: Ast.DTypeRecover(), + recover: Ast.CTypeRecover(), }); export const decodeDealiasTypeLazy = ( Lazy: Ast.ThunkBuilder, - typeParams: Ast.TypeParams, + typeParams: Ast.CTypeParams, type: Ast.Type, - scopeRef: () => Ast.Scope, + scopeRef: () => Ast.CSource, ) => Lazy({ callback: function* () { @@ -37,45 +37,45 @@ export const decodeDealiasTypeLazy = ( }, context: [Ast.TEText("checking type"), Ast.TECode(type.loc)], loc: type.loc, - recover: Ast.DTypeRecover(), + recover: Ast.CTypeRecover(), }); -export function* dealiasType(type: Ast.DecodedType, scopeRef: () => Ast.Scope) { +export function* dealiasType(type: Ast.CType, scopeRef: () => Ast.CSource) { return yield* dealiasTypeAux(type, scopeRef().typeDecls); } export function* decodeTypeMap( - typeParams: Ast.TypeParams, - type: Ast.TypeMap, - scopeRef: () => Ast.Scope, + typeParams: Ast.CTypeParams, + type: Ast.TMap, + scopeRef: () => Ast.CSource, ) { const { typeDecls } = scopeRef(); const key = yield* decodeType(typeParams, type.key, typeDecls); const value = yield* decodeType(typeParams, type.value, typeDecls); - return Ast.DTypeMap(key, value, type.loc); + return Ast.CTypeMap(key, value, type.loc); } export function* decodeTypeSet( - typeParams: Ast.TypeParams, - type: Ast.TypeMap, - scopeRef: () => Ast.Scope, + typeParams: Ast.CTypeParams, + type: Ast.TMap, + scopeRef: () => Ast.CSource, ) { const { typeDecls } = scopeRef(); const key = yield* decodeType(typeParams, type.key, typeDecls); const value = yield* decodeType(typeParams, type.value, typeDecls); - return Ast.DTypeMap(key, value, type.loc); + return Ast.CTypeMap(key, value, type.loc); } export function decodeType( - typeParams: Ast.TypeParams, + typeParams: Ast.CTypeParams, type: Ast.Type, - typeDecls: ReadonlyMap>, + typeDecls: ReadonlyMap>, ) { // decode all the types in an array function* recN( types: readonly Ast.Type[], - ): Ast.WithLog { - const results: Ast.DecodedType[] = []; + ): Ast.WithLog { + const results: Ast.CType[] = []; for (const type of types) { const result = yield* rec(type); results.push(result); @@ -84,56 +84,45 @@ export function decodeType( } // decode a type - function* rec(type: Ast.Type): Ast.WithLog { + function* rec(type: Ast.Type): Ast.WithLog { switch (type.kind) { - case "unit_type": - case "TyInt": - case "TySlice": - case "TyCell": - case "TyBuilder": - case "TypeVoid": - case "TypeNull": - case "TypeBool": - case "TypeAddress": - case "TypeString": - case "TypeStateInit": - case "TypeStringBuilder": { + case "basic": { return type; } case "tuple_type": { const result = yield* recN(type.typeArgs); - return Ast.DTypeTuple(result, type.loc); + return Ast.CTypeTuple(result, type.loc); } case "tensor_type": { const result = yield* recN(type.typeArgs); - return Ast.DTypeTensor(result, type.loc); + return Ast.CTypeTensor(result, type.loc); } case "map_type": { // NB! modify along with decodeTypeMap above const key = yield* rec(type.key); const value = yield* rec(type.value); - return Ast.DTypeMap(key, value, type.loc); + return Ast.CTypeMap(key, value, type.loc); } case "TypeBounced": { const child = yield* rec(type.type); if (child.kind !== "type_ref" || child.typeArgs.length > 0) { yield EBouncedMessage(type.loc); - return Ast.DTypeRecover(); + return Ast.CTypeRecover(); } const typeEntry = typeDecls.get(child.name.text); if (!typeEntry) { yield EBouncedMessage(type.loc); - return Ast.DTypeRecover(); + return Ast.CTypeRecover(); } else if (typeEntry.decl.kind === "message") { - return Ast.DTypeBounced(child.name, type.loc); + return Ast.CTypeBounced(child.name, type.loc); } else { yield EBouncedMessage(type.loc); - return Ast.DTypeRecover(); + return Ast.CTypeRecover(); } } case "TypeMaybe": { const child = yield* rec(type.type); - return Ast.DTypeMaybe(child, type.loc); + return Ast.CTypeMaybe(child, type.loc); } case "cons_type": { // this is where the meat of the procedure is @@ -150,9 +139,9 @@ export function decodeType( // if we used type parameter generically, throw error // because we do not support HKT if (!(yield* matchArity(name, arity, 0, type.loc))) { - return Ast.DTypeRecover(); + return Ast.CTypeRecover(); } - return Ast.DTypeParamRef(type.name, type.loc); + return Ast.CTypeParamRef(type.name, type.loc); } const typeEntry = typeDecls.get(name); @@ -160,7 +149,7 @@ export function decodeType( // there is no such type at all! if (!typeEntry) { yield ETypeNotFound(name, type.loc); - return Ast.DTypeRecover(); + return Ast.CTypeRecover(); } // check number of type arguments does match @@ -172,13 +161,13 @@ export function decodeType( type.loc, )) ) { - return Ast.DTypeRecover(); + return Ast.CTypeRecover(); } switch (typeEntry.decl.kind) { case "trait": { yield ETraitNotType(type.loc); - return Ast.DTypeRecover(); + return Ast.CTypeRecover(); } case "contract": { // this is a ground type reference @@ -202,8 +191,8 @@ export function decodeType( } case "alias": { // this is an alias reference - return Ast.DTypeAliasRef( - Ast.NotDealiased(), + return Ast.CTypeAliasRef( + Ast.CNotDealiased(), type.name, args, type.loc, @@ -217,7 +206,7 @@ export function decodeType( return rec(type); } -const getArity = (decl: Ast.TypeDeclSig): number => { +const getArity = (decl: Ast.CTypeDecl): number => { switch (decl.kind) { case "alias": case "struct": @@ -273,10 +262,10 @@ const ETraitNotType = (loc: Ast.Loc): Ast.TcError => ({ }); const dealiasTypeAux = ( - type: Ast.DecodedType, - typeDecls: ReadonlyMap>, + type: Ast.CType, + typeDecls: ReadonlyMap>, ) => { - function* rec(type: Ast.DecodedType): Ast.WithLog { + function* rec(type: Ast.CType): Ast.WithLog { switch (type.kind) { case "recover": { return type; @@ -301,7 +290,7 @@ const dealiasTypeAux = ( yield* Ast.mapLog(type.typeArgs, rec), ), ); - return Ast.DTypeAliasRef( + return Ast.CTypeAliasRef( decoded, type.name, type.typeArgs, @@ -314,32 +303,21 @@ const dealiasTypeAux = ( case "map_type": { const key = yield* rec(type.key); const value = yield* rec(type.value); - return Ast.DTypeMap(key, value, type.loc); + return Ast.CTypeMap(key, value, type.loc); } case "TypeMaybe": { const args = yield* rec(type.type); - return Ast.DTypeMaybe(args, type.loc); + return Ast.CTypeMaybe(args, type.loc); } case "tuple_type": { const args = yield* Ast.mapLog(type.typeArgs, rec); - return Ast.DTypeTuple(args, type.loc); + return Ast.CTypeTuple(args, type.loc); } case "tensor_type": { const args = yield* Ast.mapLog(type.typeArgs, rec); - return Ast.DTypeTensor(args, type.loc); + return Ast.CTypeTensor(args, type.loc); } - case "TyInt": - case "TySlice": - case "TyCell": - case "TyBuilder": - case "unit_type": - case "TypeVoid": - case "TypeNull": - case "TypeBool": - case "TypeAddress": - case "TypeString": - case "TypeStringBuilder": - case "TypeStateInit": + case "basic": case "TypeBounced": { return type; } @@ -351,10 +329,10 @@ const dealiasTypeAux = ( // NB! if substitute is used for something other than aliases, do not throwInternal on type.type export const substituteTypeArgs = ( - type: Ast.DecodedType, - params: Ast.TypeParams, - args: readonly Ast.DecodedType[], -): Ast.DecodedType => { + type: Ast.CType, + params: Ast.CTypeParams, + args: readonly Ast.CType[], +): Ast.CType => { if (params.order.length !== args.length) { return throwInternal("Decoder didn't check alias arity"); } @@ -366,12 +344,12 @@ export const substituteTypeArgs = ( ); const recN = ( - types: readonly Ast.DecodedType[], - ): readonly Ast.DecodedType[] => { + types: readonly Ast.CType[], + ): readonly Ast.CType[] => { return types.map((type) => rec(type)); }; - const rec = (type: Ast.DecodedType): Ast.DecodedType => { + const rec = (type: Ast.CType): Ast.CType => { switch (type.kind) { case "TypeParam": { const arg = substMap.get(type.name.text); @@ -389,7 +367,7 @@ export const substituteTypeArgs = ( case "TypeAlias": { if (type.type.kind === "NotDealiased") { const args = recN(type.typeArgs); - return Ast.DTypeAliasRef( + return Ast.CTypeAliasRef( type.type, type.name, args, @@ -397,7 +375,7 @@ export const substituteTypeArgs = ( ); } else { const args = recN(type.typeArgs); // ?? - return Ast.DTypeAliasRef( + return Ast.CTypeAliasRef( rec(type.type), type.name, args, @@ -408,33 +386,22 @@ export const substituteTypeArgs = ( case "map_type": { const key = rec(type.key); const value = rec(type.value); - return Ast.DTypeMap(key, value, type.loc); + return Ast.CTypeMap(key, value, type.loc); } case "TypeMaybe": { const args = rec(type.type); - return Ast.DTypeMaybe(args, type.loc); + return Ast.CTypeMaybe(args, type.loc); } case "tuple_type": { const args = recN(type.typeArgs); - return Ast.DTypeTuple(args, type.loc); + return Ast.CTypeTuple(args, type.loc); } case "tensor_type": { const args = recN(type.typeArgs); - return Ast.DTypeTensor(args, type.loc); + return Ast.CTypeTensor(args, type.loc); } case "recover": - case "TyInt": - case "TySlice": - case "TyCell": - case "TyBuilder": - case "unit_type": - case "TypeVoid": - case "TypeNull": - case "TypeBool": - case "TypeAddress": - case "TypeString": - case "TypeStringBuilder": - case "TypeStateInit": + case "basic": case "TypeBounced": { return type; } @@ -446,12 +413,12 @@ export const substituteTypeArgs = ( export function* instantiateStruct( typeName: Ast.TypeId, - typeArgs: readonly Ast.DecodedType[], + typeArgs: readonly Ast.CType[], // NB! these are type params from enclosing scope - typeParams: Ast.TypeParams, - scopeRef: () => Ast.Scope, + typeParams: Ast.CTypeParams, + scopeRef: () => Ast.CSource, ): Ast.WithLog< - undefined | { type: Ast.DTypeRef; fields: Ast.Ordered } + undefined | { type: Ast.DTypeRef; fields: Ast.Ordered } > { const decl = scopeRef().typeDecls.get(typeName.text); switch (decl?.decl.kind) { @@ -502,8 +469,8 @@ export function* instantiateStruct( return undefined; } const type = yield* dealiasType( - Ast.DTypeAliasRef( - Ast.NotDealiased(), + Ast.CTypeAliasRef( + Ast.CNotDealiased(), typeName, typeArgs, typeName.loc, @@ -545,16 +512,16 @@ const ETypeArity = ( ], }); -export function typeParamsToSubst(typeParams: Ast.TypeParams) { - const subst: Map = new Map( - typeParams.order.map((name) => [name.text, Ast.DNotSet()]), +export function typeParamsToSubst(typeParams: Ast.CTypeParams) { + const subst: Map = new Map( + typeParams.order.map((name) => [name.text, Ast.CNotSet()]), ); return subst; } export function* substToTypeArgMap( loc: Ast.Loc, - subst: Map, + subst: Map, ): Ast.WithLog { const res = substToTypeArgMapAux(subst); if (res.ok) { @@ -568,9 +535,9 @@ export function* substToTypeArgMap( } function substToTypeArgMapAux( - subst: Map, + subst: Map, ): { ok: true; args: Ast.TypeArgs } | { ok: false; names: readonly string[] } { - const args: Map = new Map(); + const args: Map = new Map(); const names: string[] = []; for (const [name, type] of subst) { if (type.kind === "not-set") { @@ -588,9 +555,9 @@ function substToTypeArgMapAux( export function* assignType( loc: Ast.Loc, - toFreeTypeParam: Ast.TypeParams, - to: Ast.DecodedType, - from: Ast.DecodedType, + toFreeTypeParam: Ast.CTypeParams, + to: Ast.CType, + from: Ast.CType, strict: boolean, ): Ast.WithLog { const subst = typeParamsToSubst(toFreeTypeParam); @@ -625,14 +592,14 @@ const AssignFailure = (tree: Ast.MatchTree): AssignFailure => type Log = Generator; export function assignTypeAux( - to: Ast.DecodedType, - from: Ast.DecodedType, - subst: Map, + to: Ast.CType, + from: Ast.CType, + subst: Map, strict: boolean, ) { function* recN( - tos: readonly Ast.DecodedType[], - froms: readonly Ast.DecodedType[], + tos: readonly Ast.CType[], + froms: readonly Ast.CType[], ): Log { if (tos.length !== froms.length) { return throwInternal( @@ -649,7 +616,7 @@ export function assignTypeAux( return result; } - function* rec(to: Ast.DecodedType, from: Ast.DecodedType): Log { + function* rec(to: Ast.CType, from: Ast.CType): Log { const result = collectMismatches(to, from); if (result.kind === "failure") { yield result.tree; @@ -659,8 +626,8 @@ export function assignTypeAux( } function collectMismatches( - to: Ast.DecodedType, - from: Ast.DecodedType, + to: Ast.CType, + from: Ast.CType, ): AssignResult { const gen = check(to, from); const results: Ast.MatchTree[] = []; @@ -685,7 +652,7 @@ export function assignTypeAux( } } - function* check(to: Ast.DecodedType, from: Ast.DecodedType): Log { + function* check(to: Ast.CType, from: Ast.CType): Log { if (from.kind === "TypeAlias") { if (from.type.kind === "NotDealiased") { return throwInternal("Decoder returned aliased type"); @@ -734,30 +701,19 @@ export function assignTypeAux( } case "TypeMaybe": { return ( - (!strict && from.kind === "TypeNull") || + (!strict && from.kind === "basic" && from.type.kind === "TypeNull") || (to.kind === from.kind && (yield* rec(to.type, from.type))) ); } case "map_type": { return ( - (!strict && from.kind === "TypeNull") || + (!strict && from.kind === "basic" && from.type.kind === "TypeNull") || (to.kind === from.kind && (yield* rec(to.key, from.key)) && (yield* rec(to.value, from.value))) ); } - case "TyInt": - case "TySlice": - case "TyCell": - case "TyBuilder": - case "unit_type": - case "TypeVoid": - case "TypeNull": - case "TypeBool": - case "TypeAddress": - case "TypeStateInit": - case "TypeString": - case "TypeStringBuilder": { + case "basic": { return from.kind === to.kind; } } @@ -767,14 +723,14 @@ export function assignTypeAux( } export function* mgu( - left: Ast.DecodedType, - right: Ast.DecodedType, + left: Ast.CType, + right: Ast.CType, loc: Ast.Loc, -): Ast.WithLog { +): Ast.WithLog { function* rec( - left: Ast.DecodedType, - right: Ast.DecodedType, - ): Ast.WithLog { + left: Ast.CType, + right: Ast.CType, + ): Ast.WithLog { if (right.kind === "TypeAlias") { if (right.type.kind === "NotDealiased") { return throwInternal("Decoder returned aliased type"); @@ -797,14 +753,14 @@ export function* mgu( if (resultR.kind === "success") { return right; } - if (right.kind === "TypeNull") { - return Ast.DTypeMaybe(left, loc); + if (right.kind === "basic" && right.type.kind === "TypeNull") { + return Ast.CTypeMaybe(left, loc); } - if (left.kind === "TypeNull") { - return Ast.DTypeMaybe(right, loc); + if (left.kind === "basic" && left.type.kind === "TypeNull") { + return Ast.CTypeMaybe(right, loc); } yield ENotUnifiable(resultL.tree, loc); - return Ast.DTypeRecover(); + return Ast.CTypeRecover(); } return yield* rec(left, right); @@ -818,14 +774,14 @@ const ENotUnifiable = (tree: Ast.MatchTree, loc: Ast.Loc): Ast.TcError => ({ }); export type CallResult = { - readonly returnType: Ast.DecodedType; + readonly returnType: Ast.CType; readonly typeArgMap: Ast.TypeArgs; }; export function* checkFnCall( loc: Ast.Loc, - fnType: Ast.DecodedFnType | Ast.DecodedMethodType, - args: readonly (readonly [Ast.Loc, Ast.DecodedType])[], + fnType: Ast.CTypeFunction | Ast.CTypeMethod, + args: readonly (readonly [Ast.Loc, Ast.CType])[], ): Ast.WithLog { const { typeParams, params, returnType } = fnType; @@ -853,12 +809,12 @@ export function* checkFnCall( if (!typeArgsMap) { return { - returnType: Ast.DTypeRecover(), + returnType: Ast.CTypeRecover(), typeArgMap: new Map(), }; } - const typeArgs: Ast.DecodedType[] = []; + const typeArgs: Ast.CType[] = []; for (const param of typeParams.order) { const arg = typeArgsMap.get(param.text); if (!arg) { @@ -908,19 +864,19 @@ const EFnArity = ( export function* checkFnCallWithArgs( Lazy: Ast.ThunkBuilder, loc: Ast.Loc, - fnType: Ast.DecodedFnType | undefined, - ascribedTypeArgs: readonly Ast.DecodedType[], - args: readonly (readonly [Ast.Loc, Ast.DecodedType])[], + fnType: Ast.CTypeFunction | undefined, + ascribedTypeArgs: readonly Ast.CType[], + args: readonly (readonly [Ast.Loc, Ast.CType])[], ): Ast.WithLog { if (!fnType) { yield ENoFunction(loc); - return { returnType: Ast.DTypeRecover(), typeArgMap: new Map() }; + return { returnType: Ast.CTypeRecover(), typeArgMap: new Map() }; } if (ascribedTypeArgs.length === 0) { return yield* checkFnCall(loc, fnType, args); } if (fnType.typeParams.order.length !== ascribedTypeArgs.length) { - return { returnType: Ast.DTypeRecover(), typeArgMap: new Map() }; + return { returnType: Ast.CTypeRecover(), typeArgMap: new Map() }; } const result = yield* checkFnCall( loc, @@ -949,13 +905,13 @@ function substFnType( typeParams, params, returnType, - }: Ast.DecodedFnType | Ast.DecodedMethodType, - args: readonly Ast.DecodedType[], + }: Ast.CTypeFunction | Ast.CTypeMethod, + args: readonly Ast.CType[], ) { - const order: Ast.Parameter[] = []; + const order: Ast.CParameter[] = []; for (const [index, param] of params.order.entries()) { order.push( - Ast.Parameter( + Ast.CParameter( param.name, Lazy({ callback: function* () { @@ -971,15 +927,15 @@ function substFnType( ), ], loc: param.loc, - recover: Ast.DTypeRecover(), + recover: Ast.CTypeRecover(), }), param.loc, ), ); } - return Ast.DecodedFnType( + return Ast.CTypeFunction( emptyTypeParams, - Ast.Parameters(order, params.set), + Ast.CParameters(order, params.set), Lazy({ callback: function* () { return substituteTypeArgs( @@ -990,21 +946,25 @@ function substFnType( }, context: [Ast.TEText(`substituting into return type`)], loc: fnLoc, - recover: Ast.DTypeRecover(), + recover: Ast.CTypeRecover(), }), ); } +export type MethodCallResult = CallResult & { + readonly mutates: boolean; +}; + export function* lookupMethod( Lazy: Ast.ThunkBuilder, - selfType: Ast.DecodedType, + selfType: Ast.CType, method: Ast.Id, - args: readonly (readonly [Ast.Loc, Ast.DecodedType])[], - typeDecls: ReadonlyMap>, - extensions: ReadonlyMap[]>>, -): Ast.WithLog { + args: readonly (readonly [Ast.Loc, Ast.CType])[], + typeDecls: ReadonlyMap>, + extensions: ReadonlyMap[]>>, +): Ast.WithLog { if (selfType.kind === "recover") { - return { returnType: Ast.DTypeRecover(), typeArgMap: new Map() }; + return { returnType: Ast.CTypeRecover(), typeArgMap: new Map(), mutates: false }; } if (selfType.kind === "TypeAlias") { if (selfType.type.kind === "NotDealiased") { @@ -1028,7 +988,7 @@ export function* lookupMethod( const selfDecl = typeDecls.get(selfType.name.text); if (!selfDecl) { yield ENoMethod(method.loc); - return { returnType: Ast.DTypeRecover(), typeArgMap: new Map() }; + return { returnType: Ast.CTypeRecover(), typeArgMap: new Map(), mutates: false }; } if (selfDecl.decl.kind === "struct" || selfDecl.decl.kind === "message") { @@ -1036,7 +996,10 @@ export function* lookupMethod( selfDecl.decl.kind === "struct" ? structBuiltin : messageBuiltin; const builtin = builtinMap.get(method.text); if (builtin) { - return yield* checkFnCall(method.loc, builtin, args); + return { + ...yield* checkFnCall(method.loc, builtin, args), + mutates: false, + }; } return yield* lookupExts(Lazy, selfType, method, args, extensions); } @@ -1046,30 +1009,33 @@ export function* lookupMethod( const met = content.methods.get(method.text); if (!met) { yield ENoMethod(method.loc); - return { returnType: Ast.DTypeRecover(), typeArgMap: new Map() }; + return { returnType: Ast.CTypeRecover(), typeArgMap: new Map(), mutates: false }; } - return yield* checkFnCall(method.loc, met.decl.type, args); + return { + ...yield* checkFnCall(method.loc, met.decl.type, args), + mutates: met.decl.type.mutates, + }; } yield ENoMethod(method.loc); - return { returnType: Ast.DTypeRecover(), typeArgMap: new Map() }; + return { returnType: Ast.CTypeRecover(), typeArgMap: new Map(), mutates: false }; } function* lookupExts( Lazy: Ast.ThunkBuilder, - selfType: Ast.DecodedType, + selfType: Ast.CType, method: Ast.Id, - args: readonly (readonly [Ast.Loc, Ast.DecodedType])[], - extensions: ReadonlyMap[]>>, -) { + args: readonly (readonly [Ast.Loc, Ast.CType])[], + extensions: ReadonlyMap[]>>, +): Ast.WithLog { const lazyExts = extensions.get(method.text); if (!lazyExts) { yield ENoMethod(method.loc); - return { returnType: Ast.DTypeRecover(), typeArgMap: new Map() }; + return { returnType: Ast.CTypeRecover(), typeArgMap: new Map(), mutates: false }; } const exts = yield* lazyExts(); - const grounds: [Ast.DecodedMethodType, Ast.TypeArgs][] = []; - const withVars: [Ast.DecodedMethodType, Ast.TypeArgs][] = []; + const grounds: [Ast.CTypeMethod, Ast.TypeArgs][] = []; + const withVars: [Ast.CTypeMethod, Ast.TypeArgs][] = []; for (const { decl } of exts) { const subst = typeParamsToSubst(decl.type.typeParams); const result = assignTypeAux(decl.type.self, selfType, subst, true); @@ -1091,7 +1057,7 @@ function* lookupExts( const either = ground || withVar; if (!either) { yield ENoMethod(method.loc); - return { returnType: Ast.DTypeRecover(), typeArgMap: new Map() }; + return { returnType: Ast.CTypeRecover(), typeArgMap: new Map(), mutates: false }; } const [methodType, typeArgs] = either; const result = yield* checkFnCall( @@ -1107,11 +1073,12 @@ function* lookupExts( return { returnType: result.returnType, typeArgMap: typeArgs, + mutates: methodType.mutates, }; } -function typeArgsToParams(args: Ast.TypeArgs, params: Ast.TypeParams) { - const result: Ast.DecodedType[] = []; +function typeArgsToParams(args: Ast.TypeArgs, params: Ast.CTypeParams) { + const result: Ast.CType[] = []; for (const name of params.order) { const arg = args.get(name.text); if (!arg) { @@ -1128,8 +1095,8 @@ const ENoMethod = (loc: Ast.Loc): Ast.TcError => ({ }); export function* assignMethodType( - prev: Ast.DecodedMethodType, - next: Ast.DecodedMethodType, + prev: Ast.CTypeMethod, + next: Ast.CTypeMethod, prevVia: Ast.ViaMember, nextVia: Ast.ViaMember, ): Ast.WithLog { diff --git a/src/next/types/typecheck.ts b/src/next/types/typecheck.ts index fb2932b8f2..98b97c5e63 100644 --- a/src/next/types/typecheck.ts +++ b/src/next/types/typecheck.ts @@ -14,10 +14,10 @@ import { decodeFunctions } from "@/next/types/functions"; import { decodeConstants } from "@/next/types/constants"; import { decodeExtensions } from "@/next/types/extensions"; -export const typecheck = (root: TactSource): [Ast.Scope, Ast.TcError[]] => { +export const typecheck = (root: TactSource): [Ast.CSource, Ast.TcError[]] => { const allErrors: Ast.TcError[] = []; - const recur = memo((source: TactSource): Ast.Scope => { + const recur = memo((source: TactSource): Ast.CSource => { const [value, errors] = Ast.runLog( tcSource( // leave only imports of .tact @@ -57,10 +57,10 @@ function* tcSource( imported: readonly Ast.SourceCheckResult[], // source for current file source: TactSource, -): Ast.WithLog { +): Ast.WithLog { const Lazy = Ast.thunkBuilder; const scopeRef = () => scope; - const scope: Ast.Scope = { + const scope: Ast.CSource = { typeDecls: yield* decodeTypeDecls(Lazy, imported, source, scopeRef), functions: yield* decodeFunctions(Lazy, imported, source, scopeRef), constants: yield* decodeConstants(Lazy, imported, source, scopeRef), @@ -68,3 +68,7 @@ function* tcSource( }; return scope; } + +function lowerSource(node: Ast.CSource) { + +} \ No newline at end of file diff --git a/src/next/types/typedecl.ts b/src/next/types/typedecl.ts index d04ae2881c..55d0d69af2 100644 --- a/src/next/types/typedecl.ts +++ b/src/next/types/typedecl.ts @@ -16,8 +16,8 @@ export function* decodeTypeDecls( Lazy: Ast.ThunkBuilder, imported: readonly Ast.SourceCheckResult[], source: TactSource, - scopeRef: () => Ast.Scope, -): Ast.WithLog>> { + scopeRef: () => Ast.CSource, +): Ast.WithLog>> { const importedSigs = imported.map( ({ globals, importedBy }) => new Map( @@ -40,7 +40,7 @@ export function* decodeTypeDecls( ]); }); - const prev: Map> = new Map(); + const prev: Map> = new Map(); for (const next of [...importedSigs, ...localSigs]) { for (const [name, nextItem] of next) { const prevItem = prev.get(name); @@ -76,8 +76,8 @@ export function* decodeTypeDecls( function* decodeTypeDecl( Lazy: Ast.ThunkBuilder, decl: Ast.TypeDecl, - scopeRef: () => Ast.Scope, -): Ast.WithLog { + scopeRef: () => Ast.CSource, +): Ast.WithLog { switch (decl.kind) { case "alias_decl": { return yield* decodeAlias(Lazy, decl, scopeRef); diff --git a/src/next/types/union.ts b/src/next/types/union.ts index 5d4c7621b5..15b98a2841 100644 --- a/src/next/types/union.ts +++ b/src/next/types/union.ts @@ -6,15 +6,15 @@ import { decodeTypeLazy } from "@/next/types/type"; import { decodeTypeParams } from "@/next/types/type-params"; type Cons = { - readonly fields: ReadonlyMap; + readonly fields: ReadonlyMap; readonly loc: Ast.Loc; }; export function* decodeUnion( Lazy: Ast.ThunkBuilder, union: Ast.UnionDecl, - scopeRef: () => Ast.Scope, -): Ast.WithLog { + scopeRef: () => Ast.CSource, +): Ast.WithLog { const typeParams = yield* decodeTypeParams(union.typeParams); const cases: Map = new Map(); @@ -25,7 +25,7 @@ export function* decodeUnion( yield EDuplicateCons(caseName, prevCons.loc, cons.name.loc); continue; } - const fields: Map = new Map(); + const fields: Map = new Map(); for (const field of cons.fields) { const fieldName = field.name.text; const prevField = fields.get(fieldName); @@ -50,7 +50,7 @@ export function* decodeUnion( scopeRef, ); - const decoded = Ast.InhFieldSig(ascribedType, lazyExpr); + const decoded = Ast.CField(ascribedType, lazyExpr); fields.set(fieldName, [decoded, field.name.loc]); } cases.set(caseName, { @@ -60,7 +60,7 @@ export function* decodeUnion( } const map = new Map([...cases].map(([name, { fields }]) => [name, fields])); - return Ast.UnionSig(typeParams, map); + return Ast.CUnion(typeParams, map); } const EDuplicateCons = ( diff --git a/src/next/types/value.ts b/src/next/types/value.ts index 37a7d41c1b..cd1e1fdac6 100644 --- a/src/next/types/value.ts +++ b/src/next/types/value.ts @@ -9,7 +9,7 @@ export function convertValueToExpr(node: Ast.Value): Ast.DecodedExpression { return Ast.DNumber( "10", node.value, - Ast.TypeInt(Ast.IFInt("signed", 257, node.loc), node.loc), + Ast.TBasic(Ast.TInt(Ast.IFInt("signed", 257, node.loc), node.loc), node.loc), node.loc, ); } From 8f713b1f365c20df9f412ba471d6f02f5aa3a16e Mon Sep 17 00:00:00 2001 From: verytactical <186486509+verytactical@users.noreply.github.com> Date: Fri, 13 Jun 2025 12:22:36 +0400 Subject: [PATCH 37/38] 1 --- src/next/ast/checked-expr.ts | 140 +-- src/next/ast/checked-stmt.ts | 117 ++- src/next/ast/checked-type.ts | 2 +- src/next/ast/checked.ts | 31 +- src/next/ast/common.ts | 5 + src/next/ast/errors.ts | 16 +- src/next/ast/generated/checked-expr.ts | 214 ++--- src/next/ast/generated/checked-stmt.ts | 170 ++-- src/next/ast/generated/checked-type.ts | 58 +- src/next/ast/generated/checked.ts | 51 +- src/next/ast/generated/common.ts | 9 + src/next/ast/generated/lowered-expr.ts | 222 +++++ src/next/ast/generated/lowered-stmt.ts | 124 +++ src/next/ast/generated/lowered-type.ts | 74 ++ src/next/ast/generated/lowered.ts | 161 ++-- src/next/ast/index.ts | 5 + src/next/ast/lazy.ts | 8 +- src/next/ast/lowered-expr.ts | 21 +- src/next/ast/lowered-stmt.ts | 11 +- src/next/ast/lowered-type.ts | 36 +- src/next/ast/lowered.ts | 155 ++-- src/next/types/alias.ts | 2 +- src/next/types/body.ts | 10 +- src/next/types/builtins.ts | 30 +- src/next/types/constant-def.ts | 4 +- src/next/types/constants.ts | 6 +- src/next/types/contract.ts | 8 +- src/next/types/effects.ts | 2 +- src/next/types/expr-eval.ts | 4 +- src/next/types/expression.ts | 130 +-- src/next/types/extensions.ts | 12 +- src/next/types/fields.ts | 6 +- src/next/types/functions.ts | 2 +- src/next/types/lower.ts | 1133 ++++++++++++++++++++++++ src/next/types/lvalue.ts | 10 +- src/next/types/message.ts | 2 +- src/next/types/methods.ts | 8 +- src/next/types/override.ts | 6 +- src/next/types/receivers.ts | 6 +- src/next/types/statements.ts | 92 +- src/next/types/struct.ts | 2 +- src/next/types/trait.ts | 4 +- src/next/types/traits-scope.ts | 2 +- src/next/types/type-fn.ts | 8 +- src/next/types/type-params.ts | 2 +- src/next/types/type.ts | 144 +-- src/next/types/typecheck.ts | 6 +- src/next/types/typedecl.ts | 4 +- src/next/types/union.ts | 2 +- src/next/types/value.ts | 2 +- 50 files changed, 2359 insertions(+), 920 deletions(-) create mode 100644 src/next/ast/generated/lowered-expr.ts create mode 100644 src/next/ast/generated/lowered-stmt.ts create mode 100644 src/next/ast/generated/lowered-type.ts create mode 100644 src/next/types/lower.ts diff --git a/src/next/ast/checked-expr.ts b/src/next/ast/checked-expr.ts index 763d4cf6bb..5ded45bd87 100644 --- a/src/next/ast/checked-expr.ts +++ b/src/next/ast/checked-expr.ts @@ -1,5 +1,5 @@ -import type { Ordered, Recover } from "@/next/ast/checked"; -import type { Id, Loc, TypeId } from "@/next/ast/common"; +import type { Recover } from "@/next/ast/checked"; +import type { Id, Loc, Ordered, TypeId } from "@/next/ast/common"; import type * as D from "@/next/ast/checked-type"; import type { BinaryOperation, @@ -10,66 +10,66 @@ import type { SelfType } from "@/next/ast/type-self"; export type TypeArgs = ReadonlyMap; -export type DecodedExpression = - | DOpBinary - | DOpUnary - | DConditional - | DMethodCall - | DStaticCall - | DStaticMethodCall - | DFieldAccess - | DStructInstance - | DInitOf - | DCodeOf - | DNumber - | DBoolean - | DNull - | DString - | DVar - | DSelf - | DUnit - | DTuple - | DTensor - | DMapLiteral - | DSetLiteral; - -export type LValue = LVar | LSelf | LFieldAccess; - -export type LSelf = { +export type CExpr = + | COpBinary + | COpUnary + | CConditional + | CMethodCall + | CStaticCall + | CStaticMethodCall + | CFieldAccess + | CStructCons + | CInitOf + | CCodeOf + | CNumber + | CBoolean + | CNull + | CString + | CVar + | CSelf + | CUnit + | CTuple + | CTensor + | CMapLiteral + | CSetLiteral; + +export type CLValue = CLVar | CLSelf | CLFieldAccess; + +export type CLSelf = { readonly kind: "self"; readonly computedType: SelfType; readonly loc: Loc; }; -export type LVar = { +export type CLVar = { readonly kind: "var"; readonly name: string; readonly computedType: D.CType; readonly loc: Loc; }; -export type LFieldAccess = { +export type CLFieldAccess = { readonly kind: "field_access"; - readonly aggregate: LValue; + readonly aggregate: CLValue; readonly field: Id; readonly computedType: D.CType; readonly loc: Loc; }; -export type DSelf = { +export type CSelf = { readonly kind: "self"; readonly computedType: SelfType; readonly loc: Loc; }; -export type DVar = { +export type CVar = { readonly kind: "var"; readonly name: string; readonly computedType: D.CType; readonly loc: Loc; }; -export type DNumber = { +export type CNumber = { readonly kind: "number"; readonly base: NumberBase; readonly value: bigint; @@ -77,92 +77,92 @@ export type DNumber = { readonly loc: Loc; }; -export type DBoolean = { +export type CBoolean = { readonly kind: "boolean"; readonly value: boolean; readonly computedType: D.CTBasic; readonly loc: Loc; }; -export type DString = { +export type CString = { readonly kind: "string"; readonly value: string; readonly computedType: D.CTBasic; readonly loc: Loc; }; -export type DNull = { +export type CNull = { readonly kind: "null"; readonly computedType: D.CTBasic; readonly loc: Loc; }; -export type DOpBinary = { +export type COpBinary = { readonly kind: "op_binary"; readonly op: BinaryOperation; - readonly left: DecodedExpression; - readonly right: DecodedExpression; + readonly left: CExpr; + readonly right: CExpr; readonly typeArgs: TypeArgs; readonly computedType: D.CType; readonly loc: Loc; }; -export type DOpUnary = { +export type COpUnary = { readonly kind: "op_unary"; readonly op: UnaryOperation; - readonly operand: DecodedExpression; + readonly operand: CExpr; readonly typeArgs: TypeArgs; readonly computedType: D.CType; readonly loc: Loc; }; -export type DFieldAccess = { +export type CFieldAccess = { readonly kind: "field_access"; - readonly aggregate: DecodedExpression; + readonly aggregate: CExpr; readonly field: Id; readonly computedType: D.CType; readonly loc: Loc; }; -export type DMethodCall = { +export type CMethodCall = { readonly kind: "method_call"; - readonly self: DecodedExpression; + readonly self: CExpr; readonly method: Id; // NB! these are substitutions to self type - readonly args: readonly DecodedExpression[]; + readonly args: readonly CExpr[]; readonly typeArgs: TypeArgs; readonly computedType: D.CType; readonly loc: Loc; }; // builtins or top-level (module) functions -export type DStaticCall = { +export type CStaticCall = { readonly kind: "static_call"; readonly function: Id; readonly typeArgs: TypeArgs; - readonly args: readonly DecodedExpression[]; + readonly args: readonly CExpr[]; readonly computedType: D.CType; readonly loc: Loc; }; -export type DStaticMethodCall = { +export type CStaticMethodCall = { readonly kind: "static_method_call"; readonly self: TypeId; readonly typeArgs: TypeArgs; readonly function: Id; - readonly args: readonly DecodedExpression[]; + readonly args: readonly CExpr[]; readonly computedType: D.CType; readonly loc: Loc; }; -export type DStructInstance = { +export type CStructCons = { readonly kind: "struct_instance"; - readonly fields: Ordered>; + readonly fields: Ordered>; readonly computedType: D.CTRef | D.CTRecover; readonly loc: Loc; }; -export type DMapLiteral = { +export type CMapLiteral = { readonly kind: "map_literal"; readonly fields: readonly DMapField[]; readonly computedType: D.CTMap; @@ -170,58 +170,58 @@ export type DMapLiteral = { }; export type DMapField = { - readonly key: DecodedExpression; - readonly value: DecodedExpression; + readonly key: CExpr; + readonly value: CExpr; }; -export type DSetLiteral = { +export type CSetLiteral = { readonly kind: "set_literal"; readonly valueType: D.CType; - readonly fields: readonly DecodedExpression[]; + readonly fields: readonly CExpr[]; readonly computedType: D.CType; readonly loc: Loc; }; -export type DInitOf = { +export type CInitOf = { readonly kind: "init_of"; readonly contract: TypeId; - readonly args: readonly DecodedExpression[]; + readonly args: readonly CExpr[]; readonly computedType: D.CType; readonly loc: Loc; }; -export type DCodeOf = { +export type CCodeOf = { readonly kind: "code_of"; readonly contract: TypeId; readonly computedType: D.CType; readonly loc: Loc; }; -export type DConditional = { +export type CConditional = { readonly kind: "conditional"; - readonly condition: DecodedExpression; - readonly thenBranch: DecodedExpression; - readonly elseBranch: DecodedExpression; + readonly condition: CExpr; + readonly thenBranch: CExpr; + readonly elseBranch: CExpr; readonly computedType: D.CType; readonly loc: Loc; }; -export type DUnit = { +export type CUnit = { readonly kind: "unit"; readonly computedType: D.CTBasic; readonly loc: Loc; }; -export type DTuple = { +export type CTuple = { readonly kind: "tuple"; - readonly children: readonly DecodedExpression[]; + readonly children: readonly CExpr[]; readonly computedType: D.CTTuple; readonly loc: Loc; }; -export type DTensor = { +export type CTensor = { readonly kind: "tensor"; - readonly children: readonly DecodedExpression[]; + readonly children: readonly CExpr[]; readonly computedType: D.CTTensor; readonly loc: Loc; }; diff --git a/src/next/ast/checked-stmt.ts b/src/next/ast/checked-stmt.ts index 15627d33ec..af91dde93b 100644 --- a/src/next/ast/checked-stmt.ts +++ b/src/next/ast/checked-stmt.ts @@ -1,126 +1,125 @@ -import type { Ordered } from "@/next/ast/checked"; -import type { DecodedExpression, LValue } from "@/next/ast/checked-expr"; +import type { CExpr, CLValue } from "@/next/ast/checked-expr"; import type { Id, Loc, OptionalId, TypeId } from "@/next/ast/common"; +import type { Ordered } from "@/next/ast/generated/common"; import type { AugmentedAssignOperation } from "@/next/ast/statement"; -export type DecodedStatement = - | DStatementLet - | DStatementReturn - | DStatementExpression - | DStatementAssign - | DStatementAugmentedAssign - | DStatementCondition - | DStatementWhile - | DStatementUntil - | DStatementRepeat - | DStatementTry - | DStatementForEach - | DStatementDestruct - | DStatementBlock; - -export type DStatementList = readonly DecodedStatement[]; - -export type DStatementLet = { +export type CStmt = + | CStmtLet + | CStmtReturn + | CStmtExpression + | CStmtAssign + | CStmtAugmentedAssign + | CStmtCondition + | CStmtWhile + | CStmtUntil + | CStmtRepeat + | CStmtTry + | CStmtForEach + | CStmtDestruct + | CStmtBlock; + +export type CStmtList = readonly CStmt[]; + +export type CStmtLet = { readonly kind: "statement_let"; readonly name: OptionalId; - readonly expression: DecodedExpression; + readonly expression: CExpr; readonly loc: Loc; }; -export type DStatementReturn = { +export type CStmtReturn = { readonly kind: "statement_return"; - readonly expression: DecodedExpression | undefined; + readonly expression: CExpr | undefined; readonly loc: Loc; }; -export type DStatementExpression = { +export type CStmtExpression = { readonly kind: "statement_expression"; - readonly expression: DecodedExpression; + readonly expression: CExpr; readonly loc: Loc; }; -export type DStatementAssign = { +export type CStmtAssign = { readonly kind: "statement_assign"; - readonly path: LValue; - readonly expression: DecodedExpression; + readonly path: CLValue; + readonly expression: CExpr; readonly loc: Loc; }; -export type DStatementAugmentedAssign = { +export type CStmtAugmentedAssign = { readonly kind: "statement_augmentedassign"; readonly op: AugmentedAssignOperation; - readonly path: LValue; - readonly expression: DecodedExpression; + readonly path: CLValue; + readonly expression: CExpr; readonly loc: Loc; }; -export type DStatementCondition = { +export type CStmtCondition = { readonly kind: "statement_condition"; - readonly condition: DecodedExpression; - readonly trueStatements: DStatementList; - readonly falseStatements: DStatementList | undefined; + readonly condition: CExpr; + readonly trueStatements: CStmtList; + readonly falseStatements: CStmtList | undefined; readonly loc: Loc; }; -export type DStatementWhile = { +export type CStmtWhile = { readonly kind: "statement_while"; - readonly condition: DecodedExpression; - readonly statements: DStatementList; + readonly condition: CExpr; + readonly statements: CStmtList; readonly loc: Loc; }; -export type DStatementUntil = { +export type CStmtUntil = { readonly kind: "statement_until"; - readonly condition: DecodedExpression; - readonly statements: DStatementList; + readonly condition: CExpr; + readonly statements: CStmtList; readonly loc: Loc; }; -export type DStatementRepeat = { +export type CStmtRepeat = { readonly kind: "statement_repeat"; - readonly iterations: DecodedExpression; - readonly statements: DStatementList; + readonly iterations: CExpr; + readonly statements: CStmtList; readonly loc: Loc; }; -export type DStatementTry = { +export type CStmtTry = { readonly kind: "statement_try"; - readonly statements: DStatementList; - readonly catchBlock: DCatchBlock | undefined; + readonly statements: CStmtList; + readonly catchBlock: CCatchBlock | undefined; readonly loc: Loc; }; -export type DCatchBlock = { +export type CCatchBlock = { readonly name: OptionalId; - readonly statements: DStatementList; + readonly statements: CStmtList; }; -export type DStatementForEach = { +export type CStmtForEach = { readonly kind: "statement_foreach"; readonly keyName: OptionalId; readonly valueName: OptionalId; - readonly map: DecodedExpression; - readonly statements: DStatementList; + readonly map: CExpr; + readonly statements: CStmtList; readonly loc: Loc; }; -export type DStatementDestruct = { +export type CStmtDestruct = { readonly kind: "statement_destruct"; readonly type: TypeId; - /** field name -> [field id, local id] */ - readonly identifiers: Ordered; + readonly identifiers: Ordered; readonly ignoreUnspecifiedFields: boolean; - readonly expression: DecodedExpression; + readonly expression: CExpr; readonly loc: Loc; }; -export type DestructPattern = { +export type CDestructPattern = { readonly field: Id; readonly variable: OptionalId; }; -export type DStatementBlock = { +export type CStmtBlock = { readonly kind: "statement_block"; - readonly statements: DStatementList; + readonly statements: CStmtList; readonly loc: Loc; }; diff --git a/src/next/ast/checked-type.ts b/src/next/ast/checked-type.ts index cbcc67a662..04bd99bde6 100644 --- a/src/next/ast/checked-type.ts +++ b/src/next/ast/checked-type.ts @@ -2,7 +2,7 @@ import type { CTypeDeclRefable } from "@/next/ast/checked"; import type { Loc, TypeId } from "@/next/ast/common"; import type { BasicType } from "@/next/ast/type-basic"; -export type DNotSet = { +export type CNotSet = { readonly kind: "not-set"; }; diff --git a/src/next/ast/checked.ts b/src/next/ast/checked.ts index 95453d8c94..b11782b231 100644 --- a/src/next/ast/checked.ts +++ b/src/next/ast/checked.ts @@ -1,5 +1,5 @@ -import type { DecodedStatement } from "@/next/ast/checked-stmt"; -import type { FuncId, Loc, OptionalId, TypeId } from "@/next/ast/common"; +import type { CStmt } from "@/next/ast/checked-stmt"; +import type { FuncId, Loc, OptionalId, Ordered, TypeId } from "@/next/ast/common"; import type { CType, CTRef, CTBounced } from "@/next/ast/checked-type"; import type { Effects } from "@/next/ast/effects"; import type { Thunk } from "@/next/ast/lazy"; @@ -37,14 +37,14 @@ export type Recover = T | undefined; export type CTypeDecl = | CAlias | CContract - | CTraitSig + | CTrait | CStruct | CMessage | CUnion; export type CTypeDeclRefable = | CContract - | CTraitSig + | CTrait | CStruct | CMessage | CUnion; @@ -55,7 +55,7 @@ export type CConstant = { }; export type CFunction = { - readonly type: CTypeFunction; + readonly type: CTFunction; readonly inline: boolean; readonly body: CBody; }; @@ -63,7 +63,7 @@ export type CFunction = { export type CStatements = Thunk>; export type CStatementsAux = { - readonly body: readonly DecodedStatement[]; + readonly body: readonly CStmt[]; readonly effects: Effects; }; @@ -84,7 +84,7 @@ export type CFiftBody = { }; export type CExtension = { - readonly type: CTypeMethod; + readonly type: CTMethod; readonly inline: boolean; readonly body: CBody; }; @@ -95,7 +95,7 @@ export type CAlias = { readonly type: Thunk; }; -export type CInitSig = CInitEmpty | CInitSimple | CInitFn; +export type CInit = CInitEmpty | CInitSimple | CInitFn; export type CInitEmpty = { readonly kind: "empty"; // initOf() would take 0 parameters @@ -124,11 +124,11 @@ export type CInitParam = { export type CContract = { readonly kind: "contract"; readonly attributes: readonly ContractAttribute[]; - readonly init: CInitSig; + readonly init: CInit; readonly content: Thunk; }; export type CContractMembers = CMembers>, CBody>; -export type CTraitSig = { +export type CTrait = { readonly kind: "trait"; readonly content: Thunk; }; @@ -162,7 +162,7 @@ export type CFieldConstant = { export type CMethod = { readonly overridable: boolean; - readonly type: CTypeMethod; + readonly type: CTMethod; readonly inline: boolean; readonly body: Body; readonly getMethodId: Thunk> | undefined; @@ -229,14 +229,14 @@ export type CUnion = { readonly cases: ReadonlyMap>; }; -export type CTypeFunction = { +export type CTFunction = { readonly kind: "DecodedFnType"; readonly typeParams: CTypeParams; readonly params: CParameters; readonly returnType: Thunk; }; -export type CTypeMethod = { +export type CTMethod = { readonly kind: "DecodedMethodType"; readonly mutates: boolean; readonly typeParams: CTypeParams; @@ -251,11 +251,6 @@ export type CParameter = { readonly loc: Loc; }; -export type Ordered = { - readonly order: readonly string[]; - readonly map: ReadonlyMap; -}; - export type CParameters = { readonly order: readonly CParameter[]; readonly set: ReadonlySet; diff --git a/src/next/ast/common.ts b/src/next/ast/common.ts index 80622a6e06..aa0504a93f 100644 --- a/src/next/ast/common.ts +++ b/src/next/ast/common.ts @@ -38,3 +38,8 @@ export type TypeId = { }; export type Language = "func" | "tact"; + +export type Ordered = { + readonly order: readonly string[]; + readonly map: ReadonlyMap; +}; \ No newline at end of file diff --git a/src/next/ast/errors.ts b/src/next/ast/errors.ts index 4d10459f16..9a172669a3 100644 --- a/src/next/ast/errors.ts +++ b/src/next/ast/errors.ts @@ -3,7 +3,7 @@ import type { CType } from "@/next/ast/checked-type"; import type { Loc } from "@/next/ast/common"; import type * as V from "@/next/ast/via"; -export type WithLog = Generator; +export type Log = Generator; export function runLog( gen: Generator, @@ -21,8 +21,8 @@ export function runLog( export function* mapLog( xs: readonly T[], - f: (x: T) => WithLog, -): WithLog { + f: (x: T) => Log, +): Log { const result: U[] = []; for (const x of xs) { result.push(yield* f(x)); @@ -33,8 +33,8 @@ export function* mapLog( export function* reduceLog( xs: readonly T[], init: U, - f: (acc: U, x: T) => WithLog, -): WithLog { + f: (acc: U, x: T) => Log, +): Log { let acc = init; for (const x of xs) { acc = yield* f(acc, x); @@ -44,8 +44,8 @@ export function* reduceLog( export function* filterLog( xs: readonly T[], - f: (x: T) => WithLog, -): WithLog { + f: (x: T) => Log, +): Log { const result: T[] = []; for (const x of xs) { const res = yield* f(x); @@ -59,7 +59,7 @@ export function* filterLog( export function* toMap( kind: string, xs: readonly (readonly [string, V])[], -): WithLog> { +): Log> { const result: Map = new Map(); for (const [key, next] of xs) { const prev = result.get(key); diff --git a/src/next/ast/generated/checked-expr.ts b/src/next/ast/generated/checked-expr.ts index a3bbfdf366..4094b34a42 100644 --- a/src/next/ast/generated/checked-expr.ts +++ b/src/next/ast/generated/checked-expr.ts @@ -1,31 +1,29 @@ /* eslint-disable @typescript-eslint/no-unnecessary-condition */ -import type { Ordered } from "@/next/ast/checked"; import type * as $ from "@/next/ast/checked-expr"; import type * as $c from "@/next/ast/common"; import type * as $d from "@/next/ast/checked-type"; import type * as $e from "@/next/ast/expression"; import type { SelfType } from "@/next/ast/type-self"; -export type DCodeOf = $.DCodeOf; -export const DCodeOf = ( +export type CCodeOf = $.CCodeOf; +export const CCodeOf = ( contract: $c.TypeId, computedType: $d.CType, loc: $c.Loc, -): $.DCodeOf => +): $.CCodeOf => Object.freeze({ kind: "code_of", contract, computedType, loc, }); -export const isDCodeOf = ($value: DCodeOf) => $value.kind === "code_of"; -export type DNumber = $.DNumber; +export type CNumber = $.CNumber; export const DNumber = ( base: $e.NumberBase, value: bigint, computedType: $d.CTBasic, loc: $c.Loc, -): $.DNumber => +): $.CNumber => Object.freeze({ kind: "number", base, @@ -33,77 +31,70 @@ export const DNumber = ( computedType, loc, }); -export const isDNumber = ($value: DNumber) => $value.kind === "number"; -export type DBoolean = $.DBoolean; -export const DBoolean = ( +export type CBoolean = $.CBoolean; +export const CBoolean = ( value: boolean, computedType: $d.CTBasic, loc: $c.Loc, -): $.DBoolean => +): $.CBoolean => Object.freeze({ kind: "boolean", value, computedType, loc, }); -export const isDBoolean = ($value: DBoolean) => $value.kind === "boolean"; -export type DNull = $.DNull; -export const DNull = (computedType: $d.CTBasic, loc: $c.Loc): $.DNull => +export type CNull = $.CNull; +export const CNull = (computedType: $d.CTBasic, loc: $c.Loc): $.CNull => Object.freeze({ kind: "null", computedType, loc, }); -export const isDNull = ($value: DNull) => $value.kind === "null"; -export type DString = $.DString; -export const DString = ( +export type CString = $.CString; +export const CString = ( value: string, computedType: $d.CTBasic, loc: $c.Loc, -): $.DString => +): $.CString => Object.freeze({ kind: "string", value, computedType, loc, }); -export const isDString = ($value: DString) => $value.kind === "string"; -export type DVar = $.DVar; -export const DVar = ( +export type CVar = $.CVar; +export const CVar = ( name: string, computedType: $d.CType, loc: $c.Loc, -): $.DVar => +): $.CVar => Object.freeze({ kind: "var", name, computedType, loc, }); -export const isDVar = ($value: DVar) => $value.kind === "var"; -export type DSelf = $.DSelf; -export const DSelf = (computedType: SelfType, loc: $c.Loc): $.DSelf => +export type CSelf = $.CSelf; +export const CSelf = (computedType: SelfType, loc: $c.Loc): $.CSelf => Object.freeze({ kind: "self", computedType, loc, }); -export const isDSelf = ($value: DSelf) => $value.kind === "self"; -export type DUnit = $.DUnit; -export const DUnit = (computedType: $d.CTBasic, loc: $c.Loc): $.DUnit => +export type CUnit = $.CUnit; +export const CUnit = (computedType: $d.CTBasic, loc: $c.Loc): $.CUnit => Object.freeze({ kind: "unit", computedType, loc, }); -export const isDUnit = ($value: DUnit) => $value.kind === "unit"; -export type DSetLiteral = $.DSetLiteral; -export const DSetLiteral = ( +export type CSetLiteral = $.CSetLiteral; +export const CSetLiteral = ( valueType: $d.CType, computedType: $d.CType, - fields: readonly $.DecodedExpression[], + fields: readonly $.CExpr[], loc: $c.Loc, -): $.DSetLiteral => +): $.CSetLiteral => Object.freeze({ kind: "set_literal", valueType, @@ -111,64 +102,58 @@ export const DSetLiteral = ( computedType, loc, }); -export const isDSetLiteral = ($value: DSetLiteral) => - $value.kind === "set_literal"; -export type DMapField = $.DMapField; -export const DMapField = ( - key: $.DecodedExpression, - value: $.DecodedExpression, +export type CMapField = $.DMapField; +export const CMapField = ( + key: $.CExpr, + value: $.CExpr, ): $.DMapField => Object.freeze({ key, value, }); -export type DMapLiteral = $.DMapLiteral; -export const DMapLiteral = ( +export type CMapLiteral = $.CMapLiteral; +export const CMapLiteral = ( computedType: $d.CTMap, fields: readonly $.DMapField[], loc: $c.Loc, -): $.DMapLiteral => +): $.CMapLiteral => Object.freeze({ kind: "map_literal", fields, computedType, loc, }); -export const isDMapLiteral = ($value: DMapLiteral) => - $value.kind === "map_literal"; -export type DTensor = $.DTensor; -export const DTensor = ( - children: readonly $.DecodedExpression[], +export type CTensor = $.CTensor; +export const CTensor = ( + children: readonly $.CExpr[], computedType: $d.CTTensor, loc: $c.Loc, -): $.DTensor => +): $.CTensor => Object.freeze({ kind: "tensor", children, computedType, loc, }); -export const isDTensor = ($value: DTensor) => $value.kind === "tensor"; -export type DTuple = $.DTuple; -export const DTuple = ( - children: readonly $.DecodedExpression[], +export type CTuple = $.CTuple; +export const CTuple = ( + children: readonly $.CExpr[], computedType: $d.CTTuple, loc: $c.Loc, -): $.DTuple => +): $.CTuple => Object.freeze({ kind: "tuple", children, computedType, loc, }); -export const isDTuple = ($value: DTuple) => $value.kind === "tuple"; -export type DInitOf = $.DInitOf; -export const DInitOf = ( +export type CInitOf = $.CInitOf; +export const CInitOf = ( contract: $c.TypeId, - args: readonly $.DecodedExpression[], + args: readonly $.CExpr[], computedType: $d.CType, loc: $c.Loc, -): $.DInitOf => +): $.CInitOf => Object.freeze({ kind: "init_of", contract, @@ -176,28 +161,25 @@ export const DInitOf = ( computedType, loc, }); -export const isDInitOf = ($value: DInitOf) => $value.kind === "init_of"; -export type DStructInstance = $.DStructInstance; -export const DStructInstance = ( - fields: Ordered, +export type CStructCons = $.CStructCons; +export const CStructCons = ( + fields: $c.Ordered, computedType: $d.CTRef | $d.CTRecover, loc: $c.Loc, -): $.DStructInstance => +): $.CStructCons => Object.freeze({ kind: "struct_instance", fields, computedType, loc, }); -export const isDStructInstance = ($value: DStructInstance) => - $value.kind === "struct_instance"; -export type DFieldAccess = $.DFieldAccess; -export const DFieldAccess = ( - aggregate: $.DecodedExpression, +export type CFieldAccess = $.CFieldAccess; +export const CFieldAccess = ( + aggregate: $.CExpr, field: $c.Id, computedType: $d.CType, loc: $c.Loc, -): $.DFieldAccess => +): $.CFieldAccess => Object.freeze({ kind: "field_access", aggregate, @@ -205,17 +187,15 @@ export const DFieldAccess = ( computedType, loc, }); -export const isDFieldAccess = ($value: DFieldAccess) => - $value.kind === "field_access"; -export type DStaticMethodCall = $.DStaticMethodCall; -export const DStaticMethodCall = ( +export type CStaticMethodCall = $.CStaticMethodCall; +export const CStaticMethodCall = ( self: $c.TypeId, typeArgs: $.TypeArgs, function_: $c.Id, - args: readonly $.DecodedExpression[], + args: readonly $.CExpr[], computedType: $d.CType, loc: $c.Loc, -): $.DStaticMethodCall => +): $.CStaticMethodCall => Object.freeze({ kind: "static_method_call", self, @@ -225,17 +205,15 @@ export const DStaticMethodCall = ( computedType, loc, }); -export const isDStaticMethodCall = ($value: DStaticMethodCall) => - $value.kind === "static_method_call"; export type TypeArgs = $.TypeArgs; -export type DStaticCall = $.DStaticCall; -export const DStaticCall = ( +export type CStaticCall = $.CStaticCall; +export const CStaticCall = ( function_: $c.Id, typeArgs: $.TypeArgs, - args: readonly $.DecodedExpression[], + args: readonly $.CExpr[], computedType: $d.CType, loc: $c.Loc, -): $.DStaticCall => +): $.CStaticCall => Object.freeze({ kind: "static_call", function: function_, @@ -244,17 +222,15 @@ export const DStaticCall = ( computedType, loc, }); -export const isDStaticCall = ($value: DStaticCall) => - $value.kind === "static_call"; -export type DMethodCall = $.DMethodCall; -export const DMethodCall = ( - self: $.DecodedExpression, +export type CMethodCall = $.CMethodCall; +export const CMethodCall = ( + self: $.CExpr, method: $c.Id, - args: readonly $.DecodedExpression[], + args: readonly $.CExpr[], typeArgs: $.TypeArgs, computedType: $d.CType, loc: $c.Loc, -): $.DMethodCall => +): $.CMethodCall => Object.freeze({ kind: "method_call", self, @@ -264,16 +240,14 @@ export const DMethodCall = ( computedType, loc, }); -export const isDMethodCall = ($value: DMethodCall) => - $value.kind === "method_call"; -export type DConditional = $.DConditional; -export const DConditional = ( - condition: $.DecodedExpression, - thenBranch: $.DecodedExpression, - elseBranch: $.DecodedExpression, +export type CConditional = $.CConditional; +export const CConditional = ( + condition: $.CExpr, + thenBranch: $.CExpr, + elseBranch: $.CExpr, computedType: $d.CType, loc: $c.Loc, -): $.DConditional => +): $.CConditional => Object.freeze({ kind: "conditional", condition, @@ -282,16 +256,14 @@ export const DConditional = ( computedType, loc, }); -export const isDConditional = ($value: DConditional) => - $value.kind === "conditional"; -export type DOpUnary = $.DOpUnary; -export const DOpUnary = ( +export type COpUnary = $.COpUnary; +export const COpUnary = ( op: $e.UnaryOperation, - operand: $.DecodedExpression, + operand: $.CExpr, typeArgs: ReadonlyMap, computedType: $d.CType, loc: $c.Loc, -): $.DOpUnary => +): $.COpUnary => Object.freeze({ kind: "op_unary", op, @@ -300,16 +272,15 @@ export const DOpUnary = ( computedType, loc, }); -export const isDOpUnary = ($value: DOpUnary) => $value.kind === "op_unary"; -export type DOpBinary = $.DOpBinary; -export const DOpBinary = ( +export type COpBinary = $.COpBinary; +export const COpBinary = ( op: $e.BinaryOperation, - left: $.DecodedExpression, - right: $.DecodedExpression, + left: $.CExpr, + right: $.CExpr, typeArgs: ReadonlyMap, computedType: $d.CType, loc: $c.Loc, -): $.DOpBinary => +): $.COpBinary => Object.freeze({ kind: "op_binary", op, @@ -319,36 +290,33 @@ export const DOpBinary = ( computedType, loc, }); -export const isDOpBinary = ($value: DOpBinary) => $value.kind === "op_binary"; -export type DecodedExpression = $.DecodedExpression; -export type LVar = $.LVar; -export const LVar = ( +export type CExpr = $.CExpr; +export type CLVar = $.CLVar; +export const CLVar = ( name: string, computedType: $d.CType, loc: $c.Loc, -): $.LVar => +): $.CLVar => Object.freeze({ kind: "var", name, computedType, loc, }); -export const isLVar = ($value: LVar) => $value.kind === "var"; -export type LSelf = $.LSelf; -export const LSelf = (computedType: SelfType, loc: $c.Loc): $.LSelf => +export type CLSelf = $.CLSelf; +export const CLSelf = (computedType: SelfType, loc: $c.Loc): $.CLSelf => Object.freeze({ kind: "self", computedType, loc, }); -export const isLSelf = ($value: LSelf) => $value.kind === "self"; -export type LFieldAccess = $.LFieldAccess; -export const LFieldAccess = ( - aggregate: $.LValue, +export type CLFieldAccess = $.CLFieldAccess; +export const CLFieldAccess = ( + aggregate: $.CLValue, field: $c.Id, computedType: $d.CType, loc: $c.Loc, -): $.LFieldAccess => +): $.CLFieldAccess => Object.freeze({ kind: "field_access", aggregate, @@ -356,6 +324,4 @@ export const LFieldAccess = ( computedType, loc, }); -export const isLFieldAccess = ($value: LFieldAccess) => - $value.kind === "field_access"; -export type LValue = $.LValue; +export type LValue = $.CLValue; diff --git a/src/next/ast/generated/checked-stmt.ts b/src/next/ast/generated/checked-stmt.ts index 640f16445e..ff6e7d0d7a 100644 --- a/src/next/ast/generated/checked-stmt.ts +++ b/src/next/ast/generated/checked-stmt.ts @@ -3,67 +3,58 @@ import type * as $ from "@/next/ast/checked-stmt"; import type * as $e from "@/next/ast/checked-expr"; import type * as $c from "@/next/ast/common"; import type * as $s from "@/next/ast/statement"; -import type { Ordered } from "@/next/ast/checked"; -export type DStatementLet = $.DStatementLet; -export const DStatementLet = ( +export type CStmtLet = $.CStmtLet; +export const CStmtLet = ( name: $c.OptionalId, - expression: $e.DecodedExpression, + expression: $e.CExpr, loc: $c.Loc, -): $.DStatementLet => +): $.CStmtLet => Object.freeze({ kind: "statement_let", name, expression, loc, }); -export const isDStatementLet = ($value: DStatementLet) => - $value.kind === "statement_let"; -export type DStatementReturn = $.DStatementReturn; -export const DStatementReturn = ( - expression: $e.DecodedExpression | undefined, +export type CStmtReturn = $.CStmtReturn; +export const CStmtReturn = ( + expression: $e.CExpr | undefined, loc: $c.Loc, -): $.DStatementReturn => +): $.CStmtReturn => Object.freeze({ kind: "statement_return", expression, loc, }); -export const isDStatementReturn = ($value: DStatementReturn) => - $value.kind === "statement_return"; -export type DStatementExpression = $.DStatementExpression; -export const DStatementExpression = ( - expression: $e.DecodedExpression, +export type CStmtExpression = $.CStmtExpression; +export const CStmtExpression = ( + expression: $e.CExpr, loc: $c.Loc, -): $.DStatementExpression => +): $.CStmtExpression => Object.freeze({ kind: "statement_expression", expression, loc, }); -export const isDStatementExpression = ($value: DStatementExpression) => - $value.kind === "statement_expression"; -export type DStatementAssign = $.DStatementAssign; -export const DStatementAssign = ( - path: $e.LValue, - expression: $e.DecodedExpression, +export type CStmtAssign = $.CStmtAssign; +export const CStmtAssign = ( + path: $e.CLValue, + expression: $e.CExpr, loc: $c.Loc, -): $.DStatementAssign => +): $.CStmtAssign => Object.freeze({ kind: "statement_assign", path, expression, loc, }); -export const isDStatementAssign = ($value: DStatementAssign) => - $value.kind === "statement_assign"; -export type DStatementAugmentedAssign = $.DStatementAugmentedAssign; -export const DStatementAugmentedAssign = ( +export type CStmtAugmentedAssign = $.CStmtAugmentedAssign; +export const CStmtAugmentedAssign = ( op: $s.AugmentedAssignOperation, - path: $e.LValue, - expression: $e.DecodedExpression, + path: $e.CLValue, + expression: $e.CExpr, loc: $c.Loc, -): $.DStatementAugmentedAssign => +): $.CStmtAugmentedAssign => Object.freeze({ kind: "statement_augmentedassign", op, @@ -71,26 +62,23 @@ export const DStatementAugmentedAssign = ( expression, loc, }); -export const isDStatementAugmentedAssign = ( - $value: DStatementAugmentedAssign, -) => $value.kind === "statement_augmentedassign"; -export type DestructPattern = $.DestructPattern; -export const DestructPattern = ( +export type CDestructPattern = $.CDestructPattern; +export const CDestructPattern = ( field: $c.Id, variable: $c.OptionalId, -): $.DestructPattern => +): $.CDestructPattern => Object.freeze({ field, variable, }); -export type DStatementDestruct = $.DStatementDestruct; -export const DStatementDestruct = ( +export type CStmtDestruct = $.CStmtDestruct; +export const CStmtDestruct = ( type_: $c.TypeId, - identifiers: Ordered<$.DestructPattern>, + identifiers: $c.Ordered<$.CDestructPattern>, ignoreUnspecifiedFields: boolean, - expression: $e.DecodedExpression, + expression: $e.CExpr, loc: $c.Loc, -): $.DStatementDestruct => +): $.CStmtDestruct => Object.freeze({ kind: "statement_destruct", type: type_, @@ -99,28 +87,24 @@ export const DStatementDestruct = ( expression, loc, }); -export const isDStatementDestruct = ($value: DStatementDestruct) => - $value.kind === "statement_destruct"; -export type DStatementBlock = $.DStatementBlock; -export const DStatementBlock = ( - statements: $.DStatementList, +export type CStmtBlock = $.CStmtBlock; +export const CStmtBlock = ( + statements: $.CStmtList, loc: $c.Loc, -): $.DStatementBlock => +): $.CStmtBlock => Object.freeze({ kind: "statement_block", statements, loc, }); -export const isDStatementBlock = ($value: DStatementBlock) => - $value.kind === "statement_block"; -export type DStatementForEach = $.DStatementForEach; -export const DStatementForEach = ( +export type CStmtForEach = $.CStmtForEach; +export const CStmtForEach = ( keyName: $c.OptionalId, valueName: $c.OptionalId, - map: $e.DecodedExpression, - statements: $.DStatementList, + map: $e.CExpr, + statements: $.CStmtList, loc: $c.Loc, -): $.DStatementForEach => +): $.CStmtForEach => Object.freeze({ kind: "statement_foreach", keyName, @@ -129,81 +113,71 @@ export const DStatementForEach = ( statements, loc, }); -export const isDStatementForEach = ($value: DStatementForEach) => - $value.kind === "statement_foreach"; -export type DCatchBlock = $.DCatchBlock; -export const DCatchBlock = ( +export type CCatchBlock = $.CCatchBlock; +export const CCatchBlock = ( catchName: $c.OptionalId, - catchStatements: $.DStatementList, -): $.DCatchBlock => + catchStatements: $.CStmtList, +): $.CCatchBlock => Object.freeze({ name: catchName, statements: catchStatements, }); -export type DStatementTry = $.DStatementTry; -export const DStatementTry = ( - statements: $.DStatementList, - catchBlock: $.DCatchBlock | undefined, +export type CStmtTry = $.CStmtTry; +export const CStmtTry = ( + statements: $.CStmtList, + catchBlock: $.CCatchBlock | undefined, loc: $c.Loc, -): $.DStatementTry => +): $.CStmtTry => Object.freeze({ kind: "statement_try", statements, catchBlock, loc, }); -export const isDStatementTry = ($value: DStatementTry) => - $value.kind === "statement_try"; -export type DStatementRepeat = $.DStatementRepeat; -export const DStatementRepeat = ( - iterations: $e.DecodedExpression, - statements: $.DStatementList, +export type CStmtRepeat = $.CStmtRepeat; +export const CStmtRepeat = ( + iterations: $e.CExpr, + statements: $.CStmtList, loc: $c.Loc, -): $.DStatementRepeat => +): $.CStmtRepeat => Object.freeze({ kind: "statement_repeat", iterations, statements, loc, }); -export const isDStatementRepeat = ($value: DStatementRepeat) => - $value.kind === "statement_repeat"; -export type DStatementUntil = $.DStatementUntil; -export const DStatementUntil = ( - condition: $e.DecodedExpression, - statements: $.DStatementList, +export type CStmtUntil = $.CStmtUntil; +export const CStmtUntil = ( + condition: $e.CExpr, + statements: $.CStmtList, loc: $c.Loc, -): $.DStatementUntil => +): $.CStmtUntil => Object.freeze({ kind: "statement_until", condition, statements, loc, }); -export const isDStatementUntil = ($value: DStatementUntil) => - $value.kind === "statement_until"; -export type DStatementWhile = $.DStatementWhile; -export const DStatementWhile = ( - condition: $e.DecodedExpression, - statements: $.DStatementList, +export type CStmtWhile = $.CStmtWhile; +export const CStmtWhile = ( + condition: $e.CExpr, + statements: $.CStmtList, loc: $c.Loc, -): $.DStatementWhile => +): $.CStmtWhile => Object.freeze({ kind: "statement_while", condition, statements, loc, }); -export const isDStatementWhile = ($value: DStatementWhile) => - $value.kind === "statement_while"; -export type DStatementList = $.DStatementList; -export type DStatementCondition = $.DStatementCondition; -export const DStatementCondition = ( - condition: $e.DecodedExpression, - trueStatements: $.DStatementList, - falseStatements: $.DStatementList | undefined, +export type CStmtList = $.CStmtList; +export type CStmtCondition = $.CStmtCondition; +export const CStmtCondition = ( + condition: $e.CExpr, + trueStatements: $.CStmtList, + falseStatements: $.CStmtList | undefined, loc: $c.Loc, -): $.DStatementCondition => +): $.CStmtCondition => Object.freeze({ kind: "statement_condition", condition, @@ -211,6 +185,4 @@ export const DStatementCondition = ( falseStatements, loc, }); -export const isDStatementCondition = ($value: DStatementCondition) => - $value.kind === "statement_condition"; -export type DecodedStatement = $.DecodedStatement; +export type CStmt = $.CStmt; diff --git a/src/next/ast/generated/checked-type.ts b/src/next/ast/generated/checked-type.ts index 714d0b4de5..db6ac372c7 100644 --- a/src/next/ast/generated/checked-type.ts +++ b/src/next/ast/generated/checked-type.ts @@ -11,17 +11,15 @@ export const CTBasic = (type: BasicType, loc: $c.Loc): $.CTBasic => type, loc, }); -export type CTypeParamRef = $.CTParamRef; -export const CTypeParamRef = (name: $c.TypeId, loc: $c.Loc): $.CTParamRef => +export type CTParamRef = $.CTParamRef; +export const CTParamRef = (name: $c.TypeId, loc: $c.Loc): $.CTParamRef => Object.freeze({ kind: "TypeParam", name, loc, }); -export const isCTypeParamRef = ($value: CTypeParamRef) => - $value.kind === "TypeParam"; -export type CTypeTensor = $.CTTensor; -export const CTypeTensor = ( +export type CTTensor = $.CTTensor; +export const CTTensor = ( typeArgs: readonly $.CType[], loc: $c.Loc, ): $.CTTensor => @@ -30,10 +28,8 @@ export const CTypeTensor = ( typeArgs, loc, }); -export const isCTypeTensor = ($value: CTypeTensor) => - $value.kind === "tensor_type"; -export type CTypeTuple = $.CTTuple; -export const CTypeTuple = ( +export type CTTuple = $.CTTuple; +export const CTTuple = ( typeArgs: readonly $.CType[], loc: $c.Loc, ): $.CTTuple => @@ -42,27 +38,22 @@ export const CTypeTuple = ( typeArgs, loc, }); -export const isCTypeTuple = ($value: CTypeTuple) => - $value.kind === "tuple_type"; -export type CTypeMaybe = $.CTMaybe; -export const CTypeMaybe = (type_: $.CType, loc: $c.Loc): $.CTMaybe => +export type CTMaybe = $.CTMaybe; +export const CTMaybe = (type_: $.CType, loc: $c.Loc): $.CTMaybe => Object.freeze({ kind: "TypeMaybe", type: type_, loc, }); -export const isCTypeMaybe = ($value: CTypeMaybe) => $value.kind === "TypeMaybe"; -export type CTypeBounced = $.CTBounced; -export const CTypeBounced = (name: $c.TypeId, loc: $c.Loc): $.CTBounced => +export type CTBounced = $.CTBounced; +export const CTBounced = (name: $c.TypeId, loc: $c.Loc): $.CTBounced => Object.freeze({ kind: "TypeBounced", name, loc, }); -export const isCTypeBounced = ($value: CTypeBounced) => - $value.kind === "TypeBounced"; -export type CTypeMap = $.CTMap; -export const CTypeMap = ( +export type CTMap = $.CTMap; +export const CTMap = ( key: $.CType, value: $.CType, loc: $c.Loc, @@ -73,9 +64,8 @@ export const CTypeMap = ( value, loc, }); -export const isCTypeMap = ($value: CTypeMap) => $value.kind === "map_type"; -export type CTypeAliasRef = $.CTAliasRef; -export const CTypeAliasRef = ( +export type CTAliasRef = $.CTAliasRef; +export const CTAliasRef = ( type: CNotDealiased | CType, name: $c.TypeId, typeArgs: readonly $.CType[], @@ -88,10 +78,8 @@ export const CTypeAliasRef = ( typeArgs, loc, }); -export const isCTypeAliasRef = ($value: CTypeAliasRef) => - $value.kind === "TypeAlias"; -export type DTypeRef = $.CTRef; -export const DTypeRef = ( +export type CTRef = $.CTRef; +export const CTRef = ( name: $c.TypeId, type: CTypeDeclRefable, typeArgs: readonly $.CType[], @@ -104,26 +92,20 @@ export const DTypeRef = ( typeArgs, loc, }); -export const isCTypeRef = ($value: DTypeRef) => $value.kind === "type_ref"; export type CType = $.CType; -export type CTypeRecover = $.CTRecover; -export const CTypeRecover = (): $.CTRecover => +export type CTRecover = $.CTRecover; +export const CTRecover = (): $.CTRecover => Object.freeze({ kind: "recover", }); -export const isCTypeRecover = ($value: CTypeRecover) => - $value.kind === "recover"; export type CNotDealiased = $.CNotDealiased; export const CNotDealiased = (): $.CNotDealiased => Object.freeze({ kind: "NotDealiased", }); -export const isCNotDealiased = ($value: CNotDealiased) => - $value.kind === "NotDealiased"; -export type CNotSet = $.DNotSet; -export const CNotSet = (): $.DNotSet => +export type CNotSet = $.CNotSet; +export const CNotSet = (): $.CNotSet => Object.freeze({ kind: "not-set", }); -export const isCNotSet = ($value: CNotSet) => $value.kind === "not-set"; diff --git a/src/next/ast/generated/checked.ts b/src/next/ast/generated/checked.ts index 1f625aa010..166325a3b9 100644 --- a/src/next/ast/generated/checked.ts +++ b/src/next/ast/generated/checked.ts @@ -11,7 +11,7 @@ import type { AsmShuffle, ContractAttribute, } from "@/next/ast/root"; -import type { DecodedStatement } from "@/next/ast/checked-stmt"; +import type { CStmt } from "@/next/ast/checked-stmt"; import type { Value } from "@/next/ast/value"; import type { Effects } from "@/next/ast/effects"; @@ -34,22 +34,13 @@ export const CAlias = ( typeParams, type: type_, }); -export type Ordered = $.Ordered; -export const Ordered = ( - order: readonly string[], - map: ReadonlyMap, -): $.Ordered => - Object.freeze({ - order, - map, - }); -export type CTypeFunction = $.CTypeFunction; -export const CTypeFunction = ( +export type CTFunction = $.CTFunction; +export const CTFunction = ( typeParams: $.CTypeParams, params: $.CParameters, returnType: Thunk<$d.CType>, -): $.CTypeFunction => +): $.CTFunction => Object.freeze({ kind: "DecodedFnType", typeParams, @@ -69,7 +60,7 @@ export const CBounce = ( export type CStruct = $.CStruct; export const CStruct = ( typeParams: $.CTypeParams, - fields: $.Ordered<$.CField>, + fields: $c.Ordered<$.CField>, ): $.CStruct => Object.freeze({ kind: "struct", @@ -98,7 +89,7 @@ export const CConstant = ( }); export type CExtension = $.CExtension; export const CExtension = ( - type: $.CTypeMethod, + type: $.CTMethod, inline: boolean, body: $.CBody, ): $.CExtension => @@ -125,14 +116,14 @@ export const CSource = ( constants: constSigs, extensions: extSigs, }); -export type CTypeMethod = $.CTypeMethod; -export const CTypeMethod = ( +export type CTMethod = $.CTMethod; +export const CTMethod = ( mutates: boolean, typeParams: $.CTypeParams, self: $m.SelfType, params: $.CParameters, returnType: Thunk<$d.CType>, -): $.CTypeMethod => +): $.CTMethod => Object.freeze({ kind: "DecodedMethodType", mutates, @@ -198,7 +189,7 @@ export const CFiftBody = ( export type CBody = $.CBody; export type CFunction = $.CFunction; export const CFunction = ( - type_: $.CTypeFunction, + type_: $.CTFunction, inline: boolean, body: $.CBody, ): $.CFunction => @@ -238,7 +229,7 @@ export type CFieldish = $.CFieldish; export type CMethod = $.CMethod; export const CMethod = ( overridable: boolean, - type_: $.CTypeMethod, + type_: $.CTMethod, inline: boolean, body: Body, getMethodId: Thunk | undefined, @@ -253,7 +244,7 @@ export const CMethod = ( export type CReceivers = $.CReceivers; export type CMembers = $.CMembers; export const CMembers = ( - fieldish: $.Ordered<$.DeclMem<$.CFieldish>>, + fieldish: $c.Ordered<$.DeclMem<$.CFieldish>>, methods: ReadonlyMap>>, receivers: $.CReceivers, ): $.CMembers => @@ -264,12 +255,12 @@ export const CMembers = ( }); export type CContractMembers = $.CContractMembers; export type CTraitMembers = $.CTraitMembers; -export type CTraitSig = $.CTraitSig; -export const CTraitSig = ( +export type CTrait = $.CTrait; +export const CTrait = ( content: Thunk< $.CMembers | undefined, $.CBody | undefined> >, -): $.CTraitSig => +): $.CTrait => Object.freeze({ kind: "trait", content, @@ -338,7 +329,7 @@ export const CReceiver = ( export type CMessage = $.CMessage; export const CMessage = ( opcode: Thunk, - fields: $.Ordered<$.CField>, + fields: $c.Ordered<$.CField>, ): $.CMessage => Object.freeze({ kind: "message", @@ -347,7 +338,7 @@ export const CMessage = ( }); export type CInitEmpty = $.CInitEmpty; export const CInitEmpty = ( - fill: Thunk>>, + fill: Thunk>>, ): $.CInitEmpty => Object.freeze({ kind: "empty", @@ -366,7 +357,7 @@ export const CInitParam = ( }); export type CInitSimple = $.CInitSimple; export const CInitSimple = ( - fill: $.Ordered<$.CInitParam>, + fill: $c.Ordered<$.CInitParam>, loc: $c.Loc, ): $.CInitSimple => Object.freeze({ @@ -376,7 +367,7 @@ export const CInitSimple = ( }); export type CStatementsAux = $.CStatementsAux; export const CStatementsAux = ( - body: readonly DecodedStatement[], + body: readonly CStmt[], effects: Effects, ): $.CStatementsAux => Object.freeze({ @@ -394,12 +385,12 @@ export const CInitFn = ( statements, }); export type CStatements = $.CStatements; -export type CInitSig = $.CInitSig; +export type CInit = $.CInit; export type CContract = $.CContract; export type CTypeDeclRefable = $.CTypeDeclRefable; export const CContract = ( attributes: readonly ContractAttribute[], - init: $.CInitSig, + init: $.CInit, content: Thunk<$.CContractMembers>, ): $.CContract => Object.freeze({ diff --git a/src/next/ast/generated/common.ts b/src/next/ast/generated/common.ts index 738e23d63c..390271866c 100644 --- a/src/next/ast/generated/common.ts +++ b/src/next/ast/generated/common.ts @@ -58,3 +58,12 @@ export const TypeId = (text: string, loc: $.Loc): $.TypeId => loc, }); export const isTypeId = ($value: TypeId) => $value.kind === "type_id"; +export type Ordered = $.Ordered; +export const Ordered = ( + order: readonly string[], + map: ReadonlyMap, +): $.Ordered => + Object.freeze({ + order, + map, + }); diff --git a/src/next/ast/generated/lowered-expr.ts b/src/next/ast/generated/lowered-expr.ts new file mode 100644 index 0000000000..857a2096dd --- /dev/null +++ b/src/next/ast/generated/lowered-expr.ts @@ -0,0 +1,222 @@ +import type * as $ from "@/next/ast/lowered-expr"; +import type * as $t from "@/next/ast/lowered-type"; +import type * as $c from "@/next/ast/common"; +import type { BinaryOperation, NumberBase, UnaryOperation } from "@/next/ast/expression"; +import type { SelfType } from "@/next/ast/type-self"; + +export type LTypeArgs = $.LTypeArgs; +export type LCodeOf = $.LCodeOf; +export const LCodeOf = (contract: $c.TypeId, computedType: $t.LType, loc: $c.Loc): $.LCodeOf => Object.freeze({ + kind: "code_of", + contract, + computedType, + loc +}); +export const isLCodeOf = ($value: LCodeOf) => $value.kind === "code_of"; +export type LNumber = $.LNumber; +export const LNumber = (base: NumberBase, value: bigint, computedType: $t.LTBasic, loc: $c.Loc): $.LNumber => Object.freeze({ + kind: "number", + base, + value, + computedType, + loc +}); +export const isLNumber = ($value: LNumber) => $value.kind === "number"; +export type LBoolean = $.LBoolean; +export const LBoolean = (value: boolean, computedType: $t.LTBasic, loc: $c.Loc): $.LBoolean => Object.freeze({ + kind: "boolean", + value, + computedType, + loc +}); +export const isLBoolean = ($value: LBoolean) => $value.kind === "boolean"; +export type LNull = $.LNull; +export const LNull = (computedType: $t.LTBasic, loc: $c.Loc): $.LNull => Object.freeze({ + kind: "null", + computedType, + loc +}); +export const isLNull = ($value: LNull) => $value.kind === "null"; +export type LString = $.LString; +export const LString = (value: string, computedType: $t.LTBasic, loc: $c.Loc): $.LString => Object.freeze({ + kind: "string", + value, + computedType, + loc +}); +export const isLString = ($value: LString) => $value.kind === "string"; +export type LVar = $.LVar; +export const LVar = (name: string, computedType: $t.LType, loc: $c.Loc): $.LVar => Object.freeze({ + kind: "var", + name, + computedType, + loc +}); +export const isLVar = ($value: LVar) => $value.kind === "var"; +export type LSelf = $.LSelf; +export const LSelf = (computedType: SelfType, loc: $c.Loc): $.LSelf => Object.freeze({ + kind: "self", + computedType, + loc +}); +export const isLSelf = ($value: LSelf) => $value.kind === "self"; +export type LUnit = $.LUnit; +export const LUnit = (computedType: $t.LTBasic, loc: $c.Loc): $.LUnit => Object.freeze({ + kind: "unit", + computedType, + loc +}); +export const isLUnit = ($value: LUnit) => $value.kind === "unit"; +export type LSetLiteral = $.LSetLiteral; +export const LSetLiteral = (valueType: $t.LType, fields: readonly $.LExpr[], computedType: $t.LType, loc: $c.Loc): $.LSetLiteral => Object.freeze({ + kind: "set_literal", + valueType, + fields, + computedType, + loc +}); +export const isLSetLiteral = ($value: LSetLiteral) => $value.kind === "set_literal"; +export type LMapField = $.LMapField; +export const LMapField = (key: $.LExpr, value: $.LExpr): $.LMapField => Object.freeze({ + key, + value +}); +export type LMapLiteral = $.LMapLiteral; +export const LMapLiteral = (fields: readonly $.LMapField[], computedType: $t.LTMap, loc: $c.Loc): $.LMapLiteral => Object.freeze({ + kind: "map_literal", + fields, + computedType, + loc +}); +export const isLMapLiteral = ($value: LMapLiteral) => $value.kind === "map_literal"; +export type LTensor = $.LTensor; +export const LTensor = (children: readonly $.LExpr[], computedType: $t.LTTensor, loc: $c.Loc): $.LTensor => Object.freeze({ + kind: "tensor", + children, + computedType, + loc +}); +export const isLTensor = ($value: LTensor) => $value.kind === "tensor"; +export type LTuple = $.LTuple; +export const LTuple = (children: readonly $.LExpr[], computedType: $t.LTTuple, loc: $c.Loc): $.LTuple => Object.freeze({ + kind: "tuple", + children, + computedType, + loc +}); +export const isLTuple = ($value: LTuple) => $value.kind === "tuple"; +export type LInitOf = $.LInitOf; +export const LInitOf = (contract: $c.TypeId, args: readonly $.LExpr[], computedType: $t.LType, loc: $c.Loc): $.LInitOf => Object.freeze({ + kind: "init_of", + contract, + args, + computedType, + loc +}); +export const isLInitOf = ($value: LInitOf) => $value.kind === "init_of"; +export type LStructCons = $.LStructCons; +export const LStructCons = (fields: $c.Ordered<$.LExpr>, computedType: $t.LTRef, loc: $c.Loc): $.LStructCons => Object.freeze({ + kind: "struct_instance", + fields, + computedType, + loc +}); +export const isLStructInstance = ($value: LStructCons) => $value.kind === "struct_instance"; +export type LFieldAccess = $.LFieldAccess; +export const LFieldAccess = (aggregate: $.LExpr, field: $c.Id, computedType: $t.LType, loc: $c.Loc): $.LFieldAccess => Object.freeze({ + kind: "field_access", + aggregate, + field, + computedType, + loc +}); +export const isLFieldAccess = ($value: LFieldAccess) => $value.kind === "field_access"; +export type LStaticMethodCall = $.LStaticMethodCall; +export const LStaticMethodCall = (self: $c.TypeId, typeArgs: $.LTypeArgs, function_: $c.Id, args: readonly $.LExpr[], computedType: $t.LType, loc: $c.Loc): $.LStaticMethodCall => Object.freeze({ + kind: "static_method_call", + self, + typeArgs, + function: function_, + args, + computedType, + loc +}); +export const isLStaticMethodCall = ($value: LStaticMethodCall) => $value.kind === "static_method_call"; +export type LStaticCall = $.LStaticCall; +export const LStaticCall = (function_: $c.Id, typeArgs: $.LTypeArgs, args: readonly $.LExpr[], computedType: $t.LType, loc: $c.Loc): $.LStaticCall => Object.freeze({ + kind: "static_call", + function: function_, + typeArgs, + args, + computedType, + loc +}); +export const isLStaticCall = ($value: LStaticCall) => $value.kind === "static_call"; +export type LMethodCall = $.LMethodCall; +export const LMethodCall = (self: $.LExpr, method: $c.Id, args: readonly $.LExpr[], typeArgs: $.LTypeArgs, computedType: $t.LType, loc: $c.Loc): $.LMethodCall => Object.freeze({ + kind: "method_call", + self, + method, + args, + typeArgs, + computedType, + loc +}); +export const isLMethodCall = ($value: LMethodCall) => $value.kind === "method_call"; +export type LConditional = $.LConditional; +export const LConditional = (condition: $.LExpr, thenBranch: $.LExpr, elseBranch: $.LExpr, computedType: $t.LType, loc: $c.Loc): $.LConditional => Object.freeze({ + kind: "conditional", + condition, + thenBranch, + elseBranch, + computedType, + loc +}); +export const isLConditional = ($value: LConditional) => $value.kind === "conditional"; +export type LOpUnary = $.LOpUnary; +export const LOpUnary = (op: UnaryOperation, operand: $.LExpr, typeArgs: $.LTypeArgs, computedType: $t.LType, loc: $c.Loc): $.LOpUnary => Object.freeze({ + kind: "op_unary", + op, + operand, + typeArgs, + computedType, + loc +}); +export const isLOpUnary = ($value: LOpUnary) => $value.kind === "op_unary"; +export type LOpBinary = $.LOpBinary; +export const LOpBinary = (op: BinaryOperation, left: $.LExpr, right: $.LExpr, typeArgs: $.LTypeArgs, computedType: $t.LType, loc: $c.Loc): $.LOpBinary => Object.freeze({ + kind: "op_binary", + op, + left, + right, + typeArgs, + computedType, + loc +}); +export const isLOpBinary = ($value: LOpBinary) => $value.kind === "op_binary"; +export type LExpr = $.LExpr; +export type LLVar = $.LLVar; +export const LLVar = (name: string, computedType: $t.LType, loc: $c.Loc): $.LLVar => Object.freeze({ + kind: "var", + name, + computedType, + loc +}); +export const isLLVar = ($value: LLVar) => $value.kind === "var"; +export type LLSelf = $.LLSelf; +export const LLSelf = (computedType: SelfType, loc: $c.Loc): $.LLSelf => Object.freeze({ + kind: "self", + computedType, + loc +}); +export const isLLSelf = ($value: LLSelf) => $value.kind === "self"; +export type LLFieldAccess = $.LLFieldAccess; +export const LLFieldAccess = (aggregate: $.LLValue, field: $c.Id, computedType: $t.LType, loc: $c.Loc): $.LLFieldAccess => Object.freeze({ + kind: "field_access", + aggregate, + field, + computedType, + loc +}); +export const isLLFieldAccess = ($value: LLFieldAccess) => $value.kind === "field_access"; +export type LLValue = $.LLValue; \ No newline at end of file diff --git a/src/next/ast/generated/lowered-stmt.ts b/src/next/ast/generated/lowered-stmt.ts new file mode 100644 index 0000000000..37edebb167 --- /dev/null +++ b/src/next/ast/generated/lowered-stmt.ts @@ -0,0 +1,124 @@ +import type * as $ from "@/next/ast/lowered-stmt"; +import type * as $e from "@/next/ast/lowered-expr"; +import type * as $c from "@/next/ast/common"; +import type { AugmentedAssignOperation } from "@/next/ast/statement"; + +export type LStmtLet = $.LStmtLet; +export const LStmtLet = (name: $c.OptionalId, expression: $e.LExpr, loc: $c.Loc): $.LStmtLet => Object.freeze({ + kind: "let", + name, + expression, + loc +}); +export const isLStmtLet = ($value: LStmtLet) => $value.kind === "let"; +export type LStmtReturn = $.LStmtReturn; +export const LStmtReturn = (expression: $e.LExpr | undefined, loc: $c.Loc): $.LStmtReturn => Object.freeze({ + kind: "return", + expression, + loc +}); +export const isLStmtReturn = ($value: LStmtReturn) => $value.kind === "return"; +export type LStmtExpression = $.LStmtExpression; +export const LStmtExpression = (expression: $e.LExpr, loc: $c.Loc): $.LStmtExpression => Object.freeze({ + kind: "expression", + expression, + loc +}); +export const isLStmtExpression = ($value: LStmtExpression) => $value.kind === "expression"; +export type LStmtAssign = $.LStmtAssign; +export const LStmtAssign = (path: $e.LLValue, expression: $e.LExpr, loc: $c.Loc): $.LStmtAssign => Object.freeze({ + kind: "assign", + path, + expression, + loc +}); +export const isLStmtAssign = ($value: LStmtAssign) => $value.kind === "assign"; +export type LStmtAugmentedAssign = $.LStmtAugmentedAssign; +export const LStmtAugmentedAssign = (op: AugmentedAssignOperation, path: $e.LLValue, expression: $e.LExpr, loc: $c.Loc): $.LStmtAugmentedAssign => Object.freeze({ + kind: "augmentedassign", + op, + path, + expression, + loc +}); +export const isLStmtAugmentedAssign = ($value: LStmtAugmentedAssign) => $value.kind === "augmentedassign"; +export type LDestructPattern = $.LDestructPattern; +export const LDestructPattern = (field: $c.Id, variable: $c.OptionalId): $.LDestructPattern => Object.freeze({ + field, + variable +}); +export type LStmtDestruct = $.LStmtDestruct; +export const LStmtDestruct = (type_: $c.TypeId, identifiers: $c.Ordered<$.LDestructPattern>, ignoreUnspecifiedFields: boolean, expression: $e.LExpr, loc: $c.Loc): $.LStmtDestruct => Object.freeze({ + kind: "destruct", + type: type_, + identifiers, + ignoreUnspecifiedFields, + expression, + loc +}); +export const isLStmtDestruct = ($value: LStmtDestruct) => $value.kind === "destruct"; +export type LStmtBlock = $.LStmtBlock; +export const LStmtBlock = (statements: $.LStmtList, loc: $c.Loc): $.LStmtBlock => Object.freeze({ + kind: "block", + statements, + loc +}); +export const isLStmtBlock = ($value: LStmtBlock) => $value.kind === "block"; +export type LStmtForEach = $.LStmtForEach; +export const LStmtForEach = (keyName: $c.OptionalId, valueName: $c.OptionalId, map: $e.LExpr, statements: $.LStmtList, loc: $c.Loc): $.LStmtForEach => Object.freeze({ + kind: "foreach", + keyName, + valueName, + map, + statements, + loc +}); +export const isLStmtForEach = ($value: LStmtForEach) => $value.kind === "foreach"; +export type LCatchBlock = $.LCatchBlock; +export const LCatchBlock = (name: $c.OptionalId, statements: $.LStmtList): $.LCatchBlock => Object.freeze({ + name, + statements +}); +export type LStmtTry = $.LStmtTry; +export const LStmtTry = (statements: $.LStmtList, catchBlock: $.LCatchBlock | undefined, loc: $c.Loc): $.LStmtTry => Object.freeze({ + kind: "try", + statements, + catchBlock, + loc +}); +export const isLStmtTry = ($value: LStmtTry) => $value.kind === "try"; +export type LStmtRepeat = $.LStmtRepeat; +export const LStmtRepeat = (iterations: $e.LExpr, statements: $.LStmtList, loc: $c.Loc): $.LStmtRepeat => Object.freeze({ + kind: "repeat", + iterations, + statements, + loc +}); +export const isLStmtRepeat = ($value: LStmtRepeat) => $value.kind === "repeat"; +export type LStmtUntil = $.LStmtUntil; +export const LStmtUntil = (condition: $e.LExpr, statements: $.LStmtList, loc: $c.Loc): $.LStmtUntil => Object.freeze({ + kind: "until", + condition, + statements, + loc +}); +export const isLStmtUntil = ($value: LStmtUntil) => $value.kind === "until"; +export type LStmtWhile = $.LStmtWhile; +export const LStmtWhile = (condition: $e.LExpr, statements: $.LStmtList, loc: $c.Loc): $.LStmtWhile => Object.freeze({ + kind: "while", + condition, + statements, + loc +}); +export const isLStmtWhile = ($value: LStmtWhile) => $value.kind === "while"; +export type LStmtList = $.LStmtList; +export type LStmtCondition = $.LStmtCondition; +export const LStmtCondition = (condition: $e.LExpr, trueStatements: $.LStmtList, falseStatements: $.LStmtList | undefined, loc: $c.Loc): $.LStmtCondition => Object.freeze({ + kind: "condition", + condition, + trueStatements, + falseStatements, + loc +}); +export const isLStmtCondition = ($value: LStmtCondition) => $value.kind === "condition"; +export type LStmt = $.LStmt; \ No newline at end of file diff --git a/src/next/ast/generated/lowered-type.ts b/src/next/ast/generated/lowered-type.ts new file mode 100644 index 0000000000..f38c821e78 --- /dev/null +++ b/src/next/ast/generated/lowered-type.ts @@ -0,0 +1,74 @@ +import type * as $ from "@/next/ast/lowered-type"; +import type * as $c from "@/next/ast/common"; +import type { BasicType } from "@/next/ast/type-basic"; +import type { CTypeDeclRefable } from "@/next/ast/checked"; + +export type LTParamRef = $.LTParamRef; +export const LTParamRef = (name: $c.TypeId, loc: $c.Loc): $.LTParamRef => Object.freeze({ + kind: "TypeParam", + name, + loc +}); +export const isLTParamRef = ($value: LTParamRef) => $value.kind === "TypeParam"; +export type LTBounced = $.LTBounced; +export const LTBounced = (name: $c.TypeId, loc: $c.Loc): $.LTBounced => Object.freeze({ + kind: "TypeBounced", + name, + loc +}); +export const isLTBounced = ($value: LTBounced) => $value.kind === "TypeBounced"; +export type LTBasic = $.LTBasic; +export const LTBasic = (type_: BasicType, loc: $c.Loc): $.LTBasic => Object.freeze({ + kind: "basic", + type: type_, + loc +}); +export const isLTBasic = ($value: LTBasic) => $value.kind === "basic"; +export type LTTensor = $.LTTensor; +export const LTTensor = (typeArgs: readonly $.LType[], loc: $c.Loc): $.LTTensor => Object.freeze({ + kind: "tensor_type", + typeArgs, + loc +}); +export const isLTTensor = ($value: LTTensor) => $value.kind === "tensor_type"; +export type LTTuple = $.LTTuple; +export const LTTuple = (typeArgs: readonly $.LType[], loc: $c.Loc): $.LTTuple => Object.freeze({ + kind: "tuple_type", + typeArgs, + loc +}); +export const isLTTuple = ($value: LTTuple) => $value.kind === "tuple_type"; +export type LTMaybe = $.LTMaybe; +export const LTMaybe = (type_: $.LType, loc: $c.Loc): $.LTMaybe => Object.freeze({ + kind: "TypeMaybe", + type: type_, + loc +}); +export const isLTMaybe = ($value: LTMaybe) => $value.kind === "TypeMaybe"; +export type LTMap = $.LTMap; +export const LTMap = (key: $.LType, value: $.LType, loc: $c.Loc): $.LTMap => Object.freeze({ + kind: "map_type", + key, + value, + loc +}); +export const isLTMap = ($value: LTMap) => $value.kind === "map_type"; +export type LTAliasRef = $.LTAliasRef; +export const LTAliasRef = (name: $c.TypeId, type_: $.LType, typeArgs: readonly $.LType[], loc: $c.Loc): $.LTAliasRef => Object.freeze({ + kind: "TypeAlias", + name, + type: type_, + typeArgs, + loc +}); +export const isLTAliasRef = ($value: LTAliasRef) => $value.kind === "TypeAlias"; +export type LTRef = $.LTRef; +export const LTRef = (name: $c.TypeId, type_: CTypeDeclRefable, typeArgs: readonly $.LType[], loc: $c.Loc): $.LTRef => Object.freeze({ + kind: "type_ref", + name, + type: type_, + typeArgs, + loc +}); +export const isLTRef = ($value: LTRef) => $value.kind === "type_ref"; +export type LType = $.LType; \ No newline at end of file diff --git a/src/next/ast/generated/lowered.ts b/src/next/ast/generated/lowered.ts index d6e6e9bec2..4494205084 100644 --- a/src/next/ast/generated/lowered.ts +++ b/src/next/ast/generated/lowered.ts @@ -1,51 +1,46 @@ import type * as $ from "@/next/ast/lowered"; import type * as $c from "@/next/ast/common"; -import type * as $d from "@/next/ast/checked-type"; +import type * as $d from "@/next/ast/lowered-type"; import type * as $v from "@/next/ast/value"; -import type { DecodedStatement } from "@/next/ast/checked-stmt"; -import type { Effects } from "@/next/ast/generated/effects"; +import type * as $s from "@/next/ast/lowered-stmt"; +import type { Effects } from "@/next/ast/effects"; import type { SelfType } from "@/next/ast/type-self"; -import type { AsmShuffle, ContractAttribute } from "@/next/ast/generated/root"; import type { AsmInstruction } from "@/next/ast/root"; +import type { AsmShuffle, ContractAttribute } from "@/next/ast/root"; export type LTypeParams = $.LTypeParams; export const LTypeParams = (order: readonly $c.TypeId[], set: ReadonlySet): $.LTypeParams => Object.freeze({ order, set }); -export type LAliasSig = $.LAliasSig; -export const LAliasSig = (typeParams: $.LTypeParams, type_: $d.CType): $.LAliasSig => Object.freeze({ +export type LAlias = $.LAlias; +export const LAlias = (typeParams: $.LTypeParams, type_: $d.LType): $.LAlias => Object.freeze({ kind: "alias", typeParams, type: type_ }); -export const isLAliasSig = ($value: LAliasSig) => $value.kind === "alias"; -export type LOrdered = $.LOrdered; -export const LOrdered = (order: readonly string[], map: ReadonlyMap): $.LOrdered => Object.freeze({ - order, - map -}); +export const isLAlias = ($value: LAlias) => $value.kind === "alias"; export type LInitEmpty = $.LInitEmpty; -export const LInitEmpty = (fill: $.LOrdered<$v.Value>): $.LInitEmpty => Object.freeze({ +export const LInitEmpty = (fill: $c.Ordered<$v.Value>): $.LInitEmpty => Object.freeze({ kind: "empty", fill }); export const isLInitEmpty = ($value: LInitEmpty) => $value.kind === "empty"; export type LInitParam = $.LInitParam; -export const LInitParam = (type_: $d.CType, init: $v.Value | undefined, loc: $c.Loc): $.LInitParam => Object.freeze({ +export const LInitParam = (type_: $d.LType, init: $v.Value | undefined, loc: $c.Loc): $.LInitParam => Object.freeze({ type: type_, init, loc }); export type LInitSimple = $.LInitSimple; -export const LInitSimple = (fill: $.LOrdered<$.LInitParam>, loc: $c.Loc): $.LInitSimple => Object.freeze({ +export const LInitSimple = (fill: $c.Ordered<$.LInitParam>, loc: $c.Loc): $.LInitSimple => Object.freeze({ kind: "simple", fill, loc }); export const isLInitSimple = ($value: LInitSimple) => $value.kind === "simple"; export type LParameter = $.LParameter; -export const LParameter = (name: $c.OptionalId, type_: $d.CType, loc: $c.Loc): $.LParameter => Object.freeze({ +export const LParameter = (name: $c.OptionalId, type_: $d.LType, loc: $c.Loc): $.LParameter => Object.freeze({ name, type: type_, loc @@ -56,7 +51,7 @@ export const LParameters = (order: readonly $.LParameter[], set: ReadonlySet Object.freeze({ +export const LStatements = (body: readonly $s.LStmt[], effects: Effects): $.LStatements => Object.freeze({ body, effects }); @@ -67,25 +62,24 @@ export const LInitFn = (params: $.LParameters, statements: $.LStatements): $.LIn statements }); export const isLInitFn = ($value: LInitFn) => $value.kind === "function"; -export type LInitSig = $.LInitSig; -export type LInhFieldSig = $.LInhFieldSig; -export const LInhFieldSig = (type_: $d.CType, init: $v.Value | undefined): $.LInhFieldSig => Object.freeze({ +export type LInit = $.LInit; +export type LField = $.LField; +export const LField = (type_: $d.LType, init: $v.Value | undefined): $.LField => Object.freeze({ kind: "field", type: type_, init }); -export const isLInhFieldSig = ($value: LInhFieldSig) => $value.kind === "field"; -export type LFieldConstSig = $.LFieldConstSig; -export const LFieldConstSig = (overridable: boolean, type_: $d.CType, init: Expr): $.LFieldConstSig => Object.freeze({ +export const isLField = ($value: LField) => $value.kind === "field"; +export type LFieldConstant = $.LFieldConstant; +export const LFieldConstant = (type_: $d.LType, init: Expr): $.LFieldConstant => Object.freeze({ kind: "constant", - overridable, type: type_, init }); -export const isLFieldConstSig = ($value: LFieldConstSig) => $value.kind === "constant"; +export const isLFieldConstant = ($value: LFieldConstant) => $value.kind === "constant"; export type LFieldish = $.LFieldish; -export type LDecodedMethodType = $.LDecodedMethodType; -export const LDecodedMethodType = (mutates: boolean, typeParams: $.LTypeParams, self: SelfType, params: $.LParameters, returnType: $d.CType): $.LDecodedMethodType => Object.freeze({ +export type LTMethod = $.LTMethod; +export const LTMethod = (mutates: boolean, typeParams: $.LTypeParams, self: SelfType, params: $.LParameters, returnType: $d.LType): $.LTMethod => Object.freeze({ kind: "DecodedMethodType", mutates, typeParams, @@ -93,65 +87,59 @@ export const LDecodedMethodType = (mutates: boolean, typeParams: $.LTypeParams, params, returnType }); -export const isLDecodedMethodType = ($value: LDecodedMethodType) => $value.kind === "DecodedMethodType"; -export type LMethodSig = $.LMethodSig; -export const LMethodSig = (overridable: boolean, type_: $.LDecodedMethodType, inline: boolean, body: Body, getMethodId: bigint | undefined): $.LMethodSig => Object.freeze({ - overridable, +export const isLTMethod = ($value: LTMethod) => $value.kind === "DecodedMethodType"; +export type LMethod = $.LMethod; +export const LMethod = (type_: $.LTMethod, inline: boolean, body: Body, getMethodId: bigint | undefined): $.LMethod => Object.freeze({ type: type_, inline, body, getMethodId }); -export type LMessageRecv = $.LMessageRecv; -export const LMessageRecv = (name: $c.OptionalId, type_: $d.CTRef, statements: $.LStatements): $.LMessageRecv => Object.freeze({ +export type LReceiverMessage = $.LReceiverMessage; +export const LReceiverMessage = (name: $c.OptionalId, type_: $d.LTBounced | $d.LTRef, statements: $.LStatements): $.LReceiverMessage => Object.freeze({ kind: "binary", name, type: type_, statements }); -export const isLMessageRecv = ($value: LMessageRecv) => $value.kind === "binary"; -export type LMessageAnyRecv = $.LMessageAnyRecv; -export const LMessageAnyRecv = (name: $c.OptionalId, statements: $.LStatements): $.LMessageAnyRecv => Object.freeze({ +export const isLReceiverMessage = ($value: LReceiverMessage) => $value.kind === "binary"; +export type LReceiverAny = $.LReceiverAny; +export const LReceiverAny = (name: $c.OptionalId, statements: $.LStatements): $.LReceiverAny => Object.freeze({ name, statements }); -export type LBounceSig = $.LBounceSig; -export const LBounceSig = (message: readonly $.LMessageRecv[], messageAny: $.LMessageAnyRecv | undefined): $.LBounceSig => Object.freeze({ +export type LBounce = $.LBounce; +export const LBounce = (message: readonly $.LReceiverMessage[], messageAny: $.LReceiverAny | undefined): $.LBounce => Object.freeze({ message, messageAny }); -export type LStringRecv = $.LStringRecv; -export const LStringRecv = (comment: string, statements: $.LStatements): $.LStringRecv => Object.freeze({ +export type LReceiverString = $.LReceiverString; +export const LReceiverString = (comment: string, statements: $.LStatements): $.LReceiverString => Object.freeze({ kind: "string", comment, statements }); -export const isLStringRecv = ($value: LStringRecv) => $value.kind === "string"; -export type LOpcodeRecv = $.LOpcodeRecv; -export type LStringAnyRecv = $.LStringAnyRecv; -export const LStringAnyRecv = (name: $c.OptionalId, statements: $.LStatements): $.LStringAnyRecv => Object.freeze({ - name, - statements -}); -export type LEmptyRecv = $.LEmptyRecv; -export const LEmptyRecv = (statements: $.LStatements): $.LEmptyRecv => Object.freeze({ +export const isLReceiverString = ($value: LReceiverString) => $value.kind === "string"; +export type LReceiverOpcode = $.LReceiverOpcode; +export type LReceiverEmpty = $.LReceiverEmpty; +export const LReceiverEmpty = (statements: $.LStatements): $.LReceiverEmpty => Object.freeze({ statements }); -export type LRecvSig = $.LRecvSig; -export const LRecvSig = (message: readonly $.LOpcodeRecv[], messageAny: $.LMessageAnyRecv | undefined, stringAny: $.LStringAnyRecv | undefined, empty: $.LEmptyRecv | undefined): $.LRecvSig => Object.freeze({ +export type LReceiver = $.LReceiver; +export const LReceiver = (message: readonly $.LReceiverOpcode[], messageAny: $.LReceiverAny | undefined, stringAny: $.LReceiverAny | undefined, empty: $.LReceiverEmpty | undefined): $.LReceiver => Object.freeze({ message, messageAny, stringAny, empty }); export type LReceivers = $.LReceivers; -export const LReceivers = (bounce: $.LBounceSig, internal: $.LRecvSig, external: $.LRecvSig): $.LReceivers => Object.freeze({ +export const LReceivers = (bounce: $.LBounce, internal: $.LReceiver, external: $.LReceiver): $.LReceivers => Object.freeze({ bounce, internal, external }); -export type LCommonSig = $.LCommonSig; -export const LCommonSig = (fieldish: $.LOrdered<$.LFieldish>, methods: ReadonlyMap>, receivers: $.LReceivers): $.LCommonSig => Object.freeze({ +export type LMembers = $.LMembers; +export const LMembers = (fieldish: $c.Ordered<$.LFieldish>, methods: ReadonlyMap>, receivers: $.LReceivers): $.LMembers => Object.freeze({ fieldish, methods, receivers @@ -176,79 +164,74 @@ export const LFiftBody = (shuffle: AsmShuffle, instructions: readonly AsmInstruc }); export const isLFiftBody = ($value: LFiftBody) => $value.kind === "fift"; export type LBody = $.LBody; -export type LContractContent = $.LContractContent; -export type LContractSig = $.LContractSig; -export const LContractSig = (attributes: readonly ContractAttribute[], init: $.LInitSig, content: $.LContractContent): $.LContractSig => Object.freeze({ +export type LContractMembers = $.LContractMembers; +export type LContract = $.LContract; +export const LContract = (attributes: readonly ContractAttribute[], init: $.LInit, content: $.LContractMembers): $.LContract => Object.freeze({ kind: "contract", attributes, init, content }); -export const isLContractSig = ($value: LContractSig) => $value.kind === "contract"; -export type LTraitContent = $.LTraitContent; -export type LTraitSig = $.LTraitSig; -export const LTraitSig = (content: $.LTraitContent): $.LTraitSig => Object.freeze({ +export const isLContract = ($value: LContract) => $value.kind === "contract"; +export type LTraitMembers = $.LTraitMembers; +export type LTrait = $.LTrait; +export const LTrait = (content: $.LTraitMembers): $.LTrait => Object.freeze({ kind: "trait", content }); -export const isLTraitSig = ($value: LTraitSig) => $value.kind === "trait"; -export type LStructSig = $.LStructSig; -export const LStructSig = (typeParams: $.LTypeParams, fields: $.LOrdered<$.LInhFieldSig>): $.LStructSig => Object.freeze({ +export const isLTrait = ($value: LTrait) => $value.kind === "trait"; +export type LStruct = $.LStruct; +export const LStruct = (typeParams: $.LTypeParams, fields: $c.Ordered<$.LField>): $.LStruct => Object.freeze({ kind: "struct", typeParams, fields }); -export const isLStructSig = ($value: LStructSig) => $value.kind === "struct"; -export type LMessageSig = $.LMessageSig; -export const LMessageSig = (opcode: bigint, fields: $.LOrdered<$.LInhFieldSig>): $.LMessageSig => Object.freeze({ +export const isLStruct = ($value: LStruct) => $value.kind === "struct"; +export type LMessage = $.LMessage; +export const LMessage = (opcode: bigint, fields: $c.Ordered<$.LField>): $.LMessage => Object.freeze({ kind: "message", opcode, fields }); -export const isLMessageSig = ($value: LMessageSig) => $value.kind === "message"; -export type LUnionSig = $.LUnionSig; -export const LUnionSig = (typeParams: $.LTypeParams, cases: ReadonlyMap>): $.LUnionSig => Object.freeze({ +export const isLMessage = ($value: LMessage) => $value.kind === "message"; +export type LUnion = $.LUnion; +export const LUnion = (typeParams: $.LTypeParams, cases: ReadonlyMap>): $.LUnion => Object.freeze({ kind: "union", typeParams, cases }); -export const isLUnionSig = ($value: LUnionSig) => $value.kind === "union"; -export type LTypeDeclSig = $.LTypeDeclSig; -export type LDecodedFnType = $.LDecodedFnType; -export const LDecodedFnType = (typeParams: $.LTypeParams, params: $.LParameters, returnType: $d.CType): $.LDecodedFnType => Object.freeze({ +export const isLUnion = ($value: LUnion) => $value.kind === "union"; +export type LTypeDecl = $.LTypeDecl; +export type LTFunction = $.LTFunction; +export const LTFunction = (typeParams: $.LTypeParams, params: $.LParameters, returnType: $d.LType): $.LTFunction => Object.freeze({ kind: "DecodedFnType", typeParams, params, returnType }); -export const isLDecodedFnType = ($value: LDecodedFnType) => $value.kind === "DecodedFnType"; -export type LFnSig = $.LFnSig; -export const LFnSig = (type_: $.LDecodedFnType, inline: boolean, body: $.LBody): $.LFnSig => Object.freeze({ +export const isLTFunction = ($value: LTFunction) => $value.kind === "DecodedFnType"; +export type LFunction = $.LFunction; +export const LFunction = (type_: $.LTFunction, inline: boolean, body: $.LBody): $.LFunction => Object.freeze({ type: type_, inline, body }); -export type LConstSig = $.LConstSig; -export const LConstSig = (initializer: $v.Value, type_: $d.CType): $.LConstSig => Object.freeze({ +export type LConstant = $.LConstant; +export const LConstant = (initializer: $v.Value, type_: $d.LType): $.LConstant => Object.freeze({ initializer, type: type_ }); -export type LExtSig = $.LExtSig; -export const LExtSig = (type_: $.LDecodedMethodType, inline: boolean, body: $.LBody): $.LExtSig => Object.freeze({ +export type LExtension = $.LExtension; +export const LExtension = (type_: $.LTMethod, inline: boolean, body: $.LBody): $.LExtension => Object.freeze({ type: type_, inline, body }); -export type LoweredSource = $.LSource; -export const LoweredSource = (typeDecls: ReadonlyMap, functions: ReadonlyMap, constants: ReadonlyMap, extensions: ReadonlyMap): $.LSource => Object.freeze({ +export type LSource = $.LSource; +export const LSource = (typeDecls: ReadonlyMap, functions: ReadonlyMap, constants: ReadonlyMap, extensions: ReadonlyMap): $.LSource => Object.freeze({ typeDecls, functions, constants, extensions }); -export type LDecodedParameter = $.LDecodedParameter; -export const LDecodedParameter = (name: $c.OptionalId, type_: $d.CType, loc: $c.Loc): $.LDecodedParameter => Object.freeze({ - name, - type: type_, - loc -}); \ No newline at end of file +export type LTypeDeclRefable = $.LTypeDeclRefable; diff --git a/src/next/ast/index.ts b/src/next/ast/index.ts index cf136c094b..52b2b48610 100644 --- a/src/next/ast/index.ts +++ b/src/next/ast/index.ts @@ -12,6 +12,11 @@ export * from "@/next/ast/generated/checked-expr"; export * from "@/next/ast/generated/checked-type"; export * from "@/next/ast/generated/checked-stmt"; +export * from "@/next/ast/generated/lowered"; +export * from "@/next/ast/generated/lowered-expr"; +export * from "@/next/ast/generated/lowered-type"; +export * from "@/next/ast/generated/lowered-stmt"; + export * from "@/next/ast/generated/via"; export * from "@/next/ast/generated/value"; export * from "@/next/ast/generated/effects"; diff --git a/src/next/ast/lazy.ts b/src/next/ast/lazy.ts index be2d2b7ef2..e020bac827 100644 --- a/src/next/ast/lazy.ts +++ b/src/next/ast/lazy.ts @@ -8,11 +8,11 @@ export const printSym = Symbol("print"); export type Thunk = { [printSym]: () => Result; -} & (() => E.WithLog); +} & (() => E.Log); function Thunk( - force: () => E.WithLog, - onOccurs: () => E.WithLog, + force: () => E.Log, + onOccurs: () => E.Log, ): Thunk { let result: Result = "waiting"; function* delayed() { @@ -47,7 +47,7 @@ type Options = { readonly loc: Loc; readonly context: readonly E.TELine[]; readonly recover: T; - readonly callback: (builder: ThunkBuilder) => E.WithLog; + readonly callback: (builder: ThunkBuilder) => E.Log; }; export type ThunkBuilder = (options: Options) => Thunk; diff --git a/src/next/ast/lowered-expr.ts b/src/next/ast/lowered-expr.ts index 089bf00bef..b1401c986a 100644 --- a/src/next/ast/lowered-expr.ts +++ b/src/next/ast/lowered-expr.ts @@ -1,13 +1,12 @@ -import type { Id, Loc, TypeId } from "@/next/ast/common"; +import type { Id, Loc, Ordered, TypeId } from "@/next/ast/common"; import type { BinaryOperation, NumberBase, UnaryOperation, } from "@/next/ast/expression"; -import type { Ordered } from "@/next/ast/checked"; // TODO: this seems incorrect import type { SelfType } from "@/next/ast/type-self"; -import type { LTBasic, LType, LTypeMap, LTypeRef, LTypeTensor, LTypeTuple } from "@/next/ast/lowered-type"; +import type { LTBasic, LType, LTMap, LTRef, LTTensor, LTTuple } from "@/next/ast/lowered-type"; export type LTypeArgs = ReadonlyMap; @@ -19,7 +18,7 @@ export type LExpr = | LStaticCall | LStaticMethodCall | LFieldAccess - | LStructInstance + | LStructCons | LInitOf | LCodeOf | LNumber @@ -156,21 +155,21 @@ export type LStaticMethodCall = { readonly loc: Loc; }; -export type LStructInstance = { +export type LStructCons = { readonly kind: "struct_instance"; readonly fields: Ordered; - readonly computedType: LTypeRef; + readonly computedType: LTRef; readonly loc: Loc; }; export type LMapLiteral = { readonly kind: "map_literal"; - readonly fields: readonly DMapField[]; - readonly computedType: LTypeMap; + readonly fields: readonly LMapField[]; + readonly computedType: LTMap; readonly loc: Loc; }; -export type DMapField = { +export type LMapField = { readonly key: LExpr; readonly value: LExpr; }; @@ -216,13 +215,13 @@ export type LUnit = { export type LTuple = { readonly kind: "tuple"; readonly children: readonly LExpr[]; - readonly computedType: LTypeTuple; + readonly computedType: LTTuple; readonly loc: Loc; }; export type LTensor = { readonly kind: "tensor"; readonly children: readonly LExpr[]; - readonly computedType: LTypeTensor; + readonly computedType: LTTensor; readonly loc: Loc; }; diff --git a/src/next/ast/lowered-stmt.ts b/src/next/ast/lowered-stmt.ts index 2d9caf627c..15c3ea7e0c 100644 --- a/src/next/ast/lowered-stmt.ts +++ b/src/next/ast/lowered-stmt.ts @@ -1,6 +1,5 @@ -import type { Ordered } from "@/next/ast/checked"; import type { LExpr, LLValue } from "@/next/ast/lowered-expr"; -import type { Id, Loc, OptionalId, TypeId } from "@/next/ast/common"; +import type { Id, Loc, OptionalId, Ordered, TypeId } from "@/next/ast/common"; import type { AugmentedAssignOperation } from "@/next/ast/statement"; export type LStmt = @@ -86,11 +85,11 @@ export type LStmtRepeat = { export type LStmtTry = { readonly kind: "try"; readonly statements: LStmtList; - readonly catchBlock: DCatchBlock | undefined; + readonly catchBlock: LCatchBlock | undefined; readonly loc: Loc; }; -export type DCatchBlock = { +export type LCatchBlock = { readonly name: OptionalId; readonly statements: LStmtList; }; @@ -107,13 +106,13 @@ export type LStmtForEach = { export type LStmtDestruct = { readonly kind: "destruct"; readonly type: TypeId; - readonly identifiers: Ordered; + readonly identifiers: Ordered; readonly ignoreUnspecifiedFields: boolean; readonly expression: LExpr; readonly loc: Loc; }; -export type DestructPattern = { +export type LDestructPattern = { readonly field: Id; readonly variable: OptionalId; }; diff --git a/src/next/ast/lowered-type.ts b/src/next/ast/lowered-type.ts index 34e482dd5a..0c62047d89 100644 --- a/src/next/ast/lowered-type.ts +++ b/src/next/ast/lowered-type.ts @@ -2,19 +2,15 @@ import type { CTypeDeclRefable } from "@/next/ast/checked"; import type { Loc, TypeId } from "@/next/ast/common"; import type { BasicType } from "@/next/ast/type-basic"; -export type LNotSet = { - readonly kind: "not-set"; -}; - export type LType = - | LTypeRef - | LTypeAliasRef - | LTypeParamRef - | LTypeMap - | LTypeBounced - | LTypeMaybe - | LTypeTuple - | LTypeTensor + | LTRef + | LTAliasRef + | LTParamRef + | LTMap + | LTBounced + | LTMaybe + | LTTuple + | LTTensor | LTBasic; export type LTBasic = { @@ -23,7 +19,7 @@ export type LTBasic = { readonly loc: Loc; }; -export type LTypeRef = { +export type LTRef = { readonly kind: "type_ref"; readonly name: TypeId; readonly type: CTypeDeclRefable; @@ -33,7 +29,7 @@ export type LTypeRef = { readonly loc: Loc; }; -export type LTypeAliasRef = { +export type LTAliasRef = { readonly kind: "TypeAlias"; readonly name: TypeId; readonly type: LType; @@ -41,39 +37,39 @@ export type LTypeAliasRef = { readonly loc: Loc; }; -export type LTypeParamRef = { +export type LTParamRef = { readonly kind: "TypeParam"; readonly name: TypeId; readonly loc: Loc; }; -export type LTypeBounced = { +export type LTBounced = { readonly kind: "TypeBounced"; // name of the message type readonly name: TypeId; readonly loc: Loc; }; -export type LTypeMaybe = { +export type LTMaybe = { readonly kind: "TypeMaybe"; readonly type: LType; readonly loc: Loc; }; -export type LTypeMap = { +export type LTMap = { readonly kind: "map_type"; readonly key: LType; readonly value: LType; readonly loc: Loc; }; -export type LTypeTuple = { +export type LTTuple = { readonly kind: "tuple_type"; readonly typeArgs: readonly LType[]; readonly loc: Loc; }; -export type LTypeTensor = { +export type LTTensor = { readonly kind: "tensor_type"; readonly typeArgs: readonly LType[]; readonly loc: Loc; diff --git a/src/next/ast/lowered.ts b/src/next/ast/lowered.ts index 3ac43f4246..67e390f7eb 100644 --- a/src/next/ast/lowered.ts +++ b/src/next/ast/lowered.ts @@ -1,7 +1,7 @@ import type { Effects } from "@/next/ast/effects"; import type { LStmt } from "@/next/ast/lowered-stmt"; -import type { FuncId, Loc, OptionalId, TypeId } from "@/next/ast/common"; -import type { LType, LTypeRef, LTypeBounced } from "@/next/ast/lowered-type"; +import type { FuncId, Loc, OptionalId, Ordered, TypeId } from "@/next/ast/common"; +import type { LType, LTRef, LTBounced } from "@/next/ast/lowered-type"; import type { SelfType } from "@/next/ast/type-self"; import type { AsmInstruction, @@ -11,27 +11,33 @@ import type { import type { Value } from "@/next/ast/value"; export type LSource = { - readonly typeDecls: ReadonlyMap; - readonly functions: ReadonlyMap; - readonly constants: ReadonlyMap; - readonly extensions: ReadonlyMap; -}; - -export type LTypeDeclSig = - | LAliasSig - | LContractSig - | LTraitSig - | LStructSig - | LMessageSig - | LUnionSig; - -export type LConstSig = { + readonly typeDecls: ReadonlyMap; + readonly functions: ReadonlyMap; + readonly constants: ReadonlyMap; + readonly extensions: ReadonlyMap; +}; + +export type LTypeDecl = + | LAlias + | LContract + | LTrait + | LStruct + | LMessage + | LUnion; + +export type LTypeDeclRefable = + | LContract + | LStruct + | LMessage + | LUnion; + +export type LConstant = { readonly initializer: Value; readonly type: LType; }; -export type LFnSig = { - readonly type: LDecodedFnType; +export type LFunction = { + readonly type: LTFunction; readonly inline: boolean; readonly body: LBody; }; @@ -57,30 +63,30 @@ export type LFiftBody = { readonly instructions: readonly AsmInstruction[]; }; -export type LExtSig = { - readonly type: LDecodedMethodType; +export type LExtension = { + readonly type: LTMethod; readonly inline: boolean; readonly body: LBody; }; -export type LAliasSig = { +export type LAlias = { readonly kind: "alias"; readonly typeParams: LTypeParams; readonly type: LType; }; -export type LInitSig = LInitEmpty | LInitSimple | LInitFn; +export type LInit = LInitEmpty | LInitSimple | LInitFn; export type LInitEmpty = { readonly kind: "empty"; // initOf() would take 0 parameters // values to fill all the fields - readonly fill: LOrdered; + readonly fill: Ordered; }; export type LInitSimple = { readonly kind: "simple"; // initOf() takes these parameters and // sets them into correspondingly named fields - readonly fill: LOrdered; + readonly fill: Ordered; readonly loc: Loc; }; export type LInitFn = { @@ -95,114 +101,108 @@ export type LInitParam = { readonly loc: Loc; }; -export type LContractSig = { +export type LContract = { readonly kind: "contract"; readonly attributes: readonly ContractAttribute[]; - readonly init: LInitSig; - readonly content: LContractContent; + readonly init: LInit; + readonly content: LContractMembers; }; -export type LContractContent = LCommonSig; -export type LTraitSig = { +export type LContractMembers = LMembers; +export type LTrait = { readonly kind: "trait"; - readonly content: LTraitContent; + readonly content: LTraitMembers; }; -export type LTraitContent = LCommonSig; -export type LCommonSig = { - readonly fieldish: LOrdered>; - readonly methods: ReadonlyMap>; +export type LTraitMembers = LMembers; +export type LMembers = { + readonly fieldish: Ordered>; + readonly methods: ReadonlyMap>; readonly receivers: LReceivers; }; export type LReceivers = { - readonly bounce: LBounceSig; - readonly internal: LRecvSig; - readonly external: LRecvSig; + readonly bounce: LBounce; + readonly internal: LReceiver; + readonly external: LReceiver; }; -export type LFieldish = LInhFieldSig | LFieldConstSig; -export type LInhFieldSig = { +export type LFieldish = LField | LFieldConstant; +export type LField = { readonly kind: "field"; readonly type: LType; readonly init: Value | undefined; }; -export type LFieldConstSig = { +export type LFieldConstant = { readonly kind: "constant"; - readonly overridable: boolean; readonly type: LType; readonly init: Expr; }; -export type LMethodSig = { - readonly overridable: boolean; - readonly type: LDecodedMethodType; +export type LMethod = { + readonly type: LTMethod; readonly inline: boolean; readonly body: Body; readonly getMethodId: bigint | undefined; }; -export type LBounceSig = { +export type LBounce = { // NB! can't compute opcodes until all receivers are present - readonly message: readonly LMessageRecv[]; - readonly messageAny: undefined | LMessageAnyRecv; + readonly message: readonly LReceiverMessage[]; + readonly messageAny: undefined | LReceiverAny; }; -export type LRecvSig = { +export type LReceiver = { // NB! can't compute opcodes until all receivers are present - readonly message: readonly LOpcodeRecv[]; - readonly messageAny: undefined | LMessageAnyRecv; - readonly stringAny: undefined | LStringAnyRecv; - readonly empty: undefined | LEmptyRecv; + readonly message: readonly LReceiverOpcode[]; + readonly messageAny: undefined | LReceiverAny; + readonly stringAny: undefined | LReceiverAny; + readonly empty: undefined | LReceiverEmpty; }; -export type LOpcodeRecv = LMessageRecv | LStringRecv; -export type LMessageRecv = { +export type LReceiverOpcode = LReceiverMessage | LReceiverString; +export type LReceiverMessage = { readonly kind: "binary"; readonly name: OptionalId; - readonly type: LTypeRef | LTypeBounced; + readonly type: LTRef | LTBounced; readonly statements: LStatements; }; -export type LMessageAnyRecv = { +export type LReceiverAny = { readonly name: OptionalId; readonly statements: LStatements; }; -export type LStringRecv = { +export type LReceiverString = { readonly kind: "string"; readonly comment: string; readonly statements: LStatements; }; -export type LStringAnyRecv = { - readonly name: OptionalId; - readonly statements: LStatements; -}; -export type LEmptyRecv = { +export type LReceiverEmpty = { readonly statements: LStatements; }; -export type LStructSig = { +export type LStruct = { readonly kind: "struct"; readonly typeParams: LTypeParams; - readonly fields: LOrdered; + readonly fields: Ordered; }; -export type LMessageSig = { +export type LMessage = { readonly kind: "message"; readonly opcode: bigint; - readonly fields: LOrdered; + readonly fields: Ordered; }; -export type LUnionSig = { +export type LUnion = { readonly kind: "union"; readonly typeParams: LTypeParams; - readonly cases: ReadonlyMap>; + readonly cases: ReadonlyMap>; }; -export type LDecodedFnType = { +export type LTFunction = { readonly kind: "DecodedFnType"; readonly typeParams: LTypeParams; readonly params: LParameters; readonly returnType: LType; }; -export type LDecodedMethodType = { +export type LTMethod = { readonly kind: "DecodedMethodType"; readonly mutates: boolean; readonly typeParams: LTypeParams; @@ -211,28 +211,17 @@ export type LDecodedMethodType = { readonly returnType: LType; }; -export type LDecodedParameter = { +export type LParameter = { readonly name: OptionalId; readonly type: LType; readonly loc: Loc; }; -export type LOrdered = { - readonly order: readonly string[]; - readonly map: ReadonlyMap; -}; - export type LParameters = { readonly order: readonly LParameter[]; readonly set: ReadonlySet; }; -export type LParameter = { - readonly name: OptionalId; - readonly type: LType; - readonly loc: Loc; -}; - export type LTypeParams = { readonly order: readonly TypeId[]; readonly set: ReadonlySet; diff --git a/src/next/types/alias.ts b/src/next/types/alias.ts index c1de48ec6a..71e10464ad 100644 --- a/src/next/types/alias.ts +++ b/src/next/types/alias.ts @@ -8,7 +8,7 @@ export function* decodeAlias( Lazy: Ast.ThunkBuilder, { typeParams, type }: Ast.AliasDecl, scopeRef: () => Ast.CSource, -): Ast.WithLog { +): Ast.Log { const decodedParams = yield* decodeTypeParams(typeParams); return Ast.CAlias( decodedParams, diff --git a/src/next/types/body.ts b/src/next/types/body.ts index a1ba6a7ca4..ce85358d64 100644 --- a/src/next/types/body.ts +++ b/src/next/types/body.ts @@ -7,10 +7,10 @@ import { decodeStatementsLazy } from "@/next/types/statements"; export function* decodeBody( Lazy: Ast.ThunkBuilder, node: Ast.FunctionalBody, - fnType: Ast.CTypeFunction | Ast.CTypeMethod, + fnType: Ast.CTFunction | Ast.CTMethod, loc: Ast.Loc, scopeRef: () => Ast.CSource, -): Ast.WithLog { +): Ast.Log { switch (node.kind) { case "abstract_body": { yield ENoBody(loc); @@ -69,7 +69,7 @@ const ENoBody = (loc: Ast.Loc): Ast.TcError => ({ function* checkShuffle( shuffle: Ast.AsmShuffle, - fnType: Ast.CTypeFunction | Ast.CTypeMethod, + fnType: Ast.CTFunction | Ast.CTMethod, loc: Ast.Loc, scopeRef: () => Ast.CSource, ) { @@ -129,9 +129,9 @@ function* checkShuffle( } function* getRetTupleSize( - { kind, returnType }: Ast.CTypeFunction | Ast.CTypeMethod, + { kind, returnType }: Ast.CTFunction | Ast.CTMethod, scopeRef: () => Ast.CSource, -): Ast.WithLog { +): Ast.Log { const type = yield* returnType(); const baseSize = yield* getTypeTupleSize(type, scopeRef); if (typeof baseSize === "undefined") { diff --git a/src/next/types/builtins.ts b/src/next/types/builtins.ts index badda0657d..9b414b522e 100644 --- a/src/next/types/builtins.ts +++ b/src/next/types/builtins.ts @@ -23,8 +23,8 @@ const Params = (params: Record): Ast.CParameters => { return Ast.CParameters(order, set); }; -const Ref = (name: string): Ast.CTypeParamRef => { - return Ast.CTypeParamRef(Ast.TypeId(name, r), r); +const Ref = (name: string): Ast.CTParamRef => { + return Ast.CTParamRef(Ast.TypeId(name, r), r); }; const mapType = Ast.SVTMap(Ref("K"), Ref("V"), r); @@ -34,10 +34,10 @@ const GenericFn = ( typeParams: readonly string[], params: Record, returnType: Ast.CType, -): [string, Ast.CTypeFunction] => { +): [string, Ast.CTFunction] => { return [ name, - Ast.CTypeFunction( + Ast.CTFunction( TypeParams(typeParams), Params(params), Ast.FakeThunk(returnType), @@ -48,7 +48,7 @@ const Fn = ( name: string, params: Record, returnType: Ast.CType, -): [string, Ast.CTypeFunction] => { +): [string, Ast.CTFunction] => { return GenericFn(name, [], params, returnType); }; const MapMethod = ( @@ -56,10 +56,10 @@ const MapMethod = ( mutates: boolean, params: Record, returnType: Ast.CType, -): [string, Ast.CTypeMethod] => { +): [string, Ast.CTMethod] => { return [ name, - Ast.CTypeMethod( + Ast.CTMethod( mutates, TypeParams(["K", "V"]), mapType, @@ -80,8 +80,8 @@ export const Address = Ast.CTBasic(Ast.TAddress(r), r); export const String = Ast.CTBasic(Ast.TString(r), r); export const StringBuilder = Ast.CTBasic(Ast.TStringBuilder(r), r); export const MapType = (k: Ast.CType, v: Ast.CType) => - Ast.CTypeMap(k, v, r); -export const Maybe = (t: Ast.CType) => Ast.CTypeMaybe(t, r); + Ast.CTMap(k, v, r); +export const Maybe = (t: Ast.CType) => Ast.CTMaybe(t, r); export const Unit = Ast.TUnit(r); export const StateInit = Ast.CTBasic(Ast.TStateInit(r), r); @@ -121,7 +121,7 @@ const BoolAssign = (name: string) => { return Fn(name, { left: Bool, right: Bool }, Void); }; -export const builtinFunctions: Map = new Map([ +export const builtinFunctions: Map = new Map([ // dump(arg: T): Void GenericFn("dump", ["T"], { data: Ref("T") }, Void), // ton(value: String): Int @@ -149,7 +149,7 @@ export const builtinFunctions: Map = new Map([ // sha256(data: Slice | String): Int ]); -export const builtinMethods: Map = new Map([ +export const builtinMethods: Map = new Map([ // set(key: K, value: V): void MapMethod("set", true, { key: Ref("K"), value: Ref("V") }, Void), // get(key: K): Maybe @@ -170,7 +170,7 @@ export const builtinMethods: Map = new Map([ MapMethod("replaceGet", true, { key: Ref("K"), value: Ref("V") }, mapType), ]); -export const builtinUnary: Map = new Map([ +export const builtinUnary: Map = new Map([ Fn("+", { arg: Int }, Int), Fn("-", { arg: Int }, Int), Fn("~", { arg: Int }, Int), @@ -178,7 +178,7 @@ export const builtinUnary: Map = new Map([ GenericFn("!!", ["T"], { arg: Maybe(Ref("T")) }, Ref("T")), ]); -export const builtinBinary: Map = new Map([ +export const builtinBinary: Map = new Map([ // (left: Int, right: Int): Int ArithBin("+"), ArithBin("-"), @@ -203,7 +203,7 @@ export const builtinBinary: Map = new Map([ BoolBin("||"), ]); -export const builtinAugmented: Map = new Map([ +export const builtinAugmented: Map = new Map([ // (left: Int, right: Int): Void; ArithAssign("+="), ArithAssign("-="), @@ -222,7 +222,7 @@ export const builtinAugmented: Map = new Map([ export const getStaticBuiltin = ( type: Ast.CType, -): Map => { +): Map => { return new Map([ // Foo.fromSlice(slice: Slice) Fn("fromSlice", { slice: Slice }, type), diff --git a/src/next/types/constant-def.ts b/src/next/types/constant-def.ts index 5bdda71ed7..4471af1439 100644 --- a/src/next/types/constant-def.ts +++ b/src/next/types/constant-def.ts @@ -74,11 +74,11 @@ export function decodeConstantDef( // resulting type is whatever the type expression has const computedType = Lazy({ callback: function* () { - return (yield* expr())?.value.computedType ?? Ast.CTypeRecover(); + return (yield* expr())?.value.computedType ?? Ast.CTRecover(); }, context: [], loc: defLoc, - recover: Ast.CTypeRecover(), + recover: Ast.CTRecover(), }); return [computedType, lazyExpr]; } diff --git a/src/next/types/constants.ts b/src/next/types/constants.ts index c9dc4a8110..e9a65dbe31 100644 --- a/src/next/types/constants.ts +++ b/src/next/types/constants.ts @@ -12,7 +12,7 @@ export function* decodeConstants( imported: readonly Ast.SourceCheckResult[], source: TactSource, scopeRef: () => Ast.CSource, -): Ast.WithLog>> { +): Ast.Log>> { const allConstSigs = [ // imported ...imported.flatMap(({ globals, importedBy }) => @@ -63,9 +63,9 @@ function* decodeConstant( Ast.TEText("defining constant"), Ast.TECode(constant.loc), ], - recover: Ast.CTypeRecover(), + recover: Ast.CTRecover(), callback: function* () { - return Ast.CTypeRecover(); + return Ast.CTRecover(); }, }); const expr = Lazy({ diff --git a/src/next/types/contract.ts b/src/next/types/contract.ts index ba840c93cb..82d8dc655e 100644 --- a/src/next/types/contract.ts +++ b/src/next/types/contract.ts @@ -95,7 +95,7 @@ function* decodeInit( init: Ast.Init | undefined, contentLazy: () => Ast.Thunk, scopeRef: () => Ast.CSource, -): Ast.WithLog { +): Ast.Log { if (!init) { // no init const lazyInit = Lazy({ @@ -218,7 +218,7 @@ function* getMethodsFromContract( traits: readonly Ast.Decl[], methods: readonly Ast.Method[], scopeRef: () => Ast.CSource, -): Ast.WithLog>>> { +): Ast.Log>>> { const res = yield* getMethodsGeneral( Lazy, contractSig, @@ -248,11 +248,11 @@ function* getFieldishFromContract( contractSig: Ast.CContract, typeName: Ast.TypeId, traits: readonly Ast.Decl[], - init: Ast.CInitSig, + init: Ast.CInit, constants: readonly Ast.FieldConstant[], fields: readonly Ast.FieldDecl[], scopeRef: () => Ast.CSource, -): Ast.WithLog< +): Ast.Log< Ast.Ordered>>>> > { const res = yield* getFieldishGeneral( diff --git a/src/next/types/effects.ts b/src/next/types/effects.ts index 58464cef82..0ba60a6899 100644 --- a/src/next/types/effects.ts +++ b/src/next/types/effects.ts @@ -56,7 +56,7 @@ export const shortCircuitEff = ( export const exitEff = (eff: Ast.Effects): Ast.Effects => ({ ...eff, mustThrow: true }); export const assignEff = (eff: Ast.Effects): Ast.Effects => ({ ...eff, mustThrow: true }); -export function hasStorageAccess(node: Ast.DecodedExpression, selfType: Ast.SelfType | undefined): boolean { +export function hasStorageAccess(node: Ast.CExpr, selfType: Ast.SelfType | undefined): boolean { // looking for `self.x.y.z` if (node.kind === 'field_access') { return hasStorageAccess(node.aggregate, selfType); diff --git a/src/next/types/expr-eval.ts b/src/next/types/expr-eval.ts index 5cce2aba8a..ce6f58c79e 100644 --- a/src/next/types/expr-eval.ts +++ b/src/next/types/expr-eval.ts @@ -3,8 +3,8 @@ import * as Ast from "@/next/ast"; export function* evalExpr( - expr: Ast.DecodedExpression, + expr: Ast.CExpr, scopeRef: () => Ast.CSource, -): Ast.WithLog { +): Ast.Log { return Ast.VNumber(0n, expr.loc); } diff --git a/src/next/types/expression.ts b/src/next/types/expression.ts index f617fd6ef2..f198893b2f 100644 --- a/src/next/types/expression.ts +++ b/src/next/types/expression.ts @@ -27,7 +27,7 @@ import { emptyEff, allEff, shortCircuitEff, anyEff, hasStorageAccess } from "@/n type Decode = ( node: T, ctx: Context, -) => Ast.WithLog>; +) => Ast.Log>; type Result = { readonly value: U; @@ -64,7 +64,7 @@ export function* decodeExpr( return { value: result.value, eff: result.eff }; } -export const decodeExprCtx: Decode = ( +export const decodeExprCtx: Decode = ( node, ctx, ) => { @@ -113,19 +113,19 @@ export const decodeExprCtx: Decode = ( } }; -const decodeNullCons: Decode = function* (node) { - return Result(Ast.DNull(Ast.TBasic(Ast.TNull(node.loc), node.loc), node.loc), emptyEff); +const decodeNullCons: Decode = function* (node) { + return Result(Ast.CNull(Ast.TBasic(Ast.TNull(node.loc), node.loc), node.loc), emptyEff); }; -const decodeUnitCons: Decode = function* (node) { - return Result(Ast.DUnit(Ast.TBasic(Ast.TUnit(node.loc), node.loc), node.loc), emptyEff); +const decodeUnitCons: Decode = function* (node) { + return Result(Ast.CUnit(Ast.TBasic(Ast.TUnit(node.loc), node.loc), node.loc), emptyEff); }; -const decodeStringCons: Decode = function* (node) { - return Result(Ast.DString(node.value, Ast.TBasic(Ast.TString(node.loc), node.loc), node.loc), emptyEff); +const decodeStringCons: Decode = function* (node) { + return Result(Ast.CString(node.value, Ast.TBasic(Ast.TString(node.loc), node.loc), node.loc), emptyEff); }; -const decodeNumberCons: Decode = function* (node) { +const decodeNumberCons: Decode = function* (node) { return Result(Ast.DNumber( node.base, node.value, @@ -134,21 +134,21 @@ const decodeNumberCons: Decode = function* (node) { ), emptyEff); }; -const decodeBooleanCons: Decode = function* (node) { - return Result(Ast.DBoolean(node.value, Ast.TBasic(Ast.TBool(node.loc), node.loc), node.loc), emptyEff); +const decodeBooleanCons: Decode = function* (node) { + return Result(Ast.CBoolean(node.value, Ast.TBasic(Ast.TBool(node.loc), node.loc), node.loc), emptyEff); }; -const decodeTupleCons: Decode = function* (node, ctx) { +const decodeTupleCons: Decode = function* (node, ctx) { const children = yield* Ast.mapLog(node.children, (child) => decodeExprCtx(child, ctx), ); const exprs = children.map((child) => child.value); const argTypes = exprs.map((expr) => expr.computedType); const newEff = allEff(children.map((child) => child.eff)); - return Result(Ast.DTuple(exprs, Ast.CTypeTuple(argTypes, node.loc), node.loc), newEff); + return Result(Ast.CTuple(exprs, Ast.CTTuple(argTypes, node.loc), node.loc), newEff); }; -const decodeTensorCons: Decode = function* ( +const decodeTensorCons: Decode = function* ( node, ctx, ) { @@ -158,10 +158,10 @@ const decodeTensorCons: Decode = function* ( const exprs = children.map((child) => child.value); const argTypes = exprs.map((expr) => expr.computedType); const newEff = allEff(children.map((child) => child.eff)); - return Result(Ast.DTensor(exprs, Ast.CTypeTensor(argTypes, node.loc), node.loc), newEff); + return Result(Ast.CTensor(exprs, Ast.CTTensor(argTypes, node.loc), node.loc), newEff); }; -const decodeMapCons: Decode = function* ( +const decodeMapCons: Decode = function* ( node, ctx, ) { @@ -188,13 +188,13 @@ const decodeMapCons: Decode = function* ( false, ); return Result( - Ast.DMapField(key.value, value.value), + Ast.CMapField(key.value, value.value), allEff([key.eff, value.eff]), ); }); return Result( - Ast.DMapLiteral( + Ast.CMapLiteral( ascribed, fields.map(field => field.value), node.loc, @@ -203,11 +203,11 @@ const decodeMapCons: Decode = function* ( ); }; -const decodeSetCons: Decode = function* () { +const decodeSetCons: Decode = function* () { return throwInternal("Set literals must have been declined before"); }; -const decodeStructCons: Decode = +const decodeStructCons: Decode = function* (node, ctx) { const typeArgs = yield* Ast.mapLog(node.typeArgs, function* (arg) { return yield* decodeTypeLazy( @@ -231,9 +231,9 @@ const decodeStructCons: Decode = ctx, ); return Result( - Ast.DStructInstance( + Ast.CStructCons( fields.value, - instance?.type ?? Ast.CTypeRecover(), + instance?.type ?? Ast.CTRecover(), node.loc, ), fields.eff, @@ -244,8 +244,8 @@ function* checkFields( args: readonly Ast.StructFieldInitializer[], loc: Ast.Loc, ctx: Context, -): Ast.WithLog>>> { - const map: Map> = new Map(); +): Ast.Log>>> { + const map: Map> = new Map(); for (const arg of args) { const fieldName = arg.field.text; @@ -278,7 +278,7 @@ function* checkFields( const effects: Ast.Effects[] = []; const result: Map< string, - Ast.Recover + Ast.Recover > = new Map(); for (const fieldName of typeFields.order) { const field = typeFields.map.get(fieldName); @@ -342,23 +342,23 @@ const EDuplicateField = ( ], }); -const decodeVar: Decode = function* (node, ctx) { +const decodeVar: Decode = function* (node, ctx) { if (node.name !== "self") { const type = yield* lookupVar(node.name, node.loc, ctx); return Result( - Ast.DVar(node.name, type, node.loc), + Ast.CVar(node.name, type, node.loc), emptyEff, ); } if (ctx.selfType) { return Result( - Ast.DSelf(ctx.selfType, node.loc), + Ast.CSelf(ctx.selfType, node.loc), emptyEff, ); } yield ENoSelf(node.loc); return Result( - Ast.DVar(node.name, Ast.TBasic(Ast.TNull(node.loc), node.loc), node.loc), + Ast.CVar(node.name, Ast.TBasic(Ast.TNull(node.loc), node.loc), node.loc), emptyEff, ); }; @@ -370,7 +370,7 @@ function* lookupVar( name: string, loc: Ast.Loc, ctx: Context, -): Ast.WithLog { +): Ast.Log { const local = ctx.localScopeRef.get(name); if (local) { const [type] = local; @@ -381,14 +381,14 @@ function* lookupVar( return yield* global.decl.type(); } yield EUndefined(name, loc); - return Ast.CTypeRecover(); + return Ast.CTRecover(); } const EUndefined = (name: string, loc: Ast.Loc): Ast.TcError => ({ loc, descr: [Ast.TEText(`Variable "${name}" not defined`)], }); -const decodeBinary: Decode = function* ( +const decodeBinary: Decode = function* ( node, ctx, ) { @@ -417,7 +417,7 @@ const decodeBinary: Decode = function* ( ? shortCircuitEff(left.eff, right.eff) : allEff([left.eff, right.eff]); return Result( - Ast.DOpBinary( + Ast.COpBinary( node.op, left.value, right.value, @@ -476,7 +476,7 @@ const supportsEqualityBasic = (common: Ast.BasicType): boolean => { }; -const decodeUnary: Decode = function* (node, ctx) { +const decodeUnary: Decode = function* (node, ctx) { const operand = yield* decodeExprCtx(node.operand, ctx); const fnType = builtinBinary.get(node.op); if (!fnType) { @@ -487,7 +487,7 @@ const decodeUnary: Decode = function* (node, ctx) { ]); return Result( - Ast.DOpUnary( + Ast.COpUnary( node.op, operand.value, typeArgMap, @@ -498,7 +498,7 @@ const decodeUnary: Decode = function* (node, ctx) { ); }; -const decodeTernary: Decode = function* ( +const decodeTernary: Decode = function* ( node, ctx, ) { @@ -518,7 +518,7 @@ const decodeTernary: Decode = function* ( node.loc, ); return Result( - Ast.DConditional( + Ast.CConditional( condition.value, thenBranch.value, elseBranch.value, @@ -535,7 +535,7 @@ const decodeTernary: Decode = function* ( ); }; -const decodeMethodCall: Decode = function* ( +const decodeMethodCall: Decode = function* ( node, ctx, ) { @@ -557,7 +557,7 @@ const decodeMethodCall: Decode = function* ( const selfArgsEff = allEff([self.eff, ...args.map(arg => arg.eff)]); return Result( - Ast.DMethodCall( + Ast.CMethodCall( self.value, node.method, args.map(arg => arg.value), @@ -576,7 +576,7 @@ const decodeMethodCall: Decode = function* ( const decodeFunctionCall: Decode< Ast.StaticCall, - Ast.DStaticCall | Ast.DNumber + Ast.CStaticCall | Ast.CNumber > = function* (node, ctx) { const name = node.function; @@ -602,7 +602,7 @@ const decodeFunctionCall: Decode< ); } else { return Result( - Ast.DStaticCall(name, new Map(), [arg.value], int, node.loc), + Ast.CStaticCall(name, new Map(), [arg.value], int, node.loc), arg.eff, ); } @@ -632,14 +632,14 @@ const decodeFunctionCall: Decode< if (name.text === "throw" || name.text === "nativeThrow") { return Result( - Ast.DStaticCall(name, typeArgMap, exprs, returnType, node.loc), + Ast.CStaticCall(name, typeArgMap, exprs, returnType, node.loc), { ...newEffs, mustThrow: true, }, ); } else { - return Result(Ast.DStaticCall(name, typeArgMap, exprs, returnType, node.loc), newEffs); + return Result(Ast.CStaticCall(name, typeArgMap, exprs, returnType, node.loc), newEffs); } }; const EMismatchSha256 = (loc: Ast.Loc): Ast.TcError => ({ @@ -649,7 +649,7 @@ const EMismatchSha256 = (loc: Ast.Loc): Ast.TcError => ({ const decodeStaticMethodCall: Decode< Ast.StaticMethodCall, - Ast.DStaticMethodCall | Ast.DNull + Ast.CStaticMethodCall | Ast.CNull > = function* (node, ctx) { if (node.typeArgs.length > 0) { yield EFunctionArity(node.loc); @@ -658,15 +658,15 @@ const decodeStaticMethodCall: Decode< const selfDecl = ctx.scopeRef().typeDecls.get(node.self.text); if (!(selfDecl?.decl.kind === "struct" || selfDecl?.decl.kind === "message")) { yield EUndefinedStatic(node.function.text, node.loc); - return Result(Ast.DNull(Ast.TBasic(Ast.TNull(node.loc), node.loc), node.loc), emptyEff); + return Result(Ast.CNull(Ast.TBasic(Ast.TNull(node.loc), node.loc), node.loc), emptyEff); } const builtins = getStaticBuiltin( - Ast.DTypeRef(node.self, selfDecl.decl, [], node.loc), + Ast.CTRef(node.self, selfDecl.decl, [], node.loc), ); const builtin = builtins.get(node.function.text); if (!builtin) { yield EUndefinedStatic(node.function.text, node.loc); - return Result(Ast.DNull(Ast.TBasic(Ast.TNull(node.loc), node.loc), node.loc), emptyEff); + return Result(Ast.CNull(Ast.TBasic(Ast.TNull(node.loc), node.loc), node.loc), emptyEff); } const { returnType, typeArgMap } = yield* checkFnCallWithArgs( ctx.Lazy, @@ -677,7 +677,7 @@ const decodeStaticMethodCall: Decode< ); const newEffs = allEff(args.map(arg => arg.eff)); return Result( - Ast.DStaticMethodCall( + Ast.CStaticMethodCall( node.self, typeArgMap, node.function, @@ -697,7 +697,7 @@ const EFunctionArity = (loc: Ast.Loc): Ast.TcError => ({ descr: [Ast.TEText(`Function doesn't take any generic arguments`)], }); -const decodeFieldAccess: Decode = function* ( +const decodeFieldAccess: Decode = function* ( node, ctx, ) { @@ -705,7 +705,7 @@ const decodeFieldAccess: Decode = function* ( const selfType = expr.value.computedType; const returnType = yield* lookupField(selfType, node.field, ctx.scopeRef); return Result( - Ast.DFieldAccess(expr.value, node.field, returnType, node.loc), + Ast.CFieldAccess(expr.value, node.field, returnType, node.loc), { ...expr.eff, mayRead: hasStorageAccess(expr.value, ctx.selfType) || expr.eff.mayRead, @@ -717,7 +717,7 @@ function* lookupField( selfType: Ast.CType, fieldName: Ast.Id, scopeRef: () => Ast.CSource, -): Ast.WithLog { +): Ast.Log { switch (selfType.kind) { case "type_ref": { const decl = selfType.type; @@ -728,7 +728,7 @@ function* lookupField( const field = fields.map.get(fieldName.text); if (!field) { yield ENoSuchField(fieldName.text, fieldName.loc); - return Ast.CTypeRecover(); + return Ast.CTRecover(); } return yield* field.decl.type(); } @@ -737,13 +737,13 @@ function* lookupField( const field = decl.fields.map.get(fieldName.text); if (!field) { yield ENoSuchField(fieldName.text, fieldName.loc); - return Ast.CTypeRecover(); + return Ast.CTRecover(); } return yield* field.type(); } case "union": { yield ENoSuchField(fieldName.text, fieldName.loc); - return Ast.CTypeRecover(); + return Ast.CTRecover(); } } // linter asks for this unreachable code @@ -754,19 +754,19 @@ function* lookupField( if (type.kind === "recover") { return type; } else { - return Ast.CTypeMaybe(type, fieldName.loc); + return Ast.CTMaybe(type, fieldName.loc); } } case "TypeBounced": { const decl = scopeRef().typeDecls.get(selfType.name.text); if (!decl || decl.decl.kind !== "message") { yield ENoSuchField(fieldName.text, fieldName.loc); - return Ast.CTypeRecover(); + return Ast.CTRecover(); } const field = decl.decl.fields.map.get(fieldName.text); if (!field) { yield ENoSuchField(fieldName.text, fieldName.loc); - return Ast.CTypeRecover(); + return Ast.CTRecover(); } return yield* field.type(); } @@ -781,18 +781,18 @@ function* lookupField( case "tensor_type": case "basic": { yield ENoSuchField(fieldName.text, fieldName.loc); - return Ast.CTypeRecover(); + return Ast.CTRecover(); } } } -const decodeInitOf: Decode = function* (node, ctx) { +const decodeInitOf: Decode = function* (node, ctx) { const args = yield* Ast.mapLog(node.args, (arg) => decodeExprCtx(arg, ctx)); const contract = ctx.scopeRef().typeDecls.get(node.contract.text); if (contract?.decl.kind !== "contract") { yield ENotContract(node.contract.text, node.loc); return Result( - Ast.DInitOf( + Ast.CInitOf( node.contract, args.map(arg => arg.value), StateInit, @@ -807,7 +807,7 @@ const decodeInitOf: Decode = function* (node, ctx) { yield* checkFnCallWithArgs( ctx.Lazy, node.loc, - Ast.CTypeFunction( + Ast.CTFunction( emptyTypeParams, params, ctx.Lazy({ @@ -824,7 +824,7 @@ const decodeInitOf: Decode = function* (node, ctx) { ); return Result( - Ast.DInitOf( + Ast.CInitOf( node.contract, args.map(arg => arg.value), StateInit, @@ -833,7 +833,7 @@ const decodeInitOf: Decode = function* (node, ctx) { allEff(args.map(arg => arg.eff)), ); }; -function* initParams(init: Ast.CInitSig) { +function* initParams(init: Ast.CInit) { switch (init.kind) { case "function": { return init.params; @@ -861,13 +861,13 @@ function* initParams(init: Ast.CInitSig) { } } -const decodeCodeOf: Decode = function* (node, ctx) { +const decodeCodeOf: Decode = function* (node, ctx) { const contract = ctx.scopeRef().typeDecls.get(node.contract.text); if (contract?.decl.kind !== "contract") { yield ENotContract(node.contract.text, node.loc); } return Result( - Ast.DCodeOf( + Ast.CCodeOf( node.contract, Ast.TBasic(Ast.TCell(Ast.SFDefault(node.loc), node.loc), node.loc), node.loc, diff --git a/src/next/types/extensions.ts b/src/next/types/extensions.ts index 3fc1ba20b3..bfc5915ddf 100644 --- a/src/next/types/extensions.ts +++ b/src/next/types/extensions.ts @@ -134,7 +134,7 @@ function* decodeExt( return undefined; } - const methodType = Ast.CTypeMethod( + const methodType = Ast.CTMethod( mutates, decodedFn.typeParams, self, @@ -157,7 +157,7 @@ function* areCompatible( name: string, prevs: readonly Ast.Decl[], next: Ast.Decl, -): Ast.WithLog { +): Ast.Log { for (const prev of prevs) { const prevType = prev.decl.type; const nextType = next.decl.type; @@ -183,8 +183,8 @@ const EMethodOverlap = ( }); function isCompatible( - prev: Ast.CTypeMethod, - next: Ast.CTypeMethod, + prev: Ast.CTMethod, + next: Ast.CTMethod, ) { const prevSelf = prev.self; const nextSelf = next.self; @@ -247,7 +247,7 @@ function allEqual( function* decodeSelfType( type: Ast.CType, scopeRef: () => Ast.CSource, -): Ast.WithLog { +): Ast.Log { switch (type.kind) { case "recover": { return undefined; @@ -376,7 +376,7 @@ function* decodeSelfType( function* toGroundType( type: Ast.CType, scopeRef: () => Ast.CSource, -): Ast.WithLog { +): Ast.Log { switch (type.kind) { case "recover": { return undefined; diff --git a/src/next/types/fields.ts b/src/next/types/fields.ts index 50c943362d..96da867dee 100644 --- a/src/next/types/fields.ts +++ b/src/next/types/fields.ts @@ -12,13 +12,13 @@ type MaybeExpr = Ast.Thunk | undefined; export function* getFieldishGeneral( Lazy: Ast.ThunkBuilder, - traitSigRef: Ast.CTraitSig | Ast.CContract, + traitSigRef: Ast.CTrait | Ast.CContract, typeName: Ast.TypeId, traits: readonly Ast.Decl[], constants: readonly Ast.FieldConstant[], fields: readonly Ast.FieldDecl[], scopeRef: () => Ast.CSource, -): Ast.WithLog>>> { +): Ast.Log>>> { // collect all inherited fields and constants const inherited: Map< string, @@ -195,7 +195,7 @@ function* decodeConstant( nextVia: Ast.ViaMember, scopeRef: () => Ast.CSource, selfType: Ast.SelfType, -): Ast.WithLog>> { +): Ast.Log>> { if (init.kind === "constant_decl") { const type = decodeTypeLazy(Lazy, emptyTypeParams, init.type, scopeRef); return Ast.DeclMem( diff --git a/src/next/types/functions.ts b/src/next/types/functions.ts index f2ac2d889f..6cf4827053 100644 --- a/src/next/types/functions.ts +++ b/src/next/types/functions.ts @@ -13,7 +13,7 @@ export function* decodeFunctions( imported: readonly Ast.SourceCheckResult[], source: TactSource, scopeRef: () => Ast.CSource, -): Ast.WithLog>> { +): Ast.Log>> { const allFnSigs = [ // imported ...imported.flatMap(({ globals, importedBy }) => diff --git a/src/next/types/lower.ts b/src/next/types/lower.ts new file mode 100644 index 0000000000..fbf1263b8b --- /dev/null +++ b/src/next/types/lower.ts @@ -0,0 +1,1133 @@ +/* eslint-disable require-yield */ +import { throwInternal } from "@/error/errors"; +import * as Ast from "@/next/ast"; + +type Lower = (t: T) => Ast.Log + +export const lowerSource: Lower = +function* (node) { + const typeDecls = yield* lowerTypeDecls(node.typeDecls); + const functions = yield* lowerFunctions(node.functions); + const constants = yield* lowerConstants(node.constants); + const extensions = yield* lowerExtensions(node.extensions); + return typeDecls && functions && constants && extensions && + Ast.LSource(typeDecls, functions, constants, extensions); +} + +const lowerTypeDecls: Lower< + ReadonlyMap>, + ReadonlyMap +> = function* (decls) { + let failed = false; + const result: Map = new Map(); + for (const [name, decl] of [...decls]) { + const res = yield* lowerTypeDecl(decl.decl); + if (res) { + result.set(name, res); + } else { + failed = true; + } + } + return failed ? undefined : result; +} + +const lowerTypeDecl: Lower = +function (node) { + switch (node.kind) { + case "alias": return lowerAlias(node); + case "contract": return lowerContract(node); + case "trait": return lowerTrait(node); + case "struct": return lowerStruct(node); + case "message": return lowerMessage(node); + case "union": return lowerUnion(node); + } +} + +const lowerAlias: Lower = +function* (node) { + const type = yield* lowerType(yield* node.type()); + return type && Ast.LAlias(node.typeParams, type); +} + +const lowerContract: Lower = +function* (node) { + const init = yield* lowerInit(node.init); + const members = yield* lowerContractMembers(node.content); + return init && members && Ast.LContract(node.attributes, init, members); +} + +const lowerInit: Lower = function (node) { + switch (node.kind) { + case "function": return lowerInitFunction(node); + case "empty": return lowerInitEmpty(node); + case "simple": return lowerInitSimple(node); + } +} + +const lowerInitFunction: Lower = +function* (node) { + const params = yield* lowerParameters(node.params); + const stmts = yield* lowerStatements(node.statements); + return params && stmts && Ast.LInitFn(params, stmts); +} + +const lowerInitEmpty: Lower = +function* (node) { + const old = yield* node.fill(); + if (!old) { + return undefined; + } + let failed = false; + const map: Map = new Map(); + for (const [name, param] of old.map) { + const res = yield* param(); + if (res) { + map.set(name, res); + } else { + failed = true; + } + } + return failed ? undefined : Ast.LInitEmpty(Ast.Ordered(old.order, map)); +} + +const lowerInitSimple: Lower = +function* (node) { + const map: Map = new Map(); + let failed = false; + for (const [name, field] of node.fill.map) { + const type = yield* lowerType(yield* field.type()); + if (!type) { + failed = true; + } + if (field.init) { + const init = yield* field.init(); + if (!init) { + failed = true; + } + if (init && type) { + map.set(name, Ast.LInitParam(type, init, field.loc)); + } + } else if (type) { + map.set(name, Ast.LInitParam(type, undefined, field.loc)); + } + } + return failed + ? undefined + : Ast.LInitSimple(Ast.Ordered(node.fill.order, map), node.loc); +} + +const lowerContractMembers: Lower< + Ast.Thunk, + Ast.LContractMembers +> = function* (thunk) { + const members = yield* thunk(); + const fieldish = yield* lowerFieldish(members.fieldish); + const methods = yield* lowerMethods(members.methods); + const receivers = yield* lowerReceivers(members.receivers); + return fieldish && methods && receivers && { fieldish, methods, receivers }; +} + +const lowerFieldish: Lower< + Ast.Ordered>>>>, + Ast.Ordered> +> = +function* (node) { + let failed = false; + const map: Map> = new Map(); + for (const [name, { decl }] of node.map) { + switch (decl.kind) { + case "field": { + const field = yield* lowerField(decl); + if (field) { + map.set(name, field); + } else { + failed = true; + } + continue; + } + case "constant": { + const constant = yield* lowerConstant(decl); + if (constant) { + map.set(name, constant); + } else { + failed = true; + } + continue; + } + } + } + return failed ? undefined : Ast.Ordered(node.order, map); +} + +const lowerField: Lower = +function* (node) { + const type = yield* lowerType(yield* node.type()); + if (node.init) { + const init = yield* node.init(); + if (!init) { + return undefined; + } + return type && Ast.LField(type, init); + } else { + return type && Ast.LField(type, undefined); + } +} + +const lowerConstant: Lower< + Ast.CFieldConstant>>, + Ast.LFieldConstant +> = function* (node) { + const init = yield* node.init(); + const type = yield* lowerType(yield* node.type()); + return type && init && Ast.LFieldConstant(type, init); +}; + +const lowerMethods: Lower< + ReadonlyMap>>, + ReadonlyMap> +> = function* (node) { + let failed = false; + const map: Map> = new Map(); + for (const [name, { decl }] of node) { + const type = yield* lowerMethodType(decl.type); + const body = yield* lowerBody(decl.body); + const getMethodId = decl.getMethodId && (yield* decl.getMethodId()); + if (type && body && (!decl.getMethodId || getMethodId)) { + map.set(name, Ast.LMethod( + type, + decl.inline, + body, + getMethodId, + )); + } else { + failed = true; + } + } + return failed ? undefined : map; +} + +const lowerMethodType: Lower = +function* (node) { + const params = yield* lowerParameters(node.params); + const returnType = yield* lowerType(yield* node.returnType()); + return params && returnType && Ast.LTMethod( + node.mutates, + node.typeParams, + node.self, + params, + returnType, + ); +}; + +const lowerBody: Lower = +function (node) { + switch (node.kind) { + case "tact": return lowerBodyTact(node); + case "func": return lowerBodyFunc(node); + case "fift": return lowerBodyFift(node); + } +}; + +const lowerBodyTact: Lower = +function* (node) { + const stmts = yield* lowerStatements(node.statements); + return stmts && Ast.LTactBody(stmts); +} +const lowerBodyFunc: Lower = +function* (node) { + return Ast.LFuncBody(node.nativeName); +} +const lowerBodyFift: Lower = +function* (node) { + const shuffle = yield* node.shuffle(); + return shuffle && Ast.LFiftBody(shuffle, node.instructions); +} + +const lowerReceivers: Lower = +function* (node) { + const bounce = yield* lowerBounce(node.bounce); + const internal = yield* lowerReceiver(node.internal); + const external = yield* lowerReceiver(node.external); + return bounce && internal && external && Ast.LReceivers(bounce, internal, external); +} + +const lowerBounce: Lower = +function* (node) { + const message = yield* mapRecv(lowerRecvMessage)(node.message); + const messageAny = node.messageAny + ? (yield* lowerRecvAny(node.messageAny.decl)) + : undefined; + return typeof message === 'undefined' + ? undefined + : (!node.messageAny || messageAny) && + Ast.LBounce(message, messageAny); +} + +const mapRecv = ( + cb: Lower +): Lower< + readonly Ast.DeclMem[], + readonly U[] +> => +function* (nodes) { + let failed = false; + const message: U[] = []; + for (const { decl } of nodes) { + const res = yield* cb(decl); + if (res) { + message.push(res); + } else { + failed = true; + } + } + return failed ? undefined : message; +}; + +const lowerRecvMessage: Lower< + Ast.CReceiverMessage, + Ast.LReceiverMessage +> = function* (node) { + const statements = yield* lowerStatements(node.statements); + const type = yield* lowerTypeRefOrBounced(node.type); + return statements && type && Ast.LReceiverMessage( + node.name, + type, + statements, + ) +}; + +const lowerTypeRefOrBounced: Lower< + Ast.CTRef | Ast.CTBounced, + Ast.LTRef | Ast.LTBounced +> = function (node) { + switch (node.kind) { + case "type_ref": return lowerTypeRef(node); + case "TypeBounced": return lowerTypeBounced(node); + } +}; + +const lowerReceiver: Lower< + Ast.CReceiver, + Ast.LReceiver +> = function* (node) { + const message = yield* mapRecv(lowerRecvOpcode)(node.message); + const messageAny = node.messageAny + ? (yield* lowerRecvAny(node.messageAny.decl)) + : undefined; + const stringAny = node.stringAny + ? (yield* lowerRecvAny(node.stringAny.decl)) + : undefined; + const empty = node.empty + ? (yield* lowerRecvEmpty(node.empty.decl)) + : undefined; + return typeof message === 'undefined' + ? undefined + : (!node.messageAny || messageAny) && + (!node.stringAny || stringAny) && + Ast.LReceiver(message, messageAny, stringAny, empty); +}; + +const lowerRecvAny: Lower = +function* (node) { + const statements = yield* lowerStatements(node.statements); + if (!statements) { + return undefined; + } + return Ast.LReceiverAny(node.name, statements); +} +const lowerRecvEmpty: Lower = +function* (node) { + const statements = yield* lowerStatements(node.statements); + if (!statements) { + return undefined; + } + return Ast.LReceiverEmpty(statements); +} + +const lowerRecvOpcode: Lower< + Ast.CReceiverOpcode, + Ast.LReceiverOpcode +> = function* (node) { + switch (node.kind) { + case "string": { + const statements = yield* lowerStatements(node.statements); + return statements && Ast.LReceiverString(node.comment, statements); + } + case "binary": { + const type = yield* lowerTypeRefOrBounced(node.type); + const statements = yield* lowerStatements(node.statements); + return type && statements && Ast.LReceiverMessage(node.name, type, statements); + } + } +}; + +const lowerTrait: Lower = +function* (node) { + const content = yield* node.content(); + const fieldish = yield* lowerFieldishTrait(content.fieldish); + const methods = yield* lowerMethodsTrait(content.methods); + const receivers = yield* lowerReceivers(content.receivers); + return fieldish && methods && receivers && Ast.LTrait({ fieldish, methods, receivers }); +} + +const lowerMethodsTrait: Lower< + ReadonlyMap>>, + ReadonlyMap> +> = function* (node) { + let failed = false; + const map: Map> = new Map(); + for (const [name, { decl }] of node) { + const type = yield* lowerMethodType(decl.type); + const body = decl.body ? (yield* lowerBody(decl.body)) : undefined; + const getMethodId = decl.getMethodId && (yield* decl.getMethodId()); + if (type && (!decl.body || body) && (!decl.getMethodId || getMethodId)) { + map.set(name, Ast.LMethod( + type, + decl.inline, + body, + getMethodId, + )); + } else { + failed = true; + } + } + return failed ? undefined : map; +} + +const lowerFieldishTrait: Lower< + Ast.Ordered>>>>, + Ast.Ordered> +> = +function* (node) { + let failed = false; + const map: Map> = new Map(); + for (const [name, { decl }] of node.map) { + switch (decl.kind) { + case "field": { + const field = yield* lowerField(decl); + if (field) { + map.set(name, field); + } else { + failed = true; + } + continue; + } + case "constant": { + const constant = yield* lowerConstantTrait(decl); + if (constant) { + map.set(name, constant); + } else { + failed = true; + } + continue; + } + } + } + return failed ? undefined : Ast.Ordered(node.order, map); +} + +const lowerConstantTrait: Lower< + Ast.CFieldConstant> | undefined>, + Ast.LFieldConstant +> = function* (node) { + const init = node.init ? (yield* node.init()) : undefined; + const type = yield* lowerType(yield* node.type()); + return type && (!node.init || init) && Ast.LFieldConstant(type, init); +}; + +const lowerStruct: Lower = +function* (node) { + const fields = yield* lowerFields(node.fields); + return fields && Ast.LStruct(node.typeParams, fields); +} + +const lowerFields: Lower, Ast.Ordered> = +function* (node) { + let failed = false; + const map: Map = new Map(); + for (const [name, field] of node.map) { + const type = yield* lowerType(yield* field.type()); + const init = field.init ? (yield* field.init()) : undefined; + if (type && (!field.init || init)) { + map.set(name, Ast.LField(type, init)); + } else { + failed = true; + } + } + return failed ? undefined : Ast.Ordered(node.order, map); +} + +const lowerMessage: Lower = +function* (node) { + const opcode = yield* node.opcode(); + const fields = yield* lowerFields(node.fields); + return typeof opcode === 'undefined' + ? undefined + : fields && Ast.LMessage(opcode, fields); +} + +const lowerUnion: Lower = +function* (node) { + let failed = false; + const cases: Map> = new Map(); + for (const [caseName, rawFields] of node.cases) { + const fields: Map = new Map(); + for (const [fieldName, field] of rawFields) { + const type = yield* lowerType(yield* field.type()); + const init = field.init ? (yield* field.init()) : undefined; + if (type && (!field.init || init)) { + fields.set(fieldName, Ast.LField(type, init)); + } else { + failed = true; + } + } + cases.set(caseName, fields); + } + return failed ? undefined : Ast.LUnion(node.typeParams, cases); +} + +const lowerFunctions: Lower< + ReadonlyMap>, + ReadonlyMap +> = function* (decls) { + let failed = false; + const result: Map = new Map(); + for (const [name, { decl }] of decls) { + const type = yield* lowerFunctionType(decl.type); + const body = yield* lowerBody(decl.body); + if (type && body) { + result.set(name, Ast.LFunction(type, decl.inline, body)); + } else { + failed = true; + } + } + return failed ? undefined : result; +} + +const lowerFunctionType: Lower = function* (node) { + const params = yield* lowerParameters(node.params); + const returnType = yield* lowerType(yield* node.returnType()); + return params && returnType && Ast.LTFunction(node.typeParams, params, returnType); +} + +const lowerConstants: Lower< + ReadonlyMap>, + ReadonlyMap +> = function* (decls) { + let failed = false; + const result: Map = new Map(); + for (const [name, { decl }] of decls) { + const type = yield* lowerType(yield* decl.type()); + const initializer = yield* decl.initializer(); + if (type && initializer) { + result.set(name, Ast.LConstant(initializer, type)); + } else { + failed = true; + } + } + return failed ? undefined : result; +} + +const lowerExtensions: Lower< + ReadonlyMap[]>>, + ReadonlyMap +> = function* (decls) { + let failed = false; + const result: Map = new Map(); + for (const [name, thunk] of decls) { + const extensions = yield* thunk(); + const exts: Ast.LExtension[] = []; + for (const { decl: extension } of extensions) { + const type = yield* lowerMethodType(extension.type); + const body = yield* lowerBody(extension.body); + if (type && body) { + exts.push(Ast.LExtension(type, extension.inline, body)); + } else { + failed = true; + } + } + result.set(name, exts); + } + return failed ? undefined : result; +} + +const lowerStatements: Lower = +function* (node) { + const stmts = yield* node(); + if (!stmts) { + return undefined; + } + const body = yield* lowerStatementList(stmts.body); + return typeof body === 'undefined' + ? undefined + : Ast.LStatements(body, stmts.effects); +} + +const lowerStatementList: Lower = +function* (stmts) { + let failed = false; + const result: Ast.LStmt[] = []; + for (const stmt of stmts) { + const lowered = yield* lowerStatement(stmt); + if (lowered) { + result.push(lowered); + } else { + failed = true; + } + } + return failed ? undefined : result; +} + +const lowerStatement: Lower = +function (node) { + switch (node.kind) { + case "statement_let": return lowerStatementLet(node); + case "statement_return": return lowerStatementReturn(node); + case "statement_expression": return lowerStatementExpression(node); + case "statement_assign": return lowerStatementAssign(node); + case "statement_augmentedassign": return lowerStatementAugmentedAssign(node); + case "statement_condition": return lowerStatementCondition(node); + case "statement_while": return lowerStatementWhile(node); + case "statement_until": return lowerStatementUntil(node); + case "statement_repeat": return lowerStatementRepeat(node); + case "statement_try": return lowerStatementTry(node); + case "statement_foreach": return lowerStatementForEach(node); + case "statement_destruct": return lowerStatementDestruct(node); + case "statement_block": return lowerStatementBlock(node); + } +} + +const lowerStatementLet: Lower = +function* (node) { + const expr = yield* lowerExpr(node.expression); + return expr && Ast.LStmtLet(node.name, expr, node.loc); +} + +const lowerStatementReturn: Lower = +function* (node) { + const expr = node.expression ? (yield* lowerExpr(node.expression)) : undefined; + return (!node.expression || expr) && Ast.LStmtReturn(expr, node.loc); +} + +const lowerStatementExpression: Lower = +function* (node) { + const expr = yield* lowerExpr(node.expression); + return expr && Ast.LStmtExpression(expr, node.loc); +} + +const lowerStatementAssign: Lower = +function* (node) { + const path = yield* lowerLValue(node.path); + const expr = yield* lowerExpr(node.expression); + return path && expr && Ast.LStmtAssign(path, expr, node.loc); +} + +const lowerStatementAugmentedAssign: Lower = +function* (node) { + const path = yield* lowerLValue(node.path); + const expr = yield* lowerExpr(node.expression); + return path && expr && Ast.LStmtAugmentedAssign(node.op, path, expr, node.loc); +} + +const lowerStatementCondition: Lower = +function* (node) { + const condition = yield* lowerExpr(node.condition); + const thenBranch = yield* lowerStatementList(node.trueStatements); + const elseBranch = node.falseStatements + ? (yield* lowerStatementList(node.falseStatements)) + : undefined; + return condition && thenBranch && (!node.falseStatements || elseBranch) && + Ast.LStmtCondition(condition, thenBranch, elseBranch, node.loc); +} + +const lowerStatementWhile: Lower = +function* (node) { + const condition = yield* lowerExpr(node.condition); + const body = yield* lowerStatementList(node.statements); + return condition && body && Ast.LStmtWhile(condition, body, node.loc); +} + +const lowerStatementUntil: Lower = +function* (node) { + const condition = yield* lowerExpr(node.condition); + const body = yield* lowerStatementList(node.statements); + return condition && body && Ast.LStmtUntil(condition, body, node.loc); +} + +const lowerStatementRepeat: Lower = +function* (node) { + const body = yield* lowerStatementList(node.statements); + const iterations = yield* lowerExpr(node.iterations); + return body && iterations && Ast.LStmtRepeat(iterations, body, node.loc); +} + +const lowerStatementTry: Lower = +function* (node) { + const body = yield* lowerStatementList(node.statements); + const catchBlock = node.catchBlock + ? (yield* lowerCatchBlock(node.catchBlock)) + : undefined; + return body && (!node.catchBlock || catchBlock) && + Ast.LStmtTry(body, catchBlock, node.loc); +} + +const lowerCatchBlock: Lower = +function* (node) { + const body = yield* lowerStatementList(node.statements); + return body && Ast.LCatchBlock(node.name, body); +} + +const lowerStatementForEach: Lower = +function* (node) { + const expr = yield* lowerExpr(node.map); + const body = yield* lowerStatementList(node.statements); + return expr && body && Ast.LStmtForEach(node.keyName, node.valueName, expr, body, node.loc); +} + +const lowerStatementDestruct: Lower = +function* (node) { + const expr = yield* lowerExpr(node.expression); + const patterns = yield* lowerDestructPatterns(node.identifiers); + return expr && patterns && Ast.LStmtDestruct( + node.type, + patterns, + node.ignoreUnspecifiedFields, + expr, + node.loc, + ); +} + +const lowerDestructPatterns: Lower< + Ast.Ordered, + Ast.Ordered +> = function* (patterns) { + return patterns; +} + +const lowerStatementBlock: Lower = +function* (node) { + const body = yield* lowerStatementList(node.statements); + return body && Ast.LStmtBlock(body, node.loc); +} + +const lowerParameters: Lower = +function* (node) { + const order = yield* Ast.mapLog(node.order, param => lowerParameter(param)); + const filtered: Ast.LParameter[] = []; + let failed = false; + for (const param of order) { + if (param) { + filtered.push(param); + } else { + failed = true; + } + } + return failed + ? undefined + : order && Ast.LParameters(filtered, node.set); +} + +const lowerLValue: Lower = +function (node) { + switch (node.kind) { + case "var": return lowerLVar(node); + case "self": return lowerLSelf(node); + case "field_access": return lowerLFieldAccess(node); + } +} + +const lowerLVar: Lower = +function* (node) { + const type = yield* lowerType(node.computedType); + return type && Ast.LLVar(node.name, type, node.loc); +} + +const lowerLSelf: Lower = +function* (node) { + return Ast.LLSelf(node.computedType, node.loc); +} + +const lowerLFieldAccess: Lower = +function* (node) { + const aggregate = yield* lowerLValue(node.aggregate); + const type = yield* lowerType(node.computedType); + return aggregate && type && + Ast.LLFieldAccess(aggregate, node.field, type, node.loc); +} + +const lowerExpr: Lower = +function (node) { + switch (node.kind) { + case "string": return lowerString(node); + case "number": return lowerNumber(node); + case "boolean": return lowerBoolean(node); + case "op_binary": return lowerOpBinary(node); + case "op_unary": return lowerOpUnary(node); + case "conditional": return lowerConditional(node); + case "method_call": return lowerMethodCall(node); + case "static_call": return lowerStaticCall(node); + case "static_method_call": return lowerStaticMethodCall(node); + case "field_access": return lowerFieldAccess(node); + case "struct_instance": return lowerStructInstance(node); + case "init_of": return lowerInitOf(node); + case "code_of": return lowerCodeOf(node); + case "null": return lowerNull(node); + case "var": return lowerVar(node); + case "self": return lowerSelf(node); + case "unit": return lowerUnit(node); + case "tuple": return lowerTuple(node); + case "tensor": return lowerTensor(node); + case "map_literal": return lowerMapLiteral(node); + case "set_literal": return lowerSetLiteral(node); + } +} + +const lowerTypeArgs: Lower = +function* (args) { + let failed = false; + const map: Map = new Map(); + for (const [name, type] of args) { + const res = yield* lowerType(type); + if (res) { + map.set(name, res); + } else { + failed = true; + } + } + return failed ? undefined : map; +}; + +const lowerExprs: Lower = +function* (nodes) { + let failed = false; + const result: Ast.LExpr[] = []; + for (const node of nodes) { + const res = yield* lowerExpr(node); + if (res) { + result.push(res); + } else { + failed = true; + } + } + return failed ? undefined : result; +}; + +const lowerString: Lower = +function* (node) { + const type = yield* lowerTypeBasic(node.computedType); + return type && Ast.LString(node.value, type, node.loc); +} +const lowerNumber: Lower = +function* (node) { + const type = yield* lowerTypeBasic(node.computedType); + return type && Ast.LNumber(node.base, node.value, type, node.loc); +} +const lowerBoolean: Lower = +function* (node) { + const type = yield* lowerTypeBasic(node.computedType); + return type && Ast.LBoolean(node.value, type, node.loc); +} +const lowerOpBinary: Lower = +function* (node) { + const left = yield* lowerExpr(node.left); + const right = yield* lowerExpr(node.right); + const typeArgs = yield* lowerTypeArgs(node.typeArgs); + const type = yield* lowerType(node.computedType); + return left && right && type && typeArgs && + Ast.LOpBinary( + node.op, + left, + right, + typeArgs, + type, + node.loc, + ); +} +const lowerOpUnary: Lower = +function* (node) { + const operand = yield* lowerExpr(node.operand); + const typeArgs = yield* lowerTypeArgs(node.typeArgs); + const type = yield* lowerType(node.computedType); + return operand && type && typeArgs && + Ast.LOpUnary( + node.op, + operand, + typeArgs, + type, + node.loc, + ); +} +const lowerConditional: Lower = +function* (node) { + const condition = yield* lowerExpr(node.condition); + const thenBranch = yield* lowerExpr(node.thenBranch); + const elseBranch = yield* lowerExpr(node.elseBranch); + const type = yield* lowerType(node.computedType); + return condition && thenBranch && elseBranch && type && + Ast.LConditional(condition, thenBranch, elseBranch, type, node.loc); +} +const lowerMethodCall: Lower = +function* (node) { + const self = yield* lowerExpr(node.self); + const typeArgs = yield* lowerTypeArgs(node.typeArgs); + const args = yield* lowerExprs(node.args); + const computedType = yield* lowerType(node.computedType); + return self && typeArgs && args && computedType && + Ast.LMethodCall( + self, + node.method, + args, + typeArgs, + computedType, + node.loc, + ); +} +const lowerStaticCall: Lower = +function* (node) { + const typeArgs = yield* lowerTypeArgs(node.typeArgs); + const args = yield* lowerExprs(node.args); + const computedType = yield* lowerType(node.computedType); + return typeArgs && args && computedType && + Ast.LStaticCall( + node.function, + typeArgs, + args, + computedType, + node.loc, + ); +} +const lowerStaticMethodCall: Lower = +function* (node) { + const typeArgs = yield* lowerTypeArgs(node.typeArgs); + const args = yield* lowerExprs(node.args); + const computedType = yield* lowerType(node.computedType); + return typeArgs && args && computedType && + Ast.LStaticMethodCall( + node.self, + typeArgs, + node.function, + args, + computedType, + node.loc, + ); +} +const lowerFieldAccess: Lower = +function* (node) { + const aggregate = yield* lowerExpr(node.aggregate); + const type = yield* lowerType(node.computedType); + return aggregate && type && + Ast.LFieldAccess( + aggregate, + node.field, + type, + node.loc, + ); +} +const lowerStructInstance: Lower = +function* (node) { + if (node.computedType.kind === 'recover') { + return undefined; + } + const type = yield* lowerTypeRef(node.computedType); + const result: Map = new Map(); + let failed = false; + for (const name of node.fields.order) { + const field = node.fields.map.get(name); + if (!field) { + return throwInternal("Ordered<>: lost field"); + } + const res = yield* lowerExpr(field); + if (res) { + result.set(name, res); + } else { + failed = true; + } + } + return failed ? undefined : type && + Ast.LStructCons( + Ast.Ordered(node.fields.order, result), + type, + node.loc, + ); +} +const lowerInitOf: Lower = +function* (node) { + const type = yield* lowerType(node.computedType); + const fields = yield* Ast.mapLog(node.fields, lowerExpr); + return type && fields && + Ast.LInitOf( + node.name, + type, + fields, + node.loc, + ); +} +const lowerCodeOf: Lower = +function* (node) { + const type = yield* lowerType(node.computedType); + const fields = yield* Ast.mapLog(node.fields, lowerExpr); + return type && fields && + Ast.LCodeOf( + node.name, + type, + fields, + node.loc, + ); +} +const lowerNull: Lower = +function* (node) { + const type = yield* lowerType(node.computedType); + return type && Ast.LNull(type, node.loc); +} +const lowerVar: Lower = +function* (node) { + const type = yield* lowerType(node.computedType); + return type && Ast.LVar(node.name, type, node.loc); +} +const lowerSelf: Lower = +function* (node) { + const type = yield* lowerType(node.computedType); + return type && Ast.LSelf(type, node.loc); +} +const lowerUnit: Lower = +function* (node) { + const type = yield* lowerType(node.computedType); + return type && Ast.LUnit(type, node.loc); +} +const lowerTuple: Lower = +function* (node) { + const type = yield* lowerType(node.computedType); + const elements = yield* Ast.mapLog(node.elements, lowerExpr); + return type && elements && + Ast.LTuple( + node.name, + type, + elements, + node.loc, + ); +} +const lowerTensor: Lower = +function* (node) { + const type = yield* lowerType(node.computedType); + const elements = yield* Ast.mapLog(node.elements, lowerExpr); + return type && elements && + Ast.LTensor( + node.name, + type, + node.dimensions, + elements, + node.loc, + ); +} +const lowerMapLiteral: Lower = +function* (node) { + const type = yield* lowerType(node.computedType); + const entries = yield* Ast.mapLog(node.entries, entry => { + return Ast.mapLog(entry, lowerExpr); + }); + return type && entries && + Ast.LMapLiteral( + node.name, + type, + entries, + node.loc, + ); +} +const lowerSetLiteral: Lower = +function* (node) { + const type = yield* lowerType(node.computedType); + const elements = yield* Ast.mapLog(node.elements, lowerExpr); + return type && elements && + Ast.LSetLiteral( + node.name, + type, + elements, + node.loc, + ); +} + +const lowerParameter: Lower = +function* (node) { + const type = yield* lowerType(yield* node.type()); + return type && Ast.LParameter(node.name, type, node.loc); +} + +const lowerType: Lower = +function* (node) { + switch (node.kind) { + case "recover": return undefined; + case "type_ref": return lowerTypeRef(node); + case "TypeAlias": return lowerTypeAliasRef(node); + case "TypeParam": return lowerTypeParam(node); + case "map_type": return lowerTypeMap(node); + case "TypeBounced": return lowerTypeBounced(node); + case "TypeMaybe": return lowerTypeMaybe(node); + case "tuple_type": return lowerTypeTuple(node); + case "tensor_type": return lowerTypeTensor(node); + case "basic": return lowerTypeBasic(node); + } +} + +const lowerTypes: Lower = +function* (nodes) { + let failed = false; + const result: Ast.LType[] = []; + for (const node of nodes) { + const res = yield* lowerType(node); + if (res) { + result.push(res); + } else { + failed = true; + } + } + return failed ? undefined : result; +}; + +const lowerTypeRef: Lower = +function* (node) { + const args = yield* lowerTypes(node.typeArgs); + return args && Ast.LTRef(node.name, node.type, args, node.loc); +}; + +const lowerTypeAliasRef: Lower = +function* (node) { + if (node.type.kind === 'NotDealiased') { + return throwInternal("Non-dealiased type in lowering"); + } + const type = yield* lowerType(node.type); + const args = yield* lowerTypes(node.typeArgs); + return type && args && Ast.LTAliasRef(node.name, type, args, node.loc); +}; +const lowerTypeParam: Lower = +function* (node) { + return Ast.LTParamRef(node.name, node.loc); +}; +const lowerTypeMap: Lower = +function* (node) { + const key = yield* lowerType(node.key); + const value = yield* lowerType(node.value); + return key && value && Ast.LTMap(key, value, node.loc); +}; +const lowerTypeBounced: Lower = +function* (node) { + return Ast.LTBounced(node.name, node.loc); +}; +const lowerTypeMaybe: Lower = +function* (node) { + const type = yield* lowerType(node.type); + return type && Ast.LTMaybe(type, node.loc); +}; +const lowerTypeTuple: Lower = +function* (node) { + const args = yield* lowerTypes(node.typeArgs); + return args && Ast.LTTuple(args, node.loc); +}; +const lowerTypeTensor: Lower = +function* (node) { + const args = yield* lowerTypes(node.typeArgs); + return args && Ast.LTTensor(args, node.loc); +}; +const lowerTypeBasic: Lower = +function* (node) { + return Ast.LTBasic(node.type, node.loc); +}; \ No newline at end of file diff --git a/src/next/types/lvalue.ts b/src/next/types/lvalue.ts index 8ce1a5591a..695f0d35c9 100644 --- a/src/next/types/lvalue.ts +++ b/src/next/types/lvalue.ts @@ -2,8 +2,8 @@ import * as Ast from "@/next/ast"; export function* convertExprToLValue( - node: Ast.DecodedExpression, -): Ast.WithLog { + node: Ast.CExpr, +): Ast.Log { const result = yield* convertExprToLValueAux(node); if (result?.kind === 'self') { yield ENoSelfAssign(node.loc); @@ -17,15 +17,15 @@ const ENoSelfAssign = (loc: Ast.Loc): Ast.TcError => ({ }); function* convertExprToLValueAux( - node: Ast.DecodedExpression, -): Ast.WithLog { + node: Ast.CExpr, +): Ast.Log { switch (node.kind) { case "field_access": { const aggregate = yield* convertExprToLValue(node.aggregate); // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition return ( aggregate && - Ast.LFieldAccess( + Ast.CLFieldAccess( aggregate, node.field, node.computedType, diff --git a/src/next/types/message.ts b/src/next/types/message.ts index d3e28de300..c1cd323c7c 100644 --- a/src/next/types/message.ts +++ b/src/next/types/message.ts @@ -14,7 +14,7 @@ export function* decodeMessage( Lazy: Ast.ThunkBuilder, message: Ast.MessageDecl, scopeRef: () => Ast.CSource, -): Ast.WithLog { +): Ast.Log { const fields = yield* decodeFields( Lazy, message.fields, diff --git a/src/next/types/methods.ts b/src/next/types/methods.ts index 4132aa5b3d..b6d5c34949 100644 --- a/src/next/types/methods.ts +++ b/src/next/types/methods.ts @@ -13,12 +13,12 @@ import { emptyTypeParams } from "@/next/types/type-params"; export function* getMethodsGeneral( Lazy: Ast.ThunkBuilder, - declSig: Ast.CTraitSig | Ast.CContract, + declSig: Ast.CTrait | Ast.CContract, typeName: Ast.TypeId, traits: readonly Ast.Decl[], methods: readonly Ast.Method[], scopeRef: () => Ast.CSource, -): Ast.WithLog< +): Ast.Log< ReadonlyMap>> > { // collect all inherited methods @@ -57,7 +57,7 @@ export function* getMethodsGeneral( const decodedFn = yield* decodeFnType(Lazy, type, scopeRef); const selfType = Ast.SVTRef(typeName, declSig, [], loc); - const methodType = Ast.CTypeMethod( + const methodType = Ast.CTMethod( true, // always mutates emptyTypeParams, selfType, @@ -147,7 +147,7 @@ function* decodeGet( get: Ast.GetAttribute, scopeRef: () => Ast.CSource, selfType: Ast.SelfType, -): Ast.WithLog { +): Ast.Log { if (get.methodId) { const expr = yield* decodeExpr( Lazy, diff --git a/src/next/types/override.ts b/src/next/types/override.ts index 397a4ebb3e..09ccd975af 100644 --- a/src/next/types/override.ts +++ b/src/next/types/override.ts @@ -12,7 +12,7 @@ export function* checkFieldOverride( nextType: Ast.Thunk, nextVia: Ast.ViaMember, override: boolean, -): Ast.WithLog { +): Ast.Log { if (prev) { if (prev.decl.kind !== "constant") { // cannot override field with constant @@ -46,10 +46,10 @@ export function* checkFieldOverride( export function* checkMethodOverride( name: string, prev: Ast.DeclMem> | undefined, - nextType: Ast.CTypeMethod, + nextType: Ast.CTMethod, nextVia: Ast.ViaMember, override: boolean, -): Ast.WithLog { +): Ast.Log { if (prev) { if (override) { // overriding without override diff --git a/src/next/types/receivers.ts b/src/next/types/receivers.ts index 5ab8a982d8..9efb290407 100644 --- a/src/next/types/receivers.ts +++ b/src/next/types/receivers.ts @@ -13,7 +13,7 @@ export function* getReceivers( traits: readonly Ast.Decl[], receivers: readonly Ast.Receiver[], scopeRef: () => Ast.CSource, -): Ast.WithLog { +): Ast.Log { const impExternals: Ast.Decl[] = []; const impInternals: Ast.Decl[] = []; const impBounces: Ast.Decl[] = []; @@ -90,7 +90,7 @@ function* mergeReceivers( readonly [Ast.ReceiverSubKind, readonly Ast.Statement[]] >[], scopeRef: () => Ast.CSource, -): Ast.WithLog { +): Ast.Log { const allMessage: Ast.DeclMem[] = []; let allMessageAny: undefined | Ast.DeclMem; let allStringAny: undefined | Ast.DeclMem; @@ -259,7 +259,7 @@ function* mergeBounce( [Ast.TypedParameter, readonly Ast.Statement[]] >[], scopeRef: () => Ast.CSource, -): Ast.WithLog { +): Ast.Log { const allMessage: Ast.DeclMem[] = []; let allMessageAny: undefined | Ast.DeclMem; diff --git a/src/next/types/statements.ts b/src/next/types/statements.ts index 5802a9e8c3..6f41a67f32 100644 --- a/src/next/types/statements.ts +++ b/src/next/types/statements.ts @@ -56,9 +56,9 @@ export function decodeStatementsLazy( const decodeStmts: Decode< readonly Ast.Statement[], - readonly Ast.DecodedStatement[] + readonly Ast.CStmt[] > = function* (nodes, ctx, eff) { - const results: Ast.DecodedStatement[] = []; + const results: Ast.CStmt[] = []; let state = [ctx, eff] as const; for (const node of nodes) { const result = yield* decodeStatement(node, ctx, eff); @@ -69,7 +69,7 @@ const decodeStmts: Decode< return Result(results, context, effects); }; -const decodeStatement: Decode = function ( +const decodeStatement: Decode = function ( stmt, ctx, eff, @@ -104,13 +104,13 @@ const decodeStatement: Decode = function ( } }; -const decodeLet: Decode = function* ( +const decodeLet: Decode = function* ( node, ctx, eff, ) { const expr = yield* decodeExprCtx(node.expression, ctx); - const result = Ast.DStatementLet(node.name, expr.value, node.loc); + const result = Ast.CStmtLet(node.name, expr.value, node.loc); if (node.type) { const ascribed = yield* decodeType( ctx.typeParams, @@ -132,7 +132,7 @@ const decodeLet: Decode = function* ( } }; -const decodeReturn: Decode = function* (node, ctx, eff) { +const decodeReturn: Decode = function* (node, ctx, eff) { if (ctx.required) { const missing = [...ctx.required].filter((p) => !eff.mustSetSelf.has(p)); for (const fieldName of missing) { @@ -141,7 +141,7 @@ const decodeReturn: Decode = function } const expr = yield* checkReturnExpr(node.expression, ctx); return Result( - Ast.DStatementReturn(expr?.value, node.loc), + Ast.CStmtReturn(expr?.value, node.loc), ctx, exitEff(expr ? expr.eff : emptyEff), ); @@ -170,11 +170,11 @@ function* checkReturnExpr(node: Ast.Expression | undefined, ctx: Context) { const decodeExpression: Decode< Ast.StatementExpression, - Ast.DStatementExpression + Ast.CStmtExpression > = function* (node, ctx, eff) { const expr = yield* decodeExprCtx(node.expression, ctx); return Result( - Ast.DStatementExpression(expr.value, node.loc), + Ast.CStmtExpression(expr.value, node.loc), ctx, expr.eff, ); @@ -182,14 +182,14 @@ const decodeExpression: Decode< const decodeAssign: Decode< Ast.StatementAssign, - Ast.DStatementAssign | Ast.DStatementExpression + Ast.CStmtAssign | Ast.CStmtExpression > = function* (node, ctx, eff) { const right = yield* decodeExprCtx(node.expression, ctx); const left = yield* decodeExprCtx(node.path, ctx); const path = yield* convertExprToLValue(left.value); if (!path) { return Result( - Ast.DStatementExpression(right.value, node.loc), + Ast.CStmtExpression(right.value, node.loc), ctx, allEff([left.eff, right.eff]), ); @@ -208,18 +208,18 @@ const decodeAssign: Decode< ...argEffs, mayWrite: isAssignToStorage || argEffs.mayWrite, }; - return Result(Ast.DStatementAssign(path, right.value, node.loc), ctx, newEff); + return Result(Ast.CStmtAssign(path, right.value, node.loc), ctx, newEff); }; const decodeAssignAugmented: Decode< Ast.StatementAugmentedAssign, - Ast.DStatementAugmentedAssign | Ast.DStatementExpression + Ast.CStmtAugmentedAssign | Ast.CStmtExpression > = function* (node, ctx, eff) { const right = yield* decodeExprCtx(node.expression, ctx); const left = yield* decodeExprCtx(node.path, ctx); const path = yield* convertExprToLValue(left.value); if (!path) { - return Result(Ast.DStatementExpression(right.value, node.loc), ctx, eff); + return Result(Ast.CStmtExpression(right.value, node.loc), ctx, eff); } const fnType = builtinAugmented.get(node.op); @@ -239,13 +239,13 @@ const decodeAssignAugmented: Decode< mayWrite: isAssignToStorage || argEffs.mayWrite, }; return Result( - Ast.DStatementAugmentedAssign(node.op, path, right.value, node.loc), + Ast.CStmtAugmentedAssign(node.op, path, right.value, node.loc), ctx, newEff, ); }; -const decodeCondition: Decode = +const decodeCondition: Decode = function* (node, ctx, eff) { const condition = yield* decodeExprCtx(node.condition, ctx); yield* assignType( @@ -258,7 +258,7 @@ const decodeCondition: Decode = const trueRes = yield* decodeStmts(node.trueStatements, ctx, eff); const falseRes = yield* checkElse(node.falseStatements, ctx, eff); return Result( - Ast.DStatementCondition( + Ast.CStmtCondition( condition.value, trueRes.value, falseRes.value, @@ -273,14 +273,14 @@ const decodeCondition: Decode = }; const checkElse: Decode< undefined | readonly Ast.Statement[], - undefined | readonly Ast.DecodedStatement[] + undefined | readonly Ast.CStmt[] > = function* (node, ctx, eff) { if (typeof node === 'undefined') { return Result(undefined, ctx, emptyEff); } return yield* decodeStmts(node, ctx, eff); } -const decodeWhile: Decode = function* ( +const decodeWhile: Decode = function* ( node, ctx, eff, @@ -297,13 +297,13 @@ const decodeWhile: Decode = function* ( // might be executed zero times, so it doesn't matter // if it always returns, or assigns to `self` return Result( - Ast.DStatementWhile(condition.value, result.value, node.loc), + Ast.CStmtWhile(condition.value, result.value, node.loc), ctx, allEff([condition.eff, anyEff([result.effects, emptyEff])]), ); }; -const decodeUntil: Decode = function* ( +const decodeUntil: Decode = function* ( node, ctx, eff, @@ -318,13 +318,13 @@ const decodeUntil: Decode = function* ( ); const result = yield* decodeStmts(node.statements, ctx, eff); return Result( - Ast.DStatementUntil(condition.value, result.value, node.loc), + Ast.CStmtUntil(condition.value, result.value, node.loc), ctx, allEff([result.effects, condition.eff, anyEff([result.effects, emptyEff])]), ); }; -const decodeRepeat: Decode = +const decodeRepeat: Decode = function* (node, ctx, eff) { const iterations = yield* decodeExprCtx(node.iterations, ctx); yield* assignType( @@ -338,13 +338,13 @@ const decodeRepeat: Decode = // might be executed zero times, so it doesn't matter // if it always returns, or assigns to `self` return Result( - Ast.DStatementRepeat(iterations.value, result.value, node.loc), + Ast.CStmtRepeat(iterations.value, result.value, node.loc), ctx, allEff([iterations.eff, anyEff([result.effects, emptyEff])]), ); }; -const decodeTry: Decode = function* ( +const decodeTry: Decode = function* ( node, ctx, eff, @@ -357,22 +357,22 @@ const decodeTry: Decode = function* ( newCtx, eff, ); - const catchBlock = Ast.DCatchBlock(node.catchBlock.name, catchRes.value); + const catchBlock = Ast.CCatchBlock(node.catchBlock.name, catchRes.value); return Result( - Ast.DStatementTry(tryRes.value, catchBlock, node.loc), + Ast.CStmtTry(tryRes.value, catchBlock, node.loc), ctx, anyEff([tryRes.effects, catchRes.effects]), ); } else { return Result( - Ast.DStatementTry(tryRes.value, undefined, node.loc), + Ast.CStmtTry(tryRes.value, undefined, node.loc), ctx, tryRes.effects, ); } }; -const decodeForeach: Decode = +const decodeForeach: Decode = function* (node, ctx, eff) { const map = yield* decodeExprCtx(node.map, ctx); const innerCtx = yield* defineForVars( @@ -383,7 +383,7 @@ const decodeForeach: Decode = ); const result = yield* decodeStmts(node.statements, innerCtx, eff); return Result( - Ast.DStatementForEach( + Ast.CStmtForEach( node.keyName, node.valueName, map.value, @@ -399,7 +399,7 @@ function* defineForVars( keyName: Ast.OptionalId, valueName: Ast.OptionalId, ctx: Context, -): Ast.WithLog { +): Ast.Log { if (type.kind === "map_type") { const ctxKey = yield* defineVar(keyName, type.key, ctx); const ctxKV = yield* defineVar(valueName, type.value, ctxKey); @@ -412,15 +412,15 @@ function* defineForVars( } return yield* defineForVars(childType, keyName, valueName, ctx); } else { - const ctxKey = yield* defineVar(keyName, Ast.CTypeRecover(), ctx); - const ctxKV = yield* defineVar(valueName, Ast.CTypeRecover(), ctxKey); + const ctxKey = yield* defineVar(keyName, Ast.CTRecover(), ctx); + const ctxKV = yield* defineVar(valueName, Ast.CTRecover(), ctxKey); return ctxKV; } } const decodeDestruct: Decode< Ast.StatementDestruct, - Ast.DStatementDestruct | Ast.DStatementExpression + Ast.CStmtDestruct | Ast.CStmtExpression > = function* (node, ctx, eff) { const expr = yield* decodeExprCtx(node.expression, ctx); @@ -435,10 +435,10 @@ const decodeDestruct: Decode< const decl = yield* findStruct(node.type, typeArgs, ctx.scopeRef); if (!decl) { - return Result(Ast.DStatementExpression(expr.value, node.loc), ctx, expr.eff); + return Result(Ast.CStmtExpression(expr.value, node.loc), ctx, expr.eff); } - const ascribed = Ast.DTypeRef(node.type, decl, typeArgs, node.loc); + const ascribed = Ast.CTRef(node.type, decl, typeArgs, node.loc); yield* assignType( node.loc, emptyTypeParams, @@ -457,7 +457,7 @@ const decodeDestruct: Decode< ); return Result( - Ast.DStatementDestruct( + Ast.CStmtDestruct( node.type, fields, node.ignoreUnspecifiedFields, @@ -474,9 +474,9 @@ function* checkFields( declFields: Ast.Ordered, ignoreUnspecifiedFields: boolean, ctx: Context, -): Ast.WithLog, Context]> { +): Ast.Log, Context]> { const order: string[] = []; - const map: Map = new Map(); + const map: Map = new Map(); for (const [field, variable] of stmtFields) { const fieldName = field.text; const prev = map.get(fieldName); @@ -494,7 +494,7 @@ function* checkFields( order.push(fieldName); - map.set(fieldName, [Ast.DestructPattern(field, variable), field.loc]); + map.set(fieldName, [Ast.CDestructPattern(field, variable), field.loc]); ctx = yield* defineVar(variable, yield* decl.type(), ctx); } @@ -549,7 +549,7 @@ function* findStruct( switch (decl.decl.kind) { case "alias": { const type = yield* dealiasType( - Ast.CTypeAliasRef(Ast.CNotDealiased(), id, typeArgs, id.loc), + Ast.CTAliasRef(Ast.CNotDealiased(), id, typeArgs, id.loc), scopeRef, ); if ( @@ -579,14 +579,14 @@ const ENotDestructible = (name: string, prev: Ast.Loc): Ast.TcError => ({ descr: [Ast.TEText(`Type "${name}" doesn't `), Ast.TECode(prev)], }); -const decodeBlock: Decode = function* ( +const decodeBlock: Decode = function* ( node, ctx, eff, ) { const result = yield* decodeStmts(node.statements, ctx, eff); return Result( - Ast.DStatementBlock(result.value, node.loc), + Ast.CStmtBlock(result.value, node.loc), ctx, result.effects, ); @@ -596,7 +596,7 @@ type Decode = ( node: T, context: Context, effAbove: Ast.Effects, -) => Ast.WithLog>; +) => Ast.Log>; type Result = { readonly value: U; @@ -623,7 +623,7 @@ function* defineVar( node: Ast.OptionalId, type: Ast.CType, ctx: Context, -): Ast.WithLog { +): Ast.Log { if (node.kind === "wildcard") { // there is nothing to define for a wildcard return ctx; @@ -687,7 +687,7 @@ const EShadowConst = ( function* getRequired( selfType: Ast.SelfType | undefined, -): Ast.WithLog> { +): Ast.Log> { if (!selfType) { return new Set(); } diff --git a/src/next/types/struct.ts b/src/next/types/struct.ts index bbdce0ef3e..f4ba1113ab 100644 --- a/src/next/types/struct.ts +++ b/src/next/types/struct.ts @@ -8,7 +8,7 @@ export function* decodeStruct( Lazy: Ast.ThunkBuilder, struct: Ast.StructDecl, scopeRef: () => Ast.CSource, -): Ast.WithLog { +): Ast.Log { const typeParams = yield* decodeTypeParams(struct.typeParams); const fields = yield* decodeFields( Lazy, diff --git a/src/next/types/trait.ts b/src/next/types/trait.ts index 73c5f3f18f..b2668d3e69 100644 --- a/src/next/types/trait.ts +++ b/src/next/types/trait.ts @@ -10,7 +10,7 @@ export function* decodeTrait( Lazy: Ast.ThunkBuilder, trait: Ast.Trait, scopeRef: () => Ast.CSource, -): Ast.WithLog { +): Ast.Log { const { attributes, declarations, name, loc } = trait; const { constants, fields, methods, receivers } = declarations; @@ -61,7 +61,7 @@ export function* decodeTrait( recover, }); - const traitSig = Ast.CTraitSig(contentLazy); + const traitSig = Ast.CTrait(contentLazy); const selfType = Ast.SVTRef(trait.name, traitSig, [], trait.loc); diff --git a/src/next/types/traits-scope.ts b/src/next/types/traits-scope.ts index c70c3ecdb6..d8a770076d 100644 --- a/src/next/types/traits-scope.ts +++ b/src/next/types/traits-scope.ts @@ -5,7 +5,7 @@ import * as Ast from "@/next/ast"; export function* getInheritedTraits( traits: readonly Ast.TypeId[], scopeRef: () => Ast.CSource, -): Ast.WithLog[]> { +): Ast.Log[]> { const decls = scopeRef().typeDecls; const prevTraits: Ast.Decl[] = []; for (const trait of traits) { diff --git a/src/next/types/type-fn.ts b/src/next/types/type-fn.ts index 20400ab0c8..e285f737c3 100644 --- a/src/next/types/type-fn.ts +++ b/src/next/types/type-fn.ts @@ -9,12 +9,12 @@ export function* decodeFnType( Lazy: Ast.ThunkBuilder, { typeParams, params, returnType }: Ast.TFunction, scopeRef: () => Ast.CSource, -): Ast.WithLog { +): Ast.Log { const decodedTypeParams = yield* decodeTypeParams(typeParams); const dealias = (type: Ast.Type) => { return decodeDealiasTypeLazy(Lazy, decodedTypeParams, type, scopeRef); }; - return Ast.CTypeFunction( + return Ast.CTFunction( decodedTypeParams, yield* decodeParams(dealias, params), dealias(returnType), @@ -24,7 +24,7 @@ export function* decodeFnType( export function* decodeParams( dealias: (type: Ast.Type) => Ast.Thunk, params: readonly Ast.TypedParameter[], -): Ast.WithLog { +): Ast.Log { const order: Ast.CParameter[] = []; const set: Set = new Set(); for (const param of params) { @@ -40,7 +40,7 @@ export function* decodeParams( function* decodeParamName( node: Ast.OptionalId, set: ReadonlySet, -): Ast.WithLog { +): Ast.Log { if (node.kind === "wildcard") { return undefined; } diff --git a/src/next/types/type-params.ts b/src/next/types/type-params.ts index 44e61bc3b0..8e4cf7df8d 100644 --- a/src/next/types/type-params.ts +++ b/src/next/types/type-params.ts @@ -5,7 +5,7 @@ export const emptyTypeParams = Ast.CTypeParams([], new Set()); export function* decodeTypeParams( ids: readonly Ast.TypeId[], -): Ast.WithLog { +): Ast.Log { const set: Set = new Set(); const order: Ast.TypeId[] = []; diff --git a/src/next/types/type.ts b/src/next/types/type.ts index 00e03b9573..6aa309a301 100644 --- a/src/next/types/type.ts +++ b/src/next/types/type.ts @@ -17,7 +17,7 @@ export const decodeTypeLazy = ( callback: () => decodeType(typeParams, type, scopeRef().typeDecls), context: [Ast.TEText("checking type"), Ast.TECode(type.loc)], loc: type.loc, - recover: Ast.CTypeRecover(), + recover: Ast.CTRecover(), }); export const decodeDealiasTypeLazy = ( @@ -37,7 +37,7 @@ export const decodeDealiasTypeLazy = ( }, context: [Ast.TEText("checking type"), Ast.TECode(type.loc)], loc: type.loc, - recover: Ast.CTypeRecover(), + recover: Ast.CTRecover(), }); export function* dealiasType(type: Ast.CType, scopeRef: () => Ast.CSource) { @@ -52,7 +52,7 @@ export function* decodeTypeMap( const { typeDecls } = scopeRef(); const key = yield* decodeType(typeParams, type.key, typeDecls); const value = yield* decodeType(typeParams, type.value, typeDecls); - return Ast.CTypeMap(key, value, type.loc); + return Ast.CTMap(key, value, type.loc); } export function* decodeTypeSet( @@ -63,7 +63,7 @@ export function* decodeTypeSet( const { typeDecls } = scopeRef(); const key = yield* decodeType(typeParams, type.key, typeDecls); const value = yield* decodeType(typeParams, type.value, typeDecls); - return Ast.CTypeMap(key, value, type.loc); + return Ast.CTMap(key, value, type.loc); } export function decodeType( @@ -74,7 +74,7 @@ export function decodeType( // decode all the types in an array function* recN( types: readonly Ast.Type[], - ): Ast.WithLog { + ): Ast.Log { const results: Ast.CType[] = []; for (const type of types) { const result = yield* rec(type); @@ -84,45 +84,45 @@ export function decodeType( } // decode a type - function* rec(type: Ast.Type): Ast.WithLog { + function* rec(type: Ast.Type): Ast.Log { switch (type.kind) { case "basic": { return type; } case "tuple_type": { const result = yield* recN(type.typeArgs); - return Ast.CTypeTuple(result, type.loc); + return Ast.CTTuple(result, type.loc); } case "tensor_type": { const result = yield* recN(type.typeArgs); - return Ast.CTypeTensor(result, type.loc); + return Ast.CTTensor(result, type.loc); } case "map_type": { // NB! modify along with decodeTypeMap above const key = yield* rec(type.key); const value = yield* rec(type.value); - return Ast.CTypeMap(key, value, type.loc); + return Ast.CTMap(key, value, type.loc); } case "TypeBounced": { const child = yield* rec(type.type); if (child.kind !== "type_ref" || child.typeArgs.length > 0) { yield EBouncedMessage(type.loc); - return Ast.CTypeRecover(); + return Ast.CTRecover(); } const typeEntry = typeDecls.get(child.name.text); if (!typeEntry) { yield EBouncedMessage(type.loc); - return Ast.CTypeRecover(); + return Ast.CTRecover(); } else if (typeEntry.decl.kind === "message") { - return Ast.CTypeBounced(child.name, type.loc); + return Ast.CTBounced(child.name, type.loc); } else { yield EBouncedMessage(type.loc); - return Ast.CTypeRecover(); + return Ast.CTRecover(); } } case "TypeMaybe": { const child = yield* rec(type.type); - return Ast.CTypeMaybe(child, type.loc); + return Ast.CTMaybe(child, type.loc); } case "cons_type": { // this is where the meat of the procedure is @@ -139,9 +139,9 @@ export function decodeType( // if we used type parameter generically, throw error // because we do not support HKT if (!(yield* matchArity(name, arity, 0, type.loc))) { - return Ast.CTypeRecover(); + return Ast.CTRecover(); } - return Ast.CTypeParamRef(type.name, type.loc); + return Ast.CTParamRef(type.name, type.loc); } const typeEntry = typeDecls.get(name); @@ -149,7 +149,7 @@ export function decodeType( // there is no such type at all! if (!typeEntry) { yield ETypeNotFound(name, type.loc); - return Ast.CTypeRecover(); + return Ast.CTRecover(); } // check number of type arguments does match @@ -161,17 +161,17 @@ export function decodeType( type.loc, )) ) { - return Ast.CTypeRecover(); + return Ast.CTRecover(); } switch (typeEntry.decl.kind) { case "trait": { yield ETraitNotType(type.loc); - return Ast.CTypeRecover(); + return Ast.CTRecover(); } case "contract": { // this is a ground type reference - return Ast.DTypeRef( + return Ast.CTRef( type.name, typeEntry.decl, [], @@ -182,7 +182,7 @@ export function decodeType( case "message": case "union": { // this is a ground type reference - return Ast.DTypeRef( + return Ast.CTRef( type.name, typeEntry.decl, args, @@ -191,7 +191,7 @@ export function decodeType( } case "alias": { // this is an alias reference - return Ast.CTypeAliasRef( + return Ast.CTAliasRef( Ast.CNotDealiased(), type.name, args, @@ -234,7 +234,7 @@ function* matchArity( got: number, expected: number, loc: Ast.Loc, -): Ast.WithLog { +): Ast.Log { const result = got === expected; if (!result) { yield EArity(name, expected, got, loc); @@ -265,14 +265,14 @@ const dealiasTypeAux = ( type: Ast.CType, typeDecls: ReadonlyMap>, ) => { - function* rec(type: Ast.CType): Ast.WithLog { + function* rec(type: Ast.CType): Ast.Log { switch (type.kind) { case "recover": { return type; } case "type_ref": { const args = yield* Ast.mapLog(type.typeArgs, rec); - return Ast.DTypeRef(type.name, type.type, args, type.loc); + return Ast.CTRef(type.name, type.type, args, type.loc); } case "TypeAlias": { const alias = typeDecls.get(type.name.text); @@ -290,7 +290,7 @@ const dealiasTypeAux = ( yield* Ast.mapLog(type.typeArgs, rec), ), ); - return Ast.CTypeAliasRef( + return Ast.CTAliasRef( decoded, type.name, type.typeArgs, @@ -303,19 +303,19 @@ const dealiasTypeAux = ( case "map_type": { const key = yield* rec(type.key); const value = yield* rec(type.value); - return Ast.CTypeMap(key, value, type.loc); + return Ast.CTMap(key, value, type.loc); } case "TypeMaybe": { const args = yield* rec(type.type); - return Ast.CTypeMaybe(args, type.loc); + return Ast.CTMaybe(args, type.loc); } case "tuple_type": { const args = yield* Ast.mapLog(type.typeArgs, rec); - return Ast.CTypeTuple(args, type.loc); + return Ast.CTTuple(args, type.loc); } case "tensor_type": { const args = yield* Ast.mapLog(type.typeArgs, rec); - return Ast.CTypeTensor(args, type.loc); + return Ast.CTTensor(args, type.loc); } case "basic": case "TypeBounced": { @@ -362,12 +362,12 @@ export const substituteTypeArgs = ( } case "type_ref": { const args = recN(type.typeArgs); - return Ast.DTypeRef(type.name, type.type, args, type.loc); + return Ast.CTRef(type.name, type.type, args, type.loc); } case "TypeAlias": { if (type.type.kind === "NotDealiased") { const args = recN(type.typeArgs); - return Ast.CTypeAliasRef( + return Ast.CTAliasRef( type.type, type.name, args, @@ -375,7 +375,7 @@ export const substituteTypeArgs = ( ); } else { const args = recN(type.typeArgs); // ?? - return Ast.CTypeAliasRef( + return Ast.CTAliasRef( rec(type.type), type.name, args, @@ -386,19 +386,19 @@ export const substituteTypeArgs = ( case "map_type": { const key = rec(type.key); const value = rec(type.value); - return Ast.CTypeMap(key, value, type.loc); + return Ast.CTMap(key, value, type.loc); } case "TypeMaybe": { const args = rec(type.type); - return Ast.CTypeMaybe(args, type.loc); + return Ast.CTMaybe(args, type.loc); } case "tuple_type": { const args = recN(type.typeArgs); - return Ast.CTypeTuple(args, type.loc); + return Ast.CTTuple(args, type.loc); } case "tensor_type": { const args = recN(type.typeArgs); - return Ast.CTypeTensor(args, type.loc); + return Ast.CTTensor(args, type.loc); } case "recover": case "basic": @@ -417,8 +417,8 @@ export function* instantiateStruct( // NB! these are type params from enclosing scope typeParams: Ast.CTypeParams, scopeRef: () => Ast.CSource, -): Ast.WithLog< - undefined | { type: Ast.DTypeRef; fields: Ast.Ordered } +): Ast.Log< + undefined | { type: Ast.CTRef; fields: Ast.Ordered } > { const decl = scopeRef().typeDecls.get(typeName.text); switch (decl?.decl.kind) { @@ -452,7 +452,7 @@ export function* instantiateStruct( return undefined; } return { - type: Ast.DTypeRef(typeName, decl.decl, typeArgs, typeName.loc), + type: Ast.CTRef(typeName, decl.decl, typeArgs, typeName.loc), fields: decl.decl.fields, }; } @@ -469,7 +469,7 @@ export function* instantiateStruct( return undefined; } const type = yield* dealiasType( - Ast.CTypeAliasRef( + Ast.CTAliasRef( Ast.CNotDealiased(), typeName, typeArgs, @@ -522,7 +522,7 @@ export function typeParamsToSubst(typeParams: Ast.CTypeParams) { export function* substToTypeArgMap( loc: Ast.Loc, subst: Map, -): Ast.WithLog { +): Ast.Log { const res = substToTypeArgMapAux(subst); if (res.ok) { return res.args; @@ -559,7 +559,7 @@ export function* assignType( to: Ast.CType, from: Ast.CType, strict: boolean, -): Ast.WithLog { +): Ast.Log { const subst = typeParamsToSubst(toFreeTypeParam); const result = assignTypeAux(to, from, subst, strict); if (result.kind === "failure") { @@ -726,11 +726,11 @@ export function* mgu( left: Ast.CType, right: Ast.CType, loc: Ast.Loc, -): Ast.WithLog { +): Ast.Log { function* rec( left: Ast.CType, right: Ast.CType, - ): Ast.WithLog { + ): Ast.Log { if (right.kind === "TypeAlias") { if (right.type.kind === "NotDealiased") { return throwInternal("Decoder returned aliased type"); @@ -754,13 +754,13 @@ export function* mgu( return right; } if (right.kind === "basic" && right.type.kind === "TypeNull") { - return Ast.CTypeMaybe(left, loc); + return Ast.CTMaybe(left, loc); } if (left.kind === "basic" && left.type.kind === "TypeNull") { - return Ast.CTypeMaybe(right, loc); + return Ast.CTMaybe(right, loc); } yield ENotUnifiable(resultL.tree, loc); - return Ast.CTypeRecover(); + return Ast.CTRecover(); } return yield* rec(left, right); @@ -780,9 +780,9 @@ export type CallResult = { export function* checkFnCall( loc: Ast.Loc, - fnType: Ast.CTypeFunction | Ast.CTypeMethod, + fnType: Ast.CTFunction | Ast.CTMethod, args: readonly (readonly [Ast.Loc, Ast.CType])[], -): Ast.WithLog { +): Ast.Log { const { typeParams, params, returnType } = fnType; const subst = typeParamsToSubst(typeParams); @@ -809,7 +809,7 @@ export function* checkFnCall( if (!typeArgsMap) { return { - returnType: Ast.CTypeRecover(), + returnType: Ast.CTRecover(), typeArgMap: new Map(), }; } @@ -864,19 +864,19 @@ const EFnArity = ( export function* checkFnCallWithArgs( Lazy: Ast.ThunkBuilder, loc: Ast.Loc, - fnType: Ast.CTypeFunction | undefined, + fnType: Ast.CTFunction | undefined, ascribedTypeArgs: readonly Ast.CType[], args: readonly (readonly [Ast.Loc, Ast.CType])[], -): Ast.WithLog { +): Ast.Log { if (!fnType) { yield ENoFunction(loc); - return { returnType: Ast.CTypeRecover(), typeArgMap: new Map() }; + return { returnType: Ast.CTRecover(), typeArgMap: new Map() }; } if (ascribedTypeArgs.length === 0) { return yield* checkFnCall(loc, fnType, args); } if (fnType.typeParams.order.length !== ascribedTypeArgs.length) { - return { returnType: Ast.CTypeRecover(), typeArgMap: new Map() }; + return { returnType: Ast.CTRecover(), typeArgMap: new Map() }; } const result = yield* checkFnCall( loc, @@ -905,7 +905,7 @@ function substFnType( typeParams, params, returnType, - }: Ast.CTypeFunction | Ast.CTypeMethod, + }: Ast.CTFunction | Ast.CTMethod, args: readonly Ast.CType[], ) { const order: Ast.CParameter[] = []; @@ -927,13 +927,13 @@ function substFnType( ), ], loc: param.loc, - recover: Ast.CTypeRecover(), + recover: Ast.CTRecover(), }), param.loc, ), ); } - return Ast.CTypeFunction( + return Ast.CTFunction( emptyTypeParams, Ast.CParameters(order, params.set), Lazy({ @@ -946,7 +946,7 @@ function substFnType( }, context: [Ast.TEText(`substituting into return type`)], loc: fnLoc, - recover: Ast.CTypeRecover(), + recover: Ast.CTRecover(), }), ); } @@ -962,9 +962,9 @@ export function* lookupMethod( args: readonly (readonly [Ast.Loc, Ast.CType])[], typeDecls: ReadonlyMap>, extensions: ReadonlyMap[]>>, -): Ast.WithLog { +): Ast.Log { if (selfType.kind === "recover") { - return { returnType: Ast.CTypeRecover(), typeArgMap: new Map(), mutates: false }; + return { returnType: Ast.CTRecover(), typeArgMap: new Map(), mutates: false }; } if (selfType.kind === "TypeAlias") { if (selfType.type.kind === "NotDealiased") { @@ -988,7 +988,7 @@ export function* lookupMethod( const selfDecl = typeDecls.get(selfType.name.text); if (!selfDecl) { yield ENoMethod(method.loc); - return { returnType: Ast.CTypeRecover(), typeArgMap: new Map(), mutates: false }; + return { returnType: Ast.CTRecover(), typeArgMap: new Map(), mutates: false }; } if (selfDecl.decl.kind === "struct" || selfDecl.decl.kind === "message") { @@ -1009,7 +1009,7 @@ export function* lookupMethod( const met = content.methods.get(method.text); if (!met) { yield ENoMethod(method.loc); - return { returnType: Ast.CTypeRecover(), typeArgMap: new Map(), mutates: false }; + return { returnType: Ast.CTRecover(), typeArgMap: new Map(), mutates: false }; } return { ...yield* checkFnCall(method.loc, met.decl.type, args), @@ -1018,7 +1018,7 @@ export function* lookupMethod( } yield ENoMethod(method.loc); - return { returnType: Ast.CTypeRecover(), typeArgMap: new Map(), mutates: false }; + return { returnType: Ast.CTRecover(), typeArgMap: new Map(), mutates: false }; } function* lookupExts( @@ -1027,15 +1027,15 @@ function* lookupExts( method: Ast.Id, args: readonly (readonly [Ast.Loc, Ast.CType])[], extensions: ReadonlyMap[]>>, -): Ast.WithLog { +): Ast.Log { const lazyExts = extensions.get(method.text); if (!lazyExts) { yield ENoMethod(method.loc); - return { returnType: Ast.CTypeRecover(), typeArgMap: new Map(), mutates: false }; + return { returnType: Ast.CTRecover(), typeArgMap: new Map(), mutates: false }; } const exts = yield* lazyExts(); - const grounds: [Ast.CTypeMethod, Ast.TypeArgs][] = []; - const withVars: [Ast.CTypeMethod, Ast.TypeArgs][] = []; + const grounds: [Ast.CTMethod, Ast.TypeArgs][] = []; + const withVars: [Ast.CTMethod, Ast.TypeArgs][] = []; for (const { decl } of exts) { const subst = typeParamsToSubst(decl.type.typeParams); const result = assignTypeAux(decl.type.self, selfType, subst, true); @@ -1057,7 +1057,7 @@ function* lookupExts( const either = ground || withVar; if (!either) { yield ENoMethod(method.loc); - return { returnType: Ast.CTypeRecover(), typeArgMap: new Map(), mutates: false }; + return { returnType: Ast.CTRecover(), typeArgMap: new Map(), mutates: false }; } const [methodType, typeArgs] = either; const result = yield* checkFnCall( @@ -1095,11 +1095,11 @@ const ENoMethod = (loc: Ast.Loc): Ast.TcError => ({ }); export function* assignMethodType( - prev: Ast.CTypeMethod, - next: Ast.CTypeMethod, + prev: Ast.CTMethod, + next: Ast.CTMethod, prevVia: Ast.ViaMember, nextVia: Ast.ViaMember, -): Ast.WithLog { +): Ast.Log { const result = assignTypeAux( yield* prev.returnType(), yield* next.returnType(), diff --git a/src/next/types/typecheck.ts b/src/next/types/typecheck.ts index 98b97c5e63..a25323d71f 100644 --- a/src/next/types/typecheck.ts +++ b/src/next/types/typecheck.ts @@ -57,7 +57,7 @@ function* tcSource( imported: readonly Ast.SourceCheckResult[], // source for current file source: TactSource, -): Ast.WithLog { +): Ast.Log { const Lazy = Ast.thunkBuilder; const scopeRef = () => scope; const scope: Ast.CSource = { @@ -68,7 +68,3 @@ function* tcSource( }; return scope; } - -function lowerSource(node: Ast.CSource) { - -} \ No newline at end of file diff --git a/src/next/types/typedecl.ts b/src/next/types/typedecl.ts index 55d0d69af2..fc2f8520d0 100644 --- a/src/next/types/typedecl.ts +++ b/src/next/types/typedecl.ts @@ -17,7 +17,7 @@ export function* decodeTypeDecls( imported: readonly Ast.SourceCheckResult[], source: TactSource, scopeRef: () => Ast.CSource, -): Ast.WithLog>> { +): Ast.Log>> { const importedSigs = imported.map( ({ globals, importedBy }) => new Map( @@ -77,7 +77,7 @@ function* decodeTypeDecl( Lazy: Ast.ThunkBuilder, decl: Ast.TypeDecl, scopeRef: () => Ast.CSource, -): Ast.WithLog { +): Ast.Log { switch (decl.kind) { case "alias_decl": { return yield* decodeAlias(Lazy, decl, scopeRef); diff --git a/src/next/types/union.ts b/src/next/types/union.ts index 15b98a2841..ea9253ade2 100644 --- a/src/next/types/union.ts +++ b/src/next/types/union.ts @@ -14,7 +14,7 @@ export function* decodeUnion( Lazy: Ast.ThunkBuilder, union: Ast.UnionDecl, scopeRef: () => Ast.CSource, -): Ast.WithLog { +): Ast.Log { const typeParams = yield* decodeTypeParams(union.typeParams); const cases: Map = new Map(); diff --git a/src/next/types/value.ts b/src/next/types/value.ts index cd1e1fdac6..98330ee6bf 100644 --- a/src/next/types/value.ts +++ b/src/next/types/value.ts @@ -2,7 +2,7 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ import * as Ast from "@/next/ast"; -export function convertValueToExpr(node: Ast.Value): Ast.DecodedExpression { +export function convertValueToExpr(node: Ast.Value): Ast.CExpr { switch (node.kind) { // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition case "number": { From 1e78dd53e11eed6b071bdffe346538895d05b7df Mon Sep 17 00:00:00 2001 From: verytactical <186486509+verytactical@users.noreply.github.com> Date: Wed, 25 Jun 2025 12:21:25 +0400 Subject: [PATCH 38/38] 1 --- .vscode/launch.json | 5 +- src/next/ast/errors.ts | 33 +- src/next/ast/generated/type.ts | 6 +- src/next/ast/lazy.ts | 7 +- src/next/grammar/index.ts | 8 +- src/next/test/_test.build.ts | 17 +- src/next/types/body.ts | 85 +- src/next/types/builtins.ts | 6 + src/next/types/constants.ts | 38 +- src/next/types/contract.ts | 80 +- src/next/types/expression.ts | 186 +- src/next/types/extensions.ts | 30 +- src/next/types/fields.ts | 16 +- src/next/types/lower.ts | 80 +- src/next/types/lvalue.ts | 22 +- src/next/types/message.ts | 24 +- src/next/types/methods.ts | 36 +- src/next/types/override.ts | 52 +- src/next/types/receivers.ts | 122 +- src/next/types/statements.ts | 126 +- src/next/types/struct-fields.ts | 18 +- src/next/types/trait.ts | 6 +- src/next/types/traits-scope.ts | 12 +- src/next/types/type-fn.ts | 6 +- src/next/types/type-params.ts | 6 +- src/next/types/type.ts | 199 +- src/next/types/union.ts | 36 +- src/stdlib/stdlib.ts | 2036 +++++++++--------- src/stdlib/stdlib/std/internal/address.tact | 24 +- src/stdlib/stdlib/std/internal/base.tact | 5 + src/stdlib/stdlib/std/internal/contract.tact | 35 +- src/stdlib/stdlib/std/internal/math.tact | 2 + src/stdlib/stdlib/std/internal/send.tact | 2 + src/stdlib/stdlib/std/internal/text.tact | 4 + 34 files changed, 1704 insertions(+), 1666 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index dfca9f8616..6714668381 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -12,7 +12,10 @@ ], "cwd": "${workspaceFolder}", "console": "integratedTerminal", - "internalConsoleOptions": "neverOpen" + "internalConsoleOptions": "neverOpen", + "env": { + "NODE_OPTIONS": "--stack-trace-limit=100000" + } } ] } \ No newline at end of file diff --git a/src/next/ast/errors.ts b/src/next/ast/errors.ts index 9a172669a3..a3673debc7 100644 --- a/src/next/ast/errors.ts +++ b/src/next/ast/errors.ts @@ -78,6 +78,13 @@ export type TcError = { // text description readonly descr: readonly TELine[]; }; +export const TcError = ( + loc: Loc, + ...descr: readonly TELine[] +): TcError => { + debugger; + return { loc, descr }; +}; export type TELine = TEText | TEVia | TEViaMember | TECode | TEMismatch; @@ -147,22 +154,20 @@ export const ERedefine = ( name: string, prev: V.Via, next: V.ViaUser, -): TcError => ({ - loc: viaToRange(next), - descr: [TEText(`There already is a ${kind} "${name}" from`), TEVia(prev)], -}); +) => TcError( + viaToRange(next), + TEText(`There already is a ${kind} "${name}" from`), TEVia(prev), +); export const ERedefineMember = ( name: string, prev: V.ViaMember, next: V.ViaMember, -): TcError => ({ - loc: next.defLoc, - descr: [ - TEText(`"${name}" is inherited twice`), - TEText(`First defined at`), - TEViaMember(prev), - TEText(`Redefined at`), - TEViaMember(next), - ], -}); +) => TcError( + next.defLoc, + TEText(`"${name}" is inherited twice`), + TEText(`First defined at`), + TEViaMember(prev), + TEText(`Redefined at`), + TEViaMember(next), +); diff --git a/src/next/ast/generated/type.ts b/src/next/ast/generated/type.ts index 7aadcd0b85..445d9e0836 100644 --- a/src/next/ast/generated/type.ts +++ b/src/next/ast/generated/type.ts @@ -38,13 +38,15 @@ export const TCons = ( name: $c.TypeId, typeArgs: readonly $.Type[], loc: $c.Loc, -): $.TCons => - Object.freeze({ +): $.TCons => { + if (name.text === 'StateInit') debugger; + return Object.freeze({ kind: "cons_type", name, typeArgs, loc, }); +}; export type Type = $.Type; export type TMap = $.TMap; export const TMap = (key: $.Type, value: $.Type, loc: $c.Loc): $.TMap => diff --git a/src/next/ast/lazy.ts b/src/next/ast/lazy.ts index e020bac827..54334c82ba 100644 --- a/src/next/ast/lazy.ts +++ b/src/next/ast/lazy.ts @@ -70,9 +70,10 @@ const makeBuilder = (allContext: readonly E.TELine[]): ThunkBuilder => { }; }; -const EOccurs = (loc: Loc, context: readonly E.TELine[]): E.TcError => ({ +const EOccurs = (loc: Loc, context: readonly E.TELine[]) => E.TcError( loc, - descr: [E.TEText(`Recursive definition`), ...context], -}); + E.TEText(`Recursive definition`), + ...context, +); export const thunkBuilder = makeBuilder([]); diff --git a/src/next/grammar/index.ts b/src/next/grammar/index.ts index 3d0178bfab..cb7e0b2c7b 100644 --- a/src/next/grammar/index.ts +++ b/src/next/grammar/index.ts @@ -1266,11 +1266,7 @@ const parseTypeOptional = ({ type, optionals }: $ast.TypeOptional): Handler => (ctx) => { return optionals.reduce((acc, optional) => { - return Ast.TCons( - Ast.TypeId("Maybe", ctx.toRange(optional.loc)), - [acc], - ctx.toRange(optional.loc), - ); + return Ast.TMaybe(acc, ctx.toRange(optional.loc)); }, parseType(type)(ctx)); }; @@ -1299,6 +1295,8 @@ const parseTypeRegular = return Ast.TBasic(Ast.TString(range), range); case "StringBuilder": return Ast.TBasic(Ast.TStringBuilder(range), range); + case "StateInit": + return Ast.TBasic(Ast.TStateInit(range), range); case "Bounced": ctx.err.mustBeGeneric()(range); return Ast.TCons(Ast.TypeId("ERROR", range), [], range); diff --git a/src/next/test/_test.build.ts b/src/next/test/_test.build.ts index d7cd753806..cd01243714 100644 --- a/src/next/test/_test.build.ts +++ b/src/next/test/_test.build.ts @@ -5,11 +5,13 @@ import { typecheck } from "@/next/types/typecheck"; import { runServer } from "@/server/run-server"; import { basename, dirname } from "path"; import type { Logger } from "@/error/logger-util"; -import type { ResolvedImport } from "@/next/imports/source"; +import type { ResolvedImport, TactSource } from "@/next/imports/source"; +import { lowerSource } from "@/next/types/lower"; +import { runLog } from "@/next/ast"; export const runTest = async (path: string): Promise => { - let types: unknown; - await runServer(async (log) => { + let source: TactSource | undefined; + const entries = await runServer(async (log) => { await log.recover(async (log) => { // const result = await buildNoStdlib(log, path); const result = await buildE2E(log, path); @@ -18,10 +20,15 @@ export const runTest = async (path: string): Promise => { return; } - types = typecheck(result); + source = result; }); }); - return toJs(types); + if (entries.length > 0 || !source) { + return toJs(entries); + } + const [csource, errors1] = typecheck(source); + const [lowered, errors2] = runLog(lowerSource(csource)); + return toJs({ lowered, errors: [...errors1, ...errors2] }); }; export const buildE2E = async (log: Logger, path: string) => { diff --git a/src/next/types/body.ts b/src/next/types/body.ts index ce85358d64..3b6441408f 100644 --- a/src/next/types/body.ts +++ b/src/next/types/body.ts @@ -26,19 +26,12 @@ export function* decodeBody( ); } case "regular_body": { - const selfTypeRef = () => { - return fnType.kind === "DecodedMethodType" - ? fnType.self - : undefined; - }; return Ast.CTactBody( decodeStatementsLazy( Lazy, loc, node.statements, - fnType.typeParams, - selfTypeRef, - fnType.returnType, + () => fnType, true, scopeRef, ), @@ -62,10 +55,10 @@ export function* decodeBody( } } -const ENoBody = (loc: Ast.Loc): Ast.TcError => ({ +const ENoBody = (loc: Ast.Loc) => Ast.TcError( loc, - descr: [Ast.TEText(`Function must have a body`)], -}); + Ast.TEText(`Function must have a body`), +); function* checkShuffle( shuffle: Ast.AsmShuffle, @@ -90,6 +83,10 @@ function* checkShuffle( } } + if (fnType.kind === 'DecodedMethodType') { + paramsArray.push("self"); + } + const paramSet = new Set(paramsArray); if (!isSubsetOf(paramSet, argSet)) { yield EMissingArgs(loc); @@ -140,7 +137,7 @@ function* getRetTupleSize( return baseSize + (kind === "DecodedMethodType" ? 1 : 0); } -function* getTypeTupleSize(type: Ast.CType, scopeRef: () => Ast.CSource) { +function* getTypeTupleSize(type: Ast.CType, scopeRef: () => Ast.CSource): Ast.Log { switch (type.kind) { case "recover": { return undefined; @@ -190,7 +187,7 @@ function* getTypeTupleSize(type: Ast.CType, scopeRef: () => Ast.CSource) { return undefined; } case "TypeMaybe": { - return getTypeTupleSize(type.type, scopeRef); + return yield* getTypeTupleSize(type.type, scopeRef); } case "tuple_type": { return 1; @@ -223,51 +220,43 @@ function* getTypeTupleSize(type: Ast.CType, scopeRef: () => Ast.CSource) { } } -const EDuplicateArgs = (loc: Ast.Loc): Ast.TcError => ({ +const EDuplicateArgs = (loc: Ast.Loc) => Ast.TcError( loc, - descr: [Ast.TEText(`Argument rearrangement cannot have duplicates`)], -}); + Ast.TEText(`Argument rearrangement cannot have duplicates`), +); -const EWildcardArgs = (loc: Ast.Loc): Ast.TcError => ({ +const EWildcardArgs = (loc: Ast.Loc) => Ast.TcError( loc, - descr: [Ast.TEText(`Argument rearrangement cannot use wildcards`)], -}); + Ast.TEText(`Argument rearrangement cannot use wildcards`) +); -const EMissingArgs = (loc: Ast.Loc): Ast.TcError => ({ +const EMissingArgs = (loc: Ast.Loc) => Ast.TcError( loc, - descr: [ - Ast.TEText( - `Argument rearrangement must mention all function parameters`, - ), - ], -}); + Ast.TEText( + `Argument rearrangement must mention all function parameters`, + ), +); -const EExtraArgs = (loc: Ast.Loc): Ast.TcError => ({ +const EExtraArgs = (loc: Ast.Loc) => Ast.TcError( loc, - descr: [ - Ast.TEText( - `Argument rearrangement must mention only function parameters`, - ), - ], -}); + Ast.TEText( + `Argument rearrangement must mention only function parameters`, + ), +); -const EDuplicateRet = (loc: Ast.Loc): Ast.TcError => ({ +const EDuplicateRet = (loc: Ast.Loc) => Ast.TcError( loc, - descr: [Ast.TEText(`Return rearrangement cannot have duplicates`)], -}); + Ast.TEText(`Return rearrangement cannot have duplicates`) +); -const EMissingRet = (loc: Ast.Loc): Ast.TcError => ({ +const EMissingRet = (loc: Ast.Loc) => Ast.TcError( loc, - descr: [ - Ast.TEText(`Return rearrangement must mention all function parameters`), - ], -}); + Ast.TEText(`Return rearrangement must mention all function parameters`), +); -const EExtraRet = (loc: Ast.Loc): Ast.TcError => ({ +const EExtraRet = (loc: Ast.Loc) => Ast.TcError( loc, - descr: [ - Ast.TEText( - `Return rearrangement must mention only function parameters`, - ), - ], -}); + Ast.TEText( + `Return rearrangement must mention only function parameters`, + ), +); diff --git a/src/next/types/builtins.ts b/src/next/types/builtins.ts index 9b414b522e..e024835a1d 100644 --- a/src/next/types/builtins.ts +++ b/src/next/types/builtins.ts @@ -85,6 +85,11 @@ export const Maybe = (t: Ast.CType) => Ast.CTMaybe(t, r); export const Unit = Ast.TUnit(r); export const StateInit = Ast.CTBasic(Ast.TStateInit(r), r); +export const stateInitFields = new Map([ + ["code", Cell], + ["data", Cell], +]); + export const builtinTypes = new Map( [ "Int", @@ -99,6 +104,7 @@ export const builtinTypes = new Map( "StringBuilder", "Map", "Maybe", + "StateInit", ].map((s) => [s, s]), ); diff --git a/src/next/types/constants.ts b/src/next/types/constants.ts index e9a65dbe31..fe418aa20b 100644 --- a/src/next/types/constants.ts +++ b/src/next/types/constants.ts @@ -13,17 +13,29 @@ export function* decodeConstants( source: TactSource, scopeRef: () => Ast.CSource, ): Ast.Log>> { - const allConstSigs = [ - // imported - ...imported.flatMap(({ globals, importedBy }) => - [...globals.constants].map( - ([name, s]) => - [ - name, - Ast.Decl(s.decl, Ast.ViaImport(importedBy, s.via)), - ] as const, - ), + // imported + const importedSigs = imported.flatMap(({ globals, importedBy }) => + [...globals.constants].map( + ([name, s]) => + [ + name, + Ast.Decl(s.decl, Ast.ViaImport(importedBy, s.via)), + ] as const, ), + ); + // deduplicate diamond imports + const filteredImports: (readonly [string, Ast.Decl])[] = []; + const map: Map = new Map(); + for (const [name, decl] of importedSigs) { + const prevSource = map.get(name); + if (typeof prevSource === 'undefined' || decl.via.source !== prevSource) { + filteredImports.push([name, decl]); + map.set(name, decl.via.source); + } + } + // merge + const allConstSigs = [ + ...filteredImports, // local ...(yield* Ast.mapLog(source.items.constants, function* (c) { return [ @@ -93,7 +105,7 @@ function* decodeConstant( } } -const ETopLevelDecl = (loc: Ast.Loc): Ast.TcError => ({ +const ETopLevelDecl = (loc: Ast.Loc) => Ast.TcError( loc, - descr: [Ast.TEText(`Top-level constant must have a body`)], -}); + Ast.TEText(`Top-level constant must have a body`), +); diff --git a/src/next/types/contract.ts b/src/next/types/contract.ts index 82d8dc655e..2bb7b7e2f0 100644 --- a/src/next/types/contract.ts +++ b/src/next/types/contract.ts @@ -167,16 +167,20 @@ function* decodeInit( Lazy, init.loc, statements, - emptyTypeParams, - selfTypeRef, - Lazy({ - callback: function* () { - return Void; - }, - context: [], - loc: init.loc, - recover: Void, - }), + () => Ast.CTMethod( + true, + emptyTypeParams, + selfTypeRef(), + decodedParams, + Lazy({ + callback: function* () { + return Void; + }, + context: [], + loc: init.loc, + recover: Void, + }), + ), true, scopeRef, ); @@ -188,28 +192,24 @@ const EDuplicateParam = ( name: string, prev: Ast.Loc, next: Ast.Loc, -): Ast.TcError => ({ - loc: next, - descr: [ - Ast.TEText(`Contract parameter ${name} was already defined`), - Ast.TEText(`New definition:`), - Ast.TECode(next), - Ast.TEText(`Previously defined at:`), - Ast.TECode(prev), - ], -}); -const ENoInitializerParams = (loc: Ast.Loc): Ast.TcError => ({ +) => Ast.TcError( + next, + Ast.TEText(`Contract parameter ${name} was already defined`), + Ast.TEText(`New definition:`), + Ast.TECode(next), + Ast.TEText(`Previously defined at:`), + Ast.TECode(prev), +); +const ENoInitializerParams = (loc: Ast.Loc) => Ast.TcError( loc, - descr: [Ast.TEText(`Contract parameters cannot have an initializer`)], -}); -const ENoInitializerEmpty = (loc: Ast.Loc): Ast.TcError => ({ + Ast.TEText(`Contract parameters cannot have an initializer`), +); +const ENoInitializerEmpty = (loc: Ast.Loc) => Ast.TcError( loc, - descr: [ - Ast.TEText( - `When there is no init() or contract parameters, all fields must have an initializer`, - ), - ], -}); + Ast.TEText( + `When there is no init() or contract parameters, all fields must have an initializer`, + ), +); function* getMethodsFromContract( Lazy: Ast.ThunkBuilder, @@ -314,23 +314,19 @@ function* getFieldishFromContract( return { order, map }; } } -const EFieldsTwice = (loc: Ast.Loc): Ast.TcError => ({ +const EFieldsTwice = (loc: Ast.Loc) => Ast.TcError( loc, - descr: [ - Ast.TEText(`Cannot define other fields when using contract parameters`), - ], -}); + Ast.TEText(`Cannot define other fields when using contract parameters`), +); const EAbstract = ( kind: string, name: string, next: Ast.ViaMember, -): Ast.TcError => ({ - loc: next.defLoc, - descr: [ - Ast.TEText(`Contract ${kind} "${name}" must have an initializer`), - Ast.TEViaMember(next), - ], -}); +) => Ast.TcError( + next.defLoc, + Ast.TEText(`Contract ${kind} "${name}" must have an initializer`), + Ast.TEViaMember(next), +); const recover: Ast.CContractMembers = { fieldish: Ast.Ordered([], new Map()), diff --git a/src/next/types/expression.ts b/src/next/types/expression.ts index f198893b2f..a7c9e25851 100644 --- a/src/next/types/expression.ts +++ b/src/next/types/expression.ts @@ -5,8 +5,10 @@ import { Bool, builtinBinary, builtinFunctions, + builtinUnary, getStaticBuiltin, StateInit, + stateInitFields, } from "@/next/types/builtins"; import { assignType, @@ -316,31 +318,27 @@ function* checkFields( ); } } -const EMissingField = (name: string, prev: Ast.Loc): Ast.TcError => ({ - loc: prev, - descr: [ - Ast.TEText(`Value for field "${name}" is missing`), - Ast.TECode(prev), - ], -}); -const ENoSuchField = (name: string, next: Ast.Loc): Ast.TcError => ({ - loc: next, - descr: [Ast.TEText(`There is no field "${name}"`), Ast.TECode(next)], -}); +const EMissingField = (name: string, prev: Ast.Loc) => Ast.TcError( + prev, + Ast.TEText(`Value for field "${name}" is missing`), + Ast.TECode(prev), +); +const ENoSuchField = (name: string, next: Ast.Loc) => Ast.TcError( + next, + Ast.TEText(`There is no field "${name}"`), Ast.TECode(next), +); const EDuplicateField = ( name: string, prev: Ast.Loc, next: Ast.Loc, -): Ast.TcError => ({ - loc: prev, - descr: [ - Ast.TEText(`Duplicate field "${name}"`), - Ast.TEText(`Defined at:`), - Ast.TECode(next), - Ast.TEText(`Previously defined at:`), - Ast.TECode(prev), - ], -}); +) => Ast.TcError( + prev, + Ast.TEText(`Duplicate field "${name}"`), + Ast.TEText(`Defined at:`), + Ast.TECode(next), + Ast.TEText(`Previously defined at:`), + Ast.TECode(prev), +); const decodeVar: Decode = function* (node, ctx) { if (node.name !== "self") { @@ -362,10 +360,10 @@ const decodeVar: Decode = function* (node, ctx) { emptyEff, ); }; -const ENoSelf = (loc: Ast.Loc): Ast.TcError => ({ +const ENoSelf = (loc: Ast.Loc) => Ast.TcError( loc, - descr: [Ast.TEText(`"self" is not allowed here`)], -}); + Ast.TEText(`"self" is not allowed here`), +); function* lookupVar( name: string, loc: Ast.Loc, @@ -383,10 +381,10 @@ function* lookupVar( yield EUndefined(name, loc); return Ast.CTRecover(); } -const EUndefined = (name: string, loc: Ast.Loc): Ast.TcError => ({ +const EUndefined = (name: string, loc: Ast.Loc) => Ast.TcError( loc, - descr: [Ast.TEText(`Variable "${name}" not defined`)], -}); + Ast.TEText(`Variable "${name}" not defined`), +); const decodeBinary: Decode = function* ( node, @@ -402,7 +400,7 @@ const decodeBinary: Decode = function* ( [left.value.loc, left.value.computedType], [right.value.loc, right.value.computedType], ]); - if (node.op === "==" || node.op === "!=") { + if ((node.op === "==" || node.op === "!=") && returnType.kind !== 'recover') { const typeArg = typeArgMap.get("T"); if (!typeArg) { return throwInternal( @@ -428,57 +426,58 @@ const decodeBinary: Decode = function* ( newEff, ); }; -const ENoEquality = (loc: Ast.Loc): Ast.TcError => ({ +const ENoEquality = (loc: Ast.Loc) => Ast.TcError( loc, - descr: [Ast.TEText(`Equality on this type is not supported`)], -}); -const supportsEquality = (common: Ast.CType): boolean => { - switch (common.kind) { - case "map_type": { - return true; - } - case "TypeMaybe": { - return supportsEquality(common.type); - } - case "recover": - case "type_ref": - case "TypeAlias": - case "TypeParam": - case "TypeBounced": - case "tuple_type": - case "tensor_type": { - return false; - } - case "basic": { - return supportsEqualityBasic(common.type); - } - } -}; -const supportsEqualityBasic = (common: Ast.BasicType): boolean => { - switch (common.kind) { - case "unit_type": - case "TyInt": - case "TySlice": - case "TyCell": - case "TypeNull": - case "TypeBool": - case "TypeAddress": - case "TypeString": { - return true; - } - case "TypeVoid": - case "TyBuilder": - case "TypeStateInit": - case "TypeStringBuilder": { - return false; - } - } + Ast.TEText(`Equality on this type is not supported`), +); +const supportsEquality = (_common: Ast.CType): boolean => { + return true; // FIXME + // switch (common.kind) { + // case "map_type": { + // return true; + // } + // case "TypeMaybe": { + // return supportsEquality(common.type); + // } + // case "recover": + // case "type_ref": + // case "TypeAlias": + // case "TypeParam": + // case "TypeBounced": + // case "tuple_type": + // case "tensor_type": { + // return false; + // } + // case "basic": { + // return supportsEqualityBasic(common.type); + // } + // } }; +// const supportsEqualityBasic = (common: Ast.BasicType): boolean => { +// switch (common.kind) { +// case "unit_type": +// case "TyInt": +// case "TySlice": +// case "TyCell": +// case "TypeNull": +// case "TypeBool": +// case "TypeAddress": +// case "TypeString": { +// return true; +// } +// case "TypeVoid": +// case "TyBuilder": +// case "TypeStateInit": +// case "TypeStringBuilder": { +// return false; +// } +// } +// }; const decodeUnary: Decode = function* (node, ctx) { const operand = yield* decodeExprCtx(node.operand, ctx); - const fnType = builtinBinary.get(node.op); + const fnType = builtinUnary.get(node.op); if (!fnType) { return throwInternal("Builtin operator is not in the map"); } @@ -642,10 +641,10 @@ const decodeFunctionCall: Decode< return Result(Ast.CStaticCall(name, typeArgMap, exprs, returnType, node.loc), newEffs); } }; -const EMismatchSha256 = (loc: Ast.Loc): Ast.TcError => ({ +const EMismatchSha256 = (loc: Ast.Loc) => Ast.TcError( loc, - descr: [Ast.TEText(`sha256() takes either Slice or String`)], -}); + Ast.TEText(`sha256() takes either Slice or String`), +); const decodeStaticMethodCall: Decode< Ast.StaticMethodCall, @@ -688,14 +687,14 @@ const decodeStaticMethodCall: Decode< newEffs, ); }; -const EUndefinedStatic = (name: string, loc: Ast.Loc): Ast.TcError => ({ +const EUndefinedStatic = (name: string, loc: Ast.Loc) => Ast.TcError( loc, - descr: [Ast.TEText(`Static method ${name} doesn't exist`)], -}); -const EFunctionArity = (loc: Ast.Loc): Ast.TcError => ({ + Ast.TEText(`Static method ${name} doesn't exist`), +); +const EFunctionArity = (loc: Ast.Loc) => Ast.TcError( loc, - descr: [Ast.TEText(`Function doesn't take any generic arguments`)], -}); + Ast.TEText(`Function doesn't take any generic arguments`), +); const decodeFieldAccess: Decode = function* ( node, @@ -770,16 +769,27 @@ function* lookupField( } return yield* field.type(); } - case "recover": + case "recover": { + return Ast.CTRecover(); + } case "TypeAlias": { const type = yield* dealiasType(selfType, scopeRef); return yield* lookupField(type, fieldName, scopeRef); } + case "basic": { + if (selfType.type.kind === 'TypeStateInit') { + const type = stateInitFields.get(fieldName.text); + if (type) { + return type; + } + } + yield ENoSuchField(fieldName.text, fieldName.loc); + return Ast.CTRecover(); + } case "TypeParam": case "map_type": case "tuple_type": - case "tensor_type": - case "basic": { + case "tensor_type": { yield ENoSuchField(fieldName.text, fieldName.loc); return Ast.CTRecover(); } @@ -875,7 +885,7 @@ const decodeCodeOf: Decode = function* (node, ctx) { emptyEff, ); }; -const ENotContract = (name: string, loc: Ast.Loc): Ast.TcError => ({ +const ENotContract = (name: string, loc: Ast.Loc) => Ast.TcError( loc, - descr: [Ast.TEText(`"${name}" is not a contract`)], -}); + Ast.TEText(`"${name}" is not a contract`), +); diff --git a/src/next/types/extensions.ts b/src/next/types/extensions.ts index bfc5915ddf..625b875442 100644 --- a/src/next/types/extensions.ts +++ b/src/next/types/extensions.ts @@ -174,13 +174,11 @@ const EMethodOverlap = ( name: string, prev: Ast.Via, next: Ast.ViaUser, -): Ast.TcError => ({ - loc: Ast.viaToRange(next), - descr: [ - Ast.TEText(`Method "${name}" overlaps previously defined method`), - Ast.TEVia(prev), - ], -}); +) => Ast.TcError( + Ast.viaToRange(next), + Ast.TEText(`Method "${name}" overlaps previously defined method`), + Ast.TEVia(prev), +); function isCompatible( prev: Ast.CTMethod, @@ -461,15 +459,13 @@ function* toGroundType( } } -const EBadMethodType = (loc: Ast.Loc): Ast.TcError => ({ +const EBadMethodType = (loc: Ast.Loc) => Ast.TcError( loc, - descr: [ - Ast.TEText( - `Type of self must either have no type parameters, or be a generic type with distinct type parameters`, - ), - ], -}); -const ENoMethods = (kind: string, loc: Ast.Loc): Ast.TcError => ({ + Ast.TEText( + `Type of self must either have no type parameters, or be a generic type with distinct type parameters`, + ), +); +const ENoMethods = (kind: string, loc: Ast.Loc) => Ast.TcError( loc, - descr: [Ast.TEText(`Cannot define methods on ${kind}`)], -}); + Ast.TEText(`Cannot define methods on ${kind}`), +); diff --git a/src/next/types/fields.ts b/src/next/types/fields.ts index 96da867dee..046d23e07f 100644 --- a/src/next/types/fields.ts +++ b/src/next/types/fields.ts @@ -178,15 +178,13 @@ function decodeField( return Ast.DeclMem(Ast.CField(decoded, init), nextVia); } -const EMustCopyField = (name: string, prev: Ast.ViaMember): Ast.TcError => ({ - loc: prev.defLoc, - descr: [ - Ast.TEText( - `Field "${name}" was defined in parent trait, but never mentioned`, - ), - Ast.TEViaMember(prev), - ], -}); +const EMustCopyField = (name: string, prev: Ast.ViaMember) => Ast.TcError( + prev.defLoc, + Ast.TEText( + `Field "${name}" was defined in parent trait, but never mentioned`, + ), + Ast.TEViaMember(prev), +); function* decodeConstant( Lazy: Ast.ThunkBuilder, diff --git a/src/next/types/lower.ts b/src/next/types/lower.ts index fbf1263b8b..88357adb3d 100644 --- a/src/next/types/lower.ts +++ b/src/next/types/lower.ts @@ -953,30 +953,28 @@ function* (node) { const lowerInitOf: Lower = function* (node) { const type = yield* lowerType(node.computedType); - const fields = yield* Ast.mapLog(node.fields, lowerExpr); - return type && fields && + const args = yield* lowerExprs(node.args); + return type && args && Ast.LInitOf( - node.name, + node.contract, + args, type, - fields, node.loc, ); } const lowerCodeOf: Lower = function* (node) { const type = yield* lowerType(node.computedType); - const fields = yield* Ast.mapLog(node.fields, lowerExpr); - return type && fields && + return type && Ast.LCodeOf( - node.name, + node.contract, type, - fields, node.loc, ); } const lowerNull: Lower = function* (node) { - const type = yield* lowerType(node.computedType); + const type = yield* lowerTypeBasic(node.computedType); return type && Ast.LNull(type, node.loc); } const lowerVar: Lower = @@ -986,64 +984,59 @@ function* (node) { } const lowerSelf: Lower = function* (node) { - const type = yield* lowerType(node.computedType); - return type && Ast.LSelf(type, node.loc); + return Ast.LSelf(node.computedType, node.loc); } const lowerUnit: Lower = function* (node) { - const type = yield* lowerType(node.computedType); + const type = yield* lowerTypeBasic(node.computedType); return type && Ast.LUnit(type, node.loc); } const lowerTuple: Lower = function* (node) { - const type = yield* lowerType(node.computedType); - const elements = yield* Ast.mapLog(node.elements, lowerExpr); + const type = yield* lowerTypeTuple(node.computedType); + const elements = yield* lowerExprs(node.children); return type && elements && Ast.LTuple( - node.name, - type, elements, + type, node.loc, ); } const lowerTensor: Lower = function* (node) { - const type = yield* lowerType(node.computedType); - const elements = yield* Ast.mapLog(node.elements, lowerExpr); + const type = yield* lowerTypeTensor(node.computedType); + const elements = yield* lowerExprs(node.children); return type && elements && Ast.LTensor( - node.name, - type, - node.dimensions, elements, + type, node.loc, ); } const lowerMapLiteral: Lower = function* (node) { - const type = yield* lowerType(node.computedType); - const entries = yield* Ast.mapLog(node.entries, entry => { - return Ast.mapLog(entry, lowerExpr); - }); - return type && entries && + const type = yield* lowerTypeMap(node.computedType); + let failed = false; + const fields: Ast.LMapField[] = []; + for (const field of node.fields) { + const key = yield* lowerExpr(field.key); + const value = yield* lowerExpr(field.value); + if (key && value) { + fields.push({ key, value }); + } else { + failed = true; + } + } + return failed ? undefined : type && Ast.LMapLiteral( - node.name, + fields, type, - entries, node.loc, ); } const lowerSetLiteral: Lower = -function* (node) { - const type = yield* lowerType(node.computedType); - const elements = yield* Ast.mapLog(node.elements, lowerExpr); - return type && elements && - Ast.LSetLiteral( - node.name, - type, - elements, - node.loc, - ); +function* (_node) { + return throwInternal("Set literals not supported"); } const lowerParameter: Lower = @@ -1053,9 +1046,9 @@ function* (node) { } const lowerType: Lower = -function* (node) { +function (node) { switch (node.kind) { - case "recover": return undefined; + case "recover": return lowerRecover(node); case "type_ref": return lowerTypeRef(node); case "TypeAlias": return lowerTypeAliasRef(node); case "TypeParam": return lowerTypeParam(node); @@ -1068,6 +1061,11 @@ function* (node) { } } +const lowerRecover: Lower = +function* () { + return undefined; +}; + const lowerTypes: Lower = function* (nodes) { let failed = false; @@ -1130,4 +1128,4 @@ function* (node) { const lowerTypeBasic: Lower = function* (node) { return Ast.LTBasic(node.type, node.loc); -}; \ No newline at end of file +}; diff --git a/src/next/types/lvalue.ts b/src/next/types/lvalue.ts index 695f0d35c9..0685e37536 100644 --- a/src/next/types/lvalue.ts +++ b/src/next/types/lvalue.ts @@ -11,10 +11,10 @@ export function* convertExprToLValue( } return result; } -const ENoSelfAssign = (loc: Ast.Loc): Ast.TcError => ({ +const ENoSelfAssign = (loc: Ast.Loc) => Ast.TcError( loc, - descr: [Ast.TEText(`Cannot assign to self`)], -}); + Ast.TEText(`Cannot assign to self`), +); function* convertExprToLValueAux( node: Ast.CExpr, @@ -60,12 +60,10 @@ function* convertExprToLValueAux( } } } -const ENotLValue = (prev: Ast.Loc): Ast.TcError => ({ - loc: prev, - descr: [ - Ast.TEText( - `This expression cannot be used on the left side of assignment`, - ), - Ast.TECode(prev), - ], -}); +const ENotLValue = (prev: Ast.Loc) => Ast.TcError( + prev, + Ast.TEText( + `This expression cannot be used on the left side of assignment`, + ), + Ast.TECode(prev), +); diff --git a/src/next/types/message.ts b/src/next/types/message.ts index c1cd323c7c..f868269b69 100644 --- a/src/next/types/message.ts +++ b/src/next/types/message.ts @@ -47,18 +47,18 @@ export function* decodeMessage( return Ast.CMessage(lazyExpr, fields); } -const EZero = (next: Ast.Loc): Ast.TcError => ({ - loc: next, - descr: [Ast.TEText(`Zero opcode is reserved for text comments`)], -}); -const ENegative = (next: Ast.Loc): Ast.TcError => ({ - loc: next, - descr: [Ast.TEText(`Opcode must be positive`)], -}); -const ETooLarge = (next: Ast.Loc): Ast.TcError => ({ - loc: next, - descr: [Ast.TEText(`Opcode is too large`)], -}); +const EZero = (next: Ast.Loc) => Ast.TcError( + next, + Ast.TEText(`Zero opcode is reserved for text comments`), +); +const ENegative = (next: Ast.Loc) => Ast.TcError( + next, + Ast.TEText(`Opcode must be positive`), +); +const ETooLarge = (next: Ast.Loc) => Ast.TcError( + next, + Ast.TEText(`Opcode is too large`), +); function* decodeOpcode( Lazy: Ast.ThunkBuilder, diff --git a/src/next/types/methods.ts b/src/next/types/methods.ts index b6d5c34949..74e59ccb8b 100644 --- a/src/next/types/methods.ts +++ b/src/next/types/methods.ts @@ -115,10 +115,10 @@ export function* getMethodsGeneral( return all; } -const EGenericMethod = (loc: Ast.Loc): Ast.TcError => ({ +const EGenericMethod = (loc: Ast.Loc) => Ast.TcError( loc, - descr: [Ast.TEText(`Method cannot be generic`)], -}); + Ast.TEText(`Method cannot be generic`), +); function decodeGetLazy( Lazy: Ast.ThunkBuilder, @@ -202,26 +202,22 @@ function* checkMethodId(methodId: bigint, loc: Ast.Loc) { } } -const EBadId = (loc: Ast.Loc): Ast.TcError => ({ +const EBadId = (loc: Ast.Loc) => Ast.TcError( loc, - descr: [Ast.TEText(`Method ids must fit 19-bit signed integer range`)], -}); -const EReservedTvmId = (loc: Ast.Loc): Ast.TcError => ({ + Ast.TEText(`Method ids must fit 19-bit signed integer range`), +); +const EReservedTvmId = (loc: Ast.Loc) => Ast.TcError( loc, - descr: [ - Ast.TEText( - `Method ids cannot overlap with the TVM reserved ids: -4, -3, -2, -1, 0 ... 2^14 - 1`, - ), - ], -}); + Ast.TEText( + `Method ids cannot overlap with the TVM reserved ids: -4, -3, -2, -1, 0 ... 2^14 - 1`, + ), +); const EReservedTactId = ( loc: Ast.Loc, tactMethodIds: readonly bigint[], -): Ast.TcError => ({ +) => Ast.TcError( loc, - descr: [ - Ast.TEText( - `Method ids cannot overlap with Tact reserved method ids: ${tactMethodIds.map((n) => n.toString()).join(", ")}`, - ), - ], -}); + Ast.TEText( + `Method ids cannot overlap with Tact reserved method ids: ${tactMethodIds.map((n) => n.toString()).join(", ")}`, + ), +); diff --git a/src/next/types/override.ts b/src/next/types/override.ts index 09ccd975af..3cb0ce0d57 100644 --- a/src/next/types/override.ts +++ b/src/next/types/override.ts @@ -80,38 +80,32 @@ const ENeedOverride = ( name: string, prev: Ast.ViaMember, next: Ast.ViaMember, -): Ast.TcError => ({ - loc: next.defLoc, - descr: [ - Ast.TEText(`Overriding "${name}" without "override"`), - Ast.TEText(`First defined at`), - Ast.TEViaMember(prev), - Ast.TEText(`Redefined at`), - Ast.TEViaMember(next), - ], -}); +) => Ast.TcError( + next.defLoc, + Ast.TEText(`Overriding "${name}" without "override"`), + Ast.TEText(`First defined at`), + Ast.TEViaMember(prev), + Ast.TEText(`Redefined at`), + Ast.TEViaMember(next), +); const ENeedAbstract = ( name: string, prev: Ast.ViaMember, next: Ast.ViaMember, -): Ast.TcError => ({ - loc: next.defLoc, - descr: [ - Ast.TEText( - `To override "${name}" it has to be "virtual" or "abstract"`, - ), - Ast.TEText(`First defined at`), - Ast.TEViaMember(prev), - Ast.TEText(`Redefined at`), - Ast.TEViaMember(next), - ], -}); +) => Ast.TcError( + next.defLoc, + Ast.TEText( + `To override "${name}" it has to be "virtual" or "abstract"`, + ), + Ast.TEText(`First defined at`), + Ast.TEViaMember(prev), + Ast.TEText(`Redefined at`), + Ast.TEViaMember(next), +); -const EEmptyOverride = (name: string, next: Ast.ViaMember): Ast.TcError => ({ - loc: next.defLoc, - descr: [ - Ast.TEText(`To override "${name}" it has to exist`), - Ast.TEViaMember(next), - ], -}); +const EEmptyOverride = (name: string, next: Ast.ViaMember) => Ast.TcError( + next.defLoc, + Ast.TEText(`To override "${name}" it has to exist`), + Ast.TEViaMember(next), +); diff --git a/src/next/types/receivers.ts b/src/next/types/receivers.ts index 9efb290407..4fb024714f 100644 --- a/src/next/types/receivers.ts +++ b/src/next/types/receivers.ts @@ -157,32 +157,41 @@ function* mergeReceivers( via, decl: [subKind, body], } of local) { - const statements = decodeStatementsLazy( + const statements = (params: Ast.CParameters) => decodeStatementsLazy( Lazy, via.defLoc, body, - emptyTypeParams, - selfTypeRef, - Lazy({ - callback: function* () { - return Void; - }, - context: [], - loc: via.defLoc, - recover: Void, - }), + () => Ast.CTMethod( + true, + emptyTypeParams, + selfTypeRef(), + params, + Lazy({ + callback: function* () { + return Void; + }, + context: [], + loc: via.defLoc, + recover: Void, + }) + ), true, scopeRef, ); switch (subKind.kind) { case "simple": { - const { name, type } = subKind.param; - const decoded = yield* decodeDealiasTypeLazy( + const { name, type, loc } = subKind.param; + const decodedLazy = decodeDealiasTypeLazy( Lazy, emptyTypeParams, type, scopeRef, - )(); + ); + const decoded = yield* decodedLazy(); + const parameters = Ast.CParameters( + [Ast.CParameter(name, decodedLazy, loc)], + name.kind === 'id' ? new Set([name.text]) : new Set() + ); if (decoded.kind === "basic" && decoded.type.kind === "TySlice") { if (allMessageAny) { yield ERedefineReceiver( @@ -192,7 +201,7 @@ function* mergeReceivers( ); } allMessageAny = Ast.DeclMem( - Ast.CReceiverMessageAny(name, statements), + Ast.CReceiverMessageAny(name, statements(parameters)), via, ); } else if (decoded.kind === "basic" && decoded.type.kind === "TypeString") { @@ -204,13 +213,13 @@ function* mergeReceivers( ); } allStringAny = Ast.DeclMem( - Ast.CReceiverStringAny(name, statements), + Ast.CReceiverStringAny(name, statements(parameters)), via, ); } else if (decoded.kind === "type_ref") { allMessage.push( Ast.DeclMem( - Ast.CReceiverMessage(name, decoded, statements), + Ast.CReceiverMessage(name, decoded, statements(parameters)), via, ), ); @@ -227,13 +236,15 @@ function* mergeReceivers( via, ); } - allEmpty = Ast.DeclMem(Ast.CReceiverEmpty(statements), via); + const parameters = Ast.CParameters([], new Set()); + allEmpty = Ast.DeclMem(Ast.CReceiverEmpty(statements(parameters)), via); continue; } case "comment": { + const parameters = Ast.CParameters([], new Set()); allMessage.push( Ast.DeclMem( - Ast.CReceiverString(subKind.comment.value, statements), + Ast.CReceiverString(subKind.comment.value, statements(parameters)), via, ), ); @@ -298,31 +309,40 @@ function* mergeBounce( // local for (const { via, - decl: [{ name, type }, body], + decl: [{ name, type, loc }, body], } of local) { + const decodedLazy = decodeDealiasTypeLazy( + Lazy, + emptyTypeParams, + type, + scopeRef, + ); + const decoded = yield* decodedLazy(); + const parameters = Ast.CParameters( + [Ast.CParameter(name, decodedLazy, loc)], + name.kind === 'id' ? new Set([name.text]) : new Set() + ); const statements = decodeStatementsLazy( Lazy, via.defLoc, body, - emptyTypeParams, - selfTypeRef, - Lazy({ - callback: function* () { - return Void; - }, - context: [], - loc: via.defLoc, - recover: Void, - }), + () => Ast.CTMethod( + true, + emptyTypeParams, + selfTypeRef(), + parameters, + Lazy({ + callback: function* () { + return Void; + }, + context: [], + loc: via.defLoc, + recover: Void, + }) + ), true, scopeRef, ); - const decoded = yield* decodeDealiasTypeLazy( - Lazy, - emptyTypeParams, - type, - scopeRef, - )(); if (decoded.kind === "basic" && decoded.type.kind === "TySlice") { if (allMessageAny) { yield ERedefineReceiver( @@ -353,26 +373,22 @@ function* mergeBounce( }; } -const EInvalidRecv = (loc: Ast.Loc): Ast.TcError => ({ +const EInvalidRecv = (loc: Ast.Loc) => Ast.TcError( loc, - descr: [ - Ast.TEText( - `Receiver's parameter must be a message type, Slice, or String`, - ), - ], -}); + Ast.TEText( + `Receiver's parameter must be a message type, Slice, or String`, + ), +); const ERedefineReceiver = ( kind: string, prev: Ast.ViaMember, next: Ast.ViaMember, -): Ast.TcError => ({ - loc: next.defLoc, - descr: [ - Ast.TEText(`There already is a ${kind} receiver`), - Ast.TEText(`First defined at`), - Ast.TEViaMember(prev), - Ast.TEText(`Redefined at`), - Ast.TEViaMember(next), - ], -}); +) => Ast.TcError( + next.defLoc, + Ast.TEText(`There already is a ${kind} receiver`), + Ast.TEText(`First defined at`), + Ast.TEViaMember(prev), + Ast.TEText(`Redefined at`), + Ast.TEViaMember(next), +); diff --git a/src/next/types/statements.ts b/src/next/types/statements.ts index 6f41a67f32..6dca49171a 100644 --- a/src/next/types/statements.ts +++ b/src/next/types/statements.ts @@ -26,24 +26,37 @@ export function decodeStatementsLazy( Lazy: Ast.ThunkBuilder, loc: Ast.Loc, statements: readonly Ast.Statement[], - typeParams: Ast.CTypeParams, - selfTypeRef: () => undefined | Ast.SelfType, - returnType: Ast.Thunk, + fnTypeRef: () => Ast.CTFunction | Ast.CTMethod, + // typeParams: Ast.CTypeParams, + // selfTypeRef: () => undefined | Ast.SelfType, + // returnType: Ast.Thunk, isInit: boolean, scopeRef: () => Ast.CSource, + // localScopeRef: ReadonlyMap, ) { return Lazy({ callback: function* (Lazy) { - const selfType = selfTypeRef(); - const required = isInit ? yield* getRequired(selfType) : undefined; + const fnType = fnTypeRef(); + const selfType = fnType.kind === "DecodedMethodType" + ? fnType.self + : undefined; + const required = isInit + ? yield* getRequired(selfType) + : undefined; + const localScopeRef: Map = new Map(); + for (const { loc, name, type } of fnType.params.order) { + if (name.kind === 'id') { + localScopeRef.set(name.text, [yield* type(), loc]); + } + } const ctx: Context = { Lazy, - localScopeRef: new Map(), + localScopeRef, required, - returnType: yield* returnType(), + returnType: yield* fnType.returnType(), scopeRef, selfType, - typeParams, + typeParams: fnType.typeParams, }; const res = yield* decodeStmts(statements, ctx, emptyEff); return Ast.CStatementsAux(res.value, res.effects); @@ -61,6 +74,7 @@ const decodeStmts: Decode< const results: Ast.CStmt[] = []; let state = [ctx, eff] as const; for (const node of nodes) { + const [ctx, eff] = state; const result = yield* decodeStatement(node, ctx, eff); results.push(result.value); state = [result.context, allEff([eff, result.effects])]; @@ -146,12 +160,10 @@ const decodeReturn: Decode = function* (no exitEff(expr ? expr.eff : emptyEff), ); }; -const EMissingSelfInit = (name: string, loc: Ast.Loc): Ast.TcError => ({ +const EMissingSelfInit = (name: string, loc: Ast.Loc) => Ast.TcError( loc, - descr: [ - Ast.TEText(`Field "self.${name}" is not initialized by this moment`), - ], -}); + Ast.TEText(`Field "self.${name}" is not initialized by this moment`), +); function* checkReturnExpr(node: Ast.Expression | undefined, ctx: Context) { if (!node) { return undefined; @@ -512,31 +524,27 @@ function* checkFields( ); return [Ast.Ordered(order, result), ctx]; } -const EMissingField = (name: string, prev: Ast.Loc): Ast.TcError => ({ - loc: prev, - descr: [ - Ast.TEText(`Value for field "${name}" is missing`), - Ast.TECode(prev), - ], -}); -const ENoSuchField = (name: string, next: Ast.Loc): Ast.TcError => ({ - loc: next, - descr: [Ast.TEText(`There is no field "${name}"`), Ast.TECode(next)], -}); +const EMissingField = (name: string, prev: Ast.Loc) => Ast.TcError( + prev, + Ast.TEText(`Value for field "${name}" is missing`), + Ast.TECode(prev), +); +const ENoSuchField = (name: string, next: Ast.Loc) => Ast.TcError( + next, + Ast.TEText(`There is no field "${name}"`), Ast.TECode(next), +); const EDuplicateField = ( name: string, prev: Ast.Loc, next: Ast.Loc, -): Ast.TcError => ({ - loc: prev, - descr: [ - Ast.TEText(`Duplicate field "${name}"`), - Ast.TEText(`Defined at:`), - Ast.TECode(next), - Ast.TEText(`Previously defined at:`), - Ast.TECode(prev), - ], -}); +) => Ast.TcError( + prev, + Ast.TEText(`Duplicate field "${name}"`), + Ast.TEText(`Defined at:`), + Ast.TECode(next), + Ast.TEText(`Previously defined at:`), + Ast.TECode(prev), +); function* findStruct( id: Ast.TypeId, typeArgs: Ast.CType[], @@ -574,10 +582,10 @@ function* findStruct( } } } -const ENotDestructible = (name: string, prev: Ast.Loc): Ast.TcError => ({ - loc: prev, - descr: [Ast.TEText(`Type "${name}" doesn't `), Ast.TECode(prev)], -}); +const ENotDestructible = (name: string, prev: Ast.Loc) => Ast.TcError( + prev, + Ast.TEText(`Type "${name}" doesn't `), Ast.TECode(prev), +); const decodeBlock: Decode = function* ( node, @@ -652,38 +660,34 @@ function* defineVar( localScopeRef.set(node.text, [type, node.loc]); return { ...ctx, localScopeRef }; } -const ENoDefineSelf = (loc: Ast.Loc): Ast.TcError => ({ +const ENoDefineSelf = (loc: Ast.Loc) => Ast.TcError( loc, - descr: [Ast.TEText(`Cannot define a variable "self"`)], -}); + Ast.TEText(`Cannot define a variable "self"`), +); const ERedefineVar = ( name: string, prev: Ast.Loc, next: Ast.Loc, -): Ast.TcError => ({ - loc: next, - descr: [ - Ast.TEText(`Variable ${name} is already defined`), - Ast.TEText(`Defined at:`), - Ast.TECode(next), - Ast.TEText(`Previously defined at:`), - Ast.TECode(prev), - ], -}); +) => Ast.TcError( + next, + Ast.TEText(`Variable ${name} is already defined`), + Ast.TEText(`Defined at:`), + Ast.TECode(next), + Ast.TEText(`Previously defined at:`), + Ast.TECode(prev), +); const EShadowConst = ( name: string, prev: Ast.Loc, next: Ast.Loc, -): Ast.TcError => ({ - loc: next, - descr: [ - Ast.TEText(`Variable ${name} shadows a global constant`), - Ast.TEText(`Defined at:`), - Ast.TECode(next), - Ast.TEText(`Previously defined at:`), - Ast.TECode(prev), - ], -}); +) => Ast.TcError( + next, + Ast.TEText(`Variable ${name} shadows a global constant`), + Ast.TEText(`Defined at:`), + Ast.TECode(next), + Ast.TEText(`Previously defined at:`), + Ast.TECode(prev), +); function* getRequired( selfType: Ast.SelfType | undefined, diff --git a/src/next/types/struct-fields.ts b/src/next/types/struct-fields.ts index 98b8083d22..44c4853bd5 100644 --- a/src/next/types/struct-fields.ts +++ b/src/next/types/struct-fields.ts @@ -93,13 +93,11 @@ const EDuplicateField = ( name: string, prev: Ast.Loc, next: Ast.Loc, -): Ast.TcError => ({ - loc: next, - descr: [ - Ast.TEText(`Duplicate field ${name}`), - Ast.TEText(`New definition:`), - Ast.TECode(next), - Ast.TEText(`Previously defined at:`), - Ast.TECode(prev), - ], -}); +) => Ast.TcError( + next, + Ast.TEText(`Duplicate field ${name}`), + Ast.TEText(`New definition:`), + Ast.TECode(next), + Ast.TEText(`Previously defined at:`), + Ast.TECode(prev), +); diff --git a/src/next/types/trait.ts b/src/next/types/trait.ts index b2668d3e69..cb31401c95 100644 --- a/src/next/types/trait.ts +++ b/src/next/types/trait.ts @@ -68,10 +68,10 @@ export function* decodeTrait( return traitSig; } -const ENoAttributes = (loc: Ast.Loc): Ast.TcError => ({ +const ENoAttributes = (loc: Ast.Loc) => Ast.TcError( loc, - descr: [Ast.TEText(`Traits cannot have attributes`)], -}); + Ast.TEText(`Traits cannot have attributes`), +); const recover: Ast.CTraitMembers = { fieldish: Ast.Ordered([], new Map()), diff --git a/src/next/types/traits-scope.ts b/src/next/types/traits-scope.ts index d8a770076d..8320e48427 100644 --- a/src/next/types/traits-scope.ts +++ b/src/next/types/traits-scope.ts @@ -25,12 +25,12 @@ export function* getInheritedTraits( return prevTraits; } -const EUndefinedTrait = (name: string, loc: Ast.Loc): Ast.TcError => ({ +const EUndefinedTrait = (name: string, loc: Ast.Loc) => Ast.TcError( loc, - descr: [Ast.TEText(`Traits "${name}" is not defined`)], -}); + Ast.TEText(`Traits "${name}" is not defined`), +); -const EOnlyTraits = (loc: Ast.Loc): Ast.TcError => ({ +const EOnlyTraits = (loc: Ast.Loc) => Ast.TcError( loc, - descr: [Ast.TEText(`Can only inherit traits`)], -}); + Ast.TEText(`Can only inherit traits`), +); diff --git a/src/next/types/type-fn.ts b/src/next/types/type-fn.ts index e285f737c3..7da9e075a9 100644 --- a/src/next/types/type-fn.ts +++ b/src/next/types/type-fn.ts @@ -52,7 +52,7 @@ function* decodeParamName( return recoverName(name, set); } -const EDuplicateParam = (name: string, loc: Ast.Loc): Ast.TcError => ({ +const EDuplicateParam = (name: string, loc: Ast.Loc) => Ast.TcError( loc, - descr: [Ast.TEText(`Duplicate parameter "${name}"`)], -}); + Ast.TEText(`Duplicate parameter "${name}"`), +); diff --git a/src/next/types/type-params.ts b/src/next/types/type-params.ts index 8e4cf7df8d..64255b748c 100644 --- a/src/next/types/type-params.ts +++ b/src/next/types/type-params.ts @@ -23,7 +23,7 @@ export function* decodeTypeParams( return Ast.CTypeParams(ids, set); } -const EDuplicateTypeParam = (name: string, loc: Ast.Loc): Ast.TcError => ({ +const EDuplicateTypeParam = (name: string, loc: Ast.Loc) => Ast.TcError( loc, - descr: [Ast.TEText(`Duplicate type parameter "${name}"`)], -}); + Ast.TEText(`Duplicate type parameter "${name}"`), +); diff --git a/src/next/types/type.ts b/src/next/types/type.ts index 6aa309a301..481d6ae501 100644 --- a/src/next/types/type.ts +++ b/src/next/types/type.ts @@ -219,15 +219,15 @@ const getArity = (decl: Ast.CTypeDecl): number => { } }; -const EBouncedMessage = (loc: Ast.Loc): Ast.TcError => ({ +const EBouncedMessage = (loc: Ast.Loc) => Ast.TcError( loc, - descr: [Ast.TEText(`Only message types can be bounced<>`)], -}); + Ast.TEText(`Only message types can be bounced<>`), +); -const ETypeNotFound = (name: string, loc: Ast.Loc): Ast.TcError => ({ +const ETypeNotFound = (name: string, loc: Ast.Loc) => Ast.TcError( loc, - descr: [Ast.TEText(`Type "${name}" is not defined`)], -}); + Ast.TEText(`Type "${name}" is not defined`), +); function* matchArity( name: string, @@ -247,19 +247,17 @@ const EArity = ( expected: number, got: number, loc: Ast.Loc, -): Ast.TcError => ({ +) => Ast.TcError( loc, - descr: [ - Ast.TEText( - `Type "${name}" is expected to have ${expected} type arguments, got ${got}`, - ), - ], -}); + Ast.TEText( + `Type "${name}" is expected to have ${expected} type arguments, got ${got}`, + ), +); -const ETraitNotType = (loc: Ast.Loc): Ast.TcError => ({ +const ETraitNotType = (loc: Ast.Loc) => Ast.TcError( loc, - descr: [Ast.TEText(`Traits cannot be used as types`)], -}); + Ast.TEText(`Traits cannot be used as types`), +); const dealiasTypeAux = ( type: Ast.CType, @@ -490,27 +488,25 @@ export function* instantiateStruct( } } } -const ENoSuchType = (name: string, loc: Ast.Loc): Ast.TcError => ({ +const ENoSuchType = (name: string, loc: Ast.Loc) => Ast.TcError( loc, - descr: [Ast.TEText(`Type ${name} is not defined`)], -}); -const ENotInstantiable = (name: string, loc: Ast.Loc): Ast.TcError => ({ + Ast.TEText(`Type ${name} is not defined`), +); +const ENotInstantiable = (name: string, loc: Ast.Loc) => Ast.TcError( loc, - descr: [Ast.TEText(`Cannot create value of type ${name}`)], -}); + Ast.TEText(`Cannot create value of type ${name}`), +); const ETypeArity = ( name: string, loc: Ast.Loc, declArity: number, useArity: number, -): Ast.TcError => ({ +) => Ast.TcError( loc, - descr: [ - Ast.TEText( - `Type ${name} expects ${declArity} arguments, got ${useArity}`, - ), - ], -}); + Ast.TEText( + `Type ${name} expects ${declArity} arguments, got ${useArity}`, + ), +); export function typeParamsToSubst(typeParams: Ast.CTypeParams) { const subst: Map = new Map( @@ -568,14 +564,14 @@ export function* assignType( } return yield* substToTypeArgMap(loc, subst); } -const EFreeTypeParam = (paramName: string, loc: Ast.Loc): Ast.TcError => ({ +const EFreeTypeParam = (paramName: string, loc: Ast.Loc) => Ast.TcError( loc, - descr: [Ast.TEText(`No substitution for type parameter "${paramName}"`)], -}); -const EMismatch = (tree: Ast.MatchTree, loc: Ast.Loc): Ast.TcError => ({ + Ast.TEText(`No substitution for type parameter "${paramName}"`), +); +const EMismatch = (tree: Ast.MatchTree, loc: Ast.Loc) => Ast.TcError( loc, - descr: [Ast.TEText(`Type mismatch`), Ast.TEMismatch(tree)], -}); + Ast.TEText(`Type mismatch`), Ast.TEMismatch(tree), +); type AssignResult = AssignSuccess | AssignFailure; type AssignSuccess = { @@ -638,9 +634,6 @@ export function assignTypeAux( results.push(res.value); continue; } - if (!results.length) { - return AssignSuccess(); - } const toStr = printType(to, false); const fromStr = printType(from, false); if (!toStr || !fromStr) { @@ -648,6 +641,9 @@ export function assignTypeAux( // because it resulted from another error return AssignSuccess(); } + if (res.value && !results.length) { + return AssignSuccess(); + } return AssignFailure(Ast.MatchTree(to, from, results)); } } @@ -672,19 +668,11 @@ export function assignTypeAux( return yield* rec(to, from); } case "type_ref": { - const typeVar = subst.get(to.name.text); - if (!typeVar) { - return ( - to.kind === from.kind && - to.name.text === from.name.text && - (yield* recN(to.typeArgs, from.typeArgs)) - ); - } else if (typeVar.kind === "not-set") { - subst.set(to.name.text, from); - return true; - } else { - return yield* rec(typeVar, from); - } + return ( + to.kind === from.kind && + to.name.text === from.name.text && + (yield* recN(to.typeArgs, from.typeArgs)) + ); } case "tuple_type": case "tensor_type": { @@ -694,15 +682,30 @@ export function assignTypeAux( ); } case "TypeParam": { - return to.kind === from.kind && to.name.text === from.name.text; + const typeVar = subst.get(to.name.text); + if (!typeVar) { + return to.kind === from.kind && to.name.text === from.name.text; + } else if (typeVar.kind === "not-set") { + subst.set(to.name.text, from); + return true; + } else { + return yield* rec(typeVar, from); + } } case "TypeBounced": { return to.kind === from.kind && to.name.text === from.name.text; } case "TypeMaybe": { return ( + // Maybe := Null (!strict && from.kind === "basic" && from.type.kind === "TypeNull") || - (to.kind === from.kind && (yield* rec(to.type, from.type))) + ( + to.kind === from.kind + // Maybe := Maybe + ? yield* rec(to.type, from.type) + // Maybe := Cell + : !strict && (yield* rec(to.type, from)) + ) ); } case "map_type": { @@ -714,7 +717,7 @@ export function assignTypeAux( ); } case "basic": { - return from.kind === to.kind; + return from.kind === to.kind && to.type.kind === from.type.kind; } } } @@ -765,13 +768,11 @@ export function* mgu( return yield* rec(left, right); } -const ENotUnifiable = (tree: Ast.MatchTree, loc: Ast.Loc): Ast.TcError => ({ +const ENotUnifiable = (tree: Ast.MatchTree, loc: Ast.Loc) => Ast.TcError( loc, - descr: [ - Ast.TEText(`Branches of condition have mismatched types`), - Ast.TEMismatch(tree), - ], -}); + Ast.TEText(`Branches of condition have mismatched types`), + Ast.TEMismatch(tree), +); export type CallResult = { readonly returnType: Ast.CType; @@ -835,13 +836,11 @@ const EMismatchArg = ( name: string, tree: Ast.MatchTree, loc: Ast.Loc, -): Ast.TcError => ({ +) => Ast.TcError( loc, - descr: [ - Ast.TEText(`Type doesn't match type of parameter ${name}`), - Ast.TEMismatch(tree), - ], -}); + Ast.TEText(`Type doesn't match type of parameter ${name}`), + Ast.TEMismatch(tree), +); function getParamName(name: Ast.OptionalId, index: number) { return name.kind === "id" ? name.text : `#${index + 1}`; @@ -852,14 +851,12 @@ const EFnArity = ( expected: number, got: number, loc: Ast.Loc, -): Ast.TcError => ({ +) => Ast.TcError( loc, - descr: [ - Ast.TEText( - `${kind} is expected to have ${expected} type arguments, got ${got}`, - ), - ], -}); + Ast.TEText( + `${kind} is expected to have ${expected} type arguments, got ${got}`, + ), +); export function* checkFnCallWithArgs( Lazy: Ast.ThunkBuilder, @@ -893,10 +890,10 @@ export function* checkFnCallWithArgs( ), }; } -const ENoFunction = (loc: Ast.Loc): Ast.TcError => ({ +const ENoFunction = (loc: Ast.Loc) => Ast.TcError( loc, - descr: [Ast.TEText(`No such function`), Ast.TECode(loc)], -}); + Ast.TEText(`No such function`), Ast.TECode(loc), +); function substFnType( Lazy: Ast.ThunkBuilder, @@ -1089,10 +1086,10 @@ function typeArgsToParams(args: Ast.TypeArgs, params: Ast.CTypeParams) { return result; } -const ENoMethod = (loc: Ast.Loc): Ast.TcError => ({ +const ENoMethod = (loc: Ast.Loc) => Ast.TcError( loc, - descr: [Ast.TEText(`No such method`), Ast.TECode(loc)], -}); + Ast.TEText(`No such method`), Ast.TECode(loc), +); export function* assignMethodType( prev: Ast.CTMethod, @@ -1142,33 +1139,29 @@ const EMismatchReturn = ( tree: Ast.MatchTree, prev: Ast.Loc, next: Ast.Loc, -): Ast.TcError => ({ - loc: next, - descr: [ - Ast.TEText(`Return type doesn't match with inherited method`), - Ast.TEMismatch(tree), - Ast.TEText(`Inherited from:`), - Ast.TECode(prev), - Ast.TEText(`Override at:`), - Ast.TECode(next), - ], -}); +) => Ast.TcError( + next, + Ast.TEText(`Return type doesn't match with inherited method`), + Ast.TEMismatch(tree), + Ast.TEText(`Inherited from:`), + Ast.TECode(prev), + Ast.TEText(`Override at:`), + Ast.TECode(next), +); const EMismatchParam = ( name: string, tree: Ast.MatchTree, prev: Ast.Loc, next: Ast.Loc, -): Ast.TcError => ({ - loc: next, - descr: [ - Ast.TEText( - `Type of parameter ${name} doesn't match with inherited method`, - ), - Ast.TEMismatch(tree), - Ast.TEText(`Inherited from:`), - Ast.TECode(prev), - Ast.TEText(`Override at:`), - Ast.TECode(next), - ], -}); +) => Ast.TcError( + next, + Ast.TEText( + `Type of parameter ${name} doesn't match with inherited method`, + ), + Ast.TEMismatch(tree), + Ast.TEText(`Inherited from:`), + Ast.TECode(prev), + Ast.TEText(`Override at:`), + Ast.TECode(next), +); diff --git a/src/next/types/union.ts b/src/next/types/union.ts index ea9253ade2..0655813347 100644 --- a/src/next/types/union.ts +++ b/src/next/types/union.ts @@ -67,28 +67,24 @@ const EDuplicateCons = ( name: string, prev: Ast.Loc, next: Ast.Loc, -): Ast.TcError => ({ - loc: next, - descr: [ - Ast.TEText(`Duplicate union case "${name}"`), - Ast.TEText(`Defined at:`), - Ast.TECode(next), - Ast.TEText(`Previously defined at:`), - Ast.TECode(prev), - ], -}); +) => Ast.TcError( + next, + Ast.TEText(`Duplicate union case "${name}"`), + Ast.TEText(`Defined at:`), + Ast.TECode(next), + Ast.TEText(`Previously defined at:`), + Ast.TECode(prev), +); const EDuplicateField = ( name: string, prev: Ast.Loc, next: Ast.Loc, -): Ast.TcError => ({ - loc: next, - descr: [ - Ast.TEText(`Duplicate field "${name}"`), - Ast.TEText(`Defined at:`), - Ast.TECode(next), - Ast.TEText(`Previously defined at:`), - Ast.TECode(prev), - ], -}); +) => Ast.TcError( + next, + Ast.TEText(`Duplicate field "${name}"`), + Ast.TEText(`Defined at:`), + Ast.TECode(next), + Ast.TEText(`Previously defined at:`), + Ast.TECode(prev), +); diff --git a/src/stdlib/stdlib.ts b/src/stdlib/stdlib.ts index f1497f29df..7285b8e407 100644 --- a/src/stdlib/stdlib.ts +++ b/src/stdlib/stdlib.ts @@ -197,244 +197,237 @@ files["libs/stoppable.tact"] = "IHN0b3BwZWQuCiAgICByZWNlaXZlKCJSZXN1bWUiKSB7CiAgICAgICAgc2VsZi5yZXF1aXJlT3duZXIoKTsKICAgICAgICBzZWxmLnJlcXVpcmVTdG9wcGVkKCk7CiAg" + "ICAgICAgc2VsZi5zdG9wcGVkID0gZmFsc2U7CiAgICAgICAgc2VsZi5yZXBseSgiUmVzdW1lZCIuYXNDb21tZW50KCkpOwogICAgfQp9Cg=="; files["std/internal/address.tact"] = - "Ly8vIEV4dGVuc2lvbiBmdW5jdGlvbiBmb3IgdGhlIGBTbGljZWAgdHlwZS4gQXZhaWxhYmxlIHNpbmNlIFRhY3QgMS42LjAuCi8vLwovLy8gQ2FzdHMgdGhlIGBTbGlj" + - "ZWAgdG8gYW4gYEFkZHJlc3NgIGluIGEgZ2l2ZW4gYGNoYWluYCBJRCBhbmQgcmV0dXJucyBpdC4gVGhlIGludmVyc2Ugb2YgYEFkZHJlc3MuYXNTbGljZSgpYCBhbmQg" + - "YSBzYWZlIGJ1dCBtb3JlIGdhcy1leHBlbnNpdmUgdmVyc2lvbiBvZiBgU2xpY2UuYXNBZGRyZXNzVW5zYWZlKClgLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFt" + - "cGxlKCkgewovLy8gICAgIGxldCBhOiBBZGRyZXNzID0gbXlBZGRyZXNzKCk7IC8vIGxldCdzIGFzc3VtZSB3ZSdyZSBpbiBhIGJhc2VjaGFpbgovLy8gICAgIGxldCBh" + - "MjogQWRkcmVzcyA9IGEuYXNTbGljZSgpLmFzQWRkcmVzcygwKTsgLy8gc28gdGhlIGNoYWluIElEIGlzIDAKLy8vCi8vLyAgICAgYSA9PSBhMjsgLy8gdHJ1ZQovLy8g" + - "fQovLy8gYGBgCi8vLwovLy8gIyMjIyBFeGl0IGNvZGVzCi8vLwovLy8gKiAxMzY6IFtJbnZhbGlkIHN0YW5kYXJkIGFkZHJlc3NdIOKAlCBUaHJvd24gd2hlbiB0aGUg" + - "Z2l2ZW4gYFNsaWNlYCBjb250YWlucyBhbiBpbnZhbGlkCi8vLyAgIHRhZyBwcmVmaXggKG5vdCBgMGIxMDBgKSBvciBhbiBpbnZhbGlkIGFjY291bnQgSUQgbGVuZ3Ro" + - "IChub3QgMjU2IGJpdHMpLgovLy8KLy8vIFNlZToKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtY2VsbHMjc2xpY2Vhc2FkZHJlc3MKLy8v" + + "aW1wb3J0ICIuL2RlYnVnIjsKaW1wb3J0ICIuL2NlbGxzIjsKaW1wb3J0ICIuL2V4aXQtY29kZXMiOwoKLy8vIEV4dGVuc2lvbiBmdW5jdGlvbiBmb3IgdGhlIGBTbGlj" + + "ZWAgdHlwZS4gQXZhaWxhYmxlIHNpbmNlIFRhY3QgMS42LjAuCi8vLwovLy8gQ2FzdHMgdGhlIGBTbGljZWAgdG8gYW4gYEFkZHJlc3NgIGluIGEgZ2l2ZW4gYGNoYWlu" + + "YCBJRCBhbmQgcmV0dXJucyBpdC4gVGhlIGludmVyc2Ugb2YgYEFkZHJlc3MuYXNTbGljZSgpYCBhbmQgYSBzYWZlIGJ1dCBtb3JlIGdhcy1leHBlbnNpdmUgdmVyc2lv" + + "biBvZiBgU2xpY2UuYXNBZGRyZXNzVW5zYWZlKClgLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAgIGxldCBhOiBBZGRyZXNzID0gbXlB" + + "ZGRyZXNzKCk7IC8vIGxldCdzIGFzc3VtZSB3ZSdyZSBpbiBhIGJhc2VjaGFpbgovLy8gICAgIGxldCBhMjogQWRkcmVzcyA9IGEuYXNTbGljZSgpLmFzQWRkcmVzcygw" + + "KTsgLy8gc28gdGhlIGNoYWluIElEIGlzIDAKLy8vCi8vLyAgICAgYSA9PSBhMjsgLy8gdHJ1ZQovLy8gfQovLy8gYGBgCi8vLwovLy8gIyMjIyBFeGl0IGNvZGVzCi8v" + + "LwovLy8gKiAxMzY6IFtJbnZhbGlkIHN0YW5kYXJkIGFkZHJlc3NdIOKAlCBUaHJvd24gd2hlbiB0aGUgZ2l2ZW4gYFNsaWNlYCBjb250YWlucyBhbiBpbnZhbGlkCi8v" + + "LyAgIHRhZyBwcmVmaXggKG5vdCBgMGIxMDBgKSBvciBhbiBpbnZhbGlkIGFjY291bnQgSUQgbGVuZ3RoIChub3QgMjU2IGJpdHMpLgovLy8KLy8vIFNlZToKLy8vICog" + + "aHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtY2VsbHMjc2xpY2Vhc2FkZHJlc3MKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2Nv" + + "cmUtY2VsbHMjc2xpY2Vhc2FkZHJlc3N1bnNhZmUKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtYWRkcmVzc2VzI2FkZHJlc3Nhc3NsaWNl" + + "Ci8vLwovLy8gW0ludmFsaWQgc3RhbmRhcmQgYWRkcmVzc106IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL2Jvb2svZXhpdC1jb2RlcyMxMzYKLy8vCmV4dGVuZHMg" + + "ZnVuIGFzQWRkcmVzcyhzZWxmOiBTbGljZSwgY2hhaW46IEludCk6IEFkZHJlc3MgewogICAgLy8gMTEgYml0cyBmb3IgdGhlIHByZWZpeCwKICAgIC8vIDI1NiBiaXRz" + + "IGZvciB0aGUgYWRkcmVzcyBpdHNlbGYKICAgIHRocm93VW5sZXNzKFRhY3RFeGl0Q29kZUludmFsaWRTdGFuZGFyZEFkZHJlc3MsIHNlbGYuYml0cygpID09IDI2Nyk7" + + "CgogICAgaWYgKGNoYWluID09IC0xKSB7CiAgICAgICAgLy8gMTI3OSA9IDBiMTAwXzExMTFfMTExMSwKICAgICAgICAvLyBpLmUuIGludGVybmFsIGFkZHJlc3MgcHJl" + + "Zml4IGFuZCBjaGFpbiBJRCAtMQogICAgICAgIHRocm93VW5sZXNzKFRhY3RFeGl0Q29kZUludmFsaWRTdGFuZGFyZEFkZHJlc3MsIHNlbGYucHJlbG9hZFVpbnQoMTEp" + + "ID09IDEyNzkpOwogICAgfSBlbHNlIHsKICAgICAgICAvLyBPbmx5IGNoZWNrIHRoZSBjb3JyZWN0IGludGVybmFsIGFkZHJlc3MgcHJlZml4LAogICAgICAgIC8vIGJ1" + + "dCBkbyBub3QgdmVyaWZ5IHRoZSBjaGFpbiBJRAogICAgICAgIHRocm93VW5sZXNzKFRhY3RFeGl0Q29kZUludmFsaWRTdGFuZGFyZEFkZHJlc3MsIHNlbGYucHJlbG9h" + + "ZFVpbnQoMykgPT0gNCk7CiAgICB9CgogICAgLy8gUHJvY2VlZCB3aXRoIHRoZSBjYXN0CiAgICByZXR1cm4gc2VsZi5hc0FkZHJlc3NVbnNhZmUoKTsKfQoKLy8vIEV4" + + "dGVuc2lvbiBmdW5jdGlvbiBmb3IgdGhlIGBTbGljZWAgdHlwZS4gQXZhaWxhYmxlIHNpbmNlIFRhY3QgMS42LjAuCi8vLwovLy8gVW5zYWZlbHkgY2FzdHMgdGhlIGBT" + + "bGljZWAgdG8gYW4gYEFkZHJlc3NgIGFuZCByZXR1cm5zIGl0LiBUaGUgaW52ZXJzZSBvZiBgQWRkcmVzcy5hc1NsaWNlKClgLgovLy8KLy8vIFRoaXMgZnVuY3Rpb24g" + + "ZG9lcyAqKm5vdCoqIHBlcmZvcm0gYW55IGNoZWNrcyBvbiB0aGUgY29udGVudHMgb2YgdGhlIGBTbGljZWAuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGUo" + + "KSB7Ci8vLyAgICAgbGV0IGE6IEFkZHJlc3MgPSBteUFkZHJlc3MoKTsKLy8vICAgICBsZXQgYTI6IEFkZHJlc3MgPSBhLmFzU2xpY2UoKS5hc0FkZHJlc3NVbnNhZmUo" + + "KTsKLy8vCi8vLyAgICAgYSA9PSBhMjsgLy8gdHJ1ZQovLy8gfQovLy8gYGBgCi8vLwovLy8gVXNlIGl0IG9ubHkgaWYgeW91IHdhbnQgdG8gb3B0aW1pemUgdGhlIGNv" + + "ZGUgZm9yIGdhcyBhbmQgY2FuIGd1YXJhbnRlZSBpbiBhZHZhbmNlIHRoYXQgdGhlIGBTbGljZWAgY29udGFpbnMgdGhlIGRhdGEgb2YgYW4gYEFkZHJlc3NgLgovLy8K" + + "Ly8vIE90aGVyd2lzZSwgdXNlIGEgc2FmZXIgYnV0IG1vcmUgZ2FzLWV4cGVuc2l2ZSBgU2xpY2UuYXNBZGRyZXNzKClgIGZ1bmN0aW9uLgovLy8KLy8vIFNlZToKLy8v" + "ICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtY2VsbHMjc2xpY2Vhc2FkZHJlc3N1bnNhZmUKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5v" + - "cmcvcmVmL2NvcmUtYWRkcmVzc2VzI2FkZHJlc3Nhc3NsaWNlCi8vLwovLy8gW0ludmFsaWQgc3RhbmRhcmQgYWRkcmVzc106IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcu" + - "b3JnL2Jvb2svZXhpdC1jb2RlcyMxMzYKLy8vCmV4dGVuZHMgZnVuIGFzQWRkcmVzcyhzZWxmOiBTbGljZSwgY2hhaW46IEludCk6IEFkZHJlc3MgewogICAgLy8gMTEg" + - "Yml0cyBmb3IgdGhlIHByZWZpeCwKICAgIC8vIDI1NiBiaXRzIGZvciB0aGUgYWRkcmVzcyBpdHNlbGYKICAgIHRocm93VW5sZXNzKFRhY3RFeGl0Q29kZUludmFsaWRT" + - "dGFuZGFyZEFkZHJlc3MsIHNlbGYuYml0cygpID09IDI2Nyk7CgogICAgaWYgKGNoYWluID09IC0xKSB7CiAgICAgICAgLy8gMTI3OSA9IDBiMTAwXzExMTFfMTExMSwK" + - "ICAgICAgICAvLyBpLmUuIGludGVybmFsIGFkZHJlc3MgcHJlZml4IGFuZCBjaGFpbiBJRCAtMQogICAgICAgIHRocm93VW5sZXNzKFRhY3RFeGl0Q29kZUludmFsaWRT" + - "dGFuZGFyZEFkZHJlc3MsIHNlbGYucHJlbG9hZFVpbnQoMTEpID09IDEyNzkpOwogICAgfSBlbHNlIHsKICAgICAgICAvLyBPbmx5IGNoZWNrIHRoZSBjb3JyZWN0IGlu" + - "dGVybmFsIGFkZHJlc3MgcHJlZml4LAogICAgICAgIC8vIGJ1dCBkbyBub3QgdmVyaWZ5IHRoZSBjaGFpbiBJRAogICAgICAgIHRocm93VW5sZXNzKFRhY3RFeGl0Q29k" + - "ZUludmFsaWRTdGFuZGFyZEFkZHJlc3MsIHNlbGYucHJlbG9hZFVpbnQoMykgPT0gNCk7CiAgICB9CgogICAgLy8gUHJvY2VlZCB3aXRoIHRoZSBjYXN0CiAgICByZXR1" + - "cm4gc2VsZi5hc0FkZHJlc3NVbnNhZmUoKTsKfQoKLy8vIEV4dGVuc2lvbiBmdW5jdGlvbiBmb3IgdGhlIGBTbGljZWAgdHlwZS4gQXZhaWxhYmxlIHNpbmNlIFRhY3Qg" + - "MS42LjAuCi8vLwovLy8gVW5zYWZlbHkgY2FzdHMgdGhlIGBTbGljZWAgdG8gYW4gYEFkZHJlc3NgIGFuZCByZXR1cm5zIGl0LiBUaGUgaW52ZXJzZSBvZiBgQWRkcmVz" + - "cy5hc1NsaWNlKClgLgovLy8KLy8vIFRoaXMgZnVuY3Rpb24gZG9lcyAqKm5vdCoqIHBlcmZvcm0gYW55IGNoZWNrcyBvbiB0aGUgY29udGVudHMgb2YgdGhlIGBTbGlj" + - "ZWAuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKSB7Ci8vLyAgICAgbGV0IGE6IEFkZHJlc3MgPSBteUFkZHJlc3MoKTsKLy8vICAgICBsZXQgYTI6IEFk" + - "ZHJlc3MgPSBhLmFzU2xpY2UoKS5hc0FkZHJlc3NVbnNhZmUoKTsKLy8vCi8vLyAgICAgYSA9PSBhMjsgLy8gdHJ1ZQovLy8gfQovLy8gYGBgCi8vLwovLy8gVXNlIGl0" + - "IG9ubHkgaWYgeW91IHdhbnQgdG8gb3B0aW1pemUgdGhlIGNvZGUgZm9yIGdhcyBhbmQgY2FuIGd1YXJhbnRlZSBpbiBhZHZhbmNlIHRoYXQgdGhlIGBTbGljZWAgY29u" + - "dGFpbnMgdGhlIGRhdGEgb2YgYW4gYEFkZHJlc3NgLgovLy8KLy8vIE90aGVyd2lzZSwgdXNlIGEgc2FmZXIgYnV0IG1vcmUgZ2FzLWV4cGVuc2l2ZSBgU2xpY2UuYXNB" + - "ZGRyZXNzKClgIGZ1bmN0aW9uLgovLy8KLy8vIFNlZToKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtY2VsbHMjc2xpY2Vhc2FkZHJlc3N1" + - "bnNhZmUKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtY2VsbHMjc2xpY2Vhc2FkZHJlc3MKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFu" + - "Zy5vcmcvcmVmL2NvcmUtYWRkcmVzc2VzI2FkZHJlc3Nhc3NsaWNlCi8vLwphc20gZXh0ZW5kcyBmdW4gYXNBZGRyZXNzVW5zYWZlKHNlbGY6IFNsaWNlKTogQWRkcmVz" + - "cyB7fQoKLy8vIEV4dGVuc2lvbiBmdW5jdGlvbiBmb3IgdGhlIGBBZGRyZXNzYCB0eXBlLgovLy8KLy8vIENhc3RzIGBzZWxmYCBiYWNrIHRvIHRoZSB1bmRlcmx5aW5n" + - "IGBTbGljZWAgYW5kIHJldHVybnMgaXQuIFRoZSBpbnZlcnNlIG9mIGBTbGljZS5hc0FkZHJlc3NVbnNhZmUoKWAuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1w" + - "bGUoKSB7Ci8vLyAgICAgbGV0IGE6IEFkZHJlc3MgPSBteUFkZHJlc3MoKTsKLy8vICAgICBsZXQgZml6ejogU2xpY2UgPSBiZWdpbkNlbGwoKS5zdG9yZUFkZHJlc3Mo" + - "YSkuYXNTbGljZSgpOwovLy8gICAgIGxldCBidXp6OiBTbGljZSA9IGEuYXNTbGljZSgpOyAvLyBjaGVhcCwgdW5saWtlIHRoZSBwcmV2aW91cyBzdGF0ZW1lbnQKLy8v" + - "Ci8vLyAgICAgZml6eiA9PSBidXp6OyAvLyB0cnVlCi8vLyB9Ci8vLyBgYGAKLy8vCi8vLyBTZWU6Ci8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9j" + - "b3JlLWFkZHJlc3NlcyNhZGRyZXNzYXNzbGljZQovLy8gKiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1jZWxscyNzbGljZWFzYWRkcmVzc3Vuc2Fm" + - "ZQovLy8KYXNtIGV4dGVuZHMgZnVuIGFzU2xpY2Uoc2VsZjogQWRkcmVzcyk6IFNsaWNlIHt9CgovLy8gR2xvYmFsIGZ1bmN0aW9uLgovLy8KLy8vIENyZWF0ZXMgYSBu" + - "ZXcgYEFkZHJlc3NgIGJhc2VkIG9uIHRoZSBgY2hhaW5gIElEIGFuZCB0aGUgU0hBLTI1NiBlbmNvZGVkIGBoYXNoYCB2YWx1ZSAoYWNjb3VudCBJRCkuCi8vLwovLy8g" + - "VGhpcyBmdW5jdGlvbiB0cmllcyB0byByZXNvbHZlIGNvbnN0YW50IHZhbHVlcyBpbiBjb21waWxlLXRpbWUgd2hlbmV2ZXIgcG9zc2libGUuCi8vLwovLy8gQXR0ZW1w" + - "dHMgdG8gc3BlY2lmeSBhbiB1bmNvbW1vbiBgY2hhaW5gIElEIChub3QgLTEgb3IgMCkgdGhhdCBjYW4gYmUgZGV0ZWN0ZWQgaW4gY29tcGlsZS10aW1lIHdpbGwgcmVz" + - "dWx0IGluIGEgY29tcGlsYXRpb24gZXJyb3IuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKSB7Ci8vLyAgICAgbGV0IG9sZFRvbkZvdW5kYXRpb25BZGRy" + - "OiBBZGRyZXNzID0KLy8vICAgICAgICAgbmV3QWRkcmVzcygwLCAweDgzZGZkNTUyZTYzNzI5YjQ3MmZjYmNjOGM0NWViY2M2NjkxNzAyNTU4YjY4ZWM3NTI3ZTFiYTQw" + - "M2EwZjMxYTgpOwovLy8gICAgICAgICAvLyAgICAgICAgIOKGkSAg4oaRCi8vLyAgICAgICAgIC8vICAgICAgICAgfCAgc2hhLTI1NiBoYXNoIG9mIGNvbnRyYWN0J3Mg" + - "aW5pdCBwYWNrYWdlIChTdGF0ZUluaXQpCi8vLyAgICAgICAgIC8vICAgICAgICAgY2hhaW4gaWQ6IDAgaXMgYSB3b3JrY2hhaW4sIC0xIGlzIGEgbWFzdGVyY2hhaW4K" + - "Ly8vIH0KLy8vIGBgYAovLy8KLy8vIFNlZTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtYWRkcmVzc2VzI25ld2FkZHJlc3MKLy8vCmlubGluZSBm" + - "dW4gbmV3QWRkcmVzcyhjaGFpbjogSW50LCBoYXNoOiBJbnQpOiBBZGRyZXNzIHsKICAgIHJldHVybiBiZWdpbkNlbGwoKQogICAgICAgIC5zdG9yZVVpbnQoMGIxMF8w" + - "LCAzKQogICAgICAgIC5zdG9yZUludChjaGFpbiwgOCkKICAgICAgICAuc3RvcmVVaW50KGhhc2gsIDI1NikKICAgICAgICAuZW5kQ2VsbCgpCiAgICAgICAgLmFzU2xp" + - "Y2UoKQogICAgICAgIC5hc0FkZHJlc3NVbnNhZmUoKTsKfQoKLy8vIFN0cnVjdCByZXByZXNlbnRpbmcgdGhlIHN0YW5kYXJkIGFkZHJlc3Mgb24gVE9OIEJsb2NrY2hh" + - "aW4gd2l0aCBzaWduZWQgOC1iaXQgYHdvcmtjaGFpbmAgSUQgYW5kIGFuIHVuc2lnbmVkIDI1Ni1iaXQgYGFkZHJlc3NgIGluIHRoZSBzcGVjaWZpZWQgYHdvcmtjaGFp" + - "bmAuIEF2YWlsYWJsZSBzaW5jZSBUYWN0IDEuNS4wLgovLy8KLy8vIEF0IHRoZSBtb21lbnQsIG9ubHkgYHdvcmtjaGFpbmAgSURzIHVzZWQgb24gVE9OIGFyZSAwIG9m" + - "IHRoZSBiYXNlY2hhaW4gYW5kIC0xIG9mIHRoZSBtYXN0ZXJjaGFpbi4KLy8vCi8vLyBTZWU6Ci8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3Jl" + - "LWFkZHJlc3NlcyNwYXJzZXN0ZGFkZHJlc3MKLy8vICogaHR0cHM6Ly9naXRodWIuY29tL3Rvbi1ibG9ja2NoYWluL3Rvbi9ibG9iL21hc3Rlci9jcnlwdG8vYmxvY2sv" + - "YmxvY2sudGxiI0wxMDUtTDEwNgovLy8Kc3RydWN0IFN0ZEFkZHJlc3MgewogICAgd29ya2NoYWluOiBJbnQgYXMgaW50ODsKICAgIGFkZHJlc3M6IEludCBhcyB1aW50" + - "MjU2Owp9CgovLy8gRGVwcmVjYXRlZCBzaW5jZSBUYWN0IDEuNi44LiBBbnkgdXNhZ2VzIG9mIHRoaXMgc3RydWN0dXJlIHdpbGwgYmUgcmVwb3J0ZWQgYXMgYW4gZXJy" + - "b3IuCi8vLwovLy8gU3RydWN0IHJlcHJlc2VudGluZyB0aGUgYWRkcmVzcyBvZiB2YXJpYWJsZSBsZW5ndGggd2l0aCBzaWduZWQgMzItYml0IGB3b3JrY2hhaW5gIElE" + - "IGFuZCBhIGBTbGljZWAgY29udGFpbmluZyB1bnNpZ25lZCBgYWRkcmVzc2AgaW4gdGhlIHNwZWNpZmllZCBgd29ya2NoYWluYC4gQXZhaWxhYmxlIHNpbmNlIFRhY3Qg" + - "MS41LjAuCi8vLwovLy8gVmFyaWFibGUtbGVuZ3RoIGFkZHJlc3NlcyBhcmUgaW50ZW5kZWQgZm9yIGZ1dHVyZSBleHRlbnNpb25zLCBhbmQgd2hpbGUgdmFsaWRhdG9y" + - "cyBtdXN0IGJlIHJlYWR5IHRvIGFjY2VwdCB0aGVtIGluIGluYm91bmQgbWVzc2FnZXMsIHRoZSBzdGFuZGFyZCAobm9uLXZhcmlhYmxlKSBhZGRyZXNzZXMgYXJlIHVz" + - "ZWQgd2hlbmV2ZXIgcG9zc2libGUuCi8vLwovLy8gU2VlOgovLy8gKiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1hZGRyZXNzZXMjcGFyc2V2YXJh" + - "ZGRyZXNzCi8vLyAqIGh0dHBzOi8vZ2l0aHViLmNvbS90b24tYmxvY2tjaGFpbi90b24vYmxvYi9tYXN0ZXIvY3J5cHRvL2Jsb2NrL2Jsb2NrLnRsYiNMMTA3LUwxMDgK" + - "Ly8vCnN0cnVjdCBWYXJBZGRyZXNzIHsKICAgIHdvcmtjaGFpbjogSW50IGFzIGludDMyOwogICAgYWRkcmVzczogU2xpY2U7Cn0KCi8vLyBHbG9iYWwgZnVuY3Rpb24u" + - "IEF2YWlsYWJsZSBzaW5jZSBUYWN0IDEuNS4wLgovLy8KLy8vIENvbnZlcnRzIGEgYHNsaWNlYCBjb250YWluaW5nIGFuIGFkZHJlc3MgaW50byB0aGUgYFN0ZEFkZHJl" + - "c3NgIHN0cnVjdCBhbmQgcmV0dXJucyBpdC4KLy8vCi8vLyBgYGB0YWN0Ci8vLyBmdW4gZXhhbXBsZSgpIHsKLy8vICAgICBsZXQgYWRkciA9IGFkZHJlc3MoIkVRRHRG" + - "cEV3Y0ZBRWNSZTVtTFZoMk42QzB4LV9oSkVNN1c2MV9KTG5TRjc0cDRxMiIpOwovLy8gICAgIGxldCBwYXJzZWRBZGRyID0gcGFyc2VTdGRBZGRyZXNzKGFkZHIuYXNT" + - "bGljZSgpKTsKLy8vCi8vLyAgICAgcGFyc2VkQWRkci53b3JrY2hhaW47IC8vIDAKLy8vICAgICBwYXJzZWRBZGRyLmFkZHJlc3M7ICAgLy8gMTA3Li4uMjg3Ci8vLyB9" + - "Ci8vLyBgYGAKLy8vCi8vLyAjIyMjIEV4aXQgY29kZXMKLy8vCi8vLyAqIDk6IFtDZWxsIHVuZGVyZmxvd10g4oCUIFRocm93biB3aGVuIHRoZSBzcGVjaWZpZWQgYHNs" + - "aWNlYCBjYW5ub3QgYmUgcGFyc2VkIGFzIGEgYFN0ZEFkZHJlc3NgLgovLy8KLy8vIFNlZTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtYWRkcmVz" + - "c2VzI3BhcnNlc3RkYWRkcmVzcwovLy8KLy8vIFtDZWxsIHVuZGVyZmxvd106IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL2Jvb2svZXhpdC1jb2RlcyM5Ci8vLwph" + - "c20gZnVuIHBhcnNlU3RkQWRkcmVzcyhzbGljZTogU2xpY2UpOiBTdGRBZGRyZXNzIHsgUkVXUklURVNUREFERFIgfQoKLy8vIEdsb2JhbCBmdW5jdGlvbi4gQXZhaWxh" + - "YmxlIHNpbmNlIFRhY3QgMS41LjAuCi8vLwovLy8gRGVwcmVjYXRlZCBzaW5jZSBUYWN0IDEuNi44LiBBbnkgdXNhZ2VzIG9mIHRoaXMgZnVuY3Rpb24gd2lsbCBiZSBy" + - "ZXBvcnRlZCBhcyBhbiBlcnJvci4KLy8vCi8vLyBDb252ZXJ0cyBhIGBzbGljZWAgY29udGFpbmluZyBhbiBhZGRyZXNzIG9mIHZhcmlhYmxlIGxlbmd0aCBpbnRvIHRo" + - "ZSBgVmFyQWRkcmVzc2Agc3RydWN0IGFuZCByZXR1cm5zIGl0LgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAgIGxldCB2YXJBZGRyU2xp" + - "Y2UgPSBiZWdpbkNlbGwoKQovLy8gICAgICAgICAuc3RvcmVVaW50KDYsIDMpICAgICAvLyB0byByZWNvZ25pemUgdGhlIGZvbGxvd2luZyBhcyBhIFZhckFkZHJlc3MK" + - "Ly8vICAgICAgICAgLnN0b3JlVWludCgxMjMsIDkpICAgLy8gbWFrZSBhZGRyZXNzIG9jY3VweSAxMjMgYml0cwovLy8gICAgICAgICAuc3RvcmVVaW50KDIzNCwgMzIp" + - "ICAvLyBzcGVjaWZ5IHdvcmtjaGFpbiBJRCBvZiAyMzQKLy8vICAgICAgICAgLnN0b3JlVWludCgzNDUsIDEyMykgLy8gc3BlY2lmeSBhZGRyZXNzIG9mIDM0NQovLy8g" + - "ICAgICAgICAuYXNTbGljZSgpOwovLy8gICAgIGxldCBwYXJzZWRWYXJBZGRyID0gcGFyc2VWYXJBZGRyZXNzKHZhckFkZHJTbGljZSk7Ci8vLwovLy8gICAgIHBhcnNl" + - "ZFZhckFkZHIud29ya2NoYWluOyAgICAgICAgICAgICAvLyAyMzQKLy8vICAgICBwYXJzZWRWYXJBZGRyLmFkZHJlc3M7ICAgICAgICAgICAgICAgLy8gQ1N7Q2VsbHsw" + - "MDIuLi4yYjN9IGJpdHM6IDQ0Li4xNjc7IHJlZnM6IDAuLjB9Ci8vLyAgICAgcGFyc2VkVmFyQWRkci5hZGRyZXNzLmxvYWRVaW50KDEyMyk7IC8vIDM0NQovLy8gfQov" + - "Ly8gYGBgCi8vLwovLy8gIyMjIyBFeGl0IGNvZGVzCi8vLwovLy8gKiA5OiBbQ2VsbCB1bmRlcmZsb3ddIOKAlCBUaHJvd24gd2hlbiB0aGUgc3BlY2lmaWVkIGBzbGlj" + - "ZWAgY2Fubm90IGJlIHBhcnNlZCBhcyBhIGBWYXJBZGRyZXNzYC4KLy8vCi8vLyBTZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWFkZHJlc3Nl" + - "cyNwYXJzZXZhcmFkZHJlc3MKLy8vCi8vLyBbQ2VsbCB1bmRlcmZsb3ddOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9ib29rL2V4aXQtY29kZXMjOQovLy8KYXNt" + - "IGZ1biBwYXJzZVZhckFkZHJlc3Moc2xpY2U6IFNsaWNlKTogVmFyQWRkcmVzcyB7IFJFV1JJVEVWQVJBRERSIH0KCi8vLyBFeHRlbnNpb24gbXV0YXRpb24gZnVuY3Rp" + - "b24gZm9yIHRoZSBgU2xpY2VgIHR5cGUuCi8vLwovLy8gTG9hZHMgYW5kIHJldHVybnMgYW4gYEFkZHJlc3NgIGZyb20gdGhlIGBTbGljZWAuCi8vLwovLy8gYGBgdGFj" + - "dAovLy8gZnVuIGV4YW1wbGUoKSB7Ci8vLyAgICAgbGV0IHM6IFNsaWNlID0gYmVnaW5DZWxsKCkuc3RvcmVBZGRyZXNzKG15QWRkcmVzcygpKS5hc1NsaWNlKCk7Ci8v" + - "LyAgICAgbGV0IGZpeno6IEFkZHJlc3MgPSBzLmxvYWRBZGRyZXNzKCk7Ci8vLyB9Ci8vLyBgYGAKLy8vCi8vLyAjIyMjIEV4aXQgY29kZXMKLy8vCi8vLyAqIDk6IFtD" + - "ZWxsIHVuZGVyZmxvd10g4oCUIFRocm93biB3aGVuIGF0dGVtcHRpbmcgdG8gbG9hZCBtb3JlIGRhdGEgdGhhbiBgU2xpY2VgIGNvbnRhaW5zLgovLy8KLy8vIFNlZTog" + - "aHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtY2VsbHMjc2xpY2Vsb2FkYWRkcmVzcwovLy8KLy8vIFtDZWxsIHVuZGVyZmxvd106IGh0dHBzOi8vZG9j" + - "cy50YWN0LWxhbmcub3JnL2Jvb2svZXhpdC1jb2RlcyM5Ci8vLwphc20oLT4gMSAwKSBleHRlbmRzIG11dGF0ZXMgZnVuIGxvYWRBZGRyZXNzKHNlbGY6IFNsaWNlKTog" + - "QWRkcmVzcyB7IExETVNHQUREUiB9CgovLy8gRXh0ZW5zaW9uIG11dGF0aW9uIGZ1bmN0aW9uIGZvciB0aGUgYFNsaWNlYCB0eXBlLiBBdmFpbGFibGUgc2luY2UgVGFj" + - "dCAxLjYuMi4KLy8vCi8vLyBTa2lwcyBhbiBgQWRkcmVzc2AgZnJvbSB0aGUgYFNsaWNlYC4KLy8vCi8vLyBgYGB0YWN0Ci8vLyBmdW4gZXhhbXBsZSgpIHsKLy8vICAg" + - "ICBsZXQgczE6IFNsaWNlID0gYmVnaW5DZWxsKCkKLy8vICAgICAgICAgLnN0b3JlQWRkcmVzcyhteUFkZHJlc3MoKSkKLy8vICAgICAgICAgLnN0b3JlVWludCg0Miwg" + - "MzIpCi8vLyAgICAgICAgIC5hc1NsaWNlKCk7Ci8vLwovLy8gICAgIHMxLnNraXBBZGRyZXNzKCk7Ci8vLyAgICAgbGV0IGZpeno6IEludCA9IHMxLmxvYWRVaW50KDMy" + - "KTsgLy8gNDIKLy8vIH0KLy8vIGBgYAovLy8KLy8vICMjIyMgRXhpdCBjb2RlcwovLy8KLy8vICogOTogW0NlbGwgdW5kZXJmbG93XSDigJQgVGhyb3duIHdoZW4gYXR0" + - "ZW1wdGluZyB0byBza2lwIG1vcmUgZGF0YSB0aGFuIGBTbGljZWAgY29udGFpbnMuCi8vLwovLy8gU2VlOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29y" + - "ZS1jZWxscyNzbGljZXNraXBhZGRyZXNzCi8vLwovLy8gW0NlbGwgdW5kZXJmbG93XTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvYm9vay9leGl0LWNvZGVzIzkK" + - "Ly8vCmFzbSBleHRlbmRzIG11dGF0ZXMgZnVuIHNraXBBZGRyZXNzKHNlbGY6IFNsaWNlKSB7IExETVNHQUREUiBOSVAgfQoKLy8vIEV4dGVuc2lvbiBmdW5jdGlvbiBm" + - "b3IgdGhlIGBCdWlsZGVyYCB0eXBlLgovLy8KLy8vIFN0b3JlcyB0aGUgYGFkZHJlc3NgIGluIHRoZSBjb3B5IG9mIHRoZSBgQnVpbGRlcmAuIFJldHVybnMgdGhhdCBj" + - "b3B5LgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAgIGxldCBiOiBCdWlsZGVyID0gYmVnaW5DZWxsKCk7Ci8vLyAgICAgbGV0IGZpeno6" + - "IEJ1aWxkZXIgPSBiLnN0b3JlQWRkcmVzcyhteUFkZHJlc3MoKSk7Ci8vLyB9Ci8vLyBgYGAKLy8vCi8vLyAjIyMjIEV4aXQgY29kZXMKLy8vCi8vLyAqIDg6IFtDZWxs" + - "IG92ZXJmbG93XSDigJQgVGhyb3duIHdoZW4gYXR0ZW1wdGluZyB0byBzdG9yZSBhbiBgYWRkcmVzc2AgaW50byB0aGUgYEJ1aWxkZXJgIHdoZW4gaXQgY2Fubm90IGZp" + - "dCBpdC4KLy8vCi8vLyBTZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWNlbGxzI2J1aWxkZXJzdG9yZWFkZHJlc3MKLy8vCi8vLyBbQ2VsbCBv" + - "dmVyZmxvd106IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL2Jvb2svZXhpdC1jb2RlcyM4Ci8vLwphc20gZXh0ZW5kcyBmdW4gc3RvcmVBZGRyZXNzKHNlbGY6IEJ1" + - "aWxkZXIsIGFkZHJlc3M6IEFkZHJlc3MpOiBCdWlsZGVyIHsgU1RTTElDRVIgfQoKLy8vIFN0cnVjdCByZXByZXNlbnRpbmcgYSBiYXNlY2hhaW4gYWRkcmVzcy4gQXZh" + - "aWxhYmxlIHNpbmNlIFRhY3QgMS42LjAuCi8vLwovLy8gQSBiYXNlY2hhaW4gYWRkcmVzcyAod29ya2NoYWluIDApIGNhbiBiZSBlaXRoZXIgZW1wdHkgKG51bGwgaGFz" + - "aCkgb3IgY29udGFpbiBhIDI1Ni1iaXQgaGFzaCB2YWx1ZS4KLy8vCi8vLyBTZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWFkZHJlc3NlcyNi" + - "YXNlY2hhaW5hZGRyZXNzCi8vLwpzdHJ1Y3QgQmFzZWNoYWluQWRkcmVzcyB7CiAgICBoYXNoOiBJbnQ/Owp9CgovLy8gR2xvYmFsIGZ1bmN0aW9uLiBBdmFpbGFibGUg" + - "c2luY2UgVGFjdCAxLjYuMC4KLy8vCi8vLyBDcmVhdGVzIGFuZCByZXR1cm5zIGFuIGVtcHR5IGJhc2VjaGFpbiBhZGRyZXNzIHdpdGggYSBudWxsIGhhc2guCi8vLwov" + - "Ly8gV2hlbiBzZXJpYWxpemVkLCBhbiBlbXB0eSBiYXNlY2hhaW4gYWRkcmVzcyBpcyByZXByZXNlbnRlZCBhcyBgYWRkcl9ub25lYC4KLy8vCi8vLyBgYGB0YWN0Ci8v" + - "LyBmdW4gZXhhbXBsZSgpIHsKLy8vICAgICBsZXQgZW1wdHlBZGRyOiBCYXNlY2hhaW5BZGRyZXNzID0gZW1wdHlCYXNlY2hhaW5BZGRyZXNzKCk7Ci8vLyAgICAgZW1w" + - "dHlBZGRyLmhhc2ggPT0gbnVsbDsgLy8gdHJ1ZQovLy8gfQovLy8gYGBgCi8vLwovLy8gU2VlOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1hZGRy" + - "ZXNzZXMjZW1wdHliYXNlY2hhaW5hZGRyZXNzCi8vLwppbmxpbmUgZnVuIGVtcHR5QmFzZWNoYWluQWRkcmVzcygpOiBCYXNlY2hhaW5BZGRyZXNzIHsKICAgIHJldHVy" + - "biBCYXNlY2hhaW5BZGRyZXNzIHsgaGFzaDogbnVsbCB9Owp9CgovLy8gR2xvYmFsIGZ1bmN0aW9uLiBBdmFpbGFibGUgc2luY2UgVGFjdCAxLjYuMC4KLy8vCi8vLyBD" + - "cmVhdGVzIGFuZCByZXR1cm5zIGEgbmV3IGJhc2VjaGFpbiBhZGRyZXNzIHdpdGggdGhlIHNwZWNpZmllZCBoYXNoIHZhbHVlLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1" + - "biBleGFtcGxlKCkgewovLy8gICAgIGxldCBhZGRyOiBCYXNlY2hhaW5BZGRyZXNzID0gbmV3QmFzZWNoYWluQWRkcmVzcygweDgzZGZkNTUyZTYzNzI5YjQ3MmZjYmNj" + - "OGM0NWViY2M2NjkxNzAyNTU4YjY4ZWM3NTI3ZTFiYTQwM2EwZjMxYTgpOwovLy8gfQovLy8gYGBgCi8vLwovLy8gU2VlOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9y" + - "Zy9yZWYvY29yZS1hZGRyZXNzZXMjbmV3YmFzZWNoYWluYWRkcmVzcwovLy8KaW5saW5lIGZ1biBuZXdCYXNlY2hhaW5BZGRyZXNzKGhhc2g6IEludCk6IEJhc2VjaGFp" + - "bkFkZHJlc3MgewogICAgcmV0dXJuIEJhc2VjaGFpbkFkZHJlc3MgeyBoYXNoIH07Cn0KCi8vLyBHbG9iYWwgZnVuY3Rpb24uIEF2YWlsYWJsZSBzaW5jZSBUYWN0IDEu" + - "Ni4wLgovLy8KLy8vIENyZWF0ZXMgYW5kIHJldHVybnMgYSBiYXNlY2hhaW4gYWRkcmVzcyBkZXJpdmVkIGZyb20gYSBjb250cmFjdCdzIGBTdGF0ZUluaXRgIChjb2Rl" + - "IGFuZCBkYXRhKS4KLy8vCi8vLyBgYGB0YWN0Ci8vLyBmdW4gZXhhbXBsZSgpIHsKLy8vICAgICBsZXQgY29kZTogQ2VsbCA9IGxvYWRDZWxsKCk7IC8vIGxvYWQgY29u" + - "dHJhY3QgY29kZQovLy8gICAgIGxldCBkYXRhOiBDZWxsID0gbG9hZENlbGwoKTsgLy8gbG9hZCBjb250cmFjdCBkYXRhCi8vLyAgICAgbGV0IHN0YXRlOiBTdGF0ZUlu" + - "aXQgPSBTdGF0ZUluaXQgeyBjb2RlLCBkYXRhIH07Ci8vLyAgICAgbGV0IGFkZHI6IEJhc2VjaGFpbkFkZHJlc3MgPSBjb250cmFjdEJhc2VjaGFpbkFkZHJlc3Moc3Rh" + - "dGUpOwovLy8gfQovLy8gYGBgCi8vLwovLy8gU2VlOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1hZGRyZXNzZXMjY29udHJhY3RiYXNlY2hhaW5h" + - "ZGRyZXNzCi8vLwppbmxpbmUgZnVuIGNvbnRyYWN0QmFzZWNoYWluQWRkcmVzcyhzOiBTdGF0ZUluaXQpOiBCYXNlY2hhaW5BZGRyZXNzIHsKICAgIGxldCBoYXNoID0g" + - "Y29udHJhY3RIYXNoKHMuY29kZSwgcy5kYXRhKTsKICAgIHJldHVybiBuZXdCYXNlY2hhaW5BZGRyZXNzKGhhc2gpOwp9CgovLy8gRXh0ZW5zaW9uIGZ1bmN0aW9uIGZv" + - "ciB0aGUgYEJ1aWxkZXJgIHR5cGUuIEF2YWlsYWJsZSBzaW5jZSBUYWN0IDEuNi4wLgovLy8KLy8vIFN0b3JlcyB0aGUgYmFzZWNoYWluIGFkZHJlc3MgaW4gdGhlIGNv" + - "cHkgb2YgdGhlIEJ1aWxkZXIgYW5kIHJldHVybnMgdGhhdCBjb3B5LgovLy8KLy8vIElmIHRoZSBhZGRyZXNzIGhhcyBhIGBudWxsYCBoYXNoLCBzdG9yZXMgdHdvIHpl" + - "cm8gYml0cyBgMGIwMGAgKGBhZGRyX25vbmVgKS4gT3RoZXJ3aXNlLAovLy8gc3RvcmVzIHRoZSBmdWxsIGFkZHJlc3Mgd2l0aCB0aGUgdGhyZWUtYml0IHByZWZpeCBg" + - "MGIxMDBgLAovLy8gZm9sbG93ZWQgYnkgdGhlIDgtYml0IHdvcmtjaGFpbiBJRCBzZXQgdG8gMCBhbmQgdGhlIDI1Ni1iaXQgaGFzaC4KLy8vCi8vLyBgYGB0YWN0Ci8v" + - "LyBmdW4gZXhhbXBsZSgpIHsKLy8vICAgICBsZXQgYWRkcjogQmFzZWNoYWluQWRkcmVzcyA9IG5ld0Jhc2VjaGFpbkFkZHJlc3MoMHg4M2RmZDU1MmU2MzcyOWI0NzJm" + - "Y2JjYzhjNDVlYmNjNjY5MTcwMjU1OGI2OGVjNzUyN2UxYmE0MDNhMGYzMWE4KTsKLy8vICAgICBsZXQgYjogQnVpbGRlciA9IGJlZ2luQ2VsbCgpOwovLy8gICAgIGxl" + - "dCBiMjogQnVpbGRlciA9IGIuc3RvcmVCYXNlY2hhaW5BZGRyZXNzKGFkZHIpOwovLy8gfQovLy8gYGBgCi8vLwovLy8gIyMjIyBFeGl0IGNvZGVzCi8vLwovLy8gKiA4" + - "OiBbQ2VsbCBvdmVyZmxvd10g4oCUIFRocm93biB3aGVuIGF0dGVtcHRpbmcgdG8gc3RvcmUgYW4gYGFkZHJlc3NgIGludG8gdGhlIGBCdWlsZGVyYCB3aGVuIGl0IGNh" + - "bm5vdCBmaXQgaXQuCi8vLwovLy8gU2VlOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1jZWxscyNidWlsZGVyc3RvcmViYXNlY2hhaW5hZGRyZXNz" + - "Ci8vLwovLy8gW0NlbGwgb3ZlcmZsb3ddOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9ib29rL2V4aXQtY29kZXMjOAovLy8KZXh0ZW5kcyBmdW4gc3RvcmVCYXNl" + - "Y2hhaW5BZGRyZXNzKHNlbGY6IEJ1aWxkZXIsIGFkZHJlc3M6IEJhc2VjaGFpbkFkZHJlc3MpOiBCdWlsZGVyIHsKICAgIGlmIChhZGRyZXNzLmhhc2ggPT0gbnVsbCkg" + - "ewogICAgICAgIHJldHVybiBzZWxmLnN0b3JlVWludCgwLCAyKTsgLy8gMGIwMAogICAgfQoKICAgIHJldHVybiBzZWxmCiAgICAgICAgLnN0b3JlVWludCgwYjEwXzBf" + - "MDAwMDAwMDAsIDMgKyA4KQogICAgICAgIC5zdG9yZVVpbnQoYWRkcmVzcy5oYXNoISEsIDI1Nik7Cn0KCi8vLyBHbG9iYWwgZnVuY3Rpb24uIEF2YWlsYWJsZSBzaW5j" + - "ZSBUYWN0IDEuNi4zLgovLy8KLy8vIENoZWNrcyB3aGV0aGVyIHRoZSBgYWRkcmVzc2AgaXMgaW4gdGhlIGJhc2VjaGFpbiwgaS5lLiwgaXRzIGNoYWluIElEIGlzIDAu" + - "Ci8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGVzKCkgewovLy8gICAgIGxldCBzb21lQmFzZWNoYWluQWRkcmVzczogQWRkcmVzcyA9Ci8vLyAgICAgICAgIG5l" + - "d0FkZHJlc3MoMCwgMHg4M2RmZDU1MmU2MzcyOWI0NzJmY2JjYzhjNDVlYmNjNjY5MTcwMjU1OGI2OGVjNzUyN2UxYmE0MDNhMGYzMWE4KTsKLy8vCi8vLyAgICAgbGV0" + - "IHNvbWVNYXN0ZXJjaGFpbkFkZHJlc3M6IEFkZHJlc3MgPQovLy8gICAgICAgICBuZXdBZGRyZXNzKC0xLCAweDgzZGZkNTUyZTYzNzI5YjQ3MmZjYmNjOGM0NWViY2M2" + - "NjkxNzAyNTU4YjY4ZWM3NTI3ZTFiYTQwM2EwZjMxYTgpOwovLy8KLy8vICAgICAvLyBEb2VzIG5vdCB0aHJvdyBiZWNhdXNlIHRoZSBjaGFpbiBJRCBpcyAwCi8vLyAg" + - "ICAgZm9yY2VCYXNlY2hhaW4oc29tZUJhc2VjaGFpbkFkZHJlc3MpOwovLy8KLy8vICAgICB0cnkgewovLy8gICAgICAgICAvLyBUaHJvd3MgYmVjYXVzZSB0aGUgY2hh" + - "aW4gSUQgaXMgLTEgKG1hc3RlcmNoYWluKQovLy8gICAgICAgICBmb3JjZUJhc2VjaGFpbihzb21lTWFzdGVyY2hhaW5BZGRyZXNzKTsKLy8vICAgICB9IGNhdGNoIChl" + - "eGl0Q29kZSkgewovLy8gICAgICAgICAvLyBleGl0Q29kZSBpcyAxMzgKLy8vICAgICB9Ci8vLyB9Ci8vLyBgYGAKLy8vCi8vLyAjIyMjIEV4aXQgY29kZXMKLy8vCi8v" + - "LyAqIDEzODogW05vdCBhIGJhc2VjaGFpbiBhZGRyZXNzXSDigJQgVGhyb3duIHdoZW4gdGhlIGdpdmVuIGBhZGRyZXNzYCBpcyBub3QgaW4gdGhlIGJhc2VjaGFpbiAo" + - "Y2hhaW4gSUQgaXMgbm90IDApLgovLy8KLy8vIFNlZTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtYWRkcmVzc2VzI2ZvcmNlYmFzZWNoYWluCi8v" + - "LwovLy8gW05vdCBhIGJhc2VjaGFpbiBhZGRyZXNzXTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvYm9vay9leGl0LWNvZGVzIzEzOAovLy8KYXNtIGZ1biBmb3Jj" + - "ZUJhc2VjaGFpbihhZGRyZXNzOiBBZGRyZXNzKSB7IFJFV1JJVEVTVERBRERSIERST1AgMTM4IFRIUk9XSUYgfQoKLy8vIEdsb2JhbCBmdW5jdGlvbi4gQXZhaWxhYmxl" + - "IHNpbmNlIFRhY3QgMS42LjQuCi8vLwovLy8gQ2hlY2tzIHdoZXRoZXIgdGhlIGBhZGRyZXNzYCBpcyBpbiB0aGUgYHdvcmtjaGFpbmAsIGkuZS4sIGl0cyBjaGFpbiBJ" + - "RCBpcyBlcXVhbCB0byBgd29ya2NoYWluYC4KLy8vCi8vLyBgYGB0YWN0Ci8vLyBmdW4gZXhhbXBsZXMoKSB7Ci8vLyAgICAgbGV0IHNvbWVCYXNlY2hhaW5BZGRyZXNz" + - "OiBBZGRyZXNzID0KLy8vICAgICAgICAgbmV3QWRkcmVzcygwLCAweDgzZGZkNTUyZTYzNzI5YjQ3MmZjYmNjOGM0NWViY2M2NjkxNzAyNTU4YjY4ZWM3NTI3ZTFiYTQw" + - "M2EwZjMxYTgpOwovLy8KLy8vICAgICBsZXQgc29tZU1hc3RlcmNoYWluQWRkcmVzczogQWRkcmVzcyA9Ci8vLyAgICAgICAgIG5ld0FkZHJlc3MoLTEsIDB4ODNkZmQ1" + - "NTJlNjM3MjliNDcyZmNiY2M4YzQ1ZWJjYzY2OTE3MDI1NThiNjhlYzc1MjdlMWJhNDAzYTBmMzFhOCk7Ci8vLwovLy8gICAgIC8vIERvZXMgbm90IHRocm93IGJlY2F1" + - "c2UgdGhlIGNoYWluIElEIG1hdGNoZXMgd29ya2NoYWluIHBhcmFtZXRlcgovLy8gICAgIGZvcmNlV29ya2NoYWluKHNvbWVCYXNlY2hhaW5BZGRyZXNzLCAwLCA1OTMp" + - "OwovLy8gICAgIGZvcmNlV29ya2NoYWluKHNvbWVNYXN0ZXJjaGFpbkFkZHJlc3MsIC0xLCA1OTMpOwovLy8KLy8vICAgICB0cnkgewovLy8gICAgICAgICAvLyBUaHJv" + - "d3MgYmVjYXVzZSB0aGUgY2hhaW4gSUQgaXMgMCB3aGljaCBkb2Vzbid0IG1hdGNoIHRoZSB3b3JrY2hhaW4gcGFyYW1ldGVyLCAtMQovLy8gICAgICAgICBmb3JjZVdv" + - "cmtjaGFpbihzb21lQmFzZWNoYWluQWRkcmVzcywgLTEsIDU5Myk7Ci8vLyAgICAgfSBjYXRjaCAoZXhpdENvZGUpIHsKLy8vICAgICAgICAgLy8gZXhpdENvZGUgaXMg" + - "NTkzCi8vLyAgICAgfQovLy8gfQovLy8gYGBgCi8vLwovLy8gIyMjIyBFeGl0IGNvZGVzCi8vLwovLy8gKiBgZXJyb3JDb2RlYCDigJQgVGhyb3duIHdoZW4gdGhlIGdp" + - "dmVuIGBhZGRyZXNzYCBpcyBub3QgaW4gdGhlIHNwZWNpZmllZCBgd29ya2NoYWluYCAoY2hhaW4gSUQgaXMgbm90IGVxdWFsIHRvIGB3b3JrY2hhaW5gKS4KLy8vCi8v" + - "LyBTZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWFkZHJlc3NlcyNmb3JjZXdvcmtjaGFpbgovLy8KYXNtKGVycm9yQ29kZSB3b3JrY2hhaW4g" + - "YWRkcmVzcykgZnVuIGZvcmNlV29ya2NoYWluKGFkZHJlc3M6IEFkZHJlc3MsIHdvcmtjaGFpbjogSW50LCBlcnJvckNvZGU6IEludCkgewogICAgUkVXUklURVNUREFE" + - "RFIKICAgIERST1AKICAgIENNUAogICAgVEhST1dBTllJRgp9Cg=="; + "cmcvcmVmL2NvcmUtY2VsbHMjc2xpY2Vhc2FkZHJlc3MKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtYWRkcmVzc2VzI2FkZHJlc3Nhc3Ns" + + "aWNlCi8vLwphc20gZXh0ZW5kcyBmdW4gYXNBZGRyZXNzVW5zYWZlKHNlbGY6IFNsaWNlKTogQWRkcmVzcyB7fQoKLy8vIEV4dGVuc2lvbiBmdW5jdGlvbiBmb3IgdGhl" + + "IGBBZGRyZXNzYCB0eXBlLgovLy8KLy8vIENhc3RzIGBzZWxmYCBiYWNrIHRvIHRoZSB1bmRlcmx5aW5nIGBTbGljZWAgYW5kIHJldHVybnMgaXQuIFRoZSBpbnZlcnNl" + + "IG9mIGBTbGljZS5hc0FkZHJlc3NVbnNhZmUoKWAuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKSB7Ci8vLyAgICAgbGV0IGE6IEFkZHJlc3MgPSBteUFk" + + "ZHJlc3MoKTsKLy8vICAgICBsZXQgZml6ejogU2xpY2UgPSBiZWdpbkNlbGwoKS5zdG9yZUFkZHJlc3MoYSkuYXNTbGljZSgpOwovLy8gICAgIGxldCBidXp6OiBTbGlj" + + "ZSA9IGEuYXNTbGljZSgpOyAvLyBjaGVhcCwgdW5saWtlIHRoZSBwcmV2aW91cyBzdGF0ZW1lbnQKLy8vCi8vLyAgICAgZml6eiA9PSBidXp6OyAvLyB0cnVlCi8vLyB9" + + "Ci8vLyBgYGAKLy8vCi8vLyBTZWU6Ci8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWFkZHJlc3NlcyNhZGRyZXNzYXNzbGljZQovLy8gKiBo" + + "dHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1jZWxscyNzbGljZWFzYWRkcmVzc3Vuc2FmZQovLy8KYXNtIGV4dGVuZHMgZnVuIGFzU2xpY2Uoc2VsZjog" + + "QWRkcmVzcyk6IFNsaWNlIHt9CgovLy8gR2xvYmFsIGZ1bmN0aW9uLgovLy8KLy8vIENyZWF0ZXMgYSBuZXcgYEFkZHJlc3NgIGJhc2VkIG9uIHRoZSBgY2hhaW5gIElE" + + "IGFuZCB0aGUgU0hBLTI1NiBlbmNvZGVkIGBoYXNoYCB2YWx1ZSAoYWNjb3VudCBJRCkuCi8vLwovLy8gVGhpcyBmdW5jdGlvbiB0cmllcyB0byByZXNvbHZlIGNvbnN0" + + "YW50IHZhbHVlcyBpbiBjb21waWxlLXRpbWUgd2hlbmV2ZXIgcG9zc2libGUuCi8vLwovLy8gQXR0ZW1wdHMgdG8gc3BlY2lmeSBhbiB1bmNvbW1vbiBgY2hhaW5gIElE" + + "IChub3QgLTEgb3IgMCkgdGhhdCBjYW4gYmUgZGV0ZWN0ZWQgaW4gY29tcGlsZS10aW1lIHdpbGwgcmVzdWx0IGluIGEgY29tcGlsYXRpb24gZXJyb3IuCi8vLwovLy8g" + + "YGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKSB7Ci8vLyAgICAgbGV0IG9sZFRvbkZvdW5kYXRpb25BZGRyOiBBZGRyZXNzID0KLy8vICAgICAgICAgbmV3QWRkcmVzcygw" + + "LCAweDgzZGZkNTUyZTYzNzI5YjQ3MmZjYmNjOGM0NWViY2M2NjkxNzAyNTU4YjY4ZWM3NTI3ZTFiYTQwM2EwZjMxYTgpOwovLy8gICAgICAgICAvLyAgICAgICAgIOKG" + + "kSAg4oaRCi8vLyAgICAgICAgIC8vICAgICAgICAgfCAgc2hhLTI1NiBoYXNoIG9mIGNvbnRyYWN0J3MgaW5pdCBwYWNrYWdlIChTdGF0ZUluaXQpCi8vLyAgICAgICAg" + + "IC8vICAgICAgICAgY2hhaW4gaWQ6IDAgaXMgYSB3b3JrY2hhaW4sIC0xIGlzIGEgbWFzdGVyY2hhaW4KLy8vIH0KLy8vIGBgYAovLy8KLy8vIFNlZTogaHR0cHM6Ly9k" + + "b2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtYWRkcmVzc2VzI25ld2FkZHJlc3MKLy8vCmlubGluZSBmdW4gbmV3QWRkcmVzcyhjaGFpbjogSW50LCBoYXNoOiBJbnQp" + + "OiBBZGRyZXNzIHsKICAgIHJldHVybiBiZWdpbkNlbGwoKQogICAgICAgIC5zdG9yZVVpbnQoMGIxMF8wLCAzKQogICAgICAgIC5zdG9yZUludChjaGFpbiwgOCkKICAg" + + "ICAgICAuc3RvcmVVaW50KGhhc2gsIDI1NikKICAgICAgICAuZW5kQ2VsbCgpCiAgICAgICAgLmFzU2xpY2UoKQogICAgICAgIC5hc0FkZHJlc3NVbnNhZmUoKTsKfQoK" + + "Ly8vIFN0cnVjdCByZXByZXNlbnRpbmcgdGhlIHN0YW5kYXJkIGFkZHJlc3Mgb24gVE9OIEJsb2NrY2hhaW4gd2l0aCBzaWduZWQgOC1iaXQgYHdvcmtjaGFpbmAgSUQg" + + "YW5kIGFuIHVuc2lnbmVkIDI1Ni1iaXQgYGFkZHJlc3NgIGluIHRoZSBzcGVjaWZpZWQgYHdvcmtjaGFpbmAuIEF2YWlsYWJsZSBzaW5jZSBUYWN0IDEuNS4wLgovLy8K" + + "Ly8vIEF0IHRoZSBtb21lbnQsIG9ubHkgYHdvcmtjaGFpbmAgSURzIHVzZWQgb24gVE9OIGFyZSAwIG9mIHRoZSBiYXNlY2hhaW4gYW5kIC0xIG9mIHRoZSBtYXN0ZXJj" + + "aGFpbi4KLy8vCi8vLyBTZWU6Ci8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWFkZHJlc3NlcyNwYXJzZXN0ZGFkZHJlc3MKLy8vICogaHR0" + + "cHM6Ly9naXRodWIuY29tL3Rvbi1ibG9ja2NoYWluL3Rvbi9ibG9iL21hc3Rlci9jcnlwdG8vYmxvY2svYmxvY2sudGxiI0wxMDUtTDEwNgovLy8Kc3RydWN0IFN0ZEFk" + + "ZHJlc3MgewogICAgd29ya2NoYWluOiBJbnQgYXMgaW50ODsKICAgIGFkZHJlc3M6IEludCBhcyB1aW50MjU2Owp9CgovLy8gRGVwcmVjYXRlZCBzaW5jZSBUYWN0IDEu" + + "Ni44LiBBbnkgdXNhZ2VzIG9mIHRoaXMgc3RydWN0dXJlIHdpbGwgYmUgcmVwb3J0ZWQgYXMgYW4gZXJyb3IuCi8vLwovLy8gU3RydWN0IHJlcHJlc2VudGluZyB0aGUg" + + "YWRkcmVzcyBvZiB2YXJpYWJsZSBsZW5ndGggd2l0aCBzaWduZWQgMzItYml0IGB3b3JrY2hhaW5gIElEIGFuZCBhIGBTbGljZWAgY29udGFpbmluZyB1bnNpZ25lZCBg" + + "YWRkcmVzc2AgaW4gdGhlIHNwZWNpZmllZCBgd29ya2NoYWluYC4gQXZhaWxhYmxlIHNpbmNlIFRhY3QgMS41LjAuCi8vLwovLy8gVmFyaWFibGUtbGVuZ3RoIGFkZHJl" + + "c3NlcyBhcmUgaW50ZW5kZWQgZm9yIGZ1dHVyZSBleHRlbnNpb25zLCBhbmQgd2hpbGUgdmFsaWRhdG9ycyBtdXN0IGJlIHJlYWR5IHRvIGFjY2VwdCB0aGVtIGluIGlu" + + "Ym91bmQgbWVzc2FnZXMsIHRoZSBzdGFuZGFyZCAobm9uLXZhcmlhYmxlKSBhZGRyZXNzZXMgYXJlIHVzZWQgd2hlbmV2ZXIgcG9zc2libGUuCi8vLwovLy8gU2VlOgov" + + "Ly8gKiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1hZGRyZXNzZXMjcGFyc2V2YXJhZGRyZXNzCi8vLyAqIGh0dHBzOi8vZ2l0aHViLmNvbS90b24t" + + "YmxvY2tjaGFpbi90b24vYmxvYi9tYXN0ZXIvY3J5cHRvL2Jsb2NrL2Jsb2NrLnRsYiNMMTA3LUwxMDgKLy8vCnN0cnVjdCBWYXJBZGRyZXNzIHsKICAgIHdvcmtjaGFp" + + "bjogSW50IGFzIGludDMyOwogICAgYWRkcmVzczogU2xpY2U7Cn0KCi8vLyBHbG9iYWwgZnVuY3Rpb24uIEF2YWlsYWJsZSBzaW5jZSBUYWN0IDEuNS4wLgovLy8KLy8v" + + "IENvbnZlcnRzIGEgYHNsaWNlYCBjb250YWluaW5nIGFuIGFkZHJlc3MgaW50byB0aGUgYFN0ZEFkZHJlc3NgIHN0cnVjdCBhbmQgcmV0dXJucyBpdC4KLy8vCi8vLyBg" + + "YGB0YWN0Ci8vLyBmdW4gZXhhbXBsZSgpIHsKLy8vICAgICBsZXQgYWRkciA9IGFkZHJlc3MoIkVRRHRGcEV3Y0ZBRWNSZTVtTFZoMk42QzB4LV9oSkVNN1c2MV9KTG5T" + + "Rjc0cDRxMiIpOwovLy8gICAgIGxldCBwYXJzZWRBZGRyID0gcGFyc2VTdGRBZGRyZXNzKGFkZHIuYXNTbGljZSgpKTsKLy8vCi8vLyAgICAgcGFyc2VkQWRkci53b3Jr" + + "Y2hhaW47IC8vIDAKLy8vICAgICBwYXJzZWRBZGRyLmFkZHJlc3M7ICAgLy8gMTA3Li4uMjg3Ci8vLyB9Ci8vLyBgYGAKLy8vCi8vLyAjIyMjIEV4aXQgY29kZXMKLy8v" + + "Ci8vLyAqIDk6IFtDZWxsIHVuZGVyZmxvd10g4oCUIFRocm93biB3aGVuIHRoZSBzcGVjaWZpZWQgYHNsaWNlYCBjYW5ub3QgYmUgcGFyc2VkIGFzIGEgYFN0ZEFkZHJl" + + "c3NgLgovLy8KLy8vIFNlZTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtYWRkcmVzc2VzI3BhcnNlc3RkYWRkcmVzcwovLy8KLy8vIFtDZWxsIHVu" + + "ZGVyZmxvd106IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL2Jvb2svZXhpdC1jb2RlcyM5Ci8vLwphc20gZnVuIHBhcnNlU3RkQWRkcmVzcyhzbGljZTogU2xpY2Up" + + "OiBTdGRBZGRyZXNzIHsgUkVXUklURVNUREFERFIgfQoKLy8vIEdsb2JhbCBmdW5jdGlvbi4gQXZhaWxhYmxlIHNpbmNlIFRhY3QgMS41LjAuCi8vLwovLy8gRGVwcmVj" + + "YXRlZCBzaW5jZSBUYWN0IDEuNi44LiBBbnkgdXNhZ2VzIG9mIHRoaXMgZnVuY3Rpb24gd2lsbCBiZSByZXBvcnRlZCBhcyBhbiBlcnJvci4KLy8vCi8vLyBDb252ZXJ0" + + "cyBhIGBzbGljZWAgY29udGFpbmluZyBhbiBhZGRyZXNzIG9mIHZhcmlhYmxlIGxlbmd0aCBpbnRvIHRoZSBgVmFyQWRkcmVzc2Agc3RydWN0IGFuZCByZXR1cm5zIGl0" + + "LgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAgIGxldCB2YXJBZGRyU2xpY2UgPSBiZWdpbkNlbGwoKQovLy8gICAgICAgICAuc3RvcmVV" + + "aW50KDYsIDMpICAgICAvLyB0byByZWNvZ25pemUgdGhlIGZvbGxvd2luZyBhcyBhIFZhckFkZHJlc3MKLy8vICAgICAgICAgLnN0b3JlVWludCgxMjMsIDkpICAgLy8g" + + "bWFrZSBhZGRyZXNzIG9jY3VweSAxMjMgYml0cwovLy8gICAgICAgICAuc3RvcmVVaW50KDIzNCwgMzIpICAvLyBzcGVjaWZ5IHdvcmtjaGFpbiBJRCBvZiAyMzQKLy8v" + + "ICAgICAgICAgLnN0b3JlVWludCgzNDUsIDEyMykgLy8gc3BlY2lmeSBhZGRyZXNzIG9mIDM0NQovLy8gICAgICAgICAuYXNTbGljZSgpOwovLy8gICAgIGxldCBwYXJz" + + "ZWRWYXJBZGRyID0gcGFyc2VWYXJBZGRyZXNzKHZhckFkZHJTbGljZSk7Ci8vLwovLy8gICAgIHBhcnNlZFZhckFkZHIud29ya2NoYWluOyAgICAgICAgICAgICAvLyAy" + + "MzQKLy8vICAgICBwYXJzZWRWYXJBZGRyLmFkZHJlc3M7ICAgICAgICAgICAgICAgLy8gQ1N7Q2VsbHswMDIuLi4yYjN9IGJpdHM6IDQ0Li4xNjc7IHJlZnM6IDAuLjB9" + + "Ci8vLyAgICAgcGFyc2VkVmFyQWRkci5hZGRyZXNzLmxvYWRVaW50KDEyMyk7IC8vIDM0NQovLy8gfQovLy8gYGBgCi8vLwovLy8gIyMjIyBFeGl0IGNvZGVzCi8vLwov" + + "Ly8gKiA5OiBbQ2VsbCB1bmRlcmZsb3ddIOKAlCBUaHJvd24gd2hlbiB0aGUgc3BlY2lmaWVkIGBzbGljZWAgY2Fubm90IGJlIHBhcnNlZCBhcyBhIGBWYXJBZGRyZXNz" + + "YC4KLy8vCi8vLyBTZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWFkZHJlc3NlcyNwYXJzZXZhcmFkZHJlc3MKLy8vCi8vLyBbQ2VsbCB1bmRl" + + "cmZsb3ddOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9ib29rL2V4aXQtY29kZXMjOQovLy8KYXNtIGZ1biBwYXJzZVZhckFkZHJlc3Moc2xpY2U6IFNsaWNlKTog" + + "VmFyQWRkcmVzcyB7IFJFV1JJVEVWQVJBRERSIH0KCi8vLyBFeHRlbnNpb24gbXV0YXRpb24gZnVuY3Rpb24gZm9yIHRoZSBgU2xpY2VgIHR5cGUuCi8vLwovLy8gTG9h" + + "ZHMgYW5kIHJldHVybnMgYW4gYEFkZHJlc3NgIGZyb20gdGhlIGBTbGljZWAuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKSB7Ci8vLyAgICAgbGV0IHM6" + + "IFNsaWNlID0gYmVnaW5DZWxsKCkuc3RvcmVBZGRyZXNzKG15QWRkcmVzcygpKS5hc1NsaWNlKCk7Ci8vLyAgICAgbGV0IGZpeno6IEFkZHJlc3MgPSBzLmxvYWRBZGRy" + + "ZXNzKCk7Ci8vLyB9Ci8vLyBgYGAKLy8vCi8vLyAjIyMjIEV4aXQgY29kZXMKLy8vCi8vLyAqIDk6IFtDZWxsIHVuZGVyZmxvd10g4oCUIFRocm93biB3aGVuIGF0dGVt" + + "cHRpbmcgdG8gbG9hZCBtb3JlIGRhdGEgdGhhbiBgU2xpY2VgIGNvbnRhaW5zLgovLy8KLy8vIFNlZTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUt" + + "Y2VsbHMjc2xpY2Vsb2FkYWRkcmVzcwovLy8KLy8vIFtDZWxsIHVuZGVyZmxvd106IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL2Jvb2svZXhpdC1jb2RlcyM5Ci8v" + + "Lwphc20oLT4gMSAwKSBleHRlbmRzIG11dGF0ZXMgZnVuIGxvYWRBZGRyZXNzKHNlbGY6IFNsaWNlKTogQWRkcmVzcyB7IExETVNHQUREUiB9CgovLy8gRXh0ZW5zaW9u" + + "IG11dGF0aW9uIGZ1bmN0aW9uIGZvciB0aGUgYFNsaWNlYCB0eXBlLiBBdmFpbGFibGUgc2luY2UgVGFjdCAxLjYuMi4KLy8vCi8vLyBTa2lwcyBhbiBgQWRkcmVzc2Ag" + + "ZnJvbSB0aGUgYFNsaWNlYC4KLy8vCi8vLyBgYGB0YWN0Ci8vLyBmdW4gZXhhbXBsZSgpIHsKLy8vICAgICBsZXQgczE6IFNsaWNlID0gYmVnaW5DZWxsKCkKLy8vICAg" + + "ICAgICAgLnN0b3JlQWRkcmVzcyhteUFkZHJlc3MoKSkKLy8vICAgICAgICAgLnN0b3JlVWludCg0MiwgMzIpCi8vLyAgICAgICAgIC5hc1NsaWNlKCk7Ci8vLwovLy8g" + + "ICAgIHMxLnNraXBBZGRyZXNzKCk7Ci8vLyAgICAgbGV0IGZpeno6IEludCA9IHMxLmxvYWRVaW50KDMyKTsgLy8gNDIKLy8vIH0KLy8vIGBgYAovLy8KLy8vICMjIyMg" + + "RXhpdCBjb2RlcwovLy8KLy8vICogOTogW0NlbGwgdW5kZXJmbG93XSDigJQgVGhyb3duIHdoZW4gYXR0ZW1wdGluZyB0byBza2lwIG1vcmUgZGF0YSB0aGFuIGBTbGlj" + + "ZWAgY29udGFpbnMuCi8vLwovLy8gU2VlOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1jZWxscyNzbGljZXNraXBhZGRyZXNzCi8vLwovLy8gW0Nl" + + "bGwgdW5kZXJmbG93XTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvYm9vay9leGl0LWNvZGVzIzkKLy8vCmFzbSBleHRlbmRzIG11dGF0ZXMgZnVuIHNraXBBZGRy" + + "ZXNzKHNlbGY6IFNsaWNlKSB7IExETVNHQUREUiBOSVAgfQoKLy8vIEV4dGVuc2lvbiBmdW5jdGlvbiBmb3IgdGhlIGBCdWlsZGVyYCB0eXBlLgovLy8KLy8vIFN0b3Jl" + + "cyB0aGUgYGFkZHJlc3NgIGluIHRoZSBjb3B5IG9mIHRoZSBgQnVpbGRlcmAuIFJldHVybnMgdGhhdCBjb3B5LgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxl" + + "KCkgewovLy8gICAgIGxldCBiOiBCdWlsZGVyID0gYmVnaW5DZWxsKCk7Ci8vLyAgICAgbGV0IGZpeno6IEJ1aWxkZXIgPSBiLnN0b3JlQWRkcmVzcyhteUFkZHJlc3Mo" + + "KSk7Ci8vLyB9Ci8vLyBgYGAKLy8vCi8vLyAjIyMjIEV4aXQgY29kZXMKLy8vCi8vLyAqIDg6IFtDZWxsIG92ZXJmbG93XSDigJQgVGhyb3duIHdoZW4gYXR0ZW1wdGlu" + + "ZyB0byBzdG9yZSBhbiBgYWRkcmVzc2AgaW50byB0aGUgYEJ1aWxkZXJgIHdoZW4gaXQgY2Fubm90IGZpdCBpdC4KLy8vCi8vLyBTZWU6IGh0dHBzOi8vZG9jcy50YWN0" + + "LWxhbmcub3JnL3JlZi9jb3JlLWNlbGxzI2J1aWxkZXJzdG9yZWFkZHJlc3MKLy8vCi8vLyBbQ2VsbCBvdmVyZmxvd106IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3Jn" + + "L2Jvb2svZXhpdC1jb2RlcyM4Ci8vLwphc20gZXh0ZW5kcyBmdW4gc3RvcmVBZGRyZXNzKHNlbGY6IEJ1aWxkZXIsIGFkZHJlc3M6IEFkZHJlc3MpOiBCdWlsZGVyIHsg" + + "U1RTTElDRVIgfQoKLy8vIFN0cnVjdCByZXByZXNlbnRpbmcgYSBiYXNlY2hhaW4gYWRkcmVzcy4gQXZhaWxhYmxlIHNpbmNlIFRhY3QgMS42LjAuCi8vLwovLy8gQSBi" + + "YXNlY2hhaW4gYWRkcmVzcyAod29ya2NoYWluIDApIGNhbiBiZSBlaXRoZXIgZW1wdHkgKG51bGwgaGFzaCkgb3IgY29udGFpbiBhIDI1Ni1iaXQgaGFzaCB2YWx1ZS4K" + + "Ly8vCi8vLyBTZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWFkZHJlc3NlcyNiYXNlY2hhaW5hZGRyZXNzCi8vLwpzdHJ1Y3QgQmFzZWNoYWlu" + + "QWRkcmVzcyB7CiAgICBoYXNoOiBJbnQ/Owp9CgovLy8gR2xvYmFsIGZ1bmN0aW9uLiBBdmFpbGFibGUgc2luY2UgVGFjdCAxLjYuMC4KLy8vCi8vLyBDcmVhdGVzIGFu" + + "ZCByZXR1cm5zIGFuIGVtcHR5IGJhc2VjaGFpbiBhZGRyZXNzIHdpdGggYSBudWxsIGhhc2guCi8vLwovLy8gV2hlbiBzZXJpYWxpemVkLCBhbiBlbXB0eSBiYXNlY2hh" + + "aW4gYWRkcmVzcyBpcyByZXByZXNlbnRlZCBhcyBgYWRkcl9ub25lYC4KLy8vCi8vLyBgYGB0YWN0Ci8vLyBmdW4gZXhhbXBsZSgpIHsKLy8vICAgICBsZXQgZW1wdHlB" + + "ZGRyOiBCYXNlY2hhaW5BZGRyZXNzID0gZW1wdHlCYXNlY2hhaW5BZGRyZXNzKCk7Ci8vLyAgICAgZW1wdHlBZGRyLmhhc2ggPT0gbnVsbDsgLy8gdHJ1ZQovLy8gfQov" + + "Ly8gYGBgCi8vLwovLy8gU2VlOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1hZGRyZXNzZXMjZW1wdHliYXNlY2hhaW5hZGRyZXNzCi8vLwppbmxp" + + "bmUgZnVuIGVtcHR5QmFzZWNoYWluQWRkcmVzcygpOiBCYXNlY2hhaW5BZGRyZXNzIHsKICAgIHJldHVybiBCYXNlY2hhaW5BZGRyZXNzIHsgaGFzaDogbnVsbCB9Owp9" + + "CgovLy8gR2xvYmFsIGZ1bmN0aW9uLiBBdmFpbGFibGUgc2luY2UgVGFjdCAxLjYuMC4KLy8vCi8vLyBDcmVhdGVzIGFuZCByZXR1cm5zIGEgbmV3IGJhc2VjaGFpbiBh" + + "ZGRyZXNzIHdpdGggdGhlIHNwZWNpZmllZCBoYXNoIHZhbHVlLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAgIGxldCBhZGRyOiBCYXNl" + + "Y2hhaW5BZGRyZXNzID0gbmV3QmFzZWNoYWluQWRkcmVzcygweDgzZGZkNTUyZTYzNzI5YjQ3MmZjYmNjOGM0NWViY2M2NjkxNzAyNTU4YjY4ZWM3NTI3ZTFiYTQwM2Ew" + + "ZjMxYTgpOwovLy8gfQovLy8gYGBgCi8vLwovLy8gU2VlOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1hZGRyZXNzZXMjbmV3YmFzZWNoYWluYWRk" + + "cmVzcwovLy8KaW5saW5lIGZ1biBuZXdCYXNlY2hhaW5BZGRyZXNzKGhhc2g6IEludCk6IEJhc2VjaGFpbkFkZHJlc3MgewogICAgcmV0dXJuIEJhc2VjaGFpbkFkZHJl" + + "c3MgeyBoYXNoIH07Cn0KCi8vLyBFeHRlbnNpb24gZnVuY3Rpb24gZm9yIHRoZSBgQnVpbGRlcmAgdHlwZS4gQXZhaWxhYmxlIHNpbmNlIFRhY3QgMS42LjAuCi8vLwov" + + "Ly8gU3RvcmVzIHRoZSBiYXNlY2hhaW4gYWRkcmVzcyBpbiB0aGUgY29weSBvZiB0aGUgQnVpbGRlciBhbmQgcmV0dXJucyB0aGF0IGNvcHkuCi8vLwovLy8gSWYgdGhl" + + "IGFkZHJlc3MgaGFzIGEgYG51bGxgIGhhc2gsIHN0b3JlcyB0d28gemVybyBiaXRzIGAwYjAwYCAoYGFkZHJfbm9uZWApLiBPdGhlcndpc2UsCi8vLyBzdG9yZXMgdGhl" + + "IGZ1bGwgYWRkcmVzcyB3aXRoIHRoZSB0aHJlZS1iaXQgcHJlZml4IGAwYjEwMGAsCi8vLyBmb2xsb3dlZCBieSB0aGUgOC1iaXQgd29ya2NoYWluIElEIHNldCB0byAw" + + "IGFuZCB0aGUgMjU2LWJpdCBoYXNoLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAgIGxldCBhZGRyOiBCYXNlY2hhaW5BZGRyZXNzID0g" + + "bmV3QmFzZWNoYWluQWRkcmVzcygweDgzZGZkNTUyZTYzNzI5YjQ3MmZjYmNjOGM0NWViY2M2NjkxNzAyNTU4YjY4ZWM3NTI3ZTFiYTQwM2EwZjMxYTgpOwovLy8gICAg" + + "IGxldCBiOiBCdWlsZGVyID0gYmVnaW5DZWxsKCk7Ci8vLyAgICAgbGV0IGIyOiBCdWlsZGVyID0gYi5zdG9yZUJhc2VjaGFpbkFkZHJlc3MoYWRkcik7Ci8vLyB9Ci8v" + + "LyBgYGAKLy8vCi8vLyAjIyMjIEV4aXQgY29kZXMKLy8vCi8vLyAqIDg6IFtDZWxsIG92ZXJmbG93XSDigJQgVGhyb3duIHdoZW4gYXR0ZW1wdGluZyB0byBzdG9yZSBh" + + "biBgYWRkcmVzc2AgaW50byB0aGUgYEJ1aWxkZXJgIHdoZW4gaXQgY2Fubm90IGZpdCBpdC4KLy8vCi8vLyBTZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3Jl" + + "Zi9jb3JlLWNlbGxzI2J1aWxkZXJzdG9yZWJhc2VjaGFpbmFkZHJlc3MKLy8vCi8vLyBbQ2VsbCBvdmVyZmxvd106IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL2Jv" + + "b2svZXhpdC1jb2RlcyM4Ci8vLwpleHRlbmRzIGZ1biBzdG9yZUJhc2VjaGFpbkFkZHJlc3Moc2VsZjogQnVpbGRlciwgYWRkcmVzczogQmFzZWNoYWluQWRkcmVzcyk6" + + "IEJ1aWxkZXIgewogICAgaWYgKGFkZHJlc3MuaGFzaCA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuc3RvcmVVaW50KDAsIDIpOyAvLyAwYjAwCiAgICB9Cgog" + + "ICAgcmV0dXJuIHNlbGYKICAgICAgICAuc3RvcmVVaW50KDBiMTBfMF8wMDAwMDAwMCwgMyArIDgpCiAgICAgICAgLnN0b3JlVWludChhZGRyZXNzLmhhc2ghISwgMjU2" + + "KTsKfQoKLy8vIEdsb2JhbCBmdW5jdGlvbi4gQXZhaWxhYmxlIHNpbmNlIFRhY3QgMS42LjMuCi8vLwovLy8gQ2hlY2tzIHdoZXRoZXIgdGhlIGBhZGRyZXNzYCBpcyBp" + + "biB0aGUgYmFzZWNoYWluLCBpLmUuLCBpdHMgY2hhaW4gSUQgaXMgMC4KLy8vCi8vLyBgYGB0YWN0Ci8vLyBmdW4gZXhhbXBsZXMoKSB7Ci8vLyAgICAgbGV0IHNvbWVC" + + "YXNlY2hhaW5BZGRyZXNzOiBBZGRyZXNzID0KLy8vICAgICAgICAgbmV3QWRkcmVzcygwLCAweDgzZGZkNTUyZTYzNzI5YjQ3MmZjYmNjOGM0NWViY2M2NjkxNzAyNTU4" + + "YjY4ZWM3NTI3ZTFiYTQwM2EwZjMxYTgpOwovLy8KLy8vICAgICBsZXQgc29tZU1hc3RlcmNoYWluQWRkcmVzczogQWRkcmVzcyA9Ci8vLyAgICAgICAgIG5ld0FkZHJl" + + "c3MoLTEsIDB4ODNkZmQ1NTJlNjM3MjliNDcyZmNiY2M4YzQ1ZWJjYzY2OTE3MDI1NThiNjhlYzc1MjdlMWJhNDAzYTBmMzFhOCk7Ci8vLwovLy8gICAgIC8vIERvZXMg" + + "bm90IHRocm93IGJlY2F1c2UgdGhlIGNoYWluIElEIGlzIDAKLy8vICAgICBmb3JjZUJhc2VjaGFpbihzb21lQmFzZWNoYWluQWRkcmVzcyk7Ci8vLwovLy8gICAgIHRy" + + "eSB7Ci8vLyAgICAgICAgIC8vIFRocm93cyBiZWNhdXNlIHRoZSBjaGFpbiBJRCBpcyAtMSAobWFzdGVyY2hhaW4pCi8vLyAgICAgICAgIGZvcmNlQmFzZWNoYWluKHNv" + + "bWVNYXN0ZXJjaGFpbkFkZHJlc3MpOwovLy8gICAgIH0gY2F0Y2ggKGV4aXRDb2RlKSB7Ci8vLyAgICAgICAgIC8vIGV4aXRDb2RlIGlzIDEzOAovLy8gICAgIH0KLy8v" + + "IH0KLy8vIGBgYAovLy8KLy8vICMjIyMgRXhpdCBjb2RlcwovLy8KLy8vICogMTM4OiBbTm90IGEgYmFzZWNoYWluIGFkZHJlc3NdIOKAlCBUaHJvd24gd2hlbiB0aGUg" + + "Z2l2ZW4gYGFkZHJlc3NgIGlzIG5vdCBpbiB0aGUgYmFzZWNoYWluIChjaGFpbiBJRCBpcyBub3QgMCkuCi8vLwovLy8gU2VlOiBodHRwczovL2RvY3MudGFjdC1sYW5n" + + "Lm9yZy9yZWYvY29yZS1hZGRyZXNzZXMjZm9yY2ViYXNlY2hhaW4KLy8vCi8vLyBbTm90IGEgYmFzZWNoYWluIGFkZHJlc3NdOiBodHRwczovL2RvY3MudGFjdC1sYW5n" + + "Lm9yZy9ib29rL2V4aXQtY29kZXMjMTM4Ci8vLwphc20gZnVuIGZvcmNlQmFzZWNoYWluKGFkZHJlc3M6IEFkZHJlc3MpIHsgUkVXUklURVNUREFERFIgRFJPUCAxMzgg" + + "VEhST1dJRiB9CgovLy8gR2xvYmFsIGZ1bmN0aW9uLiBBdmFpbGFibGUgc2luY2UgVGFjdCAxLjYuNC4KLy8vCi8vLyBDaGVja3Mgd2hldGhlciB0aGUgYGFkZHJlc3Ng" + + "IGlzIGluIHRoZSBgd29ya2NoYWluYCwgaS5lLiwgaXRzIGNoYWluIElEIGlzIGVxdWFsIHRvIGB3b3JrY2hhaW5gLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFt" + + "cGxlcygpIHsKLy8vICAgICBsZXQgc29tZUJhc2VjaGFpbkFkZHJlc3M6IEFkZHJlc3MgPQovLy8gICAgICAgICBuZXdBZGRyZXNzKDAsIDB4ODNkZmQ1NTJlNjM3Mjli" + + "NDcyZmNiY2M4YzQ1ZWJjYzY2OTE3MDI1NThiNjhlYzc1MjdlMWJhNDAzYTBmMzFhOCk7Ci8vLwovLy8gICAgIGxldCBzb21lTWFzdGVyY2hhaW5BZGRyZXNzOiBBZGRy" + + "ZXNzID0KLy8vICAgICAgICAgbmV3QWRkcmVzcygtMSwgMHg4M2RmZDU1MmU2MzcyOWI0NzJmY2JjYzhjNDVlYmNjNjY5MTcwMjU1OGI2OGVjNzUyN2UxYmE0MDNhMGYz" + + "MWE4KTsKLy8vCi8vLyAgICAgLy8gRG9lcyBub3QgdGhyb3cgYmVjYXVzZSB0aGUgY2hhaW4gSUQgbWF0Y2hlcyB3b3JrY2hhaW4gcGFyYW1ldGVyCi8vLyAgICAgZm9y" + + "Y2VXb3JrY2hhaW4oc29tZUJhc2VjaGFpbkFkZHJlc3MsIDAsIDU5Myk7Ci8vLyAgICAgZm9yY2VXb3JrY2hhaW4oc29tZU1hc3RlcmNoYWluQWRkcmVzcywgLTEsIDU5" + + "Myk7Ci8vLwovLy8gICAgIHRyeSB7Ci8vLyAgICAgICAgIC8vIFRocm93cyBiZWNhdXNlIHRoZSBjaGFpbiBJRCBpcyAwIHdoaWNoIGRvZXNuJ3QgbWF0Y2ggdGhlIHdv" + + "cmtjaGFpbiBwYXJhbWV0ZXIsIC0xCi8vLyAgICAgICAgIGZvcmNlV29ya2NoYWluKHNvbWVCYXNlY2hhaW5BZGRyZXNzLCAtMSwgNTkzKTsKLy8vICAgICB9IGNhdGNo" + + "IChleGl0Q29kZSkgewovLy8gICAgICAgICAvLyBleGl0Q29kZSBpcyA1OTMKLy8vICAgICB9Ci8vLyB9Ci8vLyBgYGAKLy8vCi8vLyAjIyMjIEV4aXQgY29kZXMKLy8v" + + "Ci8vLyAqIGBlcnJvckNvZGVgIOKAlCBUaHJvd24gd2hlbiB0aGUgZ2l2ZW4gYGFkZHJlc3NgIGlzIG5vdCBpbiB0aGUgc3BlY2lmaWVkIGB3b3JrY2hhaW5gIChjaGFp" + + "biBJRCBpcyBub3QgZXF1YWwgdG8gYHdvcmtjaGFpbmApLgovLy8KLy8vIFNlZTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtYWRkcmVzc2VzI2Zv" + + "cmNld29ya2NoYWluCi8vLwphc20oZXJyb3JDb2RlIHdvcmtjaGFpbiBhZGRyZXNzKSBmdW4gZm9yY2VXb3JrY2hhaW4oYWRkcmVzczogQWRkcmVzcywgd29ya2NoYWlu" + + "OiBJbnQsIGVycm9yQ29kZTogSW50KSB7CiAgICBSRVdSSVRFU1REQUREUgogICAgRFJPUAogICAgQ01QCiAgICBUSFJPV0FOWUlGCn0K"; files["std/internal/base.tact"] = - "Ly8vIERlc2NyaWJlcyB0aGUgYmFzZSBsb2dpYyB0aGF0IGlzIGF2YWlsYWJsZSBpbiBhbGwgY29udHJhY3RzIGFuZCB0cmFpdHMgYnkgZGVmYXVsdC4KLy8vCi8vLyBU" + - "aGlzIHRyYWl0IGlzIGltcGxpY2l0bHkgaW5oZXJpdGVkIGJ5IGV2ZXJ5IG90aGVyIGNvbnRyYWN0IGFuZCB0cmFpdC4KLy8vIEl0IGNvbnRhaW5zIGEgbnVtYmVyIG9m" + - "IHRoZSBtb3N0IHVzZWZ1bCBpbnRlcm5hbCBmdW5jdGlvbnMgZm9yIGFueSBraW5kIG9mIGNvbnRyYWN0LAovLy8gYW5kIGEgY29uc3RhbnQgYHNlbGYuc3RvcmFnZVJl" + - "c2VydmVgIGFpbWVkIGF0IGFkdmFuY2VkIHVzZXJzIG9mIFRhY3QuCi8vLwovLy8gU2VlOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1iYXNlLwp0" + - "cmFpdCBCYXNlVHJhaXQgewogICAgLy8vIFRoZSBhbW91bnQgb2YgbmFub1RvbmNvaW5zIHRvIHJlc2VydmUgYmVmb3JlIGZvcndhcmRpbmcgYSBtZXNzYWdlIHdpdGgK" + - "ICAgIC8vLyBgU2VuZFJlbWFpbmluZ0JhbGFuY2VgIG1vZGUuIERlZmF1bHQgaXMgMCAobm8gcmVzZXJ2ZSkuCiAgICAvLy8KICAgIC8vLyBgYGB0YWN0CiAgICAvLy8g" + - "Y29udHJhY3QgQWxsWW91clN0b3JhZ2VCZWxvbmdzVG9VcyB7CiAgICAvLy8gICAgIC8vIFRoaXMgd291bGQgY2hhbmdlIHRoZSBiZWhhdmlvciBvZiBgc2VsZi5mb3J3" + - "YXJkKClgIGZ1bmN0aW9uLAogICAgLy8vICAgICAvLyBjYXVzaW5nIGl0IHRvIHRyeSByZXNlcnZpbmcgdGhpcyBhbW91bnQgb2YgbmFub1RvbmNvaW5zIGJlZm9yZQog" + - "ICAgLy8vICAgICAvLyBmb3J3YXJkaW5nIGEgbWVzc2FnZSB3aXRoIGBTZW5kUmVtYWluaW5nQmFsYW5jZWAgbW9kZQogICAgLy8vICAgICBvdmVycmlkZSBjb25zdCBz" + - "dG9yYWdlUmVzZXJ2ZTogSW50ID0gdG9uKCIwLjEiKTsKICAgIC8vLyB9CiAgICAvLy8gYGBgCiAgICAvLy8KICAgIC8vLyBTZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxh" + - "bmcub3JnL3JlZi9jb3JlLWJhc2Ujc2VsZi1mb3J3YXJkCiAgICAvLy8KICAgIHZpcnR1YWwgY29uc3Qgc3RvcmFnZVJlc2VydmU6IEludCA9IDA7CgogICAgLy8vIFNl" + - "bmRzIGEgYm91bmNlYWJsZSBtZXNzYWdlIGJhY2sgdG8gdGhlIHNlbmRlciBvZiB0aGUgY3VycmVudCBtZXNzYWdlLgogICAgLy8vIEEgc2ltaWxhciBidXQgbW9yZSBn" + - "YXMtZWZmaWNpZW50IHZlcnNpb24gb2YgY2FsbGluZyB0aGUgYHNlbGYuZm9yd2FyZCgpYAogICAgLy8vIGZ1bmN0aW9uIHdpdGggdGhlIGZvbGxvd2luZyBhcmd1bWVu" + - "dHM6CiAgICAvLy8KICAgIC8vLyBgYGB0YWN0CiAgICAvLy8gc2VsZi5mb3J3YXJkKHNlbmRlcigpLCBib2R5LCB0cnVlLCBudWxsKTsKICAgIC8vLyAvLyAgICAgICAg" + - "ICAg4oaRICAgICAgICAg4oaRICAgICDihpEgICAgIOKGkQogICAgLy8vIC8vICAgICAgICAgICB8ICAgICAgICAgfCAgICAgfCAgICAgaW5pdDogU3RhdGVJbml0Pwog" + - "ICAgLy8vIC8vICAgICAgICAgICB8ICAgICAgICAgfCAgICAgYm91bmNlOiBCb29sCiAgICAvLy8gLy8gICAgICAgICAgIHwgICAgICAgICBib2R5OiBDZWxsPwogICAg" + - "Ly8vIC8vICAgICAgICAgICB0bzogQWRkcmVzcwogICAgLy8vIGBgYAogICAgLy8vCiAgICAvLy8gU2VlOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29y" + - "ZS1iYXNlI3NlbGYtZm9yd2FyZAogICAgLy8vCiAgICB2aXJ0dWFsIGlubGluZSBmdW4gcmVwbHkoYm9keTogQ2VsbD8pIHsKICAgICAgICBsZXQgdG86IEFkZHJlc3Mg" + - "PSBzZW5kZXIoKTsKICAgICAgICBsZXQgYm91bmNlOiBCb29sID0gdHJ1ZTsKICAgICAgICBpZiAoc2VsZi5zdG9yYWdlUmVzZXJ2ZSA+IDApIHsgLy8gT3B0aW1pemVk" + - "IGluIGNvbXBpbGUtdGltZQogICAgICAgICAgICBsZXQgYmFsYW5jZTogSW50ID0gbXlCYWxhbmNlKCk7CiAgICAgICAgICAgIGxldCBiYWxhbmNlQmVmb3JlTWVzc2Fn" + - "ZTogSW50ID0gYmFsYW5jZSAtIGNvbnRleHQoKS52YWx1ZTsKICAgICAgICAgICAgaWYgKGJhbGFuY2VCZWZvcmVNZXNzYWdlIDwgc2VsZi5zdG9yYWdlUmVzZXJ2ZSkg" + - "ewogICAgICAgICAgICAgICAgbmF0aXZlUmVzZXJ2ZShzZWxmLnN0b3JhZ2VSZXNlcnZlLCBSZXNlcnZlRXhhY3QpOwogICAgICAgICAgICAgICAgbWVzc2FnZShNZXNz" + - "YWdlUGFyYW1ldGVycyB7CiAgICAgICAgICAgICAgICAgICAgYm91bmNlLAogICAgICAgICAgICAgICAgICAgIHRvLAogICAgICAgICAgICAgICAgICAgIHZhbHVlOiAw" + - "LAogICAgICAgICAgICAgICAgICAgIG1vZGU6IFNlbmRSZW1haW5pbmdCYWxhbmNlIHwgU2VuZElnbm9yZUVycm9ycywKICAgICAgICAgICAgICAgICAgICBib2R5LAog" + - "ICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIEp1c3Qgc2VuZCB3aXRoIHJl" + - "bWFpbmluZyBiYWxhbmNlCiAgICAgICAgbWVzc2FnZShNZXNzYWdlUGFyYW1ldGVycyB7CiAgICAgICAgICAgIGJvdW5jZSwKICAgICAgICAgICAgdG8sCiAgICAgICAg" + - "ICAgIHZhbHVlOiAwLAogICAgICAgICAgICBtb2RlOiBTZW5kUmVtYWluaW5nVmFsdWUgfCBTZW5kSWdub3JlRXJyb3JzLAogICAgICAgICAgICBib2R5LAogICAgICAg" + - "IH0pOwogICAgfQoKICAgIC8vLyBTZW5kcyBhIG5vbi1ib3VuY2VhYmxlIG1lc3NhZ2UgYmFjayB0byB0aGUgc2VuZGVyIG9mIHRoZSBjdXJyZW50IG1lc3NhZ2UuCiAg" + - "ICAvLy8gQSBzaW1pbGFyIGJ1dCBtb3JlIGdhcy1lZmZpY2llbnQgdmVyc2lvbiBvZiBjYWxsaW5nIHRoZSBgc2VsZi5mb3J3YXJkKClgCiAgICAvLy8gZnVuY3Rpb24g" + - "d2l0aCB0aGUgZm9sbG93aW5nIGFyZ3VtZW50czoKICAgIC8vLwogICAgLy8vIGBgYHRhY3QKICAgIC8vLyBzZWxmLmZvcndhcmQoc2VuZGVyKCksIGJvZHksIGZhbHNl" + - "LCBudWxsKTsKICAgIC8vLyAvLyAgICAgICAgICAg4oaRICAgICAgICAg4oaRICAgICDihpEgICAgIOKGkQogICAgLy8vIC8vICAgICAgICAgICB8ICAgICAgICAgfCAg" + - "ICAgfCAgICAgaW5pdDogU3RhdGVJbml0PwogICAgLy8vIC8vICAgICAgICAgICB8ICAgICAgICAgfCAgICAgYm91bmNlOiBCb29sCiAgICAvLy8gLy8gICAgICAgICAg" + - "IHwgICAgICAgICBib2R5OiBDZWxsPwogICAgLy8vIC8vICAgICAgICAgICB0bzogQWRkcmVzcwogICAgLy8vIGBgYAogICAgLy8vCiAgICAvLy8gU2VlOiBodHRwczov" + - "L2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1iYXNlI3NlbGYtZm9yd2FyZAogICAgLy8vCiAgICB2aXJ0dWFsIGlubGluZSBmdW4gbm90aWZ5KGJvZHk6IENlbGw/" + - "KSB7CiAgICAgICAgbGV0IHRvOiBBZGRyZXNzID0gc2VuZGVyKCk7CiAgICAgICAgbGV0IGJvdW5jZTogQm9vbCA9IGZhbHNlOwogICAgICAgIGlmIChzZWxmLnN0b3Jh" + - "Z2VSZXNlcnZlID4gMCkgeyAvLyBPcHRpbWl6ZWQgaW4gY29tcGlsZS10aW1lCiAgICAgICAgICAgIGxldCBiYWxhbmNlOiBJbnQgPSBteUJhbGFuY2UoKTsKICAgICAg" + - "ICAgICAgbGV0IGJhbGFuY2VCZWZvcmVNZXNzYWdlOiBJbnQgPSBiYWxhbmNlIC0gY29udGV4dCgpLnZhbHVlOwogICAgICAgICAgICBpZiAoYmFsYW5jZUJlZm9yZU1l" + - "c3NhZ2UgPCBzZWxmLnN0b3JhZ2VSZXNlcnZlKSB7CiAgICAgICAgICAgICAgICBuYXRpdmVSZXNlcnZlKHNlbGYuc3RvcmFnZVJlc2VydmUsIFJlc2VydmVFeGFjdCk7" + - "CiAgICAgICAgICAgICAgICBtZXNzYWdlKE1lc3NhZ2VQYXJhbWV0ZXJzIHsKICAgICAgICAgICAgICAgICAgICBib3VuY2UsCiAgICAgICAgICAgICAgICAgICAgdG8s" + - "CiAgICAgICAgICAgICAgICAgICAgdmFsdWU6IDAsCiAgICAgICAgICAgICAgICAgICAgbW9kZTogU2VuZFJlbWFpbmluZ0JhbGFuY2UgfCBTZW5kSWdub3JlRXJyb3Jz" + - "LAogICAgICAgICAgICAgICAgICAgIGJvZHksCiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgIH0K" + - "CiAgICAgICAgLy8gSnVzdCBzZW5kIHdpdGggcmVtYWluaW5nIGJhbGFuY2UKICAgICAgICBtZXNzYWdlKE1lc3NhZ2VQYXJhbWV0ZXJzIHsKICAgICAgICAgICAgYm91" + - "bmNlLAogICAgICAgICAgICB0bywKICAgICAgICAgICAgdmFsdWU6IDAsCiAgICAgICAgICAgIG1vZGU6IFNlbmRSZW1haW5pbmdWYWx1ZSB8IFNlbmRJZ25vcmVFcnJv" + - "cnMsCiAgICAgICAgICAgIGJvZHksCiAgICAgICAgfSk7CiAgICB9CgogICAgLy8vIFF1ZXVlcyB0aGUgbWVzc2FnZSAoYm91bmNlYWJsZSBvciBub24tYm91bmNlYWJs" + - "ZSkgdG8gYmUgc2VudCB0byB0aGUgc3BlY2lmaWVkIGFkZHJlc3MgYHRvYC4KICAgIC8vLyBPcHRpb25hbGx5LCB5b3UgbWF5IHByb3ZpZGUgYSBgYm9keWAgb2YgdGhl" + - "IG1lc3NhZ2UgYW5kIHRoZSBgaW5pdGAgcGFja2FnZSB3aXRoIGBpbml0T2ZgLgogICAgLy8vCiAgICAvLy8gV2hlbiBgc2VsZi5zdG9yYWdlUmVzZXJ2ZWAgY29uc3Rh" + - "bnQgaXMgb3ZlcndyaXR0ZW4gdG8gYmUgZ3JlYXRlciB0aGFuIHplcm8sIGJlZm9yZSBzZW5kaW5nIGEKICAgIC8vLyBtZXNzYWdlIGl0IGFsc28gdHJpZXMgdG8gcmVz" + - "ZXJ2ZSB0aGUgYHNlbGYuc3RvcmFnZVJlc2VydmVgIGFtb3VudCBvZiBuYW5vVG9uY29pbnMgZnJvbSB0aGUKICAgIC8vLyByZW1haW5pbmcgYmFsYW5jZSBiZWZvcmUg" + - "bWFraW5nIHRoZSBzZW5kIGluIHRoZSBgU2VuZFJlbWFpbmluZ0JhbGFuY2VgICgxMjgpIG1vZGUuCiAgICAvLy8KICAgIC8vLyBJbiBjYXNlIHJlc2VydmF0aW9uIGF0" + - "dGVtcHQgZmFpbHMgYW5kIGluIHRoZSBkZWZhdWx0IGNhc2Ugd2l0aG91dCB0aGUgYXR0ZW1wdCwgdGhlIG1lc3NhZ2UKICAgIC8vLyBpcyBzZW50IHdpdGggdGhlIGBT" + - "ZW5kUmVtYWluaW5nVmFsdWVgICg2NCkgbW9kZSBpbnN0ZWFkLgogICAgLy8vCiAgICAvLy8gPiBOb3RlIHRoYXQgYHNlbGYuZm9yd2FyZCgpYCBuZXZlciBzZW5kcyBh" + - "ZGRpdGlvbmFsIG5hbm9Ub25jb2lucyBvbiB0b3Agb2Ygd2hhdOKAmXMgYXZhaWxhYmxlIG9uIHRoZSBiYWxhbmNlLgogICAgLy8vID4gVG8gYmUgYWJsZSB0byBzZW5k" + - "IG1vcmUgbmFub1RvbmNvaW5zIHdpdGggYSBzaW5nbGUgbWVzc2FnZSwgdXNlIHRoZSB0aGUgYHNlbmRgIGZ1bmN0aW9uLgogICAgLy8vCiAgICAvLy8gU2VlOiBodHRw" + - "czovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1iYXNlI3NlbGYtZm9yd2FyZAogICAgLy8vCiAgICB2aXJ0dWFsIGZ1biBmb3J3YXJkKHRvOiBBZGRyZXNzLCBi" + - "b2R5OiBDZWxsPywgYm91bmNlOiBCb29sLCBpbml0OiBTdGF0ZUluaXQ/KSB7CiAgICAgICAgaWYgKGluaXQgPT0gbnVsbCkgewogICAgICAgICAgICAvLyBMb2NrIHN0" + - "b3JhZ2UgaWYgbmVlZGVkCiAgICAgICAgICAgIGlmIChzZWxmLnN0b3JhZ2VSZXNlcnZlID4gMCkgeyAvLyBPcHRpbWl6ZWQgaW4gY29tcGlsZS10aW1lCiAgICAgICAg" + - "ICAgICAgICBsZXQgY3R4OiBDb250ZXh0ID0gY29udGV4dCgpOwogICAgICAgICAgICAgICAgbGV0IGJhbGFuY2U6IEludCA9IG15QmFsYW5jZSgpOwogICAgICAgICAg" + - "ICAgICAgbGV0IGJhbGFuY2VCZWZvcmVNZXNzYWdlOiBJbnQgPSBiYWxhbmNlIC0gY3R4LnZhbHVlOwogICAgICAgICAgICAgICAgaWYgKGJhbGFuY2VCZWZvcmVNZXNz" + - "YWdlIDwgc2VsZi5zdG9yYWdlUmVzZXJ2ZSkgewogICAgICAgICAgICAgICAgICAgIG5hdGl2ZVJlc2VydmUoc2VsZi5zdG9yYWdlUmVzZXJ2ZSwgUmVzZXJ2ZUV4YWN0" + - "KTsKICAgICAgICAgICAgICAgICAgICBtZXNzYWdlKE1lc3NhZ2VQYXJhbWV0ZXJzIHsKICAgICAgICAgICAgICAgICAgICAgICAgYm91bmNlLAogICAgICAgICAgICAg" + - "ICAgICAgICAgICB0bywKICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IDAsCiAgICAgICAgICAgICAgICAgICAgICAgIG1vZGU6IFNlbmRSZW1haW5pbmdCYWxh" + - "bmNlIHwgU2VuZElnbm9yZUVycm9ycywKICAgICAgICAgICAgICAgICAgICAgICAgYm9keSwKICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAg" + - "ICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIEp1c3Qgc2VuZCB3aXRoIHJlbWFpbmluZyBiYWxhbmNlCiAgICAg" + - "ICAgICAgIG1lc3NhZ2UoTWVzc2FnZVBhcmFtZXRlcnMgewogICAgICAgICAgICAgICAgYm91bmNlLAogICAgICAgICAgICAgICAgdG8sCiAgICAgICAgICAgICAgICB2" + - "YWx1ZTogMCwKICAgICAgICAgICAgICAgIG1vZGU6IFNlbmRSZW1haW5pbmdWYWx1ZSB8IFNlbmRJZ25vcmVFcnJvcnMsCiAgICAgICAgICAgICAgICBib2R5LAogICAg" + - "ICAgICAgICB9KTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgLy8gTG9jayBzdG9yYWdlIGlmIG5lZWRlZAogICAgICAgIGlmIChzZWxmLnN0" + - "b3JhZ2VSZXNlcnZlID4gMCkgeyAvLyBPcHRpbWl6ZWQgaW4gY29tcGlsZS10aW1lCiAgICAgICAgICAgIGxldCBjdHg6IENvbnRleHQgPSBjb250ZXh0KCk7CiAgICAg" + - "ICAgICAgIGxldCBiYWxhbmNlOiBJbnQgPSBteUJhbGFuY2UoKTsKICAgICAgICAgICAgbGV0IGJhbGFuY2VCZWZvcmVNZXNzYWdlOiBJbnQgPSBiYWxhbmNlIC0gY3R4" + - "LnZhbHVlOwogICAgICAgICAgICBpZiAoYmFsYW5jZUJlZm9yZU1lc3NhZ2UgPCBzZWxmLnN0b3JhZ2VSZXNlcnZlKSB7CiAgICAgICAgICAgICAgICBuYXRpdmVSZXNl" + - "cnZlKHNlbGYuc3RvcmFnZVJlc2VydmUsIFJlc2VydmVFeGFjdCk7CiAgICAgICAgICAgICAgICBzZW5kKFNlbmRQYXJhbWV0ZXJzIHsKICAgICAgICAgICAgICAgICAg" + - "ICB0bywKICAgICAgICAgICAgICAgICAgICBtb2RlOiBTZW5kUmVtYWluaW5nQmFsYW5jZSB8IFNlbmRJZ25vcmVFcnJvcnMsCiAgICAgICAgICAgICAgICAgICAgYm9k" + - "eSwKICAgICAgICAgICAgICAgICAgICB2YWx1ZTogMCwKICAgICAgICAgICAgICAgICAgICBib3VuY2UsCiAgICAgICAgICAgICAgICAgICAgY29kZTogaW5pdCEhLmNv" + - "ZGUsCiAgICAgICAgICAgICAgICAgICAgZGF0YTogaW5pdCEhLmRhdGEsCiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAg" + - "ICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gSnVzdCBzZW5kIHdpdGggcmVtYWluaW5nIGJhbGFuY2UKICAgICAgICBzZW5kKFNlbmRQYXJhbWV0ZXJzIHsKICAgICAg" + - "ICAgICAgYm91bmNlLAogICAgICAgICAgICB0bywKICAgICAgICAgICAgdmFsdWU6IDAsCiAgICAgICAgICAgIG1vZGU6IFNlbmRSZW1haW5pbmdWYWx1ZSB8IFNlbmRJ" + - "Z25vcmVFcnJvcnMsCiAgICAgICAgICAgIGJvZHksCiAgICAgICAgICAgIGNvZGU6IGluaXQhIS5jb2RlLAogICAgICAgICAgICBkYXRhOiBpbml0ISEuZGF0YSwKICAg" + - "ICAgICB9KTsKICAgIH0KfQo="; + "aW1wb3J0ICIuL2NvbnRleHQiOwppbXBvcnQgIi4vY29udHJhY3QiOwppbXBvcnQgIi4vcmVzZXJ2ZSI7CmltcG9ydCAiLi9zZW5kIjsKCi8vLyBEZXNjcmliZXMgdGhl" + + "IGJhc2UgbG9naWMgdGhhdCBpcyBhdmFpbGFibGUgaW4gYWxsIGNvbnRyYWN0cyBhbmQgdHJhaXRzIGJ5IGRlZmF1bHQuCi8vLwovLy8gVGhpcyB0cmFpdCBpcyBpbXBs" + + "aWNpdGx5IGluaGVyaXRlZCBieSBldmVyeSBvdGhlciBjb250cmFjdCBhbmQgdHJhaXQuCi8vLyBJdCBjb250YWlucyBhIG51bWJlciBvZiB0aGUgbW9zdCB1c2VmdWwg" + + "aW50ZXJuYWwgZnVuY3Rpb25zIGZvciBhbnkga2luZCBvZiBjb250cmFjdCwKLy8vIGFuZCBhIGNvbnN0YW50IGBzZWxmLnN0b3JhZ2VSZXNlcnZlYCBhaW1lZCBhdCBh" + + "ZHZhbmNlZCB1c2VycyBvZiBUYWN0LgovLy8KLy8vIFNlZTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtYmFzZS8KdHJhaXQgQmFzZVRyYWl0IHsK" + + "ICAgIC8vLyBUaGUgYW1vdW50IG9mIG5hbm9Ub25jb2lucyB0byByZXNlcnZlIGJlZm9yZSBmb3J3YXJkaW5nIGEgbWVzc2FnZSB3aXRoCiAgICAvLy8gYFNlbmRSZW1h" + + "aW5pbmdCYWxhbmNlYCBtb2RlLiBEZWZhdWx0IGlzIDAgKG5vIHJlc2VydmUpLgogICAgLy8vCiAgICAvLy8gYGBgdGFjdAogICAgLy8vIGNvbnRyYWN0IEFsbFlvdXJT" + + "dG9yYWdlQmVsb25nc1RvVXMgewogICAgLy8vICAgICAvLyBUaGlzIHdvdWxkIGNoYW5nZSB0aGUgYmVoYXZpb3Igb2YgYHNlbGYuZm9yd2FyZCgpYCBmdW5jdGlvbiwK" + + "ICAgIC8vLyAgICAgLy8gY2F1c2luZyBpdCB0byB0cnkgcmVzZXJ2aW5nIHRoaXMgYW1vdW50IG9mIG5hbm9Ub25jb2lucyBiZWZvcmUKICAgIC8vLyAgICAgLy8gZm9y" + + "d2FyZGluZyBhIG1lc3NhZ2Ugd2l0aCBgU2VuZFJlbWFpbmluZ0JhbGFuY2VgIG1vZGUKICAgIC8vLyAgICAgb3ZlcnJpZGUgY29uc3Qgc3RvcmFnZVJlc2VydmU6IElu" + + "dCA9IHRvbigiMC4xIik7CiAgICAvLy8gfQogICAgLy8vIGBgYAogICAgLy8vCiAgICAvLy8gU2VlOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1i" + + "YXNlI3NlbGYtZm9yd2FyZAogICAgLy8vCiAgICB2aXJ0dWFsIGNvbnN0IHN0b3JhZ2VSZXNlcnZlOiBJbnQgPSAwOwoKICAgIC8vLyBTZW5kcyBhIGJvdW5jZWFibGUg" + + "bWVzc2FnZSBiYWNrIHRvIHRoZSBzZW5kZXIgb2YgdGhlIGN1cnJlbnQgbWVzc2FnZS4KICAgIC8vLyBBIHNpbWlsYXIgYnV0IG1vcmUgZ2FzLWVmZmljaWVudCB2ZXJz" + + "aW9uIG9mIGNhbGxpbmcgdGhlIGBzZWxmLmZvcndhcmQoKWAKICAgIC8vLyBmdW5jdGlvbiB3aXRoIHRoZSBmb2xsb3dpbmcgYXJndW1lbnRzOgogICAgLy8vCiAgICAv" + + "Ly8gYGBgdGFjdAogICAgLy8vIHNlbGYuZm9yd2FyZChzZW5kZXIoKSwgYm9keSwgdHJ1ZSwgbnVsbCk7CiAgICAvLy8gLy8gICAgICAgICAgIOKGkSAgICAgICAgIOKG" + + "kSAgICAg4oaRICAgICDihpEKICAgIC8vLyAvLyAgICAgICAgICAgfCAgICAgICAgIHwgICAgIHwgICAgIGluaXQ6IFN0YXRlSW5pdD8KICAgIC8vLyAvLyAgICAgICAg" + + "ICAgfCAgICAgICAgIHwgICAgIGJvdW5jZTogQm9vbAogICAgLy8vIC8vICAgICAgICAgICB8ICAgICAgICAgYm9keTogQ2VsbD8KICAgIC8vLyAvLyAgICAgICAgICAg" + + "dG86IEFkZHJlc3MKICAgIC8vLyBgYGAKICAgIC8vLwogICAgLy8vIFNlZTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtYmFzZSNzZWxmLWZvcndh" + + "cmQKICAgIC8vLwogICAgdmlydHVhbCBpbmxpbmUgZnVuIHJlcGx5KGJvZHk6IENlbGw/KSB7CiAgICAgICAgbGV0IHRvOiBBZGRyZXNzID0gc2VuZGVyKCk7CiAgICAg" + + "ICAgbGV0IGJvdW5jZTogQm9vbCA9IHRydWU7CiAgICAgICAgaWYgKHNlbGYuc3RvcmFnZVJlc2VydmUgPiAwKSB7IC8vIE9wdGltaXplZCBpbiBjb21waWxlLXRpbWUK" + + "ICAgICAgICAgICAgbGV0IGJhbGFuY2U6IEludCA9IG15QmFsYW5jZSgpOwogICAgICAgICAgICBsZXQgYmFsYW5jZUJlZm9yZU1lc3NhZ2U6IEludCA9IGJhbGFuY2Ug" + + "LSBjb250ZXh0KCkudmFsdWU7CiAgICAgICAgICAgIGlmIChiYWxhbmNlQmVmb3JlTWVzc2FnZSA8IHNlbGYuc3RvcmFnZVJlc2VydmUpIHsKICAgICAgICAgICAgICAg" + + "IG5hdGl2ZVJlc2VydmUoc2VsZi5zdG9yYWdlUmVzZXJ2ZSwgUmVzZXJ2ZUV4YWN0KTsKICAgICAgICAgICAgICAgIG1lc3NhZ2UoTWVzc2FnZVBhcmFtZXRlcnMgewog" + + "ICAgICAgICAgICAgICAgICAgIGJvdW5jZSwKICAgICAgICAgICAgICAgICAgICB0bywKICAgICAgICAgICAgICAgICAgICB2YWx1ZTogMCwKICAgICAgICAgICAgICAg" + + "ICAgICBtb2RlOiBTZW5kUmVtYWluaW5nQmFsYW5jZSB8IFNlbmRJZ25vcmVFcnJvcnMsCiAgICAgICAgICAgICAgICAgICAgYm9keSwKICAgICAgICAgICAgICAgIH0p" + + "OwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBKdXN0IHNlbmQgd2l0aCByZW1haW5pbmcgYmFsYW5jZQog" + + "ICAgICAgIG1lc3NhZ2UoTWVzc2FnZVBhcmFtZXRlcnMgewogICAgICAgICAgICBib3VuY2UsCiAgICAgICAgICAgIHRvLAogICAgICAgICAgICB2YWx1ZTogMCwKICAg" + + "ICAgICAgICAgbW9kZTogU2VuZFJlbWFpbmluZ1ZhbHVlIHwgU2VuZElnbm9yZUVycm9ycywKICAgICAgICAgICAgYm9keSwKICAgICAgICB9KTsKICAgIH0KCiAgICAv" + + "Ly8gU2VuZHMgYSBub24tYm91bmNlYWJsZSBtZXNzYWdlIGJhY2sgdG8gdGhlIHNlbmRlciBvZiB0aGUgY3VycmVudCBtZXNzYWdlLgogICAgLy8vIEEgc2ltaWxhciBi" + + "dXQgbW9yZSBnYXMtZWZmaWNpZW50IHZlcnNpb24gb2YgY2FsbGluZyB0aGUgYHNlbGYuZm9yd2FyZCgpYAogICAgLy8vIGZ1bmN0aW9uIHdpdGggdGhlIGZvbGxvd2lu" + + "ZyBhcmd1bWVudHM6CiAgICAvLy8KICAgIC8vLyBgYGB0YWN0CiAgICAvLy8gc2VsZi5mb3J3YXJkKHNlbmRlcigpLCBib2R5LCBmYWxzZSwgbnVsbCk7CiAgICAvLy8g" + + "Ly8gICAgICAgICAgIOKGkSAgICAgICAgIOKGkSAgICAg4oaRICAgICDihpEKICAgIC8vLyAvLyAgICAgICAgICAgfCAgICAgICAgIHwgICAgIHwgICAgIGluaXQ6IFN0" + + "YXRlSW5pdD8KICAgIC8vLyAvLyAgICAgICAgICAgfCAgICAgICAgIHwgICAgIGJvdW5jZTogQm9vbAogICAgLy8vIC8vICAgICAgICAgICB8ICAgICAgICAgYm9keTog" + + "Q2VsbD8KICAgIC8vLyAvLyAgICAgICAgICAgdG86IEFkZHJlc3MKICAgIC8vLyBgYGAKICAgIC8vLwogICAgLy8vIFNlZTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5v" + + "cmcvcmVmL2NvcmUtYmFzZSNzZWxmLWZvcndhcmQKICAgIC8vLwogICAgdmlydHVhbCBpbmxpbmUgZnVuIG5vdGlmeShib2R5OiBDZWxsPykgewogICAgICAgIGxldCB0" + + "bzogQWRkcmVzcyA9IHNlbmRlcigpOwogICAgICAgIGxldCBib3VuY2U6IEJvb2wgPSBmYWxzZTsKICAgICAgICBpZiAoc2VsZi5zdG9yYWdlUmVzZXJ2ZSA+IDApIHsg" + + "Ly8gT3B0aW1pemVkIGluIGNvbXBpbGUtdGltZQogICAgICAgICAgICBsZXQgYmFsYW5jZTogSW50ID0gbXlCYWxhbmNlKCk7CiAgICAgICAgICAgIGxldCBiYWxhbmNl" + + "QmVmb3JlTWVzc2FnZTogSW50ID0gYmFsYW5jZSAtIGNvbnRleHQoKS52YWx1ZTsKICAgICAgICAgICAgaWYgKGJhbGFuY2VCZWZvcmVNZXNzYWdlIDwgc2VsZi5zdG9y" + + "YWdlUmVzZXJ2ZSkgewogICAgICAgICAgICAgICAgbmF0aXZlUmVzZXJ2ZShzZWxmLnN0b3JhZ2VSZXNlcnZlLCBSZXNlcnZlRXhhY3QpOwogICAgICAgICAgICAgICAg" + + "bWVzc2FnZShNZXNzYWdlUGFyYW1ldGVycyB7CiAgICAgICAgICAgICAgICAgICAgYm91bmNlLAogICAgICAgICAgICAgICAgICAgIHRvLAogICAgICAgICAgICAgICAg" + + "ICAgIHZhbHVlOiAwLAogICAgICAgICAgICAgICAgICAgIG1vZGU6IFNlbmRSZW1haW5pbmdCYWxhbmNlIHwgU2VuZElnbm9yZUVycm9ycywKICAgICAgICAgICAgICAg" + + "ICAgICBib2R5LAogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIEp1c3Qg" + + "c2VuZCB3aXRoIHJlbWFpbmluZyBiYWxhbmNlCiAgICAgICAgbWVzc2FnZShNZXNzYWdlUGFyYW1ldGVycyB7CiAgICAgICAgICAgIGJvdW5jZSwKICAgICAgICAgICAg" + + "dG8sCiAgICAgICAgICAgIHZhbHVlOiAwLAogICAgICAgICAgICBtb2RlOiBTZW5kUmVtYWluaW5nVmFsdWUgfCBTZW5kSWdub3JlRXJyb3JzLAogICAgICAgICAgICBi" + + "b2R5LAogICAgICAgIH0pOwogICAgfQoKICAgIC8vLyBRdWV1ZXMgdGhlIG1lc3NhZ2UgKGJvdW5jZWFibGUgb3Igbm9uLWJvdW5jZWFibGUpIHRvIGJlIHNlbnQgdG8g" + + "dGhlIHNwZWNpZmllZCBhZGRyZXNzIGB0b2AuCiAgICAvLy8gT3B0aW9uYWxseSwgeW91IG1heSBwcm92aWRlIGEgYGJvZHlgIG9mIHRoZSBtZXNzYWdlIGFuZCB0aGUg" + + "YGluaXRgIHBhY2thZ2Ugd2l0aCBgaW5pdE9mYC4KICAgIC8vLwogICAgLy8vIFdoZW4gYHNlbGYuc3RvcmFnZVJlc2VydmVgIGNvbnN0YW50IGlzIG92ZXJ3cml0dGVu" + + "IHRvIGJlIGdyZWF0ZXIgdGhhbiB6ZXJvLCBiZWZvcmUgc2VuZGluZyBhCiAgICAvLy8gbWVzc2FnZSBpdCBhbHNvIHRyaWVzIHRvIHJlc2VydmUgdGhlIGBzZWxmLnN0" + + "b3JhZ2VSZXNlcnZlYCBhbW91bnQgb2YgbmFub1RvbmNvaW5zIGZyb20gdGhlCiAgICAvLy8gcmVtYWluaW5nIGJhbGFuY2UgYmVmb3JlIG1ha2luZyB0aGUgc2VuZCBp" + + "biB0aGUgYFNlbmRSZW1haW5pbmdCYWxhbmNlYCAoMTI4KSBtb2RlLgogICAgLy8vCiAgICAvLy8gSW4gY2FzZSByZXNlcnZhdGlvbiBhdHRlbXB0IGZhaWxzIGFuZCBp" + + "biB0aGUgZGVmYXVsdCBjYXNlIHdpdGhvdXQgdGhlIGF0dGVtcHQsIHRoZSBtZXNzYWdlCiAgICAvLy8gaXMgc2VudCB3aXRoIHRoZSBgU2VuZFJlbWFpbmluZ1ZhbHVl" + + "YCAoNjQpIG1vZGUgaW5zdGVhZC4KICAgIC8vLwogICAgLy8vID4gTm90ZSB0aGF0IGBzZWxmLmZvcndhcmQoKWAgbmV2ZXIgc2VuZHMgYWRkaXRpb25hbCBuYW5vVG9u" + + "Y29pbnMgb24gdG9wIG9mIHdoYXTigJlzIGF2YWlsYWJsZSBvbiB0aGUgYmFsYW5jZS4KICAgIC8vLyA+IFRvIGJlIGFibGUgdG8gc2VuZCBtb3JlIG5hbm9Ub25jb2lu" + + "cyB3aXRoIGEgc2luZ2xlIG1lc3NhZ2UsIHVzZSB0aGUgdGhlIGBzZW5kYCBmdW5jdGlvbi4KICAgIC8vLwogICAgLy8vIFNlZTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFu" + + "Zy5vcmcvcmVmL2NvcmUtYmFzZSNzZWxmLWZvcndhcmQKICAgIC8vLwogICAgdmlydHVhbCBmdW4gZm9yd2FyZCh0bzogQWRkcmVzcywgYm9keTogQ2VsbD8sIGJvdW5j" + + "ZTogQm9vbCwgaW5pdDogU3RhdGVJbml0PykgewogICAgICAgIGlmIChpbml0ID09IG51bGwpIHsKICAgICAgICAgICAgLy8gTG9jayBzdG9yYWdlIGlmIG5lZWRlZAog" + + "ICAgICAgICAgICBpZiAoc2VsZi5zdG9yYWdlUmVzZXJ2ZSA+IDApIHsgLy8gT3B0aW1pemVkIGluIGNvbXBpbGUtdGltZQogICAgICAgICAgICAgICAgbGV0IGN0eDog" + + "Q29udGV4dCA9IGNvbnRleHQoKTsKICAgICAgICAgICAgICAgIGxldCBiYWxhbmNlOiBJbnQgPSBteUJhbGFuY2UoKTsKICAgICAgICAgICAgICAgIGxldCBiYWxhbmNl" + + "QmVmb3JlTWVzc2FnZTogSW50ID0gYmFsYW5jZSAtIGN0eC52YWx1ZTsKICAgICAgICAgICAgICAgIGlmIChiYWxhbmNlQmVmb3JlTWVzc2FnZSA8IHNlbGYuc3RvcmFn" + + "ZVJlc2VydmUpIHsKICAgICAgICAgICAgICAgICAgICBuYXRpdmVSZXNlcnZlKHNlbGYuc3RvcmFnZVJlc2VydmUsIFJlc2VydmVFeGFjdCk7CiAgICAgICAgICAgICAg" + + "ICAgICAgbWVzc2FnZShNZXNzYWdlUGFyYW1ldGVycyB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJvdW5jZSwKICAgICAgICAgICAgICAgICAgICAgICAgdG8sCiAg" + + "ICAgICAgICAgICAgICAgICAgICAgIHZhbHVlOiAwLAogICAgICAgICAgICAgICAgICAgICAgICBtb2RlOiBTZW5kUmVtYWluaW5nQmFsYW5jZSB8IFNlbmRJZ25vcmVF" + + "cnJvcnMsCiAgICAgICAgICAgICAgICAgICAgICAgIGJvZHksCiAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAg" + + "ICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBKdXN0IHNlbmQgd2l0aCByZW1haW5pbmcgYmFsYW5jZQogICAgICAgICAgICBtZXNzYWdlKE1l" + + "c3NhZ2VQYXJhbWV0ZXJzIHsKICAgICAgICAgICAgICAgIGJvdW5jZSwKICAgICAgICAgICAgICAgIHRvLAogICAgICAgICAgICAgICAgdmFsdWU6IDAsCiAgICAgICAg" + + "ICAgICAgICBtb2RlOiBTZW5kUmVtYWluaW5nVmFsdWUgfCBTZW5kSWdub3JlRXJyb3JzLAogICAgICAgICAgICAgICAgYm9keSwKICAgICAgICAgICAgfSk7CiAgICAg" + + "ICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIC8vIExvY2sgc3RvcmFnZSBpZiBuZWVkZWQKICAgICAgICBpZiAoc2VsZi5zdG9yYWdlUmVzZXJ2ZSA+IDAp" + + "IHsgLy8gT3B0aW1pemVkIGluIGNvbXBpbGUtdGltZQogICAgICAgICAgICBsZXQgY3R4OiBDb250ZXh0ID0gY29udGV4dCgpOwogICAgICAgICAgICBsZXQgYmFsYW5j" + + "ZTogSW50ID0gbXlCYWxhbmNlKCk7CiAgICAgICAgICAgIGxldCBiYWxhbmNlQmVmb3JlTWVzc2FnZTogSW50ID0gYmFsYW5jZSAtIGN0eC52YWx1ZTsKICAgICAgICAg" + + "ICAgaWYgKGJhbGFuY2VCZWZvcmVNZXNzYWdlIDwgc2VsZi5zdG9yYWdlUmVzZXJ2ZSkgewogICAgICAgICAgICAgICAgbmF0aXZlUmVzZXJ2ZShzZWxmLnN0b3JhZ2VS" + + "ZXNlcnZlLCBSZXNlcnZlRXhhY3QpOwogICAgICAgICAgICAgICAgc2VuZChTZW5kUGFyYW1ldGVycyB7CiAgICAgICAgICAgICAgICAgICAgdG8sCiAgICAgICAgICAg" + + "ICAgICAgICAgbW9kZTogU2VuZFJlbWFpbmluZ0JhbGFuY2UgfCBTZW5kSWdub3JlRXJyb3JzLAogICAgICAgICAgICAgICAgICAgIGJvZHksCiAgICAgICAgICAgICAg" + + "ICAgICAgdmFsdWU6IDAsCiAgICAgICAgICAgICAgICAgICAgYm91bmNlLAogICAgICAgICAgICAgICAgICAgIGNvZGU6IGluaXQhIS5jb2RlLAogICAgICAgICAgICAg" + + "ICAgICAgIGRhdGE6IGluaXQhIS5kYXRhLAogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICB9Cgog" + + "ICAgICAgIC8vIEp1c3Qgc2VuZCB3aXRoIHJlbWFpbmluZyBiYWxhbmNlCiAgICAgICAgc2VuZChTZW5kUGFyYW1ldGVycyB7CiAgICAgICAgICAgIGJvdW5jZSwKICAg" + + "ICAgICAgICAgdG8sCiAgICAgICAgICAgIHZhbHVlOiAwLAogICAgICAgICAgICBtb2RlOiBTZW5kUmVtYWluaW5nVmFsdWUgfCBTZW5kSWdub3JlRXJyb3JzLAogICAg" + + "ICAgICAgICBib2R5LAogICAgICAgICAgICBjb2RlOiBpbml0ISEuY29kZSwKICAgICAgICAgICAgZGF0YTogaW5pdCEhLmRhdGEsCiAgICAgICAgfSk7CiAgICB9Cn0K"; files["std/internal/cells.tact"] = "Ly8KLy8gQnVpbGRlcgovLwoKLy8vIENyZWF0ZXMgYSBuZXcgZW1wdHkgYEJ1aWxkZXJgLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAg" + "IGxldCBiOiBCdWlsZGVyID0gYmVnaW5DZWxsKCk7Ci8vLyB9Ci8vLyBgYGAKLy8vCi8vLyBTZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWNl" + @@ -1034,209 +1027,217 @@ files["std/internal/context.tact"] = "ICAgICAgLy8gdGhpcyBpbnN0cnVjdGlvbiBlZmZlY3RpdmVseSBtdWx0aXBsaWVzIHRoZSBmd2RfZmVlIGJ5IDEuNSwKICAgICAgICAgICAgICAgICAgICAgIC8vIGF0" + "IGxlYXN0IGZvciB0aGUgY3VycmVudCB2YWx1ZSBvZiBmaXJzdF9mcmFjLCB3aGljaCBpcyAyMTg0NQp9Cg=="; files["std/internal/contract.tact"] = - "Ly8vIEdsb2JhbCBmdW5jdGlvbi4gQXZhaWxhYmxlIHNpbmNlIFRhY3QgMS42LjAuCi8vLwovLy8gQ29tcHV0ZXMgYW5kIHJldHVybnMgYW4gYEludGAgdmFsdWUgb2Yg" + - "dGhlIFNIQS0yNTYgaGFzaCBvZiB0aGUgYGNvZGVgIGFuZCBgZGF0YWAgb2YgdGhlIGdpdmVuIGNvbnRyYWN0LiBUbyBhc3NlbWJsZSB0aGUgYGNvZGVgIGFuZCBgZGF0" + - "YWAgY2VsbHMgdG9nZXRoZXIgZm9yIGhhc2hpbmcsIHRoZSBzdGFuZGFyZCBgQ2VsbGAgcmVwcmVzZW50YXRpb24gaXMgdXNlZC4KLy8vCi8vLyBUaGlzIGhhc2ggaXMg" + - "Y29tbW9ubHkgY2FsbGVkIGFjY291bnQgSUQuIFRvZ2V0aGVyIHdpdGggdGhlIHdvcmtjaGFpbiBJRCBpdCBkZXRlcm1pbmlzdGljYWxseSBmb3JtcyB0aGUgYWRkcmVz" + - "cyBvZiB0aGUgY29udHJhY3Qgb24gVE9OIEJsb2NrY2hhaW4uCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKSB7Ci8vLyAgICAgbGV0IGluaXRQa2c6IFN0" + - "YXRlSW5pdCA9IGluaXRPZiBTb21lQ29udHJhY3QoKTsKLy8vICAgICBsZXQgYWNjb3VudElkOiBJbnQgPSBjb250cmFjdEhhc2goaW5pdFBrZy5jb2RlLCBpbml0UGtn" + - "LmRhdGEpOwovLy8gICAgIGxldCBiYXNlY2hhaW5BZGRyOiBBZGRyZXNzID0gbmV3QWRkcmVzcygwLCBhY2NvdW50SWQpOwovLy8gICAgIGxldCBiYXNlY2hhaW5BZGRy" + - "MjogQWRkcmVzcyA9IGNvbnRyYWN0QWRkcmVzc0V4dCgwLCBpbml0UGtnLmNvZGUsIGluaXRQa2cuZGF0YSk7Ci8vLwovLy8gICAgIGJhc2VjaGFpbkFkZHIgPT0gYmFz" + - "ZWNoYWluQWRkcjI7IC8vIHRydWUKLy8vIH0KLy8vIGBgYAovLy8KLy8vIFNlZToKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtYWRkcmVz" + - "c2VzI2NvbnRyYWN0aGFzaAovLy8gKiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1hZGRyZXNzZXMjbmV3YWRkcmVzcwovLy8gKiBodHRwczovL2Rv" + - "Y3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1hZGRyZXNzZXMjY29udHJhY3RhZGRyZXNzZXh0Ci8vLwphc20gZnVuIGNvbnRyYWN0SGFzaChjb2RlOiBDZWxsLCBkYXRh" + - "OiBDZWxsKTogSW50IHsKICAgIC8vIEFjY29yZGluZyB0byB0aGUgaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvYm9vay9jZWxscyNjZWxscy1yZXByZXNlbnRhdGlv" + - "biwKICAgIC8vIHRoZSBsYXlvdXQgZm9yIHRoZSBCdWlsZGVyIHRvIGhhc2ggZ29lcyBhcyBmb2xsb3dzOgogICAgLy8gMSkgcmVmc19kZXNjcmlwdG9yOmJpdHM4IHwg" + - "Yml0c19kZXNjcmlwdG9yOmJpdHM4IHwgZGF0YTpiaXRzTgogICAgLy8KICAgIC8vICByZWZzX2Rlc2NyaXB0b3I6IHJlZl9jb3VudCArICgoZXhvdGljPyAmIDEpICog" + - "OCkgKyAobWFzayAqIDMyKQogICAgLy8gICAgICAgICAgICAgICAgICAgMiByZWZzIChjb2RlICsgZGF0YSksIG5vbi1leG90aWMsIHplcm8tbWFzawogICAgLy8KICAg" + - "IC8vICBiaXRzX2Rlc2NyaXB0b3I6IGZsb29yKGJpdF9jb3VudCAvIDgpICsgY2VpbChiaXRfY291bnQsIDgpCiAgICAvLyAgICAgICAgICAgICAgICAgICBmbG9vciAo" + - "NSBiaXRzIC8gOCkgKyBjZWlsKDUgYml0cyAvIDgpID0gMCArIDEgPSAxCiAgICAvLwogICAgLy8gIGRhdGE6IFswYjAwMTEwXSArIFswYjEwMF0gPSBbMGIwMDExMDEw" + - "MF0gPSAweDM0IChkYXRhICsgYXVnbWVudGVkIGJpdHMpCiAgICAvLyAgICAgICAgMGIwMDExMCAtIGRhdGEgKHNwbGl0X2RlcHRoLCBzcGVjaWFsLCBjb2RlLCBkYXRh" + - "LCBMaWJyYXJ5KQogICAgLy8gICAgICAgIDBiMTAwIC0gYXVnbWVudGVkIGJpdHMgKExlYWRpbmcgMSArIHplcm9lcyB0byBtYWtlIHNlY3Rpb24gbXVsdGlwbGUgb2Yg" + - "ZWlnaHQpCiAgICAvLwogICAgLy8gIFRoYXQgaXM6ICgyIDw8IDE2KSB8ICgxIDw8IDgpIHwgMHgzNCA9IDEzMTM4MCBmb3IgYWxsIHRocmVlLgogICAgLy8KICAgIC8v" + - "IDIpIGFuZCAzKSBkZXB0aF9kZXNjcmlwdG9yczogQ0RFUFRIIG9mIGBjb2RlYCBhbmQgQ0RFUFRIIG9mIGBkYXRhYAogICAgLy8gNCkgYW5kIDUpIHJlZiBoYXNoZXM6" + - "IEhBU0hDVSBvZiBgY29kZWAgYW5kIEhBU0hDVSBvZiBgZGF0YWAKCiAgICAvLyBHcm91cCAxOiBDb21wdXRhdGlvbnMgYW5kIGFycmFuZ2VtZW50cwogICAgczAgUFVT" + - "SCBIQVNIQ1UgLy8gYGRhdGFgIGhhc2gKICAgIHMyIFBVU0ggSEFTSENVIC8vIGBjb2RlYCBoYXNoCiAgICBTV0FQMgogICAgQ0RFUFRIICAgICAgICAgLy8gYGRhdGFg" + - "IGRlcHRoCiAgICBTV0FQCiAgICBDREVQVEggICAgICAgICAvLyBgY29kZWAgZGVwdGgKICAgIDEzMTM4MCBJTlQgICAgIC8vICgyIDw8IDE2KSB8ICgxIDw8IDgpIHwg" + - "MHgzNAoKICAgIC8vIEdyb3VwIDI6IENvbXBvc2l0aW9uIG9mIHRoZSBCdWlsZGVyCiAgICBORVdDCiAgICAyNCBTVFUgIC8vIHN0b3JlIHJlZnNfZGVzY3JpcHRvciB8" + - "IGJpdHNfZGVzY3JpcHRvciB8IGRhdGEKICAgIDE2IFNUVSAgLy8gc3RvcmUgZGVwdGhfZGVzY3JpcHRvciBmb3IgYGNvZGVgCiAgICAxNiBTVFUgIC8vIHN0b3JlIGRl" + - "cHRoX2Rlc2NyaXB0b3IgZm9yIGBkYXRhYAogICAgMjU2IFNUVSAvLyBzdG9yZSBgY29kZWAgaGFzaAogICAgMjU2IFNUVSAvLyBzdG9yZSBgZGF0YWAgaGFzaAoKICAg" + - "IC8vIEdyb3VwIDM6IFNIQTI1NiBoYXNoIG9mIHRoZSByZXN1bHRpbmcgQnVpbGRlcgogICAgT05FIEhBU0hFWFRfU0hBMjU2Cn0KCi8vLyBHbG9iYWwgZnVuY3Rpb24u" + - "Ci8vLwovLy8gQ29tcHV0ZXMgc21hcnQgY29udHJhY3QncyBgQWRkcmVzc2AgaW4gdGhlIGBjaGFpbmAgSUQgdXNpbmcgdGhlIGNvbnRyYWN0J3MgYGNvZGVgIGFuZCB0" + - "aGUgY29udHJhY3QncyBpbml0aWFsIHN0YXRlIGBkYXRhYC4gVXNlIHRoZSBgaW5pdE9mYCBleHByZXNzaW9uIHRvIG9idGFpbiB0aGUgaW5pdGlhbCBgY29kZWAgYW5k" + - "IGluaXRpYWwgYGRhdGFgIG9mIGEgZ2l2ZW4gY29udHJhY3QuCi8vLwovLy8gVGhpcyBmdW5jdGlvbiBsZXRzIHlvdSBzcGVjaWZ5IGFyYml0cmFyeSBgY2hhaW5gIElE" + - "cywgaW5jbHVkaW5nIHRoZSBjb21tb24gLTEgKG1hc3RlcmNoYWluKSBhbmQgMCAoYmFzZWNoYWluKSBvbmVzLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxl" + - "KCkgewovLy8gICAgIGxldCBpbml0UGtnOiBTdGF0ZUluaXQgPSBpbml0T2YgU29tZUNvbnRyYWN0KCk7Ci8vLyAgICAgbGV0IGhlcmVCZURyYWdvbnM6IEFkZHJlc3Mg" + - "PSBjb250cmFjdEFkZHJlc3NFeHQoMCwgaW5pdFBrZy5jb2RlLCBpbml0UGtnLmRhdGEpOwovLy8gfQovLy8gYGBgCi8vLwovLy8gU2VlOgovLy8gKiBodHRwczovL2Rv" + - "Y3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1hZGRyZXNzZXMjY29udHJhY3RhZGRyZXNzZXh0Ci8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL2Jvb2svZXhw" + - "cmVzc2lvbnMjaW5pdG9mCi8vLwppbmxpbmUgZnVuIGNvbnRyYWN0QWRkcmVzc0V4dChjaGFpbjogSW50LCBjb2RlOiBDZWxsLCBkYXRhOiBDZWxsKTogQWRkcmVzcyB7" + - "CiAgICBsZXQgaGFzaCA9IGNvbnRyYWN0SGFzaChjb2RlLCBkYXRhKTsKICAgIHJldHVybiBuZXdBZGRyZXNzKGNoYWluLCBoYXNoKTsKfQoKLy8vIFN0cnVjdCBjb250" + - "YWluaW5nIHRoZSBpbml0aWFsIHN0YXRlLCBpLmUuIGluaXRpYWwgY29kZSBhbmQgaW5pdGlhbCBkYXRhIG9mIHRoZSBnaXZlbiBjb250cmFjdCB1cG9uIGl0cyBkZXBs" + - "b3ltZW50LgovLy8KLy8vIFNlZTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvYm9vay9leHByZXNzaW9ucyNpbml0b2YKLy8vCnN0cnVjdCBTdGF0ZUluaXQgewog" + - "ICAgLy8vIEluaXRpYWwgY29kZSBvZiB0aGUgY29udHJhY3QgKGNvbXBpbGVkIGJpdGNvZGUpCiAgICBjb2RlOiBDZWxsOwoKICAgIC8vLyBJbml0aWFsIGRhdGEgb2Yg" + - "dGhlIGNvbnRyYWN0IChwYXJhbWV0ZXJzIG9mIGBpbml0KClgIGZ1bmN0aW9uIG9yIGNvbnRyYWN0IHBhcmFtZXRlcnMpCiAgICBkYXRhOiBDZWxsOwp9CgovLy8gR2xv" + - "YmFsIGZ1bmN0aW9uLiBBdmFpbGFibGUgc2luY2UgVGFjdCAxLjYuMS4KLy8vCi8vLyBDaGVja3MgaWYgdGhlIGdpdmVuIGBhZGRyZXNzYCBjb3JyZXNwb25kcyB0byB0" + - "aGUgY29udHJhY3QgYWRkcmVzcyBpbiB0aGUgd29ya2NoYWluIElEIDAgKGJhc2VjaGFpbikgZGVyaXZlZCBmcm9tIHRoZSBgU3RhdGVJbml0YCBgc2VsZmAuIFJldHVy" + - "bnMgYHRydWVgIGlmIHRoZSBhZGRyZXNzZXMgbWF0Y2ggYW5kIGBmYWxzZWAgb3RoZXJ3aXNlLgovLy8KLy8vIFRoaXMgZnVuY3Rpb24gd29ya3MgY29ycmVjdGx5IG9u" + - "bHkgZm9yIGJhc2VjaGFpbiBhZGRyZXNzZXMuIEl0IG1heSBwcm9kdWNlIGZhbHNlIHBvc2l0aXZlcyBvciBuZWdhdGl2ZXMgaWYgdGhlIHNwZWNpZmllZCBgYWRkcmVz" + - "c2Agb3IgdGhlIGFkZHJlc3MgZGVyaXZlZCBmcm9tIHRoZSBgU3RhdGVJbml0ezp0YWN0fWAgYHNlbGZ7OnRhY3R9YCBoYXMgYSBub24temVybyB3b3JrY2hhaW4gSUQu" + - "Ci8vLwovLy8gIyMjIyBVc2FnZQovLy8KLy8vIGBgYHRhY3QKLy8vIGNvbnRyYWN0IFBhcmVudCgpIHsKLy8vICAgICByZWNlaXZlKCkgewovLy8gICAgICAgICBsZXQg" + - "Y2hpbGRDb250cmFjdCA9IGluaXRPZiBDaGlsZChteUFkZHJlc3MoKSk7Ci8vLwovLy8gICAgICAgICAvLyBJZiB5b3UgYXJlIHdvcmtpbmcgd2l0aCBjb250cmFjdHMg" + - "b24gdGhlIGJhc2VjaGFpbiwgdGhpcwovLy8gICAgICAgICBsZXQgZXhwZW5zaXZlQ2hlY2sgPSBjb250cmFjdEFkZHJlc3MoY2hpbGRDb250cmFjdCkgPT0gc2VuZGVy" + - "KCk7Ci8vLwovLy8gICAgICAgICAvLyBpcyBtb3JlIGV4cGVuc2l2ZSB0aGFuIGRvaW5nIHRoaXMKLy8vICAgICAgICAgbGV0IGNoZWFwZXJDaGVjayA9IGNoaWxkQ29u" + - "dHJhY3QuaGFzU2FtZUJhc2VjaGFpbkFkZHJlc3Moc2VuZGVyKCkpOwovLy8KLy8vICAgICAgICAgLy8gd2hpbGUgdGhlIHJlc3VsdHMgYXJlIHRoZSBzYW1lCi8vLyAg" + - "ICAgICAgIGV4cGVuc2l2ZUNoZWNrID09IGNoZWFwZXJDaGVjazsgLy8gdHJ1ZQovLy8gICAgIH0KLy8vIH0KLy8vCi8vLyBjb250cmFjdCBDaGlsZChwYXJlbnRBZGRy" + - "OiBBZGRyZXNzKSB7Ci8vLyAgICAgcmVjZWl2ZSgpIHsKLy8vICAgICAgICAgLy8gRm9yd2FyZHMgc3VycGx1cyB0byB0aGUgcGFyZW50IGFkZHJlc3MgYnkgc2VuZGlu" + - "ZyBhIG1lc3NhZ2UKLy8vICAgICAgICAgLy8gd2l0aCBhbiBlbXB0eSBib2R5IGFuZCBhbGwgcmVtYWluaW5nIGZ1bmRzIGZyb20gdGhlIHJlY2VpdmVkIG1lc3NhZ2UK" + - "Ly8vICAgICAgICAgY2FzaGJhY2soc2VsZi5wYXJlbnRBZGRyKTsKLy8vICAgICB9Ci8vLyB9Ci8vLyBgYGAKLy8vCi8vLyAjIyMjIEV4aXQgY29kZXMKLy8vCi8vLyAq" + - "IDk6IFtDZWxsIHVuZGVyZmxvd10g4oCUIFRocm93biB3aGVuIHRoZSBzcGVjaWZpZWQgYGFkZHJlc3NgIGNhbm5vdCBiZSBwYXJzZWQgYXMgYSBgU3RkQWRkcmVzc2Au" + - "Ci8vLwovLy8gU2VlOgovLy8gKiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1hZGRyZXNzZXMjc3RhdGVpbml0aGFzc2FtZWJhc2VjaGFpbmFkZHJl" + - "c3MKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtYWRkcmVzc2VzI2NvbnRyYWN0YWRkcmVzcwovLy8KLy8vIFtDZWxsIHVuZGVyZmxvd106" + - "IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL2Jvb2svZXhpdC1jb2RlcyM5Ci8vLwppbmxpbmUgZXh0ZW5kcyBmdW4gaGFzU2FtZUJhc2VjaGFpbkFkZHJlc3Moc2Vs" + - "ZjogU3RhdGVJbml0LCBhZGRyZXNzOiBBZGRyZXNzKTogQm9vbCB7CiAgICBsZXQgYWRkcmVzc0hhc2ggPSBwYXJzZVN0ZEFkZHJlc3MoYWRkcmVzcy5hc1NsaWNlKCkp" + - "LmFkZHJlc3M7CiAgICBsZXQgYmFzZUFkZHJlc3MgPSBjb250cmFjdEJhc2VjaGFpbkFkZHJlc3Moc2VsZik7CiAgICByZXR1cm4gYmFzZUFkZHJlc3MuaGFzaCEhID09" + - "IGFkZHJlc3NIYXNoOwp9CgovLy8gR2xvYmFsIGZ1bmN0aW9uLgovLy8KLy8vIENvbXB1dGVzIHNtYXJ0IGNvbnRyYWN0J3MgYEFkZHJlc3NgIGluIHRoZSB3b3JrY2hh" + - "aW4gSUQgMCAoYmFzZWNoYWluKSB1c2luZyB0aGUgYFN0YXRlSW5pdGAgYHNgIG9mIHRoZSBjb250cmFjdC4gQWxpYXMgdG8gYGNvbnRyYWN0QWRkcmVzc0V4dCgwLCBz" + - "LmNvZGUsIHMuZGF0YSlgLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAgIGxldCBzOiBTdGF0ZUluaXQgPSBpbml0T2YgU29tZUNvbnRy" + - "YWN0KCk7Ci8vLyAgICAgbGV0IGZvdW5kTWVTb21lOiBBZGRyZXNzID0gY29udHJhY3RBZGRyZXNzKHMpOwovLy8gICAgIGxldCBhbmRTb21lTW9yZTogQWRkcmVzcyA9" + - "IGNvbnRyYWN0QWRkcmVzc0V4dCgwLCBzLmNvZGUsIHMuZGF0YSk7Ci8vLwovLy8gICAgIGZvdW5kTWVTb21lID09IGFuZFNvbWVNb3JlOyAvLyB0cnVlCi8vLyB9Ci8v" + - "LyBgYGAKLy8vCi8vLyBTZWU6Ci8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWFkZHJlc3NlcyNjb250cmFjdGFkZHJlc3MKLy8vICogaHR0" + - "cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtYWRkcmVzc2VzI2NvbnRyYWN0YWRkcmVzc2V4dAovLy8gKiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9i" + - "b29rL2V4cHJlc3Npb25zI2luaXRvZgovLy8KaW5saW5lIGZ1biBjb250cmFjdEFkZHJlc3MoczogU3RhdGVJbml0KTogQWRkcmVzcyB7CiAgICByZXR1cm4gY29udHJh" + - "Y3RBZGRyZXNzRXh0KDAsIHMuY29kZSwgcy5kYXRhKTsKfQoKLy8vIEdsb2JhbCBmdW5jdGlvbi4KLy8vCi8vLyBSZXR1cm5zIHRoZSBhZGRyZXNzIG9mIHRoZSBjdXJy" + - "ZW50IHNtYXJ0IGNvbnRyYWN0IGFzIGFuIGBBZGRyZXNzYC4KLy8vCi8vLyBgYGB0YWN0Ci8vLyBmdW4gZXhhbXBsZSgpIHsKLy8vICAgICBsZXQgbWVNeXNlbGZBbmRJ" + - "OiBBZGRyZXNzID0gbXlBZGRyZXNzKCk7Ci8vLyB9Ci8vLyBgYGAKLy8vCi8vLyBTZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWNvbnRleHRz" + - "dGF0ZSNteWFkZHJlc3MKLy8vCmFzbSBmdW4gbXlBZGRyZXNzKCk6IEFkZHJlc3MgeyBNWUFERFIgfQoKLy8vIEdsb2JhbCBmdW5jdGlvbi4KLy8vCi8vLyBSZXR1cm5z" + - "IHRoZSBuYW5vVG9uY29pbiBgSW50YCBiYWxhbmNlIG9mIHRoZSBzbWFydCBjb250cmFjdCBhcyBpdCB3YXMgYXQgdGhlIHN0YXJ0IG9mIHRoZSBjb21wdXRlIHBoYXNl" + - "IG9mIHRoZSBjdXJyZW50IHRyYW5zYWN0aW9uLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAgIGxldCBpTmVlZEFEb2xsYTogSW50ID0g" + - "bXlCYWxhbmNlKCk7Ci8vLyB9Ci8vLyBgYGAKLy8vCi8vLyBTZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWNvbnRleHRzdGF0ZSNteWJhbGFu" + - "Y2UKLy8vCmFzbSBmdW4gbXlCYWxhbmNlKCk6IEludCB7IEJBTEFOQ0UgRklSU1QgfQoKLy8vIEdsb2JhbCBmdW5jdGlvbi4gQXZhaWxhYmxlIHNpbmNlIFRhY3QgMS41" + - "LjAuCi8vLwovLy8gUmV0dXJucyB0aGUgbmFub1RvbmNvaW4gYEludGAgYW1vdW50IG9mIGdhcyBjb25zdW1lZCBieSBUVk0gaW4gdGhlIGN1cnJlbnQgdHJhbnNhY3Rp" + - "b24gc28gZmFyLiBUaGUgcmVzdWx0aW5nIHZhbHVlIGluY2x1ZGVzIHRoZSBjb3N0IG9mIGNhbGxpbmcgdGhpcyBmdW5jdGlvbi4KLy8vCi8vLyBgYGB0YWN0Ci8vLyBm" + - "dW4gZXhhbXBsZSgpIHsKLy8vICAgICBsZXQgZ2FzOiBJbnQgPSBnYXNDb25zdW1lZCgpOwovLy8gfQovLy8gYGBgCi8vLwovLy8gU2VlOiBodHRwczovL2RvY3MudGFj" + - "dC1sYW5nLm9yZy9yZWYvY29yZS1jb250ZXh0c3RhdGUjZ2FzY29uc3VtZWQKLy8vCmFzbSBmdW4gZ2FzQ29uc3VtZWQoKTogSW50IHsgR0FTQ09OU1VNRUQgfQoKLy8v" + - "IEdsb2JhbCBmdW5jdGlvbi4gQXZhaWxhYmxlIHNpbmNlIFRhY3QgMS41LjAuCi8vLwovLy8gUmV0dXJucyB0aGUgbmFub1RvbmNvaW4gYEludGAgYW1vdW50IG9mIHRo" + - "ZSBhY2N1bXVsYXRlZCBzdG9yYWdlIGZlZSBkZWJ0LiBTdG9yYWdlIGZlZXMgYXJlIGRlZHVjdGVkIGZyb20gdGhlIGluY29taW5nIG1lc3NhZ2UgdmFsdWUgYmVmb3Jl" + - "IHRoZSBuZXcgY29udHJhY3QgYmFsYW5jZSBpcyBjYWxjdWxhdGVkLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAgIGxldCBkZWJ0OiBJ" + - "bnQgPSBteVN0b3JhZ2VEdWUoKTsKLy8vIH0KLy8vIGBgYAovLy8KLy8vIFNlZTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtY29udGV4dHN0YXRl" + - "I215c3RvcmFnZWR1ZQovLy8KYXNtIGZ1biBteVN0b3JhZ2VEdWUoKTogSW50IHsgRFVFUEFZTUVOVCB9CgovLy8gR2xvYmFsIGZ1bmN0aW9uLiBBdmFpbGFibGUgc2lu" + - "Y2UgVGFjdCAxLjUuMC4KLy8vCi8vLyBDYWxjdWxhdGVzIGFuZCByZXR1cm5zIHRoZSBzdG9yYWdlIGZlZSBpbiBuYW5vVG9uY29pbnMgYEludGAgZm9yIHN0b3Jpbmcg" + - "YSBjb250cmFjdCB3aXRoIGEgZ2l2ZW4gbnVtYmVyIG9mIGBjZWxsc2AgYW5kIGBiaXRzYCBmb3IgYSBudW1iZXIgb2YgYHNlY29uZHNgLiBVc2VzIHRoZSBwcmljZXMg" + - "b2YgdGhlIG1hc3RlcmNoYWluIGlmIGBpc01hc3RlcmNoYWluYCBpcyBgdHJ1ZWAsIG90aGVyd2lzZSB0aGUgcHJpY2VzIG9mIHRoZSBiYXNlY2hhaW4uIFRoZSBjdXJy" + - "ZW50IHByaWNlcyBhcmUgb2J0YWluZWQgZnJvbSB0aGUgY29uZmlnIHBhcmFtIDE4IG9mIFRPTiBCbG9ja2NoYWluLgovLy8KLy8vIE5vdGUsIHRoYXQgc3BlY2lmeWlu" + - "ZyB2YWx1ZXMgb2YgYGNlbGxzYCBhbmQgYGJpdHNgIGhpZ2hlciB0aGFuIHRoZWlyIG1heGltdW0gdmFsdWVzIGxpc3RlZCBpbiBhY2NvdW50IHN0YXRlIGxpbWl0cyAo" + - "YG1heF9hY2Nfc3RhdGVfY2VsbHNgIGFuZCBgbWF4X2FjY19zdGF0ZV9iaXRzYCkgd2lsbCBoYXZlIHRoZSBzYW1lIHJlc3VsdCBhcyB3aXRoIHNwZWNpZnlpbmcgdGhl" + - "IGV4YWN0IGxpbWl0cy4gSW4gYWRkaXRpb24sIG1ha2Ugc3VyZSB5b3UgdGFrZSBpbnRvIGFjY291bnQgdGhlIGRlZHVwbGljYXRpb24gb2YgY2VsbHMgd2l0aCB0aGUg" + - "c2FtZSBoYXNoLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAgIGxldCBmZWU6IEludCA9IGdldFN0b3JhZ2VGZWUoMV8wMDAsIDFfMDAw" + - "LCAxXzAwMCwgZmFsc2UpOwovLy8gfQovLy8gYGBgCi8vLwovLy8gIyMjIyBFeGl0IGNvZGVzCi8vLwovLy8gKiA1OiBbSW50ZWdlciBvdXQgb2YgZXhwZWN0ZWQgcmFu" + - "Z2VdIOKAlCBUaHJvd24gd2hlbiBhdHRlbXB0aW5nIHRvIHNwZWNpZnkgbmVnYXRpdmUgbnVtYmVyIG9mIGBjZWxsc2AsIGBiaXRzYCBvciBgc2Vjb25kc2AuCi8vLwov" + - "Ly8gU2VlOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1nYXMjZ2V0c3RvcmFnZWZlZQovLy8KLy8vIFtJbnRlZ2VyIG91dCBvZiBleHBlY3RlZCBy" + - "YW5nZV06IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL2Jvb2svZXhpdC1jb2RlcyM1Ci8vLwphc20gZnVuIGdldFN0b3JhZ2VGZWUoY2VsbHM6IEludCwgYml0czog" + - "SW50LCBzZWNvbmRzOiBJbnQsIGlzTWFzdGVyY2hhaW46IEJvb2wpOiBJbnQgeyBHRVRTVE9SQUdFRkVFIH0KCi8vLyBHbG9iYWwgZnVuY3Rpb24uIEF2YWlsYWJsZSBz" + - "aW5jZSBUYWN0IDEuNS4wLgovLy8KLy8vIENhbGN1bGF0ZXMgYW5kIHJldHVybnMgdGhlIGNvbXB1dGUgZmVlIGluIG5hbm9Ub25jb2lucyBgSW50YCBmb3IgYSB0cmFu" + - "c2FjdGlvbiB0aGF0IGNvbnN1bWVkIGBnYXNVc2VkYCBhbW91bnQgb2YgZ2FzLiBVc2VzIHRoZSBwcmljZXMgb2YgdGhlIG1hc3RlcmNoYWluIGlmIGBpc01hc3RlcmNo" + - "YWluYCBpcyBgdHJ1ZWAsIG90aGVyd2lzZSB0aGUgcHJpY2VzIG9mIHRoZSBiYXNlY2hhaW4uIFRoZSBjdXJyZW50IHByaWNlcyBhcmUgb2J0YWluZWQgZnJvbSB0aGUg" + - "Y29uZmlnIHBhcmFtIDIwIGZvciB0aGUgbWFzdGVyY2hhaW4gYW5kIGNvbmZpZyBwYXJhbSAyMSBmb3IgdGhlIGJhc2VjaGFpbiBvZiBUT04gQmxvY2tjaGFpbi4KLy8v" + - "Ci8vLyBXaGVuIHRoZSBgZ2FzVXNlZGAgaXMgbGVzcyB0aGFuIGEgY2VydGFpbiB0aHJlc2hvbGQgY2FsbGVkIGBmbGF0X2dhc19saW1pdGAsIHRoZXJlJ3MgYSBtaW5p" + - "bXVtIHByaWNlIHRvIHBheSBiYXNlZCBvbiB0aGUgdmFsdWUgb2YgYGZsYXRfZ2FzX3ByaWNlYC4gVGhlIGxlc3MgZ2FzIGlzIHVzZWQgYmVsb3cgdGhpcyB0aHJlc2hv" + - "bGQsIHRoZSBoaWdoZXIgdGhlIG1pbmltdW0gcHJpY2Ugd2lsbCBiZS4gU2VlIHRoZSBleGFtcGxlIGZvciBgZ2V0U2ltcGxlQ29tcHV0ZUZlZSgpYCB0byBkZXJpdmUg" + - "dGhhdCB0aHJlc2hvbGQuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKSB7Ci8vLyAgICAgbGV0IGZlZTogSW50ID0gZ2V0Q29tcHV0ZUZlZSgxXzAwMCwg" + - "ZmFsc2UpOwovLy8gfQovLy8gYGBgCi8vLwovLy8gIyMjIyBFeGl0IGNvZGVzCi8vLwovLy8gKiA1OiBbSW50ZWdlciBvdXQgb2YgZXhwZWN0ZWQgcmFuZ2VdIOKAlCBU" + - "aHJvd24gd2hlbiBhdHRlbXB0aW5nIHRvIHNwZWNpZnkgbmVnYXRpdmUgdmFsdWUgb2YgYGdhc1VzZWRgLgovLy8KLy8vIFNlZTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFu" + - "Zy5vcmcvcmVmL2NvcmUtZ2FzI2dldGNvbXB1dGVmZWUKLy8vCi8vLyBbSW50ZWdlciBvdXQgb2YgZXhwZWN0ZWQgcmFuZ2VdOiBodHRwczovL2RvY3MudGFjdC1sYW5n" + - "Lm9yZy9ib29rL2V4aXQtY29kZXMjNQovLy8KYXNtIGZ1biBnZXRDb21wdXRlRmVlKGdhc1VzZWQ6IEludCwgaXNNYXN0ZXJjaGFpbjogQm9vbCk6IEludCB7IEdFVEdB" + - "U0ZFRSB9CgovLy8gR2xvYmFsIGZ1bmN0aW9uLiBBdmFpbGFibGUgc2luY2UgVGFjdCAxLjUuMC4KLy8vCi8vLyBTaW1pbGFyIHRvIGBnZXRDb21wdXRlRmVlKClgLCBi" + - "dXQgd2l0aG91dCB0aGUgYGZsYXRfZ2FzX3ByaWNlYCwgaS5lLiB3aXRob3V0IGEgbWluaW11bSBwcmljZSB0byBwYXkgaWYgdGhlIGBnYXNVc2VkYCBpcyBsZXNzIHRo" + - "YW4gYSBjZXJ0YWluIHRocmVzaG9sZCBjYWxsZWQgYGZsYXRfZ2FzX2xpbWl0YC4gQ2FsY3VsYXRlcyBhbmQgcmV0dXJucyBvbmx5IHRoZSBgZ2FzVXNlZGAgdGltZXMg" + - "dGhlIGN1cnJlbnQgZ2FzIHByaWNlLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAgIGxldCBmZWUgPSBnZXRDb21wdXRlRmVlKDAsIGZh" + - "bHNlKTsKLy8vICAgICBsZXQgZmVlTm9GbGF0ID0gZ2V0U2ltcGxlQ29tcHV0ZUZlZSgwLCBmYWxzZSk7Ci8vLyAgICAgbGV0IG1heEZsYXRQcmljZSA9IGZlZSAtIGZl" + - "ZU5vRmxhdDsKLy8vIH0KLy8vIGBgYAovLy8KLy8vICMjIyMgRXhpdCBjb2RlcwovLy8KLy8vICogNTogW0ludGVnZXIgb3V0IG9mIGV4cGVjdGVkIHJhbmdlXSDigJQg" + - "VGhyb3duIHdoZW4gYXR0ZW1wdGluZyB0byBzcGVjaWZ5IG5lZ2F0aXZlIG51bWJlciBvZiBgY2VsbHNgLCBgYml0c2Agb3IgYHNlY29uZHNgLgovLy8KLy8vIFNlZToK" + - "Ly8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtZ2FzI2dldHNpbXBsZWNvbXB1dGVmZWUKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5v" + - "cmcvcmVmL2NvcmUtZ2FzI2dldGNvbXB1dGVmZWUKLy8vCi8vLyBbSW50ZWdlciBvdXQgb2YgZXhwZWN0ZWQgcmFuZ2VdOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9y" + - "Zy9ib29rL2V4aXQtY29kZXMjNQovLy8KYXNtIGZ1biBnZXRTaW1wbGVDb21wdXRlRmVlKGdhc1VzZWQ6IEludCwgaXNNYXN0ZXJjaGFpbjogQm9vbCk6IEludCB7IEdF" + - "VEdBU0ZFRVNJTVBMRSB9CgovLy8gR2xvYmFsIGZ1bmN0aW9uLiBBdmFpbGFibGUgc2luY2UgVGFjdCAxLjUuMC4KLy8vCi8vLyBDYWxjdWxhdGVzIGFuZCByZXR1cm5z" + - "IHRoZSBmb3J3YXJkIGZlZSBpbiBuYW5vVG9uY29pbnMgYEludGAgZm9yIGFuIG91dGdvaW5nIG1lc3NhZ2UgY29uc2lzdGluZyBvZiBhIGdpdmVuIG51bWJlciBvZiBg" + - "Y2VsbHNgIGFuZCBgYml0c2AuIFVzZXMgdGhlIHByaWNlcyBvZiB0aGUgbWFzdGVyY2hhaW4gaWYgYGlzTWFzdGVyY2hhaW5gIGlzIGB0cnVlYCwgb3RoZXJ3aXNlIHRo" + - "ZSBwcmljZXMgb2YgdGhlIGJhc2VjaGFpbi4gVGhlIGN1cnJlbnQgcHJpY2VzIGFyZSBvYnRhaW5lZCBmcm9tIHRoZSBjb25maWcgcGFyYW0gMjQgZm9yIHRoZSBtYXN0" + - "ZXJjaGFpbiBhbmQgY29uZmlnIHBhcmFtIDI1IGZvciB0aGUgYmFzZWNoYWluIG9mIFRPTiBCbG9ja2NoYWluLgovLy8KLy8vIElmIGJvdGggdGhlIHNvdXJjZSBhbmQg" + - "dGhlIGRlc3RpbmF0aW9uIGFkZHJlc3NlcyBhcmUgaW4gdGhlIGJhc2VjaGFpbiwgdGhlbiBzcGVjaWZ5IGBpc01hc3RlcmNoYWluYCBhcyBgZmFsc2VgLiBPdGhlcndp" + - "c2UsIHNwZWNpZnkgYHRydWVgLgovLy8KLy8vIE5vdGUsIHRoYXQgc3BlY2lmeWluZyB2YWx1ZXMgb2YgYGNlbGxzYCBhbmQgYGJpdHNgIGhpZ2hlciB0aGFuIHRoZWly" + - "IG1heGltdW0gdmFsdWVzIGxpc3RlZCBpbiBhY2NvdW50IHN0YXRlIGxpbWl0cyAoYG1heF9tc2dfY2VsbHNgIGFuZCBgbWF4X21zZ19iaXRzYCkgd2lsbCBoYXZlIHRo" + - "ZSBzYW1lIHJlc3VsdCBhcyB3aXRoIHNwZWNpZnlpbmcgdGhlIGV4YWN0IGxpbWl0cy4KLy8vCi8vLyBIb3dldmVyLCByZWdhcmRsZXNzIG9mIHRoZSB2YWx1ZXMgb2Yg" + - "YGNlbGxzYCBhbmQgYGJpdHNgLCB0aGlzIGZ1bmN0aW9uIGFsd2F5cyBhZGRzIHRoZSBtaW5pbXVtIHByaWNlIGJhc2VkIG9uIHRoZSB2YWx1ZSBvZiBgbHVtcF9wcmlj" + - "ZWAuIFNlZSB0aGUgZXhhbXBsZSBmb3IgYGdldFNpbXBsZUZvcndhcmRGZWUoKWAgdG8gZGVyaXZlIGl0LiBJbiBhZGRpdGlvbiwgbWFrZSBzdXJlIHlvdSB0YWtlIGlu" + - "dG8gYWNjb3VudCB0aGUgZGVkdXBsaWNhdGlvbiBvZiBjZWxscyB3aXRoIHRoZSBzYW1lIGhhc2gsIHNpbmNlIGZvciBleGFtcGxlIHRoZSByb290IGNlbGwgYW5kIGl0" + - "cyBkYXRhIGJpdHMgZG9uJ3QgY291bnQgdG93YXJkcyB0aGUgZm9yd2FyZCBmZWUgYW5kIGFyZSBjb3ZlcmVkIGJ5IHRoZSBgbHVtcF9wcmljZWAuCi8vLwovLy8gYGBg" + - "dGFjdAovLy8gZnVuIGV4YW1wbGUoKSB7Ci8vLyAgICAgbGV0IGZlZTogSW50ID0gZ2V0Rm9yd2FyZEZlZSgxXzAwMCwgMV8wMDAsIGZhbHNlKTsKLy8vIH0KLy8vIGBg" + - "YAovLy8KLy8vICMjIyMgRXhpdCBjb2RlcwovLy8KLy8vICogNTogW0ludGVnZXIgb3V0IG9mIGV4cGVjdGVkIHJhbmdlXSDigJQgVGhyb3duIHdoZW4gYXR0ZW1wdGlu" + - "ZyB0byBzcGVjaWZ5IG5lZ2F0aXZlIG51bWJlciBvZiBgY2VsbHNgIG9yIGBiaXRzYC4KLy8vCi8vLyBTZWU6Ci8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3Jn" + - "L3JlZi9jb3JlLWdhcyNnZXRmb3J3YXJkZmVlCi8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWdhcyNnZXRzaW1wbGVmb3J3YXJkZmVlCi8v" + - "LyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWdhcyNnZXRvcmlnaW5hbGZ3ZGZlZQovLy8KLy8vIFtJbnRlZ2VyIG91dCBvZiBleHBlY3RlZCBy" + - "YW5nZV06IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL2Jvb2svZXhpdC1jb2RlcyM1Ci8vLwphc20gZnVuIGdldEZvcndhcmRGZWUoY2VsbHM6IEludCwgYml0czog" + - "SW50LCBpc01hc3RlcmNoYWluOiBCb29sKTogSW50IHsgR0VURk9SV0FSREZFRSB9CgovLy8gR2xvYmFsIGZ1bmN0aW9uLiBBdmFpbGFibGUgc2luY2UgVGFjdCAxLjUu" + - "MC4KLy8vCi8vLyBTaW1pbGFyIHRvIGBnZXRGb3J3YXJkRmVlKClgLCBidXQgd2l0aG91dCB0aGUgYGx1bXBfcHJpY2VgLCBpLmUuIHdpdGhvdXQgdGhlIG1pbmltdW0g" + - "cHJpY2UgdG8gcGF5IHJlZ2FyZGxlc3Mgb2YgdGhlIGFtb3VudCBvZiBgY2VsbHNgIG9yIGBiaXRzYC4gQ2FsY3VsYXRlcyBhbmQgcmV0dXJucyBvbmx5IHRoZSBgY2Vs" + - "bHNgIHRpbWVzIHRoZSBjdXJyZW50IGNlbGwgcHJpY2UgcGx1cyBgYml0c2AgdGltZXMgdGhlIGN1cnJlbnQgYml0IHByaWNlLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1" + - "biBleGFtcGxlKCkgewovLy8gICAgIGxldCBmZWUgPSBnZXRGb3J3YXJkRmVlKDFfMDAwLCAxXzAwMCwgZmFsc2UpOwovLy8gICAgIGxldCBmZWVOb0x1bXAgPSBnZXRT" + - "aW1wbGVGb3J3YXJkRmVlKDFfMDAwLCAxXzAwMCwgZmFsc2UpOwovLy8gICAgIGxldCBsdW1wUHJpY2UgPSBmZWUgLSBmZWVOb0x1bXA7Ci8vLyB9Ci8vLyBgYGAKLy8v" + - "Ci8vLyAjIyMjIEV4aXQgY29kZXMKLy8vCi8vLyAqIDU6IFtJbnRlZ2VyIG91dCBvZiBleHBlY3RlZCByYW5nZV0g4oCUIFRocm93biB3aGVuIGF0dGVtcHRpbmcgdG8g" + - "c3BlY2lmeSBuZWdhdGl2ZSBudW1iZXIgb2YgYGNlbGxzYCBvciBgYml0c2AuCi8vLwovLy8gU2VlOgovLy8gKiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYv" + - "Y29yZS1nYXMjZ2V0c2ltcGxlZm9yd2FyZGZlZQovLy8gKiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1nYXMjZ2V0Zm9yd2FyZGZlZQovLy8KLy8v" + - "IFtJbnRlZ2VyIG91dCBvZiBleHBlY3RlZCByYW5nZV06IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL2Jvb2svZXhpdC1jb2RlcyM1Ci8vLwphc20gZnVuIGdldFNp" + - "bXBsZUZvcndhcmRGZWUoY2VsbHM6IEludCwgYml0czogSW50LCBpc01hc3RlcmNoYWluOiBCb29sKTogSW50IHsgR0VURk9SV0FSREZFRVNJTVBMRSB9CgovLy8gR2xv" + - "YmFsIGZ1bmN0aW9uLiBBdmFpbGFibGUgc2luY2UgVGFjdCAxLjUuMC4KLy8vCi8vLyBDYWxjdWxhdGVzIGFuZCByZXR1cm5zIHRoZSBzby1jYWxsZWQgX29yaWdpbmFs" + - "XyBmb3J3YXJkIGZlZSBpbiBuYW5vVG9uY29pbiBgSW50YCBmb3IgYSBtZXNzYWdlIGJhc2VkIG9uIHRoZSBnaXZlbiBgZndkRmVlYCBvZiB0aGlzIG1lc3NhZ2UsIHdo" + - "aWNoIGNhbiBiZSBvYnRhaW5lZCBieSBjYWxsaW5nIGBnZXRGb3J3YXJkRmVlKClgLiBJZiBib3RoIHRoZSBzb3VyY2UgYW5kIHRoZSBkZXN0aW5hdGlvbiBhZGRyZXNz" + - "ZXMgYXJlIGluIHRoZSBiYXNlY2hhaW4sIHNwZWNpZnkgYGlzTWFzdGVyY2hhaW5gIGFzIGBmYWxzZWAuIE90aGVyd2lzZSwgc3BlY2lmeSBgdHJ1ZWAuCi8vLwovLy8g" + - "VGhlIHJlc3VsdCBpcyBjb21wdXRlZCB1c2luZyB0aGUgYGZpcnN0X2ZyYWNgIHZhbHVlLCB3aGljaCBpcyBvYnRhaW5lZCBmcm9tIGNvbmZpZyBwYXJhbSAyNCBmb3Ig" + - "dGhlIG1hc3RlcmNoYWluIGFuZCBjb25maWcgcGFyYW0gMjUgZm9yIHRoZSBiYXNlY2hhaW4gb2YgVE9OIEJsb2NrY2hhaW4uIER1ZSB0byB0aGUgY3VycmVudCB2YWx1" + - "ZSBvZiBgZmlyc3RfZnJhY2AgZm9yIGFsbCB3b3JrY2hhaW5zLCB0aGlzIGZ1bmN0aW9uIHBlcmZvcm1zIGEgY2hlYXBlciBlcXVpdmFsZW50IGNhbGN1bGF0aW9uIG9m" + - "IGBmd2RGZWUgKiAzIC8gMmAuIFRoaXMgcmF0aW8gbWlnaHQgY2hhbmdlLCBzbyBpdCBpcyBiZXR0ZXIgbm90IHRvIGhhcmRjb2RlIGl0IGFuZCB1c2UgdGhpcyBmdW5j" + - "dGlvbiBpbnN0ZWFkLgovLy8KLy8vIFRoaXMgZnVuY3Rpb24gY2FuIGJlIHVzZWZ1bCB3aGVuIHRoZSBvdXRnb2luZyBtZXNzYWdlIGRlcGVuZHMgaGVhdmlseSBvbiB0" + - "aGUgc3RydWN0dXJlIG9mIHRoZSBpbmNvbWluZyBtZXNzYWdlLCBzbyB5b3UgY2FuIHRyeSB0byBhcHByb3hpbWF0ZSB0aGUgZm9yd2FyZCBmZWUgZm9yIHlvdXIgb3V0" + - "Z29pbmcgbWVzc2FnZSBiYXNlZCBvbiB0aGUgZmVlIHRoZSBzZW5kZXIgcGFpZC4gQ2FsY3VsYXRpbmcgdGhlIGV4YWN0IGZlZSB3aXRoIG5hbm9Ub25jb2luLWxldmVs" + - "IHByZWNpc2lvbiBjYW4gYmUgdmVyeSBleHBlbnNpdmUsIHNvIHRoZSBhcHByb3hpbWF0aW9uIGdpdmVuIGJ5IHRoaXMgZnVuY3Rpb24gaXMgb2Z0ZW4gZ29vZCBlbm91" + - "Z2guCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKSB7Ci8vLyAgICAgLy8gQ29udGV4dC5yZWFkRm9yd2FyZEZlZSgpIGFwcGxpZXMgZ2V0T3JpZ2luYWxG" + - "d2RGZWUoKSBhdCB0aGUgZW5kCi8vLyAgICAgbGV0IG9yaWdGd2RGZWU6IEludCA9IGNvbnRleHQoKS5yZWFkRm9yd2FyZEZlZSgpOwovLy8KLy8vICAgICAvLyBUaGVy" + - "ZWZvcmUsIGNhbGxpbmcgZ2V0T3JpZ2luYWxGd2RGZWUoKSBvbiB0aGF0IHZhbHVlIGlzIHJlZHVuZGFudAovLy8gICAgIGxldCBvcmlnRndkRmVlMjogSW50ID0gZ2V0" + - "T3JpZ2luYWxGd2RGZWUob3JpZ0Z3ZEZlZSwgZmFsc2UpOwovLy8KLy8vICAgICAvLyDijIgoMiAqIG9yaWdGd2RGZWUyKSAvIG9yaWdGd2RGZWXijIkgaXMgZXF1YWwg" + - "dG8gMwovLy8gICAgIG11bGRpdmMoMiwgb3JpZ0Z3ZEZlZTIsIG9yaWdGd2RGZWUpID09IDM7IC8vIHRydWUsIGJ1dCB0aGlzIHJlbGF0aW9uCi8vLyAgICAgICAgICAg" + - "ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2FuIGNoYW5nZSBpbiB0aGUgZnV0dXJlCi8vLyB9Ci8vLyBgYGAKLy8vCi8vLyAjIyMjIEV4aXQg" + - "Y29kZXMKLy8vCi8vLyAqIDU6IFtJbnRlZ2VyIG91dCBvZiBleHBlY3RlZCByYW5nZV0g4oCUIFRocm93biB3aGVuIGF0dGVtcHRpbmcgdG8gc3BlY2lmeSBhIG5lZ2F0" + - "aXZlIHZhbHVlIG9mIGBmd2RGZWVgLgovLy8KLy8vIFNlZToKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtZ2FzI2dldG9yaWdpbmFsZndk" + - "ZmVlCi8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWdhcyNnZXRmb3J3YXJkZmVlCi8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3Jn" + - "L3JlZi9jb3JlLWNvbnRleHRzdGF0ZSNjb250ZXh0cmVhZGZvcndhcmRmZWUKLy8vCi8vLyBbSW50ZWdlciBvdXQgb2YgZXhwZWN0ZWQgcmFuZ2VdOiBodHRwczovL2Rv" + - "Y3MudGFjdC1sYW5nLm9yZy9ib29rL2V4aXQtY29kZXMjNQovLy8KYXNtIGZ1biBnZXRPcmlnaW5hbEZ3ZEZlZShmd2RGZWU6IEludCwgaXNNYXN0ZXJjaGFpbjogQm9v" + - "bCk6IEludCB7IEdFVE9SSUdJTkFMRldERkVFIH0KCi8vLyBHbG9iYWwgZnVuY3Rpb24uIEF2YWlsYWJsZSBzaW5jZSBUYWN0IDEuNi4wLgovLy8KLy8vIFNldHMgdGhl" + - "IGBnYXNfbGltaXRgIHRvIHRoZSBgSW50YCBgbGltaXRgIGFuZCByZXNldHMgdGhlIGBnYXNfY3JlZGl0YCB0byAwLiBOb3RlIHRoYXQgc3BlY2lmeWluZyB0aGUgYGxp" + - "bWl0YCBoaWdoZXIgdGhhbiB0aGUgbWF4aW11bSBhbGxvd2VkIHZhbHVlIG9mIDJeNjMgLSAxIHdpbGwgaGF2ZSB0aGUgc2FtZSByZXN1bHQgYXMgd2l0aCBzcGVjaWZ5" + - "aW5nIHRoYXQgZXhhY3QgbWF4aW11bSBvciBjYWxsaW5nIGBhY2NlcHRNZXNzYWdlKClgLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAg" + - "IHNldEdhc0xpbWl0KDQyMDAwKTsKLy8vIH0KLy8vIGBgYAovLy8KLy8vICMjIyMgRXhpdCBjb2RlcwovLy8KLy8vICogLTE0OiBbT3V0IG9mIGdhcyBlcnJvcl0g4oCU" + - "IFRocm93biB3aGVuIGF0dGVtcHRpbmcgdG8gc3BlY2lmeSBhIG5lZ2F0aXZlIG9yIGluc3VmZmljaWVudCB2YWx1ZSBvZiBgbGltaXRgLgovLy8KLy8vIFNlZTogaHR0" + - "cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtZ2FzI3NldGdhc2xpbWl0Ci8vLwovLy8gW091dCBvZiBnYXMgZXJyb3JdOiBodHRwczovL2RvY3MudGFjdC1s" + - "YW5nLm9yZy9ib29rL2V4aXQtY29kZXMjLTE0Ci8vLwphc20gZnVuIHNldEdhc0xpbWl0KGxpbWl0OiBJbnQpIHsgU0VUR0FTTElNSVQgfQoKLy8vIEdsb2JhbCBmdW5j" + - "dGlvbi4gQXZhaWxhYmxlIHNpbmNlIFRhY3QgMS42LjAuCi8vLwovLy8gR2VuZXJhdGVzIGFuZCByZXR1cm5zIGFuIHVuc2lnbmVkIDI1Ni1iaXQgYEludGAgc2VlZCBm" + - "b3IgdGhlIHJhbmRvbSBudW1iZXIgZ2VuZXJhdG9yLiBUaGUgcmVzdWx0aW5nIHNlZWQgaXMgY29tbW9ubHkgdXNlZCB3aXRoIHRoZSBgc2V0U2VlZCgpYCBhbmQgYG5h" + - "dGl2ZVJhbmRvbWl6ZSgpYCBmdW5jdGlvbnMuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKSB7Ci8vLyAgICAgbGV0IHNlZWQ6IEludCA9IGdldFNlZWQo" + - "KTsKLy8vICAgICBzZXRTZWVkKHNlZWQpOyAvLyBmcm9tIG5vdyBvbiB0aGUgcmVzdWx0cyBvZiBwc2V1ZG9yYW5kb20gbnVtYmVyIGdlbmVyYXRvcgovLy8gICAgICAg" + - "ICAgICAgICAgICAgIC8vIGFyZSBjb21wbGV0ZWx5IGRldGVybWluZWQgYnkgdGhlIHNlZWQsIHdoaWNoIGNhbiBiZSBoYW5keSBpbiB0ZXN0cywKLy8vICAgICAgICAg" + - "ICAgICAgICAgICAvLyBidXQgbXVzdCBub3QgYmUgdXNlZCBpbiBwcm9kdWN0aW9uIGNvZGUhCi8vLyB9Ci8vLyBgYGAKLy8vCi8vLyBTZWU6Ci8vLyAqIGh0dHBzOi8v" + - "ZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLXJhbmRvbSNnZXRzZWVkCi8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLXJhbmRvbSNzZXRz" + - "ZWVkCi8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLXJhbmRvbSNuYXRpdmVyYW5kb21pemUKLy8vCmFzbSBmdW4gZ2V0U2VlZCgpOiBJbnQg" + - "eyBSQU5EU0VFRCB9CgovLy8gR2xvYmFsIGZ1bmN0aW9uLiBBdmFpbGFibGUgc2luY2UgVGFjdCAxLjYuMC4KLy8vCi8vLyBTZXRzIHRoZSBzZWVkIG9mIHRoZSByYW5k" + - "b20gbnVtYmVyIGdlbmVyYXRvciB0byB0aGUgdW5zaWduZWQgMjU2LWJpdCBgSW50YCBgc2VlZGAgd2hpY2ggY2FuIGJlIG9idGFpbmVkIHdpdGggdGhlIGBnZXRTZWVk" + - "KClgIGZ1bmN0aW9uLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAgIGxldCBzZWVkOiBJbnQgPSBnZXRTZWVkKCk7Ci8vLyAgICAgc2V0" + - "U2VlZChzZWVkKTsgLy8gZnJvbSBub3cgb24gdGhlIHJlc3VsdHMgb2YgcHNldWRvcmFuZG9tIG51bWJlciBnZW5lcmF0b3IKLy8vICAgICAgICAgICAgICAgICAgICAv" + - "LyBhcmUgY29tcGxldGVseSBkZXRlcm1pbmVkIGJ5IHRoZSBzZWVkLCB3aGljaCBjYW4gYmUgaGFuZHkgaW4gdGVzdHMsCi8vLyAgICAgICAgICAgICAgICAgICAgLy8g" + - "YnV0IG11c3Qgbm90IGJlIHVzZWQgaW4gcHJvZHVjdGlvbiBjb2RlIQovLy8gfQovLy8gYGBgCi8vLwovLy8gIyMjIyBFeGl0IGNvZGVzCi8vLwovLy8gKiA1OiBbSW50" + - "ZWdlciBvdXQgb2YgZXhwZWN0ZWQgcmFuZ2VdIOKAlCBUaHJvd24gd2hlbiBhdHRlbXB0aW5nIHRvIHNwZWNpZnkgYSBuZWdhdGl2ZSB2YWx1ZSBvZiBgc2VlZGAuCi8v" + - "LwovLy8gU2VlOgovLy8gKiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1yYW5kb20jc2V0c2VlZAovLy8gKiBodHRwczovL2RvY3MudGFjdC1sYW5n" + - "Lm9yZy9yZWYvY29yZS1yYW5kb20jZ2V0c2VlZAovLy8KLy8vIFtJbnRlZ2VyIG91dCBvZiBleHBlY3RlZCByYW5nZV06IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3Jn" + - "L2Jvb2svZXhpdC1jb2RlcyM1Ci8vLwphc20gZnVuIHNldFNlZWQoc2VlZDogSW50KSB7IFNFVFJBTkQgfQoKLy8vIEdsb2JhbCBmdW5jdGlvbi4gQXZhaWxhYmxlIHNp" + - "bmNlIFRhY3QgMS42LjAuCi8vLwovLy8gUmV0dXJucyB0aGUgc21hcnQgY29udHJhY3QgY29kZSBgQ2VsbGAgb2J0YWluZWQgZnJvbSB0aGUgYGM3YCByZWdpc3Rlci4K" + - "Ly8vCi8vLyBgYGB0YWN0Ci8vLyBmdW4gZXhhbXBsZSgpIHsKLy8vICAgICBsZXQgY29kZTogQ2VsbCA9IG15Q29kZSgpOwovLy8gfQovLy8gYGBgCi8vLwovLy8gU2Vl" + - "OiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1jb250ZXh0c3RhdGUjbXljb2RlCi8vLwphc20gZnVuIG15Q29kZSgpOiBDZWxsIHsgTVlDT0RFIH0K"; + "aW1wb3J0ICIuL2FkZHJlc3MiOwppbXBvcnQgIi4vY29udGV4dCI7CgovLy8gR2xvYmFsIGZ1bmN0aW9uLiBBdmFpbGFibGUgc2luY2UgVGFjdCAxLjYuMC4KLy8vCi8v" + + "LyBDb21wdXRlcyBhbmQgcmV0dXJucyBhbiBgSW50YCB2YWx1ZSBvZiB0aGUgU0hBLTI1NiBoYXNoIG9mIHRoZSBgY29kZWAgYW5kIGBkYXRhYCBvZiB0aGUgZ2l2ZW4g" + + "Y29udHJhY3QuIFRvIGFzc2VtYmxlIHRoZSBgY29kZWAgYW5kIGBkYXRhYCBjZWxscyB0b2dldGhlciBmb3IgaGFzaGluZywgdGhlIHN0YW5kYXJkIGBDZWxsYCByZXBy" + + "ZXNlbnRhdGlvbiBpcyB1c2VkLgovLy8KLy8vIFRoaXMgaGFzaCBpcyBjb21tb25seSBjYWxsZWQgYWNjb3VudCBJRC4gVG9nZXRoZXIgd2l0aCB0aGUgd29ya2NoYWlu" + + "IElEIGl0IGRldGVybWluaXN0aWNhbGx5IGZvcm1zIHRoZSBhZGRyZXNzIG9mIHRoZSBjb250cmFjdCBvbiBUT04gQmxvY2tjaGFpbi4KLy8vCi8vLyBgYGB0YWN0Ci8v" + + "LyBmdW4gZXhhbXBsZSgpIHsKLy8vICAgICBsZXQgaW5pdFBrZzogU3RhdGVJbml0ID0gaW5pdE9mIFNvbWVDb250cmFjdCgpOwovLy8gICAgIGxldCBhY2NvdW50SWQ6" + + "IEludCA9IGNvbnRyYWN0SGFzaChpbml0UGtnLmNvZGUsIGluaXRQa2cuZGF0YSk7Ci8vLyAgICAgbGV0IGJhc2VjaGFpbkFkZHI6IEFkZHJlc3MgPSBuZXdBZGRyZXNz" + + "KDAsIGFjY291bnRJZCk7Ci8vLyAgICAgbGV0IGJhc2VjaGFpbkFkZHIyOiBBZGRyZXNzID0gY29udHJhY3RBZGRyZXNzRXh0KDAsIGluaXRQa2cuY29kZSwgaW5pdFBr" + + "Zy5kYXRhKTsKLy8vCi8vLyAgICAgYmFzZWNoYWluQWRkciA9PSBiYXNlY2hhaW5BZGRyMjsgLy8gdHJ1ZQovLy8gfQovLy8gYGBgCi8vLwovLy8gU2VlOgovLy8gKiBo" + + "dHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1hZGRyZXNzZXMjY29udHJhY3RoYXNoCi8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9j" + + "b3JlLWFkZHJlc3NlcyNuZXdhZGRyZXNzCi8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWFkZHJlc3NlcyNjb250cmFjdGFkZHJlc3NleHQK" + + "Ly8vCmFzbSBmdW4gY29udHJhY3RIYXNoKGNvZGU6IENlbGwsIGRhdGE6IENlbGwpOiBJbnQgewogICAgLy8gQWNjb3JkaW5nIHRvIHRoZSBodHRwczovL2RvY3MudGFj" + + "dC1sYW5nLm9yZy9ib29rL2NlbGxzI2NlbGxzLXJlcHJlc2VudGF0aW9uLAogICAgLy8gdGhlIGxheW91dCBmb3IgdGhlIEJ1aWxkZXIgdG8gaGFzaCBnb2VzIGFzIGZv" + + "bGxvd3M6CiAgICAvLyAxKSByZWZzX2Rlc2NyaXB0b3I6Yml0czggfCBiaXRzX2Rlc2NyaXB0b3I6Yml0czggfCBkYXRhOmJpdHNOCiAgICAvLwogICAgLy8gIHJlZnNf" + + "ZGVzY3JpcHRvcjogcmVmX2NvdW50ICsgKChleG90aWM/ICYgMSkgKiA4KSArIChtYXNrICogMzIpCiAgICAvLyAgICAgICAgICAgICAgICAgICAyIHJlZnMgKGNvZGUg" + + "KyBkYXRhKSwgbm9uLWV4b3RpYywgemVyby1tYXNrCiAgICAvLwogICAgLy8gIGJpdHNfZGVzY3JpcHRvcjogZmxvb3IoYml0X2NvdW50IC8gOCkgKyBjZWlsKGJpdF9j" + + "b3VudCwgOCkKICAgIC8vICAgICAgICAgICAgICAgICAgIGZsb29yICg1IGJpdHMgLyA4KSArIGNlaWwoNSBiaXRzIC8gOCkgPSAwICsgMSA9IDEKICAgIC8vCiAgICAv" + + "LyAgZGF0YTogWzBiMDAxMTBdICsgWzBiMTAwXSA9IFswYjAwMTEwMTAwXSA9IDB4MzQgKGRhdGEgKyBhdWdtZW50ZWQgYml0cykKICAgIC8vICAgICAgICAwYjAwMTEw" + + "IC0gZGF0YSAoc3BsaXRfZGVwdGgsIHNwZWNpYWwsIGNvZGUsIGRhdGEsIExpYnJhcnkpCiAgICAvLyAgICAgICAgMGIxMDAgLSBhdWdtZW50ZWQgYml0cyAoTGVhZGlu" + + "ZyAxICsgemVyb2VzIHRvIG1ha2Ugc2VjdGlvbiBtdWx0aXBsZSBvZiBlaWdodCkKICAgIC8vCiAgICAvLyAgVGhhdCBpczogKDIgPDwgMTYpIHwgKDEgPDwgOCkgfCAw" + + "eDM0ID0gMTMxMzgwIGZvciBhbGwgdGhyZWUuCiAgICAvLwogICAgLy8gMikgYW5kIDMpIGRlcHRoX2Rlc2NyaXB0b3JzOiBDREVQVEggb2YgYGNvZGVgIGFuZCBDREVQ" + + "VEggb2YgYGRhdGFgCiAgICAvLyA0KSBhbmQgNSkgcmVmIGhhc2hlczogSEFTSENVIG9mIGBjb2RlYCBhbmQgSEFTSENVIG9mIGBkYXRhYAoKICAgIC8vIEdyb3VwIDE6" + + "IENvbXB1dGF0aW9ucyBhbmQgYXJyYW5nZW1lbnRzCiAgICBzMCBQVVNIIEhBU0hDVSAvLyBgZGF0YWAgaGFzaAogICAgczIgUFVTSCBIQVNIQ1UgLy8gYGNvZGVgIGhh" + + "c2gKICAgIFNXQVAyCiAgICBDREVQVEggICAgICAgICAvLyBgZGF0YWAgZGVwdGgKICAgIFNXQVAKICAgIENERVBUSCAgICAgICAgIC8vIGBjb2RlYCBkZXB0aAogICAg" + + "MTMxMzgwIElOVCAgICAgLy8gKDIgPDwgMTYpIHwgKDEgPDwgOCkgfCAweDM0CgogICAgLy8gR3JvdXAgMjogQ29tcG9zaXRpb24gb2YgdGhlIEJ1aWxkZXIKICAgIE5F" + + "V0MKICAgIDI0IFNUVSAgLy8gc3RvcmUgcmVmc19kZXNjcmlwdG9yIHwgYml0c19kZXNjcmlwdG9yIHwgZGF0YQogICAgMTYgU1RVICAvLyBzdG9yZSBkZXB0aF9kZXNj" + + "cmlwdG9yIGZvciBgY29kZWAKICAgIDE2IFNUVSAgLy8gc3RvcmUgZGVwdGhfZGVzY3JpcHRvciBmb3IgYGRhdGFgCiAgICAyNTYgU1RVIC8vIHN0b3JlIGBjb2RlYCBo" + + "YXNoCiAgICAyNTYgU1RVIC8vIHN0b3JlIGBkYXRhYCBoYXNoCgogICAgLy8gR3JvdXAgMzogU0hBMjU2IGhhc2ggb2YgdGhlIHJlc3VsdGluZyBCdWlsZGVyCiAgICBP" + + "TkUgSEFTSEVYVF9TSEEyNTYKfQoKLy8vIEdsb2JhbCBmdW5jdGlvbi4KLy8vCi8vLyBDb21wdXRlcyBzbWFydCBjb250cmFjdCdzIGBBZGRyZXNzYCBpbiB0aGUgYGNo" + + "YWluYCBJRCB1c2luZyB0aGUgY29udHJhY3QncyBgY29kZWAgYW5kIHRoZSBjb250cmFjdCdzIGluaXRpYWwgc3RhdGUgYGRhdGFgLiBVc2UgdGhlIGBpbml0T2ZgIGV4" + + "cHJlc3Npb24gdG8gb2J0YWluIHRoZSBpbml0aWFsIGBjb2RlYCBhbmQgaW5pdGlhbCBgZGF0YWAgb2YgYSBnaXZlbiBjb250cmFjdC4KLy8vCi8vLyBUaGlzIGZ1bmN0" + + "aW9uIGxldHMgeW91IHNwZWNpZnkgYXJiaXRyYXJ5IGBjaGFpbmAgSURzLCBpbmNsdWRpbmcgdGhlIGNvbW1vbiAtMSAobWFzdGVyY2hhaW4pIGFuZCAwIChiYXNlY2hh" + + "aW4pIG9uZXMuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKSB7Ci8vLyAgICAgbGV0IGluaXRQa2c6IFN0YXRlSW5pdCA9IGluaXRPZiBTb21lQ29udHJh" + + "Y3QoKTsKLy8vICAgICBsZXQgaGVyZUJlRHJhZ29uczogQWRkcmVzcyA9IGNvbnRyYWN0QWRkcmVzc0V4dCgwLCBpbml0UGtnLmNvZGUsIGluaXRQa2cuZGF0YSk7Ci8v" + + "LyB9Ci8vLyBgYGAKLy8vCi8vLyBTZWU6Ci8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWFkZHJlc3NlcyNjb250cmFjdGFkZHJlc3NleHQK" + + "Ly8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvYm9vay9leHByZXNzaW9ucyNpbml0b2YKLy8vCmlubGluZSBmdW4gY29udHJhY3RBZGRyZXNzRXh0KGNoYWlu" + + "OiBJbnQsIGNvZGU6IENlbGwsIGRhdGE6IENlbGwpOiBBZGRyZXNzIHsKICAgIGxldCBoYXNoID0gY29udHJhY3RIYXNoKGNvZGUsIGRhdGEpOwogICAgcmV0dXJuIG5l" + + "d0FkZHJlc3MoY2hhaW4sIGhhc2gpOwp9CgovLy8gR2xvYmFsIGZ1bmN0aW9uLiBBdmFpbGFibGUgc2luY2UgVGFjdCAxLjYuMC4KLy8vCi8vLyBDcmVhdGVzIGFuZCBy" + + "ZXR1cm5zIGEgYmFzZWNoYWluIGFkZHJlc3MgZGVyaXZlZCBmcm9tIGEgY29udHJhY3QncyBgU3RhdGVJbml0YCAoY29kZSBhbmQgZGF0YSkuCi8vLwovLy8gYGBgdGFj" + + "dAovLy8gZnVuIGV4YW1wbGUoKSB7Ci8vLyAgICAgbGV0IGNvZGU6IENlbGwgPSBsb2FkQ2VsbCgpOyAvLyBsb2FkIGNvbnRyYWN0IGNvZGUKLy8vICAgICBsZXQgZGF0" + + "YTogQ2VsbCA9IGxvYWRDZWxsKCk7IC8vIGxvYWQgY29udHJhY3QgZGF0YQovLy8gICAgIGxldCBzdGF0ZTogU3RhdGVJbml0ID0gU3RhdGVJbml0IHsgY29kZSwgZGF0" + + "YSB9OwovLy8gICAgIGxldCBhZGRyOiBCYXNlY2hhaW5BZGRyZXNzID0gY29udHJhY3RCYXNlY2hhaW5BZGRyZXNzKHN0YXRlKTsKLy8vIH0KLy8vIGBgYAovLy8KLy8v" + + "IFNlZTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtYWRkcmVzc2VzI2NvbnRyYWN0YmFzZWNoYWluYWRkcmVzcwovLy8KaW5saW5lIGZ1biBjb250" + + "cmFjdEJhc2VjaGFpbkFkZHJlc3MoczogU3RhdGVJbml0KTogQmFzZWNoYWluQWRkcmVzcyB7CiAgICBsZXQgaGFzaCA9IGNvbnRyYWN0SGFzaChzLmNvZGUsIHMuZGF0" + + "YSk7CiAgICByZXR1cm4gbmV3QmFzZWNoYWluQWRkcmVzcyhoYXNoKTsKfQoKLy8vIFN0cnVjdCBjb250YWluaW5nIHRoZSBpbml0aWFsIHN0YXRlLCBpLmUuIGluaXRp" + + "YWwgY29kZSBhbmQgaW5pdGlhbCBkYXRhIG9mIHRoZSBnaXZlbiBjb250cmFjdCB1cG9uIGl0cyBkZXBsb3ltZW50LgovLy8KLy8vIFNlZTogaHR0cHM6Ly9kb2NzLnRh" + + "Y3QtbGFuZy5vcmcvYm9vay9leHByZXNzaW9ucyNpbml0b2YKLy8vCi8vIHN0cnVjdCBTdGF0ZUluaXQgewovLyAgICAgLy8vIEluaXRpYWwgY29kZSBvZiB0aGUgY29u" + + "dHJhY3QgKGNvbXBpbGVkIGJpdGNvZGUpCi8vICAgICBjb2RlOiBDZWxsOwoKLy8gICAgIC8vLyBJbml0aWFsIGRhdGEgb2YgdGhlIGNvbnRyYWN0IChwYXJhbWV0ZXJz" + + "IG9mIGBpbml0KClgIGZ1bmN0aW9uIG9yIGNvbnRyYWN0IHBhcmFtZXRlcnMpCi8vICAgICBkYXRhOiBDZWxsOwovLyB9CgovLy8gR2xvYmFsIGZ1bmN0aW9uLiBBdmFp" + + "bGFibGUgc2luY2UgVGFjdCAxLjYuMS4KLy8vCi8vLyBDaGVja3MgaWYgdGhlIGdpdmVuIGBhZGRyZXNzYCBjb3JyZXNwb25kcyB0byB0aGUgY29udHJhY3QgYWRkcmVz" + + "cyBpbiB0aGUgd29ya2NoYWluIElEIDAgKGJhc2VjaGFpbikgZGVyaXZlZCBmcm9tIHRoZSBgU3RhdGVJbml0YCBgc2VsZmAuIFJldHVybnMgYHRydWVgIGlmIHRoZSBh" + + "ZGRyZXNzZXMgbWF0Y2ggYW5kIGBmYWxzZWAgb3RoZXJ3aXNlLgovLy8KLy8vIFRoaXMgZnVuY3Rpb24gd29ya3MgY29ycmVjdGx5IG9ubHkgZm9yIGJhc2VjaGFpbiBh" + + "ZGRyZXNzZXMuIEl0IG1heSBwcm9kdWNlIGZhbHNlIHBvc2l0aXZlcyBvciBuZWdhdGl2ZXMgaWYgdGhlIHNwZWNpZmllZCBgYWRkcmVzc2Agb3IgdGhlIGFkZHJlc3Mg" + + "ZGVyaXZlZCBmcm9tIHRoZSBgU3RhdGVJbml0ezp0YWN0fWAgYHNlbGZ7OnRhY3R9YCBoYXMgYSBub24temVybyB3b3JrY2hhaW4gSUQuCi8vLwovLy8gIyMjIyBVc2Fn" + + "ZQovLy8KLy8vIGBgYHRhY3QKLy8vIGNvbnRyYWN0IFBhcmVudCgpIHsKLy8vICAgICByZWNlaXZlKCkgewovLy8gICAgICAgICBsZXQgY2hpbGRDb250cmFjdCA9IGlu" + + "aXRPZiBDaGlsZChteUFkZHJlc3MoKSk7Ci8vLwovLy8gICAgICAgICAvLyBJZiB5b3UgYXJlIHdvcmtpbmcgd2l0aCBjb250cmFjdHMgb24gdGhlIGJhc2VjaGFpbiwg" + + "dGhpcwovLy8gICAgICAgICBsZXQgZXhwZW5zaXZlQ2hlY2sgPSBjb250cmFjdEFkZHJlc3MoY2hpbGRDb250cmFjdCkgPT0gc2VuZGVyKCk7Ci8vLwovLy8gICAgICAg" + + "ICAvLyBpcyBtb3JlIGV4cGVuc2l2ZSB0aGFuIGRvaW5nIHRoaXMKLy8vICAgICAgICAgbGV0IGNoZWFwZXJDaGVjayA9IGNoaWxkQ29udHJhY3QuaGFzU2FtZUJhc2Vj" + + "aGFpbkFkZHJlc3Moc2VuZGVyKCkpOwovLy8KLy8vICAgICAgICAgLy8gd2hpbGUgdGhlIHJlc3VsdHMgYXJlIHRoZSBzYW1lCi8vLyAgICAgICAgIGV4cGVuc2l2ZUNo" + + "ZWNrID09IGNoZWFwZXJDaGVjazsgLy8gdHJ1ZQovLy8gICAgIH0KLy8vIH0KLy8vCi8vLyBjb250cmFjdCBDaGlsZChwYXJlbnRBZGRyOiBBZGRyZXNzKSB7Ci8vLyAg" + + "ICAgcmVjZWl2ZSgpIHsKLy8vICAgICAgICAgLy8gRm9yd2FyZHMgc3VycGx1cyB0byB0aGUgcGFyZW50IGFkZHJlc3MgYnkgc2VuZGluZyBhIG1lc3NhZ2UKLy8vICAg" + + "ICAgICAgLy8gd2l0aCBhbiBlbXB0eSBib2R5IGFuZCBhbGwgcmVtYWluaW5nIGZ1bmRzIGZyb20gdGhlIHJlY2VpdmVkIG1lc3NhZ2UKLy8vICAgICAgICAgY2FzaGJh" + + "Y2soc2VsZi5wYXJlbnRBZGRyKTsKLy8vICAgICB9Ci8vLyB9Ci8vLyBgYGAKLy8vCi8vLyAjIyMjIEV4aXQgY29kZXMKLy8vCi8vLyAqIDk6IFtDZWxsIHVuZGVyZmxv" + + "d10g4oCUIFRocm93biB3aGVuIHRoZSBzcGVjaWZpZWQgYGFkZHJlc3NgIGNhbm5vdCBiZSBwYXJzZWQgYXMgYSBgU3RkQWRkcmVzc2AuCi8vLwovLy8gU2VlOgovLy8g" + + "KiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1hZGRyZXNzZXMjc3RhdGVpbml0aGFzc2FtZWJhc2VjaGFpbmFkZHJlc3MKLy8vICogaHR0cHM6Ly9k" + + "b2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtYWRkcmVzc2VzI2NvbnRyYWN0YWRkcmVzcwovLy8KLy8vIFtDZWxsIHVuZGVyZmxvd106IGh0dHBzOi8vZG9jcy50YWN0" + + "LWxhbmcub3JnL2Jvb2svZXhpdC1jb2RlcyM5Ci8vLwppbmxpbmUgZXh0ZW5kcyBmdW4gaGFzU2FtZUJhc2VjaGFpbkFkZHJlc3Moc2VsZjogU3RhdGVJbml0LCBhZGRy" + + "ZXNzOiBBZGRyZXNzKTogQm9vbCB7CiAgICBsZXQgYWRkcmVzc0hhc2ggPSBwYXJzZVN0ZEFkZHJlc3MoYWRkcmVzcy5hc1NsaWNlKCkpLmFkZHJlc3M7CiAgICBsZXQg" + + "YmFzZUFkZHJlc3MgPSBjb250cmFjdEJhc2VjaGFpbkFkZHJlc3Moc2VsZik7CiAgICByZXR1cm4gYmFzZUFkZHJlc3MuaGFzaCEhID09IGFkZHJlc3NIYXNoOwp9Cgov" + + "Ly8gR2xvYmFsIGZ1bmN0aW9uLgovLy8KLy8vIENvbXB1dGVzIHNtYXJ0IGNvbnRyYWN0J3MgYEFkZHJlc3NgIGluIHRoZSB3b3JrY2hhaW4gSUQgMCAoYmFzZWNoYWlu" + + "KSB1c2luZyB0aGUgYFN0YXRlSW5pdGAgYHNgIG9mIHRoZSBjb250cmFjdC4gQWxpYXMgdG8gYGNvbnRyYWN0QWRkcmVzc0V4dCgwLCBzLmNvZGUsIHMuZGF0YSlgLgov" + + "Ly8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAgIGxldCBzOiBTdGF0ZUluaXQgPSBpbml0T2YgU29tZUNvbnRyYWN0KCk7Ci8vLyAgICAgbGV0" + + "IGZvdW5kTWVTb21lOiBBZGRyZXNzID0gY29udHJhY3RBZGRyZXNzKHMpOwovLy8gICAgIGxldCBhbmRTb21lTW9yZTogQWRkcmVzcyA9IGNvbnRyYWN0QWRkcmVzc0V4" + + "dCgwLCBzLmNvZGUsIHMuZGF0YSk7Ci8vLwovLy8gICAgIGZvdW5kTWVTb21lID09IGFuZFNvbWVNb3JlOyAvLyB0cnVlCi8vLyB9Ci8vLyBgYGAKLy8vCi8vLyBTZWU6" + + "Ci8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWFkZHJlc3NlcyNjb250cmFjdGFkZHJlc3MKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFu" + + "Zy5vcmcvcmVmL2NvcmUtYWRkcmVzc2VzI2NvbnRyYWN0YWRkcmVzc2V4dAovLy8gKiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9ib29rL2V4cHJlc3Npb25zI2lu" + + "aXRvZgovLy8KaW5saW5lIGZ1biBjb250cmFjdEFkZHJlc3MoczogU3RhdGVJbml0KTogQWRkcmVzcyB7CiAgICByZXR1cm4gY29udHJhY3RBZGRyZXNzRXh0KDAsIHMu" + + "Y29kZSwgcy5kYXRhKTsKfQoKLy8vIEdsb2JhbCBmdW5jdGlvbi4KLy8vCi8vLyBSZXR1cm5zIHRoZSBhZGRyZXNzIG9mIHRoZSBjdXJyZW50IHNtYXJ0IGNvbnRyYWN0" + + "IGFzIGFuIGBBZGRyZXNzYC4KLy8vCi8vLyBgYGB0YWN0Ci8vLyBmdW4gZXhhbXBsZSgpIHsKLy8vICAgICBsZXQgbWVNeXNlbGZBbmRJOiBBZGRyZXNzID0gbXlBZGRy" + + "ZXNzKCk7Ci8vLyB9Ci8vLyBgYGAKLy8vCi8vLyBTZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWNvbnRleHRzdGF0ZSNteWFkZHJlc3MKLy8v" + + "CmFzbSBmdW4gbXlBZGRyZXNzKCk6IEFkZHJlc3MgeyBNWUFERFIgfQoKLy8vIEdsb2JhbCBmdW5jdGlvbi4KLy8vCi8vLyBSZXR1cm5zIHRoZSBuYW5vVG9uY29pbiBg" + + "SW50YCBiYWxhbmNlIG9mIHRoZSBzbWFydCBjb250cmFjdCBhcyBpdCB3YXMgYXQgdGhlIHN0YXJ0IG9mIHRoZSBjb21wdXRlIHBoYXNlIG9mIHRoZSBjdXJyZW50IHRy" + + "YW5zYWN0aW9uLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAgIGxldCBpTmVlZEFEb2xsYTogSW50ID0gbXlCYWxhbmNlKCk7Ci8vLyB9" + + "Ci8vLyBgYGAKLy8vCi8vLyBTZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWNvbnRleHRzdGF0ZSNteWJhbGFuY2UKLy8vCmFzbSBmdW4gbXlC" + + "YWxhbmNlKCk6IEludCB7IEJBTEFOQ0UgRklSU1QgfQoKLy8vIEdsb2JhbCBmdW5jdGlvbi4gQXZhaWxhYmxlIHNpbmNlIFRhY3QgMS41LjAuCi8vLwovLy8gUmV0dXJu" + + "cyB0aGUgbmFub1RvbmNvaW4gYEludGAgYW1vdW50IG9mIGdhcyBjb25zdW1lZCBieSBUVk0gaW4gdGhlIGN1cnJlbnQgdHJhbnNhY3Rpb24gc28gZmFyLiBUaGUgcmVz" + + "dWx0aW5nIHZhbHVlIGluY2x1ZGVzIHRoZSBjb3N0IG9mIGNhbGxpbmcgdGhpcyBmdW5jdGlvbi4KLy8vCi8vLyBgYGB0YWN0Ci8vLyBmdW4gZXhhbXBsZSgpIHsKLy8v" + + "ICAgICBsZXQgZ2FzOiBJbnQgPSBnYXNDb25zdW1lZCgpOwovLy8gfQovLy8gYGBgCi8vLwovLy8gU2VlOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29y" + + "ZS1jb250ZXh0c3RhdGUjZ2FzY29uc3VtZWQKLy8vCmFzbSBmdW4gZ2FzQ29uc3VtZWQoKTogSW50IHsgR0FTQ09OU1VNRUQgfQoKLy8vIEdsb2JhbCBmdW5jdGlvbi4g" + + "QXZhaWxhYmxlIHNpbmNlIFRhY3QgMS41LjAuCi8vLwovLy8gUmV0dXJucyB0aGUgbmFub1RvbmNvaW4gYEludGAgYW1vdW50IG9mIHRoZSBhY2N1bXVsYXRlZCBzdG9y" + + "YWdlIGZlZSBkZWJ0LiBTdG9yYWdlIGZlZXMgYXJlIGRlZHVjdGVkIGZyb20gdGhlIGluY29taW5nIG1lc3NhZ2UgdmFsdWUgYmVmb3JlIHRoZSBuZXcgY29udHJhY3Qg" + + "YmFsYW5jZSBpcyBjYWxjdWxhdGVkLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAgIGxldCBkZWJ0OiBJbnQgPSBteVN0b3JhZ2VEdWUo" + + "KTsKLy8vIH0KLy8vIGBgYAovLy8KLy8vIFNlZTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtY29udGV4dHN0YXRlI215c3RvcmFnZWR1ZQovLy8K" + + "YXNtIGZ1biBteVN0b3JhZ2VEdWUoKTogSW50IHsgRFVFUEFZTUVOVCB9CgovLy8gR2xvYmFsIGZ1bmN0aW9uLiBBdmFpbGFibGUgc2luY2UgVGFjdCAxLjUuMC4KLy8v" + + "Ci8vLyBDYWxjdWxhdGVzIGFuZCByZXR1cm5zIHRoZSBzdG9yYWdlIGZlZSBpbiBuYW5vVG9uY29pbnMgYEludGAgZm9yIHN0b3JpbmcgYSBjb250cmFjdCB3aXRoIGEg" + + "Z2l2ZW4gbnVtYmVyIG9mIGBjZWxsc2AgYW5kIGBiaXRzYCBmb3IgYSBudW1iZXIgb2YgYHNlY29uZHNgLiBVc2VzIHRoZSBwcmljZXMgb2YgdGhlIG1hc3RlcmNoYWlu" + + "IGlmIGBpc01hc3RlcmNoYWluYCBpcyBgdHJ1ZWAsIG90aGVyd2lzZSB0aGUgcHJpY2VzIG9mIHRoZSBiYXNlY2hhaW4uIFRoZSBjdXJyZW50IHByaWNlcyBhcmUgb2J0" + + "YWluZWQgZnJvbSB0aGUgY29uZmlnIHBhcmFtIDE4IG9mIFRPTiBCbG9ja2NoYWluLgovLy8KLy8vIE5vdGUsIHRoYXQgc3BlY2lmeWluZyB2YWx1ZXMgb2YgYGNlbGxz" + + "YCBhbmQgYGJpdHNgIGhpZ2hlciB0aGFuIHRoZWlyIG1heGltdW0gdmFsdWVzIGxpc3RlZCBpbiBhY2NvdW50IHN0YXRlIGxpbWl0cyAoYG1heF9hY2Nfc3RhdGVfY2Vs" + + "bHNgIGFuZCBgbWF4X2FjY19zdGF0ZV9iaXRzYCkgd2lsbCBoYXZlIHRoZSBzYW1lIHJlc3VsdCBhcyB3aXRoIHNwZWNpZnlpbmcgdGhlIGV4YWN0IGxpbWl0cy4gSW4g" + + "YWRkaXRpb24sIG1ha2Ugc3VyZSB5b3UgdGFrZSBpbnRvIGFjY291bnQgdGhlIGRlZHVwbGljYXRpb24gb2YgY2VsbHMgd2l0aCB0aGUgc2FtZSBoYXNoLgovLy8KLy8v" + + "IGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAgIGxldCBmZWU6IEludCA9IGdldFN0b3JhZ2VGZWUoMV8wMDAsIDFfMDAwLCAxXzAwMCwgZmFsc2UpOwov" + + "Ly8gfQovLy8gYGBgCi8vLwovLy8gIyMjIyBFeGl0IGNvZGVzCi8vLwovLy8gKiA1OiBbSW50ZWdlciBvdXQgb2YgZXhwZWN0ZWQgcmFuZ2VdIOKAlCBUaHJvd24gd2hl" + + "biBhdHRlbXB0aW5nIHRvIHNwZWNpZnkgbmVnYXRpdmUgbnVtYmVyIG9mIGBjZWxsc2AsIGBiaXRzYCBvciBgc2Vjb25kc2AuCi8vLwovLy8gU2VlOiBodHRwczovL2Rv" + + "Y3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1nYXMjZ2V0c3RvcmFnZWZlZQovLy8KLy8vIFtJbnRlZ2VyIG91dCBvZiBleHBlY3RlZCByYW5nZV06IGh0dHBzOi8vZG9j" + + "cy50YWN0LWxhbmcub3JnL2Jvb2svZXhpdC1jb2RlcyM1Ci8vLwphc20gZnVuIGdldFN0b3JhZ2VGZWUoY2VsbHM6IEludCwgYml0czogSW50LCBzZWNvbmRzOiBJbnQs" + + "IGlzTWFzdGVyY2hhaW46IEJvb2wpOiBJbnQgeyBHRVRTVE9SQUdFRkVFIH0KCi8vLyBHbG9iYWwgZnVuY3Rpb24uIEF2YWlsYWJsZSBzaW5jZSBUYWN0IDEuNS4wLgov" + + "Ly8KLy8vIENhbGN1bGF0ZXMgYW5kIHJldHVybnMgdGhlIGNvbXB1dGUgZmVlIGluIG5hbm9Ub25jb2lucyBgSW50YCBmb3IgYSB0cmFuc2FjdGlvbiB0aGF0IGNvbnN1" + + "bWVkIGBnYXNVc2VkYCBhbW91bnQgb2YgZ2FzLiBVc2VzIHRoZSBwcmljZXMgb2YgdGhlIG1hc3RlcmNoYWluIGlmIGBpc01hc3RlcmNoYWluYCBpcyBgdHJ1ZWAsIG90" + + "aGVyd2lzZSB0aGUgcHJpY2VzIG9mIHRoZSBiYXNlY2hhaW4uIFRoZSBjdXJyZW50IHByaWNlcyBhcmUgb2J0YWluZWQgZnJvbSB0aGUgY29uZmlnIHBhcmFtIDIwIGZv" + + "ciB0aGUgbWFzdGVyY2hhaW4gYW5kIGNvbmZpZyBwYXJhbSAyMSBmb3IgdGhlIGJhc2VjaGFpbiBvZiBUT04gQmxvY2tjaGFpbi4KLy8vCi8vLyBXaGVuIHRoZSBgZ2Fz" + + "VXNlZGAgaXMgbGVzcyB0aGFuIGEgY2VydGFpbiB0aHJlc2hvbGQgY2FsbGVkIGBmbGF0X2dhc19saW1pdGAsIHRoZXJlJ3MgYSBtaW5pbXVtIHByaWNlIHRvIHBheSBi" + + "YXNlZCBvbiB0aGUgdmFsdWUgb2YgYGZsYXRfZ2FzX3ByaWNlYC4gVGhlIGxlc3MgZ2FzIGlzIHVzZWQgYmVsb3cgdGhpcyB0aHJlc2hvbGQsIHRoZSBoaWdoZXIgdGhl" + + "IG1pbmltdW0gcHJpY2Ugd2lsbCBiZS4gU2VlIHRoZSBleGFtcGxlIGZvciBgZ2V0U2ltcGxlQ29tcHV0ZUZlZSgpYCB0byBkZXJpdmUgdGhhdCB0aHJlc2hvbGQuCi8v" + + "LwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKSB7Ci8vLyAgICAgbGV0IGZlZTogSW50ID0gZ2V0Q29tcHV0ZUZlZSgxXzAwMCwgZmFsc2UpOwovLy8gfQovLy8g" + + "YGBgCi8vLwovLy8gIyMjIyBFeGl0IGNvZGVzCi8vLwovLy8gKiA1OiBbSW50ZWdlciBvdXQgb2YgZXhwZWN0ZWQgcmFuZ2VdIOKAlCBUaHJvd24gd2hlbiBhdHRlbXB0" + + "aW5nIHRvIHNwZWNpZnkgbmVnYXRpdmUgdmFsdWUgb2YgYGdhc1VzZWRgLgovLy8KLy8vIFNlZTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtZ2Fz" + + "I2dldGNvbXB1dGVmZWUKLy8vCi8vLyBbSW50ZWdlciBvdXQgb2YgZXhwZWN0ZWQgcmFuZ2VdOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9ib29rL2V4aXQtY29k" + + "ZXMjNQovLy8KYXNtIGZ1biBnZXRDb21wdXRlRmVlKGdhc1VzZWQ6IEludCwgaXNNYXN0ZXJjaGFpbjogQm9vbCk6IEludCB7IEdFVEdBU0ZFRSB9CgovLy8gR2xvYmFs" + + "IGZ1bmN0aW9uLiBBdmFpbGFibGUgc2luY2UgVGFjdCAxLjUuMC4KLy8vCi8vLyBTaW1pbGFyIHRvIGBnZXRDb21wdXRlRmVlKClgLCBidXQgd2l0aG91dCB0aGUgYGZs" + + "YXRfZ2FzX3ByaWNlYCwgaS5lLiB3aXRob3V0IGEgbWluaW11bSBwcmljZSB0byBwYXkgaWYgdGhlIGBnYXNVc2VkYCBpcyBsZXNzIHRoYW4gYSBjZXJ0YWluIHRocmVz" + + "aG9sZCBjYWxsZWQgYGZsYXRfZ2FzX2xpbWl0YC4gQ2FsY3VsYXRlcyBhbmQgcmV0dXJucyBvbmx5IHRoZSBgZ2FzVXNlZGAgdGltZXMgdGhlIGN1cnJlbnQgZ2FzIHBy" + + "aWNlLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAgIGxldCBmZWUgPSBnZXRDb21wdXRlRmVlKDAsIGZhbHNlKTsKLy8vICAgICBsZXQg" + + "ZmVlTm9GbGF0ID0gZ2V0U2ltcGxlQ29tcHV0ZUZlZSgwLCBmYWxzZSk7Ci8vLyAgICAgbGV0IG1heEZsYXRQcmljZSA9IGZlZSAtIGZlZU5vRmxhdDsKLy8vIH0KLy8v" + + "IGBgYAovLy8KLy8vICMjIyMgRXhpdCBjb2RlcwovLy8KLy8vICogNTogW0ludGVnZXIgb3V0IG9mIGV4cGVjdGVkIHJhbmdlXSDigJQgVGhyb3duIHdoZW4gYXR0ZW1w" + + "dGluZyB0byBzcGVjaWZ5IG5lZ2F0aXZlIG51bWJlciBvZiBgY2VsbHNgLCBgYml0c2Agb3IgYHNlY29uZHNgLgovLy8KLy8vIFNlZToKLy8vICogaHR0cHM6Ly9kb2Nz" + + "LnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtZ2FzI2dldHNpbXBsZWNvbXB1dGVmZWUKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtZ2FzI2dl" + + "dGNvbXB1dGVmZWUKLy8vCi8vLyBbSW50ZWdlciBvdXQgb2YgZXhwZWN0ZWQgcmFuZ2VdOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9ib29rL2V4aXQtY29kZXMj" + + "NQovLy8KYXNtIGZ1biBnZXRTaW1wbGVDb21wdXRlRmVlKGdhc1VzZWQ6IEludCwgaXNNYXN0ZXJjaGFpbjogQm9vbCk6IEludCB7IEdFVEdBU0ZFRVNJTVBMRSB9Cgov" + + "Ly8gR2xvYmFsIGZ1bmN0aW9uLiBBdmFpbGFibGUgc2luY2UgVGFjdCAxLjUuMC4KLy8vCi8vLyBDYWxjdWxhdGVzIGFuZCByZXR1cm5zIHRoZSBmb3J3YXJkIGZlZSBp" + + "biBuYW5vVG9uY29pbnMgYEludGAgZm9yIGFuIG91dGdvaW5nIG1lc3NhZ2UgY29uc2lzdGluZyBvZiBhIGdpdmVuIG51bWJlciBvZiBgY2VsbHNgIGFuZCBgYml0c2Au" + + "IFVzZXMgdGhlIHByaWNlcyBvZiB0aGUgbWFzdGVyY2hhaW4gaWYgYGlzTWFzdGVyY2hhaW5gIGlzIGB0cnVlYCwgb3RoZXJ3aXNlIHRoZSBwcmljZXMgb2YgdGhlIGJh" + + "c2VjaGFpbi4gVGhlIGN1cnJlbnQgcHJpY2VzIGFyZSBvYnRhaW5lZCBmcm9tIHRoZSBjb25maWcgcGFyYW0gMjQgZm9yIHRoZSBtYXN0ZXJjaGFpbiBhbmQgY29uZmln" + + "IHBhcmFtIDI1IGZvciB0aGUgYmFzZWNoYWluIG9mIFRPTiBCbG9ja2NoYWluLgovLy8KLy8vIElmIGJvdGggdGhlIHNvdXJjZSBhbmQgdGhlIGRlc3RpbmF0aW9uIGFk" + + "ZHJlc3NlcyBhcmUgaW4gdGhlIGJhc2VjaGFpbiwgdGhlbiBzcGVjaWZ5IGBpc01hc3RlcmNoYWluYCBhcyBgZmFsc2VgLiBPdGhlcndpc2UsIHNwZWNpZnkgYHRydWVg" + + "LgovLy8KLy8vIE5vdGUsIHRoYXQgc3BlY2lmeWluZyB2YWx1ZXMgb2YgYGNlbGxzYCBhbmQgYGJpdHNgIGhpZ2hlciB0aGFuIHRoZWlyIG1heGltdW0gdmFsdWVzIGxp" + + "c3RlZCBpbiBhY2NvdW50IHN0YXRlIGxpbWl0cyAoYG1heF9tc2dfY2VsbHNgIGFuZCBgbWF4X21zZ19iaXRzYCkgd2lsbCBoYXZlIHRoZSBzYW1lIHJlc3VsdCBhcyB3" + + "aXRoIHNwZWNpZnlpbmcgdGhlIGV4YWN0IGxpbWl0cy4KLy8vCi8vLyBIb3dldmVyLCByZWdhcmRsZXNzIG9mIHRoZSB2YWx1ZXMgb2YgYGNlbGxzYCBhbmQgYGJpdHNg" + + "LCB0aGlzIGZ1bmN0aW9uIGFsd2F5cyBhZGRzIHRoZSBtaW5pbXVtIHByaWNlIGJhc2VkIG9uIHRoZSB2YWx1ZSBvZiBgbHVtcF9wcmljZWAuIFNlZSB0aGUgZXhhbXBs" + + "ZSBmb3IgYGdldFNpbXBsZUZvcndhcmRGZWUoKWAgdG8gZGVyaXZlIGl0LiBJbiBhZGRpdGlvbiwgbWFrZSBzdXJlIHlvdSB0YWtlIGludG8gYWNjb3VudCB0aGUgZGVk" + + "dXBsaWNhdGlvbiBvZiBjZWxscyB3aXRoIHRoZSBzYW1lIGhhc2gsIHNpbmNlIGZvciBleGFtcGxlIHRoZSByb290IGNlbGwgYW5kIGl0cyBkYXRhIGJpdHMgZG9uJ3Qg" + + "Y291bnQgdG93YXJkcyB0aGUgZm9yd2FyZCBmZWUgYW5kIGFyZSBjb3ZlcmVkIGJ5IHRoZSBgbHVtcF9wcmljZWAuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1w" + + "bGUoKSB7Ci8vLyAgICAgbGV0IGZlZTogSW50ID0gZ2V0Rm9yd2FyZEZlZSgxXzAwMCwgMV8wMDAsIGZhbHNlKTsKLy8vIH0KLy8vIGBgYAovLy8KLy8vICMjIyMgRXhp" + + "dCBjb2RlcwovLy8KLy8vICogNTogW0ludGVnZXIgb3V0IG9mIGV4cGVjdGVkIHJhbmdlXSDigJQgVGhyb3duIHdoZW4gYXR0ZW1wdGluZyB0byBzcGVjaWZ5IG5lZ2F0" + + "aXZlIG51bWJlciBvZiBgY2VsbHNgIG9yIGBiaXRzYC4KLy8vCi8vLyBTZWU6Ci8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWdhcyNnZXRm" + + "b3J3YXJkZmVlCi8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWdhcyNnZXRzaW1wbGVmb3J3YXJkZmVlCi8vLyAqIGh0dHBzOi8vZG9jcy50" + + "YWN0LWxhbmcub3JnL3JlZi9jb3JlLWdhcyNnZXRvcmlnaW5hbGZ3ZGZlZQovLy8KLy8vIFtJbnRlZ2VyIG91dCBvZiBleHBlY3RlZCByYW5nZV06IGh0dHBzOi8vZG9j" + + "cy50YWN0LWxhbmcub3JnL2Jvb2svZXhpdC1jb2RlcyM1Ci8vLwphc20gZnVuIGdldEZvcndhcmRGZWUoY2VsbHM6IEludCwgYml0czogSW50LCBpc01hc3RlcmNoYWlu" + + "OiBCb29sKTogSW50IHsgR0VURk9SV0FSREZFRSB9CgovLy8gR2xvYmFsIGZ1bmN0aW9uLiBBdmFpbGFibGUgc2luY2UgVGFjdCAxLjUuMC4KLy8vCi8vLyBTaW1pbGFy" + + "IHRvIGBnZXRGb3J3YXJkRmVlKClgLCBidXQgd2l0aG91dCB0aGUgYGx1bXBfcHJpY2VgLCBpLmUuIHdpdGhvdXQgdGhlIG1pbmltdW0gcHJpY2UgdG8gcGF5IHJlZ2Fy" + + "ZGxlc3Mgb2YgdGhlIGFtb3VudCBvZiBgY2VsbHNgIG9yIGBiaXRzYC4gQ2FsY3VsYXRlcyBhbmQgcmV0dXJucyBvbmx5IHRoZSBgY2VsbHNgIHRpbWVzIHRoZSBjdXJy" + + "ZW50IGNlbGwgcHJpY2UgcGx1cyBgYml0c2AgdGltZXMgdGhlIGN1cnJlbnQgYml0IHByaWNlLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8g" + + "ICAgIGxldCBmZWUgPSBnZXRGb3J3YXJkRmVlKDFfMDAwLCAxXzAwMCwgZmFsc2UpOwovLy8gICAgIGxldCBmZWVOb0x1bXAgPSBnZXRTaW1wbGVGb3J3YXJkRmVlKDFf" + + "MDAwLCAxXzAwMCwgZmFsc2UpOwovLy8gICAgIGxldCBsdW1wUHJpY2UgPSBmZWUgLSBmZWVOb0x1bXA7Ci8vLyB9Ci8vLyBgYGAKLy8vCi8vLyAjIyMjIEV4aXQgY29k" + + "ZXMKLy8vCi8vLyAqIDU6IFtJbnRlZ2VyIG91dCBvZiBleHBlY3RlZCByYW5nZV0g4oCUIFRocm93biB3aGVuIGF0dGVtcHRpbmcgdG8gc3BlY2lmeSBuZWdhdGl2ZSBu" + + "dW1iZXIgb2YgYGNlbGxzYCBvciBgYml0c2AuCi8vLwovLy8gU2VlOgovLy8gKiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1nYXMjZ2V0c2ltcGxl" + + "Zm9yd2FyZGZlZQovLy8gKiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1nYXMjZ2V0Zm9yd2FyZGZlZQovLy8KLy8vIFtJbnRlZ2VyIG91dCBvZiBl" + + "eHBlY3RlZCByYW5nZV06IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL2Jvb2svZXhpdC1jb2RlcyM1Ci8vLwphc20gZnVuIGdldFNpbXBsZUZvcndhcmRGZWUoY2Vs" + + "bHM6IEludCwgYml0czogSW50LCBpc01hc3RlcmNoYWluOiBCb29sKTogSW50IHsgR0VURk9SV0FSREZFRVNJTVBMRSB9CgovLy8gR2xvYmFsIGZ1bmN0aW9uLiBBdmFp" + + "bGFibGUgc2luY2UgVGFjdCAxLjUuMC4KLy8vCi8vLyBDYWxjdWxhdGVzIGFuZCByZXR1cm5zIHRoZSBzby1jYWxsZWQgX29yaWdpbmFsXyBmb3J3YXJkIGZlZSBpbiBu" + + "YW5vVG9uY29pbiBgSW50YCBmb3IgYSBtZXNzYWdlIGJhc2VkIG9uIHRoZSBnaXZlbiBgZndkRmVlYCBvZiB0aGlzIG1lc3NhZ2UsIHdoaWNoIGNhbiBiZSBvYnRhaW5l" + + "ZCBieSBjYWxsaW5nIGBnZXRGb3J3YXJkRmVlKClgLiBJZiBib3RoIHRoZSBzb3VyY2UgYW5kIHRoZSBkZXN0aW5hdGlvbiBhZGRyZXNzZXMgYXJlIGluIHRoZSBiYXNl" + + "Y2hhaW4sIHNwZWNpZnkgYGlzTWFzdGVyY2hhaW5gIGFzIGBmYWxzZWAuIE90aGVyd2lzZSwgc3BlY2lmeSBgdHJ1ZWAuCi8vLwovLy8gVGhlIHJlc3VsdCBpcyBjb21w" + + "dXRlZCB1c2luZyB0aGUgYGZpcnN0X2ZyYWNgIHZhbHVlLCB3aGljaCBpcyBvYnRhaW5lZCBmcm9tIGNvbmZpZyBwYXJhbSAyNCBmb3IgdGhlIG1hc3RlcmNoYWluIGFu" + + "ZCBjb25maWcgcGFyYW0gMjUgZm9yIHRoZSBiYXNlY2hhaW4gb2YgVE9OIEJsb2NrY2hhaW4uIER1ZSB0byB0aGUgY3VycmVudCB2YWx1ZSBvZiBgZmlyc3RfZnJhY2Ag" + + "Zm9yIGFsbCB3b3JrY2hhaW5zLCB0aGlzIGZ1bmN0aW9uIHBlcmZvcm1zIGEgY2hlYXBlciBlcXVpdmFsZW50IGNhbGN1bGF0aW9uIG9mIGBmd2RGZWUgKiAzIC8gMmAu" + + "IFRoaXMgcmF0aW8gbWlnaHQgY2hhbmdlLCBzbyBpdCBpcyBiZXR0ZXIgbm90IHRvIGhhcmRjb2RlIGl0IGFuZCB1c2UgdGhpcyBmdW5jdGlvbiBpbnN0ZWFkLgovLy8K" + + "Ly8vIFRoaXMgZnVuY3Rpb24gY2FuIGJlIHVzZWZ1bCB3aGVuIHRoZSBvdXRnb2luZyBtZXNzYWdlIGRlcGVuZHMgaGVhdmlseSBvbiB0aGUgc3RydWN0dXJlIG9mIHRo" + + "ZSBpbmNvbWluZyBtZXNzYWdlLCBzbyB5b3UgY2FuIHRyeSB0byBhcHByb3hpbWF0ZSB0aGUgZm9yd2FyZCBmZWUgZm9yIHlvdXIgb3V0Z29pbmcgbWVzc2FnZSBiYXNl" + + "ZCBvbiB0aGUgZmVlIHRoZSBzZW5kZXIgcGFpZC4gQ2FsY3VsYXRpbmcgdGhlIGV4YWN0IGZlZSB3aXRoIG5hbm9Ub25jb2luLWxldmVsIHByZWNpc2lvbiBjYW4gYmUg" + + "dmVyeSBleHBlbnNpdmUsIHNvIHRoZSBhcHByb3hpbWF0aW9uIGdpdmVuIGJ5IHRoaXMgZnVuY3Rpb24gaXMgb2Z0ZW4gZ29vZCBlbm91Z2guCi8vLwovLy8gYGBgdGFj" + + "dAovLy8gZnVuIGV4YW1wbGUoKSB7Ci8vLyAgICAgLy8gQ29udGV4dC5yZWFkRm9yd2FyZEZlZSgpIGFwcGxpZXMgZ2V0T3JpZ2luYWxGd2RGZWUoKSBhdCB0aGUgZW5k" + + "Ci8vLyAgICAgbGV0IG9yaWdGd2RGZWU6IEludCA9IGNvbnRleHQoKS5yZWFkRm9yd2FyZEZlZSgpOwovLy8KLy8vICAgICAvLyBUaGVyZWZvcmUsIGNhbGxpbmcgZ2V0" + + "T3JpZ2luYWxGd2RGZWUoKSBvbiB0aGF0IHZhbHVlIGlzIHJlZHVuZGFudAovLy8gICAgIGxldCBvcmlnRndkRmVlMjogSW50ID0gZ2V0T3JpZ2luYWxGd2RGZWUob3Jp" + + "Z0Z3ZEZlZSwgZmFsc2UpOwovLy8KLy8vICAgICAvLyDijIgoMiAqIG9yaWdGd2RGZWUyKSAvIG9yaWdGd2RGZWXijIkgaXMgZXF1YWwgdG8gMwovLy8gICAgIG11bGRp" + + "dmMoMiwgb3JpZ0Z3ZEZlZTIsIG9yaWdGd2RGZWUpID09IDM7IC8vIHRydWUsIGJ1dCB0aGlzIHJlbGF0aW9uCi8vLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAg" + + "ICAgICAgICAgICAgICAgICAgLy8gY2FuIGNoYW5nZSBpbiB0aGUgZnV0dXJlCi8vLyB9Ci8vLyBgYGAKLy8vCi8vLyAjIyMjIEV4aXQgY29kZXMKLy8vCi8vLyAqIDU6" + + "IFtJbnRlZ2VyIG91dCBvZiBleHBlY3RlZCByYW5nZV0g4oCUIFRocm93biB3aGVuIGF0dGVtcHRpbmcgdG8gc3BlY2lmeSBhIG5lZ2F0aXZlIHZhbHVlIG9mIGBmd2RG" + + "ZWVgLgovLy8KLy8vIFNlZToKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtZ2FzI2dldG9yaWdpbmFsZndkZmVlCi8vLyAqIGh0dHBzOi8v" + + "ZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWdhcyNnZXRmb3J3YXJkZmVlCi8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWNvbnRleHRz" + + "dGF0ZSNjb250ZXh0cmVhZGZvcndhcmRmZWUKLy8vCi8vLyBbSW50ZWdlciBvdXQgb2YgZXhwZWN0ZWQgcmFuZ2VdOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9i" + + "b29rL2V4aXQtY29kZXMjNQovLy8KYXNtIGZ1biBnZXRPcmlnaW5hbEZ3ZEZlZShmd2RGZWU6IEludCwgaXNNYXN0ZXJjaGFpbjogQm9vbCk6IEludCB7IEdFVE9SSUdJ" + + "TkFMRldERkVFIH0KCi8vLyBHbG9iYWwgZnVuY3Rpb24uIEF2YWlsYWJsZSBzaW5jZSBUYWN0IDEuNi4wLgovLy8KLy8vIFNldHMgdGhlIGBnYXNfbGltaXRgIHRvIHRo" + + "ZSBgSW50YCBgbGltaXRgIGFuZCByZXNldHMgdGhlIGBnYXNfY3JlZGl0YCB0byAwLiBOb3RlIHRoYXQgc3BlY2lmeWluZyB0aGUgYGxpbWl0YCBoaWdoZXIgdGhhbiB0" + + "aGUgbWF4aW11bSBhbGxvd2VkIHZhbHVlIG9mIDJeNjMgLSAxIHdpbGwgaGF2ZSB0aGUgc2FtZSByZXN1bHQgYXMgd2l0aCBzcGVjaWZ5aW5nIHRoYXQgZXhhY3QgbWF4" + + "aW11bSBvciBjYWxsaW5nIGBhY2NlcHRNZXNzYWdlKClgLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAgIHNldEdhc0xpbWl0KDQyMDAw" + + "KTsKLy8vIH0KLy8vIGBgYAovLy8KLy8vICMjIyMgRXhpdCBjb2RlcwovLy8KLy8vICogLTE0OiBbT3V0IG9mIGdhcyBlcnJvcl0g4oCUIFRocm93biB3aGVuIGF0dGVt" + + "cHRpbmcgdG8gc3BlY2lmeSBhIG5lZ2F0aXZlIG9yIGluc3VmZmljaWVudCB2YWx1ZSBvZiBgbGltaXRgLgovLy8KLy8vIFNlZTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFu" + + "Zy5vcmcvcmVmL2NvcmUtZ2FzI3NldGdhc2xpbWl0Ci8vLwovLy8gW091dCBvZiBnYXMgZXJyb3JdOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9ib29rL2V4aXQt" + + "Y29kZXMjLTE0Ci8vLwphc20gZnVuIHNldEdhc0xpbWl0KGxpbWl0OiBJbnQpIHsgU0VUR0FTTElNSVQgfQoKLy8vIEdsb2JhbCBmdW5jdGlvbi4gQXZhaWxhYmxlIHNp" + + "bmNlIFRhY3QgMS42LjAuCi8vLwovLy8gR2VuZXJhdGVzIGFuZCByZXR1cm5zIGFuIHVuc2lnbmVkIDI1Ni1iaXQgYEludGAgc2VlZCBmb3IgdGhlIHJhbmRvbSBudW1i" + + "ZXIgZ2VuZXJhdG9yLiBUaGUgcmVzdWx0aW5nIHNlZWQgaXMgY29tbW9ubHkgdXNlZCB3aXRoIHRoZSBgc2V0U2VlZCgpYCBhbmQgYG5hdGl2ZVJhbmRvbWl6ZSgpYCBm" + + "dW5jdGlvbnMuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKSB7Ci8vLyAgICAgbGV0IHNlZWQ6IEludCA9IGdldFNlZWQoKTsKLy8vICAgICBzZXRTZWVk" + + "KHNlZWQpOyAvLyBmcm9tIG5vdyBvbiB0aGUgcmVzdWx0cyBvZiBwc2V1ZG9yYW5kb20gbnVtYmVyIGdlbmVyYXRvcgovLy8gICAgICAgICAgICAgICAgICAgIC8vIGFy" + + "ZSBjb21wbGV0ZWx5IGRldGVybWluZWQgYnkgdGhlIHNlZWQsIHdoaWNoIGNhbiBiZSBoYW5keSBpbiB0ZXN0cywKLy8vICAgICAgICAgICAgICAgICAgICAvLyBidXQg" + + "bXVzdCBub3QgYmUgdXNlZCBpbiBwcm9kdWN0aW9uIGNvZGUhCi8vLyB9Ci8vLyBgYGAKLy8vCi8vLyBTZWU6Ci8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3Jn" + + "L3JlZi9jb3JlLXJhbmRvbSNnZXRzZWVkCi8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLXJhbmRvbSNzZXRzZWVkCi8vLyAqIGh0dHBzOi8v" + + "ZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLXJhbmRvbSNuYXRpdmVyYW5kb21pemUKLy8vCmFzbSBmdW4gZ2V0U2VlZCgpOiBJbnQgeyBSQU5EU0VFRCB9CgovLy8g" + + "R2xvYmFsIGZ1bmN0aW9uLiBBdmFpbGFibGUgc2luY2UgVGFjdCAxLjYuMC4KLy8vCi8vLyBTZXRzIHRoZSBzZWVkIG9mIHRoZSByYW5kb20gbnVtYmVyIGdlbmVyYXRv" + + "ciB0byB0aGUgdW5zaWduZWQgMjU2LWJpdCBgSW50YCBgc2VlZGAgd2hpY2ggY2FuIGJlIG9idGFpbmVkIHdpdGggdGhlIGBnZXRTZWVkKClgIGZ1bmN0aW9uLgovLy8K" + + "Ly8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAgIGxldCBzZWVkOiBJbnQgPSBnZXRTZWVkKCk7Ci8vLyAgICAgc2V0U2VlZChzZWVkKTsgLy8gZnJv" + + "bSBub3cgb24gdGhlIHJlc3VsdHMgb2YgcHNldWRvcmFuZG9tIG51bWJlciBnZW5lcmF0b3IKLy8vICAgICAgICAgICAgICAgICAgICAvLyBhcmUgY29tcGxldGVseSBk" + + "ZXRlcm1pbmVkIGJ5IHRoZSBzZWVkLCB3aGljaCBjYW4gYmUgaGFuZHkgaW4gdGVzdHMsCi8vLyAgICAgICAgICAgICAgICAgICAgLy8gYnV0IG11c3Qgbm90IGJlIHVz" + + "ZWQgaW4gcHJvZHVjdGlvbiBjb2RlIQovLy8gfQovLy8gYGBgCi8vLwovLy8gIyMjIyBFeGl0IGNvZGVzCi8vLwovLy8gKiA1OiBbSW50ZWdlciBvdXQgb2YgZXhwZWN0" + + "ZWQgcmFuZ2VdIOKAlCBUaHJvd24gd2hlbiBhdHRlbXB0aW5nIHRvIHNwZWNpZnkgYSBuZWdhdGl2ZSB2YWx1ZSBvZiBgc2VlZGAuCi8vLwovLy8gU2VlOgovLy8gKiBo" + + "dHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1yYW5kb20jc2V0c2VlZAovLy8gKiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1yYW5k" + + "b20jZ2V0c2VlZAovLy8KLy8vIFtJbnRlZ2VyIG91dCBvZiBleHBlY3RlZCByYW5nZV06IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL2Jvb2svZXhpdC1jb2RlcyM1" + + "Ci8vLwphc20gZnVuIHNldFNlZWQoc2VlZDogSW50KSB7IFNFVFJBTkQgfQoKLy8vIEdsb2JhbCBmdW5jdGlvbi4gQXZhaWxhYmxlIHNpbmNlIFRhY3QgMS42LjAuCi8v" + + "LwovLy8gUmV0dXJucyB0aGUgc21hcnQgY29udHJhY3QgY29kZSBgQ2VsbGAgb2J0YWluZWQgZnJvbSB0aGUgYGM3YCByZWdpc3Rlci4KLy8vCi8vLyBgYGB0YWN0Ci8v" + + "LyBmdW4gZXhhbXBsZSgpIHsKLy8vICAgICBsZXQgY29kZTogQ2VsbCA9IG15Q29kZSgpOwovLy8gfQovLy8gYGBgCi8vLwovLy8gU2VlOiBodHRwczovL2RvY3MudGFj" + + "dC1sYW5nLm9yZy9yZWYvY29yZS1jb250ZXh0c3RhdGUjbXljb2RlCi8vLwphc20gZnVuIG15Q29kZSgpOiBDZWxsIHsgTVlDT0RFIH0K"; files["std/internal/crypto.tact"] = "Ly8vIEV4dGVuc2lvbiBmdW5jdGlvbiBmb3IgdGhlIGBDZWxsYCB0eXBlLgovLy8KLy8vIENhbGN1bGF0ZXMgYW5kIHJldHVybnMgYW4gYEludGAgdmFsdWUgb2YgdGhl" + "IFtTSEEtMjU2XSBoYXNoIG9mIHRoZQovLy8gW3N0YW5kYXJkIGBDZWxsYCByZXByZXNlbnRhdGlvbl1bc3RkLXJlcHJlc2VudGF0aW9uXSBvZiB0aGUgZ2l2ZW4gYENl" + @@ -1425,181 +1426,181 @@ files["std/internal/exit-codes.tact"] = "c2VjaGFpbiAoY2hhaW4gSUQgMCkuCi8vLwovLy8gU2VlOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9ib29rL2V4aXQtY29kZXMjMTM4Ci8vLwpjb25zdCBUYWN0" + "RXhpdENvZGVOb3RCYXNlY2hhaW5BZGRyZXNzOiBJbnQgPSAxMzg7Cg=="; files["std/internal/math.tact"] = - "Ly8gUHJlcGFyZSByYW5kb20KCi8vLyBHbG9iYWwgZnVuY3Rpb24uCi8vLwovLy8gUmFuZG9taXplcyB0aGUgcHNldWRvcmFuZG9tIG51bWJlciBnZW5lcmF0b3Igd2l0" + - "aCB0aGUgc3BlY2lmaWVkIHVuc2lnbmVkIDI1Ni1iaXQgYEludGAgYHhgIGJ5IG1peGluZyBpdCB3aXRoIHRoZSBjdXJyZW50IHNlZWQuIFRoZSBuZXcgc2VlZCBpcyB0" + - "aGUgdW5zaWduZWQgMjU2LWJpdCBgSW50YCB2YWx1ZSBvZiB0aGUgU0hBLTI1NiBoYXNoIG9mIGNvbmNhdGVuYXRlZCBvbGQgc2VlZCBhbmQgYHhgIGluIHRoZWlyIDMy" + - "LWJ5dGUgc3RyaW5ncyBiaWctZW5kaWFuIHJlcHJlc2VudGF0aW9uLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAgIG5hdGl2ZVJhbmRv" + - "bWl6ZSg0Mik7ICAgICAgICAvLyBub3csIHJhbmRvbSBudW1iZXJzIGFyZSBsZXNzIHByZWRpY3RhYmxlCi8vLyAgICAgbGV0IGlkazogSW50ID0gcmFuZG9tSW50KCk7" + - "IC8vID8/PywgaXQncyByYW5kb20sCi8vLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGJ1dCB0aGUgc2VlZCB3YXMgYWRqdXN0ZWQgZGV0ZXJtaW5p" + - "c3RpY2FsbHkhCi8vLyB9Ci8vLyBgYGAKLy8vCi8vLyAjIyMjIEV4aXQgY29kZXMKLy8vCi8vLyAqIDU6IFtJbnRlZ2VyIG91dCBvZiBleHBlY3RlZCByYW5nZV0g4oCU" + - "IFRocm93biB3aGVuIGF0dGVtcHRpbmcgdG8gc3BlY2lmeSBhIG5lZ2F0aXZlIHZhbHVlIG9mIGB4YC4KLy8vCi8vLyBTZWU6Ci8vLyAqIGh0dHBzOi8vZG9jcy50YWN0" + - "LWxhbmcub3JnL3JlZi9jb3JlLXJhbmRvbSNuYXRpdmVyYW5kb21pemUKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtcmFuZG9tI3JhbmRv" + - "bWludAovLy8KLy8vIFtJbnRlZ2VyIG91dCBvZiBleHBlY3RlZCByYW5nZV06IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL2Jvb2svZXhpdC1jb2RlcyM1Ci8vLwph" + - "c20gZnVuIG5hdGl2ZVJhbmRvbWl6ZSh4OiBJbnQpIHsgQUREUkFORCB9CgovLy8gR2xvYmFsIGZ1bmN0aW9uLgovLy8KLy8vIFJhbmRvbWl6ZXMgdGhlIHJhbmRvbSBu" + - "dW1iZXIgZ2VuZXJhdG9yIHdpdGggdGhlIGxvZ2ljYWwgdGltZSBvZiB0aGUgY3VycmVudCB0cmFuc2FjdGlvbi4gRXF1aXZhbGVudCB0byBjYWxsaW5nIGBuYXRpdmVS" + - "YW5kb21pemUoY3VyTHQoKSlgLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAgIG5hdGl2ZVJhbmRvbWl6ZUx0KCk7ICAgICAgICAvLyBu" + - "b3csIHJhbmRvbSBudW1iZXJzIGFyZSB1bnByZWRpY3RhYmxlIGZvciB1c2VycywKLy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYnV0IHN0aWxs" + - "IG1heSBiZSBhZmZlY3RlZCBieSB2YWxpZGF0b3JzIG9yIGNvbGxhdG9ycwovLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBhcyB0aGV5IGRldGVy" + - "bWluZSB0aGUgc2VlZCBvZiB0aGUgY3VycmVudCBibG9jay4KLy8vICAgICBsZXQgaWRrOiBJbnQgPSByYW5kb21JbnQoKTsgLy8gPz8/LCBpdCdzIHJhbmRvbSEKLy8v" + - "IH0KLy8vIGBgYAovLy8KLy8vIFNlZToKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtcmFuZG9tI25hdGl2ZXJhbmRvbWl6ZWx0Ci8vLyAq" + - "IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLXJhbmRvbSNuYXRpdmVyYW5kb21pemUKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVm" + - "L2NvcmUtY29udGV4dHN0YXRlI2N1cmx0Ci8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLXJhbmRvbSNyYW5kb21pbnQKLy8vCmFzbSBmdW4g" + - "bmF0aXZlUmFuZG9taXplTHQoKSB7IExUSU1FIEFERFJBTkQgfQoKLy8vIEdsb2JhbCBmdW5jdGlvbi4KLy8vCi8vLyBQcmVwYXJlcyBhIHJhbmRvbSBudW1iZXIgZ2Vu" + - "ZXJhdG9yIGJ5IHVzaW5nIGBuYXRpdmVSYW5kb21pemVMdCgpYC4gQXV0b21hdGljYWxseSBjYWxsZWQgYnkgYHJhbmRvbUludCgpYCBhbmQgYHJhbmRvbSgpYCBmdW5j" + - "dGlvbnMuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKSB7Ci8vLyAgICAgbmF0aXZlUHJlcGFyZVJhbmRvbSgpOyAvLyBwcmVwYXJlIHRoZSBSTkcKLy8v" + - "ICAgICAvLyAuLi4gZG8geW91ciByYW5kb20gdGhpbmdzIC4uLgovLy8gfQovLy8gYGBgCi8vLwovLy8gU2VlOgovLy8gKiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9y" + - "Zy9yZWYvY29yZS1yYW5kb20jbmF0aXZlcHJlcGFyZXJhbmRvbQovLy8gKiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1yYW5kb20jbmF0aXZlcmFu" + - "ZG9taXplbHQKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtcmFuZG9tI3JhbmRvbWludAovLy8gKiBodHRwczovL2RvY3MudGFjdC1sYW5n" + - "Lm9yZy9yZWYvY29yZS1yYW5kb20jcmFuZG9tCi8vLwpAbmFtZShfX3RhY3RfcHJlcGFyZV9yYW5kb20pCm5hdGl2ZSBuYXRpdmVQcmVwYXJlUmFuZG9tKCk7CgovLyBS" + - "YW5kb20KCi8vIEdlbmVyYXRlcyBhIG5ldyBwc2V1ZG8tcmFuZG9tIHVuc2lnbmVkIDI1Ni1iaXQgaW50ZWdlciB4LgovLyBUaGUgYWxnb3JpdGhtIGlzIGFzIGZvbGxv" + - "d3M6IGlmIHIgaXMgdGhlIG9sZCB2YWx1ZSBvZiB0aGUgcmFuZG9tIHNlZWQsCi8vIGNvbnNpZGVyZWQgYXMgYSAzMi1ieXRlIGFycmF5IChieSBjb25zdHJ1Y3Rpbmcg" + - "dGhlIGJpZy1lbmRpYW4gcmVwcmVzZW50YXRpb24KLy8gb2YgYW4gdW5zaWduZWQgMjU2LWJpdCBpbnRlZ2VyKSwgdGhlbiBpdHMgc2hhNTEyKHIpIGlzIGNvbXB1dGVk" + - "OwovLyB0aGUgZmlyc3QgMzIgYnl0ZXMgb2YgdGhpcyBoYXNoIGFyZSBzdG9yZWQgYXMgdGhlIG5ldyB2YWx1ZSByJyBvZiB0aGUgcmFuZG9tIHNlZWQsCi8vIGFuZCB0" + - "aGUgcmVtYWluaW5nIDMyIGJ5dGVzIGFyZSByZXR1cm5lZCBhcyB0aGUgbmV4dCByYW5kb20gdmFsdWUgeC4KYXNtIGZ1biBuYXRpdmVSYW5kb20oKTogSW50IHsgUkFO" + - "RFUyNTYgfQoKLy8gR2VuZXJhdGVzIGEgbmV3IHBzZXVkby1yYW5kb20gaW50ZWdlciB6IGluIHRoZSByYW5nZSAwLi5yYW5nZeKIkjEKLy8gKG9yIHJhbmdlLi7iiJIx" + - "LCBpZiByYW5nZSA8IDApLgovLyBNb3JlIHByZWNpc2VseSwgYW4gdW5zaWduZWQgcmFuZG9tIHZhbHVlIHggaXMgZ2VuZXJhdGVkIGFzIGluIGBuYXRpdmVSYW5kb21g" + - "OwovLyB0aGVuIHogOj0geCAqIHJhbmdlIC8gMl4yNTYgaXMgY29tcHV0ZWQuCmFzbSBmdW4gbmF0aXZlUmFuZG9tSW50ZXJ2YWwobWF4OiBJbnQpOiBJbnQgeyBSQU5E" + - "IH0KCi8vLyBHZW5lcmF0ZXMgYSBuZXcgcHNldWRvLXJhbmRvbSB1bnNpZ25lZCAyNTYtYml0IGBJbnRgIHZhbHVlIGB4YC4KLy8vCi8vLyBUaGUgYWxnb3JpdGhtIHdv" + - "cmtzIGFzIGZvbGxvd3M6IGZpcnN0LCB0aGUgYHNoYTUxMihyKWAgaXMgY29tcHV0ZWQuIFRoZXJlLCBgcmAgaXMgYW4gb2xkCi8vLyB2YWx1ZSBvZiB0aGUgcmFuZG9t" + - "IHNlZWQsIHdoaWNoIGlzIHRha2VuIGFzIGEgMzItYnl0ZSBhcnJheSBjb25zdHJ1Y3RlZCBmcm9tIHRoZSBiaWctZW5kaWFuCi8vLyByZXByZXNlbnRhdGlvbiBvZiBh" + - "biB1bnNpZ25lZCAyNTYtYml0IGBJbnRgLiBUaGUgZmlyc3QgMzIgYnl0ZXMgb2YgdGhpcyBoYXNoIGFyZSBzdG9yZWQgYXMgdGhlIG5ldwovLy8gdmFsdWUgYHInYCBv" + - "ZiB0aGUgcmFuZG9tIHNlZWQsIGFuZCB0aGUgcmVtYWluaW5nIDMyIGJ5dGVzIGFyZSByZXR1cm5lZCBhcyB0aGUgbmV4dCByYW5kb20gdmFsdWUgYHhgLgovLy8KLy8v" + - "IGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAgIGxldCBhbGxZb3VyUmFuZG9tQmVsb25nVG9VczogSW50ID0gcmFuZG9tSW50KCk7IC8vID8/PywgaXQn" + - "cyByYW5kb20gOikKLy8vIH0KLy8vIGBgYAovLy8KLy8vIFNlZTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtcmFuZG9tI3JhbmRvbWludAovLy8K" + - "aW5saW5lIGZ1biByYW5kb21JbnQoKTogSW50IHsKICAgIG5hdGl2ZVByZXBhcmVSYW5kb20oKTsKICAgIHJldHVybiBuYXRpdmVSYW5kb20oKTsKfQoKLy8vIEdlbmVy" + - "YXRlcyBhIG5ldyBwc2V1ZG8tcmFuZG9tIHVuc2lnbmVkIGBJbnRgIHZhbHVlIGB4YCBpbiB0aGUgcHJvdmlkZWQgc2VtaS1jbG9zZWQKLy8vIGludGVydmFsOiBgbWlu" + - "YCDiiaQgYHhgIDwgYG1heGAsIG9yIGBtaW5gIOKJpSBgeGAgPiBgbWF4YCBpZiBib3RoIGBtaW5gIGFuZCBgbWF4YCBhcmUgbmVnYXRpdmUuCi8vLwovLy8gTm90ZSB0" + - "aGF0IHRoZSBgbWF4YCB2YWx1ZSBpcyBuZXZlciBpbmNsdWRlZCBpbiB0aGUgaW50ZXJ2YWwuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKSB7Ci8vLyAg" + - "ICAgcmFuZG9tKDQyLCA0Myk7IC8vIDQyLCBhbHdheXMKLy8vICAgICByYW5kb20oMCwgNDIpOyAgLy8gMC00MSwgYnV0IG5ldmVyIDQyCi8vLyB9Ci8vLyBgYGAKLy8v" + - "Ci8vLyBTZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLXJhbmRvbSNyYW5kb20KLy8vCmlubGluZSBmdW4gcmFuZG9tKG1pbjogSW50LCBtYXg6" + - "IEludCk6IEludCB7CiAgICBuYXRpdmVQcmVwYXJlUmFuZG9tKCk7CiAgICByZXR1cm4gbWluICsgbmF0aXZlUmFuZG9tSW50ZXJ2YWwobWF4IC0gbWluKTsKfQoKLy8g" + - "TWF0aAoKLy8vIEdsb2JhbCBmdW5jdGlvbi4KLy8vCi8vLyBDb21wdXRlcyB0aGUgbWluaW11bSBvZiB0d28gYEludGAgdmFsdWVzIGB4YCBhbmQgYHlgLgovLy8KLy8v" + - "IGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlcygpIHsKLy8vICAgICBtaW4oMSwgMik7ICAgICAgICAvLyAxCi8vLyAgICAgbWluKDIsIDIpOyAgICAgICAgLy8gMgovLy8g" + - "ICAgIG1pbigwMDcsIDMpOyAgICAgIC8vIDMKLy8vICAgICBtaW4oMHg0MiwgM18wXzApOyAvLyA2NiwgbmljZQovLy8gICAgIC8vICDihpEgICAgIOKGkQovLy8gICAg" + - "IC8vICA2NiAgICAzMDAKLy8vIH0KLy8vIGBgYAovLy8KLy8vIFNlZTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtbWF0aCNtaW4KLy8vCmFzbSBm" + - "dW4gbWluKHg6IEludCwgeTogSW50KTogSW50IHsgTUlOIH0KCi8vLyBHbG9iYWwgZnVuY3Rpb24uCi8vLwovLy8gQ29tcHV0ZXMgdGhlIG1heGltdW0gb2YgdHdvIGBJ" + - "bnRgIHZhbHVlcyBgeGAgYW5kIGB5YC4KLy8vCi8vLyBgYGB0YWN0Ci8vLyBmdW4gZXhhbXBsZXMoKSB7Ci8vLyAgICAgbWF4KDEsIDIpOyAgICAgICAgLy8gMgovLy8g" + - "ICAgIG1heCgyLCAyKTsgICAgICAgIC8vIDIKLy8vICAgICBtYXgoMDA3LCAzKTsgICAgICAvLyA3Ci8vLyAgICAgbWF4KDB4NDUsIDNfMF8wKTsgLy8gMzAwCi8vLyAg" + - "ICAgLy8gIOKGkSAgICAg4oaRCi8vLyAgICAgLy8gIDY5ICAgIDMwMAovLy8gfQovLy8gYGBgCi8vLwovLy8gU2VlOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9y" + - "ZWYvY29yZS1tYXRoI21heAovLy8KYXNtIGZ1biBtYXgoeDogSW50LCB5OiBJbnQpOiBJbnQgeyBNQVggfQoKLy8vIEdsb2JhbCBmdW5jdGlvbi4KLy8vCi8vLyBDb21w" + - "dXRlcyB0aGUgYWJzb2x1dGUgdmFsdWUgb2YgdGhlIGBJbnRgIHZhbHVlIGB4YC4KLy8vCi8vLyBgYGB0YWN0Ci8vLyBmdW4gZXhhbXBsZXMoKSB7Ci8vLyAgICAgYWJz" + - "KDQyKTsgICAgICAgIC8vIDQyCi8vLyAgICAgYWJzKC00Mik7ICAgICAgIC8vIDQyCi8vLyAgICAgYWJzKC0oLSgtNDIpKSk7IC8vIDQyCi8vLyB9Ci8vLyBgYGAKLy8v" + - "Ci8vLyAvLy8gIyMjIyBFeGl0IGNvZGVzCi8vLwovLy8gKiA0OiBbSW50ZWdlciBvdmVyZmxvd10g4oCUIFRocm93biB3aGVuIHRoZSBhcmd1bWVudCBlcXVhbHMgdGhl" + - "IG1pbmltdW0gcmVwcmVzZW50YWJsZSBpbnRlZ2VyLCAtMl4yNTYuCi8vLwovLy8gU2VlOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1tYXRoI2Fi" + - "cwovLy8KLy8vIFtJbnRlZ2VyIG92ZXJmbG93XTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvYm9vay9leGl0LWNvZGVzLyM0Ci8vLwphc20gZnVuIGFicyh4OiBJ" + - "bnQpOiBJbnQgeyBBQlMgfQoKLy8vIEdsb2JhbCBmdW5jdGlvbi4KLy8vCi8vLyBDb21wdXRlcyB0aGUgbG9nYXJpdGhtIG9mIGEgbnVtYmVyIGBudW1gID4gMCB0byB0" + - "aGUgYmFzZSBgYmFzZWAg4omlIDIuIFJlc3VsdHMgYXJlIHJvdW5kZWQgZG93bi4KLy8vCi8vLyBgYGB0YWN0Ci8vLyBmdW4gZXhhbXBsZXMoKSB7Ci8vLyAgICAgbG9n" + - "KDEwMDAsIDEwKTsgLy8gMywgYXMgMTBeMyBpcyAxMDAwCi8vLyAgICAgLy8gIOKGkSAgICAg4oaRICAgICAgICAgICAgIOKGkSAgICAgICDihpEKLy8vICAgICAvLyAg" + - "bnVtICAgYmFzZSAgICAgICAgICBiYXNlICAgIG51bQovLy8KLy8vICAgICBsb2coMTAwMSwgMTApOyAgLy8gMwovLy8gICAgIGxvZyg5OTksIDEwKTsgICAvLyAyCi8v" + - "LyAgICAgdHJ5IHsKLy8vICAgICAgICAgbG9nKC0xMDAwLCAxMCk7IC8vIGV4aXQgY29kZSA1IGJlY2F1c2Ugb2YgdGhlIG5vbi1wb3NpdGl2ZSBudW0KLy8vICAgICB9" + - "Ci8vLyAgICAgbG9nKDEwMjQsIDIpOyAgIC8vIDEwCi8vLyAgICAgdHJ5IHsKLy8vICAgICAgICAgbG9nKDEwMjQsIC0yKTsgIC8vIGV4aXQgY29kZSA1IGJlY2F1c2Ug" + - "dGhlIGJhc2UgaXMgbGVzcyB0aGFuIDIKLy8vICAgICB9Ci8vLyB9Ci8vLyBgYGAKLy8vCi8vLyAjIyMjIEV4aXQgY29kZXMKLy8vCi8vLyAqIDU6IFtJbnRlZ2VyIG91" + - "dCBvZiBleHBlY3RlZCByYW5nZV0g4oCUIFRocm93biB3aGVuIHRoZSBnaXZlbiBgbnVtYCB2YWx1ZSBpcyBub24tcG9zaXRpdmUKLy8vICAgb3IgdGhlIGdpdmVuIGBi" + - "YXNlYCB2YWx1ZSBpcyBsZXNzIHRoYW4gMi4KLy8vCi8vLyBTZWU6Ci8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLW1hdGgjbG9nCi8vLyAq" + - "IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLW1hdGgjbG9nMgovLy8KLy8vIFtJbnRlZ2VyIG91dCBvZiBleHBlY3RlZCByYW5nZV06IGh0dHBzOi8v" + - "ZG9jcy50YWN0LWxhbmcub3JnL2Jvb2svZXhpdC1jb2RlcyM1Ci8vLwppbmxpbmUgZnVuIGxvZyhudW06IEludCwgYmFzZTogSW50KTogSW50IHsKICAgIHRocm93VW5s" + - "ZXNzKDUsIG51bSA+IDApOwogICAgdGhyb3dVbmxlc3MoNSwgYmFzZSA+IDEpOwogICAgaWYgKG51bSA8IGJhc2UpIHsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAg" + - "ICBsZXQgcmVzdWx0ID0gMDsKICAgIHdoaWxlIChudW0gPj0gYmFzZSkgewogICAgICAgIG51bSAvPSBiYXNlOwogICAgICAgIHJlc3VsdCArPSAxOwogICAgfQogICAg" + - "cmV0dXJuIHJlc3VsdDsKfQoKLy8vIEdsb2JhbCBmdW5jdGlvbi4KLy8vCi8vLyBTaW1pbGFyIHRvIGBsb2coKWAsIGJ1dCBzZXRzIHRoZSBgYmFzZWAgdG8gMi4KLy8v" + - "Ci8vLyBgYGB0YWN0Ci8vLyBmdW4gZXhhbXBsZSgpIHsKLy8vICAgICBsb2cyKDEwMjQpOyAvLyAxMCwgYXMgMl4xMCBpcyAxMDI0Ci8vLyAgICAgLy8gICDihpEgICAg" + - "ICAgICAgICAgICAg4oaRICAgICAgIOKGkQovLy8gICAgIC8vICAgbnVtICAgICAgICAgICAgICBiYXNl4oKCICAgbnVtCi8vLyB9Ci8vLyBgYGAKLy8vCi8vLyAjIyMj" + - "IEV4aXQgY29kZXMKLy8vCi8vLyAqIDU6IFtJbnRlZ2VyIG91dCBvZiBleHBlY3RlZCByYW5nZV0g4oCUIFRocm93biB3aGVuIHRoZSBnaXZlbiBgbnVtYCB2YWx1ZSBp" + - "cyBub24tcG9zaXRpdmUuCi8vLwovLy8gU2VlOgovLy8gKiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1tYXRoI2xvZzIKLy8vICogaHR0cHM6Ly9k" + - "b2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtbWF0aCNsb2cuCi8vLwovLy8gW0ludGVnZXIgb3V0IG9mIGV4cGVjdGVkIHJhbmdlXTogaHR0cHM6Ly9kb2NzLnRhY3Qt" + - "bGFuZy5vcmcvYm9vay9leGl0LWNvZGVzLyM1Ci8vLwphc20gZnVuIGxvZzIobnVtOiBJbnQpOiBJbnQgeyBEVVAgNSBUSFJPV0lGTk9UIFVCSVRTSVpFIERFQyB9Cgov" + - "Ly8gR2xvYmFsIGZ1bmN0aW9uLgovLy8KLy8vIENvbXB1dGVzIHRoZSBleHBvbmVudGlhdGlvbiBpbnZvbHZpbmcgdHdvIG51bWJlcnM6IHRoZSBgYmFzZWAgYW5kIHRo" + - "ZSBleHBvbmVudCAob3IgX3Bvd2VyXykgYGV4cGAuCi8vLwovLy8gVGhpcyBmdW5jdGlvbiB0cmllcyB0byByZXNvbHZlIGNvbnN0YW50IHZhbHVlcyBpbiBjb21waWxl" + - "LXRpbWUgd2hlbmV2ZXIgcG9zc2libGUuCi8vLwovLy8gYGBgdGFjdAovLy8gY29udHJhY3QgRXhhbXBsZSB7Ci8vLyAgICAgLy8gUGVyc2lzdGVudCBzdGF0ZSB2YXJp" + - "YWJsZXMKLy8vICAgICBwMjM6IEludCA9IHBvdygyLCAzKTsgLy8gcmFpc2VzIDIgdG8gdGhlIDNyZCBwb3dlciwgd2hpY2ggaXMgOAovLy8gICAgIG9uZTogSW50ID0g" + - "cG93KDUsIDApOyAvLyByYWlzZXMgNSB0byB0aGUgcG93ZXIgMCwgd2hpY2ggYWx3YXlzIHByb2R1Y2VzIDEKLy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8g" + - "d29ya3MgYXQgY29tcGlsZS10aW1lIQovLy8KLy8vICAgICAvLyBJbnRlcm5hbCBtZXNzYWdlIHJlY2VpdmVyCi8vLyAgICAgcmVjZWl2ZSgpIHsKLy8vICAgICAgICAg" + - "cG93KHNlbGYucDIzLCBzZWxmLm9uZSArIDEpOyAvLyA2NCwgd29ya3MgYXQgcnVuLXRpbWUgdG9vIQovLy8gICAgICAgICB0cnkgewovLy8gICAgICAgICAgICAgcG93" + - "KDAsIC0xKTsgLy8gZXhpdCBjb2RlIDU6IEludGVnZXIgb3V0IG9mIGV4cGVjdGVkIHJhbmdlCi8vLyAgICAgICAgIH0KLy8vICAgICB9Ci8vLyB9Ci8vLyBgYGAKLy8v" + - "Ci8vLyAjIyMjIEV4aXQgY29kZXMKLy8vCi8vLyAqIDQ6IFtJbnRlZ2VyIG92ZXJmbG93XSDigJQgVGhyb3duIHdoZW4gdGhlIHJlc3VsdCBleGNlZWRzIHRoZSByYW5n" + - "ZSBvZiByZXByZXNlbnRhYmxlIGludGVnZXJzLCBpLmUuIFstMl4yNTY7IDJeMjU2IC0gMV0uCi8vLyAqIDU6IFtJbnRlZ2VyIG91dCBvZiBleHBlY3RlZCByYW5nZV0g" + - "4oCUIFRocm93biB3aGVuIHRoZSBnaXZlbiBgZXhwYCB2YWx1ZSBpcyBuZWdhdGl2ZS4KLy8vCi8vLyBTZWU6Ci8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3Jn" + - "L3JlZi9jb3JlLW1hdGgjcG93Ci8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLW1hdGgjcG93MgovLy8KLy8vIFtJbnRlZ2VyIG92ZXJmbG93" + - "XTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvYm9vay9leGl0LWNvZGVzLyM0Ci8vLyBbSW50ZWdlciBvdXQgb2YgZXhwZWN0ZWQgcmFuZ2VdOiBodHRwczovL2Rv" + - "Y3MudGFjdC1sYW5nLm9yZy9ib29rL2V4aXQtY29kZXMvIzUKLy8vCmlubGluZSBmdW4gcG93KGJhc2U6IEludCwgZXhwOiBJbnQpOiBJbnQgewogICAgdGhyb3dVbmxl" + - "c3MoNSwgZXhwID49IDApOwogICAgbGV0IHJlc3VsdCA9IDE7CiAgICByZXBlYXQgKGV4cCkgewogICAgICAgIHJlc3VsdCAqPSBiYXNlOwogICAgfQogICAgcmV0dXJu" + - "IHJlc3VsdDsKfQoKLy8vIEdsb2JhbCBmdW5jdGlvbi4KLy8vCi8vLyBTaW1pbGFyIHRvIGBwb3coKWAsIGJ1dCBzZXRzIHRoZSBgYmFzZWAgdG8gMi4KLy8vCi8vLyBU" + - "aGlzIGZ1bmN0aW9uIHRyaWVzIHRvIHJlc29sdmUgY29uc3RhbnQgdmFsdWVzIGluIGNvbXBpbGUtdGltZSB3aGVuZXZlciBwb3NzaWJsZS4KLy8vCi8vLyBgYGB0YWN0" + - "Ci8vLyBjb250cmFjdCBFeGFtcGxlIHsKLy8vICAgICAvLyBQZXJzaXN0ZW50IHN0YXRlIHZhcmlhYmxlcwovLy8gICAgIHAyMzogSW50ID0gcG93MigzKTsgLy8gcmFp" + - "c2VzIDIgdG8gdGhlIDNyZCBwb3dlciwgd2hpY2ggaXMgOAovLy8gICAgIG9uZTogSW50ID0gcG93MigwKTsgLy8gcmFpc2VzIDIgdG8gdGhlIHBvd2VyIDAsIHdoaWNo" + - "IGFsd2F5cyBwcm9kdWNlcyAxCi8vLyAgICAgICAgICAgICAgICAgICAgICAgICAvLyB3b3JrcyBhdCBjb21waWxlLXRpbWUhCi8vLwovLy8gICAgIC8vIEludGVybmFs" + - "IG1lc3NhZ2UgcmVjZWl2ZXIsIHdoaWNoIGFjY2VwdHMgbWVzc2FnZSBFeHRNc2cKLy8vICAgICByZWNlaXZlKCkgewovLy8gICAgICAgICBwb3cyKHNlbGYub25lICsg" + - "MSk7IC8vIDQsIHdvcmtzIGF0IHJ1bi10aW1lIHRvbyEKLy8vICAgICAgICAgdHJ5IHsKLy8vICAgICAgICAgICAgIHBvdygtMSk7IC8vIGV4aXQgY29kZSA1OiBJbnRl" + - "Z2VyIG91dCBvZiBleHBlY3RlZCByYW5nZQovLy8gICAgICAgICB9Ci8vLyAgICAgfQovLy8gfQovLy8gYGBgCi8vLwovLy8gIyMjIyBFeGl0IGNvZGVzCi8vLwovLy8g" + - "KiA0OiBbSW50ZWdlciBvdmVyZmxvd10g4oCUIFRocm93biB3aGVuIHRoZSByZXN1bHQgZXhjZWVkcyB0aGUgcmFuZ2Ugb2YgcmVwcmVzZW50YWJsZSBpbnRlZ2Vycywg" + - "aS5lLiBbLTJeMjU2OyAyXjI1NiAtIDFdLgovLy8gKiA1OiBbSW50ZWdlciBvdXQgb2YgZXhwZWN0ZWQgcmFuZ2VdIOKAlCBUaHJvd24gd2hlbiBhdHRlbXB0aW5nIHRv" + - "IHNwZWNpZnkgYSBuZWdhdGl2ZSB2YWx1ZSBvZiBgZXhwYC4KLy8vCi8vLyBTZWU6Ci8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLW1hdGgj" + - "cG93MgovLy8gKiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1tYXRoI3BvdwovLy8KLy8vIFtJbnRlZ2VyIG92ZXJmbG93XTogaHR0cHM6Ly9kb2Nz" + - "LnRhY3QtbGFuZy5vcmcvYm9vay9leGl0LWNvZGVzLyM0Ci8vLyBbSW50ZWdlciBvdXQgb2YgZXhwZWN0ZWQgcmFuZ2VdOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9y" + - "Zy9ib29rL2V4aXQtY29kZXMjNQovLy8KYXNtIGZ1biBwb3cyKGV4cDogSW50KTogSW50IHsgUE9XMiB9CgovLy8gR2xvYmFsIGZ1bmN0aW9uLiBBdmFpbGFibGUgc2lu" + - "Y2UgVGFjdCAxLjYuMC4KLy8vCi8vLyBDb21wdXRlcyB0aGUgc2lnbiBvZiB0aGUgYEludGAgdmFsdWUgYHhgLiBQcm9kdWNlcyAxIGlmIHRoZSBgeGAgaXMgcG9zaXRp" + - "dmUsIC0xIGlmIHRoZSBgeGAgaXMgbmVnYXRpdmUsIGFuZCAwIGlmIHRoZSBgeGAgaXMgMC4KLy8vCi8vLyBgYGB0YWN0Ci8vLyBmdW4gZXhhbXBsZXMoKSB7Ci8vLyAg" + - "ICAgc2lnbig0Mik7ICAgICAgICAvLyAxCi8vLyAgICAgc2lnbigtNDIpOyAgICAgICAvLyAtMQovLy8gICAgIHNpZ24oLSgtNDIpKTsgICAgLy8gMQovLy8gICAgIHNp" + - "Z24oLSgtKC00MikpKTsgLy8gLTEKLy8vICAgICBzaWduKDApOyAgICAgICAgIC8vIDAKLy8vIH0KLy8vIGBgYAovLy8KLy8vIFNlZTogaHR0cHM6Ly9kb2NzLnRhY3Qt" + - "bGFuZy5vcmcvcmVmL2NvcmUtbWF0aCNzaWduCi8vLwphc20gZnVuIHNpZ24oeDogSW50KTogSW50IHsgU0dOIH0KCi8vLyBHbG9iYWwgZnVuY3Rpb24uIEF2YWlsYWJs" + - "ZSBzaW5jZSBUYWN0IDEuNi4wLgovLy8KLy8vIENvbXB1dGVzIHRoZSByb3VuZGVkIHVwIHJlc3VsdCBvZiBkaXZpc2lvbiBvZiB0aGUgbnVtYmVycyBgeGAgYW5kIGB5" + - "YC4KLy8vCi8vLyBgYGB0YWN0Ci8vLyBmdW4gZXhhbXBsZXMoKSB7Ci8vLyAgICAgZGl2Yyg0LCAyKTsgIC8vIDIKLy8vICAgICBkaXZjKDMsIDIpOyAgLy8gMgovLy8g" + - "ICAgIGRpdmMoLTQsIDIpOyAvLyAtMgovLy8gICAgIGRpdmMoLTMsIDIpOyAvLyAtMQovLy8gfQovLy8gYGBgCi8vLwovLy8gIyMjIyBFeGl0IGNvZGVzCi8vLwovLy8g" + - "KiA0OiBbSW50ZWdlciBvdmVyZmxvd10g4oCUIFRocm93biB3aGVuIGRpdmlzaW9uIGJ5IHplcm8gaXMgYXR0ZW1wdGVkIG9yIC0yXjI1NiBpcyBkaXZpZGVkIGJ5IC0x" + - "LgovLy8KLy8vIFNlZTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtbWF0aCNkaXZjCi8vLwovLy8gW0ludGVnZXIgb3ZlcmZsb3ddOiBodHRwczov" + - "L2RvY3MudGFjdC1sYW5nLm9yZy9ib29rL2V4aXQtY29kZXMvIzQKLy8vCmFzbSBmdW4gZGl2Yyh4OiBJbnQsIHk6IEludCk6IEludCB7IERJVkMgfQoKLy8vIEdsb2Jh" + - "bCBmdW5jdGlvbi4gQXZhaWxhYmxlIHNpbmNlIFRhY3QgMS42LjAuCi8vLwovLy8gQ29tcHV0ZXMgdGhlIHJvdW5kZWQgdXAgcmVzdWx0IG9mIGAoeCAqIHkpIC8gemAu" + - "Ci8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGVzKCkgewovLy8gICAgIG11bGRpdmMoNCwgMSwgMik7ICAvLyAyCi8vLyAgICAgbXVsZGl2YygzLCAxLCAyKTsg" + - "IC8vIDIKLy8vICAgICBtdWxkaXZjKC00LCAxLCAyKTsgLy8gLTIKLy8vICAgICBtdWxkaXZjKC0zLCAxLCAyKTsgLy8gLTEKLy8vICAgICBtdWxkaXZjKC0zLCAwLCAy" + - "KTsgLy8gMAovLy8gICAgIG11bGRpdmMoLTMsIDAsIDApOyAvLyBFUlJPUiEgRXhpdCBjb2RlIDQ6IEludGVnZXIgb3ZlcmZsb3cKLy8vIH0KLy8vIGBgYAovLy8KLy8v" + - "ICMjIyMgRXhpdCBjb2RlcwovLy8KLy8vICogNDogW0ludGVnZXIgb3ZlcmZsb3ddIOKAlCBUaHJvd24gd2hlbiB0aGUgdmFsdWUgaW4gY2FsY3VsYXRpb24gZ29lcyBi" + - "ZXlvbmQKLy8vICAgdGhlIHJhbmdlIGZyb20gLTJeMjU2IHRvIDJeMjU2IC0gMSBpbmNsdXNpdmUsIG9yIGlmIHRoZXJlJ3MgYW4gYXR0ZW1wdCB0bwovLy8gICBkaXZp" + - "ZGUgYnkgemVyby4KLy8vCi8vLyBTZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLW1hdGgjbXVsZGl2YwovLy8KLy8vIFtJbnRlZ2VyIG92ZXJm" + - "bG93XTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvYm9vay9leGl0LWNvZGVzLyM0Ci8vLwphc20gZnVuIG11bGRpdmMoeDogSW50LCB5OiBJbnQsIHo6IEludCk6" + - "IEludCB7IE1VTERJVkMgfQoKLy8vIEdsb2JhbCBmdW5jdGlvbi4gQXZhaWxhYmxlIHNpbmNlIFRhY3QgMS42LjAuCi8vLwovLy8gQ29tcHV0ZXMgdGhlIHJvdW5kZWQg" + - "ZG93biByZXN1bHQgb2YgYCh4ICogeSkgLyAyXnpgLiBJdCBpcyBhIG1vcmUgZ2FzLWVmZmljaWVudCBlcXVpdmFsZW50IG9mIGRvaW5nIHRoZSBiaXR3aXNlIHNoaWZ0" + - "IHJpZ2h0IG9uIHRoZSByZXN1bHQgb2YgbXVsdGlwbGljYXRpb24gb2YgYHhgIGFuZCBgeWAsIHdoZXJlIGB6YCBpcyB0aGUgcmlnaHQgb3BlcmFuZCBvZiB0aGUgc2hp" + - "ZnQuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGVzKCkgewovLy8gICAgIG11bFNoaWZ0UmlnaHQoNSwgNSwgMik7ICAvLyA2Ci8vLyAgICAgbXVsU2hpZnRS" + - "aWdodCg1LCA1LCAxKTsgIC8vIDEyCi8vLyAgICAgbXVsU2hpZnRSaWdodCg1LCA1LCAwKTsgIC8vIDI1Ci8vLyAgICAgbXVsU2hpZnRSaWdodCg1LCA1LCAtMSk7IC8v" + - "IEVSUk9SISBFeGl0IGNvZGUgNTogSW50ZWdlciBvdXQgb2YgZXhwZWN0ZWQgcmFuZ2UKLy8vIH0KLy8vIGBgYAovLy8KLy8vICMjIyMgRXhpdCBjb2RlcwovLy8KLy8v" + - "ICogNDogW0ludGVnZXIgb3ZlcmZsb3ddIOKAlCBUaHJvd24gd2hlbiB0aGUgdmFsdWUgaW4gY2FsY3VsYXRpb24gZ29lcyBiZXlvbmQKLy8vICAgdGhlIHJhbmdlIGZy" + - "b20gLTJeMjU2IHRvIDJeMjU2IC0gMSBpbmNsdXNpdmUuCi8vLwovLy8gKiA1OiBbSW50ZWdlciBvdXQgb2YgZXhwZWN0ZWQgcmFuZ2VdIOKAlCBUaHJvd24gd2hlbiB0" + - "aGUgZ2l2ZW4gYHpgIHZhbHVlIGlzCi8vLyAgIG91dHNpZGUgdGhlIGluY2x1c2l2ZSByYW5nZSBmcm9tIDAgdG8gMjU2LgovLy8KLy8vIFNlZTogaHR0cHM6Ly9kb2Nz" + - "LnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtbWF0aCNtdWxzaGlmdHJpZ2h0Ci8vLwovLy8gW0ludGVnZXIgb3ZlcmZsb3ddOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9y" + - "Zy9ib29rL2V4aXQtY29kZXMvIzQKLy8vIFtJbnRlZ2VyIG91dCBvZiBleHBlY3RlZCByYW5nZV06IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL2Jvb2svZXhpdC1j" + - "b2Rlcy8jNQovLy8KYXNtIGZ1biBtdWxTaGlmdFJpZ2h0KHg6IEludCwgeTogSW50LCB6OiBJbnQpOiBJbnQgeyBNVUxSU0hJRlQgfQoKLy8vIEdsb2JhbCBmdW5jdGlv" + - "bi4gQXZhaWxhYmxlIHNpbmNlIFRhY3QgMS42LjAuCi8vLwovLy8gQ29tcHV0ZXMgYGZsb29yKCh4ICogeSkgLyAyXnogKyAwLjUpYC4gSXQgaXMgc2ltaWxhciB0byBg" + - "bXVsU2hpZnRSaWdodGAsIGJ1dCBpbnN0ZWFkIG9mIHJvdW5kaW5nIGRvd24sIHRoZSByZXN1bHQgdmFsdWUgaXMgcm91bmRlZCB0byB0aGUgbmVhcmVzdCBpbnRlZ2Vy" + - "IHdpdGggcmVzdWx0cyBsaWtlIDQyLjUgcm91bmRlZCB0byA0My4KLy8vCi8vLyBgYGB0YWN0Ci8vLyBmdW4gZXhhbXBsZXMoKSB7Ci8vLyAgICAgbXVsU2hpZnRSaWdo" + - "dFJvdW5kKDUsIDUsIDIpOyAgLy8gNgovLy8gICAgIG11bFNoaWZ0UmlnaHRSb3VuZCg1LCA1LCAxKTsgIC8vIDEzCi8vLyAgICAgbXVsU2hpZnRSaWdodFJvdW5kKDUs" + - "IDUsIDApOyAgLy8gMjUKLy8vICAgICBtdWxTaGlmdFJpZ2h0Um91bmQoNSwgNSwgLTEpOyAvLyBFUlJPUiEgRXhpdCBjb2RlIDU6IEludGVnZXIgb3V0IG9mIGV4cGVj" + - "dGVkIHJhbmdlCi8vLyB9Ci8vLyBgYGAKLy8vCi8vLyAjIyMjIEV4aXQgY29kZXMKLy8vCi8vLyAqIDQ6IFtJbnRlZ2VyIG92ZXJmbG93XSDigJQgVGhyb3duIHdoZW4g" + - "dGhlIHZhbHVlIGluIGNhbGN1bGF0aW9uIGdvZXMgYmV5b25kCi8vLyAgIHRoZSByYW5nZSBmcm9tIC0yXjI1NiB0byAyXjI1NiAtIDEgaW5jbHVzaXZlLgovLy8KLy8v" + - "ICogNTogW0ludGVnZXIgb3V0IG9mIGV4cGVjdGVkIHJhbmdlXSDigJQgVGhyb3duIHdoZW4gdGhlIGdpdmVuIGB6YCB2YWx1ZSBpcwovLy8gICBvdXRzaWRlIHRoZSBp" + - "bmNsdXNpdmUgcmFuZ2UgZnJvbSAwIHRvIDI1Ni4KLy8vCi8vLyBTZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLW1hdGgjbXVsc2hpZnRyaWdo" + - "dHJvdW5kCi8vLwovLy8gW0ludGVnZXIgb3ZlcmZsb3ddOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9ib29rL2V4aXQtY29kZXMvIzQKLy8vIFtJbnRlZ2VyIG91" + - "dCBvZiBleHBlY3RlZCByYW5nZV06IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL2Jvb2svZXhpdC1jb2Rlcy8jNQovLy8KYXNtIGZ1biBtdWxTaGlmdFJpZ2h0Um91" + - "bmQoeDogSW50LCB5OiBJbnQsIHo6IEludCk6IEludCB7IE1VTFJTSElGVFIgfQoKLy8vIEdsb2JhbCBmdW5jdGlvbi4gQXZhaWxhYmxlIHNpbmNlIFRhY3QgMS42LjAu" + - "Ci8vLwovLy8gQ29tcHV0ZXMgYGNlaWwoKHggKiB5KSAvIDJeeilgLiBTaW1pbGFyIHRvIGBtdWxTaGlmdFJpZ2h0KClgLCBidXQgaW5zdGVhZCBvZiByb3VuZGluZyBk" + - "b3duLCB0aGUgcmVzdWx0IHZhbHVlIGlzIHJvdW5kZWQgdXAuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGVzKCkgewovLy8gICAgIG11bFNoaWZ0UmlnaHRD" + - "ZWlsKDUsIDUsIDIpOyAgLy8gNwovLy8gICAgIG11bFNoaWZ0UmlnaHRDZWlsKDUsIDUsIDEpOyAgLy8gMTMKLy8vICAgICBtdWxTaGlmdFJpZ2h0Q2VpbCg1LCA1LCAw" + - "KTsgIC8vIDI1Ci8vLyAgICAgbXVsU2hpZnRSaWdodENlaWwoNSwgNSwgLTEpOyAvLyBFUlJPUiEgRXhpdCBjb2RlIDU6IEludGVnZXIgb3V0IG9mIGV4cGVjdGVkIHJh" + - "bmdlCi8vLyB9Ci8vLyBgYGAKLy8vCi8vLyAjIyMjIEV4aXQgY29kZXMKLy8vCi8vLyAqIDQ6IFtJbnRlZ2VyIG92ZXJmbG93XSDigJQgVGhyb3duIHdoZW4gdGhlIHZh" + - "bHVlIGluIGNhbGN1bGF0aW9uIGdvZXMgYmV5b25kCi8vLyAgIHRoZSByYW5nZSBmcm9tIC0yXjI1NiB0byAyXjI1NiAtIDEgaW5jbHVzaXZlLgovLy8KLy8vICogNTog" + - "W0ludGVnZXIgb3V0IG9mIGV4cGVjdGVkIHJhbmdlXSDigJQgVGhyb3duIHdoZW4gdGhlIGdpdmVuIGB6YCB2YWx1ZSBpcwovLy8gICBvdXRzaWRlIHRoZSBpbmNsdXNp" + - "dmUgcmFuZ2UgZnJvbSAwIHRvIDI1Ni4KLy8vCi8vLyBTZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLW1hdGgjbXVsc2hpZnRyaWdodGNlaWwK" + - "Ly8vCi8vLyBbSW50ZWdlciBvdmVyZmxvd106IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL2Jvb2svZXhpdC1jb2Rlcy8jNAovLy8gW0ludGVnZXIgb3V0IG9mIGV4" + - "cGVjdGVkIHJhbmdlXTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvYm9vay9leGl0LWNvZGVzLyM1Ci8vLwphc20gZnVuIG11bFNoaWZ0UmlnaHRDZWlsKHg6IElu" + - "dCwgeTogSW50LCB6OiBJbnQpOiBJbnQgeyBNVUxSU0hJRlRDIH0KCi8vLyBHbG9iYWwgZnVuY3Rpb24uIEF2YWlsYWJsZSBzaW5jZSBUYWN0IDEuNi4wLgovLy8KLy8v" + - "IENvbXB1dGVzIHRoZSBzcXVhcmUgcm9vdCBvZiB0aGUgYEludGAgdmFsdWUgYG51bWAuIFJldHVybnMgdGhlIHJlc3VsdCByb3VuZGVkIHRvIHRoZSBuZWFyZXN0IGlu" + - "dGVnZXIuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGVzKCkgewovLy8gICAgIHNxcnQoNCk7ICAvLyAyCi8vLyAgICAgc3FydCgzKTsgIC8vIDIKLy8vICAg" + - "ICBzcXJ0KDIpOyAgLy8gMQovLy8gICAgIHNxcnQoMSk7ICAvLyAxCi8vLyAgICAgc3FydCgwKTsgIC8vIDAKLy8vICAgICBzcXJ0KC0xKTsgLy8gRVJST1IhIEV4aXQg" + - "Y29kZSA1OiBJbnRlZ2VyIG91dCBvZiBleHBlY3RlZCByYW5nZQovLy8gfQovLy8gYGBgCi8vLwovLy8gIyMjIyBFeGl0IGNvZGVzCi8vLwovLy8gKiA1OiBbSW50ZWdl" + - "ciBvdXQgb2YgZXhwZWN0ZWQgcmFuZ2VdIOKAlCBUaHJvd24gd2hlbiBhdHRlbXB0aW5nIHRvIHNwZWNpZnkgYSBuZWdhdGl2ZSB2YWx1ZSBvZiBgbnVtYC4KLy8vCi8v" + - "LyBTZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLW1hdGgjc3FydAovLy8KLy8vIFtJbnRlZ2VyIG91dCBvZiBleHBlY3RlZCByYW5nZV06IGh0" + - "dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL2Jvb2svZXhpdC1jb2RlcyM1Ci8vLwpmdW4gc3FydChudW06IEludCk6IEludCB7CiAgICBpZiAobnVtID09IDApIHsKICAg" + - "ICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBsZXQgczogSW50ID0gbG9nMihudW0pOwogICAgbGV0IHg6IEludCA9IChzID09IDEgPyAobnVtIC0gMSkgLyAyICsgMSA6" + - "IDEgPDwgKChzICsgMSkgLyAyKSk7CgogICAgbGV0IHE6IEludCA9IDA7CgogICAgZG8gewogICAgICAgIHEgPSAoZGl2YyhudW0sIHgpIC0geCkgLyAyOwogICAgICAg" + - "IHggKz0gcTsKICAgIH0gdW50aWwgKHEgPT0gMCk7CgogICAgcmV0dXJuIHg7Cn0K"; + "aW1wb3J0ICIuL2RlYnVnIjsKCi8vIFByZXBhcmUgcmFuZG9tCgovLy8gR2xvYmFsIGZ1bmN0aW9uLgovLy8KLy8vIFJhbmRvbWl6ZXMgdGhlIHBzZXVkb3JhbmRvbSBu" + + "dW1iZXIgZ2VuZXJhdG9yIHdpdGggdGhlIHNwZWNpZmllZCB1bnNpZ25lZCAyNTYtYml0IGBJbnRgIGB4YCBieSBtaXhpbmcgaXQgd2l0aCB0aGUgY3VycmVudCBzZWVk" + + "LiBUaGUgbmV3IHNlZWQgaXMgdGhlIHVuc2lnbmVkIDI1Ni1iaXQgYEludGAgdmFsdWUgb2YgdGhlIFNIQS0yNTYgaGFzaCBvZiBjb25jYXRlbmF0ZWQgb2xkIHNlZWQg" + + "YW5kIGB4YCBpbiB0aGVpciAzMi1ieXRlIHN0cmluZ3MgYmlnLWVuZGlhbiByZXByZXNlbnRhdGlvbi4KLy8vCi8vLyBgYGB0YWN0Ci8vLyBmdW4gZXhhbXBsZSgpIHsK" + + "Ly8vICAgICBuYXRpdmVSYW5kb21pemUoNDIpOyAgICAgICAgLy8gbm93LCByYW5kb20gbnVtYmVycyBhcmUgbGVzcyBwcmVkaWN0YWJsZQovLy8gICAgIGxldCBpZGs6" + + "IEludCA9IHJhbmRvbUludCgpOyAvLyA/Pz8sIGl0J3MgcmFuZG9tLAovLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBidXQgdGhlIHNlZWQgd2Fz" + + "IGFkanVzdGVkIGRldGVybWluaXN0aWNhbGx5IQovLy8gfQovLy8gYGBgCi8vLwovLy8gIyMjIyBFeGl0IGNvZGVzCi8vLwovLy8gKiA1OiBbSW50ZWdlciBvdXQgb2Yg" + + "ZXhwZWN0ZWQgcmFuZ2VdIOKAlCBUaHJvd24gd2hlbiBhdHRlbXB0aW5nIHRvIHNwZWNpZnkgYSBuZWdhdGl2ZSB2YWx1ZSBvZiBgeGAuCi8vLwovLy8gU2VlOgovLy8g" + + "KiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1yYW5kb20jbmF0aXZlcmFuZG9taXplCi8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3Jl" + + "Zi9jb3JlLXJhbmRvbSNyYW5kb21pbnQKLy8vCi8vLyBbSW50ZWdlciBvdXQgb2YgZXhwZWN0ZWQgcmFuZ2VdOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9ib29r" + + "L2V4aXQtY29kZXMjNQovLy8KYXNtIGZ1biBuYXRpdmVSYW5kb21pemUoeDogSW50KSB7IEFERFJBTkQgfQoKLy8vIEdsb2JhbCBmdW5jdGlvbi4KLy8vCi8vLyBSYW5k" + + "b21pemVzIHRoZSByYW5kb20gbnVtYmVyIGdlbmVyYXRvciB3aXRoIHRoZSBsb2dpY2FsIHRpbWUgb2YgdGhlIGN1cnJlbnQgdHJhbnNhY3Rpb24uIEVxdWl2YWxlbnQg" + + "dG8gY2FsbGluZyBgbmF0aXZlUmFuZG9taXplKGN1ckx0KCkpYC4KLy8vCi8vLyBgYGB0YWN0Ci8vLyBmdW4gZXhhbXBsZSgpIHsKLy8vICAgICBuYXRpdmVSYW5kb21p" + + "emVMdCgpOyAgICAgICAgLy8gbm93LCByYW5kb20gbnVtYmVycyBhcmUgdW5wcmVkaWN0YWJsZSBmb3IgdXNlcnMsCi8vLyAgICAgICAgICAgICAgICAgICAgICAgICAg" + + "ICAgICAgIC8vIGJ1dCBzdGlsbCBtYXkgYmUgYWZmZWN0ZWQgYnkgdmFsaWRhdG9ycyBvciBjb2xsYXRvcnMKLy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg" + + "ICAgLy8gYXMgdGhleSBkZXRlcm1pbmUgdGhlIHNlZWQgb2YgdGhlIGN1cnJlbnQgYmxvY2suCi8vLyAgICAgbGV0IGlkazogSW50ID0gcmFuZG9tSW50KCk7IC8vID8/" + + "PywgaXQncyByYW5kb20hCi8vLyB9Ci8vLyBgYGAKLy8vCi8vLyBTZWU6Ci8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLXJhbmRvbSNuYXRp" + + "dmVyYW5kb21pemVsdAovLy8gKiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1yYW5kb20jbmF0aXZlcmFuZG9taXplCi8vLyAqIGh0dHBzOi8vZG9j" + + "cy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWNvbnRleHRzdGF0ZSNjdXJsdAovLy8gKiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1yYW5kb20jcmFu" + + "ZG9taW50Ci8vLwphc20gZnVuIG5hdGl2ZVJhbmRvbWl6ZUx0KCkgeyBMVElNRSBBRERSQU5EIH0KCi8vLyBHbG9iYWwgZnVuY3Rpb24uCi8vLwovLy8gUHJlcGFyZXMg" + + "YSByYW5kb20gbnVtYmVyIGdlbmVyYXRvciBieSB1c2luZyBgbmF0aXZlUmFuZG9taXplTHQoKWAuIEF1dG9tYXRpY2FsbHkgY2FsbGVkIGJ5IGByYW5kb21JbnQoKWAg" + + "YW5kIGByYW5kb20oKWAgZnVuY3Rpb25zLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAgIG5hdGl2ZVByZXBhcmVSYW5kb20oKTsgLy8g" + + "cHJlcGFyZSB0aGUgUk5HCi8vLyAgICAgLy8gLi4uIGRvIHlvdXIgcmFuZG9tIHRoaW5ncyAuLi4KLy8vIH0KLy8vIGBgYAovLy8KLy8vIFNlZToKLy8vICogaHR0cHM6" + + "Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtcmFuZG9tI25hdGl2ZXByZXBhcmVyYW5kb20KLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2Nv" + + "cmUtcmFuZG9tI25hdGl2ZXJhbmRvbWl6ZWx0Ci8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLXJhbmRvbSNyYW5kb21pbnQKLy8vICogaHR0" + + "cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtcmFuZG9tI3JhbmRvbQovLy8KQG5hbWUoX190YWN0X3ByZXBhcmVfcmFuZG9tKQpuYXRpdmUgbmF0aXZlUHJl" + + "cGFyZVJhbmRvbSgpOwoKLy8gUmFuZG9tCgovLyBHZW5lcmF0ZXMgYSBuZXcgcHNldWRvLXJhbmRvbSB1bnNpZ25lZCAyNTYtYml0IGludGVnZXIgeC4KLy8gVGhlIGFs" + + "Z29yaXRobSBpcyBhcyBmb2xsb3dzOiBpZiByIGlzIHRoZSBvbGQgdmFsdWUgb2YgdGhlIHJhbmRvbSBzZWVkLAovLyBjb25zaWRlcmVkIGFzIGEgMzItYnl0ZSBhcnJh" + + "eSAoYnkgY29uc3RydWN0aW5nIHRoZSBiaWctZW5kaWFuIHJlcHJlc2VudGF0aW9uCi8vIG9mIGFuIHVuc2lnbmVkIDI1Ni1iaXQgaW50ZWdlciksIHRoZW4gaXRzIHNo" + + "YTUxMihyKSBpcyBjb21wdXRlZDsKLy8gdGhlIGZpcnN0IDMyIGJ5dGVzIG9mIHRoaXMgaGFzaCBhcmUgc3RvcmVkIGFzIHRoZSBuZXcgdmFsdWUgcicgb2YgdGhlIHJh" + + "bmRvbSBzZWVkLAovLyBhbmQgdGhlIHJlbWFpbmluZyAzMiBieXRlcyBhcmUgcmV0dXJuZWQgYXMgdGhlIG5leHQgcmFuZG9tIHZhbHVlIHguCmFzbSBmdW4gbmF0aXZl" + + "UmFuZG9tKCk6IEludCB7IFJBTkRVMjU2IH0KCi8vIEdlbmVyYXRlcyBhIG5ldyBwc2V1ZG8tcmFuZG9tIGludGVnZXIgeiBpbiB0aGUgcmFuZ2UgMC4ucmFuZ2XiiJIx" + + "Ci8vIChvciByYW5nZS4u4oiSMSwgaWYgcmFuZ2UgPCAwKS4KLy8gTW9yZSBwcmVjaXNlbHksIGFuIHVuc2lnbmVkIHJhbmRvbSB2YWx1ZSB4IGlzIGdlbmVyYXRlZCBh" + + "cyBpbiBgbmF0aXZlUmFuZG9tYDsKLy8gdGhlbiB6IDo9IHggKiByYW5nZSAvIDJeMjU2IGlzIGNvbXB1dGVkLgphc20gZnVuIG5hdGl2ZVJhbmRvbUludGVydmFsKG1h" + + "eDogSW50KTogSW50IHsgUkFORCB9CgovLy8gR2VuZXJhdGVzIGEgbmV3IHBzZXVkby1yYW5kb20gdW5zaWduZWQgMjU2LWJpdCBgSW50YCB2YWx1ZSBgeGAuCi8vLwov" + + "Ly8gVGhlIGFsZ29yaXRobSB3b3JrcyBhcyBmb2xsb3dzOiBmaXJzdCwgdGhlIGBzaGE1MTIocilgIGlzIGNvbXB1dGVkLiBUaGVyZSwgYHJgIGlzIGFuIG9sZAovLy8g" + + "dmFsdWUgb2YgdGhlIHJhbmRvbSBzZWVkLCB3aGljaCBpcyB0YWtlbiBhcyBhIDMyLWJ5dGUgYXJyYXkgY29uc3RydWN0ZWQgZnJvbSB0aGUgYmlnLWVuZGlhbgovLy8g" + + "cmVwcmVzZW50YXRpb24gb2YgYW4gdW5zaWduZWQgMjU2LWJpdCBgSW50YC4gVGhlIGZpcnN0IDMyIGJ5dGVzIG9mIHRoaXMgaGFzaCBhcmUgc3RvcmVkIGFzIHRoZSBu" + + "ZXcKLy8vIHZhbHVlIGByJ2Agb2YgdGhlIHJhbmRvbSBzZWVkLCBhbmQgdGhlIHJlbWFpbmluZyAzMiBieXRlcyBhcmUgcmV0dXJuZWQgYXMgdGhlIG5leHQgcmFuZG9t" + + "IHZhbHVlIGB4YC4KLy8vCi8vLyBgYGB0YWN0Ci8vLyBmdW4gZXhhbXBsZSgpIHsKLy8vICAgICBsZXQgYWxsWW91clJhbmRvbUJlbG9uZ1RvVXM6IEludCA9IHJhbmRv" + + "bUludCgpOyAvLyA/Pz8sIGl0J3MgcmFuZG9tIDopCi8vLyB9Ci8vLyBgYGAKLy8vCi8vLyBTZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLXJh" + + "bmRvbSNyYW5kb21pbnQKLy8vCmlubGluZSBmdW4gcmFuZG9tSW50KCk6IEludCB7CiAgICBuYXRpdmVQcmVwYXJlUmFuZG9tKCk7CiAgICByZXR1cm4gbmF0aXZlUmFu" + + "ZG9tKCk7Cn0KCi8vLyBHZW5lcmF0ZXMgYSBuZXcgcHNldWRvLXJhbmRvbSB1bnNpZ25lZCBgSW50YCB2YWx1ZSBgeGAgaW4gdGhlIHByb3ZpZGVkIHNlbWktY2xvc2Vk" + + "Ci8vLyBpbnRlcnZhbDogYG1pbmAg4omkIGB4YCA8IGBtYXhgLCBvciBgbWluYCDiiaUgYHhgID4gYG1heGAgaWYgYm90aCBgbWluYCBhbmQgYG1heGAgYXJlIG5lZ2F0" + + "aXZlLgovLy8KLy8vIE5vdGUgdGhhdCB0aGUgYG1heGAgdmFsdWUgaXMgbmV2ZXIgaW5jbHVkZWQgaW4gdGhlIGludGVydmFsLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1" + + "biBleGFtcGxlKCkgewovLy8gICAgIHJhbmRvbSg0MiwgNDMpOyAvLyA0MiwgYWx3YXlzCi8vLyAgICAgcmFuZG9tKDAsIDQyKTsgIC8vIDAtNDEsIGJ1dCBuZXZlciA0" + + "MgovLy8gfQovLy8gYGBgCi8vLwovLy8gU2VlOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1yYW5kb20jcmFuZG9tCi8vLwppbmxpbmUgZnVuIHJh" + + "bmRvbShtaW46IEludCwgbWF4OiBJbnQpOiBJbnQgewogICAgbmF0aXZlUHJlcGFyZVJhbmRvbSgpOwogICAgcmV0dXJuIG1pbiArIG5hdGl2ZVJhbmRvbUludGVydmFs" + + "KG1heCAtIG1pbik7Cn0KCi8vIE1hdGgKCi8vLyBHbG9iYWwgZnVuY3Rpb24uCi8vLwovLy8gQ29tcHV0ZXMgdGhlIG1pbmltdW0gb2YgdHdvIGBJbnRgIHZhbHVlcyBg" + + "eGAgYW5kIGB5YC4KLy8vCi8vLyBgYGB0YWN0Ci8vLyBmdW4gZXhhbXBsZXMoKSB7Ci8vLyAgICAgbWluKDEsIDIpOyAgICAgICAgLy8gMQovLy8gICAgIG1pbigyLCAy" + + "KTsgICAgICAgIC8vIDIKLy8vICAgICBtaW4oMDA3LCAzKTsgICAgICAvLyAzCi8vLyAgICAgbWluKDB4NDIsIDNfMF8wKTsgLy8gNjYsIG5pY2UKLy8vICAgICAvLyAg" + + "4oaRICAgICDihpEKLy8vICAgICAvLyAgNjYgICAgMzAwCi8vLyB9Ci8vLyBgYGAKLy8vCi8vLyBTZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3Jl" + + "LW1hdGgjbWluCi8vLwphc20gZnVuIG1pbih4OiBJbnQsIHk6IEludCk6IEludCB7IE1JTiB9CgovLy8gR2xvYmFsIGZ1bmN0aW9uLgovLy8KLy8vIENvbXB1dGVzIHRo" + + "ZSBtYXhpbXVtIG9mIHR3byBgSW50YCB2YWx1ZXMgYHhgIGFuZCBgeWAuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGVzKCkgewovLy8gICAgIG1heCgxLCAy" + + "KTsgICAgICAgIC8vIDIKLy8vICAgICBtYXgoMiwgMik7ICAgICAgICAvLyAyCi8vLyAgICAgbWF4KDAwNywgMyk7ICAgICAgLy8gNwovLy8gICAgIG1heCgweDQ1LCAz" + + "XzBfMCk7IC8vIDMwMAovLy8gICAgIC8vICDihpEgICAgIOKGkQovLy8gICAgIC8vICA2OSAgICAzMDAKLy8vIH0KLy8vIGBgYAovLy8KLy8vIFNlZTogaHR0cHM6Ly9k" + + "b2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtbWF0aCNtYXgKLy8vCmFzbSBmdW4gbWF4KHg6IEludCwgeTogSW50KTogSW50IHsgTUFYIH0KCi8vLyBHbG9iYWwgZnVu" + + "Y3Rpb24uCi8vLwovLy8gQ29tcHV0ZXMgdGhlIGFic29sdXRlIHZhbHVlIG9mIHRoZSBgSW50YCB2YWx1ZSBgeGAuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1w" + + "bGVzKCkgewovLy8gICAgIGFicyg0Mik7ICAgICAgICAvLyA0MgovLy8gICAgIGFicygtNDIpOyAgICAgICAvLyA0MgovLy8gICAgIGFicygtKC0oLTQyKSkpOyAvLyA0" + + "MgovLy8gfQovLy8gYGBgCi8vLwovLy8gLy8vICMjIyMgRXhpdCBjb2RlcwovLy8KLy8vICogNDogW0ludGVnZXIgb3ZlcmZsb3ddIOKAlCBUaHJvd24gd2hlbiB0aGUg" + + "YXJndW1lbnQgZXF1YWxzIHRoZSBtaW5pbXVtIHJlcHJlc2VudGFibGUgaW50ZWdlciwgLTJeMjU2LgovLy8KLy8vIFNlZTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5v" + + "cmcvcmVmL2NvcmUtbWF0aCNhYnMKLy8vCi8vLyBbSW50ZWdlciBvdmVyZmxvd106IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL2Jvb2svZXhpdC1jb2Rlcy8jNAov" + + "Ly8KYXNtIGZ1biBhYnMoeDogSW50KTogSW50IHsgQUJTIH0KCi8vLyBHbG9iYWwgZnVuY3Rpb24uCi8vLwovLy8gQ29tcHV0ZXMgdGhlIGxvZ2FyaXRobSBvZiBhIG51" + + "bWJlciBgbnVtYCA+IDAgdG8gdGhlIGJhc2UgYGJhc2VgIOKJpSAyLiBSZXN1bHRzIGFyZSByb3VuZGVkIGRvd24uCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1w" + + "bGVzKCkgewovLy8gICAgIGxvZygxMDAwLCAxMCk7IC8vIDMsIGFzIDEwXjMgaXMgMTAwMAovLy8gICAgIC8vICDihpEgICAgIOKGkSAgICAgICAgICAgICDihpEgICAg" + + "ICAg4oaRCi8vLyAgICAgLy8gIG51bSAgIGJhc2UgICAgICAgICAgYmFzZSAgICBudW0KLy8vCi8vLyAgICAgbG9nKDEwMDEsIDEwKTsgIC8vIDMKLy8vICAgICBsb2co" + + "OTk5LCAxMCk7ICAgLy8gMgovLy8gICAgIHRyeSB7Ci8vLyAgICAgICAgIGxvZygtMTAwMCwgMTApOyAvLyBleGl0IGNvZGUgNSBiZWNhdXNlIG9mIHRoZSBub24tcG9z" + + "aXRpdmUgbnVtCi8vLyAgICAgfQovLy8gICAgIGxvZygxMDI0LCAyKTsgICAvLyAxMAovLy8gICAgIHRyeSB7Ci8vLyAgICAgICAgIGxvZygxMDI0LCAtMik7ICAvLyBl" + + "eGl0IGNvZGUgNSBiZWNhdXNlIHRoZSBiYXNlIGlzIGxlc3MgdGhhbiAyCi8vLyAgICAgfQovLy8gfQovLy8gYGBgCi8vLwovLy8gIyMjIyBFeGl0IGNvZGVzCi8vLwov" + + "Ly8gKiA1OiBbSW50ZWdlciBvdXQgb2YgZXhwZWN0ZWQgcmFuZ2VdIOKAlCBUaHJvd24gd2hlbiB0aGUgZ2l2ZW4gYG51bWAgdmFsdWUgaXMgbm9uLXBvc2l0aXZlCi8v" + + "LyAgIG9yIHRoZSBnaXZlbiBgYmFzZWAgdmFsdWUgaXMgbGVzcyB0aGFuIDIuCi8vLwovLy8gU2VlOgovLy8gKiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYv" + + "Y29yZS1tYXRoI2xvZwovLy8gKiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1tYXRoI2xvZzIKLy8vCi8vLyBbSW50ZWdlciBvdXQgb2YgZXhwZWN0" + + "ZWQgcmFuZ2VdOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9ib29rL2V4aXQtY29kZXMjNQovLy8KaW5saW5lIGZ1biBsb2cobnVtOiBJbnQsIGJhc2U6IEludCk6" + + "IEludCB7CiAgICB0aHJvd1VubGVzcyg1LCBudW0gPiAwKTsKICAgIHRocm93VW5sZXNzKDUsIGJhc2UgPiAxKTsKICAgIGlmIChudW0gPCBiYXNlKSB7CiAgICAgICAg" + + "cmV0dXJuIDA7CiAgICB9CgogICAgbGV0IHJlc3VsdCA9IDA7CiAgICB3aGlsZSAobnVtID49IGJhc2UpIHsKICAgICAgICBudW0gLz0gYmFzZTsKICAgICAgICByZXN1" + + "bHQgKz0gMTsKICAgIH0KICAgIHJldHVybiByZXN1bHQ7Cn0KCi8vLyBHbG9iYWwgZnVuY3Rpb24uCi8vLwovLy8gU2ltaWxhciB0byBgbG9nKClgLCBidXQgc2V0cyB0" + + "aGUgYGJhc2VgIHRvIDIuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKSB7Ci8vLyAgICAgbG9nMigxMDI0KTsgLy8gMTAsIGFzIDJeMTAgaXMgMTAyNAov" + + "Ly8gICAgIC8vICAg4oaRICAgICAgICAgICAgICAgIOKGkSAgICAgICDihpEKLy8vICAgICAvLyAgIG51bSAgICAgICAgICAgICAgYmFzZeKCgiAgIG51bQovLy8gfQov" + + "Ly8gYGBgCi8vLwovLy8gIyMjIyBFeGl0IGNvZGVzCi8vLwovLy8gKiA1OiBbSW50ZWdlciBvdXQgb2YgZXhwZWN0ZWQgcmFuZ2VdIOKAlCBUaHJvd24gd2hlbiB0aGUg" + + "Z2l2ZW4gYG51bWAgdmFsdWUgaXMgbm9uLXBvc2l0aXZlLgovLy8KLy8vIFNlZToKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtbWF0aCNs" + + "b2cyCi8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLW1hdGgjbG9nLgovLy8KLy8vIFtJbnRlZ2VyIG91dCBvZiBleHBlY3RlZCByYW5nZV06" + + "IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL2Jvb2svZXhpdC1jb2Rlcy8jNQovLy8KYXNtIGZ1biBsb2cyKG51bTogSW50KTogSW50IHsgRFVQIDUgVEhST1dJRk5P" + + "VCBVQklUU0laRSBERUMgfQoKLy8vIEdsb2JhbCBmdW5jdGlvbi4KLy8vCi8vLyBDb21wdXRlcyB0aGUgZXhwb25lbnRpYXRpb24gaW52b2x2aW5nIHR3byBudW1iZXJz" + + "OiB0aGUgYGJhc2VgIGFuZCB0aGUgZXhwb25lbnQgKG9yIF9wb3dlcl8pIGBleHBgLgovLy8KLy8vIFRoaXMgZnVuY3Rpb24gdHJpZXMgdG8gcmVzb2x2ZSBjb25zdGFu" + + "dCB2YWx1ZXMgaW4gY29tcGlsZS10aW1lIHdoZW5ldmVyIHBvc3NpYmxlLgovLy8KLy8vIGBgYHRhY3QKLy8vIGNvbnRyYWN0IEV4YW1wbGUgewovLy8gICAgIC8vIFBl" + + "cnNpc3RlbnQgc3RhdGUgdmFyaWFibGVzCi8vLyAgICAgcDIzOiBJbnQgPSBwb3coMiwgMyk7IC8vIHJhaXNlcyAyIHRvIHRoZSAzcmQgcG93ZXIsIHdoaWNoIGlzIDgK" + + "Ly8vICAgICBvbmU6IEludCA9IHBvdyg1LCAwKTsgLy8gcmFpc2VzIDUgdG8gdGhlIHBvd2VyIDAsIHdoaWNoIGFsd2F5cyBwcm9kdWNlcyAxCi8vLyAgICAgICAgICAg" + + "ICAgICAgICAgICAgICAgIC8vIHdvcmtzIGF0IGNvbXBpbGUtdGltZSEKLy8vCi8vLyAgICAgLy8gSW50ZXJuYWwgbWVzc2FnZSByZWNlaXZlcgovLy8gICAgIHJlY2Vp" + + "dmUoKSB7Ci8vLyAgICAgICAgIHBvdyhzZWxmLnAyMywgc2VsZi5vbmUgKyAxKTsgLy8gNjQsIHdvcmtzIGF0IHJ1bi10aW1lIHRvbyEKLy8vICAgICAgICAgdHJ5IHsK" + + "Ly8vICAgICAgICAgICAgIHBvdygwLCAtMSk7IC8vIGV4aXQgY29kZSA1OiBJbnRlZ2VyIG91dCBvZiBleHBlY3RlZCByYW5nZQovLy8gICAgICAgICB9Ci8vLyAgICAg" + + "fQovLy8gfQovLy8gYGBgCi8vLwovLy8gIyMjIyBFeGl0IGNvZGVzCi8vLwovLy8gKiA0OiBbSW50ZWdlciBvdmVyZmxvd10g4oCUIFRocm93biB3aGVuIHRoZSByZXN1" + + "bHQgZXhjZWVkcyB0aGUgcmFuZ2Ugb2YgcmVwcmVzZW50YWJsZSBpbnRlZ2VycywgaS5lLiBbLTJeMjU2OyAyXjI1NiAtIDFdLgovLy8gKiA1OiBbSW50ZWdlciBvdXQg" + + "b2YgZXhwZWN0ZWQgcmFuZ2VdIOKAlCBUaHJvd24gd2hlbiB0aGUgZ2l2ZW4gYGV4cGAgdmFsdWUgaXMgbmVnYXRpdmUuCi8vLwovLy8gU2VlOgovLy8gKiBodHRwczov" + + "L2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1tYXRoI3BvdwovLy8gKiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1tYXRoI3BvdzIKLy8vCi8v" + + "LyBbSW50ZWdlciBvdmVyZmxvd106IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL2Jvb2svZXhpdC1jb2Rlcy8jNAovLy8gW0ludGVnZXIgb3V0IG9mIGV4cGVjdGVk" + + "IHJhbmdlXTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvYm9vay9leGl0LWNvZGVzLyM1Ci8vLwppbmxpbmUgZnVuIHBvdyhiYXNlOiBJbnQsIGV4cDogSW50KTog" + + "SW50IHsKICAgIHRocm93VW5sZXNzKDUsIGV4cCA+PSAwKTsKICAgIGxldCByZXN1bHQgPSAxOwogICAgcmVwZWF0IChleHApIHsKICAgICAgICByZXN1bHQgKj0gYmFz" + + "ZTsKICAgIH0KICAgIHJldHVybiByZXN1bHQ7Cn0KCi8vLyBHbG9iYWwgZnVuY3Rpb24uCi8vLwovLy8gU2ltaWxhciB0byBgcG93KClgLCBidXQgc2V0cyB0aGUgYGJh" + + "c2VgIHRvIDIuCi8vLwovLy8gVGhpcyBmdW5jdGlvbiB0cmllcyB0byByZXNvbHZlIGNvbnN0YW50IHZhbHVlcyBpbiBjb21waWxlLXRpbWUgd2hlbmV2ZXIgcG9zc2li" + + "bGUuCi8vLwovLy8gYGBgdGFjdAovLy8gY29udHJhY3QgRXhhbXBsZSB7Ci8vLyAgICAgLy8gUGVyc2lzdGVudCBzdGF0ZSB2YXJpYWJsZXMKLy8vICAgICBwMjM6IElu" + + "dCA9IHBvdzIoMyk7IC8vIHJhaXNlcyAyIHRvIHRoZSAzcmQgcG93ZXIsIHdoaWNoIGlzIDgKLy8vICAgICBvbmU6IEludCA9IHBvdzIoMCk7IC8vIHJhaXNlcyAyIHRv" + + "IHRoZSBwb3dlciAwLCB3aGljaCBhbHdheXMgcHJvZHVjZXMgMQovLy8gICAgICAgICAgICAgICAgICAgICAgICAgLy8gd29ya3MgYXQgY29tcGlsZS10aW1lIQovLy8K" + + "Ly8vICAgICAvLyBJbnRlcm5hbCBtZXNzYWdlIHJlY2VpdmVyLCB3aGljaCBhY2NlcHRzIG1lc3NhZ2UgRXh0TXNnCi8vLyAgICAgcmVjZWl2ZSgpIHsKLy8vICAgICAg" + + "ICAgcG93MihzZWxmLm9uZSArIDEpOyAvLyA0LCB3b3JrcyBhdCBydW4tdGltZSB0b28hCi8vLyAgICAgICAgIHRyeSB7Ci8vLyAgICAgICAgICAgICBwb3coLTEpOyAv" + + "LyBleGl0IGNvZGUgNTogSW50ZWdlciBvdXQgb2YgZXhwZWN0ZWQgcmFuZ2UKLy8vICAgICAgICAgfQovLy8gICAgIH0KLy8vIH0KLy8vIGBgYAovLy8KLy8vICMjIyMg" + + "RXhpdCBjb2RlcwovLy8KLy8vICogNDogW0ludGVnZXIgb3ZlcmZsb3ddIOKAlCBUaHJvd24gd2hlbiB0aGUgcmVzdWx0IGV4Y2VlZHMgdGhlIHJhbmdlIG9mIHJlcHJl" + + "c2VudGFibGUgaW50ZWdlcnMsIGkuZS4gWy0yXjI1NjsgMl4yNTYgLSAxXS4KLy8vICogNTogW0ludGVnZXIgb3V0IG9mIGV4cGVjdGVkIHJhbmdlXSDigJQgVGhyb3du" + + "IHdoZW4gYXR0ZW1wdGluZyB0byBzcGVjaWZ5IGEgbmVnYXRpdmUgdmFsdWUgb2YgYGV4cGAuCi8vLwovLy8gU2VlOgovLy8gKiBodHRwczovL2RvY3MudGFjdC1sYW5n" + + "Lm9yZy9yZWYvY29yZS1tYXRoI3BvdzIKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtbWF0aCNwb3cKLy8vCi8vLyBbSW50ZWdlciBvdmVy" + + "Zmxvd106IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL2Jvb2svZXhpdC1jb2Rlcy8jNAovLy8gW0ludGVnZXIgb3V0IG9mIGV4cGVjdGVkIHJhbmdlXTogaHR0cHM6" + + "Ly9kb2NzLnRhY3QtbGFuZy5vcmcvYm9vay9leGl0LWNvZGVzIzUKLy8vCmFzbSBmdW4gcG93MihleHA6IEludCk6IEludCB7IFBPVzIgfQoKLy8vIEdsb2JhbCBmdW5j" + + "dGlvbi4gQXZhaWxhYmxlIHNpbmNlIFRhY3QgMS42LjAuCi8vLwovLy8gQ29tcHV0ZXMgdGhlIHNpZ24gb2YgdGhlIGBJbnRgIHZhbHVlIGB4YC4gUHJvZHVjZXMgMSBp" + + "ZiB0aGUgYHhgIGlzIHBvc2l0aXZlLCAtMSBpZiB0aGUgYHhgIGlzIG5lZ2F0aXZlLCBhbmQgMCBpZiB0aGUgYHhgIGlzIDAuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVu" + + "IGV4YW1wbGVzKCkgewovLy8gICAgIHNpZ24oNDIpOyAgICAgICAgLy8gMQovLy8gICAgIHNpZ24oLTQyKTsgICAgICAgLy8gLTEKLy8vICAgICBzaWduKC0oLTQyKSk7" + + "ICAgIC8vIDEKLy8vICAgICBzaWduKC0oLSgtNDIpKSk7IC8vIC0xCi8vLyAgICAgc2lnbigwKTsgICAgICAgICAvLyAwCi8vLyB9Ci8vLyBgYGAKLy8vCi8vLyBTZWU6" + + "IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLW1hdGgjc2lnbgovLy8KYXNtIGZ1biBzaWduKHg6IEludCk6IEludCB7IFNHTiB9CgovLy8gR2xvYmFs" + + "IGZ1bmN0aW9uLiBBdmFpbGFibGUgc2luY2UgVGFjdCAxLjYuMC4KLy8vCi8vLyBDb21wdXRlcyB0aGUgcm91bmRlZCB1cCByZXN1bHQgb2YgZGl2aXNpb24gb2YgdGhl" + + "IG51bWJlcnMgYHhgIGFuZCBgeWAuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGVzKCkgewovLy8gICAgIGRpdmMoNCwgMik7ICAvLyAyCi8vLyAgICAgZGl2" + + "YygzLCAyKTsgIC8vIDIKLy8vICAgICBkaXZjKC00LCAyKTsgLy8gLTIKLy8vICAgICBkaXZjKC0zLCAyKTsgLy8gLTEKLy8vIH0KLy8vIGBgYAovLy8KLy8vICMjIyMg" + + "RXhpdCBjb2RlcwovLy8KLy8vICogNDogW0ludGVnZXIgb3ZlcmZsb3ddIOKAlCBUaHJvd24gd2hlbiBkaXZpc2lvbiBieSB6ZXJvIGlzIGF0dGVtcHRlZCBvciAtMl4y" + + "NTYgaXMgZGl2aWRlZCBieSAtMS4KLy8vCi8vLyBTZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLW1hdGgjZGl2YwovLy8KLy8vIFtJbnRlZ2Vy" + + "IG92ZXJmbG93XTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvYm9vay9leGl0LWNvZGVzLyM0Ci8vLwphc20gZnVuIGRpdmMoeDogSW50LCB5OiBJbnQpOiBJbnQg" + + "eyBESVZDIH0KCi8vLyBHbG9iYWwgZnVuY3Rpb24uIEF2YWlsYWJsZSBzaW5jZSBUYWN0IDEuNi4wLgovLy8KLy8vIENvbXB1dGVzIHRoZSByb3VuZGVkIHVwIHJlc3Vs" + + "dCBvZiBgKHggKiB5KSAvIHpgLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlcygpIHsKLy8vICAgICBtdWxkaXZjKDQsIDEsIDIpOyAgLy8gMgovLy8gICAg" + + "IG11bGRpdmMoMywgMSwgMik7ICAvLyAyCi8vLyAgICAgbXVsZGl2YygtNCwgMSwgMik7IC8vIC0yCi8vLyAgICAgbXVsZGl2YygtMywgMSwgMik7IC8vIC0xCi8vLyAg" + + "ICAgbXVsZGl2YygtMywgMCwgMik7IC8vIDAKLy8vICAgICBtdWxkaXZjKC0zLCAwLCAwKTsgLy8gRVJST1IhIEV4aXQgY29kZSA0OiBJbnRlZ2VyIG92ZXJmbG93Ci8v" + + "LyB9Ci8vLyBgYGAKLy8vCi8vLyAjIyMjIEV4aXQgY29kZXMKLy8vCi8vLyAqIDQ6IFtJbnRlZ2VyIG92ZXJmbG93XSDigJQgVGhyb3duIHdoZW4gdGhlIHZhbHVlIGlu" + + "IGNhbGN1bGF0aW9uIGdvZXMgYmV5b25kCi8vLyAgIHRoZSByYW5nZSBmcm9tIC0yXjI1NiB0byAyXjI1NiAtIDEgaW5jbHVzaXZlLCBvciBpZiB0aGVyZSdzIGFuIGF0" + + "dGVtcHQgdG8KLy8vICAgZGl2aWRlIGJ5IHplcm8uCi8vLwovLy8gU2VlOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1tYXRoI211bGRpdmMKLy8v" + + "Ci8vLyBbSW50ZWdlciBvdmVyZmxvd106IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL2Jvb2svZXhpdC1jb2Rlcy8jNAovLy8KYXNtIGZ1biBtdWxkaXZjKHg6IElu" + + "dCwgeTogSW50LCB6OiBJbnQpOiBJbnQgeyBNVUxESVZDIH0KCi8vLyBHbG9iYWwgZnVuY3Rpb24uIEF2YWlsYWJsZSBzaW5jZSBUYWN0IDEuNi4wLgovLy8KLy8vIENv" + + "bXB1dGVzIHRoZSByb3VuZGVkIGRvd24gcmVzdWx0IG9mIGAoeCAqIHkpIC8gMl56YC4gSXQgaXMgYSBtb3JlIGdhcy1lZmZpY2llbnQgZXF1aXZhbGVudCBvZiBkb2lu" + + "ZyB0aGUgYml0d2lzZSBzaGlmdCByaWdodCBvbiB0aGUgcmVzdWx0IG9mIG11bHRpcGxpY2F0aW9uIG9mIGB4YCBhbmQgYHlgLCB3aGVyZSBgemAgaXMgdGhlIHJpZ2h0" + + "IG9wZXJhbmQgb2YgdGhlIHNoaWZ0LgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlcygpIHsKLy8vICAgICBtdWxTaGlmdFJpZ2h0KDUsIDUsIDIpOyAgLy8g" + + "NgovLy8gICAgIG11bFNoaWZ0UmlnaHQoNSwgNSwgMSk7ICAvLyAxMgovLy8gICAgIG11bFNoaWZ0UmlnaHQoNSwgNSwgMCk7ICAvLyAyNQovLy8gICAgIG11bFNoaWZ0" + + "UmlnaHQoNSwgNSwgLTEpOyAvLyBFUlJPUiEgRXhpdCBjb2RlIDU6IEludGVnZXIgb3V0IG9mIGV4cGVjdGVkIHJhbmdlCi8vLyB9Ci8vLyBgYGAKLy8vCi8vLyAjIyMj" + + "IEV4aXQgY29kZXMKLy8vCi8vLyAqIDQ6IFtJbnRlZ2VyIG92ZXJmbG93XSDigJQgVGhyb3duIHdoZW4gdGhlIHZhbHVlIGluIGNhbGN1bGF0aW9uIGdvZXMgYmV5b25k" + + "Ci8vLyAgIHRoZSByYW5nZSBmcm9tIC0yXjI1NiB0byAyXjI1NiAtIDEgaW5jbHVzaXZlLgovLy8KLy8vICogNTogW0ludGVnZXIgb3V0IG9mIGV4cGVjdGVkIHJhbmdl" + + "XSDigJQgVGhyb3duIHdoZW4gdGhlIGdpdmVuIGB6YCB2YWx1ZSBpcwovLy8gICBvdXRzaWRlIHRoZSBpbmNsdXNpdmUgcmFuZ2UgZnJvbSAwIHRvIDI1Ni4KLy8vCi8v" + + "LyBTZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLW1hdGgjbXVsc2hpZnRyaWdodAovLy8KLy8vIFtJbnRlZ2VyIG92ZXJmbG93XTogaHR0cHM6" + + "Ly9kb2NzLnRhY3QtbGFuZy5vcmcvYm9vay9leGl0LWNvZGVzLyM0Ci8vLyBbSW50ZWdlciBvdXQgb2YgZXhwZWN0ZWQgcmFuZ2VdOiBodHRwczovL2RvY3MudGFjdC1s" + + "YW5nLm9yZy9ib29rL2V4aXQtY29kZXMvIzUKLy8vCmFzbSBmdW4gbXVsU2hpZnRSaWdodCh4OiBJbnQsIHk6IEludCwgejogSW50KTogSW50IHsgTVVMUlNISUZUIH0K" + + "Ci8vLyBHbG9iYWwgZnVuY3Rpb24uIEF2YWlsYWJsZSBzaW5jZSBUYWN0IDEuNi4wLgovLy8KLy8vIENvbXB1dGVzIGBmbG9vcigoeCAqIHkpIC8gMl56ICsgMC41KWAu" + + "IEl0IGlzIHNpbWlsYXIgdG8gYG11bFNoaWZ0UmlnaHRgLCBidXQgaW5zdGVhZCBvZiByb3VuZGluZyBkb3duLCB0aGUgcmVzdWx0IHZhbHVlIGlzIHJvdW5kZWQgdG8g" + + "dGhlIG5lYXJlc3QgaW50ZWdlciB3aXRoIHJlc3VsdHMgbGlrZSA0Mi41IHJvdW5kZWQgdG8gNDMuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGVzKCkgewov" + + "Ly8gICAgIG11bFNoaWZ0UmlnaHRSb3VuZCg1LCA1LCAyKTsgIC8vIDYKLy8vICAgICBtdWxTaGlmdFJpZ2h0Um91bmQoNSwgNSwgMSk7ICAvLyAxMwovLy8gICAgIG11" + + "bFNoaWZ0UmlnaHRSb3VuZCg1LCA1LCAwKTsgIC8vIDI1Ci8vLyAgICAgbXVsU2hpZnRSaWdodFJvdW5kKDUsIDUsIC0xKTsgLy8gRVJST1IhIEV4aXQgY29kZSA1OiBJ" + + "bnRlZ2VyIG91dCBvZiBleHBlY3RlZCByYW5nZQovLy8gfQovLy8gYGBgCi8vLwovLy8gIyMjIyBFeGl0IGNvZGVzCi8vLwovLy8gKiA0OiBbSW50ZWdlciBvdmVyZmxv" + + "d10g4oCUIFRocm93biB3aGVuIHRoZSB2YWx1ZSBpbiBjYWxjdWxhdGlvbiBnb2VzIGJleW9uZAovLy8gICB0aGUgcmFuZ2UgZnJvbSAtMl4yNTYgdG8gMl4yNTYgLSAx" + + "IGluY2x1c2l2ZS4KLy8vCi8vLyAqIDU6IFtJbnRlZ2VyIG91dCBvZiBleHBlY3RlZCByYW5nZV0g4oCUIFRocm93biB3aGVuIHRoZSBnaXZlbiBgemAgdmFsdWUgaXMK" + + "Ly8vICAgb3V0c2lkZSB0aGUgaW5jbHVzaXZlIHJhbmdlIGZyb20gMCB0byAyNTYuCi8vLwovLy8gU2VlOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29y" + + "ZS1tYXRoI211bHNoaWZ0cmlnaHRyb3VuZAovLy8KLy8vIFtJbnRlZ2VyIG92ZXJmbG93XTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvYm9vay9leGl0LWNvZGVz" + + "LyM0Ci8vLyBbSW50ZWdlciBvdXQgb2YgZXhwZWN0ZWQgcmFuZ2VdOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9ib29rL2V4aXQtY29kZXMvIzUKLy8vCmFzbSBm" + + "dW4gbXVsU2hpZnRSaWdodFJvdW5kKHg6IEludCwgeTogSW50LCB6OiBJbnQpOiBJbnQgeyBNVUxSU0hJRlRSIH0KCi8vLyBHbG9iYWwgZnVuY3Rpb24uIEF2YWlsYWJs" + + "ZSBzaW5jZSBUYWN0IDEuNi4wLgovLy8KLy8vIENvbXB1dGVzIGBjZWlsKCh4ICogeSkgLyAyXnopYC4gU2ltaWxhciB0byBgbXVsU2hpZnRSaWdodCgpYCwgYnV0IGlu" + + "c3RlYWQgb2Ygcm91bmRpbmcgZG93biwgdGhlIHJlc3VsdCB2YWx1ZSBpcyByb3VuZGVkIHVwLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlcygpIHsKLy8v" + + "ICAgICBtdWxTaGlmdFJpZ2h0Q2VpbCg1LCA1LCAyKTsgIC8vIDcKLy8vICAgICBtdWxTaGlmdFJpZ2h0Q2VpbCg1LCA1LCAxKTsgIC8vIDEzCi8vLyAgICAgbXVsU2hp" + + "ZnRSaWdodENlaWwoNSwgNSwgMCk7ICAvLyAyNQovLy8gICAgIG11bFNoaWZ0UmlnaHRDZWlsKDUsIDUsIC0xKTsgLy8gRVJST1IhIEV4aXQgY29kZSA1OiBJbnRlZ2Vy" + + "IG91dCBvZiBleHBlY3RlZCByYW5nZQovLy8gfQovLy8gYGBgCi8vLwovLy8gIyMjIyBFeGl0IGNvZGVzCi8vLwovLy8gKiA0OiBbSW50ZWdlciBvdmVyZmxvd10g4oCU" + + "IFRocm93biB3aGVuIHRoZSB2YWx1ZSBpbiBjYWxjdWxhdGlvbiBnb2VzIGJleW9uZAovLy8gICB0aGUgcmFuZ2UgZnJvbSAtMl4yNTYgdG8gMl4yNTYgLSAxIGluY2x1" + + "c2l2ZS4KLy8vCi8vLyAqIDU6IFtJbnRlZ2VyIG91dCBvZiBleHBlY3RlZCByYW5nZV0g4oCUIFRocm93biB3aGVuIHRoZSBnaXZlbiBgemAgdmFsdWUgaXMKLy8vICAg" + + "b3V0c2lkZSB0aGUgaW5jbHVzaXZlIHJhbmdlIGZyb20gMCB0byAyNTYuCi8vLwovLy8gU2VlOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1tYXRo" + + "I211bHNoaWZ0cmlnaHRjZWlsCi8vLwovLy8gW0ludGVnZXIgb3ZlcmZsb3ddOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9ib29rL2V4aXQtY29kZXMvIzQKLy8v" + + "IFtJbnRlZ2VyIG91dCBvZiBleHBlY3RlZCByYW5nZV06IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL2Jvb2svZXhpdC1jb2Rlcy8jNQovLy8KYXNtIGZ1biBtdWxT" + + "aGlmdFJpZ2h0Q2VpbCh4OiBJbnQsIHk6IEludCwgejogSW50KTogSW50IHsgTVVMUlNISUZUQyB9CgovLy8gR2xvYmFsIGZ1bmN0aW9uLiBBdmFpbGFibGUgc2luY2Ug" + + "VGFjdCAxLjYuMC4KLy8vCi8vLyBDb21wdXRlcyB0aGUgc3F1YXJlIHJvb3Qgb2YgdGhlIGBJbnRgIHZhbHVlIGBudW1gLiBSZXR1cm5zIHRoZSByZXN1bHQgcm91bmRl" + + "ZCB0byB0aGUgbmVhcmVzdCBpbnRlZ2VyLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlcygpIHsKLy8vICAgICBzcXJ0KDQpOyAgLy8gMgovLy8gICAgIHNx" + + "cnQoMyk7ICAvLyAyCi8vLyAgICAgc3FydCgyKTsgIC8vIDEKLy8vICAgICBzcXJ0KDEpOyAgLy8gMQovLy8gICAgIHNxcnQoMCk7ICAvLyAwCi8vLyAgICAgc3FydCgt" + + "MSk7IC8vIEVSUk9SISBFeGl0IGNvZGUgNTogSW50ZWdlciBvdXQgb2YgZXhwZWN0ZWQgcmFuZ2UKLy8vIH0KLy8vIGBgYAovLy8KLy8vICMjIyMgRXhpdCBjb2Rlcwov" + + "Ly8KLy8vICogNTogW0ludGVnZXIgb3V0IG9mIGV4cGVjdGVkIHJhbmdlXSDigJQgVGhyb3duIHdoZW4gYXR0ZW1wdGluZyB0byBzcGVjaWZ5IGEgbmVnYXRpdmUgdmFs" + + "dWUgb2YgYG51bWAuCi8vLwovLy8gU2VlOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1tYXRoI3NxcnQKLy8vCi8vLyBbSW50ZWdlciBvdXQgb2Yg" + + "ZXhwZWN0ZWQgcmFuZ2VdOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9ib29rL2V4aXQtY29kZXMjNQovLy8KZnVuIHNxcnQobnVtOiBJbnQpOiBJbnQgewogICAg" + + "aWYgKG51bSA9PSAwKSB7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgbGV0IHM6IEludCA9IGxvZzIobnVtKTsKICAgIGxldCB4OiBJbnQgPSAocyA9PSAxID8g" + + "KG51bSAtIDEpIC8gMiArIDEgOiAxIDw8ICgocyArIDEpIC8gMikpOwoKICAgIGxldCBxOiBJbnQgPSAwOwoKICAgIGRvIHsKICAgICAgICBxID0gKGRpdmMobnVtLCB4" + + "KSAtIHgpIC8gMjsKICAgICAgICB4ICs9IHE7CiAgICB9IHVudGlsIChxID09IDApOwoKICAgIHJldHVybiB4Owp9Cg=="; files["std/internal/primitives.tact"] = "Ly8vIGBJbnRgIGlzIHRoZSBwcmltaXRpdmUgMjU3LWJpdCBzaWduZWQgaW50ZWdlciB0eXBlLgovLy8KLy8vIFNlZTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcv" + "Ym9vay9pbnRlZ2VycwovLy8KcHJpbWl0aXZlIEludDsKCi8vLyBgQm9vbGAgaXMgdGhlIGNsYXNzaWNhbCBib29sZWFuIHR5cGUsIHdoaWNoIGNhbiBob2xkIG9ubHkg" + @@ -1683,412 +1684,413 @@ files["std/internal/reserve.tact"] = "YWN0LWxhbmcub3JnL3JlZi9jb3JlLWNvbnRleHRzdGF0ZSNuYXRpdmVyZXNlcnZlLW9wdGlvbmFsLWZsYWdzCi8vLwpjb25zdCBSZXNlcnZlQm91bmNlSWZBY3Rpb25G" + "YWlsOiBJbnQgPSAxNjsK"; files["std/internal/send.tact"] = - "Ly8vIE9yZGluYXJ5IG1lc3NhZ2UgKGRlZmF1bHQpLgovLy8KLy8vIFRoaXMgY29uc3RhbnQgaXMgYXZhaWxhYmxlIHNpbmNlIFRhY3QgMS42LjAuCi8vLwovLy8gU2Vl" + - "OiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9ib29rL21lc3NhZ2UtbW9kZSNiYXNlLW1vZGVzCi8vLwpjb25zdCBTZW5kRGVmYXVsdE1vZGU6IEludCA9IDA7Cgov" + - "Ly8gQ2FycnkgYWxsIHRoZSByZW1haW5pbmcgdmFsdWUgb2YgdGhlIGluYm91bmQgbWVzc2FnZSBpbiBhZGRpdGlvbgovLy8gdG8gdGhlIHZhbHVlIGluaXRpYWxseSBp" + - "bmRpY2F0ZWQgaW4gdGhlIG5ldyBtZXNzYWdlLgovLy8KLy8vIFNlZTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvYm9vay9tZXNzYWdlLW1vZGUjYmFzZS1tb2Rl" + - "cwovLy8KY29uc3QgU2VuZFJlbWFpbmluZ1ZhbHVlOiBJbnQgPSA2NDsKCi8vLyBDYXJyeSAqKmFsbCB0aGUgcmVtYWluaW5nIGJhbGFuY2UqKiBvZiB0aGUgY3VycmVu" + - "dCBzbWFydCBjb250cmFjdCBpbnN0ZWFkCi8vLyBvZiB0aGUgdmFsdWUgb3JpZ2luYWxseSBpbmRpY2F0ZWQgaW4gdGhlIG1lc3NhZ2UuCi8vLwovLy8gU2VlOiBodHRw" + - "czovL2RvY3MudGFjdC1sYW5nLm9yZy9ib29rL21lc3NhZ2UtbW9kZSNiYXNlLW1vZGVzCi8vLwpjb25zdCBTZW5kUmVtYWluaW5nQmFsYW5jZTogSW50ID0gMTI4OwoK" + - "Ly8vIERvZXNuJ3Qgc2VuZCB0aGUgbWVzc2FnZSwgb25seSBlc3RpbWF0ZXMgdGhlIGZvcndhcmQgZmVlcwovLy8gaWYgdGhlIG1lc3NhZ2Utc2VuZGluZyBmdW5jdGlv" + - "biBjb21wdXRlcyB0aG9zZS4KLy8vCi8vLyBUaGlzIGNvbnN0YW50IGlzIGF2YWlsYWJsZSBzaW5jZSBUYWN0IDEuNS4wLgovLy8KLy8vIFNlZToKLy8vICogaHR0cHM6" + - "Ly9kb2NzLnRhY3QtbGFuZy5vcmcvYm9vay9tZXNzYWdlLW1vZGUjYmFzZS1tb2RlcwovLy8gKiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9ib29rL3NlbmQjbWVz" + - "c2FnZS1zZW5kaW5nLWZ1bmN0aW9ucwovLy8KY29uc3QgU2VuZE9ubHlFc3RpbWF0ZUZlZTogSW50ID0gMTAyNDsKCi8vLyAqKkRlcHJlY2F0ZWQqKiBzaW5jZSBUYWN0" + - "IDEuNi41LiBVc2UgYFNlbmRQYXlGd2RGZWVzU2VwYXJhdGVseWAgaW5zdGVhZC4KLy8vCi8vLyBQYXkgZm9yd2FyZCBmZWVzIHNlcGFyYXRlbHkgZnJvbSB0aGUgbWVz" + - "c2FnZSB2YWx1ZS4KLy8vCi8vLyBTZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL2Jvb2svbWVzc2FnZS1tb2RlI29wdGlvbmFsLWZsYWdzCi8vLwpjb25zdCBT" + - "ZW5kUGF5R2FzU2VwYXJhdGVseTogSW50ID0gMTsKCi8vLyBQYXkgZm9yd2FyZCBmZWVzIHNlcGFyYXRlbHkgZnJvbSB0aGUgbWVzc2FnZSB2YWx1ZS4KLy8vCi8vLyBT" + - "ZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL2Jvb2svbWVzc2FnZS1tb2RlI29wdGlvbmFsLWZsYWdzCi8vLwpjb25zdCBTZW5kUGF5RndkRmVlc1NlcGFyYXRl" + - "bHk6IEludCA9IDE7CgovLy8gSWdub3JlIGFueSBlcnJvcnMgYXJpc2luZyB3aGlsZSBwcm9jZXNzaW5nIHRoaXMgbWVzc2FnZSBkdXJpbmcgdGhlIGFjdGlvbiBwaGFz" + - "ZS4KLy8vCi8vLyBTZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL2Jvb2svbWVzc2FnZS1tb2RlI29wdGlvbmFsLWZsYWdzCi8vLwpjb25zdCBTZW5kSWdub3Jl" + - "RXJyb3JzOiBJbnQgPSAyOwoKLy8vIEJvdW5jZSB0cmFuc2FjdGlvbiBpbiBjYXNlIG9mIGFueSBlcnJvcnMgZHVyaW5nIGFjdGlvbiBwaGFzZS4KLy8vIEhhcyBubyBl" + - "ZmZlY3QgaWYgZmxhZyArMiwgYFNlbmRJZ25vcmVFcnJvcnNgIGlzIHVzZWQuCi8vLwovLy8gU2VlOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9ib29rL21lc3Nh" + - "Z2UtbW9kZSNvcHRpb25hbC1mbGFncwovLy8KY29uc3QgU2VuZEJvdW5jZUlmQWN0aW9uRmFpbDogSW50ID0gMTY7CgovLy8gQ3VycmVudCBhY2NvdW50IChjb250cmFj" + - "dCkgd2lsbCBiZSBkZXN0cm95ZWQgaWYgaXRzIHJlc3VsdGluZyBiYWxhbmNlIGlzIHplcm8uCi8vLyBUaGlzIGZsYWcgaXMgb2Z0ZW4gdXNlZCB3aXRoIG1vZGUgMTI4" + - "LCBgU2VuZFJlbWFpbmluZ0JhbGFuY2VgLgovLy8KLy8vIFNlZTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvYm9vay9tZXNzYWdlLW1vZGUjb3B0aW9uYWwtZmxh" + - "Z3MKLy8vCmNvbnN0IFNlbmREZXN0cm95SWZaZXJvOiBJbnQgPSAzMjsKCi8vLyBTdHJ1Y3QgZm9yIHNwZWNpZnlpbmcgdGhlIG1lc3NhZ2UgcGFyYW1ldGVycyBvZiB0" + - "aGUgYHNlbmQoKWAgZnVuY3Rpb24uCi8vLwovLy8gU2VlOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1zZW5kI3NlbmQKLy8vCnN0cnVjdCBTZW5k" + - "UGFyYW1ldGVycyB7CiAgICAvLy8gQW4gOC1iaXQgdmFsdWUgdGhhdCBjb25maWd1cmVzIGhvdyB0byBzZW5kIGEgbWVzc2FnZSwgZGVmYXVsdHMgdG8gMC4KICAgIC8v" + - "LyBTZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL2Jvb2svbWVzc2FnZS1tb2RlCiAgICBtb2RlOiBJbnQgPSBTZW5kRGVmYXVsdE1vZGU7CgogICAgLy8vIE9w" + - "dGlvbmFsIG1lc3NhZ2UgYm9keSBhcyBhIGBDZWxsYC4KICAgIGJvZHk6IENlbGw/ID0gbnVsbDsKCiAgICAvLy8gT3B0aW9uYWwgaW5pdGlhbCBjb2RlIG9mIHRoZSBj" + - "b250cmFjdCAoY29tcGlsZWQgYml0Y29kZSkuCiAgICBjb2RlOiBDZWxsPyA9IG51bGw7CgogICAgLy8vIE9wdGlvbmFsIGluaXRpYWwgZGF0YSBvZiB0aGUgY29udHJh" + - "Y3QgKGFyZ3VtZW50cyBvZiBgaW5pdCgpYCBmdW5jdGlvbiBvciB2YWx1ZXMgb2YgY29udHJhY3QgcGFyYW1ldGVycykuCiAgICBkYXRhOiBDZWxsPyA9IG51bGw7Cgog" + - "ICAgLy8vIFRoZSBhbW91bnQgb2YgbmFub1RvbmNvaW5zIHlvdSB3YW50IHRvIHNlbmQgd2l0aAogICAgLy8vIHRoZSBtZXNzYWdlLiBUaGlzIHZhbHVlIGlzIHVzZWQg" + - "dG8gY292ZXIgZm9yd2FyZCBmZWVzLAogICAgLy8vIHVubGVzcyB0aGUgb3B0aW9uYWwgZmxhZyBgU2VuZFBheUZ3ZEZlZXNTZXBhcmF0ZWx5YCBpcyB1c2VkLgogICAg" + - "dmFsdWU6IEludDsKCiAgICAvLy8gUmVjaXBpZW50IGludGVybmFsIGBBZGRyZXNzYCBvbiBUT04gQmxvY2tjaGFpbi4KICAgIHRvOiBBZGRyZXNzOwoKICAgIC8vLyBX" + - "aGVuIHNldCB0byBgdHJ1ZWAgKGRlZmF1bHQpIG1lc3NhZ2UgYm91bmNlcyBiYWNrIHRvIHRoZSBzZW5kZXIgaWYKICAgIC8vLyB0aGUgcmVjaXBpZW50IGNvbnRyYWN0" + - "IGRvZXNuJ3QgZXhpc3Qgb3Igd2Fzbid0IGFibGUgdG8gcHJvY2VzcyB0aGUgbWVzc2FnZS4KICAgIGJvdW5jZTogQm9vbCA9IHRydWU7Cn0KCi8vLyBTdHJ1Y3QgZm9y" + - "IHNwZWNpZnlpbmcgdGhlIG1lc3NhZ2UgcGFyYW1ldGVycyBvZiB0aGUgYG1lc3NhZ2UoKWAgZnVuY3Rpb24uIEF2YWlsYWJsZSBzaW5jZSBUYWN0IDEuNi4wLgovLy8K" + - "Ly8vIFNlZTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtc2VuZCNtZXNzYWdlCi8vLwpzdHJ1Y3QgTWVzc2FnZVBhcmFtZXRlcnMgewogICAgLy8v" + - "IEFuIDgtYml0IHZhbHVlIHRoYXQgY29uZmlndXJlcyBob3cgdG8gc2VuZCBhIG1lc3NhZ2UsIGRlZmF1bHRzIHRvIDAuCiAgICAvLy8gU2VlOiBodHRwczovL2RvY3Mu" + - "dGFjdC1sYW5nLm9yZy9ib29rL21lc3NhZ2UtbW9kZQogICAgbW9kZTogSW50ID0gU2VuZERlZmF1bHRNb2RlOwoKICAgIC8vLyBPcHRpb25hbCBtZXNzYWdlIGJvZHkg" + - "YXMgYSBgQ2VsbGAuCiAgICBib2R5OiBDZWxsPyA9IG51bGw7CgogICAgLy8vIFRoZSBhbW91bnQgb2YgbmFub1RvbmNvaW5zIHlvdSB3YW50IHRvIHNlbmQgd2l0aAog" + - "ICAgLy8vIHRoZSBtZXNzYWdlLiBUaGlzIHZhbHVlIGlzIHVzZWQgdG8gY292ZXIgZm9yd2FyZCBmZWVzLAogICAgLy8vIHVubGVzcyB0aGUgb3B0aW9uYWwgZmxhZyBg" + - "U2VuZFBheUZ3ZEZlZXNTZXBhcmF0ZWx5YCBpcyB1c2VkLgogICAgdmFsdWU6IEludDsKCiAgICAvLy8gUmVjaXBpZW50IGludGVybmFsIGBBZGRyZXNzYCBvbiBUT04g" + - "QmxvY2tjaGFpbi4KICAgIHRvOiBBZGRyZXNzOwoKICAgIC8vLyBXaGVuIHNldCB0byBgdHJ1ZWAgKGRlZmF1bHQpIG1lc3NhZ2UgYm91bmNlcyBiYWNrIHRvIHRoZSBz" + - "ZW5kZXIgaWYKICAgIC8vLyB0aGUgcmVjaXBpZW50IGNvbnRyYWN0IGRvZXNuJ3QgZXhpc3Qgb3Igd2Fzbid0IGFibGUgdG8gcHJvY2VzcyB0aGUgbWVzc2FnZS4KICAg" + - "IGJvdW5jZTogQm9vbCA9IHRydWU7Cn0KCi8vLyBHbG9iYWwgZnVuY3Rpb24uIEF2YWlsYWJsZSBzaW5jZSBUYWN0IDEuNi4wLgovLy8KLy8vIFF1ZXVlcyB0aGUgbWVz" + - "c2FnZSB0byBiZSBzZW50IHVzaW5nIHRoZSBgTWVzc2FnZVBhcmFtZXRlcnNgIHN0cnVjdC4gQWxsb3dzIGZvciBjaGVhcGVyIG5vbi1kZXBsb3ltZW50LCByZWd1bGFy" + - "IG1lc3NhZ2VzIGNvbXBhcmVkIHRvIHRoZSBgc2VuZCgpYCBmdW5jdGlvbi4KLy8vCi8vLyBUaGUgYE1lc3NhZ2VQYXJhbWV0ZXJzYCBzdHJ1Y3QgaXMgc2ltaWxhciB0" + - "byBgU2VuZFBhcmFtZXRlcnNgIHN0cnVjdCwgYnV0IHdpdGhvdXQgdGhlIGBjb2RlYCBhbmQgYGRhdGFgIGZpZWxkcy4KLy8vCi8vLyBgYGB0YWN0Ci8vLyBmdW4gZXhh" + - "bXBsZSgpIHsKLy8vICAgICBtZXNzYWdlKE1lc3NhZ2VQYXJhbWV0ZXJzewovLy8gICAgICAgICB0bzogc2VuZGVyKCksICAgIC8vIGJhY2sgdG8gdGhlIHNlbmRlciwK" + - "Ly8vICAgICAgICAgdmFsdWU6IHRvbigiMSIpLCAvLyB3aXRoIDEgVG9uY29pbiAoMV8wMDBfMDAwXzAwMCBuYW5vVG9uY29pbiksCi8vLyAgICAgICAgICAgICAgICAg" + - "ICAgICAgICAgLy8gYW5kIG5vIG1lc3NhZ2UgYm9keQovLy8gICAgIH0pOwovLy8gfQovLy8gYGBgCi8vLwovLy8gIyMjIyBFeGl0IGNvZGVzCi8vLwovLy8gKiAzMzog" + - "W0FjdGlvbiBsaXN0IGlzIHRvbyBsb25nXSDigJQgVGhyb3duIHdoZW4gYXR0ZW1wdGluZyB0byBxdWV1ZSBtb3JlIHRoYW4gMjU1IG1lc3NhZ2VzLgovLy8KLy8vIFNl" + - "ZToKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtc2VuZCNtZXNzYWdlCi8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL2Jvb2sv" + - "bWVzc2FnZS1tb2RlCi8vLwovLy8gW0FjdGlvbiBsaXN0IGlzIHRvbyBsb25nXTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvYm9vay9leGl0LWNvZGVzIzMzCi8v" + - "Lwphc20gZnVuIG1lc3NhZ2UocGFyYW1zOiBNZXNzYWdlUGFyYW1ldGVycykgewogICAgTkVXQwogICAgYnswMX0gU1RTTElDRUNPTlNUICAvLyBzdG9yZSB0YWcgPSAk" + - "MCBhbmQgaWhyX2Rpc2FibGVkID0gdHJ1ZQogICAgMSBTVEkgICAgICAgICAgICAgICAvLyBzdG9yZSBgYm91bmNlYAogICAgYnswMDB9IFNUU0xJQ0VDT05TVCAvLyBz" + - "dG9yZSBib3VuY2VkID0gZmFsc2UgYW5kIHNyYyA9IGFkZHJfbm9uZQogICAgU1RTTElDRSAgICAgICAgICAgICAvLyBzdG9yZSBgdG9gCiAgICBTV0FQCiAgICBTVEdS" + - "QU1TICAgICAgICAgICAgIC8vIHN0b3JlIGB2YWx1ZWAKICAgIDEwNiBQVVNISU5UICAgICAgICAgLy8gMSArIDQgKyA0ICsgNjQgKyAzMiArIDEKICAgIFNUWkVST0VT" + - "CiAgICAvLyDihpIgU3RhY2sgc3RhdGUKICAgIC8vIHMwOiBCdWlsZGVyCiAgICAvLyBzMTogYGJvZHlgCiAgICAvLyBzMjogYG1vZGVgCiAgICBTVERJQ1QKICAgIEVO" + - "REMKICAgIFNXQVAKICAgIFNFTkRSQVdNU0cKfQoKLy8vIEdsb2JhbCBmdW5jdGlvbi4gUXVldWVzIHRoZSBtZXNzYWdlIHRvIGJlIHNlbnQgdXNpbmcgYSBgU2VuZFBh" + - "cmFtZXRlcnNgIHN0cnVjdC4KLy8vCi8vLyBgYGB0YWN0Ci8vLyBmdW4gZXhhbXBsZSgpIHsKLy8vICAgICBzZW5kKFNlbmRQYXJhbWV0ZXJzewovLy8gICAgICAgICB0" + - "bzogc2VuZGVyKCksICAgIC8vIGJhY2sgdG8gdGhlIHNlbmRlciwKLy8vICAgICAgICAgdmFsdWU6IHRvbigiMSIpLCAvLyB3aXRoIDEgVG9uY29pbiAoMV8wMDBfMDAw" + - "XzAwMCBuYW5vVG9uY29pbiksCi8vLyAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYW5kIG5vIG1lc3NhZ2UgYm9keQovLy8gICAgIH0pOwovLy8gfQovLy8gYGBg" + - "Ci8vLwovLy8gIyMjIyBFeGl0IGNvZGVzCi8vLwovLy8gKiAzMzogW0FjdGlvbiBsaXN0IGlzIHRvbyBsb25nXSDigJQgVGhyb3duIHdoZW4gYXR0ZW1wdGluZyB0byBx" + - "dWV1ZSBtb3JlIHRoYW4gMjU1IG1lc3NhZ2VzLgovLy8KLy8vIFNlZTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtc2VuZCNzZW5kCi8vLwovLy8g" + - "W0FjdGlvbiBsaXN0IGlzIHRvbyBsb25nXTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvYm9vay9leGl0LWNvZGVzIzMzCi8vLwphc20gZnVuIHNlbmQocGFyYW1z" + - "OiBTZW5kUGFyYW1ldGVycykgewogICAgLy8gSW5zdHJ1Y3Rpb25zIGFyZSBncm91cGVkLCBhbmQgdGhlIHN0YWNrIHN0YXRlcyB0aGV5IHByb2R1Y2UgYXMgYSBncm91" + - "cCBhcmUgc2hvd24gcmlnaHQgYWZ0ZXIuCiAgICAvLyBJbiB0aGUgZW5kLCBvdXIgbWVzc2FnZSBDZWxsIHNob3VsZCBoYXZlIHRoZSBmb2xsb3dpbmcgVEwtQiBzdHJ1" + - "Y3R1cmU6CiAgICAvLyBtZXNzYWdlJF8ge1g6VHlwZX0KICAgIC8vICAgaW5mbzpDb21tb25Nc2dJbmZvUmVsYXhlZAogICAgLy8gICBpbml0OihNYXliZSAoRWl0aGVy" + - "IFN0YXRlSW5pdCBeU3RhdGVJbml0KSkKICAgIC8vICAgYm9keTooRWl0aGVyIFggXlgpCiAgICAvLyA9IE1lc3NhZ2VSZWxheGVkIFg7CgogICAgLy8g4oaSIFN0YWNr" + - "IHN0YXRlCiAgICAvLyBzMDogYHBhcmFtcy5ib3VuY2VgCiAgICAvLyBzMTogYHBhcmFtcy50b2AKICAgIC8vIHMyOiBgcGFyYW1zLnZhbHVlYAogICAgLy8gczM6IGBw" + - "YXJhbXMuZGF0YWAKICAgIC8vIHM0OiBgcGFyYW1zLmNvZGVgCiAgICAvLyBzNTogYHBhcmFtcy5ib2R5YAogICAgLy8gczY6IGBwYXJhbXMubW9kZWAKICAgIC8vIEZv" + - "ciBicmV2aXR5LCB0aGUgInBhcmFtcyIgcHJlZml4IHdpbGwgYmUgb21pdHRlZCBmcm9tIG5vdyBvbi4KCiAgICAvLyBHcm91cCAxOiBTdG9yaW5nIHRoZSBgYm91bmNl" + - "YCwgYHRvYCBhbmQgYHZhbHVlYCBpbnRvIGEgQnVpbGRlcgogICAgTkVXQwogICAgYnswMX0gU1RTTElDRUNPTlNUICAvLyBzdG9yZSB0YWcgPSAkMCBhbmQgaWhyX2Rp" + - "c2FibGVkID0gdHJ1ZQogICAgMSBTVEkgICAgICAgICAgICAgICAvLyBzdG9yZSBgYm91bmNlYAogICAgYnswMDB9IFNUU0xJQ0VDT05TVCAvLyBzdG9yZSBib3VuY2Vk" + - "ID0gZmFsc2UgYW5kIHNyYyA9IGFkZHJfbm9uZQogICAgU1RTTElDRSAgICAgICAgICAgICAvLyBzdG9yZSBgdG9gCiAgICBTV0FQCiAgICBTVEdSQU1TICAgICAgICAg" + - "ICAgIC8vIHN0b3JlIGB2YWx1ZWAKICAgIDEwNSBQVVNISU5UICAgICAgICAgLy8gMSArIDQgKyA0ICsgNjQgKyAzMgogICAgU1RaRVJPRVMgICAgICAgICAgICAvLyBz" + - "dG9yZSBjdXJyZW5jeV9jb2xsZWN0aW9uLCBpaHJfZmVlLCBmd2RfZmVlLCBjcmVhdGVkX2x0IGFuZCBjcmVhdGVkX2F0CiAgICAvLyDihpIgU3RhY2sgc3RhdGUKICAg" + - "IC8vIHMwOiBCdWlsZGVyCiAgICAvLyBzMTogYGRhdGFgCiAgICAvLyBzMjogYGNvZGVgCiAgICAvLyBzMzogYGJvZHlgCiAgICAvLyBzNDogYG1vZGVgCgogICAgLy8g" + - "R3JvdXAgMjogUGxhY2luZyB0aGUgQnVpbGRlciBhZnRlciBjb2RlIGFuZCBkYXRhLCB0aGVuIGNoZWNraW5nIHRob3NlIGZvciBudWxsYWJpbGl0eQogICAgczIgWENI" + - "RzAKICAgIERVUDIKICAgIElTTlVMTAogICAgU1dBUAogICAgSVNOVUxMCiAgICBBTkQKICAgIC8vIOKGkiBTdGFjayBzdGF0ZQogICAgLy8gczA6IC0xICh0cnVlKSBp" + - "ZiBgZGF0YWAgYW5kIGBjb2RlYCBhcmUgYm90aCBudWxsLCAwIChmYWxzZSkgb3RoZXJ3aXNlCiAgICAvLyBzMTogYGNvZGVgCiAgICAvLyBzMjogYGRhdGFgCiAgICAv" + - "LyBzMzogQnVpbGRlcgogICAgLy8gczQ6IGBib2R5YAogICAgLy8gczU6IGBtb2RlYAoKICAgIC8vIEdyb3VwIDM6IExlZnQgYnJhbmNoIG9mIHRoZSBJRkVMU0UsIGV4" + - "ZWN1dGVkIGlmIHMwIGlzIC0xICh0cnVlKQogICAgPHsKICAgICAgICBEUk9QMiAvLyBkcm9wIGBkYXRhYCBhbmQgYGNvZGVgLCBzaW5jZSBlaXRoZXIgb2YgdGhvc2Ug" + - "aXMgbnVsbAogICAgICAgIGJ7MH0gU1RTTElDRUNPTlNUCiAgICB9PiBQVVNIQ09OVAoKICAgIC8vIEdyb3VwIDM6IFJpZ2h0IGJyYW5jaCBvZiB0aGUgSUZFTFNFLCBl" + - "eGVjdXRlZCBpZiBzMCBpcyAwIChmYWxzZSkKICAgIDx7CiAgICAgICAgLy8gXyBzcGxpdF9kZXB0aDooTWF5YmUgKCMjIDUpKQogICAgICAgIC8vICAgc3BlY2lhbDoo" + - "TWF5YmUgVGlja1RvY2spCiAgICAgICAgLy8gICBjb2RlOihNYXliZSBeQ2VsbCkKICAgICAgICAvLyAgIGRhdGE6KE1heWJlIF5DZWxsKQogICAgICAgIC8vICAgbGli" + - "cmFyeTooTWF5YmUgXkNlbGwpCiAgICAgICAgLy8gPSBTdGF0ZUluaXQ7CiAgICAgICAgUk9UICAgICAgICAgICAgICAgIC8vIHBsYWNlIG1lc3NhZ2UgQnVpbGRlciBv" + - "biB0b3AKICAgICAgICBiezEwfSBTVFNMSUNFQ09OU1QgLy8gc3RvcmUgTWF5YmUgPSB0cnVlLCBFaXRoZXIgPSBmYWxzZQogICAgICAgIC8vIFN0YXJ0IGNvbXBvc2lu" + - "ZyBpbmxpbmVkIFN0YXRlSW5pdAogICAgICAgIGJ7MDB9IFNUU0xJQ0VDT05TVCAvLyBzdG9yZSBzcGxpdF9kZXB0aCBhbmQgc3BlY2lhbCBmaXJzdAogICAgICAgIFNU" + - "RElDVCAgICAgICAgICAgICAvLyBzdG9yZSBjb2RlCiAgICAgICAgU1RESUNUICAgICAgICAgICAgIC8vIHN0b3JlIGRhdGEKICAgICAgICBiezB9IFNUU0xJQ0VDT05T" + - "VCAgLy8gc3RvcmUgbGlicmFyeQogICAgfT4gUFVTSENPTlQKCiAgICAvLyBHcm91cCAzOiBJRkVMU0UgdGhhdCBkb2VzIHRoZSBicmFuY2hpbmcgc2hvd24gYWJvdmUK" + - "ICAgIElGRUxTRQogICAgLy8g4oaSIFN0YWNrIHN0YXRlCiAgICAvLyBzMDogQnVpbGRlcgogICAgLy8gczE6IG51bGwgb3IgU3RhdGVJbml0CiAgICAvLyBzMjogYGJv" + - "ZHlgCiAgICAvLyBzMzogYG1vZGVgCgogICAgLy8gR3JvdXAgNDogRmluYWxpemluZyB0aGUgbWVzc2FnZQogICAgU1RESUNUIC8vIHN0b3JlIGBib2R5YCBhcyByZWYg" + - "d2l0aCBhbiBleHRyYSBNYXliZSBiaXQsIHNpbmNlIGBib2R5YCBtaWdodCBiZSBudWxsCiAgICBFTkRDCiAgICAvLyDihpIgU3RhY2sgc3RhdGUKICAgIC8vIHMwOiBD" + - "ZWxsCiAgICAvLyBzMTogYG1vZGVgCgogICAgLy8gR3JvdXAgNTogU2VuZGluZyB0aGUgbWVzc2FnZSwgd2l0aCBgbW9kZWAgb24gdG9wCiAgICBTV0FQCiAgICBTRU5E" + - "UkFXTVNHIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS90YWN0LWxhbmcvdGFjdC9pc3N1ZXMvMTU1OAp9CgovLy8gU3RydWN0IGZvciBzcGVjaWZ5aW5nIHRoZSBkZXBsb3lt" + - "ZW50IG1lc3NhZ2UgcGFyYW1ldGVycyBvZiB0aGUgYGRlcGxveSgpYCBmdW5jdGlvbi4gQXZhaWxhYmxlIHNpbmNlIFRhY3QgMS42LjAuCi8vLwovLy8gU2VlOiBodHRw" + - "czovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1zZW5kI2RlcGxveQovLy8Kc3RydWN0IERlcGxveVBhcmFtZXRlcnMgewogICAgLy8vIEFuIDgtYml0IHZhbHVl" + - "IHRoYXQgY29uZmlndXJlcyBob3cgdG8gc2VuZCBhIG1lc3NhZ2UsIGRlZmF1bHRzIHRvIDAuCiAgICAvLy8gU2VlOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9i" + - "b29rL21lc3NhZ2UtbW9kZQogICAgbW9kZTogSW50ID0gU2VuZERlZmF1bHRNb2RlOwoKICAgIC8vLyBPcHRpb25hbCBtZXNzYWdlIGJvZHkgYXMgYSBgQ2VsbGAuCiAg" + - "ICBib2R5OiBDZWxsPyA9IG51bGw7CgogICAgLy8vIFRoZSBhbW91bnQgb2YgbmFub1RvbmNvaW5zIHlvdSB3YW50IHRvIHNlbmQgd2l0aAogICAgLy8vIHRoZSBtZXNz" + - "YWdlLiBUaGlzIHZhbHVlIGlzIHVzZWQgdG8gY292ZXIgZm9yd2FyZCBmZWVzLAogICAgLy8vIHVubGVzcyB0aGUgb3B0aW9uYWwgZmxhZyBgU2VuZFBheUZ3ZEZlZXNT" + - "ZXBhcmF0ZWx5YCBpcyB1c2VkLgogICAgdmFsdWU6IEludDsKCiAgICAvLy8gV2hlbiBzZXQgdG8gYHRydWVgIChkZWZhdWx0KSBtZXNzYWdlIGJvdW5jZXMgYmFjayB0" + - "byB0aGUgc2VuZGVyIGlmCiAgICAvLy8gdGhlIHJlY2lwaWVudCBjb250cmFjdCBkb2Vzbid0IGV4aXN0IG9yIHdhc24ndCBhYmxlIHRvIHByb2Nlc3MgdGhlIG1lc3Nh" + - "Z2UuCiAgICBib3VuY2U6IEJvb2wgPSB0cnVlOwoKICAgIC8vLyBJbml0aWFsIHBhY2thZ2Ugb2YgdGhlIGNvbnRyYWN0IChpbml0aWFsIGNvZGUgYW5kIGluaXRpYWwg" + - "ZGF0YSkuCiAgICAvLy8gU2VlOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9ib29rL2V4cHJlc3Npb25zI2luaXRvZgogICAgaW5pdDogU3RhdGVJbml0Owp9Cgov" + - "Ly8gR2xvYmFsIGZ1bmN0aW9uLiBBdmFpbGFibGUgc2luY2UgVGFjdCAxLjYuMC4KLy8vCi8vLyBRdWV1ZXMgdGhlIGNvbnRyYWN0IGRlcGxveW1lbnQgbWVzc2FnZSB0" + - "byBiZSBzZW50IHVzaW5nIHRoZSBgRGVwbG95UGFyYW1ldGVyc2Agc3RydWN0LiBBbGxvd3MgZm9yIGNoZWFwZXIgb24tY2hhaW4gZGVwbG95bWVudHMgY29tcGFyZWQg" + - "dG8gdGhlIGBzZW5kKClgIGZ1bmN0aW9uLgovLy8KLy8vIFRoZSBgRGVwbG95UGFyYW1ldGVyc2Agc3RydWN0IGNvbnNpc3RzIG9mIHRoZSBmb2xsb3dpbmcgZmllbGRz" + - "OgovLy8gKiBgbW9kZTogSW50YCwgYW4gOC1iaXQgdmFsdWUgdGhhdCBjb25maWd1cmVzIGhvdyB0byBzZW5kIGEgbWVzc2FnZSwgZGVmYXVsdHMgdG8gMC4KLy8vICog" + - "YGJvZHk6IENlbGw/YCwgb3B0aW9uYWwgbWVzc2FnZSBib2R5IGFzIGEgYENlbGxgLgovLy8gKiBgdmFsdWU6IEludGAsIHRoZSBhbW91bnQgb2YgbmFub1RvbmNvaW5z" + - "IHlvdSB3YW50IHRvIHNlbmQgd2l0aCB0aGUgbWVzc2FnZS4KLy8vICAgVGhpcyB2YWx1ZSBpcyB1c2VkIHRvIGNvdmVyIGZvcndhcmQgZmVlcywgdW5sZXNzIHRoZSBv" + - "cHRpb25hbCBmbGFnIGBTZW5kUGF5RndkRmVlc1NlcGFyYXRlbHlgIGlzIHVzZWQuCi8vLyAqIGBib3VuY2U6IEJvb2xgLCB3aGVuIHNldCB0byBgdHJ1ZWAgKGRlZmF1" + - "bHQpIG1lc3NhZ2UgYm91bmNlcyBiYWNrIHRvIHRoZSBzZW5kZXIKLy8vICAgIGlmIHRoZSByZWNpcGllbnQgY29udHJhY3QgZG9lc24ndCBleGlzdCBvciB3YXNuJ3Qg" + - "YWJsZSB0byBwcm9jZXNzIHRoZSBtZXNzYWdlLgovLy8gKiBgaW5pdDogU3RhdGVJbml0YCwgaW5pdCBwYWNrYWdlIG9mIHRoZSBjb250cmFjdCAoaW5pdGlhbCBjb2Rl" + - "IGFuZCBpbml0aWFsIGRhdGEpLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAgIGRlcGxveShEZXBsb3lQYXJhbWV0ZXJzewovLy8gICAg" + - "ICAgICBpbml0OiBpbml0T2YgU29tZUNvbnRyYWN0KCksIC8vIHdpdGggaW5pdGlhbCBjb2RlIGFuZCBkYXRhIG9mIFNvbWVDb250cmFjdAovLy8gICAgICAgICAgICAg" + - "ICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFuZCBubyBhZGRpdGlvbmFsIG1lc3NhZ2UgYm9keQovLy8gICAgICAgICBtb2RlOiBTZW5kSWdub3JlRXJyb3JzLCAg" + - "ICAgIC8vIHNraXAgdGhlIG1lc3NhZ2UgaW4gY2FzZSBvZiBlcnJvcnMKLy8vICAgICAgICAgdmFsdWU6IHRvbigiMSIpLCAgICAgICAgICAgICAvLyBzZW5kIDEgVG9u" + - "Y29pbiAoMV8wMDBfMDAwXzAwMCBuYW5vVG9uY29pbikKLy8vICAgICB9KTsKLy8vIH0KLy8vIGBgYAovLy8KLy8vICMjIyMgRXhpdCBjb2RlcwovLy8KLy8vICogMzM6" + - "IFtBY3Rpb24gbGlzdCBpcyB0b28gbG9uZ10g4oCUIFRocm93biB3aGVuIGF0dGVtcHRpbmcgdG8gcXVldWUgbW9yZSB0aGFuIDI1NSBtZXNzYWdlcy4KLy8vCi8vLyBT" + - "ZWU6Ci8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLXNlbmQjZGVwbG95Ci8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL2Jvb2sv" + - "bWVzc2FnZS1tb2RlCi8vLwovLy8gW0FjdGlvbiBsaXN0IGlzIHRvbyBsb25nXTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvYm9vay9leGl0LWNvZGVzIzMzCi8v" + - "Lwphc20gZnVuIGRlcGxveShwYXJhbXM6IERlcGxveVBhcmFtZXRlcnMpIHsKICAgIC8vIEluc3RydWN0aW9ucyBhcmUgZ3JvdXBlZCwgYW5kIHRoZSBzdGFjayBzdGF0" + - "ZXMgdGhleSBwcm9kdWNlIGFzIGEgZ3JvdXAgYXJlIHNob3duIHJpZ2h0IGFmdGVyLgogICAgLy8KICAgIC8vIOKGkiBTdGFjayBzdGF0ZQogICAgLy8gczA6IGBwYXJh" + - "bXMuaW5pdC5kYXRhYAogICAgLy8gczE6IGBwYXJhbXMuaW5pdC5jb2RlYAogICAgLy8gczI6IGBwYXJhbXMuYm91bmNlYAogICAgLy8gczM6IGBwYXJhbXMudmFsdWVg" + - "CiAgICAvLyBzNDogYHBhcmFtcy5ib2R5YAogICAgLy8gczU6IGBwYXJhbXMubW9kZWAKICAgIC8vIEZvciBicmV2aXR5LCB0aGUgInBhcmFtcyIgcHJlZml4IHdpbGwg" + - "YmUgb21pdHRlZCBmcm9tIG5vdyBvbi4KCiAgICAvLyBHcm91cCAxOiBQcmVwYXJhdGlvbiBvZiBuZWVkZWQgcGFyYW1zCiAgICAvLyBGb3IgYWxtb3N0IGlkZW50aWNh" + - "bCBsb2dpYyBhbmQgaW5zdHJ1Y3Rpb25zLAogICAgLy8gc2VlIGNvbW1lbnRzIGluc2lkZSBgY29udHJhY3RIYXNoKClgIGZ1bmN0aW9uIGluIGNvbnRyYWN0LnRhY3QK" + - "ICAgIDQgMSBCTEtQVVNIIC8vIHB1c2hlcyAyIGNvcGllcyBvZiBgaW5pdC5jb2RlYCBhbmQgYGluaXQuZGF0YWAKICAgIEhBU0hDVSAvLyBgaW5pdC5kYXRhYCBoYXNo" + - "CiAgICBTV0FQCiAgICBIQVNIQ1UgLy8gYGluaXQuY29kZWAgaGFzaAogICAgU1dBUDIKICAgIENERVBUSCAvLyBgaW5pdC5kYXRhYCBkZXB0aAogICAgU1dBUAogICAg" + - "Q0RFUFRIIC8vIGBpbml0LmNvZGVgIGRlcHRoCgogICAgLy8gR3JvdXAgMjogQ2FsY3VsYXRpbmcgZGVzdGluYXRpb24gYWRkcmVzcwogICAgLy8gRm9yIGFsbW9zdCBp" + - "ZGVudGljYWwgbG9naWMgYW5kIGluc3RydWN0aW9ucywKICAgIC8vIHNlZSBjb21tZW50cyBpbnNpZGUgYGNvbnRyYWN0SGFzaCgpYCBmdW5jdGlvbiBpbiBjb250cmFj" + - "dC50YWN0CiAgICAxMzEzODAgSU5UIC8vICgyIDw8IDE2KSB8ICgxIDw8IDgpIHwgMHgzNAogICAgTkVXQwogICAgMjQgU1RVCiAgICAxNiBTVFUKICAgIDE2IFNUVQog" + - "ICAgMjU2IFNUVQogICAgMjU2IFNUVQogICAgT05FIEhBU0hFWFRfU0hBMjU2IC8vIG9idGFpbnMgaGFzaCBwYXJ0IChhY2NvdW50IGlkKSBvZiB0aGUgYWRkcmVzcwog" + - "ICAgLy8g4oaSIFN0YWNrIHN0YXRlCiAgICAvLyBzMDogZGVzdEFkZHIoaGFzaCBwYXJ0KQogICAgLy8gczE6IGBpbml0LmRhdGFgCiAgICAvLyBzMjogYGluaXQuY29k" + - "ZWAKICAgIC8vIHMzIGFuZCBiZWxvdzogYGJvdW5jZWAsIGB2YWx1ZWAsIGBib2R5YCwgYG1vZGVgCgogICAgLy8gR3JvdXAgMzogQnVpbGRpbmcgYSBtZXNzYWdlIChD" + - "b21tb25Nc2dJbmZvUmVsYXhlZCkKICAgIHMzIFhDSEcwICAgICAgICAgICAvLyBzd2FwcyBgYm91bmNlYCB3aXRoIGRlc3RBZGRyKGhhc2ggcGFydCkKICAgIE5FV0MK" + - "ICAgIGJ7MDF9IFNUU0xJQ0VDT05TVCAvLyBzdG9yZSB0YWcgPSAkMCBhbmQgaWhyX2Rpc2FibGVkID0gdHJ1ZQogICAgMSBTVEkgICAgICAgICAgICAgIC8vIHN0b3Jl" + - "IGBib3VuY2VgCiAgICBzMSBzMiBYQ0hHICAgICAgICAgLy8gc3dhcCBgaW5pdC5kYXRhYCB3aXRoIGBpbml0LmNvZGVgLCBwbGFjaW5nIGNvZGUgb24gczEKICAgIFNU" + - "UkVGICAgICAgICAgICAgICAvLyBzdG9yZSBgaW5pdC5jb2RlYAogICAgU1RSRUYgICAgICAgICAgICAgIC8vIHN0b3JlIGBpbml0LmRhdGFgCiAgICAvLyBJbmxpbmUg" + - "U3RhdGVJbml0OgogICAgYnswMDAxMDAwMDAwMDAwMH0gU1RTTElDRUNPTlNUCiAgICAvLyAwICsgMDAgKyAxMCArIDAgKyAwMDAwMDAwMAogICAgLy8gMSkgMCAtIGJv" + - "dW5jZWQgPSBmYWxzZQogICAgLy8gMikgMDAgLSBzcmMgPSBhZGRyX25vbmUKICAgIC8vIDMpIDEwIC0gdGFnIG9mIGFkZHJfc3RkIChwYXJ0IG9mIGRlc3QpCiAgICAv" + - "LyA0KSAwIC0gTWF5YmUgQW55Y2FzdCA9IGZhbHNlCiAgICAvLyA1KSAwMDAwMDAwMCAtIHdvcmtjaGFpbl9pZCAocGFydCBvZiBkZXN0KQogICAgLy8KICAgIDI1NiBT" + - "VFUgICAgIC8vIHN0b3JlIGRlc3RBZGRyKGhhc2ggcGFydCkKICAgIFNXQVAgICAgICAgIC8vIEJ1aWxkZXIgb24gdG9wLCBgdmFsdWVgIGJlbG93CiAgICBTVEdSQU1T" + - "ICAgICAvLyBzdG9yZSBgdmFsdWVgCiAgICAxMDUgUFVTSElOVCAvLyAxICsgNCArIDQgKyA2NCArIDMyCiAgICBTVFpFUk9FUyAgICAvLyBzdG9yZSBjdXJyZW5jeV9j" + - "b2xsZWN0aW9uLCBpaHJfZmVlLCBmd2RfZmVlLCBjcmVhdGVkX2x0IGFuZCBjcmVhdGVkX2F0CgogICAgLy8gR3JvdXAgNDogQ29udGludWUgYnVpbGRpbmcgYSBtZXNz" + - "YWdlIChDb21tb25Nc2dJbmZvUmVsYXhlZCBpbnRvIE1lc3NhZ2VSZWxheGVkKQogICAgLy8gUmVtYWluaW5nIGJpdHMgb2YgTWVzc2FnZVJlbGF4ZWQ6CiAgICBiezEw" + - "MDAxMTB9IFNUU0xJQ0VDT05TVAogICAgLy8gMTAgKyAwICsgMCArIDEgKyAxICsgMAogICAgLy8gMTAgLSBNYXliZSAoRWl0aGVyIFN0YXRlSW5pdCBeU3RhdGVJbml0" + - "KSA9IHRydWUgZmFsc2UKICAgIC8vIDAgLSBzcGxpdF9kZXB0aDooTWF5YmUgKCMjIDUpKSA9IGZhbHNlCiAgICAvLyAwID0gc3BlY2lhbDooTWF5YmUgVGlja1RvY2sp" + - "ID0gZmFsc2UKICAgIC8vIDEgPSBjb2RlOihNYXliZSBeQ2VsbCkgPSB0cnVlCiAgICAvLyAxID0gZGF0YTooTWF5YmUgXkNlbGwpID0gdHJ1ZQogICAgLy8gMCA9IGxp" + - "YnJhcnk6KE1heWJlIF5DZWxsKSA9IGZhbHNlCiAgICAvLwogICAgU1RESUNUIC8vIHN0b3JlIGBib2R5YCBhcyByZWYgd2l0aCBhbiBleHRyYSBNYXliZSBiaXQsIHNp" + - "bmNlIGBib2R5YCBtaWdodCBiZSBudWxsCiAgICBFTkRDICAgLy8gZmluYWxpemUgdGhlIG1lc3NhZ2UKICAgIC8vIOKGkiBTdGFjayBzdGF0ZQogICAgLy8gczA6IENl" + - "bGwKICAgIC8vIHMxOiBwYXJhbXMuYG1vZGVgCgogICAgLy8gR3JvdXAgNTogU2VuZGluZyB0aGUgbWVzc2FnZSwgd2l0aCBgbW9kZWAgb24gdG9wCiAgICBTV0FQCiAg" + - "ICBTRU5EUkFXTVNHCn0KCi8vLyBHbG9iYWwgZnVuY3Rpb24uIEF2YWlsYWJsZSBzaW5jZSBUYWN0IDEuNi4xLgovLy8KLy8vIFF1ZXVlcyBhbiBlbXB0eSBtZXNzYWdl" + - "IHRvIGJlIHNlbnQgd2l0aCB0aGUgYFNlbmRSZW1haW5pbmdWYWx1ZWAgbW9kZSBhbmQgdGhlIGBTZW5kSWdub3JlRXJyb3JzYCBmbGFnIHRvIHRoZSBkZXN0aW5hdGlv" + - "biBhZGRyZXNzIGB0b2AuCi8vLyBUaGlzIGlzIHRoZSBtb3N0IGdhcy1lZmZpY2llbnQgd2F5IHRvIHNlbmQgdGhlIHJlbWFpbmluZyB2YWx1ZSBmcm9tIHRoZSBpbmNv" + - "bWluZyBtZXNzYWdlIHRvIHRoZSBnaXZlbiBhZGRyZXNzLgovLy8KLy8vIFRoaXMgZnVuY3Rpb24gd29uJ3QgZm9yd2FyZCBleGNlc3MgdmFsdWVzIGlmIGFueSBvdGhl" + - "ciBtZXNzYWdlLXNlbmRpbmcgZnVuY3Rpb25zIHdlcmUgY2FsbGVkIGluIHRoZSBzYW1lIHJlY2VpdmVyIGJlZm9yZS4KLy8vCi8vLyBgYGB0YWN0Ci8vLyBmdW4gZXhh" + - "bXBsZXMoKSB7Ci8vLyAgICAgLy8gRm9yd2FyZCB0aGUgcmVtYWluaW5nIHZhbHVlIGJhY2sgdG8gdGhlIHNlbmRlcgovLy8gICAgIGNhc2hiYWNrKHNlbmRlcigpKTsK" + - "Ly8vCi8vLyAgICAgLy8gVGhlIGNhc2hiYWNrKCkgZnVuY3Rpb24gYWJvdmUgaXMgY2hlYXBlciwgYnV0IGZ1bmN0aW9uYWxseQovLy8gICAgIC8vIGVxdWl2YWxlbnQg" + - "dG8gdGhlIGZvbGxvd2luZyBjYWxsIHRvIHRoZSBtZXNzYWdlKCkgZnVuY3Rpb24KLy8vICAgICBtZXNzYWdlKE1lc3NhZ2VQYXJhbWV0ZXJzewovLy8gICAgICAgICBt" + - "b2RlOiBTZW5kUmVtYWluaW5nVmFsdWUgfCBTZW5kSWdub3JlRXJyb3JzLAovLy8gICAgICAgICBib2R5OiBudWxsLAovLy8gICAgICAgICB2YWx1ZTogMCwKLy8vICAg" + - "ICAgICAgdG86IHNlbmRlcigpLAovLy8gICAgICAgICBib3VuY2U6IGZhbHNlLAovLy8gICAgIH0pOwovLy8gfQovLy8gYGBgCi8vLwovLy8gIyMjIyBFeGl0IGNvZGVz" + - "Ci8vLwovLy8gKiAzMzogW0FjdGlvbiBsaXN0IGlzIHRvbyBsb25nXSDigJQgVGhyb3duIHdoZW4gYXR0ZW1wdGluZyB0byBxdWV1ZSBtb3JlIHRoYW4gMjU1IG1lc3Nh" + - "Z2VzLgovLy8KLy8vIFNlZTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtc2VuZCNjYXNoYmFjawovLy8KLy8vIFtBY3Rpb24gbGlzdCBpcyB0b28g" + - "bG9uZ106IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL2Jvb2svZXhpdC1jb2RlcyMzMwovLy8KYXNtIGZ1biBjYXNoYmFjayh0bzogQWRkcmVzcykgewogICAgTkVX" + - "QwogICAgeHs0Ml99IFNUU0xJQ0VDT05TVCAvLyAuc3RvcmVVaW50KDB4MTAsIDYpCiAgICBTVFNMSUNFICAgICAgICAgIC8vIC5zdG9yZUFkZHJlc3ModG8pCiAgICAw" + - "IFBVU0hJTlQgICAgICAgIC8vIDAKICAgIDExMSBTVFVSICAgICAgICAgLy8gLnN0b3JlVWludCgwLCAxMTEpCiAgICAgICAgICAgICAgICAgICAgIC8vIDQgemVyb3Mg" + - "Zm9yIGNvaW5zIGFuZCAxMDcgemVyb3MgZm9yIGx0LCBmZWVzLCBldGMuCiAgICBFTkRDCiAgICA2NiBQVVNISU5UICAgICAgIC8vIFNlbmRSZW1haW5pbmdWYWx1ZSB8" + - "IFNlbmRJZ25vcmVFcnJvcnMKICAgIFNFTkRSQVdNU0cKfQoKLy8vIEdsb2JhbCBmdW5jdGlvbi4gKipEZXByZWNhdGVkKiogc2luY2UgVGFjdCAxLjYuNi4gVXNlIGBz" + - "ZW5kUmF3TWVzc2FnZSgpYCBpbnN0ZWFkLgovLy8KLy8vIFF1ZXVlcyB0aGUgbWVzc2FnZSB0byBiZSBzZW50IGJ5IHNwZWNpZnlpbmcgdGhlIGNvbXBsZXRlIGBtc2dg" + - "IGNlbGwgYW5kIHRoZSBtZXNzYWdlIGBtb2RlYC4KLy8vCi8vLyAjIyMjIEV4aXQgY29kZXMKLy8vCi8vLyAqIDMzOiBbQWN0aW9uIGxpc3QgaXMgdG9vIGxvbmddIOKA" + - "lCBUaHJvd24gd2hlbiBhdHRlbXB0aW5nIHRvIHF1ZXVlIG1vcmUgdGhhbiAyNTUgbWVzc2FnZXMuCi8vLwovLy8gU2VlOgovLy8gKiBodHRwczovL2RvY3MudGFjdC1s" + - "YW5nLm9yZy9yZWYvY29yZS1zZW5kI3NlbmRyYXdtZXNzYWdlCi8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLXNlbmQjbmF0aXZlc2VuZG1l" + - "c3NhZ2UKLy8vCi8vLyBbQWN0aW9uIGxpc3QgaXMgdG9vIGxvbmddOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9ib29rL2V4aXQtY29kZXMjMzMKLy8vCmFzbSBm" + - "dW4gbmF0aXZlU2VuZE1lc3NhZ2UobXNnOiBDZWxsLCBtb2RlOiBJbnQpIHsgU0VORFJBV01TRyB9CgovLy8gR2xvYmFsIGZ1bmN0aW9uLiBBdmFpbGFibGUgc2luY2Ug" + - "VGFjdCAxLjYuNi4KLy8vCi8vLyBRdWV1ZXMgdGhlIG1lc3NhZ2UgdG8gYmUgc2VudCBieSBzcGVjaWZ5aW5nIHRoZSBjb21wbGV0ZSBgbXNnYCBjZWxsIGFuZCB0aGUg" + - "bWVzc2FnZSBgbW9kZWAuCi8vLwovLy8gUHJlZmVyIHVzaW5nIHRoZSBtb3JlIHVzZXItZnJpZW5kbHkgYG1lc3NhZ2UoKWAsIGBkZXBsb3koKWAsIG9yIGBzZW5kKClg" + - "IGZ1bmN0aW9ucyB1bmxlc3MgeW91IGhhdmUgYSBjb21wbGV4IGxvZ2ljIHRoYXQgY2Fubm90IGJlIGV4cHJlc3NlZCBvdGhlcndpc2UuCi8vLwovLy8gIyMjIyBFeGl0" + - "IGNvZGVzCi8vLwovLy8gKiAzMzogW0FjdGlvbiBsaXN0IGlzIHRvbyBsb25nXSDigJQgVGhyb3duIHdoZW4gYXR0ZW1wdGluZyB0byBxdWV1ZSBtb3JlIHRoYW4gMjU1" + - "IG1lc3NhZ2VzLgovLy8KLy8vIFNlZToKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtc2VuZCNzZW5kcmF3bWVzc2FnZQovLy8gKiBodHRw" + - "czovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1zZW5kI21lc3NhZ2UKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtc2VuZCNkZXBs" + - "b3kKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtc2VuZCNzZW5kCi8vLwovLy8gW0FjdGlvbiBsaXN0IGlzIHRvbyBsb25nXTogaHR0cHM6" + - "Ly9kb2NzLnRhY3QtbGFuZy5vcmcvYm9vay9leGl0LWNvZGVzIzMzCi8vLwphc20gZnVuIHNlbmRSYXdNZXNzYWdlKG1zZzogQ2VsbCwgbW9kZTogSW50KSB7IFNFTkRS" + - "QVdNU0cgfQoKLy8vIEdsb2JhbCBmdW5jdGlvbi4gKipEZXByZWNhdGVkKiogc2luY2UgVGFjdCAxLjYuNi4gVXNlIGBzZW5kUmF3TWVzc2FnZVJldHVybkZvcndhcmRG" + - "ZWUoKWAgaW5zdGVhZC4KLy8vCi8vLyBTaW1pbGFyIHRvIGBzZW5kUmF3TWVzc2FnZSgpYCwgYnV0IGFsc28gY2FsY3VsYXRlcyBhbmQgcmV0dXJucyB0aGUgZm9yd2Fy" + - "ZCBmZWUgaW4gbmFub1RvbmNvaW4uCi8vLwovLy8gIyMjIyBFeGl0IGNvZGVzCi8vLwovLy8gKiA1OiBbSW50ZWdlciBvdXQgb2YgZXhwZWN0ZWQgcmFuZ2VdIC0gVGhy" + - "b3duIGlmIHRoZSBtZXNzYWdlIG1vZGUgaXMgaW52YWxpZC4KLy8vICogNzogW1R5cGUgY2hlY2sgZXJyb3JdIC0gVGhyb3duIGlmIGFueSBvZiB0aGUgYmxvY2tjaGFp" + - "biBjb25maWcsIGNvbnRyYWN0IGJhbGFuY2Ugb3IgaW5jb21pbmcgbWVzc2FnZSB2YWx1ZSBhcmUgaW52YWxpZC4KLy8vICogOTogW0NlbGwgdW5kZXJmbG93XSAtIFRo" + - "cm93biBpZiB0aGUgYmxvY2tjaGFpbiBjb25maWcgaXMgaW52YWxpZC4KLy8vICogMTE6IFsiVW5rbm93biIgZXJyb3JdIC0gVGhyb3duIGlmIHRoZSBtZXNzYWdlIGNl" + - "bGwgaXMgaWxsLWZvcm1lZCBvciB0aGUgYmxvY2tjaGFpbiBjb25maWcgaXMgaW52YWxpZC4KLy8vICogMzM6IFtBY3Rpb24gbGlzdCBpcyB0b28gbG9uZ10g4oCUIFRo" + - "cm93biB3aGVuIGF0dGVtcHRpbmcgdG8gcXVldWUgbW9yZSB0aGFuIDI1NSBtZXNzYWdlcy4KLy8vCi8vLyBTZWU6Ci8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcu" + - "b3JnL3JlZi9jb3JlLXNlbmQjbmF0aXZlc2VuZG1lc3NhZ2VyZXR1cm5mb3J3YXJkZmVlCi8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLXNl" + - "bmQjc2VuZHJhd21lc3NhZ2UKLy8vCi8vLyBbSW50ZWdlciBvdXQgb2YgZXhwZWN0ZWQgcmFuZ2VdOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9ib29rL2V4aXQt" + - "Y29kZXMjNQovLy8gW1R5cGUgY2hlY2sgZXJyb3JdOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9ib29rL2V4aXQtY29kZXMjNwovLy8gW0NlbGwgdW5kZXJmbG93" + - "XTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvYm9vay9leGl0LWNvZGVzIzkKLy8vIFsiVW5rbm93biIgZXJyb3JdOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9y" + - "Zy9ib29rL2V4aXQtY29kZXMjMTEKLy8vIFtBY3Rpb24gbGlzdCBpcyB0b28gbG9uZ106IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL2Jvb2svZXhpdC1jb2RlcyMz" + - "MwovLy8KYXNtIGZ1biBuYXRpdmVTZW5kTWVzc2FnZVJldHVybkZvcndhcmRGZWUobXNnOiBDZWxsLCBtb2RlOiBJbnQpOiBJbnQgeyBTRU5ETVNHIH0KCi8vLyBHbG9i" + - "YWwgZnVuY3Rpb24uIEF2YWlsYWJsZSBzaW5jZSBUYWN0IDEuNi42LgovLy8KLy8vIFNpbWlsYXIgdG8gYHNlbmRSYXdNZXNzYWdlKClgLCBidXQgYWxzbyBjYWxjdWxh" + - "dGVzIGFuZCByZXR1cm5zIHRoZSBmb3J3YXJkIGZlZSBpbiBuYW5vVG9uY29pbi4KLy8vCi8vLyAjIyMjIEV4aXQgY29kZXMKLy8vCi8vLyAqIDU6IFtJbnRlZ2VyIG91" + - "dCBvZiBleHBlY3RlZCByYW5nZV0gLSBUaHJvd24gaWYgdGhlIG1lc3NhZ2UgbW9kZSBpcyBpbnZhbGlkLgovLy8gKiA3OiBbVHlwZSBjaGVjayBlcnJvcl0gLSBUaHJv" + - "d24gaWYgYW55IG9mIHRoZSBibG9ja2NoYWluIGNvbmZpZywgY29udHJhY3QgYmFsYW5jZSBvciBpbmNvbWluZyBtZXNzYWdlIHZhbHVlIGFyZSBpbnZhbGlkLgovLy8g" + - "KiAxMTogWyJVbmtub3duIiBlcnJvcl0gLSBUaHJvd24gaWYgdGhlIG1lc3NhZ2UgY2VsbCBpcyBpbGwtZm9ybWVkIG9yIHRoZSBUVk0gY29uZmlnIGlzIGludmFsaWQu" + - "Ci8vLyAqIDMzOiBbQWN0aW9uIGxpc3QgaXMgdG9vIGxvbmddIOKAlCBUaHJvd24gd2hlbiBhdHRlbXB0aW5nIHRvIHF1ZXVlIG1vcmUgdGhhbiAyNTUgbWVzc2FnZXMu" + - "Ci8vLwovLy8gU2VlOgovLy8gKiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1zZW5kI3NlbmRyYXdtZXNzYWdlcmV0dXJuZm9yd2FyZGZlZQovLy8g" + - "KiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1zZW5kI3NlbmRyYXdtZXNzYWdlCi8vLwovLy8gW0ludGVnZXIgb3V0IG9mIGV4cGVjdGVkIHJhbmdl" + - "XTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvYm9vay9leGl0LWNvZGVzIzUKLy8vIFtUeXBlIGNoZWNrIGVycm9yXTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5v" + - "cmcvYm9vay9leGl0LWNvZGVzIzcKLy8vIFsiVW5rbm93biIgZXJyb3JdOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9ib29rL2V4aXQtY29kZXMjMTEKLy8vIFtB" + - "Y3Rpb24gbGlzdCBpcyB0b28gbG9uZ106IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL2Jvb2svZXhpdC1jb2RlcyMzMwovLy8KYXNtIGZ1biBzZW5kTWVzc2FnZVJl" + - "dHVybkZvcndhcmRGZWUobXNnOiBDZWxsLCBtb2RlOiBJbnQpOiBJbnQgeyBTRU5ETVNHIH0KCi8vLyBHbG9iYWwgZnVuY3Rpb24uCi8vLwovLy8gUXVldWVzIHRoZSBt" + - "ZXNzYWdlIGBib2R5YCB0byBiZSBzZW50IHRvIHRoZSBvdXRlciB3b3JsZCB3aXRoIHRoZSBwdXJwb3NlIG9mIGxvZ2dpbmcgYW5kIGFuYWx5emluZyBpdCBsYXRlciBv" + - "ZmYtY2hhaW4uIFRoZSBtZXNzYWdlIGRvZXMgbm90IGhhdmUgYSByZWNpcGllbnQgYW5kIGlzIG1vcmUgZ2FzLWVmZmljaWVudCBjb21wYXJlZCB0byB1c2luZyBhbnkg" + - "b3RoZXIgbWVzc2FnZS1zZW5kaW5nIGZ1bmN0aW9ucyBvZiBUYWN0LgovLy8KLy8vIFRoZSBtZXNzYWdlIGlzIHNlbnQgd2l0aCB0aGUgZGVmYXVsdCBtb2RlOiBgU2Vu" + - "ZERlZmF1bHRNb2RlYCAoMCkuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKSB7Ci8vLyAgICAgZW1pdCgiQ2F0Y2ggbWUgaWYgeW91IGNhbiwgTXIuIEhv" + - "bG1lcyIuYXNDb21tZW50KCkpOyAvLyBhc0NvbW1lbnQoKSBjb252ZXJ0cyBhIFN0cmluZyB0byBhIENlbGwKLy8vIH0KLy8vIGBgYAovLy8KLy8vICMjIyMgRXhpdCBj" + + "aW1wb3J0ICIuL2NlbGxzIjsKCi8vLyBPcmRpbmFyeSBtZXNzYWdlIChkZWZhdWx0KS4KLy8vCi8vLyBUaGlzIGNvbnN0YW50IGlzIGF2YWlsYWJsZSBzaW5jZSBUYWN0" + + "IDEuNi4wLgovLy8KLy8vIFNlZTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvYm9vay9tZXNzYWdlLW1vZGUjYmFzZS1tb2RlcwovLy8KY29uc3QgU2VuZERlZmF1" + + "bHRNb2RlOiBJbnQgPSAwOwoKLy8vIENhcnJ5IGFsbCB0aGUgcmVtYWluaW5nIHZhbHVlIG9mIHRoZSBpbmJvdW5kIG1lc3NhZ2UgaW4gYWRkaXRpb24KLy8vIHRvIHRo" + + "ZSB2YWx1ZSBpbml0aWFsbHkgaW5kaWNhdGVkIGluIHRoZSBuZXcgbWVzc2FnZS4KLy8vCi8vLyBTZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL2Jvb2svbWVz" + + "c2FnZS1tb2RlI2Jhc2UtbW9kZXMKLy8vCmNvbnN0IFNlbmRSZW1haW5pbmdWYWx1ZTogSW50ID0gNjQ7CgovLy8gQ2FycnkgKiphbGwgdGhlIHJlbWFpbmluZyBiYWxh" + + "bmNlKiogb2YgdGhlIGN1cnJlbnQgc21hcnQgY29udHJhY3QgaW5zdGVhZAovLy8gb2YgdGhlIHZhbHVlIG9yaWdpbmFsbHkgaW5kaWNhdGVkIGluIHRoZSBtZXNzYWdl" + + "LgovLy8KLy8vIFNlZTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvYm9vay9tZXNzYWdlLW1vZGUjYmFzZS1tb2RlcwovLy8KY29uc3QgU2VuZFJlbWFpbmluZ0Jh" + + "bGFuY2U6IEludCA9IDEyODsKCi8vLyBEb2Vzbid0IHNlbmQgdGhlIG1lc3NhZ2UsIG9ubHkgZXN0aW1hdGVzIHRoZSBmb3J3YXJkIGZlZXMKLy8vIGlmIHRoZSBtZXNz" + + "YWdlLXNlbmRpbmcgZnVuY3Rpb24gY29tcHV0ZXMgdGhvc2UuCi8vLwovLy8gVGhpcyBjb25zdGFudCBpcyBhdmFpbGFibGUgc2luY2UgVGFjdCAxLjUuMC4KLy8vCi8v" + + "LyBTZWU6Ci8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL2Jvb2svbWVzc2FnZS1tb2RlI2Jhc2UtbW9kZXMKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFu" + + "Zy5vcmcvYm9vay9zZW5kI21lc3NhZ2Utc2VuZGluZy1mdW5jdGlvbnMKLy8vCmNvbnN0IFNlbmRPbmx5RXN0aW1hdGVGZWU6IEludCA9IDEwMjQ7CgovLy8gKipEZXBy" + + "ZWNhdGVkKiogc2luY2UgVGFjdCAxLjYuNS4gVXNlIGBTZW5kUGF5RndkRmVlc1NlcGFyYXRlbHlgIGluc3RlYWQuCi8vLwovLy8gUGF5IGZvcndhcmQgZmVlcyBzZXBh" + + "cmF0ZWx5IGZyb20gdGhlIG1lc3NhZ2UgdmFsdWUuCi8vLwovLy8gU2VlOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9ib29rL21lc3NhZ2UtbW9kZSNvcHRpb25h" + + "bC1mbGFncwovLy8KY29uc3QgU2VuZFBheUdhc1NlcGFyYXRlbHk6IEludCA9IDE7CgovLy8gUGF5IGZvcndhcmQgZmVlcyBzZXBhcmF0ZWx5IGZyb20gdGhlIG1lc3Nh" + + "Z2UgdmFsdWUuCi8vLwovLy8gU2VlOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9ib29rL21lc3NhZ2UtbW9kZSNvcHRpb25hbC1mbGFncwovLy8KY29uc3QgU2Vu" + + "ZFBheUZ3ZEZlZXNTZXBhcmF0ZWx5OiBJbnQgPSAxOwoKLy8vIElnbm9yZSBhbnkgZXJyb3JzIGFyaXNpbmcgd2hpbGUgcHJvY2Vzc2luZyB0aGlzIG1lc3NhZ2UgZHVy" + + "aW5nIHRoZSBhY3Rpb24gcGhhc2UuCi8vLwovLy8gU2VlOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9ib29rL21lc3NhZ2UtbW9kZSNvcHRpb25hbC1mbGFncwov" + + "Ly8KY29uc3QgU2VuZElnbm9yZUVycm9yczogSW50ID0gMjsKCi8vLyBCb3VuY2UgdHJhbnNhY3Rpb24gaW4gY2FzZSBvZiBhbnkgZXJyb3JzIGR1cmluZyBhY3Rpb24g" + + "cGhhc2UuCi8vLyBIYXMgbm8gZWZmZWN0IGlmIGZsYWcgKzIsIGBTZW5kSWdub3JlRXJyb3JzYCBpcyB1c2VkLgovLy8KLy8vIFNlZTogaHR0cHM6Ly9kb2NzLnRhY3Qt" + + "bGFuZy5vcmcvYm9vay9tZXNzYWdlLW1vZGUjb3B0aW9uYWwtZmxhZ3MKLy8vCmNvbnN0IFNlbmRCb3VuY2VJZkFjdGlvbkZhaWw6IEludCA9IDE2OwoKLy8vIEN1cnJl" + + "bnQgYWNjb3VudCAoY29udHJhY3QpIHdpbGwgYmUgZGVzdHJveWVkIGlmIGl0cyByZXN1bHRpbmcgYmFsYW5jZSBpcyB6ZXJvLgovLy8gVGhpcyBmbGFnIGlzIG9mdGVu" + + "IHVzZWQgd2l0aCBtb2RlIDEyOCwgYFNlbmRSZW1haW5pbmdCYWxhbmNlYC4KLy8vCi8vLyBTZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL2Jvb2svbWVzc2Fn" + + "ZS1tb2RlI29wdGlvbmFsLWZsYWdzCi8vLwpjb25zdCBTZW5kRGVzdHJveUlmWmVybzogSW50ID0gMzI7CgovLy8gU3RydWN0IGZvciBzcGVjaWZ5aW5nIHRoZSBtZXNz" + + "YWdlIHBhcmFtZXRlcnMgb2YgdGhlIGBzZW5kKClgIGZ1bmN0aW9uLgovLy8KLy8vIFNlZTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtc2VuZCNz" + + "ZW5kCi8vLwpzdHJ1Y3QgU2VuZFBhcmFtZXRlcnMgewogICAgLy8vIEFuIDgtYml0IHZhbHVlIHRoYXQgY29uZmlndXJlcyBob3cgdG8gc2VuZCBhIG1lc3NhZ2UsIGRl" + + "ZmF1bHRzIHRvIDAuCiAgICAvLy8gU2VlOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9ib29rL21lc3NhZ2UtbW9kZQogICAgbW9kZTogSW50ID0gU2VuZERlZmF1" + + "bHRNb2RlOwoKICAgIC8vLyBPcHRpb25hbCBtZXNzYWdlIGJvZHkgYXMgYSBgQ2VsbGAuCiAgICBib2R5OiBDZWxsPyA9IG51bGw7CgogICAgLy8vIE9wdGlvbmFsIGlu" + + "aXRpYWwgY29kZSBvZiB0aGUgY29udHJhY3QgKGNvbXBpbGVkIGJpdGNvZGUpLgogICAgY29kZTogQ2VsbD8gPSBudWxsOwoKICAgIC8vLyBPcHRpb25hbCBpbml0aWFs" + + "IGRhdGEgb2YgdGhlIGNvbnRyYWN0IChhcmd1bWVudHMgb2YgYGluaXQoKWAgZnVuY3Rpb24gb3IgdmFsdWVzIG9mIGNvbnRyYWN0IHBhcmFtZXRlcnMpLgogICAgZGF0" + + "YTogQ2VsbD8gPSBudWxsOwoKICAgIC8vLyBUaGUgYW1vdW50IG9mIG5hbm9Ub25jb2lucyB5b3Ugd2FudCB0byBzZW5kIHdpdGgKICAgIC8vLyB0aGUgbWVzc2FnZS4g" + + "VGhpcyB2YWx1ZSBpcyB1c2VkIHRvIGNvdmVyIGZvcndhcmQgZmVlcywKICAgIC8vLyB1bmxlc3MgdGhlIG9wdGlvbmFsIGZsYWcgYFNlbmRQYXlGd2RGZWVzU2VwYXJh" + + "dGVseWAgaXMgdXNlZC4KICAgIHZhbHVlOiBJbnQ7CgogICAgLy8vIFJlY2lwaWVudCBpbnRlcm5hbCBgQWRkcmVzc2Agb24gVE9OIEJsb2NrY2hhaW4uCiAgICB0bzog" + + "QWRkcmVzczsKCiAgICAvLy8gV2hlbiBzZXQgdG8gYHRydWVgIChkZWZhdWx0KSBtZXNzYWdlIGJvdW5jZXMgYmFjayB0byB0aGUgc2VuZGVyIGlmCiAgICAvLy8gdGhl" + + "IHJlY2lwaWVudCBjb250cmFjdCBkb2Vzbid0IGV4aXN0IG9yIHdhc24ndCBhYmxlIHRvIHByb2Nlc3MgdGhlIG1lc3NhZ2UuCiAgICBib3VuY2U6IEJvb2wgPSB0cnVl" + + "Owp9CgovLy8gU3RydWN0IGZvciBzcGVjaWZ5aW5nIHRoZSBtZXNzYWdlIHBhcmFtZXRlcnMgb2YgdGhlIGBtZXNzYWdlKClgIGZ1bmN0aW9uLiBBdmFpbGFibGUgc2lu" + + "Y2UgVGFjdCAxLjYuMC4KLy8vCi8vLyBTZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLXNlbmQjbWVzc2FnZQovLy8Kc3RydWN0IE1lc3NhZ2VQ" + + "YXJhbWV0ZXJzIHsKICAgIC8vLyBBbiA4LWJpdCB2YWx1ZSB0aGF0IGNvbmZpZ3VyZXMgaG93IHRvIHNlbmQgYSBtZXNzYWdlLCBkZWZhdWx0cyB0byAwLgogICAgLy8v" + + "IFNlZTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvYm9vay9tZXNzYWdlLW1vZGUKICAgIG1vZGU6IEludCA9IFNlbmREZWZhdWx0TW9kZTsKCiAgICAvLy8gT3B0" + + "aW9uYWwgbWVzc2FnZSBib2R5IGFzIGEgYENlbGxgLgogICAgYm9keTogQ2VsbD8gPSBudWxsOwoKICAgIC8vLyBUaGUgYW1vdW50IG9mIG5hbm9Ub25jb2lucyB5b3Ug" + + "d2FudCB0byBzZW5kIHdpdGgKICAgIC8vLyB0aGUgbWVzc2FnZS4gVGhpcyB2YWx1ZSBpcyB1c2VkIHRvIGNvdmVyIGZvcndhcmQgZmVlcywKICAgIC8vLyB1bmxlc3Mg" + + "dGhlIG9wdGlvbmFsIGZsYWcgYFNlbmRQYXlGd2RGZWVzU2VwYXJhdGVseWAgaXMgdXNlZC4KICAgIHZhbHVlOiBJbnQ7CgogICAgLy8vIFJlY2lwaWVudCBpbnRlcm5h" + + "bCBgQWRkcmVzc2Agb24gVE9OIEJsb2NrY2hhaW4uCiAgICB0bzogQWRkcmVzczsKCiAgICAvLy8gV2hlbiBzZXQgdG8gYHRydWVgIChkZWZhdWx0KSBtZXNzYWdlIGJv" + + "dW5jZXMgYmFjayB0byB0aGUgc2VuZGVyIGlmCiAgICAvLy8gdGhlIHJlY2lwaWVudCBjb250cmFjdCBkb2Vzbid0IGV4aXN0IG9yIHdhc24ndCBhYmxlIHRvIHByb2Nl" + + "c3MgdGhlIG1lc3NhZ2UuCiAgICBib3VuY2U6IEJvb2wgPSB0cnVlOwp9CgovLy8gR2xvYmFsIGZ1bmN0aW9uLiBBdmFpbGFibGUgc2luY2UgVGFjdCAxLjYuMC4KLy8v" + + "Ci8vLyBRdWV1ZXMgdGhlIG1lc3NhZ2UgdG8gYmUgc2VudCB1c2luZyB0aGUgYE1lc3NhZ2VQYXJhbWV0ZXJzYCBzdHJ1Y3QuIEFsbG93cyBmb3IgY2hlYXBlciBub24t" + + "ZGVwbG95bWVudCwgcmVndWxhciBtZXNzYWdlcyBjb21wYXJlZCB0byB0aGUgYHNlbmQoKWAgZnVuY3Rpb24uCi8vLwovLy8gVGhlIGBNZXNzYWdlUGFyYW1ldGVyc2Ag" + + "c3RydWN0IGlzIHNpbWlsYXIgdG8gYFNlbmRQYXJhbWV0ZXJzYCBzdHJ1Y3QsIGJ1dCB3aXRob3V0IHRoZSBgY29kZWAgYW5kIGBkYXRhYCBmaWVsZHMuCi8vLwovLy8g" + + "YGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKSB7Ci8vLyAgICAgbWVzc2FnZShNZXNzYWdlUGFyYW1ldGVyc3sKLy8vICAgICAgICAgdG86IHNlbmRlcigpLCAgICAvLyBi" + + "YWNrIHRvIHRoZSBzZW5kZXIsCi8vLyAgICAgICAgIHZhbHVlOiB0b24oIjEiKSwgLy8gd2l0aCAxIFRvbmNvaW4gKDFfMDAwXzAwMF8wMDAgbmFub1RvbmNvaW4pLAov" + + "Ly8gICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFuZCBubyBtZXNzYWdlIGJvZHkKLy8vICAgICB9KTsKLy8vIH0KLy8vIGBgYAovLy8KLy8vICMjIyMgRXhpdCBj" + "b2RlcwovLy8KLy8vICogMzM6IFtBY3Rpb24gbGlzdCBpcyB0b28gbG9uZ10g4oCUIFRocm93biB3aGVuIGF0dGVtcHRpbmcgdG8gcXVldWUgbW9yZSB0aGFuIDI1NSBt" + - "ZXNzYWdlcy4KLy8vCi8vLyBTZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLXNlbmQjZW1pdAovLy8KLy8vIFtBY3Rpb24gbGlzdCBpcyB0b28g" + - "bG9uZ106IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL2Jvb2svZXhpdC1jb2RlcyMzMwovLy8KaW5saW5lIGZ1biBlbWl0KGJvZHk6IENlbGwpIHsKICAgIC8vIGV4" + - "dF9vdXRfbXNnX2luZm8kMTEgc3JjOk1zZ0FkZHJlc3NJbnQgZGVzdDpNc2dBZGRyZXNzRXh0IGNyZWF0ZWRfbHQ6dWludDY0IGNyZWF0ZWRfYXQ6dWludDMyCiAgICAv" + - "LyAgICAgICAgICAgICAgICAgICAgIG1heWJlOiBzdGF0ZUluaXQgKGZhbHNlKSBib2R5UmVmOiBib29sICh0cnVlKQogICAgbGV0IGM6IENlbGwgPSBiZWdpbkNlbGwo" + - "KQogICAgICAgIC5zdG9yZVVpbnQoMTUyMTE4MDcyMDI3Mzg3NTI4MTc5NjA0Mzg0NjQ1MTMsIDEwNCkKICAgICAgICAuc3RvcmVSZWYoYm9keSkKICAgICAgICAuZW5k" + - "Q2VsbCgpOwogICAgc2VuZFJhd01lc3NhZ2UoYywgMCk7Cn0KCi8vLyBHbG9iYWwgZnVuY3Rpb24uCi8vLwovLy8gQWdyZWVzIHRvIGJ1eSBzb21lIGdhcyB0byBmaW5p" + - "c2ggdGhlIGN1cnJlbnQgdHJhbnNhY3Rpb24gYnkgc2V0dGluZyB0aGUgYGdhc19saW1pdGAgdG8gaXRzIG1heGltdW0gYWxsb3dlZCB2YWx1ZSBvZiAyXjYzIC0gMSBh" + - "bmQgcmVzZXR0aW5nIHRoZSBgZ2FzX2NyZWRpdGAgdG8gMC4gVGhpcyBhY3Rpb24gaXMgcmVxdWlyZWQgdG8gcHJvY2VzcyBleHRlcm5hbCBtZXNzYWdlcywgd2hpY2gg" + - "YnJpbmcgbm8gdmFsdWUgKGhlbmNlIG5vIGdhcykgd2l0aCB0aGVtc2VsdmVzLgovLy8KLy8vIGBgYHRhY3QKLy8vIGNvbnRyYWN0IFRpbWVvdXQgewovLy8gICAgIHRp" + - "bWVvdXQ6IEludDsKLy8vCi8vLyAgICAgaW5pdCgpIHsKLy8vICAgICAgICAgc2VsZi50aW1lb3V0ID0gbm93KCkgKyA1ICogNjA7IC8vIDUgbWludXRlcyBmcm9tIG5v" + - "dwovLy8gICAgIH0KLy8vCi8vLyAgICAgZXh0ZXJuYWwoInRpbWVvdXQiKSB7Ci8vLyAgICAgICAgIGlmIChub3coKSA+IHNlbGYudGltZW91dCkgewovLy8gICAgICAg" + - "ICAgICAgYWNjZXB0TWVzc2FnZSgpOyAvLyBzdGFydCBhY2NlcHRpbmcgZXh0ZXJuYWwgbWVzc2FnZXMgb25jZSB0aW1lb3V0IHdlbnQgb3V0Ci8vLyAgICAgICAgIH0K" + - "Ly8vICAgICB9Ci8vLyB9Ci8vLyBgYGAKLy8vCi8vLyBTZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWdhcyNhY2NlcHRtZXNzYWdlCi8vLwph" + - "c20gZnVuIGFjY2VwdE1lc3NhZ2UoKSB7IEFDQ0VQVCB9CgovLy8gR2xvYmFsIGZ1bmN0aW9uLgovLy8KLy8vIENvbW1pdHMgdGhlIGN1cnJlbnQgc3RhdGUgb2YgcmVn" + - "aXN0ZXJzIGBjNGAgKHBlcnNpc3RlbnQgZGF0YSkgYW5kIGBjNWAgKGFjdGlvbnMpLCBzbyB0aGF0IHRoZSBjdXJyZW50IGV4ZWN1dGlvbiBpcyBjb25zaWRlcmVkICJz" + - "dWNjZXNzZnVsIiB3aXRoIHRoZSBzYXZlZCB2YWx1ZXMgZXZlbiBpZiBhbiBleGNlcHRpb24gaW4gY29tcHV0ZSBwaGFzZSBpcyB0aHJvd24gbGF0ZXIuCi8vCi8vLyBg" + - "YGB0YWN0Ci8vLyBmdW4gZXhhbXBsZSgpIHsKLy8vICAgICBjb21taXQoKTsgIC8vIG5vdywgdHJhbnNhY3Rpb24gaXMgY29uc2lkZXJlZCAic3VjY2Vzc2Z1bCIKLy8v" + - "ICAgICB0aHJvdyg0Mik7IC8vIGFuZCB0aGlzIHdvbid0IGZhaWwgaXQKLy8vIH0KLy8vIGBgYAovLy8KLy8vIFNlZTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcv" + - "cmVmL2NvcmUtY29udGV4dHN0YXRlI2NvbW1pdAovLy8KYXNtIGZ1biBjb21taXQoKSB7IENPTU1JVCB9Cg=="; + "ZXNzYWdlcy4KLy8vCi8vLyBTZWU6Ci8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLXNlbmQjbWVzc2FnZQovLy8gKiBodHRwczovL2RvY3Mu" + + "dGFjdC1sYW5nLm9yZy9ib29rL21lc3NhZ2UtbW9kZQovLy8KLy8vIFtBY3Rpb24gbGlzdCBpcyB0b28gbG9uZ106IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL2Jv" + + "b2svZXhpdC1jb2RlcyMzMwovLy8KYXNtIGZ1biBtZXNzYWdlKHBhcmFtczogTWVzc2FnZVBhcmFtZXRlcnMpIHsKICAgIE5FV0MKICAgIGJ7MDF9IFNUU0xJQ0VDT05T" + + "VCAgLy8gc3RvcmUgdGFnID0gJDAgYW5kIGlocl9kaXNhYmxlZCA9IHRydWUKICAgIDEgU1RJICAgICAgICAgICAgICAgLy8gc3RvcmUgYGJvdW5jZWAKICAgIGJ7MDAw" + + "fSBTVFNMSUNFQ09OU1QgLy8gc3RvcmUgYm91bmNlZCA9IGZhbHNlIGFuZCBzcmMgPSBhZGRyX25vbmUKICAgIFNUU0xJQ0UgICAgICAgICAgICAgLy8gc3RvcmUgYHRv" + + "YAogICAgU1dBUAogICAgU1RHUkFNUyAgICAgICAgICAgICAvLyBzdG9yZSBgdmFsdWVgCiAgICAxMDYgUFVTSElOVCAgICAgICAgIC8vIDEgKyA0ICsgNCArIDY0ICsg" + + "MzIgKyAxCiAgICBTVFpFUk9FUwogICAgLy8g4oaSIFN0YWNrIHN0YXRlCiAgICAvLyBzMDogQnVpbGRlcgogICAgLy8gczE6IGBib2R5YAogICAgLy8gczI6IGBtb2Rl" + + "YAogICAgU1RESUNUCiAgICBFTkRDCiAgICBTV0FQCiAgICBTRU5EUkFXTVNHCn0KCi8vLyBHbG9iYWwgZnVuY3Rpb24uIFF1ZXVlcyB0aGUgbWVzc2FnZSB0byBiZSBz" + + "ZW50IHVzaW5nIGEgYFNlbmRQYXJhbWV0ZXJzYCBzdHJ1Y3QuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKSB7Ci8vLyAgICAgc2VuZChTZW5kUGFyYW1l" + + "dGVyc3sKLy8vICAgICAgICAgdG86IHNlbmRlcigpLCAgICAvLyBiYWNrIHRvIHRoZSBzZW5kZXIsCi8vLyAgICAgICAgIHZhbHVlOiB0b24oIjEiKSwgLy8gd2l0aCAx" + + "IFRvbmNvaW4gKDFfMDAwXzAwMF8wMDAgbmFub1RvbmNvaW4pLAovLy8gICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFuZCBubyBtZXNzYWdlIGJvZHkKLy8vICAg" + + "ICB9KTsKLy8vIH0KLy8vIGBgYAovLy8KLy8vICMjIyMgRXhpdCBjb2RlcwovLy8KLy8vICogMzM6IFtBY3Rpb24gbGlzdCBpcyB0b28gbG9uZ10g4oCUIFRocm93biB3" + + "aGVuIGF0dGVtcHRpbmcgdG8gcXVldWUgbW9yZSB0aGFuIDI1NSBtZXNzYWdlcy4KLy8vCi8vLyBTZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3Jl" + + "LXNlbmQjc2VuZAovLy8KLy8vIFtBY3Rpb24gbGlzdCBpcyB0b28gbG9uZ106IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL2Jvb2svZXhpdC1jb2RlcyMzMwovLy8K" + + "YXNtIGZ1biBzZW5kKHBhcmFtczogU2VuZFBhcmFtZXRlcnMpIHsKICAgIC8vIEluc3RydWN0aW9ucyBhcmUgZ3JvdXBlZCwgYW5kIHRoZSBzdGFjayBzdGF0ZXMgdGhl" + + "eSBwcm9kdWNlIGFzIGEgZ3JvdXAgYXJlIHNob3duIHJpZ2h0IGFmdGVyLgogICAgLy8gSW4gdGhlIGVuZCwgb3VyIG1lc3NhZ2UgQ2VsbCBzaG91bGQgaGF2ZSB0aGUg" + + "Zm9sbG93aW5nIFRMLUIgc3RydWN0dXJlOgogICAgLy8gbWVzc2FnZSRfIHtYOlR5cGV9CiAgICAvLyAgIGluZm86Q29tbW9uTXNnSW5mb1JlbGF4ZWQKICAgIC8vICAg" + + "aW5pdDooTWF5YmUgKEVpdGhlciBTdGF0ZUluaXQgXlN0YXRlSW5pdCkpCiAgICAvLyAgIGJvZHk6KEVpdGhlciBYIF5YKQogICAgLy8gPSBNZXNzYWdlUmVsYXhlZCBY" + + "OwoKICAgIC8vIOKGkiBTdGFjayBzdGF0ZQogICAgLy8gczA6IGBwYXJhbXMuYm91bmNlYAogICAgLy8gczE6IGBwYXJhbXMudG9gCiAgICAvLyBzMjogYHBhcmFtcy52" + + "YWx1ZWAKICAgIC8vIHMzOiBgcGFyYW1zLmRhdGFgCiAgICAvLyBzNDogYHBhcmFtcy5jb2RlYAogICAgLy8gczU6IGBwYXJhbXMuYm9keWAKICAgIC8vIHM2OiBgcGFy" + + "YW1zLm1vZGVgCiAgICAvLyBGb3IgYnJldml0eSwgdGhlICJwYXJhbXMiIHByZWZpeCB3aWxsIGJlIG9taXR0ZWQgZnJvbSBub3cgb24uCgogICAgLy8gR3JvdXAgMTog" + + "U3RvcmluZyB0aGUgYGJvdW5jZWAsIGB0b2AgYW5kIGB2YWx1ZWAgaW50byBhIEJ1aWxkZXIKICAgIE5FV0MKICAgIGJ7MDF9IFNUU0xJQ0VDT05TVCAgLy8gc3RvcmUg" + + "dGFnID0gJDAgYW5kIGlocl9kaXNhYmxlZCA9IHRydWUKICAgIDEgU1RJICAgICAgICAgICAgICAgLy8gc3RvcmUgYGJvdW5jZWAKICAgIGJ7MDAwfSBTVFNMSUNFQ09O" + + "U1QgLy8gc3RvcmUgYm91bmNlZCA9IGZhbHNlIGFuZCBzcmMgPSBhZGRyX25vbmUKICAgIFNUU0xJQ0UgICAgICAgICAgICAgLy8gc3RvcmUgYHRvYAogICAgU1dBUAog" + + "ICAgU1RHUkFNUyAgICAgICAgICAgICAvLyBzdG9yZSBgdmFsdWVgCiAgICAxMDUgUFVTSElOVCAgICAgICAgIC8vIDEgKyA0ICsgNCArIDY0ICsgMzIKICAgIFNUWkVS" + + "T0VTICAgICAgICAgICAgLy8gc3RvcmUgY3VycmVuY3lfY29sbGVjdGlvbiwgaWhyX2ZlZSwgZndkX2ZlZSwgY3JlYXRlZF9sdCBhbmQgY3JlYXRlZF9hdAogICAgLy8g" + + "4oaSIFN0YWNrIHN0YXRlCiAgICAvLyBzMDogQnVpbGRlcgogICAgLy8gczE6IGBkYXRhYAogICAgLy8gczI6IGBjb2RlYAogICAgLy8gczM6IGBib2R5YAogICAgLy8g" + + "czQ6IGBtb2RlYAoKICAgIC8vIEdyb3VwIDI6IFBsYWNpbmcgdGhlIEJ1aWxkZXIgYWZ0ZXIgY29kZSBhbmQgZGF0YSwgdGhlbiBjaGVja2luZyB0aG9zZSBmb3IgbnVs" + + "bGFiaWxpdHkKICAgIHMyIFhDSEcwCiAgICBEVVAyCiAgICBJU05VTEwKICAgIFNXQVAKICAgIElTTlVMTAogICAgQU5ECiAgICAvLyDihpIgU3RhY2sgc3RhdGUKICAg" + + "IC8vIHMwOiAtMSAodHJ1ZSkgaWYgYGRhdGFgIGFuZCBgY29kZWAgYXJlIGJvdGggbnVsbCwgMCAoZmFsc2UpIG90aGVyd2lzZQogICAgLy8gczE6IGBjb2RlYAogICAg" + + "Ly8gczI6IGBkYXRhYAogICAgLy8gczM6IEJ1aWxkZXIKICAgIC8vIHM0OiBgYm9keWAKICAgIC8vIHM1OiBgbW9kZWAKCiAgICAvLyBHcm91cCAzOiBMZWZ0IGJyYW5j" + + "aCBvZiB0aGUgSUZFTFNFLCBleGVjdXRlZCBpZiBzMCBpcyAtMSAodHJ1ZSkKICAgIDx7CiAgICAgICAgRFJPUDIgLy8gZHJvcCBgZGF0YWAgYW5kIGBjb2RlYCwgc2lu" + + "Y2UgZWl0aGVyIG9mIHRob3NlIGlzIG51bGwKICAgICAgICBiezB9IFNUU0xJQ0VDT05TVAogICAgfT4gUFVTSENPTlQKCiAgICAvLyBHcm91cCAzOiBSaWdodCBicmFu" + + "Y2ggb2YgdGhlIElGRUxTRSwgZXhlY3V0ZWQgaWYgczAgaXMgMCAoZmFsc2UpCiAgICA8ewogICAgICAgIC8vIF8gc3BsaXRfZGVwdGg6KE1heWJlICgjIyA1KSkKICAg" + + "ICAgICAvLyAgIHNwZWNpYWw6KE1heWJlIFRpY2tUb2NrKQogICAgICAgIC8vICAgY29kZTooTWF5YmUgXkNlbGwpCiAgICAgICAgLy8gICBkYXRhOihNYXliZSBeQ2Vs" + + "bCkKICAgICAgICAvLyAgIGxpYnJhcnk6KE1heWJlIF5DZWxsKQogICAgICAgIC8vID0gU3RhdGVJbml0OwogICAgICAgIFJPVCAgICAgICAgICAgICAgICAvLyBwbGFj" + + "ZSBtZXNzYWdlIEJ1aWxkZXIgb24gdG9wCiAgICAgICAgYnsxMH0gU1RTTElDRUNPTlNUIC8vIHN0b3JlIE1heWJlID0gdHJ1ZSwgRWl0aGVyID0gZmFsc2UKICAgICAg" + + "ICAvLyBTdGFydCBjb21wb3NpbmcgaW5saW5lZCBTdGF0ZUluaXQKICAgICAgICBiezAwfSBTVFNMSUNFQ09OU1QgLy8gc3RvcmUgc3BsaXRfZGVwdGggYW5kIHNwZWNp" + + "YWwgZmlyc3QKICAgICAgICBTVERJQ1QgICAgICAgICAgICAgLy8gc3RvcmUgY29kZQogICAgICAgIFNURElDVCAgICAgICAgICAgICAvLyBzdG9yZSBkYXRhCiAgICAg" + + "ICAgYnswfSBTVFNMSUNFQ09OU1QgIC8vIHN0b3JlIGxpYnJhcnkKICAgIH0+IFBVU0hDT05UCgogICAgLy8gR3JvdXAgMzogSUZFTFNFIHRoYXQgZG9lcyB0aGUgYnJh" + + "bmNoaW5nIHNob3duIGFib3ZlCiAgICBJRkVMU0UKICAgIC8vIOKGkiBTdGFjayBzdGF0ZQogICAgLy8gczA6IEJ1aWxkZXIKICAgIC8vIHMxOiBudWxsIG9yIFN0YXRl" + + "SW5pdAogICAgLy8gczI6IGBib2R5YAogICAgLy8gczM6IGBtb2RlYAoKICAgIC8vIEdyb3VwIDQ6IEZpbmFsaXppbmcgdGhlIG1lc3NhZ2UKICAgIFNURElDVCAvLyBz" + + "dG9yZSBgYm9keWAgYXMgcmVmIHdpdGggYW4gZXh0cmEgTWF5YmUgYml0LCBzaW5jZSBgYm9keWAgbWlnaHQgYmUgbnVsbAogICAgRU5EQwogICAgLy8g4oaSIFN0YWNr" + + "IHN0YXRlCiAgICAvLyBzMDogQ2VsbAogICAgLy8gczE6IGBtb2RlYAoKICAgIC8vIEdyb3VwIDU6IFNlbmRpbmcgdGhlIG1lc3NhZ2UsIHdpdGggYG1vZGVgIG9uIHRv" + + "cAogICAgU1dBUAogICAgU0VORFJBV01TRyAvLyBodHRwczovL2dpdGh1Yi5jb20vdGFjdC1sYW5nL3RhY3QvaXNzdWVzLzE1NTgKfQoKLy8vIFN0cnVjdCBmb3Igc3Bl" + + "Y2lmeWluZyB0aGUgZGVwbG95bWVudCBtZXNzYWdlIHBhcmFtZXRlcnMgb2YgdGhlIGBkZXBsb3koKWAgZnVuY3Rpb24uIEF2YWlsYWJsZSBzaW5jZSBUYWN0IDEuNi4w" + + "LgovLy8KLy8vIFNlZTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtc2VuZCNkZXBsb3kKLy8vCnN0cnVjdCBEZXBsb3lQYXJhbWV0ZXJzIHsKICAg" + + "IC8vLyBBbiA4LWJpdCB2YWx1ZSB0aGF0IGNvbmZpZ3VyZXMgaG93IHRvIHNlbmQgYSBtZXNzYWdlLCBkZWZhdWx0cyB0byAwLgogICAgLy8vIFNlZTogaHR0cHM6Ly9k" + + "b2NzLnRhY3QtbGFuZy5vcmcvYm9vay9tZXNzYWdlLW1vZGUKICAgIG1vZGU6IEludCA9IFNlbmREZWZhdWx0TW9kZTsKCiAgICAvLy8gT3B0aW9uYWwgbWVzc2FnZSBi" + + "b2R5IGFzIGEgYENlbGxgLgogICAgYm9keTogQ2VsbD8gPSBudWxsOwoKICAgIC8vLyBUaGUgYW1vdW50IG9mIG5hbm9Ub25jb2lucyB5b3Ugd2FudCB0byBzZW5kIHdp" + + "dGgKICAgIC8vLyB0aGUgbWVzc2FnZS4gVGhpcyB2YWx1ZSBpcyB1c2VkIHRvIGNvdmVyIGZvcndhcmQgZmVlcywKICAgIC8vLyB1bmxlc3MgdGhlIG9wdGlvbmFsIGZs" + + "YWcgYFNlbmRQYXlGd2RGZWVzU2VwYXJhdGVseWAgaXMgdXNlZC4KICAgIHZhbHVlOiBJbnQ7CgogICAgLy8vIFdoZW4gc2V0IHRvIGB0cnVlYCAoZGVmYXVsdCkgbWVz" + + "c2FnZSBib3VuY2VzIGJhY2sgdG8gdGhlIHNlbmRlciBpZgogICAgLy8vIHRoZSByZWNpcGllbnQgY29udHJhY3QgZG9lc24ndCBleGlzdCBvciB3YXNuJ3QgYWJsZSB0" + + "byBwcm9jZXNzIHRoZSBtZXNzYWdlLgogICAgYm91bmNlOiBCb29sID0gdHJ1ZTsKCiAgICAvLy8gSW5pdGlhbCBwYWNrYWdlIG9mIHRoZSBjb250cmFjdCAoaW5pdGlh" + + "bCBjb2RlIGFuZCBpbml0aWFsIGRhdGEpLgogICAgLy8vIFNlZTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvYm9vay9leHByZXNzaW9ucyNpbml0b2YKICAgIGlu" + + "aXQ6IFN0YXRlSW5pdDsKfQoKLy8vIEdsb2JhbCBmdW5jdGlvbi4gQXZhaWxhYmxlIHNpbmNlIFRhY3QgMS42LjAuCi8vLwovLy8gUXVldWVzIHRoZSBjb250cmFjdCBk" + + "ZXBsb3ltZW50IG1lc3NhZ2UgdG8gYmUgc2VudCB1c2luZyB0aGUgYERlcGxveVBhcmFtZXRlcnNgIHN0cnVjdC4gQWxsb3dzIGZvciBjaGVhcGVyIG9uLWNoYWluIGRl" + + "cGxveW1lbnRzIGNvbXBhcmVkIHRvIHRoZSBgc2VuZCgpYCBmdW5jdGlvbi4KLy8vCi8vLyBUaGUgYERlcGxveVBhcmFtZXRlcnNgIHN0cnVjdCBjb25zaXN0cyBvZiB0" + + "aGUgZm9sbG93aW5nIGZpZWxkczoKLy8vICogYG1vZGU6IEludGAsIGFuIDgtYml0IHZhbHVlIHRoYXQgY29uZmlndXJlcyBob3cgdG8gc2VuZCBhIG1lc3NhZ2UsIGRl" + + "ZmF1bHRzIHRvIDAuCi8vLyAqIGBib2R5OiBDZWxsP2AsIG9wdGlvbmFsIG1lc3NhZ2UgYm9keSBhcyBhIGBDZWxsYC4KLy8vICogYHZhbHVlOiBJbnRgLCB0aGUgYW1v" + + "dW50IG9mIG5hbm9Ub25jb2lucyB5b3Ugd2FudCB0byBzZW5kIHdpdGggdGhlIG1lc3NhZ2UuCi8vLyAgIFRoaXMgdmFsdWUgaXMgdXNlZCB0byBjb3ZlciBmb3J3YXJk" + + "IGZlZXMsIHVubGVzcyB0aGUgb3B0aW9uYWwgZmxhZyBgU2VuZFBheUZ3ZEZlZXNTZXBhcmF0ZWx5YCBpcyB1c2VkLgovLy8gKiBgYm91bmNlOiBCb29sYCwgd2hlbiBz" + + "ZXQgdG8gYHRydWVgIChkZWZhdWx0KSBtZXNzYWdlIGJvdW5jZXMgYmFjayB0byB0aGUgc2VuZGVyCi8vLyAgICBpZiB0aGUgcmVjaXBpZW50IGNvbnRyYWN0IGRvZXNu" + + "J3QgZXhpc3Qgb3Igd2Fzbid0IGFibGUgdG8gcHJvY2VzcyB0aGUgbWVzc2FnZS4KLy8vICogYGluaXQ6IFN0YXRlSW5pdGAsIGluaXQgcGFja2FnZSBvZiB0aGUgY29u" + + "dHJhY3QgKGluaXRpYWwgY29kZSBhbmQgaW5pdGlhbCBkYXRhKS4KLy8vCi8vLyBgYGB0YWN0Ci8vLyBmdW4gZXhhbXBsZSgpIHsKLy8vICAgICBkZXBsb3koRGVwbG95" + + "UGFyYW1ldGVyc3sKLy8vICAgICAgICAgaW5pdDogaW5pdE9mIFNvbWVDb250cmFjdCgpLCAvLyB3aXRoIGluaXRpYWwgY29kZSBhbmQgZGF0YSBvZiBTb21lQ29udHJh" + + "Y3QKLy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBhbmQgbm8gYWRkaXRpb25hbCBtZXNzYWdlIGJvZHkKLy8vICAgICAgICAgbW9kZTog" + + "U2VuZElnbm9yZUVycm9ycywgICAgICAvLyBza2lwIHRoZSBtZXNzYWdlIGluIGNhc2Ugb2YgZXJyb3JzCi8vLyAgICAgICAgIHZhbHVlOiB0b24oIjEiKSwgICAgICAg" + + "ICAgICAgLy8gc2VuZCAxIFRvbmNvaW4gKDFfMDAwXzAwMF8wMDAgbmFub1RvbmNvaW4pCi8vLyAgICAgfSk7Ci8vLyB9Ci8vLyBgYGAKLy8vCi8vLyAjIyMjIEV4aXQg" + + "Y29kZXMKLy8vCi8vLyAqIDMzOiBbQWN0aW9uIGxpc3QgaXMgdG9vIGxvbmddIOKAlCBUaHJvd24gd2hlbiBhdHRlbXB0aW5nIHRvIHF1ZXVlIG1vcmUgdGhhbiAyNTUg" + + "bWVzc2FnZXMuCi8vLwovLy8gU2VlOgovLy8gKiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1zZW5kI2RlcGxveQovLy8gKiBodHRwczovL2RvY3Mu" + + "dGFjdC1sYW5nLm9yZy9ib29rL21lc3NhZ2UtbW9kZQovLy8KLy8vIFtBY3Rpb24gbGlzdCBpcyB0b28gbG9uZ106IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL2Jv" + + "b2svZXhpdC1jb2RlcyMzMwovLy8KYXNtIGZ1biBkZXBsb3kocGFyYW1zOiBEZXBsb3lQYXJhbWV0ZXJzKSB7CiAgICAvLyBJbnN0cnVjdGlvbnMgYXJlIGdyb3VwZWQs" + + "IGFuZCB0aGUgc3RhY2sgc3RhdGVzIHRoZXkgcHJvZHVjZSBhcyBhIGdyb3VwIGFyZSBzaG93biByaWdodCBhZnRlci4KICAgIC8vCiAgICAvLyDihpIgU3RhY2sgc3Rh" + + "dGUKICAgIC8vIHMwOiBgcGFyYW1zLmluaXQuZGF0YWAKICAgIC8vIHMxOiBgcGFyYW1zLmluaXQuY29kZWAKICAgIC8vIHMyOiBgcGFyYW1zLmJvdW5jZWAKICAgIC8v" + + "IHMzOiBgcGFyYW1zLnZhbHVlYAogICAgLy8gczQ6IGBwYXJhbXMuYm9keWAKICAgIC8vIHM1OiBgcGFyYW1zLm1vZGVgCiAgICAvLyBGb3IgYnJldml0eSwgdGhlICJw" + + "YXJhbXMiIHByZWZpeCB3aWxsIGJlIG9taXR0ZWQgZnJvbSBub3cgb24uCgogICAgLy8gR3JvdXAgMTogUHJlcGFyYXRpb24gb2YgbmVlZGVkIHBhcmFtcwogICAgLy8g" + + "Rm9yIGFsbW9zdCBpZGVudGljYWwgbG9naWMgYW5kIGluc3RydWN0aW9ucywKICAgIC8vIHNlZSBjb21tZW50cyBpbnNpZGUgYGNvbnRyYWN0SGFzaCgpYCBmdW5jdGlv" + + "biBpbiBjb250cmFjdC50YWN0CiAgICA0IDEgQkxLUFVTSCAvLyBwdXNoZXMgMiBjb3BpZXMgb2YgYGluaXQuY29kZWAgYW5kIGBpbml0LmRhdGFgCiAgICBIQVNIQ1Ug" + + "Ly8gYGluaXQuZGF0YWAgaGFzaAogICAgU1dBUAogICAgSEFTSENVIC8vIGBpbml0LmNvZGVgIGhhc2gKICAgIFNXQVAyCiAgICBDREVQVEggLy8gYGluaXQuZGF0YWAg" + + "ZGVwdGgKICAgIFNXQVAKICAgIENERVBUSCAvLyBgaW5pdC5jb2RlYCBkZXB0aAoKICAgIC8vIEdyb3VwIDI6IENhbGN1bGF0aW5nIGRlc3RpbmF0aW9uIGFkZHJlc3MK" + + "ICAgIC8vIEZvciBhbG1vc3QgaWRlbnRpY2FsIGxvZ2ljIGFuZCBpbnN0cnVjdGlvbnMsCiAgICAvLyBzZWUgY29tbWVudHMgaW5zaWRlIGBjb250cmFjdEhhc2goKWAg" + + "ZnVuY3Rpb24gaW4gY29udHJhY3QudGFjdAogICAgMTMxMzgwIElOVCAvLyAoMiA8PCAxNikgfCAoMSA8PCA4KSB8IDB4MzQKICAgIE5FV0MKICAgIDI0IFNUVQogICAg" + + "MTYgU1RVCiAgICAxNiBTVFUKICAgIDI1NiBTVFUKICAgIDI1NiBTVFUKICAgIE9ORSBIQVNIRVhUX1NIQTI1NiAvLyBvYnRhaW5zIGhhc2ggcGFydCAoYWNjb3VudCBp" + + "ZCkgb2YgdGhlIGFkZHJlc3MKICAgIC8vIOKGkiBTdGFjayBzdGF0ZQogICAgLy8gczA6IGRlc3RBZGRyKGhhc2ggcGFydCkKICAgIC8vIHMxOiBgaW5pdC5kYXRhYAog" + + "ICAgLy8gczI6IGBpbml0LmNvZGVgCiAgICAvLyBzMyBhbmQgYmVsb3c6IGBib3VuY2VgLCBgdmFsdWVgLCBgYm9keWAsIGBtb2RlYAoKICAgIC8vIEdyb3VwIDM6IEJ1" + + "aWxkaW5nIGEgbWVzc2FnZSAoQ29tbW9uTXNnSW5mb1JlbGF4ZWQpCiAgICBzMyBYQ0hHMCAgICAgICAgICAgLy8gc3dhcHMgYGJvdW5jZWAgd2l0aCBkZXN0QWRkciho" + + "YXNoIHBhcnQpCiAgICBORVdDCiAgICBiezAxfSBTVFNMSUNFQ09OU1QgLy8gc3RvcmUgdGFnID0gJDAgYW5kIGlocl9kaXNhYmxlZCA9IHRydWUKICAgIDEgU1RJICAg" + + "ICAgICAgICAgICAvLyBzdG9yZSBgYm91bmNlYAogICAgczEgczIgWENIRyAgICAgICAgIC8vIHN3YXAgYGluaXQuZGF0YWAgd2l0aCBgaW5pdC5jb2RlYCwgcGxhY2lu" + + "ZyBjb2RlIG9uIHMxCiAgICBTVFJFRiAgICAgICAgICAgICAgLy8gc3RvcmUgYGluaXQuY29kZWAKICAgIFNUUkVGICAgICAgICAgICAgICAvLyBzdG9yZSBgaW5pdC5k" + + "YXRhYAogICAgLy8gSW5saW5lIFN0YXRlSW5pdDoKICAgIGJ7MDAwMTAwMDAwMDAwMDB9IFNUU0xJQ0VDT05TVAogICAgLy8gMCArIDAwICsgMTAgKyAwICsgMDAwMDAw" + + "MDAKICAgIC8vIDEpIDAgLSBib3VuY2VkID0gZmFsc2UKICAgIC8vIDIpIDAwIC0gc3JjID0gYWRkcl9ub25lCiAgICAvLyAzKSAxMCAtIHRhZyBvZiBhZGRyX3N0ZCAo" + + "cGFydCBvZiBkZXN0KQogICAgLy8gNCkgMCAtIE1heWJlIEFueWNhc3QgPSBmYWxzZQogICAgLy8gNSkgMDAwMDAwMDAgLSB3b3JrY2hhaW5faWQgKHBhcnQgb2YgZGVz" + + "dCkKICAgIC8vCiAgICAyNTYgU1RVICAgICAvLyBzdG9yZSBkZXN0QWRkcihoYXNoIHBhcnQpCiAgICBTV0FQICAgICAgICAvLyBCdWlsZGVyIG9uIHRvcCwgYHZhbHVl" + + "YCBiZWxvdwogICAgU1RHUkFNUyAgICAgLy8gc3RvcmUgYHZhbHVlYAogICAgMTA1IFBVU0hJTlQgLy8gMSArIDQgKyA0ICsgNjQgKyAzMgogICAgU1RaRVJPRVMgICAg" + + "Ly8gc3RvcmUgY3VycmVuY3lfY29sbGVjdGlvbiwgaWhyX2ZlZSwgZndkX2ZlZSwgY3JlYXRlZF9sdCBhbmQgY3JlYXRlZF9hdAoKICAgIC8vIEdyb3VwIDQ6IENvbnRp" + + "bnVlIGJ1aWxkaW5nIGEgbWVzc2FnZSAoQ29tbW9uTXNnSW5mb1JlbGF4ZWQgaW50byBNZXNzYWdlUmVsYXhlZCkKICAgIC8vIFJlbWFpbmluZyBiaXRzIG9mIE1lc3Nh" + + "Z2VSZWxheGVkOgogICAgYnsxMDAwMTEwfSBTVFNMSUNFQ09OU1QKICAgIC8vIDEwICsgMCArIDAgKyAxICsgMSArIDAKICAgIC8vIDEwIC0gTWF5YmUgKEVpdGhlciBT" + + "dGF0ZUluaXQgXlN0YXRlSW5pdCkgPSB0cnVlIGZhbHNlCiAgICAvLyAwIC0gc3BsaXRfZGVwdGg6KE1heWJlICgjIyA1KSkgPSBmYWxzZQogICAgLy8gMCA9IHNwZWNp" + + "YWw6KE1heWJlIFRpY2tUb2NrKSA9IGZhbHNlCiAgICAvLyAxID0gY29kZTooTWF5YmUgXkNlbGwpID0gdHJ1ZQogICAgLy8gMSA9IGRhdGE6KE1heWJlIF5DZWxsKSA9" + + "IHRydWUKICAgIC8vIDAgPSBsaWJyYXJ5OihNYXliZSBeQ2VsbCkgPSBmYWxzZQogICAgLy8KICAgIFNURElDVCAvLyBzdG9yZSBgYm9keWAgYXMgcmVmIHdpdGggYW4g" + + "ZXh0cmEgTWF5YmUgYml0LCBzaW5jZSBgYm9keWAgbWlnaHQgYmUgbnVsbAogICAgRU5EQyAgIC8vIGZpbmFsaXplIHRoZSBtZXNzYWdlCiAgICAvLyDihpIgU3RhY2sg" + + "c3RhdGUKICAgIC8vIHMwOiBDZWxsCiAgICAvLyBzMTogcGFyYW1zLmBtb2RlYAoKICAgIC8vIEdyb3VwIDU6IFNlbmRpbmcgdGhlIG1lc3NhZ2UsIHdpdGggYG1vZGVg" + + "IG9uIHRvcAogICAgU1dBUAogICAgU0VORFJBV01TRwp9CgovLy8gR2xvYmFsIGZ1bmN0aW9uLiBBdmFpbGFibGUgc2luY2UgVGFjdCAxLjYuMS4KLy8vCi8vLyBRdWV1" + + "ZXMgYW4gZW1wdHkgbWVzc2FnZSB0byBiZSBzZW50IHdpdGggdGhlIGBTZW5kUmVtYWluaW5nVmFsdWVgIG1vZGUgYW5kIHRoZSBgU2VuZElnbm9yZUVycm9yc2AgZmxh" + + "ZyB0byB0aGUgZGVzdGluYXRpb24gYWRkcmVzcyBgdG9gLgovLy8gVGhpcyBpcyB0aGUgbW9zdCBnYXMtZWZmaWNpZW50IHdheSB0byBzZW5kIHRoZSByZW1haW5pbmcg" + + "dmFsdWUgZnJvbSB0aGUgaW5jb21pbmcgbWVzc2FnZSB0byB0aGUgZ2l2ZW4gYWRkcmVzcy4KLy8vCi8vLyBUaGlzIGZ1bmN0aW9uIHdvbid0IGZvcndhcmQgZXhjZXNz" + + "IHZhbHVlcyBpZiBhbnkgb3RoZXIgbWVzc2FnZS1zZW5kaW5nIGZ1bmN0aW9ucyB3ZXJlIGNhbGxlZCBpbiB0aGUgc2FtZSByZWNlaXZlciBiZWZvcmUuCi8vLwovLy8g" + + "YGBgdGFjdAovLy8gZnVuIGV4YW1wbGVzKCkgewovLy8gICAgIC8vIEZvcndhcmQgdGhlIHJlbWFpbmluZyB2YWx1ZSBiYWNrIHRvIHRoZSBzZW5kZXIKLy8vICAgICBj" + + "YXNoYmFjayhzZW5kZXIoKSk7Ci8vLwovLy8gICAgIC8vIFRoZSBjYXNoYmFjaygpIGZ1bmN0aW9uIGFib3ZlIGlzIGNoZWFwZXIsIGJ1dCBmdW5jdGlvbmFsbHkKLy8v" + + "ICAgICAvLyBlcXVpdmFsZW50IHRvIHRoZSBmb2xsb3dpbmcgY2FsbCB0byB0aGUgbWVzc2FnZSgpIGZ1bmN0aW9uCi8vLyAgICAgbWVzc2FnZShNZXNzYWdlUGFyYW1l" + + "dGVyc3sKLy8vICAgICAgICAgbW9kZTogU2VuZFJlbWFpbmluZ1ZhbHVlIHwgU2VuZElnbm9yZUVycm9ycywKLy8vICAgICAgICAgYm9keTogbnVsbCwKLy8vICAgICAg" + + "ICAgdmFsdWU6IDAsCi8vLyAgICAgICAgIHRvOiBzZW5kZXIoKSwKLy8vICAgICAgICAgYm91bmNlOiBmYWxzZSwKLy8vICAgICB9KTsKLy8vIH0KLy8vIGBgYAovLy8K" + + "Ly8vICMjIyMgRXhpdCBjb2RlcwovLy8KLy8vICogMzM6IFtBY3Rpb24gbGlzdCBpcyB0b28gbG9uZ10g4oCUIFRocm93biB3aGVuIGF0dGVtcHRpbmcgdG8gcXVldWUg" + + "bW9yZSB0aGFuIDI1NSBtZXNzYWdlcy4KLy8vCi8vLyBTZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLXNlbmQjY2FzaGJhY2sKLy8vCi8vLyBb" + + "QWN0aW9uIGxpc3QgaXMgdG9vIGxvbmddOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9ib29rL2V4aXQtY29kZXMjMzMKLy8vCmFzbSBmdW4gY2FzaGJhY2sodG86" + + "IEFkZHJlc3MpIHsKICAgIE5FV0MKICAgIHh7NDJffSBTVFNMSUNFQ09OU1QgLy8gLnN0b3JlVWludCgweDEwLCA2KQogICAgU1RTTElDRSAgICAgICAgICAvLyAuc3Rv" + + "cmVBZGRyZXNzKHRvKQogICAgMCBQVVNISU5UICAgICAgICAvLyAwCiAgICAxMTEgU1RVUiAgICAgICAgIC8vIC5zdG9yZVVpbnQoMCwgMTExKQogICAgICAgICAgICAg" + + "ICAgICAgICAvLyA0IHplcm9zIGZvciBjb2lucyBhbmQgMTA3IHplcm9zIGZvciBsdCwgZmVlcywgZXRjLgogICAgRU5EQwogICAgNjYgUFVTSElOVCAgICAgICAvLyBT" + + "ZW5kUmVtYWluaW5nVmFsdWUgfCBTZW5kSWdub3JlRXJyb3JzCiAgICBTRU5EUkFXTVNHCn0KCi8vLyBHbG9iYWwgZnVuY3Rpb24uICoqRGVwcmVjYXRlZCoqIHNpbmNl" + + "IFRhY3QgMS42LjYuIFVzZSBgc2VuZFJhd01lc3NhZ2UoKWAgaW5zdGVhZC4KLy8vCi8vLyBRdWV1ZXMgdGhlIG1lc3NhZ2UgdG8gYmUgc2VudCBieSBzcGVjaWZ5aW5n" + + "IHRoZSBjb21wbGV0ZSBgbXNnYCBjZWxsIGFuZCB0aGUgbWVzc2FnZSBgbW9kZWAuCi8vLwovLy8gIyMjIyBFeGl0IGNvZGVzCi8vLwovLy8gKiAzMzogW0FjdGlvbiBs" + + "aXN0IGlzIHRvbyBsb25nXSDigJQgVGhyb3duIHdoZW4gYXR0ZW1wdGluZyB0byBxdWV1ZSBtb3JlIHRoYW4gMjU1IG1lc3NhZ2VzLgovLy8KLy8vIFNlZToKLy8vICog" + + "aHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtc2VuZCNzZW5kcmF3bWVzc2FnZQovLy8gKiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29y" + + "ZS1zZW5kI25hdGl2ZXNlbmRtZXNzYWdlCi8vLwovLy8gW0FjdGlvbiBsaXN0IGlzIHRvbyBsb25nXTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvYm9vay9leGl0" + + "LWNvZGVzIzMzCi8vLwphc20gZnVuIG5hdGl2ZVNlbmRNZXNzYWdlKG1zZzogQ2VsbCwgbW9kZTogSW50KSB7IFNFTkRSQVdNU0cgfQoKLy8vIEdsb2JhbCBmdW5jdGlv" + + "bi4gQXZhaWxhYmxlIHNpbmNlIFRhY3QgMS42LjYuCi8vLwovLy8gUXVldWVzIHRoZSBtZXNzYWdlIHRvIGJlIHNlbnQgYnkgc3BlY2lmeWluZyB0aGUgY29tcGxldGUg" + + "YG1zZ2AgY2VsbCBhbmQgdGhlIG1lc3NhZ2UgYG1vZGVgLgovLy8KLy8vIFByZWZlciB1c2luZyB0aGUgbW9yZSB1c2VyLWZyaWVuZGx5IGBtZXNzYWdlKClgLCBgZGVw" + + "bG95KClgLCBvciBgc2VuZCgpYCBmdW5jdGlvbnMgdW5sZXNzIHlvdSBoYXZlIGEgY29tcGxleCBsb2dpYyB0aGF0IGNhbm5vdCBiZSBleHByZXNzZWQgb3RoZXJ3aXNl" + + "LgovLy8KLy8vICMjIyMgRXhpdCBjb2RlcwovLy8KLy8vICogMzM6IFtBY3Rpb24gbGlzdCBpcyB0b28gbG9uZ10g4oCUIFRocm93biB3aGVuIGF0dGVtcHRpbmcgdG8g" + + "cXVldWUgbW9yZSB0aGFuIDI1NSBtZXNzYWdlcy4KLy8vCi8vLyBTZWU6Ci8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLXNlbmQjc2VuZHJh" + + "d21lc3NhZ2UKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtc2VuZCNtZXNzYWdlCi8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3Jn" + + "L3JlZi9jb3JlLXNlbmQjZGVwbG95Ci8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLXNlbmQjc2VuZAovLy8KLy8vIFtBY3Rpb24gbGlzdCBp" + + "cyB0b28gbG9uZ106IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL2Jvb2svZXhpdC1jb2RlcyMzMwovLy8KYXNtIGZ1biBzZW5kUmF3TWVzc2FnZShtc2c6IENlbGws" + + "IG1vZGU6IEludCkgeyBTRU5EUkFXTVNHIH0KCi8vLyBHbG9iYWwgZnVuY3Rpb24uICoqRGVwcmVjYXRlZCoqIHNpbmNlIFRhY3QgMS42LjYuIFVzZSBgc2VuZFJhd01l" + + "c3NhZ2VSZXR1cm5Gb3J3YXJkRmVlKClgIGluc3RlYWQuCi8vLwovLy8gU2ltaWxhciB0byBgc2VuZFJhd01lc3NhZ2UoKWAsIGJ1dCBhbHNvIGNhbGN1bGF0ZXMgYW5k" + + "IHJldHVybnMgdGhlIGZvcndhcmQgZmVlIGluIG5hbm9Ub25jb2luLgovLy8KLy8vICMjIyMgRXhpdCBjb2RlcwovLy8KLy8vICogNTogW0ludGVnZXIgb3V0IG9mIGV4" + + "cGVjdGVkIHJhbmdlXSAtIFRocm93biBpZiB0aGUgbWVzc2FnZSBtb2RlIGlzIGludmFsaWQuCi8vLyAqIDc6IFtUeXBlIGNoZWNrIGVycm9yXSAtIFRocm93biBpZiBh" + + "bnkgb2YgdGhlIGJsb2NrY2hhaW4gY29uZmlnLCBjb250cmFjdCBiYWxhbmNlIG9yIGluY29taW5nIG1lc3NhZ2UgdmFsdWUgYXJlIGludmFsaWQuCi8vLyAqIDk6IFtD" + + "ZWxsIHVuZGVyZmxvd10gLSBUaHJvd24gaWYgdGhlIGJsb2NrY2hhaW4gY29uZmlnIGlzIGludmFsaWQuCi8vLyAqIDExOiBbIlVua25vd24iIGVycm9yXSAtIFRocm93" + + "biBpZiB0aGUgbWVzc2FnZSBjZWxsIGlzIGlsbC1mb3JtZWQgb3IgdGhlIGJsb2NrY2hhaW4gY29uZmlnIGlzIGludmFsaWQuCi8vLyAqIDMzOiBbQWN0aW9uIGxpc3Qg" + + "aXMgdG9vIGxvbmddIOKAlCBUaHJvd24gd2hlbiBhdHRlbXB0aW5nIHRvIHF1ZXVlIG1vcmUgdGhhbiAyNTUgbWVzc2FnZXMuCi8vLwovLy8gU2VlOgovLy8gKiBodHRw" + + "czovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1zZW5kI25hdGl2ZXNlbmRtZXNzYWdlcmV0dXJuZm9yd2FyZGZlZQovLy8gKiBodHRwczovL2RvY3MudGFjdC1s" + + "YW5nLm9yZy9yZWYvY29yZS1zZW5kI3NlbmRyYXdtZXNzYWdlCi8vLwovLy8gW0ludGVnZXIgb3V0IG9mIGV4cGVjdGVkIHJhbmdlXTogaHR0cHM6Ly9kb2NzLnRhY3Qt" + + "bGFuZy5vcmcvYm9vay9leGl0LWNvZGVzIzUKLy8vIFtUeXBlIGNoZWNrIGVycm9yXTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvYm9vay9leGl0LWNvZGVzIzcK" + + "Ly8vIFtDZWxsIHVuZGVyZmxvd106IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL2Jvb2svZXhpdC1jb2RlcyM5Ci8vLyBbIlVua25vd24iIGVycm9yXTogaHR0cHM6" + + "Ly9kb2NzLnRhY3QtbGFuZy5vcmcvYm9vay9leGl0LWNvZGVzIzExCi8vLyBbQWN0aW9uIGxpc3QgaXMgdG9vIGxvbmddOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9y" + + "Zy9ib29rL2V4aXQtY29kZXMjMzMKLy8vCmFzbSBmdW4gbmF0aXZlU2VuZE1lc3NhZ2VSZXR1cm5Gb3J3YXJkRmVlKG1zZzogQ2VsbCwgbW9kZTogSW50KTogSW50IHsg" + + "U0VORE1TRyB9CgovLy8gR2xvYmFsIGZ1bmN0aW9uLiBBdmFpbGFibGUgc2luY2UgVGFjdCAxLjYuNi4KLy8vCi8vLyBTaW1pbGFyIHRvIGBzZW5kUmF3TWVzc2FnZSgp" + + "YCwgYnV0IGFsc28gY2FsY3VsYXRlcyBhbmQgcmV0dXJucyB0aGUgZm9yd2FyZCBmZWUgaW4gbmFub1RvbmNvaW4uCi8vLwovLy8gIyMjIyBFeGl0IGNvZGVzCi8vLwov" + + "Ly8gKiA1OiBbSW50ZWdlciBvdXQgb2YgZXhwZWN0ZWQgcmFuZ2VdIC0gVGhyb3duIGlmIHRoZSBtZXNzYWdlIG1vZGUgaXMgaW52YWxpZC4KLy8vICogNzogW1R5cGUg" + + "Y2hlY2sgZXJyb3JdIC0gVGhyb3duIGlmIGFueSBvZiB0aGUgYmxvY2tjaGFpbiBjb25maWcsIGNvbnRyYWN0IGJhbGFuY2Ugb3IgaW5jb21pbmcgbWVzc2FnZSB2YWx1" + + "ZSBhcmUgaW52YWxpZC4KLy8vICogMTE6IFsiVW5rbm93biIgZXJyb3JdIC0gVGhyb3duIGlmIHRoZSBtZXNzYWdlIGNlbGwgaXMgaWxsLWZvcm1lZCBvciB0aGUgVFZN" + + "IGNvbmZpZyBpcyBpbnZhbGlkLgovLy8gKiAzMzogW0FjdGlvbiBsaXN0IGlzIHRvbyBsb25nXSDigJQgVGhyb3duIHdoZW4gYXR0ZW1wdGluZyB0byBxdWV1ZSBtb3Jl" + + "IHRoYW4gMjU1IG1lc3NhZ2VzLgovLy8KLy8vIFNlZToKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtc2VuZCNzZW5kcmF3bWVzc2FnZXJl" + + "dHVybmZvcndhcmRmZWUKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtc2VuZCNzZW5kcmF3bWVzc2FnZQovLy8KLy8vIFtJbnRlZ2VyIG91" + + "dCBvZiBleHBlY3RlZCByYW5nZV06IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL2Jvb2svZXhpdC1jb2RlcyM1Ci8vLyBbVHlwZSBjaGVjayBlcnJvcl06IGh0dHBz" + + "Oi8vZG9jcy50YWN0LWxhbmcub3JnL2Jvb2svZXhpdC1jb2RlcyM3Ci8vLyBbIlVua25vd24iIGVycm9yXTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvYm9vay9l" + + "eGl0LWNvZGVzIzExCi8vLyBbQWN0aW9uIGxpc3QgaXMgdG9vIGxvbmddOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9ib29rL2V4aXQtY29kZXMjMzMKLy8vCmFz" + + "bSBmdW4gc2VuZE1lc3NhZ2VSZXR1cm5Gb3J3YXJkRmVlKG1zZzogQ2VsbCwgbW9kZTogSW50KTogSW50IHsgU0VORE1TRyB9CgovLy8gR2xvYmFsIGZ1bmN0aW9uLgov" + + "Ly8KLy8vIFF1ZXVlcyB0aGUgbWVzc2FnZSBgYm9keWAgdG8gYmUgc2VudCB0byB0aGUgb3V0ZXIgd29ybGQgd2l0aCB0aGUgcHVycG9zZSBvZiBsb2dnaW5nIGFuZCBh" + + "bmFseXppbmcgaXQgbGF0ZXIgb2ZmLWNoYWluLiBUaGUgbWVzc2FnZSBkb2VzIG5vdCBoYXZlIGEgcmVjaXBpZW50IGFuZCBpcyBtb3JlIGdhcy1lZmZpY2llbnQgY29t" + + "cGFyZWQgdG8gdXNpbmcgYW55IG90aGVyIG1lc3NhZ2Utc2VuZGluZyBmdW5jdGlvbnMgb2YgVGFjdC4KLy8vCi8vLyBUaGUgbWVzc2FnZSBpcyBzZW50IHdpdGggdGhl" + + "IGRlZmF1bHQgbW9kZTogYFNlbmREZWZhdWx0TW9kZWAgKDApLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAgIGVtaXQoIkNhdGNoIG1l" + + "IGlmIHlvdSBjYW4sIE1yLiBIb2xtZXMiLmFzQ29tbWVudCgpKTsgLy8gYXNDb21tZW50KCkgY29udmVydHMgYSBTdHJpbmcgdG8gYSBDZWxsCi8vLyB9Ci8vLyBgYGAK" + + "Ly8vCi8vLyAjIyMjIEV4aXQgY29kZXMKLy8vCi8vLyAqIDMzOiBbQWN0aW9uIGxpc3QgaXMgdG9vIGxvbmddIOKAlCBUaHJvd24gd2hlbiBhdHRlbXB0aW5nIHRvIHF1" + + "ZXVlIG1vcmUgdGhhbiAyNTUgbWVzc2FnZXMuCi8vLwovLy8gU2VlOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1zZW5kI2VtaXQKLy8vCi8vLyBb" + + "QWN0aW9uIGxpc3QgaXMgdG9vIGxvbmddOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9ib29rL2V4aXQtY29kZXMjMzMKLy8vCmlubGluZSBmdW4gZW1pdChib2R5" + + "OiBDZWxsKSB7CiAgICAvLyBleHRfb3V0X21zZ19pbmZvJDExIHNyYzpNc2dBZGRyZXNzSW50IGRlc3Q6TXNnQWRkcmVzc0V4dCBjcmVhdGVkX2x0OnVpbnQ2NCBjcmVh" + + "dGVkX2F0OnVpbnQzMgogICAgLy8gICAgICAgICAgICAgICAgICAgICBtYXliZTogc3RhdGVJbml0IChmYWxzZSkgYm9keVJlZjogYm9vbCAodHJ1ZSkKICAgIGxldCBj" + + "OiBDZWxsID0gYmVnaW5DZWxsKCkKICAgICAgICAuc3RvcmVVaW50KDE1MjExODA3MjAyNzM4NzUyODE3OTYwNDM4NDY0NTEzLCAxMDQpCiAgICAgICAgLnN0b3JlUmVm" + + "KGJvZHkpCiAgICAgICAgLmVuZENlbGwoKTsKICAgIHNlbmRSYXdNZXNzYWdlKGMsIDApOwp9CgovLy8gR2xvYmFsIGZ1bmN0aW9uLgovLy8KLy8vIEFncmVlcyB0byBi" + + "dXkgc29tZSBnYXMgdG8gZmluaXNoIHRoZSBjdXJyZW50IHRyYW5zYWN0aW9uIGJ5IHNldHRpbmcgdGhlIGBnYXNfbGltaXRgIHRvIGl0cyBtYXhpbXVtIGFsbG93ZWQg" + + "dmFsdWUgb2YgMl42MyAtIDEgYW5kIHJlc2V0dGluZyB0aGUgYGdhc19jcmVkaXRgIHRvIDAuIFRoaXMgYWN0aW9uIGlzIHJlcXVpcmVkIHRvIHByb2Nlc3MgZXh0ZXJu" + + "YWwgbWVzc2FnZXMsIHdoaWNoIGJyaW5nIG5vIHZhbHVlIChoZW5jZSBubyBnYXMpIHdpdGggdGhlbXNlbHZlcy4KLy8vCi8vLyBgYGB0YWN0Ci8vLyBjb250cmFjdCBU" + + "aW1lb3V0IHsKLy8vICAgICB0aW1lb3V0OiBJbnQ7Ci8vLwovLy8gICAgIGluaXQoKSB7Ci8vLyAgICAgICAgIHNlbGYudGltZW91dCA9IG5vdygpICsgNSAqIDYwOyAv" + + "LyA1IG1pbnV0ZXMgZnJvbSBub3cKLy8vICAgICB9Ci8vLwovLy8gICAgIGV4dGVybmFsKCJ0aW1lb3V0IikgewovLy8gICAgICAgICBpZiAobm93KCkgPiBzZWxmLnRp" + + "bWVvdXQpIHsKLy8vICAgICAgICAgICAgIGFjY2VwdE1lc3NhZ2UoKTsgLy8gc3RhcnQgYWNjZXB0aW5nIGV4dGVybmFsIG1lc3NhZ2VzIG9uY2UgdGltZW91dCB3ZW50" + + "IG91dAovLy8gICAgICAgICB9Ci8vLyAgICAgfQovLy8gfQovLy8gYGBgCi8vLwovLy8gU2VlOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1nYXMj" + + "YWNjZXB0bWVzc2FnZQovLy8KYXNtIGZ1biBhY2NlcHRNZXNzYWdlKCkgeyBBQ0NFUFQgfQoKLy8vIEdsb2JhbCBmdW5jdGlvbi4KLy8vCi8vLyBDb21taXRzIHRoZSBj" + + "dXJyZW50IHN0YXRlIG9mIHJlZ2lzdGVycyBgYzRgIChwZXJzaXN0ZW50IGRhdGEpIGFuZCBgYzVgIChhY3Rpb25zKSwgc28gdGhhdCB0aGUgY3VycmVudCBleGVjdXRp" + + "b24gaXMgY29uc2lkZXJlZCAic3VjY2Vzc2Z1bCIgd2l0aCB0aGUgc2F2ZWQgdmFsdWVzIGV2ZW4gaWYgYW4gZXhjZXB0aW9uIGluIGNvbXB1dGUgcGhhc2UgaXMgdGhy" + + "b3duIGxhdGVyLgovLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKSB7Ci8vLyAgICAgY29tbWl0KCk7ICAvLyBub3csIHRyYW5zYWN0aW9uIGlzIGNvbnNpZGVy" + + "ZWQgInN1Y2Nlc3NmdWwiCi8vLyAgICAgdGhyb3coNDIpOyAvLyBhbmQgdGhpcyB3b24ndCBmYWlsIGl0Ci8vLyB9Ci8vLyBgYGAKLy8vCi8vLyBTZWU6IGh0dHBzOi8v" + + "ZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWNvbnRleHRzdGF0ZSNjb21taXQKLy8vCmFzbSBmdW4gY29tbWl0KCkgeyBDT01NSVQgfQo="; files["std/internal/text.tact"] = - "Ly8KLy8gU3RyaW5nIGJ1aWxkZXIKLy8KCi8vLyBHbG9iYWwgZnVuY3Rpb24uCi8vLwovLy8gQ3JlYXRlcyBhbmQgcmV0dXJucyBhbiBlbXB0eSBgU3RyaW5nQnVpbGRl" + - "cmAuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKTogU3RyaW5nIHsKLy8vICAgICBsZXQgZml6ejogU3RyaW5nQnVpbGRlciA9IGJlZ2luU3RyaW5nKCk7" + - "Ci8vLyB9Ci8vLyBgYGAKLy8vCi8vLyBTZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLXN0cmluZ3MjYmVnaW5zdHJpbmcKLy8vCkBuYW1lKF9f" + - "dGFjdF9zdHJpbmdfYnVpbGRlcl9zdGFydF9zdHJpbmcpCm5hdGl2ZSBiZWdpblN0cmluZygpOiBTdHJpbmdCdWlsZGVyOwoKLy8vIEdsb2JhbCBmdW5jdGlvbi4KLy8v" + - "Ci8vLyBDcmVhdGVzIGFuZCByZXR1cm5zIGFuIGVtcHR5IGBTdHJpbmdCdWlsZGVyYCBmb3IgYnVpbGRpbmcgYSBjb21tZW50IHN0cmluZywgd2hpY2ggcHJlZml4ZXMK" + - "Ly8vIHRoZSByZXN1bHRpbmcgYFN0cmluZ2Agd2l0aCBmb3VyIG51bGwgYnl0ZXMuIFRoaXMgZm9ybWF0IGlzIHVzZWQgZm9yIHBhc3NpbmcgdGV4dCBjb21tZW50cwov" + - "Ly8gYXMgbWVzc2FnZSBib2RpZXMuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKTogU3RyaW5nIHsKLy8vICAgICBsZXQgZml6ejogU3RyaW5nQnVpbGRl" + - "ciA9IGJlZ2luQ29tbWVudCgpOwovLy8gfQovLy8gYGBgCi8vLwovLy8gU2VlOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1zdHJpbmdzI2JlZ2lu" + - "Y29tbWVudAovLy8KQG5hbWUoX190YWN0X3N0cmluZ19idWlsZGVyX3N0YXJ0X2NvbW1lbnQpCm5hdGl2ZSBiZWdpbkNvbW1lbnQoKTogU3RyaW5nQnVpbGRlcjsKCi8v" + - "LyBHbG9iYWwgZnVuY3Rpb24uCi8vLwovLy8gQ3JlYXRlcyBhbmQgcmV0dXJucyBhbiBlbXB0eSBgU3RyaW5nQnVpbGRlcmAgZm9yIGJ1aWxkaW5nIGEgdGFpbCBzdHJp" + - "bmcsIHdoaWNoIHByZWZpeGVzCi8vLyB0aGUgcmVzdWx0aW5nIGBTdHJpbmdgIHdpdGggYSBzaW5nbGUgbnVsbCBieXRlLiBUaGlzIGZvcm1hdCBpcyB1c2VkIGluIHZh" + - "cmlvdXMgc3RhbmRhcmRzCi8vLyBzdWNoIGFzIE5GVCBvciBKZXR0b24uCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKTogU3RyaW5nIHsKLy8vICAgICBs" + - "ZXQgZml6ejogU3RyaW5nQnVpbGRlciA9IGJlZ2luVGFpbFN0cmluZygpOwovLy8gfQovLy8gYGBgCi8vLwovLy8gU2VlOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9y" + - "Zy9yZWYvY29yZS1zdHJpbmdzI2JlZ2ludGFpbHN0cmluZwovLy8KQG5hbWUoX190YWN0X3N0cmluZ19idWlsZGVyX3N0YXJ0X3RhaWxfc3RyaW5nKQpuYXRpdmUgYmVn" + - "aW5UYWlsU3RyaW5nKCk6IFN0cmluZ0J1aWxkZXI7CgovLy8gR2xvYmFsIGZ1bmN0aW9uLgovLy8KLy8vIENyZWF0ZXMgYW5kIHJldHVybnMgYSBuZXcgYFN0cmluZ0J1" + - "aWxkZXJgIGZyb20gYW4gZXhpc3RpbmcgYFN0cmluZ0J1aWxkZXJgIGBiYC4gVXNlZnVsIHdoZW4KLy8vIHlvdSBuZWVkIHRvIHNlcmlhbGl6ZSBhbiBleGlzdGluZyBg" + - "U3RyaW5nYCB0byBhIGBDZWxsYCBhbG9uZyB3aXRoIG90aGVyIGRhdGEuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKTogU3RyaW5nIHsKLy8vICAgICBs" + - "ZXQgZml6ejogU3RyaW5nQnVpbGRlciA9IGJlZ2luU3RyaW5nRnJvbUJ1aWxkZXIoYmVnaW5TdHJpbmcoKSk7Ci8vLyB9Ci8vLyBgYGAKLy8vCi8vLyBTZWU6IGh0dHBz" + - "Oi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLXN0cmluZ3MjYmVnaW5zdHJpbmdmcm9tYnVpbGRlcgovLy8KQG5hbWUoX190YWN0X3N0cmluZ19idWlsZGVyX3N0" + - "YXJ0KQpuYXRpdmUgYmVnaW5TdHJpbmdGcm9tQnVpbGRlcihiOiBCdWlsZGVyKTogU3RyaW5nQnVpbGRlcjsKCi8vLyBFeHRlbnNpb24gbXV0YXRpb24gZnVuY3Rpb24g" + - "Zm9yIHRoZSBgU3RyaW5nQnVpbGRlcmAgdHlwZS4KLy8vCi8vLyBBcHBlbmRzIGEgYFN0cmluZ2AgYHNgIHRvIHRoZSBgU3RyaW5nQnVpbGRlcmAuCi8vLwovLy8gYGBg" + - "dGFjdAovLy8gZnVuIGV4YW1wbGUoKSB7Ci8vLyAgICAgbGV0IGZpeno6IFN0cmluZ0J1aWxkZXIgPSBiZWdpblN0cmluZygpOwovLy8gICAgIGZpenouYXBwZW5kKCJv" + - "aCIpOwovLy8gICAgIGZpenouYXBwZW5kKCJteSIpOwovLy8gICAgIGZpenouYXBwZW5kKCJUYWN0ISIpOwovLy8gfQovLy8gYGBgCi8vLwovLy8gU2VlOiBodHRwczov" + - "L2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1zdHJpbmdzI3N0cmluZ2J1aWxkZXJhcHBlbmQKLy8vCkBuYW1lKF9fdGFjdF9zdHJpbmdfYnVpbGRlcl9hcHBlbmQp" + - "CmV4dGVuZHMgbXV0YXRlcyBuYXRpdmUgYXBwZW5kKHNlbGY6IFN0cmluZ0J1aWxkZXIsIHM6IFN0cmluZyk7CgovLy8gRXh0ZW5zaW9uIGZ1bmN0aW9uIGZvciB0aGUg" + - "YFN0cmluZ0J1aWxkZXJgIHR5cGUuCi8vLwovLy8gUmV0dXJucyBhIG5ldyBgU3RyaW5nQnVpbGRlcmAgYWZ0ZXIgY29uY2F0ZW5hdGluZyBpdCB3aXRoIGEgYFN0cmlu" + - "Z2AgYHNgLiBJdCBjYW4gYmUgY2hhaW5lZCwKLy8vIHVubGlrZSBgU3RyaW5nQnVpbGRlci5hcHBlbmQoKWAuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGUo" + - "KSB7Ci8vLyAgICAgbGV0IGZpeno6IFN0cmluZ0J1aWxkZXIgPSBiZWdpblN0cmluZygpCi8vLyAgICAgICAgIC5jb25jYXQoIm9oIikKLy8vICAgICAgICAgLmNvbmNh" + - "dCgibXkiKQovLy8gICAgICAgICAuY29uY2F0KCJUYWN0ISIpOwovLy8gfQovLy8gYGBgCi8vLwovLy8gU2VlOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYv" + - "Y29yZS1zdHJpbmdzI3N0cmluZ2J1aWxkZXJjb25jYXQKLy8vCkBuYW1lKF9fdGFjdF9zdHJpbmdfYnVpbGRlcl9hcHBlbmRfbm90X211dCkKZXh0ZW5kcyBuYXRpdmUg" + - "Y29uY2F0KHNlbGY6IFN0cmluZ0J1aWxkZXIsIHM6IFN0cmluZyk6IFN0cmluZ0J1aWxkZXI7CgovLy8gRXh0ZW5zaW9uIGZ1bmN0aW9uIGZvciB0aGUgYFN0cmluZ0J1" + - "aWxkZXJgIHR5cGUuCi8vLwovLy8gUmV0dXJucyBhbiBhc3NlbWJsZWQgYENlbGxgIGZyb20gYSBgU3RyaW5nQnVpbGRlcmAuCi8vLwovLy8gTk9URTogKipHYXMgZXhw" + + "aW1wb3J0ICIuL2NlbGxzIjsKaW1wb3J0ICIuL2V4aXQtY29kZXMiOwppbXBvcnQgIi4vZGVidWciOwoKLy8KLy8gU3RyaW5nIGJ1aWxkZXIKLy8KCi8vLyBHbG9iYWwg" + + "ZnVuY3Rpb24uCi8vLwovLy8gQ3JlYXRlcyBhbmQgcmV0dXJucyBhbiBlbXB0eSBgU3RyaW5nQnVpbGRlcmAuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGUo" + + "KTogU3RyaW5nIHsKLy8vICAgICBsZXQgZml6ejogU3RyaW5nQnVpbGRlciA9IGJlZ2luU3RyaW5nKCk7Ci8vLyB9Ci8vLyBgYGAKLy8vCi8vLyBTZWU6IGh0dHBzOi8v" + + "ZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLXN0cmluZ3MjYmVnaW5zdHJpbmcKLy8vCkBuYW1lKF9fdGFjdF9zdHJpbmdfYnVpbGRlcl9zdGFydF9zdHJpbmcpCm5h" + + "dGl2ZSBiZWdpblN0cmluZygpOiBTdHJpbmdCdWlsZGVyOwoKLy8vIEdsb2JhbCBmdW5jdGlvbi4KLy8vCi8vLyBDcmVhdGVzIGFuZCByZXR1cm5zIGFuIGVtcHR5IGBT" + + "dHJpbmdCdWlsZGVyYCBmb3IgYnVpbGRpbmcgYSBjb21tZW50IHN0cmluZywgd2hpY2ggcHJlZml4ZXMKLy8vIHRoZSByZXN1bHRpbmcgYFN0cmluZ2Agd2l0aCBmb3Vy" + + "IG51bGwgYnl0ZXMuIFRoaXMgZm9ybWF0IGlzIHVzZWQgZm9yIHBhc3NpbmcgdGV4dCBjb21tZW50cwovLy8gYXMgbWVzc2FnZSBib2RpZXMuCi8vLwovLy8gYGBgdGFj" + + "dAovLy8gZnVuIGV4YW1wbGUoKTogU3RyaW5nIHsKLy8vICAgICBsZXQgZml6ejogU3RyaW5nQnVpbGRlciA9IGJlZ2luQ29tbWVudCgpOwovLy8gfQovLy8gYGBgCi8v" + + "LwovLy8gU2VlOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1zdHJpbmdzI2JlZ2luY29tbWVudAovLy8KQG5hbWUoX190YWN0X3N0cmluZ19idWls" + + "ZGVyX3N0YXJ0X2NvbW1lbnQpCm5hdGl2ZSBiZWdpbkNvbW1lbnQoKTogU3RyaW5nQnVpbGRlcjsKCi8vLyBHbG9iYWwgZnVuY3Rpb24uCi8vLwovLy8gQ3JlYXRlcyBh" + + "bmQgcmV0dXJucyBhbiBlbXB0eSBgU3RyaW5nQnVpbGRlcmAgZm9yIGJ1aWxkaW5nIGEgdGFpbCBzdHJpbmcsIHdoaWNoIHByZWZpeGVzCi8vLyB0aGUgcmVzdWx0aW5n" + + "IGBTdHJpbmdgIHdpdGggYSBzaW5nbGUgbnVsbCBieXRlLiBUaGlzIGZvcm1hdCBpcyB1c2VkIGluIHZhcmlvdXMgc3RhbmRhcmRzCi8vLyBzdWNoIGFzIE5GVCBvciBK" + + "ZXR0b24uCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKTogU3RyaW5nIHsKLy8vICAgICBsZXQgZml6ejogU3RyaW5nQnVpbGRlciA9IGJlZ2luVGFpbFN0" + + "cmluZygpOwovLy8gfQovLy8gYGBgCi8vLwovLy8gU2VlOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1zdHJpbmdzI2JlZ2ludGFpbHN0cmluZwov" + + "Ly8KQG5hbWUoX190YWN0X3N0cmluZ19idWlsZGVyX3N0YXJ0X3RhaWxfc3RyaW5nKQpuYXRpdmUgYmVnaW5UYWlsU3RyaW5nKCk6IFN0cmluZ0J1aWxkZXI7CgovLy8g" + + "R2xvYmFsIGZ1bmN0aW9uLgovLy8KLy8vIENyZWF0ZXMgYW5kIHJldHVybnMgYSBuZXcgYFN0cmluZ0J1aWxkZXJgIGZyb20gYW4gZXhpc3RpbmcgYFN0cmluZ0J1aWxk" + + "ZXJgIGBiYC4gVXNlZnVsIHdoZW4KLy8vIHlvdSBuZWVkIHRvIHNlcmlhbGl6ZSBhbiBleGlzdGluZyBgU3RyaW5nYCB0byBhIGBDZWxsYCBhbG9uZyB3aXRoIG90aGVy" + + "IGRhdGEuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKTogU3RyaW5nIHsKLy8vICAgICBsZXQgZml6ejogU3RyaW5nQnVpbGRlciA9IGJlZ2luU3RyaW5n" + + "RnJvbUJ1aWxkZXIoYmVnaW5TdHJpbmcoKSk7Ci8vLyB9Ci8vLyBgYGAKLy8vCi8vLyBTZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLXN0cmlu" + + "Z3MjYmVnaW5zdHJpbmdmcm9tYnVpbGRlcgovLy8KQG5hbWUoX190YWN0X3N0cmluZ19idWlsZGVyX3N0YXJ0KQpuYXRpdmUgYmVnaW5TdHJpbmdGcm9tQnVpbGRlcihi" + + "OiBCdWlsZGVyKTogU3RyaW5nQnVpbGRlcjsKCi8vLyBFeHRlbnNpb24gbXV0YXRpb24gZnVuY3Rpb24gZm9yIHRoZSBgU3RyaW5nQnVpbGRlcmAgdHlwZS4KLy8vCi8v" + + "LyBBcHBlbmRzIGEgYFN0cmluZ2AgYHNgIHRvIHRoZSBgU3RyaW5nQnVpbGRlcmAuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKSB7Ci8vLyAgICAgbGV0" + + "IGZpeno6IFN0cmluZ0J1aWxkZXIgPSBiZWdpblN0cmluZygpOwovLy8gICAgIGZpenouYXBwZW5kKCJvaCIpOwovLy8gICAgIGZpenouYXBwZW5kKCJteSIpOwovLy8g" + + "ICAgIGZpenouYXBwZW5kKCJUYWN0ISIpOwovLy8gfQovLy8gYGBgCi8vLwovLy8gU2VlOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1zdHJpbmdz" + + "I3N0cmluZ2J1aWxkZXJhcHBlbmQKLy8vCkBuYW1lKF9fdGFjdF9zdHJpbmdfYnVpbGRlcl9hcHBlbmQpCmV4dGVuZHMgbXV0YXRlcyBuYXRpdmUgYXBwZW5kKHNlbGY6" + + "IFN0cmluZ0J1aWxkZXIsIHM6IFN0cmluZyk7CgovLy8gRXh0ZW5zaW9uIGZ1bmN0aW9uIGZvciB0aGUgYFN0cmluZ0J1aWxkZXJgIHR5cGUuCi8vLwovLy8gUmV0dXJu" + + "cyBhIG5ldyBgU3RyaW5nQnVpbGRlcmAgYWZ0ZXIgY29uY2F0ZW5hdGluZyBpdCB3aXRoIGEgYFN0cmluZ2AgYHNgLiBJdCBjYW4gYmUgY2hhaW5lZCwKLy8vIHVubGlr" + + "ZSBgU3RyaW5nQnVpbGRlci5hcHBlbmQoKWAuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKSB7Ci8vLyAgICAgbGV0IGZpeno6IFN0cmluZ0J1aWxkZXIg" + + "PSBiZWdpblN0cmluZygpCi8vLyAgICAgICAgIC5jb25jYXQoIm9oIikKLy8vICAgICAgICAgLmNvbmNhdCgibXkiKQovLy8gICAgICAgICAuY29uY2F0KCJUYWN0ISIp" + + "OwovLy8gfQovLy8gYGBgCi8vLwovLy8gU2VlOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1zdHJpbmdzI3N0cmluZ2J1aWxkZXJjb25jYXQKLy8v" + + "CkBuYW1lKF9fdGFjdF9zdHJpbmdfYnVpbGRlcl9hcHBlbmRfbm90X211dCkKZXh0ZW5kcyBuYXRpdmUgY29uY2F0KHNlbGY6IFN0cmluZ0J1aWxkZXIsIHM6IFN0cmlu" + + "Zyk6IFN0cmluZ0J1aWxkZXI7CgovLy8gRXh0ZW5zaW9uIGZ1bmN0aW9uIGZvciB0aGUgYFN0cmluZ0J1aWxkZXJgIHR5cGUuCi8vLwovLy8gUmV0dXJucyBhbiBhc3Nl" + + "bWJsZWQgYENlbGxgIGZyb20gYSBgU3RyaW5nQnVpbGRlcmAuCi8vLwovLy8gTk9URTogKipHYXMgZXhwZW5zaXZlISoqIFRoaXMgZnVuY3Rpb24gdXNlcyA1MDAgZ2Fz" + + "IHVuaXRzIG9yIG1vcmUuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKSB7Ci8vLyAgICAgbGV0IGZpeno6IFN0cmluZ0J1aWxkZXIgPSBiZWdpblN0cmlu" + + "ZygpOwovLy8gICAgIGxldCBidXp6OiBDZWxsID0gZml6ei50b0NlbGwoKTsKLy8vIH0KLy8vIGBgYAovLy8KLy8vIFNlZTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5v" + + "cmcvcmVmL2NvcmUtc3RyaW5ncyNzdHJpbmdidWlsZGVydG9jZWxsCi8vLwpAbmFtZShfX3RhY3Rfc3RyaW5nX2J1aWxkZXJfZW5kKQpleHRlbmRzIG5hdGl2ZSB0b0Nl" + + "bGwoc2VsZjogU3RyaW5nQnVpbGRlcik6IENlbGw7CgovLy8gRXh0ZW5zaW9uIGZ1bmN0aW9uIGZvciB0aGUgYFN0cmluZ0J1aWxkZXJgIHR5cGUuCi8vLwovLy8gUmV0" + + "dXJucyBhIGJ1aWx0IGBTdHJpbmdgIGZyb20gYSBgU3RyaW5nQnVpbGRlcmAuCi8vLwovLy8gTk9URTogKipHYXMgZXhwZW5zaXZlISoqIFRoaXMgZnVuY3Rpb24gdXNl" + + "cyA1MDAgZ2FzIHVuaXRzIG9yIG1vcmUuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKSB7Ci8vLyAgICAgbGV0IGZpeno6IFN0cmluZ0J1aWxkZXIgPSBi" + + "ZWdpblN0cmluZygpOwovLy8gICAgIGxldCBidXp6OiBTdHJpbmcgPSBmaXp6LnRvU3RyaW5nKCk7Ci8vLyB9Ci8vLyBgYGAKLy8vCi8vLyBTZWU6IGh0dHBzOi8vZG9j" + + "cy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLXN0cmluZ3Mjc3RyaW5nYnVpbGRlcnRvc3RyaW5nCi8vLwpAbmFtZShfX3RhY3Rfc3RyaW5nX2J1aWxkZXJfZW5kX3NsaWNl" + + "KQpleHRlbmRzIG5hdGl2ZSB0b1N0cmluZyhzZWxmOiBTdHJpbmdCdWlsZGVyKTogU3RyaW5nOwoKLy8vIEV4dGVuc2lvbiBmdW5jdGlvbiBmb3IgdGhlIGBTdHJpbmdC" + + "dWlsZGVyYCB0eXBlLgovLy8KLy8vIFJldHVybnMgYW4gYXNzZW1ibGVkIGBDZWxsYCBhcyBhIGBTbGljZWAgZnJvbSBhIGBTdHJpbmdCdWlsZGVyYC4KLy8vIEFuIGFs" + + "aWFzIHRvIGBzZWxmLnRvQ2VsbCgpLmFzU2xpY2UoKWAuCi8vLwovLy8gTk9URTogKipHYXMgZXhwZW5zaXZlISoqIFRoaXMgZnVuY3Rpb24gdXNlcyA1MDAgZ2FzIHVu" + + "aXRzIG9yIG1vcmUuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKSB7Ci8vLyAgICAgbGV0IHM6IFN0cmluZ0J1aWxkZXIgPSBiZWdpblN0cmluZygpOwov" + + "Ly8gICAgIGxldCBmaXp6OiBTbGljZSA9IHMudG9TbGljZSgpOwovLy8gICAgIGxldCBidXp6OiBTbGljZSA9IHMudG9DZWxsKCkuYXNTbGljZSgpOwovLy8KLy8vICAg" + + "ICBmaXp6ID09IGJ1eno7IC8vIHRydWUKLy8vIH0KLy8vIGBgYAovLy8KLy8vIFNlZTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtc3RyaW5ncyNz" + + "dHJpbmdidWlsZGVydG9zbGljZQovLy8KQG5hbWUoX190YWN0X3N0cmluZ19idWlsZGVyX2VuZF9zbGljZSkKZXh0ZW5kcyBuYXRpdmUgdG9TbGljZShzZWxmOiBTdHJp" + + "bmdCdWlsZGVyKTogU2xpY2U7CgovLwovLyBTdHJpbmcgY29udmVyc2lvbgovLwoKLy8vIEV4dGVuc2lvbiBmdW5jdGlvbiBmb3IgdGhlIGBJbnRgIHR5cGUuCi8vLwov" + + "Ly8gUmV0dXJucyBhIGBTdHJpbmdgIGZyb20gYW4gYEludGAgdmFsdWUuCi8vLwovLy8gTk9URTogKipHYXMgZXhwZW5zaXZlISoqIFRoaXMgZnVuY3Rpb24gdXNlcyA1" + + "MDAgZ2FzIHVuaXRzIG9yIG1vcmUuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKSB7Ci8vLyAgICAgbGV0IGZpeno6IFN0cmluZyA9ICg4NCAtIDQyKS50" + + "b1N0cmluZygpOwovLy8gfQovLy8gYGBgCi8vLwovLy8gU2VlOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1zdHJpbmdzI2ludHRvc3RyaW5nCi8v" + + "Lwphc20gZXh0ZW5kcyBmdW4gdG9TdHJpbmcoc2VsZjogSW50KTogU3RyaW5nIHsKICAgIC8vIHgKCiAgICA8ewogICAgICAgIC8vIHgKICAgICAgICBORVdDIC8vIHgg" + + "YgogICAgICAgIE9WRVIgLy8geCBiIHgKICAgICAgICAwIExFU1NJTlQgLy8geCBiIDwwPwogICAgICAgIDx7CiAgICAgICAgICAgIC8vIHggYgogICAgICAgICAgICA0" + + "NSBQVVNISU5UIC8vIHggYiA0NQogICAgICAgICAgICBTV0FQIC8vIHggNDUgYgogICAgICAgICAgICA4IFNUVSAvLyB4IGIKICAgICAgICAgICAgU1dBUCAvLyBiIHgK" + + "ICAgICAgICAgICAgTkVHQVRFIC8vIGIgLXgKICAgICAgICAgICAgU1dBUCAvLyAteCBiCiAgICAgICAgfT5DT05UIElGCiAgICAgICAgLy8geCBiCgogICAgICAgIFNX" + + "QVAgLy8gYiB4CgogICAgICAgIDx7CiAgICAgICAgICAgIC8vIGIgeAogICAgICAgICAgICAxMCBQVVNISU5UIERJVk1PRCAvLyBiIHgvMTAgeCUxMAogICAgICAgICAg" + + "ICA0OCBBRERDT05TVCAvLyBiIHgvMTAgKHglMTArNDgpCiAgICAgICAgICAgIHMyIHMyIHMwIFhDMlBVIElTWkVSTyAvLyAoeCUxMCs0OCkgYiB4LzEwIHgvMTA9PTA/" + + "CiAgICAgICAgfT5DT05UIFVOVElMCiAgICAgICAgLy8gLi4uIGIgeAoKICAgICAgICBEUk9QIC8vIC4uLiBiCiAgICAgICAgREVQVEggREVDIC8vIC4uLiBiIG4KICAg" + + "ICAgICA8eyA4IFNUVSB9PkNPTlQgUkVQRUFUIC8vIGIKICAgIH0+Q09OVCAxIDEgQ0FMTFhBUkdTCiAgICAvLyBiCgogICAgRU5EQyBDVE9TIC8vIHMKfQoKLy8vIEV4" + + "dGVuc2lvbiBmdW5jdGlvbiBmb3IgdGhlIGBJbnRgIHR5cGUuCi8vLwovLy8gUmV0dXJucyBhIGBTdHJpbmdgIGZyb20gYW4gYEludGAgdmFsdWUgdXNpbmcgYSBbZml4" + + "ZWQtcG9pbnQgcmVwcmVzZW50YXRpb25dIG9mIGEgZnJhY3Rpb25hbAovLy8gbnVtYmVyLCB3aGVyZSBgc2VsZmAgaXMgdGhlIHNpZ25pZmljYW50IHBhcnQgb2YgdGhl" + + "IG51bWJlciBhbmQgYGRpZ2l0c2AgaXMgdGhlIG51bWJlcgovLy8gb2YgZGlnaXRzIGluIHRoZSBmcmFjdGlvbmFsIHBhcnQuCi8vLwovLy8gTk9URTogKipHYXMgZXhw" + "ZW5zaXZlISoqIFRoaXMgZnVuY3Rpb24gdXNlcyA1MDAgZ2FzIHVuaXRzIG9yIG1vcmUuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKSB7Ci8vLyAgICAg" + - "bGV0IGZpeno6IFN0cmluZ0J1aWxkZXIgPSBiZWdpblN0cmluZygpOwovLy8gICAgIGxldCBidXp6OiBDZWxsID0gZml6ei50b0NlbGwoKTsKLy8vIH0KLy8vIGBgYAov" + - "Ly8KLy8vIFNlZTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtc3RyaW5ncyNzdHJpbmdidWlsZGVydG9jZWxsCi8vLwpAbmFtZShfX3RhY3Rfc3Ry" + - "aW5nX2J1aWxkZXJfZW5kKQpleHRlbmRzIG5hdGl2ZSB0b0NlbGwoc2VsZjogU3RyaW5nQnVpbGRlcik6IENlbGw7CgovLy8gRXh0ZW5zaW9uIGZ1bmN0aW9uIGZvciB0" + - "aGUgYFN0cmluZ0J1aWxkZXJgIHR5cGUuCi8vLwovLy8gUmV0dXJucyBhIGJ1aWx0IGBTdHJpbmdgIGZyb20gYSBgU3RyaW5nQnVpbGRlcmAuCi8vLwovLy8gTk9URTog" + - "KipHYXMgZXhwZW5zaXZlISoqIFRoaXMgZnVuY3Rpb24gdXNlcyA1MDAgZ2FzIHVuaXRzIG9yIG1vcmUuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKSB7" + - "Ci8vLyAgICAgbGV0IGZpeno6IFN0cmluZ0J1aWxkZXIgPSBiZWdpblN0cmluZygpOwovLy8gICAgIGxldCBidXp6OiBTdHJpbmcgPSBmaXp6LnRvU3RyaW5nKCk7Ci8v" + - "LyB9Ci8vLyBgYGAKLy8vCi8vLyBTZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLXN0cmluZ3Mjc3RyaW5nYnVpbGRlcnRvc3RyaW5nCi8vLwpA" + - "bmFtZShfX3RhY3Rfc3RyaW5nX2J1aWxkZXJfZW5kX3NsaWNlKQpleHRlbmRzIG5hdGl2ZSB0b1N0cmluZyhzZWxmOiBTdHJpbmdCdWlsZGVyKTogU3RyaW5nOwoKLy8v" + - "IEV4dGVuc2lvbiBmdW5jdGlvbiBmb3IgdGhlIGBTdHJpbmdCdWlsZGVyYCB0eXBlLgovLy8KLy8vIFJldHVybnMgYW4gYXNzZW1ibGVkIGBDZWxsYCBhcyBhIGBTbGlj" + - "ZWAgZnJvbSBhIGBTdHJpbmdCdWlsZGVyYC4KLy8vIEFuIGFsaWFzIHRvIGBzZWxmLnRvQ2VsbCgpLmFzU2xpY2UoKWAuCi8vLwovLy8gTk9URTogKipHYXMgZXhwZW5z" + - "aXZlISoqIFRoaXMgZnVuY3Rpb24gdXNlcyA1MDAgZ2FzIHVuaXRzIG9yIG1vcmUuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKSB7Ci8vLyAgICAgbGV0" + - "IHM6IFN0cmluZ0J1aWxkZXIgPSBiZWdpblN0cmluZygpOwovLy8gICAgIGxldCBmaXp6OiBTbGljZSA9IHMudG9TbGljZSgpOwovLy8gICAgIGxldCBidXp6OiBTbGlj" + - "ZSA9IHMudG9DZWxsKCkuYXNTbGljZSgpOwovLy8KLy8vICAgICBmaXp6ID09IGJ1eno7IC8vIHRydWUKLy8vIH0KLy8vIGBgYAovLy8KLy8vIFNlZTogaHR0cHM6Ly9k" + - "b2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtc3RyaW5ncyNzdHJpbmdidWlsZGVydG9zbGljZQovLy8KQG5hbWUoX190YWN0X3N0cmluZ19idWlsZGVyX2VuZF9zbGlj" + - "ZSkKZXh0ZW5kcyBuYXRpdmUgdG9TbGljZShzZWxmOiBTdHJpbmdCdWlsZGVyKTogU2xpY2U7CgovLwovLyBTdHJpbmcgY29udmVyc2lvbgovLwoKLy8vIEV4dGVuc2lv" + - "biBmdW5jdGlvbiBmb3IgdGhlIGBJbnRgIHR5cGUuCi8vLwovLy8gUmV0dXJucyBhIGBTdHJpbmdgIGZyb20gYW4gYEludGAgdmFsdWUuCi8vLwovLy8gTk9URTogKipH" + - "YXMgZXhwZW5zaXZlISoqIFRoaXMgZnVuY3Rpb24gdXNlcyA1MDAgZ2FzIHVuaXRzIG9yIG1vcmUuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKSB7Ci8v" + - "LyAgICAgbGV0IGZpeno6IFN0cmluZyA9ICg4NCAtIDQyKS50b1N0cmluZygpOwovLy8gfQovLy8gYGBgCi8vLwovLy8gU2VlOiBodHRwczovL2RvY3MudGFjdC1sYW5n" + - "Lm9yZy9yZWYvY29yZS1zdHJpbmdzI2ludHRvc3RyaW5nCi8vLwphc20gZXh0ZW5kcyBmdW4gdG9TdHJpbmcoc2VsZjogSW50KTogU3RyaW5nIHsKICAgIC8vIHgKCiAg" + - "ICA8ewogICAgICAgIC8vIHgKICAgICAgICBORVdDIC8vIHggYgogICAgICAgIE9WRVIgLy8geCBiIHgKICAgICAgICAwIExFU1NJTlQgLy8geCBiIDwwPwogICAgICAg" + - "IDx7CiAgICAgICAgICAgIC8vIHggYgogICAgICAgICAgICA0NSBQVVNISU5UIC8vIHggYiA0NQogICAgICAgICAgICBTV0FQIC8vIHggNDUgYgogICAgICAgICAgICA4" + - "IFNUVSAvLyB4IGIKICAgICAgICAgICAgU1dBUCAvLyBiIHgKICAgICAgICAgICAgTkVHQVRFIC8vIGIgLXgKICAgICAgICAgICAgU1dBUCAvLyAteCBiCiAgICAgICAg" + - "fT5DT05UIElGCiAgICAgICAgLy8geCBiCgogICAgICAgIFNXQVAgLy8gYiB4CgogICAgICAgIDx7CiAgICAgICAgICAgIC8vIGIgeAogICAgICAgICAgICAxMCBQVVNI" + - "SU5UIERJVk1PRCAvLyBiIHgvMTAgeCUxMAogICAgICAgICAgICA0OCBBRERDT05TVCAvLyBiIHgvMTAgKHglMTArNDgpCiAgICAgICAgICAgIHMyIHMyIHMwIFhDMlBV" + - "IElTWkVSTyAvLyAoeCUxMCs0OCkgYiB4LzEwIHgvMTA9PTA/CiAgICAgICAgfT5DT05UIFVOVElMCiAgICAgICAgLy8gLi4uIGIgeAoKICAgICAgICBEUk9QIC8vIC4u" + - "LiBiCiAgICAgICAgREVQVEggREVDIC8vIC4uLiBiIG4KICAgICAgICA8eyA4IFNUVSB9PkNPTlQgUkVQRUFUIC8vIGIKICAgIH0+Q09OVCAxIDEgQ0FMTFhBUkdTCiAg" + - "ICAvLyBiCgogICAgRU5EQyBDVE9TIC8vIHMKfQoKLy8vIEV4dGVuc2lvbiBmdW5jdGlvbiBmb3IgdGhlIGBJbnRgIHR5cGUuCi8vLwovLy8gUmV0dXJucyBhIGBTdHJp" + - "bmdgIGZyb20gYW4gYEludGAgdmFsdWUgdXNpbmcgYSBbZml4ZWQtcG9pbnQgcmVwcmVzZW50YXRpb25dIG9mIGEgZnJhY3Rpb25hbAovLy8gbnVtYmVyLCB3aGVyZSBg" + - "c2VsZmAgaXMgdGhlIHNpZ25pZmljYW50IHBhcnQgb2YgdGhlIG51bWJlciBhbmQgYGRpZ2l0c2AgaXMgdGhlIG51bWJlcgovLy8gb2YgZGlnaXRzIGluIHRoZSBmcmFj" + - "dGlvbmFsIHBhcnQuCi8vLwovLy8gTk9URTogKipHYXMgZXhwZW5zaXZlISoqIFRoaXMgZnVuY3Rpb24gdXNlcyA1MDAgZ2FzIHVuaXRzIG9yIG1vcmUuCi8vLwovLy8g" + - "YGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKSB7Ci8vLyAgICAgbGV0IGZpeno6IFN0cmluZyA9ICg0MikudG9GbG9hdFN0cmluZyg5KTsgLy8gIjAuMDAwMDAwMDQyIgov" + - "Ly8gfQovLy8gYGBgCi8vLwovLy8gIyMjIyBFeGl0IGNvZGVzCi8vLwovLy8gKiAxMzQ6IFtJbnZhbGlkIGFyZ3VtZW50XSDigJQgVGhyb3duIHdoZW4gdGhlIGdpdmVu" + - "IGBkaWdpdHNgIHZhbHVlIGlzIG91dCBvZiByYW5nZS4KLy8vCi8vLyBTZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLXN0cmluZ3MjaW50dG9m" + - "bG9hdHN0cmluZwovLy8KLy8vIFtmaXhlZC1wb2ludCByZXByZXNlbnRhdGlvbl06IGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0ZpeGVkLXBvaW50X2FyaXRo" + - "bWV0aWMKLy8vIFtJbnZhbGlkIGFyZ3VtZW50XTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvYm9vay9leGl0LWNvZGVzIzEzNAovLy8KYXNtIGV4dGVuZHMgZnVu" + - "IHRvRmxvYXRTdHJpbmcoc2VsZjogSW50LCBkaWdpdHM6IEludCk6IFN0cmluZyB7CiAgICAvLyB4IGRpZ2l0cwoKICAgIERVUCAvLyB4IGRpZ2l0cyBkaWdpdHMKICAg" + - "IDEgTEVTU0lOVCAvLyB4IGRpZ2l0cyBkaWdpdHM8PTAKICAgIDEzNCBUSFJPV0lGIC8vIHggZGlnaXRzCiAgICBEVVAgLy8geCBkaWdpdHMgZGlnaXRzCiAgICA3NyBH" + - "VElOVCAvLyB4IGRpZ2l0cyBkaWdpdHM+NzcKICAgIDEzNCBUSFJPV0lGIC8vIHggZGlnaXRzCgogICAgTkVXQyAvLyB4IGRpZ2l0cyBiCiAgICBST1RSRVYgLy8gYiB4" + - "IGRpZ2l0cwogICAgczEgUFVTSCAvLyBiIHggZGlnaXRzIHgKICAgIDAgTEVTU0lOVCAvLyBiIHggZGlnaXRzIHg8MD8KCiAgICA8ewogICAgICAgIC8vIGIgeCBkaWdp" + - "dHMKICAgICAgICBST1QgLy8geCBkaWdpdHMgYgogICAgICAgIHh7MmR9IFNUU0xJQ0VDT05TVCAvLyB4IGRpZ2l0cyBiCiAgICAgICAgUk9UIC8vIGRpZ2l0cyBiIHgK" + - "ICAgICAgICBORUdBVEUgLy8gZGlnaXRzIGIgLXgKICAgICAgICBST1QgLy8gYiAteCBkaWdpdHMKICAgIH0+Q09OVCBJRgoKICAgIC8vIGIgeCBkaWdpdHMKICAgIE9O" + - "RSAvLyBiIHggZGlnaXRzIDEKICAgIE9WRVIgLy8gYiB4IGRpZ2l0cyAxIGRpZ2l0cwoKICAgIDx7IDEwIE1VTENPTlNUIH0+Q09OVCBSRVBFQVQgLy8gYiB4IGRpZ2l0" + - "cyAxMF5kaWdpdHMKCiAgICBzMSBzMiBYQ0hHIC8vIGIgZGlnaXRzIHggMTBeZGlnaXRzCiAgICBESVZNT0QgLy8gYiBkaWdpdHMgbGVmdCByaWdodAogICAgczMgczMg" + - "WENIRzIgLy8gcmlnaHQgZGlnaXRzIGIgbGVmdAoKICAgIDx7CiAgICAgICAgLy8gYiB4CgogICAgICAgIDx7CiAgICAgICAgICAgIC8vIGIgeAogICAgICAgICAgICAx" + - "MCBQVVNISU5UIERJVk1PRCAvLyBiIHgvMTAgeCUxMAogICAgICAgICAgICA0OCBBRERDT05TVCAvLyBiIHgvMTAgKHglMTArNDgpCiAgICAgICAgICAgIHMyIHMyIHMw" + - "IFhDMlBVIElTWkVSTyAvLyAoeCUxMCs0OCkgYiB4LzEwIHgvMTA9PTA/CiAgICAgICAgfT5DT05UIFVOVElMCiAgICAgICAgLy8gLi4uIGIgeAoKICAgICAgICBEUk9Q" + - "IC8vIC4uLiBiCiAgICAgICAgREVQVEggREVDIC8vIC4uLiBiIG4KICAgICAgICA8eyA4IFNUVSB9PkNPTlQgUkVQRUFUIC8vIGIKICAgIH0+Q09OVCAyIDEgQ0FMTFhB" + - "UkdTCgogICAgLy8gcmlnaHQgZGlnaXRzICJsZWZ0IgoKICAgIFJPVCAvLyBkaWdpdHMgImxlZnQiIHJpZ2h0CiAgICBEVVAgLy8gZGlnaXRzICJsZWZ0IiByaWdodCBy" + - "aWdodAogICAgSVNaRVJPIC8vIGRpZ2l0cyAibGVmdCIgcmlnaHQgcmlnaHQ9PTA/CgogICAgPHsKICAgICAgICAvLyBkaWdpdHMgImxlZnQiIHJpZ2h0CiAgICAgICAg" + - "RFJPUCAvLyBkaWdpdHMgImxlZnQiCiAgICAgICAgTklQIC8vICJsZWZ0IgogICAgfT5DT05UCgogICAgPHsKICAgICAgICAvLyBkaWdpdHMgImxlZnQiIHJpZ2h0CiAg" + - "ICAgICAgWkVSTyAvLyBkaWdpdHMgImxlZnQiIHJpZ2h0IDAKICAgICAgICBTV0FQIC8vIGRpZ2l0cyAibGVmdCIgMCByaWdodAoKICAgICAgICA8ewogICAgICAgICAg" + - "ICAvLyBkaWdpdHMgImxlZnQiIGkgcmlnaHQKICAgICAgICAgICAgRFVQIC8vIGRpZ2l0cyAibGVmdCIgaSByaWdodCByaWdodAogICAgICAgICAgICAxMCBQVVNISU5U" + - "IC8vIGRpZ2l0cyAibGVmdCIgaSByaWdodCByaWdodCAxMAogICAgICAgICAgICBNT0QgLy8gZGlnaXRzICJsZWZ0IiBpIHJpZ2h0IHJpZ2h0JTEwCiAgICAgICAgICAg" + - "IElTWkVSTyAvLyBkaWdpdHMgImxlZnQiIGkgcmlnaHQgcmlnaHQlMTA9PTA/CiAgICAgICAgfT5DT05UCgogICAgICAgIDx7CiAgICAgICAgICAgIC8vIGRpZ2l0cyAi" + - "bGVmdCIgaSByaWdodAogICAgICAgICAgICAxMCBQVVNISU5UIC8vIGRpZ2l0cyAibGVmdCIgaSByaWdodCAxMAogICAgICAgICAgICBESVYgLy8gZGlnaXRzICJsZWZ0" + - "IiBpIHJpZ2h0LzEwCiAgICAgICAgICAgIFNXQVAgLy8gZGlnaXRzICJsZWZ0IiByaWdodC8xMCBpCiAgICAgICAgICAgIElOQyAvLyBkaWdpdHMgImxlZnQiIHJpZ2h0" + - "LzEwIGkrMQogICAgICAgICAgICBTV0FQIC8vIGRpZ2l0cyAibGVmdCIgaSsxIHJpZ2h0LzEwCiAgICAgICAgfT5DT05UCgogICAgICAgIFdISUxFIC8vIGRpZ2l0cyAi" + - "bGVmdCIgaSByaWdodAoKICAgICAgICA8ewogICAgICAgICAgICAvLyB4CiAgICAgICAgICAgIE5FV0MgLy8geCBiCiAgICAgICAgICAgIFNXQVAgLy8gYiB4CgogICAg" + - "ICAgICAgICA8ewogICAgICAgICAgICAgICAgLy8gYiB4CiAgICAgICAgICAgICAgICAxMCBQVVNISU5UIERJVk1PRCAvLyBiIHgvMTAgeCUxMAogICAgICAgICAgICAg" + - "ICAgNDggQUREQ09OU1QgLy8gYiB4LzEwICh4JTEwKzQ4KQogICAgICAgICAgICAgICAgczIgczIgczAgWEMyUFUgSVNaRVJPIC8vICh4JTEwKzQ4KSBiIHgvMTAgeC8x" + - "MD09MD8KICAgICAgICAgICAgfT5DT05UIFVOVElMCiAgICAgICAgICAgIC8vIC4uLiBiIHgKCiAgICAgICAgICAgIERST1AgLy8gLi4uIGIKICAgICAgICAgICAgREVQ" + - "VEggREVDIERVUCAvLyAuLi4gYiBuIG4KICAgICAgICAgICAgUk9UUkVWIC8vIC4uLiBuIGIgbgogICAgICAgICAgICA8ewogICAgICAgICAgICAgICAgLy8gLi4uIGMg" + - "biBiCiAgICAgICAgICAgICAgICBzMSBzMiBYQ0hHIC8vIC4uLiBuIGMgYgogICAgICAgICAgICAgICAgOCBTVFUgLy8gLi4uIG4gYgogICAgICAgICAgICB9PkNPTlQg" + - "UkVQRUFUIC8vIG4gYgogICAgICAgIH0+Q09OVCAxIDIgQ0FMTFhBUkdTCiAgICAgICAgLy8gZGlnaXRzICJsZWZ0IiBpIHJpZ2h0X2RpZ2l0cyAicmlnaHQiCiAgICAg" + - "ICAgUk9UUkVWIC8vIGRpZ2l0cyAibGVmdCIgInJpZ2h0IiBpIHJpZ2h0X2RpZ2l0cwogICAgICAgIEFERCAvLyBkaWdpdHMgImxlZnQiICJyaWdodCIgcmlnaHRfZGln" + - "aXRzCgogICAgICAgIHMzIHMxIFhDSEcgLy8gInJpZ2h0IiAibGVmdCIgZGlnaXRzIHJpZ2h0X2RpZ2l0cwogICAgICAgIFNVQiAvLyAicmlnaHQiICJsZWZ0IiBkaWdp" + - "dHNfZGlmZgogICAgICAgIFNXQVAgLy8gInJpZ2h0IiBkaWdpdHNfZGlmZiAibGVmdCIKICAgICAgICB4ezJlfSBTVFNMSUNFQ09OU1QgLy8gInJpZ2h0IiBkaWdpdHNf" + - "ZGlmZiAibGVmdC4iCiAgICAgICAgU1dBUCAvLyAicmlnaHQiICJsZWZ0LiIgZGlnaXRzX2RpZmYKCiAgICAgICAgPHsKICAgICAgICAgICAgLy8gInJpZ2h0IiAibGVm" + - "dC4iCiAgICAgICAgICAgIHh7MzB9IFNUU0xJQ0VDT05TVCAvLyAicmlnaHQiICJsZWZ0LjAiCiAgICAgICAgfT5DT05UIFJFUEVBVCAvLyAicmlnaHQiICJsZWZ0LjAw" + - "MCIKCiAgICAgICAgU1RCIC8vICJsZWZ0LjAwMHJpZ2h0IgogICAgfT5DT05UCgogICAgSUZFTFNFIC8vIGIKCiAgICBFTkRDIENUT1MgLy8gcwp9CgovLy8gRXh0ZW5z" + - "aW9uIGZ1bmN0aW9uIGZvciB0aGUgYEludGAgdHlwZS4KLy8vCi8vLyBSZXR1cm5zIGEgYFN0cmluZ2AgZnJvbSBhbiBgSW50YCB2YWx1ZSB1c2luZyBhIFtmaXhlZC1w" + - "b2ludCByZXByZXNlbnRhdGlvbl0gb2YgYSBmcmFjdGlvbmFsIG51bWJlci4KLy8vIEFuIGFsaWFzIHRvIGBzZWxmLnRvRmxvYXRTdHJpbmcoOSlgLgovLy8KLy8vIFRo" + - "aXMgaXMgdXNlZCB0byByZXByZXNlbnQgW25hbm9Ub25jb2luXSBgSW50YCB2YWx1ZXMgdXNpbmcgc3RyaW5ncy4KLy8vCi8vLyBgYGB0YWN0Ci8vLyBmdW4gZXhhbXBs" + - "ZSgpIHsKLy8vICAgICBsZXQgbmFub3RvbnM6IEludCA9IDQyOwovLy8gICAgIGxldCBmaXp6OiBTdHJpbmcgPSBuYW5vdG9ucy50b0NvaW5zU3RyaW5nKCk7Ci8vLyAg" + - "ICAgbGV0IGJ1eno6IFN0cmluZyA9IG5hbm90b25zLnRvRmxvYXRTdHJpbmcoOSk7Ci8vLwovLy8gICAgIGZpenogPT0gYnV6ejsgLy8gdHJ1ZSwgYm90aCBzdG9yZSAi" + - "MC4wMDAwMDAwNDIiCi8vLyB9Ci8vLyBgYGAKLy8vCi8vLyBTZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLXN0cmluZ3MjaW50dG9jb2luc3N0" + - "cmluZwovLy8KLy8vIFtmaXhlZC1wb2ludCByZXByZXNlbnRhdGlvbl06IGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0ZpeGVkLXBvaW50X2FyaXRobWV0aWMK" + - "Ly8vIFtuYW5vVG9uY29pbl06IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL2Jvb2svaW50ZWdlcnMjbmFub3RvbmNvaW4KLy8vCmlubGluZSBleHRlbmRzIGZ1biB0" + - "b0NvaW5zU3RyaW5nKHNlbGY6IEludCk6IFN0cmluZyB7CiAgICByZXR1cm4gc2VsZi50b0Zsb2F0U3RyaW5nKDkpOwp9CgovLy8gRXh0ZW5zaW9uIGZ1bmN0aW9uIGZv" + - "ciB0aGUgYFN0cmluZ2AgdHlwZS4KLy8vCi8vLyBSZXR1cm5zIGEgYENlbGxgIGZyb20gYSBgU3RyaW5nYCBieSBwcmVmaXhpbmcgdGhlIGxhdHRlciB3aXRoIGZvdXIg" + - "bnVsbCBieXRlcy4KLy8vIFRoaXMgZm9ybWF0IGlzIHVzZWQgZm9yIHBhc3NpbmcgdGV4dCBjb21tZW50cyBhcyBtZXNzYWdlIGJvZGllcy4KLy8vCi8vLyBOT1RFOiAq" + - "KkdhcyBleHBlbnNpdmUhKiogVGhpcyBmdW5jdGlvbiB1c2VzIDUwMCBnYXMgdW5pdHMgb3IgbW9yZS4KLy8vCi8vLyBgYGB0YWN0Ci8vLyBmdW4gZXhhbXBsZSgpIHsK" + - "Ly8vICAgICBsZXQgczogU3RyaW5nID0gIldoZW4gbGlmZSBnaXZlcyB5b3UgbGVtb25zLCBjYWxsIHRoZW0gJ3llbGxvdyBvcmFuZ2VzJyBhbmQgc2VsbCB0aGVtIGZv" + - "ciBkb3VibGUgdGhlIHByaWNlLiI7Ci8vLyAgICAgbGV0IGZpeno6IENlbGwgPSBzLmFzQ29tbWVudCgpOwovLy8KLy8vICAgICBsZXQgYjogU3RyaW5nQnVpbGRlciA9" + - "IGJlZ2luQ29tbWVudCgpOwovLy8gICAgIGIuYXBwZW5kKHMpOwovLy8gICAgIGxldCBidXp6OiBDZWxsID0gYi50b0NlbGwoKTsKLy8vCi8vLyAgICAgZml6eiA9PSBi" + - "dXp6OyAvLyB0cnVlCi8vLyB9Ci8vLyBgYGAKLy8vCi8vLyBTZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLXN0cmluZ3Mjc3RyaW5nYXNjb21t" + - "ZW50Ci8vLwpleHRlbmRzIGZ1biBhc0NvbW1lbnQoc2VsZjogU3RyaW5nKTogQ2VsbCB7CiAgICBsZXQgYjogU3RyaW5nQnVpbGRlciA9IGJlZ2luQ29tbWVudCgpOwog" + - "ICAgYi5hcHBlbmQoc2VsZik7CiAgICByZXR1cm4gYi50b0NlbGwoKTsKfQoKLy8vIEV4dGVuc2lvbiBmdW5jdGlvbiBmb3IgdGhlIGBTdHJpbmdgIHR5cGUuCi8vLwov" + - "Ly8gQ2FzdHMgdGhlIGBTdHJpbmdgIGJhY2sgdG8gdGhlIHVuZGVybHlpbmcgYFNsaWNlYCBhbmQgcmV0dXJucyBpdC4gVGhlIGludmVyc2Ugb2YgYFNsaWNlLmFzU3Ry" + - "aW5nKClgLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAgIGxldCBzOiBTdHJpbmcgPSAiSXQncyBhbGl2ZSEgSXQncyBhbGl2ZSEhISI7" + - "Ci8vLyAgICAgbGV0IGZpeno6IFNsaWNlID0gcy5hc1NsaWNlKCk7Ci8vLyAgICAgbGV0IGJ1eno6IFNsaWNlID0gcy5hc1NsaWNlKCkuYXNTdHJpbmcoKS5hc1NsaWNl" + - "KCk7Ci8vLwovLy8gICAgIGZpenogPT0gYnV6ejsgLy8gdHJ1ZQovLy8gfQovLy8gYGBgCi8vLwovLy8gU2VlOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYv" + - "Y29yZS1zdHJpbmdzI3N0cmluZ2Fzc2xpY2UKLy8vCi8vLwphc20gZXh0ZW5kcyBmdW4gYXNTbGljZShzZWxmOiBTdHJpbmcpOiBTbGljZSB7fQoKLy8vIEV4dGVuc2lv" + - "biBmdW5jdGlvbiBmb3IgdGhlIGBTbGljZWAgdHlwZS4KLy8vCi8vLyBDYXN0cyB0aGUgYFNsaWNlYCB0byBhIGBTdHJpbmdgIGFuZCByZXR1cm5zIGl0LiBUaGUgaW52" + - "ZXJzZSBvZiBgU3RyaW5nLmFzU2xpY2UoKWAuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKSB7Ci8vLyAgICAgbGV0IHM6IFN0cmluZyA9ICJLZWVwIHlv" + - "dXIgU2xpY2VzIGNsb3NlLCBidXQgeW91ciBTdHJpbmdzIGNsb3Nlci4iOwovLy8gICAgIGxldCBmaXp6OiBTdHJpbmcgPSBzOwovLy8gICAgIGxldCBidXp6OiBTdHJp" + - "bmcgPSBzLmFzU2xpY2UoKS5hc1N0cmluZygpOwovLy8KLy8vICAgICBmaXp6ID09IGJ1eno7IC8vIHRydWUKLy8vIH0KLy8vIGBgYAovLy8KLy8vIFNlZTogaHR0cHM6" + - "Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtY2VsbHMjc2xpY2Vhc3N0cmluZwovLy8KYXNtIGV4dGVuZHMgZnVuIGFzU3RyaW5nKHNlbGY6IFNsaWNlKTogU3Ry" + - "aW5nIHt9CgovLy8gRXh0ZW5zaW9uIGZ1bmN0aW9uIGZvciB0aGUgYFNsaWNlYCB0eXBlLgovLy8KLy8vIFJldHVybnMgYSBuZXcgYFNsaWNlYCBmcm9tIHRoZSBkZWNv" + - "ZGVkIFtiYXNlNjRdIGBTbGljZWAuCi8vLwovLy8gTm90ZSB0aGF0IHRoaXMgZnVuY3Rpb24gaXMgbGltaXRlZCBhbmQgb25seSB0YWtlcyB0aGUgZmlyc3QgMTAyMyBi" + - "aXRzIG9mIGRhdGEgZnJvbQovLy8gdGhlIGdpdmVuIGBTbGljZWAsIHdpdGhvdXQgdGhyb3dpbmcgYW4gZXhjZXB0aW9uIGlmIHRoZSBgU2xpY2VgIGhhcyBtb3JlIGRh" + - "dGEKLy8vIChpLmUuLCB3aGVuIGl0IGhhcyBhbnkgcmVmZXJlbmNlcykuCi8vLwovLy8gSWYgdGhlIGdpdmVuIGBTbGljZWAgY29udGFpbnMgY2hhcmFjdGVycyBub3Qg" + - "ZnJvbSB0aGUgYmFzZTY0IHNldCwgYW4gZXhjZXB0aW9uIHdpdGgKLy8vIFtleGl0IGNvZGUgMTM0XSB3aWxsIGJlIHRocm93bjogYEludmFsaWQgYXJndW1lbnRgLgov" + - "Ly8KLy8vIE5PVEU6ICoqR2FzIGV4cGVuc2l2ZSEqKiBUaGlzIGZ1bmN0aW9uIHVzZXMgNTAwIGdhcyB1bml0cyBvciBtb3JlLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1" + - "biBleGFtcGxlKCkgewovLy8gICAgIGxldCBzOiBTbGljZSA9ICJTU0JoYlNCSGNtOXZkQzQ9Ii5hc1NsaWNlKCk7Ci8vLyAgICAgbGV0IGZpeno6IFNsaWNlID0gcy5m" + - "cm9tQmFzZTY0KCk7Ci8vLyB9Ci8vLyBgYGAKLy8vCi8vLyBTZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLXN0cmluZ3Mjc3RyaW5nZnJvbWJh" + - "c2U2NAovLy8KLy8vIFtleGl0IGNvZGUgMTM0XTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvYm9vay9leGl0LWNvZGVzIzEzNAovLy8gW2Jhc2U2NF06IGh0dHBz" + - "Oi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0Jhc2U2NAppbmxpbmUgZXh0ZW5kcyBmdW4gZnJvbUJhc2U2NChzZWxmOiBTdHJpbmcpOiBTbGljZSB7CiAgICByZXR1cm4g" + - "c2VsZi5hc1NsaWNlKCkuZnJvbUJhc2U2NCgpOwp9CgovLy8gRXh0ZW5zaW9uIGZ1bmN0aW9uIGZvciB0aGUgYFN0cmluZ2AgdHlwZS4KLy8vCi8vLyBSZXR1cm5zIGEg" + - "YFNsaWNlYCBmcm9tIHRoZSBkZWNvZGVkIFtiYXNlNjRdIGBTdHJpbmdgLgovLy8gQW4gYWxpYXMgdG8gYHNlbGYuYXNTbGljZSgpLmZyb21CYXNlNjQoKWAuCi8vLwov" + - "Ly8gTm90ZSB0aGF0IHRoaXMgZnVuY3Rpb24gaXMgbGltaXRlZCBhbmQgb25seSB0YWtlcyB0aGUgZmlyc3QgMTAyMyBiaXRzIG9mIGRhdGEgZnJvbQovLy8gdGhlIGdp" + - "dmVuIGBTdHJpbmdgLCB3aXRob3V0IHRocm93aW5nIGFuIGV4Y2VwdGlvbiB3aGVuIHRoZSBgU3RyaW5nYCBpcyBsYXJnZXIKLy8vIChpLmUuLCBjb250YWlucyBtb3Jl" + - "IHRoYW4gMTAyMyBiaXRzIG9mIGRhdGEpLgovLy8KLy8vIE5PVEU6ICoqR2FzIGV4cGVuc2l2ZSEqKiBUaGlzIGZ1bmN0aW9uIHVzZXMgNTAwIGdhcyB1bml0cyBvciBt" + - "b3JlLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAgIGxldCBzOiBTdHJpbmcgPSAiU0dWeVpTZHpJRXB2YUc1dWVTRT0iOwovLy8gICAg" + - "IGxldCBmaXp6OiBTbGljZSA9IHMuZnJvbUJhc2U2NCgpOwovLy8gICAgIGxldCBidXp6OiBTbGljZSA9IHMuYXNTbGljZSgpLmZyb21CYXNlNjQoKTsKLy8vCi8vLyAg" + - "ICAgZml6eiA9PSBidXp6OyAvLyB0cnVlCi8vLyB9Ci8vLyBgYGAKLy8vCi8vLyAjIyMjIEV4aXQgY29kZXMKLy8vCi8vLyAqIDEzNDogW0ludmFsaWQgYXJndW1lbnRd" + - "IOKAlCBUaHJvd24gd2hlbiB0aGUgZ2l2ZW4gYFN0cmluZ2AgY29udGFpbnMgY2hhcmFjdGVycyBub3QgZnJvbSB0aGUgYmFzZTY0IHNldC4KLy8vCi8vLyBTZWU6IGh0" + - "dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWNlbGxzI3NsaWNlZnJvbWJhc2U2NAovLy8KLy8vIFtJbnZhbGlkIGFyZ3VtZW50XTogaHR0cHM6Ly9kb2Nz" + - "LnRhY3QtbGFuZy5vcmcvYm9vay9leGl0LWNvZGVzIzEzNAovLy8gW2Jhc2U2NF06IGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0Jhc2U2NAovLy8KZXh0ZW5k" + - "cyBmdW4gZnJvbUJhc2U2NChzZWxmOiBTbGljZSk6IFNsaWNlIHsKICAgIGxldCBzaXplOiBJbnQgPSBzZWxmLmJpdHMoKSAvIDg7CiAgICBsZXQgcmVzdWx0OiBCdWls" + - "ZGVyID0gYmVnaW5DZWxsKCk7CgogICAgcmVwZWF0IChzaXplKSB7CiAgICAgICAgbGV0IGNvZGU6IEludCA9IHNlbGYubG9hZFVpbnQoOCk7CiAgICAgICAgaWYgKGNv" + - "ZGUgPj0gNjUgJiYgY29kZSA8PSA5MCkgeyAvLyBBLVoKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0LnN0b3JlVWludChjb2RlIC0gNjUsIDYpOwogICAgICAgIH0g" + - "ZWxzZSBpZiAoY29kZSA+PSA5NyAmJiBjb2RlIDw9IDEyMikgeyAvLyBhLXoKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0LnN0b3JlVWludChjb2RlIC0gKDk3IC0g" + - "MjYpLCA2KTsKICAgICAgICB9IGVsc2UgaWYgKGNvZGUgPj0gNDggJiYgY29kZSA8PSA1NykgeyAvLyAwLTkKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0LnN0b3Jl" + - "VWludChjb2RlICsgKDUyIC0gNDgpLCA2KTsKICAgICAgICB9IGVsc2UgaWYgKGNvZGUgPT0gNDUgfHwgY29kZSA9PSA0MykgeyAvLyAtIG9yICsKICAgICAgICAgICAg" + - "cmVzdWx0ID0gcmVzdWx0LnN0b3JlVWludCg2MiwgNik7CiAgICAgICAgfSBlbHNlIGlmIChjb2RlID09IDk1IHx8IGNvZGUgPT0gNDcpIHsgLy8gXyBvciAvCiAgICAg" + - "ICAgICAgIHJlc3VsdCA9IHJlc3VsdC5zdG9yZVVpbnQoNjMsIDYpOwogICAgICAgIH0gZWxzZSBpZiAoY29kZSA9PSA2MSkgeyAvLyA9CiAgICAgICAgICAgIC8vIFNr" + - "aXAKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0aHJvdyhUYWN0RXhpdENvZGVJbnZhbGlkQXJndW1lbnQpOwogICAgICAgIH0KICAgIH0KCiAgICAvLyBQYWRk" + - "aW5nCiAgICBsZXQgdG90YWw6IEludCA9IHJlc3VsdC5iaXRzKCk7CiAgICBsZXQgcGFkZGluZzogSW50ID0gdG90YWwgJSA4OwogICAgaWYgKHBhZGRpbmcgIT0gMCkg" + - "ewogICAgICAgIGxldCBzOiBTbGljZSA9IHJlc3VsdC5hc1NsaWNlKCk7CiAgICAgICAgcmV0dXJuIHMubG9hZEJpdHModG90YWwgLSBwYWRkaW5nKTsKICAgIH0gZWxz" + - "ZSB7CiAgICAgICAgcmV0dXJuIHJlc3VsdC5hc1NsaWNlKCk7CiAgICB9Cn0KCi8vCi8vIEFkZHJlc3MgY29udmVyc2lvbgovLwoKLy8vIEV4dGVuc2lvbiBmdW5jdGlv" + - "biBmb3IgdGhlIGBBZGRyZXNzYCB0eXBlLgovLy8KLy8vIFJldHVybnMgYSBgU3RyaW5nYCBmcm9tIGFuIGBBZGRyZXNzYC4KLy8vCi8vLyBgYGB0YWN0Ci8vLyBmdW4g" + - "ZXhhbXBsZSgpIHsKLy8vICAgICBsZXQgY29tbXVuaXR5OiBBZGRyZXNzID0gYWRkcmVzcygiVVFEcFhMWktya0hzT3VFX0MxYVM2OUM2OTd3RTU2OHZUbnFTZVJmQlha" + - "ZnZtVk9vIik7Ci8vLyAgICAgbGV0IGZpeno6IFN0cmluZyA9IGNvbW11bml0eS50b1N0cmluZygpOwovLy8gfQovLy8gYGBgCi8vLwovLy8gU2VlOiBodHRwczovL2Rv" + - "Y3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1hZGRyZXNzZXMjYWRkcmVzc3Rvc3RyaW5nCi8vLwpAbmFtZShfX3RhY3RfYWRkcmVzc190b191c2VyX2ZyaWVuZGx5KQpl" + - "eHRlbmRzIG5hdGl2ZSB0b1N0cmluZyhzZWxmOiBBZGRyZXNzKTogU3RyaW5nOwo="; + "bGV0IGZpeno6IFN0cmluZyA9ICg0MikudG9GbG9hdFN0cmluZyg5KTsgLy8gIjAuMDAwMDAwMDQyIgovLy8gfQovLy8gYGBgCi8vLwovLy8gIyMjIyBFeGl0IGNvZGVz" + + "Ci8vLwovLy8gKiAxMzQ6IFtJbnZhbGlkIGFyZ3VtZW50XSDigJQgVGhyb3duIHdoZW4gdGhlIGdpdmVuIGBkaWdpdHNgIHZhbHVlIGlzIG91dCBvZiByYW5nZS4KLy8v" + + "Ci8vLyBTZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLXN0cmluZ3MjaW50dG9mbG9hdHN0cmluZwovLy8KLy8vIFtmaXhlZC1wb2ludCByZXBy" + + "ZXNlbnRhdGlvbl06IGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0ZpeGVkLXBvaW50X2FyaXRobWV0aWMKLy8vIFtJbnZhbGlkIGFyZ3VtZW50XTogaHR0cHM6" + + "Ly9kb2NzLnRhY3QtbGFuZy5vcmcvYm9vay9leGl0LWNvZGVzIzEzNAovLy8KYXNtIGV4dGVuZHMgZnVuIHRvRmxvYXRTdHJpbmcoc2VsZjogSW50LCBkaWdpdHM6IElu" + + "dCk6IFN0cmluZyB7CiAgICAvLyB4IGRpZ2l0cwoKICAgIERVUCAvLyB4IGRpZ2l0cyBkaWdpdHMKICAgIDEgTEVTU0lOVCAvLyB4IGRpZ2l0cyBkaWdpdHM8PTAKICAg" + + "IDEzNCBUSFJPV0lGIC8vIHggZGlnaXRzCiAgICBEVVAgLy8geCBkaWdpdHMgZGlnaXRzCiAgICA3NyBHVElOVCAvLyB4IGRpZ2l0cyBkaWdpdHM+NzcKICAgIDEzNCBU" + + "SFJPV0lGIC8vIHggZGlnaXRzCgogICAgTkVXQyAvLyB4IGRpZ2l0cyBiCiAgICBST1RSRVYgLy8gYiB4IGRpZ2l0cwogICAgczEgUFVTSCAvLyBiIHggZGlnaXRzIHgK" + + "ICAgIDAgTEVTU0lOVCAvLyBiIHggZGlnaXRzIHg8MD8KCiAgICA8ewogICAgICAgIC8vIGIgeCBkaWdpdHMKICAgICAgICBST1QgLy8geCBkaWdpdHMgYgogICAgICAg" + + "IHh7MmR9IFNUU0xJQ0VDT05TVCAvLyB4IGRpZ2l0cyBiCiAgICAgICAgUk9UIC8vIGRpZ2l0cyBiIHgKICAgICAgICBORUdBVEUgLy8gZGlnaXRzIGIgLXgKICAgICAg" + + "ICBST1QgLy8gYiAteCBkaWdpdHMKICAgIH0+Q09OVCBJRgoKICAgIC8vIGIgeCBkaWdpdHMKICAgIE9ORSAvLyBiIHggZGlnaXRzIDEKICAgIE9WRVIgLy8gYiB4IGRp" + + "Z2l0cyAxIGRpZ2l0cwoKICAgIDx7IDEwIE1VTENPTlNUIH0+Q09OVCBSRVBFQVQgLy8gYiB4IGRpZ2l0cyAxMF5kaWdpdHMKCiAgICBzMSBzMiBYQ0hHIC8vIGIgZGln" + + "aXRzIHggMTBeZGlnaXRzCiAgICBESVZNT0QgLy8gYiBkaWdpdHMgbGVmdCByaWdodAogICAgczMgczMgWENIRzIgLy8gcmlnaHQgZGlnaXRzIGIgbGVmdAoKICAgIDx7" + + "CiAgICAgICAgLy8gYiB4CgogICAgICAgIDx7CiAgICAgICAgICAgIC8vIGIgeAogICAgICAgICAgICAxMCBQVVNISU5UIERJVk1PRCAvLyBiIHgvMTAgeCUxMAogICAg" + + "ICAgICAgICA0OCBBRERDT05TVCAvLyBiIHgvMTAgKHglMTArNDgpCiAgICAgICAgICAgIHMyIHMyIHMwIFhDMlBVIElTWkVSTyAvLyAoeCUxMCs0OCkgYiB4LzEwIHgv" + + "MTA9PTA/CiAgICAgICAgfT5DT05UIFVOVElMCiAgICAgICAgLy8gLi4uIGIgeAoKICAgICAgICBEUk9QIC8vIC4uLiBiCiAgICAgICAgREVQVEggREVDIC8vIC4uLiBi" + + "IG4KICAgICAgICA8eyA4IFNUVSB9PkNPTlQgUkVQRUFUIC8vIGIKICAgIH0+Q09OVCAyIDEgQ0FMTFhBUkdTCgogICAgLy8gcmlnaHQgZGlnaXRzICJsZWZ0IgoKICAg" + + "IFJPVCAvLyBkaWdpdHMgImxlZnQiIHJpZ2h0CiAgICBEVVAgLy8gZGlnaXRzICJsZWZ0IiByaWdodCByaWdodAogICAgSVNaRVJPIC8vIGRpZ2l0cyAibGVmdCIgcmln" + + "aHQgcmlnaHQ9PTA/CgogICAgPHsKICAgICAgICAvLyBkaWdpdHMgImxlZnQiIHJpZ2h0CiAgICAgICAgRFJPUCAvLyBkaWdpdHMgImxlZnQiCiAgICAgICAgTklQIC8v" + + "ICJsZWZ0IgogICAgfT5DT05UCgogICAgPHsKICAgICAgICAvLyBkaWdpdHMgImxlZnQiIHJpZ2h0CiAgICAgICAgWkVSTyAvLyBkaWdpdHMgImxlZnQiIHJpZ2h0IDAK" + + "ICAgICAgICBTV0FQIC8vIGRpZ2l0cyAibGVmdCIgMCByaWdodAoKICAgICAgICA8ewogICAgICAgICAgICAvLyBkaWdpdHMgImxlZnQiIGkgcmlnaHQKICAgICAgICAg" + + "ICAgRFVQIC8vIGRpZ2l0cyAibGVmdCIgaSByaWdodCByaWdodAogICAgICAgICAgICAxMCBQVVNISU5UIC8vIGRpZ2l0cyAibGVmdCIgaSByaWdodCByaWdodCAxMAog" + + "ICAgICAgICAgICBNT0QgLy8gZGlnaXRzICJsZWZ0IiBpIHJpZ2h0IHJpZ2h0JTEwCiAgICAgICAgICAgIElTWkVSTyAvLyBkaWdpdHMgImxlZnQiIGkgcmlnaHQgcmln" + + "aHQlMTA9PTA/CiAgICAgICAgfT5DT05UCgogICAgICAgIDx7CiAgICAgICAgICAgIC8vIGRpZ2l0cyAibGVmdCIgaSByaWdodAogICAgICAgICAgICAxMCBQVVNISU5U" + + "IC8vIGRpZ2l0cyAibGVmdCIgaSByaWdodCAxMAogICAgICAgICAgICBESVYgLy8gZGlnaXRzICJsZWZ0IiBpIHJpZ2h0LzEwCiAgICAgICAgICAgIFNXQVAgLy8gZGln" + + "aXRzICJsZWZ0IiByaWdodC8xMCBpCiAgICAgICAgICAgIElOQyAvLyBkaWdpdHMgImxlZnQiIHJpZ2h0LzEwIGkrMQogICAgICAgICAgICBTV0FQIC8vIGRpZ2l0cyAi" + + "bGVmdCIgaSsxIHJpZ2h0LzEwCiAgICAgICAgfT5DT05UCgogICAgICAgIFdISUxFIC8vIGRpZ2l0cyAibGVmdCIgaSByaWdodAoKICAgICAgICA8ewogICAgICAgICAg" + + "ICAvLyB4CiAgICAgICAgICAgIE5FV0MgLy8geCBiCiAgICAgICAgICAgIFNXQVAgLy8gYiB4CgogICAgICAgICAgICA8ewogICAgICAgICAgICAgICAgLy8gYiB4CiAg" + + "ICAgICAgICAgICAgICAxMCBQVVNISU5UIERJVk1PRCAvLyBiIHgvMTAgeCUxMAogICAgICAgICAgICAgICAgNDggQUREQ09OU1QgLy8gYiB4LzEwICh4JTEwKzQ4KQog" + + "ICAgICAgICAgICAgICAgczIgczIgczAgWEMyUFUgSVNaRVJPIC8vICh4JTEwKzQ4KSBiIHgvMTAgeC8xMD09MD8KICAgICAgICAgICAgfT5DT05UIFVOVElMCiAgICAg" + + "ICAgICAgIC8vIC4uLiBiIHgKCiAgICAgICAgICAgIERST1AgLy8gLi4uIGIKICAgICAgICAgICAgREVQVEggREVDIERVUCAvLyAuLi4gYiBuIG4KICAgICAgICAgICAg" + + "Uk9UUkVWIC8vIC4uLiBuIGIgbgogICAgICAgICAgICA8ewogICAgICAgICAgICAgICAgLy8gLi4uIGMgbiBiCiAgICAgICAgICAgICAgICBzMSBzMiBYQ0hHIC8vIC4u" + + "LiBuIGMgYgogICAgICAgICAgICAgICAgOCBTVFUgLy8gLi4uIG4gYgogICAgICAgICAgICB9PkNPTlQgUkVQRUFUIC8vIG4gYgogICAgICAgIH0+Q09OVCAxIDIgQ0FM" + + "TFhBUkdTCiAgICAgICAgLy8gZGlnaXRzICJsZWZ0IiBpIHJpZ2h0X2RpZ2l0cyAicmlnaHQiCiAgICAgICAgUk9UUkVWIC8vIGRpZ2l0cyAibGVmdCIgInJpZ2h0IiBp" + + "IHJpZ2h0X2RpZ2l0cwogICAgICAgIEFERCAvLyBkaWdpdHMgImxlZnQiICJyaWdodCIgcmlnaHRfZGlnaXRzCgogICAgICAgIHMzIHMxIFhDSEcgLy8gInJpZ2h0IiAi" + + "bGVmdCIgZGlnaXRzIHJpZ2h0X2RpZ2l0cwogICAgICAgIFNVQiAvLyAicmlnaHQiICJsZWZ0IiBkaWdpdHNfZGlmZgogICAgICAgIFNXQVAgLy8gInJpZ2h0IiBkaWdp" + + "dHNfZGlmZiAibGVmdCIKICAgICAgICB4ezJlfSBTVFNMSUNFQ09OU1QgLy8gInJpZ2h0IiBkaWdpdHNfZGlmZiAibGVmdC4iCiAgICAgICAgU1dBUCAvLyAicmlnaHQi" + + "ICJsZWZ0LiIgZGlnaXRzX2RpZmYKCiAgICAgICAgPHsKICAgICAgICAgICAgLy8gInJpZ2h0IiAibGVmdC4iCiAgICAgICAgICAgIHh7MzB9IFNUU0xJQ0VDT05TVCAv" + + "LyAicmlnaHQiICJsZWZ0LjAiCiAgICAgICAgfT5DT05UIFJFUEVBVCAvLyAicmlnaHQiICJsZWZ0LjAwMCIKCiAgICAgICAgU1RCIC8vICJsZWZ0LjAwMHJpZ2h0Igog" + + "ICAgfT5DT05UCgogICAgSUZFTFNFIC8vIGIKCiAgICBFTkRDIENUT1MgLy8gcwp9CgovLy8gRXh0ZW5zaW9uIGZ1bmN0aW9uIGZvciB0aGUgYEludGAgdHlwZS4KLy8v" + + "Ci8vLyBSZXR1cm5zIGEgYFN0cmluZ2AgZnJvbSBhbiBgSW50YCB2YWx1ZSB1c2luZyBhIFtmaXhlZC1wb2ludCByZXByZXNlbnRhdGlvbl0gb2YgYSBmcmFjdGlvbmFs" + + "IG51bWJlci4KLy8vIEFuIGFsaWFzIHRvIGBzZWxmLnRvRmxvYXRTdHJpbmcoOSlgLgovLy8KLy8vIFRoaXMgaXMgdXNlZCB0byByZXByZXNlbnQgW25hbm9Ub25jb2lu" + + "XSBgSW50YCB2YWx1ZXMgdXNpbmcgc3RyaW5ncy4KLy8vCi8vLyBgYGB0YWN0Ci8vLyBmdW4gZXhhbXBsZSgpIHsKLy8vICAgICBsZXQgbmFub3RvbnM6IEludCA9IDQy" + + "OwovLy8gICAgIGxldCBmaXp6OiBTdHJpbmcgPSBuYW5vdG9ucy50b0NvaW5zU3RyaW5nKCk7Ci8vLyAgICAgbGV0IGJ1eno6IFN0cmluZyA9IG5hbm90b25zLnRvRmxv" + + "YXRTdHJpbmcoOSk7Ci8vLwovLy8gICAgIGZpenogPT0gYnV6ejsgLy8gdHJ1ZSwgYm90aCBzdG9yZSAiMC4wMDAwMDAwNDIiCi8vLyB9Ci8vLyBgYGAKLy8vCi8vLyBT" + + "ZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLXN0cmluZ3MjaW50dG9jb2luc3N0cmluZwovLy8KLy8vIFtmaXhlZC1wb2ludCByZXByZXNlbnRh" + + "dGlvbl06IGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0ZpeGVkLXBvaW50X2FyaXRobWV0aWMKLy8vIFtuYW5vVG9uY29pbl06IGh0dHBzOi8vZG9jcy50YWN0" + + "LWxhbmcub3JnL2Jvb2svaW50ZWdlcnMjbmFub3RvbmNvaW4KLy8vCmlubGluZSBleHRlbmRzIGZ1biB0b0NvaW5zU3RyaW5nKHNlbGY6IEludCk6IFN0cmluZyB7CiAg" + + "ICByZXR1cm4gc2VsZi50b0Zsb2F0U3RyaW5nKDkpOwp9CgovLy8gRXh0ZW5zaW9uIGZ1bmN0aW9uIGZvciB0aGUgYFN0cmluZ2AgdHlwZS4KLy8vCi8vLyBSZXR1cm5z" + + "IGEgYENlbGxgIGZyb20gYSBgU3RyaW5nYCBieSBwcmVmaXhpbmcgdGhlIGxhdHRlciB3aXRoIGZvdXIgbnVsbCBieXRlcy4KLy8vIFRoaXMgZm9ybWF0IGlzIHVzZWQg" + + "Zm9yIHBhc3NpbmcgdGV4dCBjb21tZW50cyBhcyBtZXNzYWdlIGJvZGllcy4KLy8vCi8vLyBOT1RFOiAqKkdhcyBleHBlbnNpdmUhKiogVGhpcyBmdW5jdGlvbiB1c2Vz" + + "IDUwMCBnYXMgdW5pdHMgb3IgbW9yZS4KLy8vCi8vLyBgYGB0YWN0Ci8vLyBmdW4gZXhhbXBsZSgpIHsKLy8vICAgICBsZXQgczogU3RyaW5nID0gIldoZW4gbGlmZSBn" + + "aXZlcyB5b3UgbGVtb25zLCBjYWxsIHRoZW0gJ3llbGxvdyBvcmFuZ2VzJyBhbmQgc2VsbCB0aGVtIGZvciBkb3VibGUgdGhlIHByaWNlLiI7Ci8vLyAgICAgbGV0IGZp" + + "eno6IENlbGwgPSBzLmFzQ29tbWVudCgpOwovLy8KLy8vICAgICBsZXQgYjogU3RyaW5nQnVpbGRlciA9IGJlZ2luQ29tbWVudCgpOwovLy8gICAgIGIuYXBwZW5kKHMp" + + "OwovLy8gICAgIGxldCBidXp6OiBDZWxsID0gYi50b0NlbGwoKTsKLy8vCi8vLyAgICAgZml6eiA9PSBidXp6OyAvLyB0cnVlCi8vLyB9Ci8vLyBgYGAKLy8vCi8vLyBT" + + "ZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLXN0cmluZ3Mjc3RyaW5nYXNjb21tZW50Ci8vLwpleHRlbmRzIGZ1biBhc0NvbW1lbnQoc2VsZjog" + + "U3RyaW5nKTogQ2VsbCB7CiAgICBsZXQgYjogU3RyaW5nQnVpbGRlciA9IGJlZ2luQ29tbWVudCgpOwogICAgYi5hcHBlbmQoc2VsZik7CiAgICByZXR1cm4gYi50b0Nl" + + "bGwoKTsKfQoKLy8vIEV4dGVuc2lvbiBmdW5jdGlvbiBmb3IgdGhlIGBTdHJpbmdgIHR5cGUuCi8vLwovLy8gQ2FzdHMgdGhlIGBTdHJpbmdgIGJhY2sgdG8gdGhlIHVu" + + "ZGVybHlpbmcgYFNsaWNlYCBhbmQgcmV0dXJucyBpdC4gVGhlIGludmVyc2Ugb2YgYFNsaWNlLmFzU3RyaW5nKClgLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFt" + + "cGxlKCkgewovLy8gICAgIGxldCBzOiBTdHJpbmcgPSAiSXQncyBhbGl2ZSEgSXQncyBhbGl2ZSEhISI7Ci8vLyAgICAgbGV0IGZpeno6IFNsaWNlID0gcy5hc1NsaWNl" + + "KCk7Ci8vLyAgICAgbGV0IGJ1eno6IFNsaWNlID0gcy5hc1NsaWNlKCkuYXNTdHJpbmcoKS5hc1NsaWNlKCk7Ci8vLwovLy8gICAgIGZpenogPT0gYnV6ejsgLy8gdHJ1" + + "ZQovLy8gfQovLy8gYGBgCi8vLwovLy8gU2VlOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1zdHJpbmdzI3N0cmluZ2Fzc2xpY2UKLy8vCi8vLwph" + + "c20gZXh0ZW5kcyBmdW4gYXNTbGljZShzZWxmOiBTdHJpbmcpOiBTbGljZSB7fQoKLy8vIEV4dGVuc2lvbiBmdW5jdGlvbiBmb3IgdGhlIGBTbGljZWAgdHlwZS4KLy8v" + + "Ci8vLyBDYXN0cyB0aGUgYFNsaWNlYCB0byBhIGBTdHJpbmdgIGFuZCByZXR1cm5zIGl0LiBUaGUgaW52ZXJzZSBvZiBgU3RyaW5nLmFzU2xpY2UoKWAuCi8vLwovLy8g" + + "YGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKSB7Ci8vLyAgICAgbGV0IHM6IFN0cmluZyA9ICJLZWVwIHlvdXIgU2xpY2VzIGNsb3NlLCBidXQgeW91ciBTdHJpbmdzIGNs" + + "b3Nlci4iOwovLy8gICAgIGxldCBmaXp6OiBTdHJpbmcgPSBzOwovLy8gICAgIGxldCBidXp6OiBTdHJpbmcgPSBzLmFzU2xpY2UoKS5hc1N0cmluZygpOwovLy8KLy8v" + + "ICAgICBmaXp6ID09IGJ1eno7IC8vIHRydWUKLy8vIH0KLy8vIGBgYAovLy8KLy8vIFNlZTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtY2VsbHMj" + + "c2xpY2Vhc3N0cmluZwovLy8KYXNtIGV4dGVuZHMgZnVuIGFzU3RyaW5nKHNlbGY6IFNsaWNlKTogU3RyaW5nIHt9CgovLy8gRXh0ZW5zaW9uIGZ1bmN0aW9uIGZvciB0" + + "aGUgYFNsaWNlYCB0eXBlLgovLy8KLy8vIFJldHVybnMgYSBuZXcgYFNsaWNlYCBmcm9tIHRoZSBkZWNvZGVkIFtiYXNlNjRdIGBTbGljZWAuCi8vLwovLy8gTm90ZSB0" + + "aGF0IHRoaXMgZnVuY3Rpb24gaXMgbGltaXRlZCBhbmQgb25seSB0YWtlcyB0aGUgZmlyc3QgMTAyMyBiaXRzIG9mIGRhdGEgZnJvbQovLy8gdGhlIGdpdmVuIGBTbGlj" + + "ZWAsIHdpdGhvdXQgdGhyb3dpbmcgYW4gZXhjZXB0aW9uIGlmIHRoZSBgU2xpY2VgIGhhcyBtb3JlIGRhdGEKLy8vIChpLmUuLCB3aGVuIGl0IGhhcyBhbnkgcmVmZXJl" + + "bmNlcykuCi8vLwovLy8gSWYgdGhlIGdpdmVuIGBTbGljZWAgY29udGFpbnMgY2hhcmFjdGVycyBub3QgZnJvbSB0aGUgYmFzZTY0IHNldCwgYW4gZXhjZXB0aW9uIHdp" + + "dGgKLy8vIFtleGl0IGNvZGUgMTM0XSB3aWxsIGJlIHRocm93bjogYEludmFsaWQgYXJndW1lbnRgLgovLy8KLy8vIE5PVEU6ICoqR2FzIGV4cGVuc2l2ZSEqKiBUaGlz" + + "IGZ1bmN0aW9uIHVzZXMgNTAwIGdhcyB1bml0cyBvciBtb3JlLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAgIGxldCBzOiBTbGljZSA9" + + "ICJTU0JoYlNCSGNtOXZkQzQ9Ii5hc1NsaWNlKCk7Ci8vLyAgICAgbGV0IGZpeno6IFNsaWNlID0gcy5mcm9tQmFzZTY0KCk7Ci8vLyB9Ci8vLyBgYGAKLy8vCi8vLyBT" + + "ZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLXN0cmluZ3Mjc3RyaW5nZnJvbWJhc2U2NAovLy8KLy8vIFtleGl0IGNvZGUgMTM0XTogaHR0cHM6" + + "Ly9kb2NzLnRhY3QtbGFuZy5vcmcvYm9vay9leGl0LWNvZGVzIzEzNAovLy8gW2Jhc2U2NF06IGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0Jhc2U2NAppbmxp" + + "bmUgZXh0ZW5kcyBmdW4gZnJvbUJhc2U2NChzZWxmOiBTdHJpbmcpOiBTbGljZSB7CiAgICByZXR1cm4gc2VsZi5hc1NsaWNlKCkuZnJvbUJhc2U2NCgpOwp9CgovLy8g" + + "RXh0ZW5zaW9uIGZ1bmN0aW9uIGZvciB0aGUgYFN0cmluZ2AgdHlwZS4KLy8vCi8vLyBSZXR1cm5zIGEgYFNsaWNlYCBmcm9tIHRoZSBkZWNvZGVkIFtiYXNlNjRdIGBT" + + "dHJpbmdgLgovLy8gQW4gYWxpYXMgdG8gYHNlbGYuYXNTbGljZSgpLmZyb21CYXNlNjQoKWAuCi8vLwovLy8gTm90ZSB0aGF0IHRoaXMgZnVuY3Rpb24gaXMgbGltaXRl" + + "ZCBhbmQgb25seSB0YWtlcyB0aGUgZmlyc3QgMTAyMyBiaXRzIG9mIGRhdGEgZnJvbQovLy8gdGhlIGdpdmVuIGBTdHJpbmdgLCB3aXRob3V0IHRocm93aW5nIGFuIGV4" + + "Y2VwdGlvbiB3aGVuIHRoZSBgU3RyaW5nYCBpcyBsYXJnZXIKLy8vIChpLmUuLCBjb250YWlucyBtb3JlIHRoYW4gMTAyMyBiaXRzIG9mIGRhdGEpLgovLy8KLy8vIE5P" + + "VEU6ICoqR2FzIGV4cGVuc2l2ZSEqKiBUaGlzIGZ1bmN0aW9uIHVzZXMgNTAwIGdhcyB1bml0cyBvciBtb3JlLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxl" + + "KCkgewovLy8gICAgIGxldCBzOiBTdHJpbmcgPSAiU0dWeVpTZHpJRXB2YUc1dWVTRT0iOwovLy8gICAgIGxldCBmaXp6OiBTbGljZSA9IHMuZnJvbUJhc2U2NCgpOwov" + + "Ly8gICAgIGxldCBidXp6OiBTbGljZSA9IHMuYXNTbGljZSgpLmZyb21CYXNlNjQoKTsKLy8vCi8vLyAgICAgZml6eiA9PSBidXp6OyAvLyB0cnVlCi8vLyB9Ci8vLyBg" + + "YGAKLy8vCi8vLyAjIyMjIEV4aXQgY29kZXMKLy8vCi8vLyAqIDEzNDogW0ludmFsaWQgYXJndW1lbnRdIOKAlCBUaHJvd24gd2hlbiB0aGUgZ2l2ZW4gYFN0cmluZ2Ag" + + "Y29udGFpbnMgY2hhcmFjdGVycyBub3QgZnJvbSB0aGUgYmFzZTY0IHNldC4KLy8vCi8vLyBTZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWNl" + + "bGxzI3NsaWNlZnJvbWJhc2U2NAovLy8KLy8vIFtJbnZhbGlkIGFyZ3VtZW50XTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvYm9vay9leGl0LWNvZGVzIzEzNAov" + + "Ly8gW2Jhc2U2NF06IGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0Jhc2U2NAovLy8KZXh0ZW5kcyBmdW4gZnJvbUJhc2U2NChzZWxmOiBTbGljZSk6IFNsaWNl" + + "IHsKICAgIGxldCBzaXplOiBJbnQgPSBzZWxmLmJpdHMoKSAvIDg7CiAgICBsZXQgcmVzdWx0OiBCdWlsZGVyID0gYmVnaW5DZWxsKCk7CgogICAgcmVwZWF0IChzaXpl" + + "KSB7CiAgICAgICAgbGV0IGNvZGU6IEludCA9IHNlbGYubG9hZFVpbnQoOCk7CiAgICAgICAgaWYgKGNvZGUgPj0gNjUgJiYgY29kZSA8PSA5MCkgeyAvLyBBLVoKICAg" + + "ICAgICAgICAgcmVzdWx0ID0gcmVzdWx0LnN0b3JlVWludChjb2RlIC0gNjUsIDYpOwogICAgICAgIH0gZWxzZSBpZiAoY29kZSA+PSA5NyAmJiBjb2RlIDw9IDEyMikg" + + "eyAvLyBhLXoKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0LnN0b3JlVWludChjb2RlIC0gKDk3IC0gMjYpLCA2KTsKICAgICAgICB9IGVsc2UgaWYgKGNvZGUgPj0g" + + "NDggJiYgY29kZSA8PSA1NykgeyAvLyAwLTkKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0LnN0b3JlVWludChjb2RlICsgKDUyIC0gNDgpLCA2KTsKICAgICAgICB9" + + "IGVsc2UgaWYgKGNvZGUgPT0gNDUgfHwgY29kZSA9PSA0MykgeyAvLyAtIG9yICsKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0LnN0b3JlVWludCg2MiwgNik7CiAg" + + "ICAgICAgfSBlbHNlIGlmIChjb2RlID09IDk1IHx8IGNvZGUgPT0gNDcpIHsgLy8gXyBvciAvCiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdC5zdG9yZVVpbnQoNjMs" + + "IDYpOwogICAgICAgIH0gZWxzZSBpZiAoY29kZSA9PSA2MSkgeyAvLyA9CiAgICAgICAgICAgIC8vIFNraXAKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0aHJv" + + "dyhUYWN0RXhpdENvZGVJbnZhbGlkQXJndW1lbnQpOwogICAgICAgIH0KICAgIH0KCiAgICAvLyBQYWRkaW5nCiAgICBsZXQgdG90YWw6IEludCA9IHJlc3VsdC5iaXRz" + + "KCk7CiAgICBsZXQgcGFkZGluZzogSW50ID0gdG90YWwgJSA4OwogICAgaWYgKHBhZGRpbmcgIT0gMCkgewogICAgICAgIGxldCBzOiBTbGljZSA9IHJlc3VsdC5hc1Ns" + + "aWNlKCk7CiAgICAgICAgcmV0dXJuIHMubG9hZEJpdHModG90YWwgLSBwYWRkaW5nKTsKICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIHJlc3VsdC5hc1NsaWNlKCk7" + + "CiAgICB9Cn0KCi8vCi8vIEFkZHJlc3MgY29udmVyc2lvbgovLwoKLy8vIEV4dGVuc2lvbiBmdW5jdGlvbiBmb3IgdGhlIGBBZGRyZXNzYCB0eXBlLgovLy8KLy8vIFJl" + + "dHVybnMgYSBgU3RyaW5nYCBmcm9tIGFuIGBBZGRyZXNzYC4KLy8vCi8vLyBgYGB0YWN0Ci8vLyBmdW4gZXhhbXBsZSgpIHsKLy8vICAgICBsZXQgY29tbXVuaXR5OiBB" + + "ZGRyZXNzID0gYWRkcmVzcygiVVFEcFhMWktya0hzT3VFX0MxYVM2OUM2OTd3RTU2OHZUbnFTZVJmQlhaZnZtVk9vIik7Ci8vLyAgICAgbGV0IGZpeno6IFN0cmluZyA9" + + "IGNvbW11bml0eS50b1N0cmluZygpOwovLy8gfQovLy8gYGBgCi8vLwovLy8gU2VlOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1hZGRyZXNzZXMj" + + "YWRkcmVzc3Rvc3RyaW5nCi8vLwpAbmFtZShfX3RhY3RfYWRkcmVzc190b191c2VyX2ZyaWVuZGx5KQpleHRlbmRzIG5hdGl2ZSB0b1N0cmluZyhzZWxmOiBBZGRyZXNz" + + "KTogU3RyaW5nOwo="; files["std/internal/time.tact"] = "Ly8vIEdsb2JhbCBmdW5jdGlvbi4KLy8vCi8vLyBSZXR1cm5zIHRoZSBjdXJyZW50IFVuaXggdGltZS4KLy8vCi8vLyBgYGB0YWN0Ci8vLyBmdW4gZXhhbXBsZSgpIHsK" + "Ly8vICAgICBsZXQgdGltZU9mZnNldDogSW50ID0gbm93KCkgKyAxMDAwOyAvLyB0aG91c2FuZCBzZWNvbmRzIGZyb20gbm93KCkKLy8vIH0KLy8vIGBgYAovLy8KLy8v" + diff --git a/src/stdlib/stdlib/std/internal/address.tact b/src/stdlib/stdlib/std/internal/address.tact index 7df2aed0d9..793a17482a 100644 --- a/src/stdlib/stdlib/std/internal/address.tact +++ b/src/stdlib/stdlib/std/internal/address.tact @@ -1,3 +1,7 @@ +import "./debug"; +import "./cells"; +import "./exit-codes"; + /// Extension function for the `Slice` type. Available since Tact 1.6.0. /// /// Casts the `Slice` to an `Address` in a given `chain` ID and returns it. The inverse of `Address.asSlice()` and a safe but more gas-expensive version of `Slice.asAddressUnsafe()`. @@ -315,26 +319,6 @@ inline fun newBasechainAddress(hash: Int): BasechainAddress { return BasechainAddress { hash }; } -/// Global function. Available since Tact 1.6.0. -/// -/// Creates and returns a basechain address derived from a contract's `StateInit` (code and data). -/// -/// ```tact -/// fun example() { -/// let code: Cell = loadCell(); // load contract code -/// let data: Cell = loadCell(); // load contract data -/// let state: StateInit = StateInit { code, data }; -/// let addr: BasechainAddress = contractBasechainAddress(state); -/// } -/// ``` -/// -/// See: https://docs.tact-lang.org/ref/core-addresses#contractbasechainaddress -/// -inline fun contractBasechainAddress(s: StateInit): BasechainAddress { - let hash = contractHash(s.code, s.data); - return newBasechainAddress(hash); -} - /// Extension function for the `Builder` type. Available since Tact 1.6.0. /// /// Stores the basechain address in the copy of the Builder and returns that copy. diff --git a/src/stdlib/stdlib/std/internal/base.tact b/src/stdlib/stdlib/std/internal/base.tact index 4454446b3f..dd77eb39bf 100644 --- a/src/stdlib/stdlib/std/internal/base.tact +++ b/src/stdlib/stdlib/std/internal/base.tact @@ -1,3 +1,8 @@ +import "./context"; +import "./contract"; +import "./reserve"; +import "./send"; + /// Describes the base logic that is available in all contracts and traits by default. /// /// This trait is implicitly inherited by every other contract and trait. diff --git a/src/stdlib/stdlib/std/internal/contract.tact b/src/stdlib/stdlib/std/internal/contract.tact index 4f24460143..e7314e3473 100644 --- a/src/stdlib/stdlib/std/internal/contract.tact +++ b/src/stdlib/stdlib/std/internal/contract.tact @@ -1,3 +1,6 @@ +import "./address"; +import "./context"; + /// Global function. Available since Tact 1.6.0. /// /// Computes and returns an `Int` value of the SHA-256 hash of the `code` and `data` of the given contract. To assemble the `code` and `data` cells together for hashing, the standard `Cell` representation is used. @@ -83,17 +86,37 @@ inline fun contractAddressExt(chain: Int, code: Cell, data: Cell): Address { return newAddress(chain, hash); } +/// Global function. Available since Tact 1.6.0. +/// +/// Creates and returns a basechain address derived from a contract's `StateInit` (code and data). +/// +/// ```tact +/// fun example() { +/// let code: Cell = loadCell(); // load contract code +/// let data: Cell = loadCell(); // load contract data +/// let state: StateInit = StateInit { code, data }; +/// let addr: BasechainAddress = contractBasechainAddress(state); +/// } +/// ``` +/// +/// See: https://docs.tact-lang.org/ref/core-addresses#contractbasechainaddress +/// +inline fun contractBasechainAddress(s: StateInit): BasechainAddress { + let hash = contractHash(s.code, s.data); + return newBasechainAddress(hash); +} + /// Struct containing the initial state, i.e. initial code and initial data of the given contract upon its deployment. /// /// See: https://docs.tact-lang.org/book/expressions#initof /// -struct StateInit { - /// Initial code of the contract (compiled bitcode) - code: Cell; +// struct StateInit { +// /// Initial code of the contract (compiled bitcode) +// code: Cell; - /// Initial data of the contract (parameters of `init()` function or contract parameters) - data: Cell; -} +// /// Initial data of the contract (parameters of `init()` function or contract parameters) +// data: Cell; +// } /// Global function. Available since Tact 1.6.1. /// diff --git a/src/stdlib/stdlib/std/internal/math.tact b/src/stdlib/stdlib/std/internal/math.tact index c124885b5d..4ecdc1356f 100644 --- a/src/stdlib/stdlib/std/internal/math.tact +++ b/src/stdlib/stdlib/std/internal/math.tact @@ -1,3 +1,5 @@ +import "./debug"; + // Prepare random /// Global function. diff --git a/src/stdlib/stdlib/std/internal/send.tact b/src/stdlib/stdlib/std/internal/send.tact index c7b783bebe..a5090d8940 100644 --- a/src/stdlib/stdlib/std/internal/send.tact +++ b/src/stdlib/stdlib/std/internal/send.tact @@ -1,3 +1,5 @@ +import "./cells"; + /// Ordinary message (default). /// /// This constant is available since Tact 1.6.0. diff --git a/src/stdlib/stdlib/std/internal/text.tact b/src/stdlib/stdlib/std/internal/text.tact index 1f1238b82d..3ff06bb589 100644 --- a/src/stdlib/stdlib/std/internal/text.tact +++ b/src/stdlib/stdlib/std/internal/text.tact @@ -1,3 +1,7 @@ +import "./cells"; +import "./exit-codes"; +import "./debug"; + // // String builder //