Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Testandr #25

Merged
merged 14 commits into from
Dec 14, 2023
1,955 changes: 1,293 additions & 662 deletions generated_block.ts

Large diffs are not rendered by default.

230 changes: 137 additions & 93 deletions generated_test.ts

Large diffs are not rendered by default.

33 changes: 19 additions & 14 deletions src/codegen/combinator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export function handleCombinator(expr: ParserExpression, fieldName: string, isFi

insideStoreParameters = [tMemberExpression(tIdentifier(variableCombinatorName), tIdentifier(goodVariableName(fieldName)))];
let insideStoreParameters2: Expression[] = [tIdentifier('arg')]

if (expr instanceof BuiltinZeroArgs) {
if (expr.name == '#') {
exprForParam = {argLoadExpr: tNumericLiteral(32), argStoreExpr: tNumericLiteral(32), paramType: 'number', fieldLoadStoreSuffix: 'Uint'}
Expand All @@ -49,7 +49,12 @@ export function handleCombinator(expr: ParserExpression, fieldName: string, isFi
} else if (expr instanceof BuiltinOneArgExpr) {
if (expr.name.toString() == '##' || expr.name.toString() == '(##)') {
if (expr.arg instanceof NumberExpr) {
exprForParam = {argLoadExpr: tNumericLiteral(expr.arg.num), argStoreExpr: tNumericLiteral(expr.arg.num), paramType: 'number', fieldLoadStoreSuffix: 'Uint'}
exprForParam = {
argLoadExpr: tNumericLiteral(expr.arg.num),
argStoreExpr: tNumericLiteral(expr.arg.num),
paramType: expr.arg.num <= 63 ? 'number' : 'bigint',
fieldLoadStoreSuffix: 'Uint'
}
}
if (expr.arg instanceof NameExpr) {
let parameter = constructor.parametersMap.get(expr.arg.name)
Expand All @@ -59,7 +64,7 @@ export function handleCombinator(expr: ParserExpression, fieldName: string, isFi
exprForParam = {
argLoadExpr: getParamVarExpr(parameter, constructor),
argStoreExpr: tMemberExpression(tIdentifier(variableCombinatorName), tIdentifier(goodVariableName(expr.arg.name))),
paramType: 'number', fieldLoadStoreSuffix: 'Uint'
paramType: 'bigint', fieldLoadStoreSuffix: 'Uint'
}
} // TODO: handle other cases
} else if (expr.name == '#<') {
Expand All @@ -85,14 +90,16 @@ export function handleCombinator(expr: ParserExpression, fieldName: string, isFi
exprForParam = {
argLoadExpr: convertToAST(myMathExpr, constructor),
argStoreExpr: convertToAST(myMathExpr, constructor, false, tIdentifier(variableSubStructName)),
paramType: 'number', fieldLoadStoreSuffix: 'Int'
paramType: (expr.args[0] instanceof NumberExpr && expr.args[0].num <= 63) ? 'number' : 'bigint',
fieldLoadStoreSuffix: 'Int'
}
} else if (expr.name == 'uint' && expr.args.length == 1 && (expr.args[0] instanceof MathExpr || expr.args[0] instanceof NumberExpr || expr.args[0] instanceof NameExpr)) {
let myMathExpr = convertToMathExpr(expr.args[0])
exprForParam = {
argLoadExpr: convertToAST(myMathExpr, constructor),
argStoreExpr: convertToAST(myMathExpr, constructor, false, tIdentifier(variableSubStructName)),
paramType: 'number', fieldLoadStoreSuffix: 'Uint'
paramType: (expr.args[0] instanceof NumberExpr && expr.args[0].num <= 63) ? 'number' : 'bigint',
fieldLoadStoreSuffix: 'Uint'
}
} else if (expr.name == 'bits' && expr.args.length == 1 && (expr.args[0] instanceof MathExpr || expr.args[0] instanceof NumberExpr || expr.args[0] instanceof NameExpr)) {
let myMathExpr = convertToMathExpr(expr.args[0])
Expand Down Expand Up @@ -255,23 +262,22 @@ export function handleCombinator(expr: ParserExpression, fieldName: string, isFi
throw new Error('Expression not supported: ' + expr);
}
if (exprForParam) {
result.loadExpr = tFunctionCall(tMemberExpression(tIdentifier(theSlice), tIdentifier('load' + exprForParam.fieldLoadStoreSuffix)), [exprForParam.argLoadExpr])
let fieldLoadSuffix = exprForParam.fieldLoadStoreSuffix;
if (exprForParam.paramType == 'bigint') {
fieldLoadSuffix += 'Big'
}
if (exprForParam.paramType != 'BitString' && exprForParam.paramType != 'Slice') {
insideStoreParameters.push(exprForParam.argStoreExpr);
insideStoreParameters2.push(exprForParam.argStoreExpr);
}
result.storeExpr = tExpressionStatement(tFunctionCall(tMemberExpression(tIdentifier(theCell), tIdentifier('store' + exprForParam.fieldLoadStoreSuffix)), insideStoreParameters));
storeExpr2 = tExpressionStatement(tFunctionCall(tMemberExpression(tIdentifier(theCell), tIdentifier('store' + exprForParam.fieldLoadStoreSuffix)), insideStoreParameters2));
}
if (exprForParam != undefined) {
result.loadExpr = tFunctionCall(tMemberExpression(tIdentifier(currentSlice), tIdentifier('load' + exprForParam.fieldLoadStoreSuffix)), [exprForParam.argLoadExpr]);
result.loadExpr = tFunctionCall(tMemberExpression(tIdentifier(currentSlice), tIdentifier('load' + fieldLoadSuffix)), [exprForParam.argLoadExpr]);
if (exprForParam.paramType == 'Slice') {
result.loadExpr = tIdentifier(currentSlice)
result.loadFunctionExpr = tArrowFunctionExpression([tTypedIdentifier(tIdentifier('slice'), tIdentifier('Slice'))], [tReturnStatement(tIdentifier('slice'))])
}
result.typeParamExpr = tIdentifier(exprForParam.paramType);
result.storeExpr = tExpressionStatement(tFunctionCall(tMemberExpression(tIdentifier(currentCell), tIdentifier('store' + exprForParam.fieldLoadStoreSuffix)), insideStoreParameters));
storeExpr2 = tExpressionStatement(tFunctionCall(tMemberExpression(tIdentifier(currentCell), tIdentifier('store' + exprForParam.fieldLoadStoreSuffix)), insideStoreParameters2));
result.storeExpr = tExpressionStatement(tFunctionCall(tMemberExpression(tIdentifier(theCell), tIdentifier('store' + exprForParam.fieldLoadStoreSuffix)), insideStoreParameters));
storeExpr2 = tExpressionStatement(tFunctionCall(tMemberExpression(tIdentifier(theCell), tIdentifier('store' + exprForParam.fieldLoadStoreSuffix)), insideStoreParameters2));
}

if (result.loadExpr && !result.loadFunctionExpr) {
Expand All @@ -297,6 +303,5 @@ export function handleCombinator(expr: ParserExpression, fieldName: string, isFi
}

result.storeExpr2 = storeExpr2

return result;
}
31 changes: 24 additions & 7 deletions src/codegen/field.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,31 @@ export function handleField(field: FieldDefinition, slicePrefix: Array<number>,
}

if (field.expr instanceof CellRefExpr) {
slicePrefix[slicePrefix.length - 1]++;
slicePrefix.push(0)

constructorLoadStatements.push(sliceLoad(slicePrefix, currentSlice))
subStructStoreStatements.push(tExpressionStatement(tDeclareVariable(tIdentifier(getCurrentSlice(slicePrefix, 'cell')), tFunctionCall(tIdentifier('beginCell'), []))))
handleField(new FieldNamedDef(fieldName, field.expr.expr), slicePrefix, tlbCode, constructor, constructorLoadStatements, subStructStoreStatements, subStructProperties, subStructLoadProperties, variableCombinatorName, variableSubStructName, jsCodeFunctionsDeclarations, fieldIndex)
subStructStoreStatements.push(tExpressionStatement(tFunctionCall(tMemberExpression(tIdentifier(currentCell), tIdentifier('storeRef')), [tIdentifier(getCurrentSlice(slicePrefix, 'cell'))])))
slicePrefix.pop();
if (field.expr.expr instanceof CombinatorExpr && (field.expr.expr.name == 'MERKLE_UPDATE' || field.expr.expr.name == 'MERKLE_ROOT')) {
slicePrefix[slicePrefix.length - 1]++;
slicePrefix.push(0);
constructorLoadStatements.push(
tExpressionStatement(tDeclareVariable(tIdentifier(getCurrentSlice(slicePrefix, 'cell')),

tFunctionCall(tMemberExpression(
tIdentifier(currentSlice), tIdentifier('loadRef')
), []),)))
addLoadProperty(goodVariableName(fieldName), tIdentifier(getCurrentSlice(slicePrefix, 'cell')), undefined, constructorLoadStatements, subStructLoadProperties)
subStructProperties.push(tTypedIdentifier(tIdentifier(goodVariableName(fieldName)), tIdentifier('Cell')));
subStructStoreStatements.push(tExpressionStatement(tFunctionCall(tMemberExpression(tIdentifier(currentCell), tIdentifier('storeRef')), [tMemberExpression(tIdentifier(variableCombinatorName), tIdentifier(goodVariableName(fieldName)))])))

// subStructStoreStatements
slicePrefix.pop();
} else {
slicePrefix[slicePrefix.length - 1]++;
slicePrefix.push(0)
constructorLoadStatements.push(sliceLoad(slicePrefix, currentSlice))
subStructStoreStatements.push(tExpressionStatement(tDeclareVariable(tIdentifier(getCurrentSlice(slicePrefix, 'cell')), tFunctionCall(tIdentifier('beginCell'), []))))
handleField(new FieldNamedDef(fieldName, field.expr.expr), slicePrefix, tlbCode, constructor, constructorLoadStatements, subStructStoreStatements, subStructProperties, subStructLoadProperties, variableCombinatorName, variableSubStructName, jsCodeFunctionsDeclarations, fieldIndex)
subStructStoreStatements.push(tExpressionStatement(tFunctionCall(tMemberExpression(tIdentifier(currentCell), tIdentifier('storeRef')), [tIdentifier(getCurrentSlice(slicePrefix, 'cell'))])))
slicePrefix.pop();
}
}

if (field.expr instanceof CombinatorExpr || field.expr instanceof NameExpr || field.expr instanceof BuiltinZeroArgs || field.expr instanceof BuiltinOneArgExpr || field.expr instanceof MathExpr || field.expr instanceof CondExpr) {
Expand Down
20 changes: 16 additions & 4 deletions src/codegen/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,20 @@ export function addLoadProperty(name: string, loadExpr: Expression, typeExpr: Ty
}

export function calculateOpcode(declaration: Declaration, input: string[]): string {
let constructorString = getStringDeclaration(declaration, input)
const a = BigInt(crc32.str(constructorString));
const b = BigInt(0x80000000);
return ((a | b) < 0 ? (a | b) + BigInt('4294967296') : a | b).toString(16);
let scheme = getStringDeclaration(declaration, input)
let constructor = scheme.substring(0, scheme.indexOf(' '));
const rest = scheme.substring(scheme.indexOf(' '));
if (constructor.includes('#')) {
constructor = constructor.substring(0, constructor.indexOf('#'));
}
scheme =
constructor +
' ' +
rest
.replace(/\(/g, '')
.replace(/\)/g, '')
.replace(/\s+/g, ' ')
.replace(/;/g, '')
.trim()
return (BigInt(crc32.str(scheme)) & BigInt(0x7fffffff)).toString(16);
}
1 change: 1 addition & 0 deletions src/codegen/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export function generate(tree: Program, input: string) {
jsCodeDeclarations.push(tImportDeclaration(tIdentifier('Slice'), tStringLiteral('ton'))) // importDeclaration([importSpecifier(identifier('Slice'), identifier('Slice'))], stringLiteral('../boc/Slice')))
jsCodeDeclarations.push(tImportDeclaration(tIdentifier('beginCell'), tStringLiteral('ton')))
jsCodeDeclarations.push(tImportDeclaration(tIdentifier('BitString'), tStringLiteral('ton')))
jsCodeDeclarations.push(tImportDeclaration(tIdentifier('Cell'), tStringLiteral('ton')))

let jsCodeConstructorDeclarations: GenDeclaration[] = []
let jsCodeFunctionsDeclarations: FunctionDeclaration[] = []
Expand Down
12 changes: 6 additions & 6 deletions src/codegen/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -364,19 +364,19 @@ export function calculateVariables(constructor: TLBConstructor) {

export function getConstructorTag(declaration: Declaration, input: string[]): TLBConstructorTag {
let tag = declaration.constructorDef.tag;
if (tag == null && declaration.constructorDef.name == '_' || tag && tag.length > 1 && tag[1] == '_') {
return {
bitLen: 0,
binary: ''
};
}
if (tag == null) {
let opCode = calculateOpcode(declaration, input)
return {
bitLen: 32,
binary: '0x' + opCode
}
}
if (tag == undefined || tag && tag.length > 1 && tag[1] == '_') {
return {
bitLen: 0,
binary: ''
};
}
if (tag[0] == '$') {
return {
bitLen: tag?.length - 1,
Expand Down
Loading
Loading