From ac2e10b51c2a2dd6ffffab8f4f8e59a857c095e6 Mon Sep 17 00:00:00 2001 From: Novus Nota <68142933+novusnota@users.noreply.github.com> Date: Sun, 28 Jul 2024 03:21:24 +0200 Subject: [PATCH 01/12] fix: improve `funcId` recognition and squash misdetection bugs That took a looooooooot of RegEx iterations, including going into `grammar.ts` and trying to adjust things in the semantic analysis. Fortunately, that wasn't needed. --- .../__snapshots__/grammar.spec.ts.snap | 153 +++++++++++++++++- src/grammar/grammar.ohm | 6 +- .../test-failed/funcid-native-fun-hash.tact | 2 + ...uncid-native-fun-number-hexadecimal-2.tact | 2 + .../funcid-native-fun-number-neg-decimal.tact | 2 + ...cid-native-fun-number-neg-hexadecimal.tact | 2 + src/grammar/test/items-native-fun-funcid.tact | 27 ++++ 7 files changed, 187 insertions(+), 7 deletions(-) create mode 100644 src/grammar/test-failed/funcid-native-fun-hash.tact create mode 100644 src/grammar/test-failed/funcid-native-fun-number-hexadecimal-2.tact create mode 100644 src/grammar/test-failed/funcid-native-fun-number-neg-decimal.tact create mode 100644 src/grammar/test-failed/funcid-native-fun-number-neg-hexadecimal.tact diff --git a/src/grammar/__snapshots__/grammar.spec.ts.snap b/src/grammar/__snapshots__/grammar.spec.ts.snap index 2677286fe..b0978f46f 100644 --- a/src/grammar/__snapshots__/grammar.spec.ts.snap +++ b/src/grammar/__snapshots__/grammar.spec.ts.snap @@ -91,8 +91,18 @@ Line 1, col 10: " `; +exports[`grammar should fail funcid-native-fun-hash 1`] = ` +":1:7: Parse error: expected not ("\\"" or "{-" or "#") + +Line 1, col 7: +> 1 | @name(#notInclude) + ^ + 2 | native idTest(); +" +`; + exports[`grammar should fail funcid-native-fun-multiline-comments 1`] = ` -":1:7: Parse error: expected not ("\\"" or "{-") +":1:7: Parse error: expected not ("\\"" or "{-" or "#") Line 1, col 7: > 1 | @name({-aaa-}) @@ -131,6 +141,36 @@ Line 1, col 10: " `; +exports[`grammar should fail funcid-native-fun-number-hexadecimal-2 1`] = ` +":1:17: Parse error: expected not (a whiteSpace or "(" or ")" or "," or "." or ";" or "~") + +Line 1, col 17: +> 1 | @name(0xDEADBEEF) + ^ + 2 | native idTest(); +" +`; + +exports[`grammar should fail funcid-native-fun-number-neg-decimal 1`] = ` +":1:9: Parse error: expected not (a whiteSpace or "(" or ")" or "," or "." or ";" or "~") + +Line 1, col 9: +> 1 | @name(-1) + ^ + 2 | native idTest(); +" +`; + +exports[`grammar should fail funcid-native-fun-number-neg-hexadecimal 1`] = ` +":1:11: Parse error: expected not (a whiteSpace or "(" or ")" or "," or "." or ";" or "~") + +Line 1, col 11: +> 1 | @name(-0x0) + ^ + 2 | native idTest(); +" +`; + exports[`grammar should fail funcid-native-fun-only-underscore 1`] = ` ":1:8: Parse error: expected not (a whiteSpace or "(" or ")" or "," or "." or ";" or "~") @@ -172,7 +212,7 @@ Line 1, col 11: `; exports[`grammar should fail funcid-native-fun-string 1`] = ` -":1:7: Parse error: expected not ("\\"" or "{-") +":1:7: Parse error: expected not ("\\"" or "{-" or "#") Line 1, col 7: > 1 | @name("not_a_string) @@ -182,7 +222,7 @@ Line 1, col 7: `; exports[`grammar should fail funcid-native-fun-unclosed-parens 1`] = ` -":1:9: Parse error: expected not (a whiteSpace or "(" or ")" or "," or "." or ";" or "~") +":1:9: Parse error: expected ")" Line 1, col 9: > 1 | @name(aa(bb) @@ -3821,7 +3861,7 @@ native testFunc(): Bool;, exports[`grammar should parse items-native-fun-funcid 1`] = ` { - "id": 55, + "id": 70, "imports": [], "items": [ { @@ -4202,6 +4242,111 @@ native idTest18();, "params": [], "return": null, }, + { + "attributes": [], + "id": 57, + "kind": "native_function_decl", + "loc": @name(C4) +native idTest19();, + "name": { + "id": 55, + "kind": "id", + "loc": idTest19, + "text": "idTest19", + }, + "nativeName": { + "id": 56, + "kind": "func_id", + "loc": C4, + "text": "C4", + }, + "params": [], + "return": null, + }, + { + "attributes": [], + "id": 60, + "kind": "native_function_decl", + "loc": @name(C4g) +native idTest20();, + "name": { + "id": 58, + "kind": "id", + "loc": idTest20, + "text": "idTest20", + }, + "nativeName": { + "id": 59, + "kind": "func_id", + "loc": C4g, + "text": "C4g", + }, + "params": [], + "return": null, + }, + { + "attributes": [], + "id": 63, + "kind": "native_function_decl", + "loc": @name(4C) +native idTest21();, + "name": { + "id": 61, + "kind": "id", + "loc": idTest21, + "text": "idTest21", + }, + "nativeName": { + "id": 62, + "kind": "func_id", + "loc": 4C, + "text": "4C", + }, + "params": [], + "return": null, + }, + { + "attributes": [], + "id": 66, + "kind": "native_function_decl", + "loc": @name(_0x0) +native idTest22();, + "name": { + "id": 64, + "kind": "id", + "loc": idTest22, + "text": "idTest22", + }, + "nativeName": { + "id": 65, + "kind": "func_id", + "loc": _0x0, + "text": "_0x0", + }, + "params": [], + "return": null, + }, + { + "attributes": [], + "id": 69, + "kind": "native_function_decl", + "loc": @name(_0) +native idTest23();, + "name": { + "id": 67, + "kind": "id", + "loc": idTest23, + "text": "idTest23", + }, + "nativeName": { + "id": 68, + "kind": "func_id", + "loc": _0, + "text": "_0", + }, + "params": [], + "return": null, + }, ], "kind": "module", } diff --git a/src/grammar/grammar.ohm b/src/grammar/grammar.ohm index a253dadc7..a88db72ed 100644 --- a/src/grammar/grammar.ohm +++ b/src/grammar/grammar.ohm @@ -263,12 +263,12 @@ Tact { id = ~reservedWord #idStart #(idPart*) // FunC identifiers, where `funcId` stands for FunC function identifier - // The plain identifier cannot be a single underscore nor just a number - funcPlainId = "_"? "-"? "0x"? hexDigit* ~hexDigit (~(whiteSpace | "(" | ")" | "," | "." | ";" | "~") any)+ + // A plain identifier cannot be a number or a single underscore + funcPlainId = ("-"? "0x" hexDigit+ ~hexDigit)? ("-"? digit+ ~digit)? "_"? (~(whiteSpace | "(" | ")" | "," | "." | ";" | "~") any)+ funcQuotedId = "`" (~("`" | "\n") any)+ "`" - funcId = ~("\"" | "{-") ("." | "~")? (funcQuotedId | funcPlainId) + funcId = ~("\"" | "{-" | "#") ("." | "~")? (funcQuotedId | funcPlainId) // Boolean literals boolLiteral = ("true" | "false") ~idPart diff --git a/src/grammar/test-failed/funcid-native-fun-hash.tact b/src/grammar/test-failed/funcid-native-fun-hash.tact new file mode 100644 index 000000000..214f7c668 --- /dev/null +++ b/src/grammar/test-failed/funcid-native-fun-hash.tact @@ -0,0 +1,2 @@ +@name(#notInclude) +native idTest(); diff --git a/src/grammar/test-failed/funcid-native-fun-number-hexadecimal-2.tact b/src/grammar/test-failed/funcid-native-fun-number-hexadecimal-2.tact new file mode 100644 index 000000000..ef3db123b --- /dev/null +++ b/src/grammar/test-failed/funcid-native-fun-number-hexadecimal-2.tact @@ -0,0 +1,2 @@ +@name(0xDEADBEEF) +native idTest(); diff --git a/src/grammar/test-failed/funcid-native-fun-number-neg-decimal.tact b/src/grammar/test-failed/funcid-native-fun-number-neg-decimal.tact new file mode 100644 index 000000000..05b304f67 --- /dev/null +++ b/src/grammar/test-failed/funcid-native-fun-number-neg-decimal.tact @@ -0,0 +1,2 @@ +@name(-1) +native idTest(); diff --git a/src/grammar/test-failed/funcid-native-fun-number-neg-hexadecimal.tact b/src/grammar/test-failed/funcid-native-fun-number-neg-hexadecimal.tact new file mode 100644 index 000000000..98f707094 --- /dev/null +++ b/src/grammar/test-failed/funcid-native-fun-number-neg-hexadecimal.tact @@ -0,0 +1,2 @@ +@name(-0x0) +native idTest(); diff --git a/src/grammar/test/items-native-fun-funcid.tact b/src/grammar/test/items-native-fun-funcid.tact index d4fa3b818..f664f71be 100644 --- a/src/grammar/test/items-native-fun-funcid.tact +++ b/src/grammar/test/items-native-fun-funcid.tact @@ -51,3 +51,30 @@ native idTest17(); @name(`any symbols ; ~ () are allowed here...`) native idTest18(); + +@name(C4) +native idTest19(); + +@name(C4g) +native idTest20(); + +@name(4C) +native idTest21(); + +// Fun fact: +// Individually, _0x0 and _0 are totally valid identifiers in FunC, and the resulting Fift works fine too. +// But if they're together, FunC still compiles, but Fift interpreter cannot deal with that and crashes. + +@name(_0x0) +native idTest22(); + +@name(_0) +native idTest23(); + +// NOTE(novusnota): +// There is a only small set of cases related to the above that our parser won't parse, but C++ FunC's will: +// The hexadecimal or decimal number, followed immediately by a single underscore. +// It can look like: 0x0_, for example. Or like: 9000_. +// +// I decided not to fix these peculiar cases, as the RegEx gets absolutely wild. Also, these are super-weird identifiers, +// which have a big chance of breaking once the Fift interpreter comes into play, as described in the "Fun fact" paragraph above. From 0163633804961197b305ffc721be83720fb96b2f Mon Sep 17 00:00:00 2001 From: Novus Nota <68142933+novusnota@users.noreply.github.com> Date: Sun, 28 Jul 2024 03:24:06 +0200 Subject: [PATCH 02/12] chore: CHANGELOG --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fefeeb5c4..5e77464bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +- FunC function identifiers with characters from hexadecimal set: PR [#635](https://github.com/tact-lang/tact/pull/635) + ## [1.4.1] - 2024-07-26 ### Added From 65c5417a20c156405d7ec5e6c99f0e60ef24cc61 Mon Sep 17 00:00:00 2001 From: Novus Nota <68142933+novusnota@users.noreply.github.com> Date: Sun, 28 Jul 2024 04:10:10 +0200 Subject: [PATCH 03/12] test: chaos ensues --- .../__snapshots__/grammar.spec.ts.snap | 44 ++++++++++++++++++- src/grammar/test/items-native-fun-funcid.tact | 8 ++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/src/grammar/__snapshots__/grammar.spec.ts.snap b/src/grammar/__snapshots__/grammar.spec.ts.snap index b0978f46f..83a778706 100644 --- a/src/grammar/__snapshots__/grammar.spec.ts.snap +++ b/src/grammar/__snapshots__/grammar.spec.ts.snap @@ -3861,7 +3861,7 @@ native testFunc(): Bool;, exports[`grammar should parse items-native-fun-funcid 1`] = ` { - "id": 70, + "id": 76, "imports": [], "items": [ { @@ -4347,6 +4347,48 @@ native idTest23();, "params": [], "return": null, }, + { + "attributes": [], + "id": 72, + "kind": "native_function_decl", + "loc": @name(hash#256) +native idTest24();, + "name": { + "id": 70, + "kind": "id", + "loc": idTest24, + "text": "idTest24", + }, + "nativeName": { + "id": 71, + "kind": "func_id", + "loc": hash#256, + "text": "hash#256", + }, + "params": [], + "return": null, + }, + { + "attributes": [], + "id": 75, + "kind": "native_function_decl", + "loc": @name(💀💀💀0xDEADBEEF💀💀💀) +native idTest25();, + "name": { + "id": 73, + "kind": "id", + "loc": idTest25, + "text": "idTest25", + }, + "nativeName": { + "id": 74, + "kind": "func_id", + "loc": 💀💀💀0xDEADBEEF💀💀💀, + "text": "💀💀💀0xDEADBEEF💀💀💀", + }, + "params": [], + "return": null, + }, ], "kind": "module", } diff --git a/src/grammar/test/items-native-fun-funcid.tact b/src/grammar/test/items-native-fun-funcid.tact index f664f71be..127e85dfb 100644 --- a/src/grammar/test/items-native-fun-funcid.tact +++ b/src/grammar/test/items-native-fun-funcid.tact @@ -64,6 +64,8 @@ native idTest21(); // Fun fact: // Individually, _0x0 and _0 are totally valid identifiers in FunC, and the resulting Fift works fine too. // But if they're together, FunC still compiles, but Fift interpreter cannot deal with that and crashes. +// Same goes for identifiers using hashes # or emojis. +// I.e., you can have a function with any of those combinations of characters, but only one. @name(_0x0) native idTest22(); @@ -78,3 +80,9 @@ native idTest23(); // // I decided not to fix these peculiar cases, as the RegEx gets absolutely wild. Also, these are super-weird identifiers, // which have a big chance of breaking once the Fift interpreter comes into play, as described in the "Fun fact" paragraph above. + +@name(hash#256) +native idTest24(); + +@name(💀💀💀0xDEADBEEF💀💀💀) +native idTest25(); From 0d7e4a790fc60a6bde01394060518c695bf4172f Mon Sep 17 00:00:00 2001 From: Novus Nota <68142933+novusnota@users.noreply.github.com> Date: Sun, 28 Jul 2024 11:03:07 +0200 Subject: [PATCH 04/12] Update CHANGELOG.md Co-authored-by: Anton Trunov --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e77464bb..a627b248d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed -- FunC function identifiers with characters from hexadecimal set: PR [#635](https://github.com/tact-lang/tact/pull/635) +- FunC function identifiers with characters from hexadecimal set: PR [#636](https://github.com/tact-lang/tact/pull/636) ## [1.4.1] - 2024-07-26 From c955962053875f2253765e396ebe6d6c181fb3ec Mon Sep 17 00:00:00 2001 From: Novus Nota <68142933+novusnota@users.noreply.github.com> Date: Sun, 28 Jul 2024 11:31:31 +0200 Subject: [PATCH 05/12] feat/test: extended the possibilities and added more tests Came up with a simple solution for 0x0_ stuff, so our parser can deal with them too! --- .../__snapshots__/grammar.spec.ts.snap | 274 +++++++++++++++++- src/grammar/grammar.ohm | 12 +- src/grammar/test/items-native-fun-funcid.tact | 46 ++- 3 files changed, 311 insertions(+), 21 deletions(-) diff --git a/src/grammar/__snapshots__/grammar.spec.ts.snap b/src/grammar/__snapshots__/grammar.spec.ts.snap index 83a778706..ff3b91132 100644 --- a/src/grammar/__snapshots__/grammar.spec.ts.snap +++ b/src/grammar/__snapshots__/grammar.spec.ts.snap @@ -112,7 +112,7 @@ Line 1, col 7: `; exports[`grammar should fail funcid-native-fun-number 1`] = ` -":1:10: Parse error: expected not (a whiteSpace or "(" or ")" or "," or "." or ";" or "~") +":1:10: Parse error: expected "_" or not (a whiteSpace or "(" or ")" or "," or "." or ";" or "~") Line 1, col 10: > 1 | @name(123) @@ -122,7 +122,7 @@ Line 1, col 10: `; exports[`grammar should fail funcid-native-fun-number-decimal 1`] = ` -":1:8: Parse error: expected not (a whiteSpace or "(" or ")" or "," or "." or ";" or "~") +":1:8: Parse error: expected "_" or not (a whiteSpace or "(" or ")" or "," or "." or ";" or "~") Line 1, col 8: > 1 | @name(0) @@ -132,7 +132,7 @@ Line 1, col 8: `; exports[`grammar should fail funcid-native-fun-number-hexadecimal 1`] = ` -":1:10: Parse error: expected not (a whiteSpace or "(" or ")" or "," or "." or ";" or "~") +":1:10: Parse error: expected "_" or not (a whiteSpace or "(" or ")" or "," or "." or ";" or "~") Line 1, col 10: > 1 | @name(0x0) @@ -142,7 +142,7 @@ Line 1, col 10: `; exports[`grammar should fail funcid-native-fun-number-hexadecimal-2 1`] = ` -":1:17: Parse error: expected not (a whiteSpace or "(" or ")" or "," or "." or ";" or "~") +":1:17: Parse error: expected "_" or not (a whiteSpace or "(" or ")" or "," or "." or ";" or "~") Line 1, col 17: > 1 | @name(0xDEADBEEF) @@ -152,7 +152,7 @@ Line 1, col 17: `; exports[`grammar should fail funcid-native-fun-number-neg-decimal 1`] = ` -":1:9: Parse error: expected not (a whiteSpace or "(" or ")" or "," or "." or ";" or "~") +":1:9: Parse error: expected "_" or not (a whiteSpace or "(" or ")" or "," or "." or ";" or "~") Line 1, col 9: > 1 | @name(-1) @@ -162,7 +162,7 @@ Line 1, col 9: `; exports[`grammar should fail funcid-native-fun-number-neg-hexadecimal 1`] = ` -":1:11: Parse error: expected not (a whiteSpace or "(" or ")" or "," or "." or ";" or "~") +":1:11: Parse error: expected "_" or not (a whiteSpace or "(" or ")" or "," or "." or ";" or "~") Line 1, col 11: > 1 | @name(-0x0) @@ -3861,7 +3861,7 @@ native testFunc(): Bool;, exports[`grammar should parse items-native-fun-funcid 1`] = ` { - "id": 76, + "id": 112, "imports": [], "items": [ { @@ -4351,7 +4351,7 @@ native idTest23();, "attributes": [], "id": 72, "kind": "native_function_decl", - "loc": @name(hash#256) + "loc": @name(0x_) native idTest24();, "name": { "id": 70, @@ -4362,8 +4362,8 @@ native idTest24();, "nativeName": { "id": 71, "kind": "func_id", - "loc": hash#256, - "text": "hash#256", + "loc": 0x_, + "text": "0x_", }, "params": [], "return": null, @@ -4372,7 +4372,7 @@ native idTest24();, "attributes": [], "id": 75, "kind": "native_function_decl", - "loc": @name(💀💀💀0xDEADBEEF💀💀💀) + "loc": @name(0x0_) native idTest25();, "name": { "id": 73, @@ -4383,12 +4383,264 @@ native idTest25();, "nativeName": { "id": 74, "kind": "func_id", + "loc": 0x0_, + "text": "0x0_", + }, + "params": [], + "return": null, + }, + { + "attributes": [], + "id": 78, + "kind": "native_function_decl", + "loc": @name(0_) +native idTest26();, + "name": { + "id": 76, + "kind": "id", + "loc": idTest26, + "text": "idTest26", + }, + "nativeName": { + "id": 77, + "kind": "func_id", + "loc": 0_, + "text": "0_", + }, + "params": [], + "return": null, + }, + { + "attributes": [], + "id": 81, + "kind": "native_function_decl", + "loc": @name(hash#256) +native idTest27();, + "name": { + "id": 79, + "kind": "id", + "loc": idTest27, + "text": "idTest27", + }, + "nativeName": { + "id": 80, + "kind": "func_id", + "loc": hash#256, + "text": "hash#256", + }, + "params": [], + "return": null, + }, + { + "attributes": [], + "id": 84, + "kind": "native_function_decl", + "loc": @name(💀💀💀0xDEADBEEF💀💀💀) +native idTest28();, + "name": { + "id": 82, + "kind": "id", + "loc": idTest28, + "text": "idTest28", + }, + "nativeName": { + "id": 83, + "kind": "func_id", "loc": 💀💀💀0xDEADBEEF💀💀💀, "text": "💀💀💀0xDEADBEEF💀💀💀", }, "params": [], "return": null, }, + { + "attributes": [], + "id": 87, + "kind": "native_function_decl", + "loc": @name(__tact_verify_address) +native idTest29();, + "name": { + "id": 85, + "kind": "id", + "loc": idTest29, + "text": "idTest29", + }, + "nativeName": { + "id": 86, + "kind": "func_id", + "loc": __tact_verify_address, + "text": "__tact_verify_address", + }, + "params": [], + "return": null, + }, + { + "attributes": [], + "id": 90, + "kind": "native_function_decl", + "loc": @name(__tact_pow2) +native idTest30();, + "name": { + "id": 88, + "kind": "id", + "loc": idTest30, + "text": "idTest30", + }, + "nativeName": { + "id": 89, + "kind": "func_id", + "loc": __tact_pow2, + "text": "__tact_pow2", + }, + "params": [], + "return": null, + }, + { + "attributes": [], + "id": 93, + "kind": "native_function_decl", + "loc": @name(randomize_lt) +native idTest31();, + "name": { + "id": 91, + "kind": "id", + "loc": idTest31, + "text": "idTest31", + }, + "nativeName": { + "id": 92, + "kind": "func_id", + "loc": randomize_lt, + "text": "randomize_lt", + }, + "params": [], + "return": null, + }, + { + "attributes": [], + "id": 96, + "kind": "native_function_decl", + "loc": @name(fixed248::asin) +native idTest32();, + "name": { + "id": 94, + "kind": "id", + "loc": idTest32, + "text": "idTest32", + }, + "nativeName": { + "id": 95, + "kind": "func_id", + "loc": fixed248::asin, + "text": "fixed248::asin", + }, + "params": [], + "return": null, + }, + { + "attributes": [], + "id": 99, + "kind": "native_function_decl", + "loc": @name(fixed248::nrand_fast) +native idTest33();, + "name": { + "id": 97, + "kind": "id", + "loc": idTest33, + "text": "idTest33", + }, + "nativeName": { + "id": 98, + "kind": "func_id", + "loc": fixed248::nrand_fast, + "text": "fixed248::nrand_fast", + }, + "params": [], + "return": null, + }, + { + "attributes": [], + "id": 102, + "kind": "native_function_decl", + "loc": @name(atan_f261_inlined) +native idTest34();, + "name": { + "id": 100, + "kind": "id", + "loc": idTest34, + "text": "idTest34", + }, + "nativeName": { + "id": 101, + "kind": "func_id", + "loc": atan_f261_inlined, + "text": "atan_f261_inlined", + }, + "params": [], + "return": null, + }, + { + "attributes": [], + "id": 105, + "kind": "native_function_decl", + "loc": @name(~impure_touch) +native idTest35();, + "name": { + "id": 103, + "kind": "id", + "loc": idTest35, + "text": "idTest35", + }, + "nativeName": { + "id": 104, + "kind": "func_id", + "loc": ~impure_touch, + "text": "~impure_touch", + }, + "params": [], + "return": null, + }, + { + "attributes": [], + "id": 108, + "kind": "native_function_decl", + "loc": @name(~udict::delete_get_min) +native idTest36();, + "name": { + "id": 106, + "kind": "id", + "loc": idTest36, + "text": "idTest36", + }, + "nativeName": { + "id": 107, + "kind": "func_id", + "loc": ~udict::delete_get_min, + "text": "~udict::delete_get_min", + }, + "params": [], + "return": null, + }, + { + "attributes": [], + "id": 111, + "kind": "native_function_decl", + "loc": @name(.something) +native idTest37();, + "name": { + "id": 109, + "kind": "id", + "loc": idTest37, + "text": "idTest37", + }, + "nativeName": { + "id": 110, + "kind": "func_id", + "loc": .something, + "text": ".something", + }, + "params": [], + "return": null, + }, ], "kind": "module", } diff --git a/src/grammar/grammar.ohm b/src/grammar/grammar.ohm index a88db72ed..dc8c87bc7 100644 --- a/src/grammar/grammar.ohm +++ b/src/grammar/grammar.ohm @@ -264,12 +264,22 @@ Tact { // FunC identifiers, where `funcId` stands for FunC function identifier // A plain identifier cannot be a number or a single underscore - funcPlainId = ("-"? "0x" hexDigit+ ~hexDigit)? ("-"? digit+ ~digit)? "_"? (~(whiteSpace | "(" | ")" | "," | "." | ";" | "~") any)+ + funcPlainId = ("-"? "0x" hexDigit+ ~hexDigit)? ("-"? digit+ ~digit)? "_"? (~(whiteSpace | "(" | ")" | "," | "." | ";" | "~") any)+ --generic + | "-"? "0x" hexDigit* "_" --justHexUnderscore + | "-"? digit+ "_" --justDecUnderscore funcQuotedId = "`" (~("`" | "\n") any)+ "`" funcId = ~("\"" | "{-" | "#") ("." | "~")? (funcQuotedId | funcPlainId) + /* + NOTE(novusnota): + + 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. + */ + // Boolean literals boolLiteral = ("true" | "false") ~idPart diff --git a/src/grammar/test/items-native-fun-funcid.tact b/src/grammar/test/items-native-fun-funcid.tact index 127e85dfb..8d22e1473 100644 --- a/src/grammar/test/items-native-fun-funcid.tact +++ b/src/grammar/test/items-native-fun-funcid.tact @@ -73,16 +73,44 @@ native idTest22(); @name(_0) native idTest23(); -// NOTE(novusnota): -// There is a only small set of cases related to the above that our parser won't parse, but C++ FunC's will: -// The hexadecimal or decimal number, followed immediately by a single underscore. -// It can look like: 0x0_, for example. Or like: 9000_. -// -// I decided not to fix these peculiar cases, as the RegEx gets absolutely wild. Also, these are super-weird identifiers, -// which have a big chance of breaking once the Fift interpreter comes into play, as described in the "Fun fact" paragraph above. +@name(0x_) +native idTest24(); + +@name(0x0_) +native idTest25(); + +@name(0_) +native idTest26(); @name(hash#256) -native idTest24(); +native idTest27(); @name(💀💀💀0xDEADBEEF💀💀💀) -native idTest25(); +native idTest28(); + +@name(__tact_verify_address) +native idTest29(); + +@name(__tact_pow2) +native idTest30(); + +@name(randomize_lt) +native idTest31(); + +@name(fixed248::asin) +native idTest32(); + +@name(fixed248::nrand_fast) +native idTest33(); + +@name(atan_f261_inlined) +native idTest34(); + +@name(~impure_touch) +native idTest35(); + +@name(~udict::delete_get_min) +native idTest36(); + +@name(.something) +native idTest37(); From c5dadf4f0ba415c3544810182a8cb79414a1e08e Mon Sep 17 00:00:00 2001 From: Novus Nota <68142933+novusnota@users.noreply.github.com> Date: Sun, 28 Jul 2024 11:40:16 +0200 Subject: [PATCH 06/12] Update src/grammar/grammar.ohm Co-authored-by: Anton Trunov --- src/grammar/grammar.ohm | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/grammar/grammar.ohm b/src/grammar/grammar.ohm index dc8c87bc7..b46a06618 100644 --- a/src/grammar/grammar.ohm +++ b/src/grammar/grammar.ohm @@ -273,8 +273,6 @@ Tact { funcId = ~("\"" | "{-" | "#") ("." | "~")? (funcQuotedId | funcPlainId) /* - NOTE(novusnota): - 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. From 155bba3236d4ce81992d06ea4dee37884f1fed0c Mon Sep 17 00:00:00 2001 From: Novus Nota <68142933+novusnota@users.noreply.github.com> Date: Sun, 28 Jul 2024 11:45:54 +0200 Subject: [PATCH 07/12] test: corrupted and emojified identifiers --- .../__snapshots__/grammar.spec.ts.snap | 44 ++++++++++++++++++- src/grammar/test/items-native-fun-funcid.tact | 6 +++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/src/grammar/__snapshots__/grammar.spec.ts.snap b/src/grammar/__snapshots__/grammar.spec.ts.snap index ff3b91132..789af86b3 100644 --- a/src/grammar/__snapshots__/grammar.spec.ts.snap +++ b/src/grammar/__snapshots__/grammar.spec.ts.snap @@ -3861,7 +3861,7 @@ native testFunc(): Bool;, exports[`grammar should parse items-native-fun-funcid 1`] = ` { - "id": 112, + "id": 118, "imports": [], "items": [ { @@ -4641,6 +4641,48 @@ native idTest37();, "params": [], "return": null, }, + { + "attributes": [], + "id": 114, + "kind": "native_function_decl", + "loc": @name(f̷̨͈͚́͌̀i̵̩͔̭̐͐̊n̸̟̝̻̩̎̓͋̕e̸̝̙̒̿͒̾̕) +native idTest38();, + "name": { + "id": 112, + "kind": "id", + "loc": idTest38, + "text": "idTest38", + }, + "nativeName": { + "id": 113, + "kind": "func_id", + "loc": f̷̨͈͚́͌̀i̵̩͔̭̐͐̊n̸̟̝̻̩̎̓͋̕e̸̝̙̒̿͒̾̕, + "text": "f̷̨͈͚́͌̀i̵̩͔̭̐͐̊n̸̟̝̻̩̎̓͋̕e̸̝̙̒̿͒̾̕", + }, + "params": [], + "return": null, + }, + { + "attributes": [], + "id": 117, + "kind": "native_function_decl", + "loc": @name(❤️❤️❤️thanks❤️❤️❤️) +native idTest39();, + "name": { + "id": 115, + "kind": "id", + "loc": idTest39, + "text": "idTest39", + }, + "nativeName": { + "id": 116, + "kind": "func_id", + "loc": ❤️❤️❤️thanks❤️❤️❤️, + "text": "❤️❤️❤️thanks❤️❤️❤️", + }, + "params": [], + "return": null, + }, ], "kind": "module", } diff --git a/src/grammar/test/items-native-fun-funcid.tact b/src/grammar/test/items-native-fun-funcid.tact index 8d22e1473..639d00cb2 100644 --- a/src/grammar/test/items-native-fun-funcid.tact +++ b/src/grammar/test/items-native-fun-funcid.tact @@ -114,3 +114,9 @@ native idTest36(); @name(.something) native idTest37(); + +@name(f̷̨͈͚́͌̀i̵̩͔̭̐͐̊n̸̟̝̻̩̎̓͋̕e̸̝̙̒̿͒̾̕) +native idTest38(); + +@name(❤️❤️❤️thanks❤️❤️❤️) +native idTest39(); From 071572fbf575a871338a7c61eb9b281261e6a6d3 Mon Sep 17 00:00:00 2001 From: Novus Nota <68142933+novusnota@users.noreply.github.com> Date: Sun, 28 Jul 2024 20:26:38 +0200 Subject: [PATCH 08/12] fix/test: prohibit keywords, operators and compiler directives --- .../__snapshots__/grammar.spec.ts.snap | 132 ++++++++++++++---- src/grammar/grammar.ohm | 28 +++- .../funcid-native-fun-arith-operator.tact | 2 + .../funcid-native-fun-assign-operator.tact | 2 + .../funcid-native-fun-bitwise-operator.tact | 2 + ...funcid-native-fun-comparison-operator.tact | 2 + .../funcid-native-fun-control-keyword.tact | 2 + .../funcid-native-fun-delimiter.tact | 2 + .../funcid-native-fun-directive.tact | 2 + .../test-failed/funcid-native-fun-hash.tact | 2 - .../funcid-native-fun-keyword.tact | 2 + .../funcid-native-fun-type-keyword.tact | 2 + 12 files changed, 147 insertions(+), 33 deletions(-) create mode 100644 src/grammar/test-failed/funcid-native-fun-arith-operator.tact create mode 100644 src/grammar/test-failed/funcid-native-fun-assign-operator.tact create mode 100644 src/grammar/test-failed/funcid-native-fun-bitwise-operator.tact create mode 100644 src/grammar/test-failed/funcid-native-fun-comparison-operator.tact create mode 100644 src/grammar/test-failed/funcid-native-fun-control-keyword.tact create mode 100644 src/grammar/test-failed/funcid-native-fun-delimiter.tact create mode 100644 src/grammar/test-failed/funcid-native-fun-directive.tact delete mode 100644 src/grammar/test-failed/funcid-native-fun-hash.tact create mode 100644 src/grammar/test-failed/funcid-native-fun-keyword.tact create mode 100644 src/grammar/test-failed/funcid-native-fun-type-keyword.tact diff --git a/src/grammar/__snapshots__/grammar.spec.ts.snap b/src/grammar/__snapshots__/grammar.spec.ts.snap index 789af86b3..feb110ae3 100644 --- a/src/grammar/__snapshots__/grammar.spec.ts.snap +++ b/src/grammar/__snapshots__/grammar.spec.ts.snap @@ -71,6 +71,36 @@ Line 2, col 24: " `; +exports[`grammar should fail funcid-native-fun-arith-operator 1`] = ` +":1:7: Parse error: expected not a funcInvalidId or "\`" + +Line 1, col 7: +> 1 | @name(/) + ^ + 2 | native idTest(); +" +`; + +exports[`grammar should fail funcid-native-fun-assign-operator 1`] = ` +":1:7: Parse error: expected not a funcInvalidId or "\`" + +Line 1, col 7: +> 1 | @name(<<) + ^ + 2 | native idTest(); +" +`; + +exports[`grammar should fail funcid-native-fun-bitwise-operator 1`] = ` +":1:8: Parse error: expected not (a whiteSpace or "(" or ")" or "," or "." or ";" or "~") or "\`" + +Line 1, col 8: +> 1 | @name(~) + ^ + 2 | native idTest(); +" +`; + exports[`grammar should fail funcid-native-fun-comma 1`] = ` ":1:19: Parse error: expected ")" @@ -81,6 +111,46 @@ Line 1, col 19: " `; +exports[`grammar should fail funcid-native-fun-comparison-operator 1`] = ` +":1:7: Parse error: expected not a funcInvalidId or "\`" + +Line 1, col 7: +> 1 | @name(<=>) + ^ + 2 | native idTest(); +" +`; + +exports[`grammar should fail funcid-native-fun-control-keyword 1`] = ` +":1:7: Parse error: expected not a funcInvalidId or "\`" + +Line 1, col 7: +> 1 | @name(elseifnot) + ^ + 2 | native idTest(); +" +`; + +exports[`grammar should fail funcid-native-fun-delimiter 1`] = ` +":1:7: Parse error: expected not a funcInvalidId or "\`" + +Line 1, col 7: +> 1 | @name([) + ^ + 2 | native idTest(); +" +`; + +exports[`grammar should fail funcid-native-fun-directive 1`] = ` +":1:7: Parse error: expected not a funcInvalidId or "\`" + +Line 1, col 7: +> 1 | @name(#include) + ^ + 2 | native idTest(); +" +`; + exports[`grammar should fail funcid-native-fun-dot 1`] = ` ":1:10: Parse error: expected ")" @@ -91,18 +161,18 @@ Line 1, col 10: " `; -exports[`grammar should fail funcid-native-fun-hash 1`] = ` -":1:7: Parse error: expected not ("\\"" or "{-" or "#") +exports[`grammar should fail funcid-native-fun-keyword 1`] = ` +":1:7: Parse error: expected not a funcInvalidId or "\`" Line 1, col 7: -> 1 | @name(#notInclude) +> 1 | @name(global) ^ 2 | native idTest(); " `; exports[`grammar should fail funcid-native-fun-multiline-comments 1`] = ` -":1:7: Parse error: expected not ("\\"" or "{-" or "#") +":1:7: Parse error: expected not ("\\"" or "{-") Line 1, col 7: > 1 | @name({-aaa-}) @@ -112,71 +182,71 @@ Line 1, col 7: `; exports[`grammar should fail funcid-native-fun-number 1`] = ` -":1:10: Parse error: expected "_" or not (a whiteSpace or "(" or ")" or "," or "." or ";" or "~") +":1:7: Parse error: expected not a funcInvalidId or "\`" -Line 1, col 10: +Line 1, col 7: > 1 | @name(123) - ^ + ^ 2 | native idTest(); " `; exports[`grammar should fail funcid-native-fun-number-decimal 1`] = ` -":1:8: Parse error: expected "_" or not (a whiteSpace or "(" or ")" or "," or "." or ";" or "~") +":1:7: Parse error: expected not a funcInvalidId or "\`" -Line 1, col 8: +Line 1, col 7: > 1 | @name(0) - ^ + ^ 2 | native idTest(); " `; exports[`grammar should fail funcid-native-fun-number-hexadecimal 1`] = ` -":1:10: Parse error: expected "_" or not (a whiteSpace or "(" or ")" or "," or "." or ";" or "~") +":1:7: Parse error: expected not a funcInvalidId or "\`" -Line 1, col 10: +Line 1, col 7: > 1 | @name(0x0) - ^ + ^ 2 | native idTest(); " `; exports[`grammar should fail funcid-native-fun-number-hexadecimal-2 1`] = ` -":1:17: Parse error: expected "_" or not (a whiteSpace or "(" or ")" or "," or "." or ";" or "~") +":1:7: Parse error: expected not a funcInvalidId or "\`" -Line 1, col 17: +Line 1, col 7: > 1 | @name(0xDEADBEEF) - ^ + ^ 2 | native idTest(); " `; exports[`grammar should fail funcid-native-fun-number-neg-decimal 1`] = ` -":1:9: Parse error: expected "_" or not (a whiteSpace or "(" or ")" or "," or "." or ";" or "~") +":1:7: Parse error: expected not a funcInvalidId or "\`" -Line 1, col 9: +Line 1, col 7: > 1 | @name(-1) - ^ + ^ 2 | native idTest(); " `; exports[`grammar should fail funcid-native-fun-number-neg-hexadecimal 1`] = ` -":1:11: Parse error: expected "_" or not (a whiteSpace or "(" or ")" or "," or "." or ";" or "~") +":1:7: Parse error: expected not a funcInvalidId or "\`" -Line 1, col 11: +Line 1, col 7: > 1 | @name(-0x0) - ^ + ^ 2 | native idTest(); " `; exports[`grammar should fail funcid-native-fun-only-underscore 1`] = ` -":1:8: Parse error: expected not (a whiteSpace or "(" or ")" or "," or "." or ";" or "~") +":1:7: Parse error: expected not a funcInvalidId or "\`" -Line 1, col 8: +Line 1, col 7: > 1 | @name(_) - ^ + ^ 2 | native idTest(); " `; @@ -212,7 +282,7 @@ Line 1, col 11: `; exports[`grammar should fail funcid-native-fun-string 1`] = ` -":1:7: Parse error: expected not ("\\"" or "{-" or "#") +":1:7: Parse error: expected not ("\\"" or "{-") Line 1, col 7: > 1 | @name("not_a_string) @@ -221,6 +291,16 @@ Line 1, col 7: " `; +exports[`grammar should fail funcid-native-fun-type-keyword 1`] = ` +":1:7: Parse error: expected not a funcInvalidId or "\`" + +Line 1, col 7: +> 1 | @name(->) + ^ + 2 | native idTest(); +" +`; + exports[`grammar should fail funcid-native-fun-unclosed-parens 1`] = ` ":1:9: Parse error: expected ")" diff --git a/src/grammar/grammar.ohm b/src/grammar/grammar.ohm index b46a06618..2f2577cef 100644 --- a/src/grammar/grammar.ohm +++ b/src/grammar/grammar.ohm @@ -263,14 +263,32 @@ Tact { id = ~reservedWord #idStart #(idPart*) // FunC identifiers, where `funcId` stands for FunC function identifier - // A plain identifier cannot be a number or a single underscore - funcPlainId = ("-"? "0x" hexDigit+ ~hexDigit)? ("-"? digit+ ~digit)? "_"? (~(whiteSpace | "(" | ")" | "," | "." | ";" | "~") any)+ --generic - | "-"? "0x" hexDigit* "_" --justHexUnderscore - | "-"? digit+ "_" --justDecUnderscore + // 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 + + // Order of inner alternations matters + funcInvalidId = "_" ")" --notUnderscore + | ("+" | "-" | "*" | "/%" | "/" | "%" | "~/" | "^/" | "~%" | "^%") ")" --notArithOperator + | ("<=>" | "<=" | "<" | ">" | "=>" | "!=" | "==") ")" --notComparisonOperator + | ("~>>" | "~" | "^>>" | "^" | "&" | "|" | "<<" | ">>" ) ")" --notBitwiseOperator + | ("=" | "+=" | "-=" | "*=" | "/=" | "%=" + | "~>>=" | "~/=" | "~%=" | "^>>=" | "^/=" | "^%=" | "^=" + | "<<=" | ">>=" | "&=" | "|=") ")" --notAssignOperator + | ("[" | "]" | "{" | "}" | "?" | ":") ")" --notDelimiter + | ("return" | "var" | "repeat" | "do" | "while" | "until" | "try" | "catch" + | "ifnot" | "if" | "then" | "elseifnot" | "elseif" | "else") ")" --notControlKeyword + | ("int" | "cell" | "builder" | "slice" | "cont" | "tuple" | "type" | "->" | "forall") ")" --notTypeKeyword + | ("extern" | "global" | "asm" | "impure" | "inline_ref" | "inline" | "auto_apply" | "method_id" + | "operator" | "infixl" | "infixr" | "infix" | "const") ")" --notKeyword + | ("#include" | "#pragma") ")" --notDirective + | ("-"? digit+) ")" --notDecimalNumber + | ("-"? "0x" hexDigit+) ")" --notHexadecimalNumber + + funcPlainId = ~funcInvalidId (~(whiteSpace | "(" | ")" | "," | "." | ";" | "~") any)+ funcQuotedId = "`" (~("`" | "\n") any)+ "`" - funcId = ~("\"" | "{-" | "#") ("." | "~")? (funcQuotedId | funcPlainId) + funcId = ~("\"" | "{-") ("." | "~")? (funcQuotedId | funcPlainId) /* 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. diff --git a/src/grammar/test-failed/funcid-native-fun-arith-operator.tact b/src/grammar/test-failed/funcid-native-fun-arith-operator.tact new file mode 100644 index 000000000..e62909e01 --- /dev/null +++ b/src/grammar/test-failed/funcid-native-fun-arith-operator.tact @@ -0,0 +1,2 @@ +@name(/) +native idTest(); diff --git a/src/grammar/test-failed/funcid-native-fun-assign-operator.tact b/src/grammar/test-failed/funcid-native-fun-assign-operator.tact new file mode 100644 index 000000000..7f942d2fd --- /dev/null +++ b/src/grammar/test-failed/funcid-native-fun-assign-operator.tact @@ -0,0 +1,2 @@ +@name(^>>=) +native idTest(); diff --git a/src/grammar/test-failed/funcid-native-fun-bitwise-operator.tact b/src/grammar/test-failed/funcid-native-fun-bitwise-operator.tact new file mode 100644 index 000000000..e9b553502 --- /dev/null +++ b/src/grammar/test-failed/funcid-native-fun-bitwise-operator.tact @@ -0,0 +1,2 @@ +@name(~) +native idTest(); diff --git a/src/grammar/test-failed/funcid-native-fun-comparison-operator.tact b/src/grammar/test-failed/funcid-native-fun-comparison-operator.tact new file mode 100644 index 000000000..76b241bcd --- /dev/null +++ b/src/grammar/test-failed/funcid-native-fun-comparison-operator.tact @@ -0,0 +1,2 @@ +@name(<=>) +native idTest(); diff --git a/src/grammar/test-failed/funcid-native-fun-control-keyword.tact b/src/grammar/test-failed/funcid-native-fun-control-keyword.tact new file mode 100644 index 000000000..4c9bb9dde --- /dev/null +++ b/src/grammar/test-failed/funcid-native-fun-control-keyword.tact @@ -0,0 +1,2 @@ +@name(elseifnot) +native idTest(); diff --git a/src/grammar/test-failed/funcid-native-fun-delimiter.tact b/src/grammar/test-failed/funcid-native-fun-delimiter.tact new file mode 100644 index 000000000..0d6689502 --- /dev/null +++ b/src/grammar/test-failed/funcid-native-fun-delimiter.tact @@ -0,0 +1,2 @@ +@name([) +native idTest(); diff --git a/src/grammar/test-failed/funcid-native-fun-directive.tact b/src/grammar/test-failed/funcid-native-fun-directive.tact new file mode 100644 index 000000000..6ded6ea60 --- /dev/null +++ b/src/grammar/test-failed/funcid-native-fun-directive.tact @@ -0,0 +1,2 @@ +@name(#include) +native idTest(); diff --git a/src/grammar/test-failed/funcid-native-fun-hash.tact b/src/grammar/test-failed/funcid-native-fun-hash.tact deleted file mode 100644 index 214f7c668..000000000 --- a/src/grammar/test-failed/funcid-native-fun-hash.tact +++ /dev/null @@ -1,2 +0,0 @@ -@name(#notInclude) -native idTest(); diff --git a/src/grammar/test-failed/funcid-native-fun-keyword.tact b/src/grammar/test-failed/funcid-native-fun-keyword.tact new file mode 100644 index 000000000..9d4497a45 --- /dev/null +++ b/src/grammar/test-failed/funcid-native-fun-keyword.tact @@ -0,0 +1,2 @@ +@name(global) +native idTest(); diff --git a/src/grammar/test-failed/funcid-native-fun-type-keyword.tact b/src/grammar/test-failed/funcid-native-fun-type-keyword.tact new file mode 100644 index 000000000..f0abd9e96 --- /dev/null +++ b/src/grammar/test-failed/funcid-native-fun-type-keyword.tact @@ -0,0 +1,2 @@ +@name(->) +native idTest(); From 67b4d35274346cefe97cd5b4a56e0d94808c78a7 Mon Sep 17 00:00:00 2001 From: Novus Nota <68142933+novusnota@users.noreply.github.com> Date: Sun, 28 Jul 2024 20:36:23 +0200 Subject: [PATCH 09/12] chore: update snapshots --- src/grammar/__snapshots__/grammar.spec.ts.snap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/grammar/__snapshots__/grammar.spec.ts.snap b/src/grammar/__snapshots__/grammar.spec.ts.snap index feb110ae3..918714306 100644 --- a/src/grammar/__snapshots__/grammar.spec.ts.snap +++ b/src/grammar/__snapshots__/grammar.spec.ts.snap @@ -85,7 +85,7 @@ exports[`grammar should fail funcid-native-fun-assign-operator 1`] = ` ":1:7: Parse error: expected not a funcInvalidId or "\`" Line 1, col 7: -> 1 | @name(<<) +> 1 | @name(^>>=) ^ 2 | native idTest(); " From 097a13119e655e391b414abce221f4383a7276d1 Mon Sep 17 00:00:00 2001 From: Novus Nota <68142933+novusnota@users.noreply.github.com> Date: Sun, 28 Jul 2024 23:12:12 +0200 Subject: [PATCH 10/12] test: derivatives of reserved words should parse --- .../__snapshots__/grammar.spec.ts.snap | 44 ++++++++++++++++++- src/grammar/test/items-native-fun-funcid.tact | 6 +++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/src/grammar/__snapshots__/grammar.spec.ts.snap b/src/grammar/__snapshots__/grammar.spec.ts.snap index 918714306..3f5d08e20 100644 --- a/src/grammar/__snapshots__/grammar.spec.ts.snap +++ b/src/grammar/__snapshots__/grammar.spec.ts.snap @@ -3941,7 +3941,7 @@ native testFunc(): Bool;, exports[`grammar should parse items-native-fun-funcid 1`] = ` { - "id": 118, + "id": 124, "imports": [], "items": [ { @@ -4763,6 +4763,48 @@ native idTest39();, "params": [], "return": null, }, + { + "attributes": [], + "id": 120, + "kind": "native_function_decl", + "loc": @name(intslice) +native idTest40();, + "name": { + "id": 118, + "kind": "id", + "loc": idTest40, + "text": "idTest40", + }, + "nativeName": { + "id": 119, + "kind": "func_id", + "loc": intslice, + "text": "intslice", + }, + "params": [], + "return": null, + }, + { + "attributes": [], + "id": 123, + "kind": "native_function_decl", + "loc": @name(int2) +native idTest40();, + "name": { + "id": 121, + "kind": "id", + "loc": idTest40, + "text": "idTest40", + }, + "nativeName": { + "id": 122, + "kind": "func_id", + "loc": int2, + "text": "int2", + }, + "params": [], + "return": null, + }, ], "kind": "module", } diff --git a/src/grammar/test/items-native-fun-funcid.tact b/src/grammar/test/items-native-fun-funcid.tact index 639d00cb2..90ca19a94 100644 --- a/src/grammar/test/items-native-fun-funcid.tact +++ b/src/grammar/test/items-native-fun-funcid.tact @@ -120,3 +120,9 @@ native idTest38(); @name(❤️❤️❤️thanks❤️❤️❤️) native idTest39(); + +@name(intslice) +native idTest40(); + +@name(int2) +native idTest40(); From ca8a50f2067b9cbca8665698321ea15ccd94d1dd Mon Sep 17 00:00:00 2001 From: Novus Nota <68142933+novusnota@users.noreply.github.com> Date: Sun, 28 Jul 2024 23:33:33 +0200 Subject: [PATCH 11/12] fix: typo in the operator --- src/grammar/grammar.ohm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/grammar/grammar.ohm b/src/grammar/grammar.ohm index 2f2577cef..6e08f50cb 100644 --- a/src/grammar/grammar.ohm +++ b/src/grammar/grammar.ohm @@ -269,7 +269,7 @@ Tact { // Order of inner alternations matters funcInvalidId = "_" ")" --notUnderscore | ("+" | "-" | "*" | "/%" | "/" | "%" | "~/" | "^/" | "~%" | "^%") ")" --notArithOperator - | ("<=>" | "<=" | "<" | ">" | "=>" | "!=" | "==") ")" --notComparisonOperator + | ("<=>" | "<=" | "<" | ">=" | ">" | "!=" | "==") ")" --notComparisonOperator | ("~>>" | "~" | "^>>" | "^" | "&" | "|" | "<<" | ">>" ) ")" --notBitwiseOperator | ("=" | "+=" | "-=" | "*=" | "/=" | "%=" | "~>>=" | "~/=" | "~%=" | "^>>=" | "^/=" | "^%=" | "^=" From 9d40c88ef027fd0af1a6cf8aab340529817f85f0 Mon Sep 17 00:00:00 2001 From: Novus Nota <68142933+novusnota@users.noreply.github.com> Date: Mon, 29 Jul 2024 11:10:29 +0200 Subject: [PATCH 12/12] fix: prohibit square brackets (used in tuples) --- src/grammar/__snapshots__/grammar.spec.ts.snap | 12 +++++++++++- src/grammar/grammar.ohm | 2 +- .../funcid-native-fun-square-brackets.tact | 2 ++ 3 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 src/grammar/test-failed/funcid-native-fun-square-brackets.tact diff --git a/src/grammar/__snapshots__/grammar.spec.ts.snap b/src/grammar/__snapshots__/grammar.spec.ts.snap index 3f5d08e20..054c91939 100644 --- a/src/grammar/__snapshots__/grammar.spec.ts.snap +++ b/src/grammar/__snapshots__/grammar.spec.ts.snap @@ -92,7 +92,7 @@ Line 1, col 7: `; exports[`grammar should fail funcid-native-fun-bitwise-operator 1`] = ` -":1:8: Parse error: expected not (a whiteSpace or "(" or ")" or "," or "." or ";" or "~") or "\`" +":1:8: Parse error: expected not (a whiteSpace or "(" or ")" or "[" or "]" or "," or "." or ";" or "~") or "\`" Line 1, col 8: > 1 | @name(~) @@ -281,6 +281,16 @@ Line 1, col 11: " `; +exports[`grammar should fail funcid-native-fun-square-brackets 1`] = ` +":1:11: Parse error: expected ")" + +Line 1, col 11: +> 1 | @name(take[some]entry) + ^ + 2 | native idTest(); +" +`; + exports[`grammar should fail funcid-native-fun-string 1`] = ` ":1:7: Parse error: expected not ("\\"" or "{-") diff --git a/src/grammar/grammar.ohm b/src/grammar/grammar.ohm index 6e08f50cb..17ebb582f 100644 --- a/src/grammar/grammar.ohm +++ b/src/grammar/grammar.ohm @@ -284,7 +284,7 @@ Tact { | ("-"? digit+) ")" --notDecimalNumber | ("-"? "0x" hexDigit+) ")" --notHexadecimalNumber - funcPlainId = ~funcInvalidId (~(whiteSpace | "(" | ")" | "," | "." | ";" | "~") any)+ + funcPlainId = ~funcInvalidId (~(whiteSpace | "(" | ")" | "[" | "]" | "," | "." | ";" | "~") any)+ funcQuotedId = "`" (~("`" | "\n") any)+ "`" diff --git a/src/grammar/test-failed/funcid-native-fun-square-brackets.tact b/src/grammar/test-failed/funcid-native-fun-square-brackets.tact new file mode 100644 index 000000000..e93bbb9d9 --- /dev/null +++ b/src/grammar/test-failed/funcid-native-fun-square-brackets.tact @@ -0,0 +1,2 @@ +@name(take[some]entry) +native idTest();