Skip to content

Commit 3b63bdf

Browse files
authored
feat: support Tact 1.5.0 (#24)
* feat: `asm` functions * feat: `uint1-256` and `int1-257` Without completions for those for now, since doing it naively would introduce 500+ entries into the completions list, with each entry taking 6 lines. I'll take a look into using some Python code as part of the plugin and Sublime APIs. * feat: new builtin (comptime) and stdlib functions * fix: tests and extra constant
1 parent 440f907 commit 3b63bdf

File tree

6 files changed

+245
-8
lines changed

6 files changed

+245
-8
lines changed

package/Tact.sublime-completions

Lines changed: 101 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@
1414
"kind": ["function", "a", "Attribute"],
1515
"details": "<a href=\"https://docs.tact-lang.org/book/contracts#interfaces\">Tact Docs</a>"
1616
},
17+
{
18+
"trigger": "asm\tasm with optional arrangement (...)",
19+
"contents": "asm $0",
20+
"kind": ["function", "a", "Attribute"]
21+
},
1722

1823
// Literals, Base trait and constants
1924
{
@@ -100,6 +105,11 @@
100105
"kind": ["variable", "c", "Constant"],
101106
"details": "<a href=\"https://docs.tact-lang.org/book/message-mode#optional-flags\">Tact Docs</a>"
102107
},
108+
{
109+
"trigger": "SendOnlyEstimateFee\tequal to 1024",
110+
"contents": "SendOnlyEstimateFee",
111+
"kind": ["variable", "c", "Constant"]
112+
},
103113
{
104114
"trigger": "ReserveExact\tequal to 0",
105115
"contents": "ReserveExact",
@@ -150,6 +160,16 @@
150160
"kind": ["variable", "s", "Struct"],
151161
"details": "<a href=\"https://docs.tact-lang.org/book/expressions#initof\">Tact Docs</a>"
152162
},
163+
{
164+
"trigger": "StdAddress",
165+
"contents": "StdAddress",
166+
"kind": ["variable", "s", "Struct"]
167+
},
168+
{
169+
"trigger": "VarAddress",
170+
"contents": "VarAddress",
171+
"kind": ["variable", "s", "Struct"]
172+
},
153173

154174
// Built-in types and serialization options
155175
{
@@ -607,6 +627,26 @@
607627
"kind": "function",
608628
"details": "<a href=\"https://docs.tact-lang.org/ref/core-comptime#ton\">Tact Docs</a>"
609629
},
630+
{
631+
"trigger": "slice\tSlice from a BoC String at compile-time",
632+
"contents": "slice(${1:bocBase64String})",
633+
"kind": "function"
634+
},
635+
{
636+
"trigger": "rawSlice\tSlice from a String at compile-time",
637+
"contents": "rawSlice(${1:someString})",
638+
"kind": "function"
639+
},
640+
{
641+
"trigger": "ascii\tInt sum of ASCII values at compile-time",
642+
"contents": "aslii(${1:asciiString})",
643+
"kind": "function"
644+
},
645+
{
646+
"trigger": "crc32\tCRC32 of a String at compile-time",
647+
"contents": "crc32(${1:someString})",
648+
"kind": "function"
649+
},
610650

611651
// Core library: Debug
612652
{
@@ -651,6 +691,16 @@
651691
"kind": "function",
652692
"details": "<a href=\"https://docs.tact-lang.org/ref/core-debug#nativethrowunless\">Tact Docs</a>"
653693
},
694+
{
695+
"trigger": "parseStdAddress\tparse StdAddress from a Slice",
696+
"contents": "parseStdAddress(${1:slice_Slice})",
697+
"kind": "function"
698+
},
699+
{
700+
"trigger": "parseVarAddress\tparse VarAddress from a Slice",
701+
"contents": "parseVarAddress(${1:slice_Slice})",
702+
"kind": "function"
703+
},
654704

655705
// Core library: Random
656706
{
@@ -823,11 +873,61 @@
823873
"kind": "function",
824874
"details": "<a href=\"https://docs.tact-lang.org/ref/core-advanced#nativesendmessage\">Tact Docs</a>"
825875
},
876+
{
877+
"trigger": "nativeSendMessageReturnForwardFee\tsend message Cell with mode Int and get fees",
878+
"contents": "nativeSendMessageReturnForwardFee(${1:cell}, ${2:mode_Int})",
879+
"kind": "function"
880+
},
826881
{
827882
"trigger": "nativeReserve\treserve nanoToncoin amount Int with mode Int",
828883
"contents": "nativeReserve(${1:amount_Int}, ${2:mode_Int})",
829884
"kind": "function",
830885
"details": "<a href=\"https://docs.tact-lang.org/ref/core-advanced#nativereserve\">Tact Docs</a>"
831-
}
886+
},
887+
{
888+
"trigger": "nativeReserve\treserve nanoToncoin amount Int with mode Int",
889+
"contents": "nativeReserve(${1:amount_Int}, ${2:mode_Int})",
890+
"kind": "function"
891+
},
892+
{
893+
"trigger": "gasConsumed\tget gas consumed so far",
894+
"contents": "gasConsumed()",
895+
"kind": "function"
896+
},
897+
{
898+
"trigger": "getComputeFee\tcalc compute cost in nanoToncoins",
899+
"contents": "getComputeFee(${1:gas_used_Int, ${2:is_masterchain_Bool})",
900+
"kind": "function"
901+
},
902+
{
903+
"trigger": "getStorageFee\tcalc storage fees in nanoToncoins",
904+
"contents": "getStorageFee(${1:cells_Int, ${2:bits_Int}, ${3:seconds_Int}, ${4:is_masterchain_Bool})",
905+
"kind": "function"
906+
},
907+
{
908+
"trigger": "getForwardFee\tcalc forward fees in nanoToncoins",
909+
"contents": "getForwardFee(${1:cells_Int, ${2:bits_Int}, ${3:is_masterchain_Bool})",
910+
"kind": "function"
911+
},
912+
{
913+
"trigger": "getSimpleComputeFee\tcalc extra compute cost in nanoToncoins",
914+
"contents": "getSimpleComputeFee(${1:gas_used_Int, ${2:is_masterchain_Bool})",
915+
"kind": "function"
916+
},
917+
{
918+
"trigger": "getSimpleForwardFee\tcalc extra forward fees in nanoToncoins",
919+
"contents": "getSimpleForwardFee(${1:cells_Int, ${2:bits_Int}, ${3:is_masterchain_Bool})",
920+
"kind": "function"
921+
},
922+
{
923+
"trigger": "getOriginalFwdFee\tcalc original fwd_fee in nanoToncoins",
924+
"contents": "getOriginalFwdFee(${1:fwd_fee_Int, ${2:is_masterchain_Bool})",
925+
"kind": "function"
926+
},
927+
{
928+
"trigger": "myStorageDue\tstorage fee debt in nanoToncoins",
929+
"contents": "myStorageDue(${1:fwd_fee_Int, ${2:is_masterchain_Bool})",
930+
"kind": "function"
931+
},
832932
]
833933
}

package/Tact.tmLanguage

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -212,11 +212,59 @@
212212
</dict>
213213
</dict>
214214
</dict>
215+
<dict>
216+
<key>comment</key>
217+
<string>Asm arrangements</string>
218+
<key>begin</key>
219+
<string>(?&lt;!\.)(asm)\s*(\()</string>
220+
<key>beginCaptures</key>
221+
<dict>
222+
<key>1</key>
223+
<dict>
224+
<key>name</key>
225+
<string>entity.other.attribute-name.tact</string>
226+
</dict>
227+
<key>2</key>
228+
<dict>
229+
<key>name</key>
230+
<string>punctuation.brackets.round.tact</string>
231+
</dict>
232+
</dict>
233+
<key>patterns</key>
234+
<array>
235+
<dict>
236+
<key>include</key>
237+
<string>#variable</string>
238+
</dict>
239+
<dict>
240+
<key>match</key>
241+
<string>-&gt;</string>
242+
<key>name</key>
243+
<string>keyword.operator.mapsto.tact</string>
244+
</dict>
245+
<dict>
246+
<key>match</key>
247+
<string>\b([0-9]*)\b</string>
248+
<key>name</key>
249+
<string>constant.numeric.decimal.tact</string>
250+
</dict>
251+
</array>
252+
<key>end</key>
253+
<string>\)</string>
254+
<key>endCaptures</key>
255+
<dict>
256+
<key>0</key>
257+
<dict>
258+
<key>name</key>
259+
<string>punctuation.brackets.round.tact</string>
260+
</dict>
261+
</dict>
262+
</dict>
215263
<dict>
216264
<key>comment</key>
217265
<string>Fallback match</string>
218266
<key>match</key>
219-
<string>(?&lt;!\.)\b(@name|@interface)\b</string>
267+
<string>(?&lt;!\.)\b(@name|@interface|asm)\b</string>
220268
<key>name</key>
221269
<string>entity.other.attribute-name.tact</string>
222270
</dict>
@@ -394,7 +442,7 @@
394442
<key>comment</key>
395443
<string>Other constants from the core library</string>
396444
<key>match</key>
397-
<string>(?&lt;!\.)\b(SendRemainingValue|SendRemainingBalance|SendPayGasSeparately|SendIgnoreErrors|SendBounceIfActionFail|SendDestroyIfZero|ReserveExact|ReserveAllExcept|ReserveAtMost|ReserveAddOriginalBalance|ReserveInvertSign|ReserveBounceIfActionFail)\b</string>
445+
<string>(?&lt;!\.)\b(SendRemainingValue|SendRemainingBalance|SendPayGasSeparately|SendIgnoreErrors|SendBounceIfActionFail|SendDestroyIfZero|SendOnlyEstimateFee|ReserveExact|ReserveAllExcept|ReserveAtMost|ReserveAddOriginalBalance|ReserveInvertSign|ReserveBounceIfActionFail)\b</string>
398446
<key>name</key>
399447
<string>constant.other.builtin.tact</string>
400448
</dict>
@@ -559,7 +607,7 @@
559607
<array>
560608
<dict>
561609
<key>match</key>
562-
<string>(?&lt;!\.)\b(as)\s+([a-zA-Z_][a-zA-Z0-9_]*)\b</string>
610+
<string>(?&lt;!\.)\b(as)\s+(coins|remaining|bytes32|bytes64|int257|u?int(?:2[0-5][0-6]|1[0-9][0-9]|[1-9][0-9]?))\b</string>
563611
<key>captures</key>
564612
<dict>
565613
<key>1</key>
@@ -871,4 +919,4 @@
871919
</dict>
872920
</dict>
873921
</dict>
874-
</plist>
922+
</plist>

package/Tact.tmLanguage.json

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,9 +138,40 @@
138138
}
139139
}
140140
},
141+
{
142+
"comment": "Asm arrangements",
143+
"begin": "(?<!\\.)(asm)\\s*(\\()",
144+
"beginCaptures": {
145+
"1": {
146+
"name": "entity.other.attribute-name.tact"
147+
},
148+
"2": {
149+
"name": "punctuation.brackets.round.tact"
150+
}
151+
},
152+
"patterns": [
153+
{
154+
"include": "#variable"
155+
},
156+
{
157+
"match": "->",
158+
"name": "keyword.operator.mapsto.tact"
159+
},
160+
{
161+
"match": "\\b([0-9]*)\\b",
162+
"name": "constant.numeric.decimal.tact"
163+
}
164+
],
165+
"end": "\\)",
166+
"endCaptures": {
167+
"0": {
168+
"name": "punctuation.brackets.round.tact"
169+
}
170+
}
171+
},
141172
{
142173
"comment": "Fallback match",
143-
"match": "(?<!\\.)\\b(@name|@interface)\\b",
174+
"match": "(?<!\\.)\\b(@name|@interface|asm)\\b",
144175
"name": "entity.other.attribute-name.tact"
145176
}
146177
]
@@ -256,7 +287,7 @@
256287
},
257288
{
258289
"comment": "Other constants from the core library",
259-
"match": "(?<!\\.)\\b(SendRemainingValue|SendRemainingBalance|SendPayGasSeparately|SendIgnoreErrors|SendBounceIfActionFail|SendDestroyIfZero|ReserveExact|ReserveAllExcept|ReserveAtMost|ReserveAddOriginalBalance|ReserveInvertSign|ReserveBounceIfActionFail)\\b",
290+
"match": "(?<!\\.)\\b(SendRemainingValue|SendRemainingBalance|SendPayGasSeparately|SendIgnoreErrors|SendBounceIfActionFail|SendDestroyIfZero|SendOnlyEstimateFee|ReserveExact|ReserveAllExcept|ReserveAtMost|ReserveAddOriginalBalance|ReserveInvertSign|ReserveBounceIfActionFail)\\b",
260291
"name": "constant.other.builtin.tact"
261292
},
262293
{
@@ -365,7 +396,7 @@
365396
"comment": "Serialization",
366397
"patterns": [
367398
{
368-
"match": "(?<!\\.)\\b(as)\\s+([a-zA-Z_][a-zA-Z0-9_]*)\\b",
399+
"match": "(?<!\\.)\\b(as)\\s+(coins|remaining|bytes32|bytes64|int257|u?int(?:2[0-5][0-6]|1[0-9][0-9]|[1-9][0-9]?))\\b",
369400
"captures": {
370401
"1": {
371402
"name": "keyword.other.as.tact storage.modifier.tact"

tests/syntax_test_const.tact

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ fun builtin() {
4646
// <- constant.other.builtin.tact
4747
SendDestroyIfZero;
4848
// <- constant.other.builtin.tact
49+
SendOnlyEstimateFee;
50+
// <- constant.other.builtin.tact
4951

5052
ReserveExact;
5153
// <- constant.other.builtin.tact

tests/syntax_test_native.tact

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,23 @@ extends mutates native loadInt(self: Slice, l: Int, ): Int;
2424
// ^ punctuation.colon.tact
2525
// ^^^ entity.name.type.tact
2626
// ^ punctuation.semi.tact
27+
28+
asm fun increase(): Int { INC }
29+
// <- entity.other.attribute-name.tact
30+
// ^^^ keyword.other.function.tact
31+
// ^^^^^^^^ entity.name.function.tact
32+
// ^^ punctuation.brackets.round.tact
33+
// ^ punctuation.colon.tact
34+
// ^^^ entity.name.type.tact
35+
// ^ punctuation.brackets.curly.tact
36+
// ^^^ constant.other.caps.tact
37+
// ^ punctuation.brackets.curly.tact
38+
39+
asm(second first -> 0) fun addTwo(first: Int, second: Int): Int { SOMETHING SOMETHING }
40+
// <- entity.other.attribute-name.tact
41+
// ^ punctuation.brackets.round.tact
42+
// ^^^^^^ variable.other.tact
43+
// ^^^^^ variable.other.tact
44+
// ^^ keyword.operator.mapsto.tact
45+
// ^ constant.numeric.decimal.tact
46+
// ^ punctuation.brackets.round.tact

tests/syntax_test_struct.tact

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,39 @@ fun TestStruct() {
6363
// ^ punctuation.brackets.curly.tact
6464
// ^ punctuation.semi.tact
6565
}
66+
67+
struct Serialization {
68+
f1: Int as uint1;
69+
// ^^^^^ entity.name.type.tact
70+
f2: Int as int1;
71+
// ^^^^ entity.name.type.tact
72+
f3: Int as uint10;
73+
// ^^^^^^ entity.name.type.tact
74+
f4: Int as int10;
75+
// ^^^^^ entity.name.type.tact
76+
f5: Int as uint100;
77+
// ^^^^^^^ entity.name.type.tact
78+
f6: Int as int100;
79+
// ^^^^^^ entity.name.type.tact
80+
f7: Int as uint200;
81+
// ^^^^^^^ entity.name.type.tact
82+
f8: Int as int200;
83+
// ^^^^^^ entity.name.type.tact
84+
f9: Int as uint256;
85+
// ^^^^^^^ entity.name.type.tact
86+
f10: Int as int257;
87+
// ^^^^^^ entity.name.type.tact
88+
f9wrong: Int as uint257;
89+
// ^^^^^^^ variable.other.tact
90+
f10wrong: Int as int258;
91+
// ^^^^^^ variable.other.tact
92+
93+
b32: Slice as bytes32;
94+
// ^^^^^^^ entity.name.type.tact
95+
b64: Slice as bytes64;
96+
// ^^^^^^^ entity.name.type.tact
97+
coin: Int as coins;
98+
// ^^^^^ entity.name.type.tact
99+
payload: Slice as remaining;
100+
// ^^^^^^^^^ entity.name.type.tact
101+
}

0 commit comments

Comments
 (0)