Skip to content

Commit

Permalink
complete bool constant resolving and add test cases
Browse files Browse the repository at this point in the history
  • Loading branch information
Gusarich committed Mar 27, 2024
1 parent b2eee01 commit 8518723
Show file tree
Hide file tree
Showing 2 changed files with 145 additions and 39 deletions.
80 changes: 80 additions & 0 deletions src/test/features/constants.tact
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,22 @@ contract ConstantTester {
const something6: Int = 10 * 1;
const something7: Int = 10 >> 1;
const something8: Int = (2 + 4) & 4;
const something9: Bool = true && false;
const something10: Bool = true || false;
const something11: Bool = !true;
const something12: Bool = true == false;
const something13: Bool = true != false;
const something14: Bool = !(true == false);
const something15: Bool = 5 > 5;
const something16: Bool = 5 >= 5;
const something17: Bool = "Hello" == "Hello";
const something18: Bool = "Hello" != "Hello";
const something19: Bool = "Hello".asCell() == "Hello".asCell();
const something20: Bool = "Hello".asCell() != "Hello".asCell();
const something21: Bool = newAddress(0, 0x606813c5f6a76175eae668630c6d8ffe229543610e3d204db245dd51f9ba0503) == newAddress(0, 0x606813c5f6a76175eae668630c6d8ffe229543610e3d204db245dd51f9ba0503);
const something22: Bool = newAddress(0, 0x606813c5f6a76175eae668630c6d8ffe229543610e3d204db245dd51f9ba0503) != newAddress(0, 0x606813c5f6a76175eae668630c6d8ffe229543610e3d204db245dd51f9ba0503);
const something23: Bool = "Hello".asCell() == "Hello".asCell();
const something24: Bool = "Hello".asCell() != "Hello".asCell();

init() {

Expand Down Expand Up @@ -49,4 +65,68 @@ contract ConstantTester {
get fun globalConst(): Int {
return someGlobalConst;
}

get fun something9(): Bool {
return self.something9;
}

get fun something10(): Bool {
return self.something10;
}

get fun something11(): Bool {
return self.something11;
}

get fun something12(): Bool {
return self.something12;
}

get fun something13(): Bool {
return self.something13;
}

get fun something14(): Bool {
return self.something14;
}

get fun something15(): Bool {
return self.something15;
}

get fun something16(): Bool {
return self.something16;
}

get fun something17(): Bool {
return self.something17;
}

get fun something18(): Bool {
return self.something18;
}

get fun something19(): Bool {
return self.something19;
}

get fun something20(): Bool {
return self.something20;
}

get fun something21(): Bool {
return self.something21;
}

get fun something22(): Bool {
return self.something22;
}

get fun something23(): Bool {
return self.something23;
}

get fun something24(): Bool {
return self.something24;
}
}
104 changes: 65 additions & 39 deletions src/types/resolveConstantValue.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,23 @@
import { Address, Cell, Slice, toNano } from "@ton/core";
import { enabledMasterchain } from "../config/features";
import { CompilerContext } from "../context";
import { ASTExpression, throwError } from "../grammar/ast";
import { ASTExpression, ASTOpCallStatic, throwError } from "../grammar/ast";
import { printTypeRef, TypeRef } from "./types";
import { sha256_sync } from "@ton/crypto";
import { getExpType } from "./resolveExpression";

function isSlice(ast: ASTExpression): boolean {
return (ast.kind === 'op_static_call') && (ast.name === 'slice') && (ast.args.length === 1);
}

function isCell(ast: ASTExpression): boolean {
return (ast.kind === 'op_static_call') && (ast.name === 'cell') && (ast.args.length === 1);
}

function isAddress(ast: ASTExpression): boolean {
return (ast.kind === 'op_static_call') && (ast.name === 'address') && (ast.args.length === 1);
}

function reduceInt(ast: ASTExpression): bigint {
if (ast.kind === 'number') {
return ast.value;
Expand Down Expand Up @@ -103,7 +115,26 @@ function reduceBool(ast: ASTExpression, ctx: CompilerContext): boolean {
} else if (leftType.kind === 'null' && rightType.kind === 'null') {
return true;
}
} else if (ast.op === '!=') {
if (leftType.kind === 'ref' && rightType.kind === 'ref') {
if (leftType.name === 'Address' && rightType.name === 'Address') {
return !reduceAddress(ast.left, ctx).equals(reduceAddress(ast.right, ctx));
} else if (leftType.name === 'Cell' && rightType.name === 'Cell') {
return !reduceCell(ast.left).equals(reduceCell(ast.right));
} else if (leftType.name === 'String' && rightType.name === 'String') {
return reduceString(ast.left) !== reduceString(ast.right);
} else if (leftType.name === 'Int' && rightType.name === 'Int') {
return reduceInt(ast.left) !== reduceInt(ast.right);
} else if (leftType.name === 'Bool' && rightType.name === 'Bool') {
return reduceBool(ast.left, ctx) !== reduceBool(ast.right, ctx);
} else if (leftType.name === 'Slice' && rightType.name === 'Slice') {
return !reduceSlice(ast.left).asCell().equals(reduceSlice(ast.right).asCell());
}
} else if (leftType.kind === 'null' && rightType.kind === 'null') {
return false;
}
}
return true;
}
}

Expand All @@ -118,58 +149,53 @@ function reduceString(ast: ASTExpression): string {
}

function reduceAddress(ast: ASTExpression, ctx: CompilerContext): Address {
if (ast.kind === 'op_static_call') {
if (ast.name === 'address') {
if (ast.args.length === 1) {
const str = reduceString(ast.args[0]);
const address = Address.parse(str);
if (address.workChain !== 0 && address.workChain !== -1) {
throwError(`Address ${str} invalid address`, ast.ref);
}
if (!enabledMasterchain(ctx)) {
if (address.workChain !== 0) {
throwError(`Address ${str} from masterchain are not enabled for this contract`, ast.ref);
}
}
return address;
if (isAddress(ast)) {
ast = ast as ASTOpCallStatic;
const str = reduceString(ast.args[0]);
const address = Address.parse(str);
if (address.workChain !== 0 && address.workChain !== -1) {
throwError(`Address ${str} invalid address`, ast.ref);
}
if (!enabledMasterchain(ctx)) {
if (address.workChain !== 0) {
throwError(
`Address ${str} from masterchain are not enabled for this contract`,
ast.ref
);
}
}
return address;
}
throwError('Cannot reduce expression to a constant Address', ast.ref);
}

function reduceCell(ast: ASTExpression): Cell {
if (ast.kind === 'op_static_call') {
if (ast.name === 'cell') {
if (ast.args.length === 1) {
const str = reduceString(ast.args[0]);
let c: Cell;
try {
c = Cell.fromBase64(str);
} catch (e) {
throwError(`Invalid cell ${str}`, ast.ref);
}
return c;
}
if (isCell(ast)) {
ast = ast as ASTOpCallStatic;
const str = reduceString(ast.args[0]);
let c: Cell;
try {
c = Cell.fromBase64(str);
} catch (e) {
throwError(`Invalid cell ${str}`, ast.ref);
}
return c;
}

throwError('Cannot reduce expression to a constant Cell', ast.ref);
}

function reduceSlice(ast: ASTExpression): Slice {
if (ast.kind === 'op_static_call') {
if (ast.name === 'slice') {
if (ast.args.length === 1) {
const str = reduceString(ast.args[0]);
let c: Cell;
try {
c = Cell.fromBase64(str);
} catch (e) {
throwError(`Invalid cell ${str}`, ast.ref);
}
return c.asSlice();
}
if (isSlice(ast)) {
ast = ast as ASTOpCallStatic;
const str = reduceString(ast.args[0]);
let c: Cell;
try {
c = Cell.fromBase64(str);
} catch (e) {
throwError(`Invalid cell ${str}`, ast.ref);
}
return c.asSlice();
}
throwError('Cannot reduce expression to a constant Slice', ast.ref);
}
Expand Down

0 comments on commit 8518723

Please sign in to comment.