From 2e1789a3fde984b1f4c01c83b8b990ad82e4e05c Mon Sep 17 00:00:00 2001 From: Gusarich Date: Tue, 28 Nov 2023 22:41:23 +0300 Subject: [PATCH] add tests for ternary operator --- src/test/feature-ternary.spec.ts | 34 ++ .../features/output/ternary_TernaryTester.abi | 1 + .../output/ternary_TernaryTester.code.boc | Bin 0 -> 475 bytes .../output/ternary_TernaryTester.code.fc | 146 ++++++++ .../output/ternary_TernaryTester.code.fif | 211 +++++++++++ .../output/ternary_TernaryTester.code.rev.fif | 211 +++++++++++ .../output/ternary_TernaryTester.headers.fc | 28 ++ .../features/output/ternary_TernaryTester.md | 61 ++++ .../features/output/ternary_TernaryTester.pkg | 1 + .../output/ternary_TernaryTester.stdlib.fc | 12 + .../output/ternary_TernaryTester.storage.fc | 23 ++ .../features/output/ternary_TernaryTester.ts | 334 ++++++++++++++++++ src/test/features/ternary.tact | 26 ++ tact.config.json | 8 + 14 files changed, 1096 insertions(+) create mode 100644 src/test/feature-ternary.spec.ts create mode 100644 src/test/features/output/ternary_TernaryTester.abi create mode 100644 src/test/features/output/ternary_TernaryTester.code.boc create mode 100644 src/test/features/output/ternary_TernaryTester.code.fc create mode 100644 src/test/features/output/ternary_TernaryTester.code.fif create mode 100644 src/test/features/output/ternary_TernaryTester.code.rev.fif create mode 100644 src/test/features/output/ternary_TernaryTester.headers.fc create mode 100644 src/test/features/output/ternary_TernaryTester.md create mode 100644 src/test/features/output/ternary_TernaryTester.pkg create mode 100644 src/test/features/output/ternary_TernaryTester.stdlib.fc create mode 100644 src/test/features/output/ternary_TernaryTester.storage.fc create mode 100644 src/test/features/output/ternary_TernaryTester.ts create mode 100644 src/test/features/ternary.tact diff --git a/src/test/feature-ternary.spec.ts b/src/test/feature-ternary.spec.ts new file mode 100644 index 000000000..3247c2294 --- /dev/null +++ b/src/test/feature-ternary.spec.ts @@ -0,0 +1,34 @@ +import { beginCell, toNano } from 'ton-core'; +import { ContractSystem } from '@tact-lang/emulator'; +import { __DANGER_resetNodeId } from '../grammar/ast'; +import { TernaryTester } from './features/output/ternary_TernaryTester'; + +describe('feature-ternary', () => { + beforeEach(() => { + __DANGER_resetNodeId(); + }); + it('should implement ternary operator correctly', async () => { + + // Init + let system = await ContractSystem.create(); + let treasure = system.treasure('treasure'); + let contract = system.open(await TernaryTester.fromInit()); + await contract.send(treasure, { value: toNano('10') }, null); + await system.run(); + + // Check methods + expect(await contract.getTest1(123n)).toEqual(1n); + expect(await contract.getTest1(5n)).toEqual(2n); + + expect(await contract.getTest2(123n)).toEqual(246n); + expect(await contract.getTest2(5n)).toEqual(15n); + + expect(await contract.getTest3(2n, 2n)).toEqual(1n); + expect(await contract.getTest3(2n, 3n)).toEqual(2n); + + expect(await contract.getTest4(123n, 456n)).toEqual(1n); + expect(await contract.getTest4(123n, 5n)).toEqual(2n); + expect(await contract.getTest4(5n, 789n)).toEqual(3n); + expect(await contract.getTest4(5n, 5n)).toEqual(4n); + }); +}); \ No newline at end of file diff --git a/src/test/features/output/ternary_TernaryTester.abi b/src/test/features/output/ternary_TernaryTester.abi new file mode 100644 index 000000000..12b2bda78 --- /dev/null +++ b/src/test/features/output/ternary_TernaryTester.abi @@ -0,0 +1 @@ +{"name":"TernaryTester","types":[{"name":"StateInit","header":null,"fields":[{"name":"code","type":{"kind":"simple","type":"cell","optional":false}},{"name":"data","type":{"kind":"simple","type":"cell","optional":false}}]},{"name":"Context","header":null,"fields":[{"name":"bounced","type":{"kind":"simple","type":"bool","optional":false}},{"name":"sender","type":{"kind":"simple","type":"address","optional":false}},{"name":"value","type":{"kind":"simple","type":"int","optional":false,"format":257}},{"name":"raw","type":{"kind":"simple","type":"slice","optional":false}}]},{"name":"SendParameters","header":null,"fields":[{"name":"bounce","type":{"kind":"simple","type":"bool","optional":false}},{"name":"to","type":{"kind":"simple","type":"address","optional":false}},{"name":"value","type":{"kind":"simple","type":"int","optional":false,"format":257}},{"name":"mode","type":{"kind":"simple","type":"int","optional":false,"format":257}},{"name":"body","type":{"kind":"simple","type":"cell","optional":true}},{"name":"code","type":{"kind":"simple","type":"cell","optional":true}},{"name":"data","type":{"kind":"simple","type":"cell","optional":true}}]}],"receivers":[{"receiver":"internal","message":{"kind":"empty"}}],"getters":[{"name":"test1","arguments":[{"name":"a","type":{"kind":"simple","type":"int","optional":false,"format":257}}],"returnType":{"kind":"simple","type":"int","optional":false,"format":257}},{"name":"test2","arguments":[{"name":"a","type":{"kind":"simple","type":"int","optional":false,"format":257}}],"returnType":{"kind":"simple","type":"int","optional":false,"format":257}},{"name":"test3","arguments":[{"name":"a","type":{"kind":"simple","type":"int","optional":false,"format":257}},{"name":"b","type":{"kind":"simple","type":"int","optional":false,"format":257}}],"returnType":{"kind":"simple","type":"int","optional":false,"format":257}},{"name":"test4","arguments":[{"name":"a","type":{"kind":"simple","type":"int","optional":false,"format":257}},{"name":"b","type":{"kind":"simple","type":"int","optional":false,"format":257}}],"returnType":{"kind":"simple","type":"int","optional":false,"format":257}}],"errors":{"2":{"message":"Stack undeflow"},"3":{"message":"Stack overflow"},"4":{"message":"Integer overflow"},"5":{"message":"Integer out of expected range"},"6":{"message":"Invalid opcode"},"7":{"message":"Type check error"},"8":{"message":"Cell overflow"},"9":{"message":"Cell underflow"},"10":{"message":"Dictionary error"},"13":{"message":"Out of gas error"},"32":{"message":"Method ID not found"},"34":{"message":"Action is invalid or not supported"},"37":{"message":"Not enough TON"},"38":{"message":"Not enough extra-currencies"},"128":{"message":"Null reference exception"},"129":{"message":"Invalid serialization prefix"},"130":{"message":"Invalid incoming message"},"131":{"message":"Constraints error"},"132":{"message":"Access denied"},"133":{"message":"Contract stopped"},"134":{"message":"Invalid argument"},"135":{"message":"Code of a contract was not found"},"136":{"message":"Invalid address"},"137":{"message":"Masterchain support is not enabled for this contract"}},"interfaces":["org.ton.introspection.v0","org.ton.abi.ipfs.v0","org.ton.deploy.lazy.v0","org.ton.debug.v0","org.ton.chain.workchain.v0"]} \ No newline at end of file diff --git a/src/test/features/output/ternary_TernaryTester.code.boc b/src/test/features/output/ternary_TernaryTester.code.boc new file mode 100644 index 0000000000000000000000000000000000000000..2dd8291decd30475af08f89160522e34ba68bc61 GIT binary patch literal 475 zcmdn`ZcY&+lQ<&-<9P-~k^c-|mI!~@^XUXPBNJm16EoAK3yc>oGcy)$Sj_m#fl=YQ zXCou`u1^m-6s~h~DKxVD-}UK2XEP^ABqSi1IiKZ6BGZqg+cuH6Z9Y9{GC1+Wnej|L z<0*!dZ$kuFm>3mU*%)jXCmGZ~C{Voac}RY$0ni-zdj}X8uX`R;+%OR+4phX>0VIS) zfCMKOli&`8*v&`hZayp_Ajl-REkruK!8*OoK!6)4&BM#Ucc6M=;l!dxOoAIWd^^uj zcAh6efDg#ovF*GVn8VK?qHv&k(kg~Y%b6cB@azJsW;A*0a^VW&kK{`X1`~51{LldU z2JDN@+crWB28;))XErjPfT*3>$Sk^RV)4Y1M~@hoav65+-YcQbdhYPmOQ)W1eBpO^ zZpwS&bZg}-p`Q8 ze3?>P+Xta@jDWgsmONc;@@Bj7f|qGG-SWCTm>4}o#TW!Ptlu4IV$#5nz)-p=@3C{( zbhdQkMW4QkU3I%GCcZp> 128, + "org.ton.abi.ipfs.v0"H >> 128, + "org.ton.deploy.lazy.v0"H >> 128, + "org.ton.debug.v0"H >> 128, + "org.ton.chain.workchain.v0"H >> 128 + ); +} + +_ get_abi_ipfs() method_id { + return "ipfs://QmTm1azvz3xGNedgaYyb1nvMYZS1Nf9zkvFmYH9qBDg6FC"; +} + +_ lazy_deployment_completed() method_id { + return get_data().begin_parse().load_int(1); +} + +;; +;; Routing of a Contract TernaryTester +;; + +(tuple, int) $TernaryTester$_contract_router_internal(tuple self, int msg_bounced, slice in_msg) impure inline_ref { + ;; Handle bounced messages + if (msg_bounced) { + return (self, true); + } + + ;; Parse incoming message + int op = 0; + if (slice_bits(in_msg) >= 32) { + op = in_msg.preload_uint(32); + } + + + ;; Receive empty message + if ((op == 0) & (slice_bits(in_msg) <= 32)) { + self~%$TernaryTester$_internal_empty(); + return (self, true); + } + + return (self, false); +} + +() recv_internal(int msg_value, cell in_msg_cell, slice in_msg) impure { + + ;; Context + var cs = in_msg_cell.begin_parse(); + var msg_flags = cs~load_uint(4); + var msg_bounced = -(msg_flags & 1); + slice msg_sender_addr = __tact_verify_address(cs~load_msg_addr()); + __tact_context = (msg_bounced, msg_sender_addr, msg_value, cs); + __tact_context_sender = msg_sender_addr; + + ;; Load contract data + var self = $TernaryTester$_contract_load(); + + ;; Handle operation + int handled = self~$TernaryTester$_contract_router_internal(msg_bounced, in_msg); + + ;; Throw if not handled + throw_unless(130, handled); + + ;; Persist state + $TernaryTester$_contract_store(self); +} diff --git a/src/test/features/output/ternary_TernaryTester.code.fif b/src/test/features/output/ternary_TernaryTester.code.fif new file mode 100644 index 000000000..50c27b06d --- /dev/null +++ b/src/test/features/output/ternary_TernaryTester.code.fif @@ -0,0 +1,211 @@ +PROGRAM{ + DECLPROC __tact_verify_address + DECLPROC $TernaryTester$_contract_init + DECLPROC $TernaryTester$_contract_load + DECLPROC $TernaryTester$_contract_store + DECLPROC $TernaryTester$_fun_test1 + DECLPROC $TernaryTester$_fun_test2 + DECLPROC $TernaryTester$_fun_test3 + DECLPROC $TernaryTester$_fun_test4 + DECLPROC %$TernaryTester$_internal_empty + 70304 DECLMETHOD %test1 + 74435 DECLMETHOD %test2 + 78562 DECLMETHOD %test3 + 82437 DECLMETHOD %test4 + 113617 DECLMETHOD supported_interfaces + 121275 DECLMETHOD get_abi_ipfs + 115390 DECLMETHOD lazy_deployment_completed + DECLPROC $TernaryTester$_contract_router_internal + DECLPROC recv_internal + DECLGLOBVAR __tact_context + DECLGLOBVAR __tact_context_sender + DECLGLOBVAR __tact_context_sys + DECLGLOBVAR __tact_randomized + __tact_verify_address PROCINLINE:<{ + DUP + SBITS + 267 PUSHINT + EQUAL + 136 THROWIFNOT + DUP + 11 PLDU + DUP + 1279 PUSHINT + EQUAL + 137 THROWIF + 10 PUSHPOW2 + EQUAL + 136 THROWIFNOT + }> + $TernaryTester$_contract_init PROCREF:<{ + PUSHNULL + }> + $TernaryTester$_contract_load PROCREF:<{ + c4 PUSH + CTOS + LDREF + SWAP + __tact_context_sys SETGLOB + 1 LDI + DROP + IFJMP:<{ + PUSHNULL + }> + MYADDR + 11 PLDU + 10 PUSHPOW2 + EQUAL + 137 THROWIFNOT + $TernaryTester$_contract_init INLINECALLDICT + }> + $TernaryTester$_contract_store PROCINLINE:<{ + DROP + NEWC + __tact_context_sys GETGLOB + SWAP + STREF + TRUE + SWAP + 1 STI + ENDC + c4 POP + }> + $TernaryTester$_fun_test1 PROCREF:<{ + 123 EQINT + IF:<{ + 1 PUSHINT + }>ELSE<{ + 2 PUSHINT + }> + }> + $TernaryTester$_fun_test2 PROCREF:<{ + DUP + 123 EQINT + IF:<{ + 1 LSHIFT# + }>ELSE<{ + 3 MULCONST + }> + }> + $TernaryTester$_fun_test3 PROCREF:<{ + EQUAL + IF:<{ + 1 PUSHINT + }>ELSE<{ + 2 PUSHINT + }> + }> + $TernaryTester$_fun_test4 PROCREF:<{ + SWAP + 123 EQINT + IF:<{ + 456 PUSHINT + EQUAL + IF:<{ + 1 PUSHINT + }>ELSE<{ + 2 PUSHINT + }> + }>ELSE<{ + 789 PUSHINT + EQUAL + IF:<{ + 3 PUSHINT + }>ELSE<{ + 4 PUSHINT + }> + }> + }> + %$TernaryTester$_internal_empty PROCINLINE:<{ + }> + %test1 PROC:<{ + $TernaryTester$_contract_load INLINECALLDICT + SWAP + $TernaryTester$_fun_test1 INLINECALLDICT + NIP + }> + %test2 PROC:<{ + $TernaryTester$_contract_load INLINECALLDICT + SWAP + $TernaryTester$_fun_test2 INLINECALLDICT + NIP + }> + %test3 PROC:<{ + $TernaryTester$_contract_load INLINECALLDICT + -ROT + $TernaryTester$_fun_test3 INLINECALLDICT + NIP + }> + %test4 PROC:<{ + $TernaryTester$_contract_load INLINECALLDICT + -ROT + $TernaryTester$_fun_test4 INLINECALLDICT + NIP + }> + supported_interfaces PROC:<{ + 123515602279859691144772641439386770278 PUSHINT + 209801025412363888721030803524359905849 PUSHINT + 42980537499636128163026532310500881091 PUSHINT + 36993126140238121407019133875791708966 PUSHINT + 209474421377847335869795010607481022628 PUSHINT + }> + get_abi_ipfs PROC:<{ + x{697066733a2f2f516d546d31617a767a3378474e65646761597962316e764d595a53314e66397a6b76466d59483971424467364643} PUSHSLICE + }> + lazy_deployment_completed PROC:<{ + c4 PUSH + CTOS + 1 LDI + SWAP + }> + $TernaryTester$_contract_router_internal PROCREF:<{ + SWAP + IFJMP:<{ + DROP + TRUE + }> + 0 PUSHINT + OVER + SBITS + 31 GTINT + IF:<{ + DROP + DUP + 32 PLDU + }> + 0 EQINT + SWAP + SBITS + 33 LESSINT + AND + IFJMP:<{ + %$TernaryTester$_internal_empty INLINECALLDICT + TRUE + }> + FALSE + }> + recv_internal PROC:<{ + SWAP + CTOS + 4 LDU + SWAP + 1 PUSHINT + AND + NEGATE + SWAP + LDMSGADDR + SWAP + __tact_verify_address INLINECALLDICT + s0 s4 s2 PUXCPU + s0 s3 XCHG + 4 TUPLE + __tact_context SETGLOB + s0 s2 XCHG + __tact_context_sender SETGLOB + $TernaryTester$_contract_load INLINECALLDICT + -ROT + $TernaryTester$_contract_router_internal INLINECALLDICT + 130 THROWIFNOT + $TernaryTester$_contract_store INLINECALLDICT + }> +}END>c diff --git a/src/test/features/output/ternary_TernaryTester.code.rev.fif b/src/test/features/output/ternary_TernaryTester.code.rev.fif new file mode 100644 index 000000000..d6db86af3 --- /dev/null +++ b/src/test/features/output/ternary_TernaryTester.code.rev.fif @@ -0,0 +1,211 @@ +PROGRAM{ + DECLPROC recv_internal; + DECLPROC ?fun_70304; + DECLPROC ?fun_74435; + DECLPROC ?fun_78562; + DECLPROC ?fun_82437; + DECLPROC supported_interfaces; + DECLPROC lazy_deployment_completed; + DECLPROC get_abi_ipfs; + DECLPROC ?fun_ref_364de9562794919e; + DECLPROC ?fun_ref_4b7c16b16b29693f; + DECLPROC ?fun_ref_96bb5087664b6772; + DECLPROC ?fun_ref_a05e0042bce184fb; + DECLPROC ?fun_ref_c0ca23818e24f3c9; + DECLPROC ?fun_ref_eac35a6e322f692c; + DECLPROC ?fun_ref_f7f33a77d1558909; + recv_internal PROC:<{ + s0 s1 XCHG + CTOS + 4 LDU + s0 s1 XCHG + 1 PUSHINT + AND + -1 MULCONST + s0 s1 XCHG + LDMSGADDR + s0 s1 XCHG + s0 PUSH + SBITS + 267 PUSHINT + EQUAL + 136 THROWIFNOT + s0 PUSH + 11 PLDU + s0 PUSH + 1279 PUSHINT + EQUAL + 137 THROWIF + 10 PUSHPOW2 + EQUAL + 136 THROWIFNOT + s0 s6 s4 PUXCPU + s0 s3 XCHG + 4 TUPLE + 1 SETGLOBVAR + s0 s2 XCHG + 2 SETGLOBVAR + ?fun_ref_a05e0042bce184fb INLINECALLDICT + ROTREV + ?fun_ref_364de9562794919e INLINECALLDICT + 130 THROWIFNOT + s0 POP + NEWC + 3 GETGLOBVAR + s0 s1 XCHG + STREF + -1 PUSHINT + s0 s1 XCHG + 1 STI + ENDC + c4 POP + }> + ?fun_70304 PROC:<{ + ?fun_ref_a05e0042bce184fb INLINECALLDICT + s0 s1 XCHG + ?fun_ref_4b7c16b16b29693f INLINECALLDICT + s1 POP + }> + ?fun_74435 PROC:<{ + ?fun_ref_a05e0042bce184fb INLINECALLDICT + s0 s1 XCHG + ?fun_ref_f7f33a77d1558909 INLINECALLDICT + s1 POP + }> + ?fun_78562 PROC:<{ + ?fun_ref_a05e0042bce184fb INLINECALLDICT + ROTREV + ?fun_ref_eac35a6e322f692c INLINECALLDICT + s1 POP + }> + ?fun_82437 PROC:<{ + ?fun_ref_a05e0042bce184fb INLINECALLDICT + ROTREV + ?fun_ref_96bb5087664b6772 INLINECALLDICT + s1 POP + }> + supported_interfaces PROC:<{ + 123515602279859691144772641439386770278 PUSHINT + 209801025412363888721030803524359905849 PUSHINT + 42980537499636128163026532310500881091 PUSHINT + 36993126140238121407019133875791708966 PUSHINT + 209474421377847335869795010607481022628 PUSHINT + }> + lazy_deployment_completed PROC:<{ + c4 PUSH + CTOS + 1 LDI + s0 s1 XCHG + }> + get_abi_ipfs PROC:<{ + x{697066733A2F2F516D546D31617A767A3378474E65646761597962316E764D595A53314E66397A6B76466D5948397142446736464382_} PUSHSLICE + }> + ?fun_ref_364de9562794919e PROCREF:<{ + s0 s1 XCHG + <{ + s0 POP + -1 PUSHINT + }> PUSHCONT + IFJMP + 0 PUSHINT + s1 PUSH + SBITS + 31 GTINT + <{ + s0 POP + s0 PUSH + 32 PLDU + }> PUSHCONT + IF + 0 EQINT + s0 s1 XCHG + SBITS + 33 LESSINT + AND + <{ + -1 PUSHINT + }> PUSHCONT + IFJMP + 0 PUSHINT + }> + ?fun_ref_4b7c16b16b29693f PROCREF:<{ + 123 EQINT + <{ + 1 PUSHINT + }> PUSHCONT + <{ + 2 PUSHINT + }> PUSHCONT + IFELSE + }> + ?fun_ref_96bb5087664b6772 PROCREF:<{ + s0 s1 XCHG + 123 EQINT + <{ + 456 PUSHINT + EQUAL + <{ + 1 PUSHINT + }> PUSHCONT + <{ + 2 PUSHINT + }> PUSHCONT + IFELSE + }> PUSHCONT + <{ + 789 PUSHINT + EQUAL + <{ + 3 PUSHINT + }> PUSHCONT + <{ + 4 PUSHINT + }> PUSHCONT + IFELSE + }> PUSHCONT + IFELSE + }> + ?fun_ref_a05e0042bce184fb PROCREF:<{ + c4 PUSH + CTOS + LDREF + s0 s1 XCHG + 3 SETGLOBVAR + 1 LDI + s0 POP + <{ + NULL + }> PUSHCONT + IFJMP + MYADDR + 11 PLDU + 10 PUSHPOW2 + EQUAL + 137 THROWIFNOT + ?fun_ref_c0ca23818e24f3c9 INLINECALLDICT + }> + ?fun_ref_c0ca23818e24f3c9 PROCREF:<{ + NULL + }> + ?fun_ref_eac35a6e322f692c PROCREF:<{ + EQUAL + <{ + 1 PUSHINT + }> PUSHCONT + <{ + 2 PUSHINT + }> PUSHCONT + IFELSE + }> + ?fun_ref_f7f33a77d1558909 PROCREF:<{ + s0 PUSH + 123 EQINT + <{ + 1 LSHIFT + }> PUSHCONT + <{ + 3 MULCONST + }> PUSHCONT + IFELSE + }> +}END>c \ No newline at end of file diff --git a/src/test/features/output/ternary_TernaryTester.headers.fc b/src/test/features/output/ternary_TernaryTester.headers.fc new file mode 100644 index 000000000..788865358 --- /dev/null +++ b/src/test/features/output/ternary_TernaryTester.headers.fc @@ -0,0 +1,28 @@ +;; +;; Header files for TernaryTester +;; NOTE: declarations are sorted for optimal order +;; + +;; __tact_verify_address +slice __tact_verify_address(slice address) inline; + +;; $TernaryTester$_contract_init +tuple $TernaryTester$_contract_init() impure inline_ref; + +;; $TernaryTester$_contract_load +tuple $TernaryTester$_contract_load() impure inline_ref; + +;; $TernaryTester$_contract_store +() $TernaryTester$_contract_store(tuple v) impure inline; + +;; $TernaryTester$_fun_test1 +(tuple, int) $TernaryTester$_fun_test1(tuple $self, int $a) impure inline_ref; + +;; $TernaryTester$_fun_test2 +(tuple, int) $TernaryTester$_fun_test2(tuple $self, int $a) impure inline_ref; + +;; $TernaryTester$_fun_test3 +(tuple, int) $TernaryTester$_fun_test3(tuple $self, int $a, int $b) impure inline_ref; + +;; $TernaryTester$_fun_test4 +(tuple, int) $TernaryTester$_fun_test4(tuple $self, int $a, int $b) impure inline_ref; diff --git a/src/test/features/output/ternary_TernaryTester.md b/src/test/features/output/ternary_TernaryTester.md new file mode 100644 index 000000000..f87f35300 --- /dev/null +++ b/src/test/features/output/ternary_TernaryTester.md @@ -0,0 +1,61 @@ +# TACT Compilation Report +Contract: TernaryTester +BOC Size: 475 bytes + +# Types +Total Types: 3 + +## StateInit +TLB: `_ code:^cell data:^cell = StateInit` +Signature: `StateInit{code:^cell,data:^cell}` + +## Context +TLB: `_ bounced:bool sender:address value:int257 raw:^slice = Context` +Signature: `Context{bounced:bool,sender:address,value:int257,raw:^slice}` + +## SendParameters +TLB: `_ bounce:bool to:address value:int257 mode:int257 body:Maybe ^cell code:Maybe ^cell data:Maybe ^cell = SendParameters` +Signature: `SendParameters{bounce:bool,to:address,value:int257,mode:int257,body:Maybe ^cell,code:Maybe ^cell,data:Maybe ^cell}` + +# Get Methods +Total Get Methods: 4 + +## test1 +Argument: a + +## test2 +Argument: a + +## test3 +Argument: a +Argument: b + +## test4 +Argument: a +Argument: b + +# Error Codes +2: Stack undeflow +3: Stack overflow +4: Integer overflow +5: Integer out of expected range +6: Invalid opcode +7: Type check error +8: Cell overflow +9: Cell underflow +10: Dictionary error +13: Out of gas error +32: Method ID not found +34: Action is invalid or not supported +37: Not enough TON +38: Not enough extra-currencies +128: Null reference exception +129: Invalid serialization prefix +130: Invalid incoming message +131: Constraints error +132: Access denied +133: Contract stopped +134: Invalid argument +135: Code of a contract was not found +136: Invalid address +137: Masterchain support is not enabled for this contract \ No newline at end of file diff --git a/src/test/features/output/ternary_TernaryTester.pkg b/src/test/features/output/ternary_TernaryTester.pkg new file mode 100644 index 000000000..9d4234f8b --- /dev/null +++ b/src/test/features/output/ternary_TernaryTester.pkg @@ -0,0 +1 @@ +{"name":"TernaryTester","code":"te6ccgECFwEAAc8AART/APSkE/S88sgLAQIBYgIDApLQAdDTAwFxsKMB+kABINdJgQELuvLgiCDXCwoggQT/uvLQiYMJuvLgiFRQUwNvBPhhAvhi2zxZ2zzy4IIwyPhDAcx/AcoAye1UEAQCASAFBgA8AZIwf+BwIddJwh+VMCDXCx/ewAAB10nBIbCRf+BwAgEgBwgCASATFAIBIAkKAhG4IF2zxZ2zwxgQEQIRtlQbZ4A7Z4YwEAsCASAMDQAOwHuRcZFy4gIRsLD2zwB2zwxgEA4CEbC4ts8Wds8MYBAPABQgwHuSqgCSpwPiAAy6kXGRcuIBNO1E0NQB+GPSADCRbeD4KNcLCoMJuvLgids8EgAwAcB7mYEByLqRcZFy4pmBAxW6kXORdOLiAAJtALm7vRgnBc7D1dLK57HoTsOdZKhRtmgnCd1jUtK2R8syLTry398WI5gnAgVcAbgGdjlM5YOq5HJbLDgnAb1J3vlUWW8cdT094FWcMmgnCdl05as07LczoOlm2UZuikgCAUgVFgARsK+7UTQ0gABgAHWybuNDVpcGZzOi8vUW1UbTFhenZ6M3hHTmVkZ2FZeWIxbnZNWVpTMU5mOXprdkZtWUg5cUJEZzZGQ4IA==","abi":"{\"name\":\"TernaryTester\",\"types\":[{\"name\":\"StateInit\",\"header\":null,\"fields\":[{\"name\":\"code\",\"type\":{\"kind\":\"simple\",\"type\":\"cell\",\"optional\":false}},{\"name\":\"data\",\"type\":{\"kind\":\"simple\",\"type\":\"cell\",\"optional\":false}}]},{\"name\":\"Context\",\"header\":null,\"fields\":[{\"name\":\"bounced\",\"type\":{\"kind\":\"simple\",\"type\":\"bool\",\"optional\":false}},{\"name\":\"sender\",\"type\":{\"kind\":\"simple\",\"type\":\"address\",\"optional\":false}},{\"name\":\"value\",\"type\":{\"kind\":\"simple\",\"type\":\"int\",\"optional\":false,\"format\":257}},{\"name\":\"raw\",\"type\":{\"kind\":\"simple\",\"type\":\"slice\",\"optional\":false}}]},{\"name\":\"SendParameters\",\"header\":null,\"fields\":[{\"name\":\"bounce\",\"type\":{\"kind\":\"simple\",\"type\":\"bool\",\"optional\":false}},{\"name\":\"to\",\"type\":{\"kind\":\"simple\",\"type\":\"address\",\"optional\":false}},{\"name\":\"value\",\"type\":{\"kind\":\"simple\",\"type\":\"int\",\"optional\":false,\"format\":257}},{\"name\":\"mode\",\"type\":{\"kind\":\"simple\",\"type\":\"int\",\"optional\":false,\"format\":257}},{\"name\":\"body\",\"type\":{\"kind\":\"simple\",\"type\":\"cell\",\"optional\":true}},{\"name\":\"code\",\"type\":{\"kind\":\"simple\",\"type\":\"cell\",\"optional\":true}},{\"name\":\"data\",\"type\":{\"kind\":\"simple\",\"type\":\"cell\",\"optional\":true}}]}],\"receivers\":[{\"receiver\":\"internal\",\"message\":{\"kind\":\"empty\"}}],\"getters\":[{\"name\":\"test1\",\"arguments\":[{\"name\":\"a\",\"type\":{\"kind\":\"simple\",\"type\":\"int\",\"optional\":false,\"format\":257}}],\"returnType\":{\"kind\":\"simple\",\"type\":\"int\",\"optional\":false,\"format\":257}},{\"name\":\"test2\",\"arguments\":[{\"name\":\"a\",\"type\":{\"kind\":\"simple\",\"type\":\"int\",\"optional\":false,\"format\":257}}],\"returnType\":{\"kind\":\"simple\",\"type\":\"int\",\"optional\":false,\"format\":257}},{\"name\":\"test3\",\"arguments\":[{\"name\":\"a\",\"type\":{\"kind\":\"simple\",\"type\":\"int\",\"optional\":false,\"format\":257}},{\"name\":\"b\",\"type\":{\"kind\":\"simple\",\"type\":\"int\",\"optional\":false,\"format\":257}}],\"returnType\":{\"kind\":\"simple\",\"type\":\"int\",\"optional\":false,\"format\":257}},{\"name\":\"test4\",\"arguments\":[{\"name\":\"a\",\"type\":{\"kind\":\"simple\",\"type\":\"int\",\"optional\":false,\"format\":257}},{\"name\":\"b\",\"type\":{\"kind\":\"simple\",\"type\":\"int\",\"optional\":false,\"format\":257}}],\"returnType\":{\"kind\":\"simple\",\"type\":\"int\",\"optional\":false,\"format\":257}}],\"errors\":{\"2\":{\"message\":\"Stack undeflow\"},\"3\":{\"message\":\"Stack overflow\"},\"4\":{\"message\":\"Integer overflow\"},\"5\":{\"message\":\"Integer out of expected range\"},\"6\":{\"message\":\"Invalid opcode\"},\"7\":{\"message\":\"Type check error\"},\"8\":{\"message\":\"Cell overflow\"},\"9\":{\"message\":\"Cell underflow\"},\"10\":{\"message\":\"Dictionary error\"},\"13\":{\"message\":\"Out of gas error\"},\"32\":{\"message\":\"Method ID not found\"},\"34\":{\"message\":\"Action is invalid or not supported\"},\"37\":{\"message\":\"Not enough TON\"},\"38\":{\"message\":\"Not enough extra-currencies\"},\"128\":{\"message\":\"Null reference exception\"},\"129\":{\"message\":\"Invalid serialization prefix\"},\"130\":{\"message\":\"Invalid incoming message\"},\"131\":{\"message\":\"Constraints error\"},\"132\":{\"message\":\"Access denied\"},\"133\":{\"message\":\"Contract stopped\"},\"134\":{\"message\":\"Invalid argument\"},\"135\":{\"message\":\"Code of a contract was not found\"},\"136\":{\"message\":\"Invalid address\"},\"137\":{\"message\":\"Masterchain support is not enabled for this contract\"}},\"interfaces\":[\"org.ton.introspection.v0\",\"org.ton.abi.ipfs.v0\",\"org.ton.deploy.lazy.v0\",\"org.ton.debug.v0\",\"org.ton.chain.workchain.v0\"]}","init":{"kind":"direct","args":[],"prefix":{"bits":1,"value":0},"deployment":{"kind":"system-cell","system":"te6cckECGQEAAdkAAQHAAQEFoEs9AgEU/wD0pBP0vPLICwMCAWIVBAIBIAoFAgEgCQYCAUgIBwB1sm7jQ1aXBmczovL1FtVG0xYXp2ejN4R05lZGdhWXliMW52TVlaUzFOZjl6a3ZGbVlIOXFCRGc2RkOCAAEbCvu1E0NIAAYAC5u70YJwXOw9XSyuex6E7DnWSoUbZoJwndY1LStkfLMi068t/fFiOYJwIFXAG4BnY5TOWDquRyWyw4JwG9Sd75VFlvHHU9PeBVnDJoJwnZdOWrNOy3M6DpZtlGbopIAgEgDQsCEbggXbPFnbPDGBcMADABwHuZgQHIupFxkXLimYEDFbqRc5F04uICASATDgIBIBEPAhGwuLbPFnbPDGAXEAAMupFxkXLiAhGwsPbPAHbPDGAXEgAUIMB7kqoAkqcD4gIRtlQbZ4A7Z4YwFxQADsB7kXGRcuICktAB0NMDAXGwowH6QAEg10mBAQu68uCIINcLCiCBBP+68tCJgwm68uCIVFBTA28E+GEC+GLbPFnbPPLggjDI+EMBzH8BygDJ7VQXFgA8AZIwf+BwIddJwh+VMCDXCx/ewAAB10nBIbCRf+BwATTtRNDUAfhj0gAwkW3g+CjXCwqDCbry4InbPBgAAm07gEnQ"}},"sources":{"src/test/features/ternary.tact":"Y29udHJhY3QgVGVybmFyeVRlc3RlciB7CgogICAgaW5pdCgpIHsKICAgICAgICAKICAgIH0KICAgIAogICAgcmVjZWl2ZSgpIHsKICAgICAgICAvLyBEZXBsb3kKICAgIH0KCiAgICBnZXQgZnVuIHRlc3QxKGE6IEludCk6IEludCB7CiAgICAgICAgcmV0dXJuIGEgPT0gMTIzID8gMSA6IDI7CiAgICB9CgogICAgZ2V0IGZ1biB0ZXN0MihhOiBJbnQpOiBJbnQgewogICAgICAgIHJldHVybiBhID09IDEyMyA/IGEgKiAyIDogYSAqIDM7CiAgICB9CgogICAgZ2V0IGZ1biB0ZXN0MyhhOiBJbnQsIGI6IEludCk6IEludCB7CiAgICAgICAgcmV0dXJuIGEgPT0gYiA/IDEgOiAyOwogICAgfQoKICAgIGdldCBmdW4gdGVzdDQoYTogSW50LCBiOiBJbnQpOiBJbnQgewogICAgICAgIHJldHVybiBhID09IDEyMyA/IChiID09IDQ1NiA/IDEgOiAyKSA6IChiID09IDc4OSA/IDMgOiA0KTsKICAgIH0KfQ=="},"compiler":{"name":"tact","version":"invalid","parameters":"{\"entrypoint\":\"./src/test/features/ternary.tact\",\"options\":{\"debug\":true}}"}} \ No newline at end of file diff --git a/src/test/features/output/ternary_TernaryTester.stdlib.fc b/src/test/features/output/ternary_TernaryTester.stdlib.fc new file mode 100644 index 000000000..b987818a0 --- /dev/null +++ b/src/test/features/output/ternary_TernaryTester.stdlib.fc @@ -0,0 +1,12 @@ +global (int, slice, int, slice) __tact_context; +global slice __tact_context_sender; +global cell __tact_context_sys; +global int __tact_randomized; + +slice __tact_verify_address(slice address) inline { + throw_unless(136, address.slice_bits() == 267); + var h = address.preload_uint(11); + throw_if(137, h == 1279); + throw_unless(136, h == 1024); + return address; +} \ No newline at end of file diff --git a/src/test/features/output/ternary_TernaryTester.storage.fc b/src/test/features/output/ternary_TernaryTester.storage.fc new file mode 100644 index 000000000..58d3baae1 --- /dev/null +++ b/src/test/features/output/ternary_TernaryTester.storage.fc @@ -0,0 +1,23 @@ +;; +;; Type: TernaryTester +;; + +tuple $TernaryTester$_contract_load() impure inline_ref { + slice $sc = get_data().begin_parse(); + __tact_context_sys = $sc~load_ref(); + int $loaded = $sc~load_int(1); + if ($loaded) { + return null(); + } else { + ;; Allow only workchain deployments + throw_unless(137, my_address().preload_uint(11) == 1024); + return $TernaryTester$_contract_init(); + } +} + +() $TernaryTester$_contract_store(tuple v) impure inline { + builder b = begin_cell(); + b = b.store_ref(__tact_context_sys); + b = b.store_int(true, 1); + set_data(b.end_cell()); +} \ No newline at end of file diff --git a/src/test/features/output/ternary_TernaryTester.ts b/src/test/features/output/ternary_TernaryTester.ts new file mode 100644 index 000000000..3ffd449b3 --- /dev/null +++ b/src/test/features/output/ternary_TernaryTester.ts @@ -0,0 +1,334 @@ +import { + Cell, + Slice, + Address, + Builder, + beginCell, + ComputeError, + TupleItem, + TupleReader, + Dictionary, + contractAddress, + ContractProvider, + Sender, + Contract, + ContractABI, + ABIType, + ABIGetter, + ABIReceiver, + TupleBuilder, + DictionaryValue +} from 'ton-core'; + +export type StateInit = { + $$type: 'StateInit'; + code: Cell; + data: Cell; +} + +export function storeStateInit(src: StateInit) { + return (builder: Builder) => { + let b_0 = builder; + b_0.storeRef(src.code); + b_0.storeRef(src.data); + }; +} + +export function loadStateInit(slice: Slice) { + let sc_0 = slice; + let _code = sc_0.loadRef(); + let _data = sc_0.loadRef(); + return { $$type: 'StateInit' as const, code: _code, data: _data }; +} + +function loadTupleStateInit(source: TupleReader) { + let _code = source.readCell(); + let _data = source.readCell(); + return { $$type: 'StateInit' as const, code: _code, data: _data }; +} + +function storeTupleStateInit(source: StateInit) { + let builder = new TupleBuilder(); + builder.writeCell(source.code); + builder.writeCell(source.data); + return builder.build(); +} + +function dictValueParserStateInit(): DictionaryValue { + return { + serialize: (src, buidler) => { + buidler.storeRef(beginCell().store(storeStateInit(src)).endCell()); + }, + parse: (src) => { + return loadStateInit(src.loadRef().beginParse()); + } + } +} + +export type Context = { + $$type: 'Context'; + bounced: boolean; + sender: Address; + value: bigint; + raw: Cell; +} + +export function storeContext(src: Context) { + return (builder: Builder) => { + let b_0 = builder; + b_0.storeBit(src.bounced); + b_0.storeAddress(src.sender); + b_0.storeInt(src.value, 257); + b_0.storeRef(src.raw); + }; +} + +export function loadContext(slice: Slice) { + let sc_0 = slice; + let _bounced = sc_0.loadBit(); + let _sender = sc_0.loadAddress(); + let _value = sc_0.loadIntBig(257); + let _raw = sc_0.loadRef(); + return { $$type: 'Context' as const, bounced: _bounced, sender: _sender, value: _value, raw: _raw }; +} + +function loadTupleContext(source: TupleReader) { + let _bounced = source.readBoolean(); + let _sender = source.readAddress(); + let _value = source.readBigNumber(); + let _raw = source.readCell(); + return { $$type: 'Context' as const, bounced: _bounced, sender: _sender, value: _value, raw: _raw }; +} + +function storeTupleContext(source: Context) { + let builder = new TupleBuilder(); + builder.writeBoolean(source.bounced); + builder.writeAddress(source.sender); + builder.writeNumber(source.value); + builder.writeSlice(source.raw); + return builder.build(); +} + +function dictValueParserContext(): DictionaryValue { + return { + serialize: (src, buidler) => { + buidler.storeRef(beginCell().store(storeContext(src)).endCell()); + }, + parse: (src) => { + return loadContext(src.loadRef().beginParse()); + } + } +} + +export type SendParameters = { + $$type: 'SendParameters'; + bounce: boolean; + to: Address; + value: bigint; + mode: bigint; + body: Cell | null; + code: Cell | null; + data: Cell | null; +} + +export function storeSendParameters(src: SendParameters) { + return (builder: Builder) => { + let b_0 = builder; + b_0.storeBit(src.bounce); + b_0.storeAddress(src.to); + b_0.storeInt(src.value, 257); + b_0.storeInt(src.mode, 257); + if (src.body !== null && src.body !== undefined) { b_0.storeBit(true).storeRef(src.body); } else { b_0.storeBit(false); } + if (src.code !== null && src.code !== undefined) { b_0.storeBit(true).storeRef(src.code); } else { b_0.storeBit(false); } + if (src.data !== null && src.data !== undefined) { b_0.storeBit(true).storeRef(src.data); } else { b_0.storeBit(false); } + }; +} + +export function loadSendParameters(slice: Slice) { + let sc_0 = slice; + let _bounce = sc_0.loadBit(); + let _to = sc_0.loadAddress(); + let _value = sc_0.loadIntBig(257); + let _mode = sc_0.loadIntBig(257); + let _body = sc_0.loadBit() ? sc_0.loadRef() : null; + let _code = sc_0.loadBit() ? sc_0.loadRef() : null; + let _data = sc_0.loadBit() ? sc_0.loadRef() : null; + return { $$type: 'SendParameters' as const, bounce: _bounce, to: _to, value: _value, mode: _mode, body: _body, code: _code, data: _data }; +} + +function loadTupleSendParameters(source: TupleReader) { + let _bounce = source.readBoolean(); + let _to = source.readAddress(); + let _value = source.readBigNumber(); + let _mode = source.readBigNumber(); + let _body = source.readCellOpt(); + let _code = source.readCellOpt(); + let _data = source.readCellOpt(); + return { $$type: 'SendParameters' as const, bounce: _bounce, to: _to, value: _value, mode: _mode, body: _body, code: _code, data: _data }; +} + +function storeTupleSendParameters(source: SendParameters) { + let builder = new TupleBuilder(); + builder.writeBoolean(source.bounce); + builder.writeAddress(source.to); + builder.writeNumber(source.value); + builder.writeNumber(source.mode); + builder.writeCell(source.body); + builder.writeCell(source.code); + builder.writeCell(source.data); + return builder.build(); +} + +function dictValueParserSendParameters(): DictionaryValue { + return { + serialize: (src, buidler) => { + buidler.storeRef(beginCell().store(storeSendParameters(src)).endCell()); + }, + parse: (src) => { + return loadSendParameters(src.loadRef().beginParse()); + } + } +} + + type TernaryTester_init_args = { + $$type: 'TernaryTester_init_args'; +} + +function initTernaryTester_init_args(src: TernaryTester_init_args) { + return (builder: Builder) => { + let b_0 = builder; + }; +} + +async function TernaryTester_init() { + const __code = Cell.fromBase64('te6ccgECFwEAAc8AART/APSkE/S88sgLAQIBYgIDApLQAdDTAwFxsKMB+kABINdJgQELuvLgiCDXCwoggQT/uvLQiYMJuvLgiFRQUwNvBPhhAvhi2zxZ2zzy4IIwyPhDAcx/AcoAye1UEAQCASAFBgA8AZIwf+BwIddJwh+VMCDXCx/ewAAB10nBIbCRf+BwAgEgBwgCASATFAIBIAkKAhG4IF2zxZ2zwxgQEQIRtlQbZ4A7Z4YwEAsCASAMDQAOwHuRcZFy4gIRsLD2zwB2zwxgEA4CEbC4ts8Wds8MYBAPABQgwHuSqgCSpwPiAAy6kXGRcuIBNO1E0NQB+GPSADCRbeD4KNcLCoMJuvLgids8EgAwAcB7mYEByLqRcZFy4pmBAxW6kXORdOLiAAJtALm7vRgnBc7D1dLK57HoTsOdZKhRtmgnCd1jUtK2R8syLTry398WI5gnAgVcAbgGdjlM5YOq5HJbLDgnAb1J3vlUWW8cdT094FWcMmgnCdl05as07LczoOlm2UZuikgCAUgVFgARsK+7UTQ0gABgAHWybuNDVpcGZzOi8vUW1UbTFhenZ6M3hHTmVkZ2FZeWIxbnZNWVpTMU5mOXprdkZtWUg5cUJEZzZGQ4IA=='); + const __system = Cell.fromBase64('te6cckECGQEAAdkAAQHAAQEFoEs9AgEU/wD0pBP0vPLICwMCAWIVBAIBIAoFAgEgCQYCAUgIBwB1sm7jQ1aXBmczovL1FtVG0xYXp2ejN4R05lZGdhWXliMW52TVlaUzFOZjl6a3ZGbVlIOXFCRGc2RkOCAAEbCvu1E0NIAAYAC5u70YJwXOw9XSyuex6E7DnWSoUbZoJwndY1LStkfLMi068t/fFiOYJwIFXAG4BnY5TOWDquRyWyw4JwG9Sd75VFlvHHU9PeBVnDJoJwnZdOWrNOy3M6DpZtlGbopIAgEgDQsCEbggXbPFnbPDGBcMADABwHuZgQHIupFxkXLimYEDFbqRc5F04uICASATDgIBIBEPAhGwuLbPFnbPDGAXEAAMupFxkXLiAhGwsPbPAHbPDGAXEgAUIMB7kqoAkqcD4gIRtlQbZ4A7Z4YwFxQADsB7kXGRcuICktAB0NMDAXGwowH6QAEg10mBAQu68uCIINcLCiCBBP+68tCJgwm68uCIVFBTA28E+GEC+GLbPFnbPPLggjDI+EMBzH8BygDJ7VQXFgA8AZIwf+BwIddJwh+VMCDXCx/ewAAB10nBIbCRf+BwATTtRNDUAfhj0gAwkW3g+CjXCwqDCbry4InbPBgAAm07gEnQ'); + let builder = beginCell(); + builder.storeRef(__system); + builder.storeUint(0, 1); + initTernaryTester_init_args({ $$type: 'TernaryTester_init_args' })(builder); + const __data = builder.endCell(); + return { code: __code, data: __data }; +} + +const TernaryTester_errors: { [key: number]: { message: string } } = { + 2: { message: `Stack undeflow` }, + 3: { message: `Stack overflow` }, + 4: { message: `Integer overflow` }, + 5: { message: `Integer out of expected range` }, + 6: { message: `Invalid opcode` }, + 7: { message: `Type check error` }, + 8: { message: `Cell overflow` }, + 9: { message: `Cell underflow` }, + 10: { message: `Dictionary error` }, + 13: { message: `Out of gas error` }, + 32: { message: `Method ID not found` }, + 34: { message: `Action is invalid or not supported` }, + 37: { message: `Not enough TON` }, + 38: { message: `Not enough extra-currencies` }, + 128: { message: `Null reference exception` }, + 129: { message: `Invalid serialization prefix` }, + 130: { message: `Invalid incoming message` }, + 131: { message: `Constraints error` }, + 132: { message: `Access denied` }, + 133: { message: `Contract stopped` }, + 134: { message: `Invalid argument` }, + 135: { message: `Code of a contract was not found` }, + 136: { message: `Invalid address` }, + 137: { message: `Masterchain support is not enabled for this contract` }, +} + +const TernaryTester_types: ABIType[] = [ + {"name":"StateInit","header":null,"fields":[{"name":"code","type":{"kind":"simple","type":"cell","optional":false}},{"name":"data","type":{"kind":"simple","type":"cell","optional":false}}]}, + {"name":"Context","header":null,"fields":[{"name":"bounced","type":{"kind":"simple","type":"bool","optional":false}},{"name":"sender","type":{"kind":"simple","type":"address","optional":false}},{"name":"value","type":{"kind":"simple","type":"int","optional":false,"format":257}},{"name":"raw","type":{"kind":"simple","type":"slice","optional":false}}]}, + {"name":"SendParameters","header":null,"fields":[{"name":"bounce","type":{"kind":"simple","type":"bool","optional":false}},{"name":"to","type":{"kind":"simple","type":"address","optional":false}},{"name":"value","type":{"kind":"simple","type":"int","optional":false,"format":257}},{"name":"mode","type":{"kind":"simple","type":"int","optional":false,"format":257}},{"name":"body","type":{"kind":"simple","type":"cell","optional":true}},{"name":"code","type":{"kind":"simple","type":"cell","optional":true}},{"name":"data","type":{"kind":"simple","type":"cell","optional":true}}]}, +] + +const TernaryTester_getters: ABIGetter[] = [ + {"name":"test1","arguments":[{"name":"a","type":{"kind":"simple","type":"int","optional":false,"format":257}}],"returnType":{"kind":"simple","type":"int","optional":false,"format":257}}, + {"name":"test2","arguments":[{"name":"a","type":{"kind":"simple","type":"int","optional":false,"format":257}}],"returnType":{"kind":"simple","type":"int","optional":false,"format":257}}, + {"name":"test3","arguments":[{"name":"a","type":{"kind":"simple","type":"int","optional":false,"format":257}},{"name":"b","type":{"kind":"simple","type":"int","optional":false,"format":257}}],"returnType":{"kind":"simple","type":"int","optional":false,"format":257}}, + {"name":"test4","arguments":[{"name":"a","type":{"kind":"simple","type":"int","optional":false,"format":257}},{"name":"b","type":{"kind":"simple","type":"int","optional":false,"format":257}}],"returnType":{"kind":"simple","type":"int","optional":false,"format":257}}, +] + +const TernaryTester_receivers: ABIReceiver[] = [ + {"receiver":"internal","message":{"kind":"empty"}}, +] + +export class TernaryTester implements Contract { + + static async init() { + return await TernaryTester_init(); + } + + static async fromInit() { + const init = await TernaryTester_init(); + const address = contractAddress(0, init); + return new TernaryTester(address, init); + } + + static fromAddress(address: Address) { + return new TernaryTester(address); + } + + readonly address: Address; + readonly init?: { code: Cell, data: Cell }; + readonly abi: ContractABI = { + types: TernaryTester_types, + getters: TernaryTester_getters, + receivers: TernaryTester_receivers, + errors: TernaryTester_errors, + }; + + private constructor(address: Address, init?: { code: Cell, data: Cell }) { + this.address = address; + this.init = init; + } + + async send(provider: ContractProvider, via: Sender, args: { value: bigint, bounce?: boolean| null | undefined }, message: null) { + + let body: Cell | null = null; + if (message === null) { + body = new Cell(); + } + if (body === null) { throw new Error('Invalid message type'); } + + await provider.internal(via, { ...args, body: body }); + + } + + async getTest1(provider: ContractProvider, a: bigint) { + let builder = new TupleBuilder(); + builder.writeNumber(a); + let source = (await provider.get('test1', builder.build())).stack; + let result = source.readBigNumber(); + return result; + } + + async getTest2(provider: ContractProvider, a: bigint) { + let builder = new TupleBuilder(); + builder.writeNumber(a); + let source = (await provider.get('test2', builder.build())).stack; + let result = source.readBigNumber(); + return result; + } + + async getTest3(provider: ContractProvider, a: bigint, b: bigint) { + let builder = new TupleBuilder(); + builder.writeNumber(a); + builder.writeNumber(b); + let source = (await provider.get('test3', builder.build())).stack; + let result = source.readBigNumber(); + return result; + } + + async getTest4(provider: ContractProvider, a: bigint, b: bigint) { + let builder = new TupleBuilder(); + builder.writeNumber(a); + builder.writeNumber(b); + let source = (await provider.get('test4', builder.build())).stack; + let result = source.readBigNumber(); + return result; + } + +} \ No newline at end of file diff --git a/src/test/features/ternary.tact b/src/test/features/ternary.tact new file mode 100644 index 000000000..075cd88d4 --- /dev/null +++ b/src/test/features/ternary.tact @@ -0,0 +1,26 @@ +contract TernaryTester { + + init() { + + } + + receive() { + // Deploy + } + + get fun test1(a: Int): Int { + return a == 123 ? 1 : 2; + } + + get fun test2(a: Int): Int { + return a == 123 ? a * 2 : a * 3; + } + + get fun test3(a: Int, b: Int): Int { + return a == b ? 1 : 2; + } + + get fun test4(a: Int, b: Int): Int { + return a == 123 ? (b == 456 ? 1 : 2) : (b == 789 ? 3 : 4); + } +} \ No newline at end of file diff --git a/tact.config.json b/tact.config.json index 5908e1820..d1a900ac5 100644 --- a/tact.config.json +++ b/tact.config.json @@ -221,6 +221,14 @@ "masterchain": true } }, + { + "name": "ternary", + "path": "./src/test/features/ternary.tact", + "output": "./src/test/features/output", + "options": { + "debug": true + } + }, { "name": "benchmark_functions", "path": "./src/benchmarks/contracts/functions.tact",