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

Support for trailing comma #179

Merged
merged 25 commits into from
Apr 2, 2024
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
1c3d633
Restore the closed commit
vitorpy Mar 20, 2024
4797e78
Add support for trailing commas in argument lists
vitorpy Mar 20, 2024
f566f7e
Revert changes to serialization-2.tact
vitorpy Mar 20, 2024
4547492
Expand coverage to Function, convert to using ? syntax instead of dup…
vitorpy Mar 20, 2024
99e689d
Adding test case for empty argument list
vitorpy Mar 20, 2024
8b61dad
Add changes to CHANGELOG
vitorpy Mar 20, 2024
b439d71
Better wording on CHANGELOG.md
vitorpy Mar 20, 2024
9943023
Add additional test case for more than two arguments
vitorpy Mar 20, 2024
42b1d55
Fixing test case
vitorpy Mar 21, 2024
ae10d4e
Expand coverage to include ExpressionCall, ExpressionInitOf and Expre…
vitorpy Mar 21, 2024
9703fec
Expand test cases
vitorpy Mar 21, 2024
baf26c5
Update src/grammar/test/case-17.tact
vitorpy Mar 22, 2024
9bde284
Fix tests
vitorpy Mar 22, 2024
d9d392f
Expand tests and checks for dangling commas
vitorpy Mar 24, 2024
24998a6
Fix and expand tests
vitorpy Mar 25, 2024
3c85b22
Merge branch 'main' into trailing-comma
vitorpy Mar 25, 2024
58b7d22
Fix parsing and tests for abstract functions.
vitorpy Mar 25, 2024
f161773
Fix support for native functions
vitorpy Mar 25, 2024
11b736e
:Merge branch 'main' into trailing-comma
vitorpy Mar 31, 2024
572dedd
Split test cases into different files
vitorpy Mar 31, 2024
4f4de39
revert accidental deletion in grammar.ts
anton-trunov Apr 2, 2024
e362df6
Merge branch 'main' into trailing-comma
anton-trunov Apr 2, 2024
6984209
Update src/grammar/test-failed/case-26.tact
anton-trunov Apr 2, 2024
9f8f808
Update src/grammar/test-failed/case-25.tact
anton-trunov Apr 2, 2024
46e45f7
update snapshot
anton-trunov Apr 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed
- Update the `dump` function to handle addresses: PR [#175](https://github.com/tact-lang/tact/pull/175)
- Support trailing commas for struct fields and function arguments: PR [#179](https://github.com/tact-lang/tact/pull/179)

### Fixed

Expand Down
20 changes: 10 additions & 10 deletions src/grammar/grammar.ohm
vitorpy marked this conversation as resolved.
Show resolved Hide resolved
vitorpy marked this conversation as resolved.
Show resolved Hide resolved
vitorpy marked this conversation as resolved.
Show resolved Hide resolved
vitorpy marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ Tact {

// Static function
StaticFunction = Function
NativeFunction = nameAttribute "(" funcId ")" FunctionAttribute* native id "(" ListOf<FunctionArg,","> ")" ";" --withVoid
| nameAttribute "(" funcId ")" FunctionAttribute* native id "(" ListOf<FunctionArg,","> ")" ":" Type ";" --withType
NativeFunction = nameAttribute "(" funcId ")" FunctionAttribute* native id "(" ListOf<FunctionArg,","> ","? ")" ";" --withVoid
| nameAttribute "(" funcId ")" FunctionAttribute* native id "(" ListOf<FunctionArg,","> ","? ")" ":" Type ";" --withType

// Field declarations
Type = typeLiteral "?" --optional
Expand Down Expand Up @@ -72,10 +72,10 @@ Tact {
| override --override
| inline --inline
| abstract --abstract
Function = FunctionAttribute* fun id "(" ListOf<FunctionArg,","> ")" "{" Statement* "}" --withVoid
| FunctionAttribute* fun id "(" ListOf<FunctionArg,","> ")" ":" Type "{" Statement* "}" --withType
| FunctionAttribute* fun id "(" ListOf<FunctionArg,","> ")" ";" --abstractVoid
| FunctionAttribute* fun id "(" ListOf<FunctionArg,","> ")" ":" Type ";" --abstractType
Function = FunctionAttribute* fun id "(" ListOf<FunctionArg,","> ","? ")" "{" Statement* "}" --withVoid
| FunctionAttribute* fun id "(" ListOf<FunctionArg,","> ","? ")" ":" Type "{" Statement* "}" --withType
| FunctionAttribute* fun id "(" ListOf<FunctionArg,","> ","? ")" ";" --abstractVoid
| FunctionAttribute* fun id "(" ListOf<FunctionArg,","> ","? ")" ":" Type ";" --abstractType
FunctionArg = id ":" Type

ReceiveFunction = "receive" "(" FunctionArg ")" "{" Statement* "}" --simple
Expand Down Expand Up @@ -173,11 +173,11 @@ Tact {
| ExpressionString
ExpressionString = stringLiteral
ExpressionField = ExpressionValue "." id ~"("
ExpressionCall = ExpressionValue "." id "(" ListOf<Expression, ","> ")"
ExpressionNew = id "{" ListOf<NewParameter, ","> "}"
ExpressionCall = ExpressionValue "." id "(" ListOf<Expression, ","> ","? ")"
ExpressionNew = id "{" ListOf<NewParameter, ","> ","? "}"
NewParameter = id ":" Expression
ExpressionStaticCall = id "(" ListOf<Expression, ","> ")"
ExpressionInitOf = initOf id "(" ListOf<Expression, ","> ")"
ExpressionStaticCall = id "(" ListOf<Expression, ","> ","? ")"
ExpressionInitOf = initOf id "(" ListOf<Expression, ","> ","? ")"

// Type Literal
typeLiteral = letterAsciiUC typeLiteralPart*
Expand Down
20 changes: 10 additions & 10 deletions src/grammar/grammar.ohm-bundle.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ export interface TactActionDict<T> extends ActionDict<T> {
ProgramImport?: (this: NonterminalNode, arg0: NonterminalNode, arg1: NonterminalNode, arg2: TerminalNode) => T;
Primitive?: (this: NonterminalNode, arg0: TerminalNode, arg1: NonterminalNode, arg2: TerminalNode) => T;
StaticFunction?: (this: NonterminalNode, arg0: NonterminalNode) => T;
NativeFunction_withVoid?: (this: NonterminalNode, arg0: NonterminalNode, arg1: TerminalNode, arg2: NonterminalNode, arg3: TerminalNode, arg4: IterationNode, arg5: NonterminalNode, arg6: NonterminalNode, arg7: TerminalNode, arg8: NonterminalNode, arg9: TerminalNode, arg10: TerminalNode) => T;
NativeFunction_withType?: (this: NonterminalNode, arg0: NonterminalNode, arg1: TerminalNode, arg2: NonterminalNode, arg3: TerminalNode, arg4: IterationNode, arg5: NonterminalNode, arg6: NonterminalNode, arg7: TerminalNode, arg8: NonterminalNode, arg9: TerminalNode, arg10: TerminalNode, arg11: NonterminalNode, arg12: TerminalNode) => T;
NativeFunction_withVoid?: (this: NonterminalNode, arg0: NonterminalNode, arg1: TerminalNode, arg2: NonterminalNode, arg3: TerminalNode, arg4: IterationNode, arg5: NonterminalNode, arg6: NonterminalNode, arg7: TerminalNode, arg8: NonterminalNode, arg9: IterationNode, arg10: TerminalNode, arg11: TerminalNode) => T;
NativeFunction_withType?: (this: NonterminalNode, arg0: NonterminalNode, arg1: TerminalNode, arg2: NonterminalNode, arg3: TerminalNode, arg4: IterationNode, arg5: NonterminalNode, arg6: NonterminalNode, arg7: TerminalNode, arg8: NonterminalNode, arg9: IterationNode, arg10: TerminalNode, arg11: TerminalNode, arg12: NonterminalNode, arg13: TerminalNode) => T;
NativeFunction?: (this: NonterminalNode, arg0: NonterminalNode) => T;
Type_optional?: (this: NonterminalNode, arg0: NonterminalNode, arg1: TerminalNode) => T;
Type_required?: (this: NonterminalNode, arg0: NonterminalNode) => T;
Expand Down Expand Up @@ -61,10 +61,10 @@ export interface TactActionDict<T> extends ActionDict<T> {
FunctionAttribute_inline?: (this: NonterminalNode, arg0: NonterminalNode) => T;
FunctionAttribute_abstract?: (this: NonterminalNode, arg0: NonterminalNode) => T;
FunctionAttribute?: (this: NonterminalNode, arg0: NonterminalNode) => T;
Function_withVoid?: (this: NonterminalNode, arg0: IterationNode, arg1: NonterminalNode, arg2: NonterminalNode, arg3: TerminalNode, arg4: NonterminalNode, arg5: TerminalNode, arg6: TerminalNode, arg7: IterationNode, arg8: TerminalNode) => T;
Function_withType?: (this: NonterminalNode, arg0: IterationNode, arg1: NonterminalNode, arg2: NonterminalNode, arg3: TerminalNode, arg4: NonterminalNode, arg5: TerminalNode, arg6: TerminalNode, arg7: NonterminalNode, arg8: TerminalNode, arg9: IterationNode, arg10: TerminalNode) => T;
Function_abstractVoid?: (this: NonterminalNode, arg0: IterationNode, arg1: NonterminalNode, arg2: NonterminalNode, arg3: TerminalNode, arg4: NonterminalNode, arg5: TerminalNode, arg6: TerminalNode) => T;
Function_abstractType?: (this: NonterminalNode, arg0: IterationNode, arg1: NonterminalNode, arg2: NonterminalNode, arg3: TerminalNode, arg4: NonterminalNode, arg5: TerminalNode, arg6: TerminalNode, arg7: NonterminalNode, arg8: TerminalNode) => T;
Function_withVoid?: (this: NonterminalNode, arg0: IterationNode, arg1: NonterminalNode, arg2: NonterminalNode, arg3: TerminalNode, arg4: NonterminalNode, arg5: IterationNode, arg6: TerminalNode, arg7: TerminalNode, arg8: IterationNode, arg9: TerminalNode) => T;
Function_withType?: (this: NonterminalNode, arg0: IterationNode, arg1: NonterminalNode, arg2: NonterminalNode, arg3: TerminalNode, arg4: NonterminalNode, arg5: IterationNode, arg6: TerminalNode, arg7: TerminalNode, arg8: NonterminalNode, arg9: TerminalNode, arg10: IterationNode, arg11: TerminalNode) => T;
Function_abstractVoid?: (this: NonterminalNode, arg0: IterationNode, arg1: NonterminalNode, arg2: NonterminalNode, arg3: TerminalNode, arg4: NonterminalNode, arg5: IterationNode, arg6: TerminalNode, arg7: TerminalNode) => T;
Function_abstractType?: (this: NonterminalNode, arg0: IterationNode, arg1: NonterminalNode, arg2: NonterminalNode, arg3: TerminalNode, arg4: NonterminalNode, arg5: IterationNode, arg6: TerminalNode, arg7: TerminalNode, arg8: NonterminalNode, arg9: TerminalNode) => T;
Function?: (this: NonterminalNode, arg0: NonterminalNode) => T;
FunctionArg?: (this: NonterminalNode, arg0: NonterminalNode, arg1: TerminalNode, arg2: NonterminalNode) => T;
ReceiveFunction_simple?: (this: NonterminalNode, arg0: TerminalNode, arg1: TerminalNode, arg2: NonterminalNode, arg3: TerminalNode, arg4: TerminalNode, arg5: IterationNode, arg6: TerminalNode) => T;
Expand Down Expand Up @@ -135,11 +135,11 @@ export interface TactActionDict<T> extends ActionDict<T> {
ExpressionValue?: (this: NonterminalNode, arg0: NonterminalNode) => T;
ExpressionString?: (this: NonterminalNode, arg0: NonterminalNode) => T;
ExpressionField?: (this: NonterminalNode, arg0: NonterminalNode, arg1: TerminalNode, arg2: NonterminalNode) => T;
ExpressionCall?: (this: NonterminalNode, arg0: NonterminalNode, arg1: TerminalNode, arg2: NonterminalNode, arg3: TerminalNode, arg4: NonterminalNode, arg5: TerminalNode) => T;
ExpressionNew?: (this: NonterminalNode, arg0: NonterminalNode, arg1: TerminalNode, arg2: NonterminalNode, arg3: TerminalNode) => T;
ExpressionCall?: (this: NonterminalNode, arg0: NonterminalNode, arg1: TerminalNode, arg2: NonterminalNode, arg3: TerminalNode, arg4: NonterminalNode, arg5: IterationNode, arg6: TerminalNode) => T;
ExpressionNew?: (this: NonterminalNode, arg0: NonterminalNode, arg1: TerminalNode, arg2: NonterminalNode, arg3: IterationNode, arg4: TerminalNode) => T;
NewParameter?: (this: NonterminalNode, arg0: NonterminalNode, arg1: TerminalNode, arg2: NonterminalNode) => T;
ExpressionStaticCall?: (this: NonterminalNode, arg0: NonterminalNode, arg1: TerminalNode, arg2: NonterminalNode, arg3: TerminalNode) => T;
ExpressionInitOf?: (this: NonterminalNode, arg0: NonterminalNode, arg1: NonterminalNode, arg2: TerminalNode, arg3: NonterminalNode, arg4: TerminalNode) => T;
ExpressionStaticCall?: (this: NonterminalNode, arg0: NonterminalNode, arg1: TerminalNode, arg2: NonterminalNode, arg3: IterationNode, arg4: TerminalNode) => T;
ExpressionInitOf?: (this: NonterminalNode, arg0: NonterminalNode, arg1: NonterminalNode, arg2: TerminalNode, arg3: NonterminalNode, arg4: IterationNode, arg5: TerminalNode) => T;
typeLiteral?: (this: NonterminalNode, arg0: NonterminalNode, arg1: IterationNode) => T;
typeLiteralPart?: (this: NonterminalNode, arg0: NonterminalNode | TerminalNode) => T;
integerLiteral?: (this: NonterminalNode, arg0: NonterminalNode) => T;
Expand Down
2 changes: 1 addition & 1 deletion src/grammar/grammar.ohm-bundle.js

Large diffs are not rendered by default.

30 changes: 15 additions & 15 deletions src/grammar/grammar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ semantics.addOperation<ASTNode>('resolve_declaration', {
ref: createRef(this)
})
},
Function_withType(arg0, _arg1, arg2, _arg3, arg4, _arg5, _arg6, arg7, _arg8, arg9, _) {
Function_withType(arg0, _arg1, arg2, _arg3, arg4, _arg5, _arg6, _arg7, arg8, _arg9, arg10, _arg11) {
const attributes = arg0.children.map((v) => v.resolve_attributes()) as ASTFunctionAttribute[];
checkVariableName(arg2.sourceString, createRef(arg2));
checkFunctionAttributes(false, attributes, createRef(this));
Expand All @@ -291,13 +291,13 @@ semantics.addOperation<ASTNode>('resolve_declaration', {
origin: ctx!.origin,
attributes,
name: arg2.sourceString,
return: arg7.resolve_expression(),
return: arg8.resolve_expression(),
args: arg4.asIteration().children.map((v) => v.resolve_declaration()),
statements: arg9.children.map((v) => v.resolve_statement()),
statements: arg10.children.map((v) => v.resolve_statement()),
ref: createRef(this)
})
},
Function_withVoid(arg0, _arg1, arg2, _arg3, arg4, _arg5, _arg6, arg7, _) {
Function_withVoid(arg0, _arg1, arg2, _arg3, arg4, _arg5, _arg6, _arg7, arg8, _arg9) {
const attributes = arg0.children.map((v) => v.resolve_attributes()) as ASTFunctionAttribute[];
checkVariableName(arg2.sourceString, createRef(arg2));
checkFunctionAttributes(false, attributes, createRef(this));
Expand All @@ -308,11 +308,11 @@ semantics.addOperation<ASTNode>('resolve_declaration', {
name: arg2.sourceString,
return: null,
args: arg4.asIteration().children.map((v) => v.resolve_declaration()),
statements: arg7.children.map((v) => v.resolve_statement()),
statements: arg8.children.map((v) => v.resolve_statement()),
ref: createRef(this)
})
},
Function_abstractVoid(arg0, _arg1, arg2, _arg3, arg4, _arg5, _arg6) {
Function_abstractVoid(arg0, _arg1, arg2, _arg3, arg4, _arg5, _arg6, _arg7) {
const attributes = arg0.children.map((v) => v.resolve_attributes()) as ASTFunctionAttribute[];
checkVariableName(arg2.sourceString, createRef(arg2));
checkFunctionAttributes(true, attributes, createRef(this));
Expand All @@ -327,7 +327,7 @@ semantics.addOperation<ASTNode>('resolve_declaration', {
ref: createRef(this)
})
},
Function_abstractType(arg0, _arg1, arg2, _arg3, arg4, _arg5, _arg6, arg7, _arg8) {
Function_abstractType(arg0, _arg1, arg2, _arg3, arg4, _arg5, _arg6, _arg7, arg8, _arg9) {
const attributes = arg0.children.map((v) => v.resolve_attributes()) as ASTFunctionAttribute[];
checkVariableName(arg2.sourceString, createRef(arg2));
checkFunctionAttributes(true, attributes, createRef(this));
Expand All @@ -336,26 +336,26 @@ semantics.addOperation<ASTNode>('resolve_declaration', {
origin: ctx!.origin,
attributes,
name: arg2.sourceString,
return: arg7.resolve_expression(),
return: arg8.resolve_expression(),
args: arg4.asIteration().children.map((v) => v.resolve_declaration()),
statements: null,
ref: createRef(this)
})
},
NativeFunction_withType(_arg0, _arg1, arg2, _arg3, arg4, arg5, arg6, _arg7, arg8, _arg9, _arg10, arg11, _arg12) {
NativeFunction_withType(_arg0, _arg1, arg2, _arg3, arg4, arg5, arg6, _arg7, arg8, _arg9, _arg10, _arg11, arg12, _arg13) {
checkVariableName(arg5.sourceString, createRef(arg5));
return createNode({
kind: 'def_native_function',
origin: ctx!.origin,
attributes: arg4.children.map((v) => v.resolve_attributes()),
name: arg6.sourceString,
nativeName: arg2.sourceString,
return: arg11.resolve_expression(),
return: arg12.resolve_expression(),
args: arg8.asIteration().children.map((v) => v.resolve_declaration()),
ref: createRef(this)
})
},
NativeFunction_withVoid(_arg0, _arg1, arg2, _arg3, arg4, arg5, arg6, _arg7, arg8, _arg9, _arg10) {
NativeFunction_withVoid(_arg0, _arg1, arg2, _arg3, arg4, arg5, arg6, _arg7, arg8, _arg9, _arg10, _arg11) {
checkVariableName(arg5.sourceString, createRef(arg5));
return createNode({
kind: 'def_native_function',
Expand Down Expand Up @@ -706,19 +706,19 @@ semantics.addOperation<ASTNode>('resolve_expression', {
ExpressionField(arg0, _arg1, arg2) {
return createNode({ kind: 'op_field', src: arg0.resolve_expression(), name: arg2.sourceString, ref: createRef(this) });
},
ExpressionCall(arg0, _arg1, arg2, _arg3, arg4, _arg5) {
ExpressionCall(arg0, _arg1, arg2, _arg3, arg4, _arg5, _arg6) {
return createNode({ kind: 'op_call', src: arg0.resolve_expression(), name: arg2.sourceString, args: arg4.asIteration().children.map((v) => v.resolve_expression()), ref: createRef(this) });
},
ExpressionStaticCall(arg0, _arg1, arg2, _arg3) {
ExpressionStaticCall(arg0, _arg1, arg2, _arg3, _arg4) {
return createNode({ kind: 'op_static_call', name: arg0.sourceString, args: arg2.asIteration().children.map((v) => v.resolve_expression()), ref: createRef(this) });
},
ExpressionNew(arg0, _arg1, arg2, _arg3) {
ExpressionNew(arg0, _arg1, arg2, _arg3, _arg4) {
return createNode({ kind: 'op_new', type: arg0.sourceString, args: arg2.asIteration().children.map((v) => v.resolve_expression()), ref: createRef(this) });
},
NewParameter(arg0, _arg1, arg2) {
return createNode({ kind: 'new_parameter', name: arg0.sourceString, exp: arg2.resolve_expression(), ref: createRef(this) });
},
ExpressionInitOf(_arg0, arg1, _arg2, arg3, _arg4) {
ExpressionInitOf(_arg0, arg1, _arg2, arg3, _arg4, _arg5) {
return createNode({ kind: 'init_of', name: arg1.sourceString, args: arg3.asIteration().children.map((v) => v.resolve_expression()), ref: createRef(this) });
},

Expand Down
1 change: 1 addition & 0 deletions src/grammar/test-failed/case-19.tact
vitorpy marked this conversation as resolved.
Show resolved Hide resolved
vitorpy marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fun function(,) {}
vitorpy marked this conversation as resolved.
Show resolved Hide resolved
vitorpy marked this conversation as resolved.
Show resolved Hide resolved
22 changes: 21 additions & 1 deletion src/grammar/test/case-17.tact
Original file line number Diff line number Diff line change
@@ -1,7 +1,27 @@
struct A {
x: Int;
y: Int;
}

const a: A = new { x: 1 };

fun getA(): A {
return A {
x: 1,
y: 2,
};
}

message B {
x: Int;
}
y: Int;
}

const b: B = new {
x: 2,
y: 3,
};

fun getB(): B {
vitorpy marked this conversation as resolved.
Show resolved Hide resolved
return B { x = 1, y = 5, };
}
46 changes: 45 additions & 1 deletion src/grammar/test/case-25.tact
vitorpy marked this conversation as resolved.
Show resolved Hide resolved
vitorpy marked this conversation as resolved.
Show resolved Hide resolved
vitorpy marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -1,3 +1,47 @@
fun function(a: Int, b: Int): Int {
return (a >> b) || (a << (32 - b));
}
}

fun anotherFunction(
a: Int,
b: Int,
): Int {
return (a >> b) || (a << (32 - b));
}

extends fun extension(self: Int, c: Int, d: Int) {
return self + c + d;
}

fun coverage(a: Int, b: Int) {
let k: Int = a.extension(
b,
4,
);

let c: Int = anotherFunction(
a,
b,
);
}

vitorpy marked this conversation as resolved.
Show resolved Hide resolved
fun oneMoreFunction(
a: Int,
b: Int,
): Int {
return anotherFunction(
a,
b,
);
}

contract TestContract {
init(arg1: Int, arg2: Int) {}
}

fun test() {
let k: StateInit = initOf TestContract(
2,
3,
);
}
Loading