mirror of
https://github.com/ton-blockchain/ton
synced 2025-02-13 03:32:22 +00:00
Lots of changes, actually. Most noticeable are: - traditional //comments - #include -> import - a rule "import what you use" - ~ found -> !found (for -1/0) - null() -> null - is_null?(v) -> v == null - throw is a keyword - catch with swapped arguments - throw_if, throw_unless -> assert - do until -> do while - elseif -> else if - drop ifnot, elseifnot - drop rarely used operators A testing framework also appears here. All tests existed earlier, but due to significant syntax changes, their history is useless.
1655 lines
46 KiB
Text
1655 lines
46 KiB
Text
library TVM_Asm
|
|
// simple TVM Assembler
|
|
namespace Asm
|
|
Asm definitions
|
|
"0.4.5" constant asm-fif-version
|
|
|
|
variable @atend
|
|
variable @was-split
|
|
false @was-split !
|
|
{ "not in asm context" abort } @atend !
|
|
{ `normal eq? not abort"must be terminated by }>" } : @normal?
|
|
{ context@ @atend @ 2 { @atend ! context! @normal? } does @atend ! } : @pushatend
|
|
{ @pushatend Asm <b } : <{
|
|
{ @atend @ execute } : @endblk
|
|
{ false @was-split ! `normal @endblk } : }>
|
|
{ }> b> } : }>c
|
|
{ }>c <s } : }>s
|
|
{ @atend @ 2 { true @was-split ! @atend ! rot b> ref, swap @endblk } does @atend ! <b } : @|
|
|
{ @atend @ 3 { @atend ! 2swap rot execute } does @atend ! <b } : @doafter<{
|
|
{ over brembits <= } : @havebits
|
|
{ rot + -rot + swap } : pair+
|
|
{ rot >= -rot <= and } : 2x<=
|
|
{ 2 pick brembitrefs 1- 2x<= } : @havebitrefs
|
|
{ @havebits ' @| ifnot } : @ensurebits
|
|
{ @havebitrefs ' @| ifnot } : @ensurebitrefs
|
|
{ rot over @ensurebits -rot u, } : @simpleuop
|
|
{ tuck sbitrefs @ensurebitrefs swap s, } : @addop
|
|
{ tuck bbitrefs @ensurebitrefs swap b+ } : @addopb
|
|
' @addopb : @inline
|
|
{ 1 ' @addop does create } : @Defop
|
|
{ 1 { <b swap s, swap 8 u, @addopb } does create } : @Defop(8u)
|
|
{ 1 { <b swap s, swap 8 i, @addopb } does create } : @Defop(8i)
|
|
{ 1 { <b swap s, swap 1- 8 u, @addopb } does create } : @Defop(8u+1)
|
|
{ 1 { <b swap s, swap 4 u, @addopb } does create } : @Defop(4u)
|
|
{ 1 { <b swap s, swap 12 u, @addopb } does create } : @Defop(12u)
|
|
{ 1 { <b swap s, rot 4 u, swap 4 u, @addopb } does create } : @Defop(4u,4u)
|
|
{ 1 { <b swap s, swap ref, @addopb } does create } : @Defop(ref)
|
|
{ 1 { <b swap s, rot ref, swap ref, @addopb } does create } : @Defop(ref*2)
|
|
{ <b 0xef 8 u, swap 12 i, b> } : si()
|
|
// x mi ma -- ?
|
|
{ rot tuck >= -rot <= and } : @range
|
|
{ rot tuck < -rot > or } : @-range
|
|
{ @-range abort"Out of range" } : @rangechk
|
|
{ dup 0 < over 255 > or abort"Invalid stack register number" si() } : s()
|
|
{ si() constant } : @Sreg
|
|
-2 @Sreg s(-2)
|
|
-1 @Sreg s(-1)
|
|
0 @Sreg s0
|
|
1 @Sreg s1
|
|
2 @Sreg s2
|
|
3 @Sreg s3
|
|
4 @Sreg s4
|
|
5 @Sreg s5
|
|
6 @Sreg s6
|
|
7 @Sreg s7
|
|
8 @Sreg s8
|
|
9 @Sreg s9
|
|
10 @Sreg s10
|
|
11 @Sreg s11
|
|
12 @Sreg s12
|
|
13 @Sreg s13
|
|
14 @Sreg s14
|
|
15 @Sreg s15
|
|
{ dup 0 < over 7 > or abort"Invalid control register number" <b 0xcc 8 u, swap 4 u, b> } : c()
|
|
{ c() constant } : @Creg
|
|
0 @Creg c0
|
|
1 @Creg c1
|
|
2 @Creg c2
|
|
3 @Creg c3
|
|
4 @Creg c4
|
|
5 @Creg c5
|
|
7 @Creg c7
|
|
{ <s 8 u@+ swap 0xef <> abort"not a stack register" 12 i@+ s> } : @bigsridx
|
|
{ @bigsridx dup 16 >= over 0< or abort"stack register s0..s15 expected" } : @sridx
|
|
{ rot @bigsridx tuck < -rot tuck > rot or abort"stack register out of range" } : @sridxrange
|
|
{ swap @bigsridx + dup 16 >= over 0< or abort"stack register out of range" } : @sridx+
|
|
{ <s 8 u@+ 4 u@+ s> swap 0xcc <> over 7 > or over 6 = or abort"not a control register c0..c5 or c7" } : @cridx
|
|
{ <s 8 u@ 0xcc = } : @iscr?
|
|
{ <b swap s, 1 { swap @sridx 4 u, @addopb } does create } : @Defop(s)
|
|
{ <b swap s, 1 { rot @sridx 4 u, swap @sridx 4 u, @addopb } does create } : @Defop(s,s)
|
|
{ <b swap s, 1 { swap @cridx 4 u, @addopb } does create } : @Defop(c)
|
|
//
|
|
// stack manipulation primitives
|
|
// (simple stack primitives)
|
|
//
|
|
x{00} @Defop NOP
|
|
x{01} @Defop SWAP
|
|
x{0} @Defop(s) XCHG0
|
|
{ @bigsridx swap @bigsridx 2dup =
|
|
{ 2drop <b }
|
|
{ 2dup < { swap } if dup 0=
|
|
{ drop dup 16 <
|
|
{ <b x{0} s, swap 4 u, }
|
|
{ <b x{11} s, swap 8 u, }
|
|
cond
|
|
}
|
|
{ over 16 >=
|
|
{ tuck 16 >=
|
|
{ <b x{11} s, 2 pick 8 u, x{11} s, swap 8 u, x{11} s, swap 8 u, }
|
|
{ <b x{0} s, 2 pick 4 u, x{11} s, swap 8 u, x{0} s, swap 4 u, } cond
|
|
}
|
|
{ dup 1 =
|
|
{ drop <b x{1} s, swap 4 u, }
|
|
{ <b x{10} s, swap 4 u, swap 4 u, }
|
|
cond
|
|
} cond
|
|
} cond
|
|
} cond
|
|
@addopb } : XCHG
|
|
x{ED4} @Defop(c) PUSHCTR
|
|
x{ED5} @Defop(c) POPCTR
|
|
{ dup @iscr?
|
|
' PUSHCTR
|
|
{ @bigsridx dup 16 <
|
|
{ <b x{2} s, swap 4 u, }
|
|
{ <b x{56} s, swap 8 u,
|
|
} cond
|
|
@addopb
|
|
} cond
|
|
} : PUSH
|
|
x{20} @Defop DUP
|
|
x{21} @Defop OVER
|
|
{ dup @iscr?
|
|
' POPCTR
|
|
{ @bigsridx dup 16 <
|
|
{ <b x{3} s, swap 4 u, }
|
|
{ <b x{57} s, swap 8 u,
|
|
} cond
|
|
@addopb
|
|
} cond
|
|
} : POP
|
|
x{30} @Defop DROP
|
|
x{31} @Defop NIP
|
|
|
|
// compound stack primitives
|
|
{ @sridx rot @sridx rot @sridx swap <b x{4} s, swap 4 u, swap 4 u, swap 4 u, @addopb } : XCHG3
|
|
x{50} @Defop(s,s) XCHG2
|
|
x{51} @Defop(s,s) XCPU
|
|
{ <b x{52} s, rot @sridx 4 u, swap 1 @sridx+ 4 u, @addopb } : PUXC
|
|
x{53} @Defop(s,s) PUSH2
|
|
{ @sridx rot @sridx rot @sridx swap <b x{540} s, swap 4 u, swap 4 u, swap 4 u, @addopb } : XCHG3_l
|
|
{ @sridx rot @sridx rot @sridx swap <b x{541} s, swap 4 u, swap 4 u, swap 4 u, @addopb } : XC2PU
|
|
{ 1 @sridx+ rot @sridx rot @sridx swap <b x{542} s, swap 4 u, swap 4 u, swap 4 u, @addopb } : XCPUXC
|
|
{ @sridx rot @sridx rot @sridx swap <b x{543} s, swap 4 u, swap 4 u, swap 4 u, @addopb } : XCPU2
|
|
{ 1 @sridx+ rot @sridx rot 1 @sridx+ swap <b x{544} s, swap 4 u, swap 4 u, swap 4 u, @addopb } : PUXC2
|
|
{ 1 @sridx+ rot @sridx rot 1 @sridx+ swap <b x{545} s, swap 4 u, swap 4 u, swap 4 u, @addopb } : PUXCPU
|
|
{ 2 @sridx+ rot @sridx rot 1 @sridx+ swap <b x{546} s, swap 4 u, swap 4 u, swap 4 u, @addopb } : PU2XC
|
|
{ @sridx rot @sridx rot @sridx swap <b x{547} s, swap 4 u, swap 4 u, swap 4 u, @addopb } : PUSH3
|
|
{ <b x{55} s, rot 1- 4 u, swap 1- 4 u, @addopb } : BLKSWAP
|
|
{ dup { 1 swap BLKSWAP } { drop } cond } : ROLL
|
|
{ dup { 1 BLKSWAP } { drop } cond } dup : -ROLL : ROLLREV
|
|
x{5513} dup @Defop 2ROT @Defop ROT2
|
|
|
|
// exotic stack primitives
|
|
x{58} @Defop ROT
|
|
x{59} dup @Defop -ROT @Defop ROTREV
|
|
x{5A} dup @Defop 2SWAP @Defop SWAP2
|
|
x{5B} dup @Defop 2DROP @Defop DROP2
|
|
x{5C} dup @Defop 2DUP @Defop DUP2
|
|
x{5D} dup @Defop 2OVER @Defop OVER2
|
|
{ <b x{5E} s, rot 2 - 4 u, swap 4 u, @addopb } : REVERSE
|
|
{ <b x{5F0} s, swap 4 u, @addopb } : BLKDROP
|
|
{ over 0= abort"first argument must be non-zero"
|
|
<b x{5F} s, rot 4 u, swap 4 u, @addopb } : BLKPUSH
|
|
x{60} dup @Defop PICK @Defop PUSHX
|
|
x{61} @Defop ROLLX
|
|
x{62} dup @Defop -ROLLX @Defop ROLLREVX
|
|
x{63} @Defop BLKSWX
|
|
x{64} @Defop REVX
|
|
x{65} @Defop DROPX
|
|
x{66} @Defop TUCK
|
|
x{67} @Defop XCHGX
|
|
x{68} @Defop DEPTH
|
|
x{69} @Defop CHKDEPTH
|
|
x{6A} @Defop ONLYTOPX
|
|
x{6B} @Defop ONLYX
|
|
{ over 0= abort"first argument must be non-zero"
|
|
<b x{6C} s, rot 4 u, swap 4 u, @addopb } : BLKDROP2
|
|
|
|
// null primitives
|
|
x{6D} dup @Defop NULL @Defop PUSHNULL
|
|
x{6E} @Defop ISNULL
|
|
// tuple primitives
|
|
x{6F0} @Defop(4u) TUPLE
|
|
x{6F00} @Defop NIL
|
|
x{6F01} @Defop SINGLE
|
|
x{6F02} dup @Defop PAIR @Defop CONS
|
|
x{6F03} @Defop TRIPLE
|
|
x{6F1} @Defop(4u) INDEX
|
|
x{6F10} dup @Defop FIRST @Defop CAR
|
|
x{6F11} dup @Defop SECOND @Defop CDR
|
|
x{6F12} @Defop THIRD
|
|
x{6F2} @Defop(4u) UNTUPLE
|
|
x{6F21} @Defop UNSINGLE
|
|
x{6F22} dup @Defop UNPAIR @Defop UNCONS
|
|
x{6F23} @Defop UNTRIPLE
|
|
x{6F3} @Defop(4u) UNPACKFIRST
|
|
x{6F30} @Defop CHKTUPLE
|
|
x{6F4} @Defop(4u) EXPLODE
|
|
x{6F5} @Defop(4u) SETINDEX
|
|
x{6F50} @Defop SETFIRST
|
|
x{6F51} @Defop SETSECOND
|
|
x{6F52} @Defop SETTHIRD
|
|
x{6F6} @Defop(4u) INDEXQ
|
|
x{6F60} dup @Defop FIRSTQ @Defop CARQ
|
|
x{6F61} dup @Defop SECONDQ @Defop CDRQ
|
|
x{6F62} @Defop THIRDQ
|
|
x{6F7} @Defop(4u) SETINDEXQ
|
|
x{6F70} @Defop SETFIRSTQ
|
|
x{6F71} @Defop SETSECONDQ
|
|
x{6F72} @Defop SETTHIRDQ
|
|
x{6F80} @Defop TUPLEVAR
|
|
x{6F81} @Defop INDEXVAR
|
|
x{6F82} @Defop UNTUPLEVAR
|
|
x{6F83} @Defop UNPACKFIRSTVAR
|
|
x{6F84} @Defop EXPLODEVAR
|
|
x{6F85} @Defop SETINDEXVAR
|
|
x{6F86} @Defop INDEXVARQ
|
|
x{6F87} @Defop SETINDEXVARQ
|
|
x{6F88} @Defop TLEN
|
|
x{6F89} @Defop QTLEN
|
|
x{6F8A} @Defop ISTUPLE
|
|
x{6F8B} @Defop LAST
|
|
x{6F8C} dup @Defop TPUSH @Defop COMMA
|
|
x{6F8D} @Defop TPOP
|
|
x{6FA0} @Defop NULLSWAPIF
|
|
x{6FA1} @Defop NULLSWAPIFNOT
|
|
x{6FA2} @Defop NULLROTRIF
|
|
x{6FA3} @Defop NULLROTRIFNOT
|
|
x{6FA4} @Defop NULLSWAPIF2
|
|
x{6FA5} @Defop NULLSWAPIFNOT2
|
|
x{6FA6} @Defop NULLROTRIF2
|
|
x{6FA7} @Defop NULLROTRIFNOT2
|
|
{ <b x{6FB} s, rot 2 u, swap 2 u, @addopb } : INDEX2
|
|
x{6FB4} @Defop CADR
|
|
x{6FB5} @Defop CDDR
|
|
{ <b x{6FE_} s, 3 roll 2 u, rot 2 u, swap 2 u, @addopb } : INDEX3
|
|
x{6FD4} @Defop CADDR
|
|
x{6FD5} @Defop CDDDR
|
|
|
|
// integer constants
|
|
x{70} dup @Defop ZERO @Defop FALSE
|
|
x{71} @Defop ONE
|
|
x{72} @Defop TWO
|
|
x{7A} @Defop TEN
|
|
x{7F} @Defop TRUE
|
|
{ dup 10 <= over -5 >= and
|
|
{ 15 and <b x{7} s, swap 4 u, }
|
|
{ dup 8 fits
|
|
{ <b x{80} s, swap 8 i, }
|
|
{ dup 16 fits
|
|
{ <b x{81} s, swap 16 i, }
|
|
{ 11 { dup 259 > abort"integer too large" 8 + 2dup fits } until
|
|
<b x{82} s, over 3 >> 2- 5 u, -rot i,
|
|
} cond
|
|
} cond
|
|
} cond
|
|
@addopb } dup : PUSHINT : INT
|
|
{ dup 256 = abort"use PUSHNAN instead of 256 PUSHPOW2" <b x{83} s, swap 1- 8 u, @addopb } : PUSHPOW2
|
|
x{83FF} @Defop PUSHNAN
|
|
{ <b x{84} s, swap 1- 8 u, @addopb } : PUSHPOW2DEC
|
|
{ <b x{85} s, swap 1- 8 u, @addopb } : PUSHNEGPOW2
|
|
//
|
|
// other constants
|
|
x{88} @Defop(ref) PUSHREF
|
|
x{89} @Defop(ref) PUSHREFSLICE
|
|
x{8A} @Defop(ref) PUSHREFCONT
|
|
{ 1- dup 0< over 8 >= or abort"invalid slice padding"
|
|
swap 1 1 u, 0 rot u, } : @scomplete
|
|
{ tuck sbitrefs swap 26 + swap @havebitrefs not
|
|
{ <b rot s, b> PUSHREFSLICE }
|
|
{ over sbitrefs 2dup 123 0 2x<=
|
|
{ drop tuck 4 + 3 >> swap x{8B} s, over 4 u, 3 roll s,
|
|
-rot 3 << 4 + swap - @scomplete }
|
|
{ 2dup 1 >= swap 248 <= and
|
|
{ rot x{8C} s, swap 1- 2 u, over 7 + 3 >> tuck 5 u, 3 roll s,
|
|
-rot 3 << 1 + swap - @scomplete }
|
|
{ rot x{8D} s, swap 3 u, over 2 + 3 >> tuck 7 u, 3 roll s,
|
|
-rot 3 << 6 + swap - @scomplete
|
|
} cond
|
|
} cond
|
|
} cond
|
|
} dup : PUSHSLICE : SLICE
|
|
// ( b' -- ? )
|
|
{ bbitrefs or 0= } : @cont-empty?
|
|
{ bbits 7 and 0= } : @cont-aligned?
|
|
// ( b b' -- ? )
|
|
{ bbitrefs over 7 and { 2drop drop false } {
|
|
swap 16 + swap @havebitrefs nip
|
|
} cond
|
|
} : @cont-fits?
|
|
// ( b b' -- ? )
|
|
{ bbitrefs over 7 and { 2drop drop false } {
|
|
32 1 pair+ @havebitrefs nip
|
|
} cond
|
|
} : @cont-ref-fit?
|
|
// ( b b' b'' -- ? )
|
|
{ over @cont-aligned? over @cont-aligned? and not { 2drop drop false } {
|
|
bbitrefs rot bbitrefs pair+ swap 32 + swap @havebitrefs nip
|
|
} cond
|
|
} : @two-cont-fit?
|
|
{ 2dup @cont-fits? not
|
|
{ b> PUSHREFCONT }
|
|
{ swap over bbitrefs 2dup 120 0 2x<=
|
|
{ drop swap x{9} s, swap 3 >> 4 u, swap b+ }
|
|
{ rot x{8F_} s, swap 2 u, swap 3 >> 7 u, swap b+ } cond
|
|
} cond
|
|
} dup : PUSHCONT : CONT
|
|
{ }> PUSHCONT } : }>CONT
|
|
{ { @normal? PUSHCONT } @doafter<{ } : CONT:<{
|
|
|
|
// arithmetic operations
|
|
{ 2 { rot dup 8 fits
|
|
{ nip <b rot s, swap 8 i, }
|
|
{ rot drop <b swap PUSHINT swap s, }
|
|
cond @addopb
|
|
} does create
|
|
} : @Defop(8i,alt)
|
|
x{A0} @Defop ADD
|
|
x{A1} @Defop SUB
|
|
x{A2} @Defop SUBR
|
|
x{A3} @Defop NEGATE
|
|
x{A4} @Defop INC
|
|
x{A5} @Defop DEC
|
|
x{A6} x{A0} @Defop(8i,alt) ADDCONST
|
|
{ negate ADDCONST } : SUBCONST
|
|
x{A7} x{A8} @Defop(8i,alt) MULCONST
|
|
' ADDCONST : ADDINT
|
|
' SUBCONST : SUBINT
|
|
' MULCONST : MULINT
|
|
x{A8} @Defop MUL
|
|
|
|
x{A904} @Defop DIV
|
|
x{A905} @Defop DIVR
|
|
x{A906} @Defop DIVC
|
|
x{A908} @Defop MOD
|
|
x{A909} @Defop MODR
|
|
x{A90A} @Defop MODC
|
|
x{A90C} @Defop DIVMOD
|
|
x{A90D} @Defop DIVMODR
|
|
x{A90E} @Defop DIVMODC
|
|
x{A900} @Defop ADDDIVMOD
|
|
x{A901} @Defop ADDDIVMODR
|
|
x{A902} @Defop ADDDIVMODC
|
|
|
|
x{A925} @Defop RSHIFTR
|
|
x{A926} @Defop RSHIFTC
|
|
x{A928} @Defop MODPOW2
|
|
x{A929} @Defop MODPOW2R
|
|
x{A92A} @Defop MODPOW2C
|
|
x{A92C} @Defop RSHIFTMOD
|
|
x{A92D} @Defop RSHIFTMODR
|
|
x{A92E} @Defop RSHIFTMODC
|
|
x{A920} @Defop ADDRSHIFTMOD
|
|
x{A921} @Defop ADDRSHIFTMODR
|
|
x{A922} @Defop ADDRSHIFTMODC
|
|
|
|
x{A935} @Defop(8u+1) RSHIFTR#
|
|
x{A936} @Defop(8u+1) RSHIFTC#
|
|
x{A938} @Defop(8u+1) MODPOW2#
|
|
x{A939} @Defop(8u+1) MODPOW2R#
|
|
x{A93A} @Defop(8u+1) MODPOW2C#
|
|
x{A93C} @Defop(8u+1) RSHIFT#MOD
|
|
x{A93D} @Defop(8u+1) RSHIFTR#MOD
|
|
x{A93E} @Defop(8u+1) RSHIFTC#MOD
|
|
x{A930} @Defop(8u+1) ADDRSHIFT#MOD
|
|
x{A931} @Defop(8u+1) ADDRSHIFTR#MOD
|
|
x{A932} @Defop(8u+1) ADDRSHIFTC#MOD
|
|
|
|
x{A984} @Defop MULDIV
|
|
x{A985} @Defop MULDIVR
|
|
x{A986} @Defop MULDIVC
|
|
x{A988} @Defop MULMOD
|
|
x{A989} @Defop MULMODR
|
|
x{A98A} @Defop MULMODC
|
|
x{A98C} @Defop MULDIVMOD
|
|
x{A98D} @Defop MULDIVMODR
|
|
x{A98E} @Defop MULDIVMODC
|
|
x{A980} @Defop MULADDDIVMOD
|
|
x{A981} @Defop MULADDDIVMODR
|
|
x{A982} @Defop MULADDDIVMODC
|
|
|
|
x{A9A4} @Defop MULRSHIFT
|
|
x{A9A5} @Defop MULRSHIFTR
|
|
x{A9A6} @Defop MULRSHIFTC
|
|
x{A9A8} @Defop MULMODPOW2
|
|
x{A9A9} @Defop MULMODPOW2R
|
|
x{A9AA} @Defop MULMODPOW2C
|
|
x{A9AC} @Defop MULRSHIFTMOD
|
|
x{A9AD} @Defop MULRSHIFTRMOD
|
|
x{A9AE} @Defop MULRSHIFTCMOD
|
|
x{A9A0} @Defop MULADDRSHIFTMOD
|
|
x{A9A1} @Defop MULADDRSHIFTRMOD
|
|
x{A9A2} @Defop MULADDRSHIFTCMOD
|
|
|
|
x{A9B4} @Defop(8u+1) MULRSHIFT#
|
|
x{A9B5} @Defop(8u+1) MULRSHIFTR#
|
|
x{A9B6} @Defop(8u+1) MULRSHIFTC#
|
|
x{A9B8} @Defop(8u+1) MULMODPOW2#
|
|
x{A9B9} @Defop(8u+1) MULMODPOW2R#
|
|
x{A9BA} @Defop(8u+1) MULMODPOW2C#
|
|
x{A9BC} @Defop(8u+1) MULRSHIFT#MOD
|
|
x{A9BD} @Defop(8u+1) MULRSHIFTR#MOD
|
|
x{A9BE} @Defop(8u+1) MULRSHIFTC#MOD
|
|
x{A9B0} @Defop(8u+1) MULADDRSHIFT#MOD
|
|
x{A9B1} @Defop(8u+1) MULADDRSHIFTR#MOD
|
|
x{A9B2} @Defop(8u+1) MULADDRSHIFTC#MOD
|
|
|
|
x{A9C4} @Defop LSHIFTDIV
|
|
x{A9C5} @Defop LSHIFTDIVR
|
|
x{A9C6} @Defop LSHIFTDIVC
|
|
x{A9C8} @Defop LSHIFTMOD
|
|
x{A9C9} @Defop LSHIFTMODR
|
|
x{A9CA} @Defop LSHIFTMODC
|
|
x{A9CC} @Defop LSHIFTDIVMOD
|
|
x{A9CD} @Defop LSHIFTDIVMODR
|
|
x{A9CE} @Defop LSHIFTDIVMODC
|
|
x{A9C0} @Defop LSHIFTADDDIVMOD
|
|
x{A9C1} @Defop LSHIFTADDDIVMODR
|
|
x{A9C2} @Defop LSHIFTADDDIVMODC
|
|
|
|
x{A9D4} @Defop(8u+1) LSHIFT#DIV
|
|
x{A9D5} @Defop(8u+1) LSHIFT#DIVR
|
|
x{A9D6} @Defop(8u+1) LSHIFT#DIVC
|
|
x{A9D8} @Defop(8u+1) LSHIFT#MOD
|
|
x{A9D9} @Defop(8u+1) LSHIFT#MODR
|
|
x{A9DA} @Defop(8u+1) LSHIFT#MODC
|
|
x{A9DC} @Defop(8u+1) LSHIFT#DIVMOD
|
|
x{A9DD} @Defop(8u+1) LSHIFT#DIVMODR
|
|
x{A9DE} @Defop(8u+1) LSHIFT#DIVMODC
|
|
x{A9D0} @Defop(8u+1) LSHIFT#ADDDIVMOD
|
|
x{A9D1} @Defop(8u+1) LSHIFT#ADDDIVMODR
|
|
x{A9D2} @Defop(8u+1) LSHIFT#ADDDIVMODC
|
|
|
|
x{AA} @Defop(8u+1) LSHIFT#
|
|
x{AB} @Defop(8u+1) RSHIFT#
|
|
x{AC} @Defop LSHIFT
|
|
x{AD} @Defop RSHIFT
|
|
x{AE} @Defop POW2
|
|
x{B0} @Defop AND
|
|
x{B1} @Defop OR
|
|
x{B2} @Defop XOR
|
|
x{B3} @Defop NOT
|
|
x{B4} @Defop(8u+1) FITS
|
|
x{B400} @Defop CHKBOOL
|
|
x{B5} @Defop(8u+1) UFITS
|
|
x{B500} @Defop CHKBIT
|
|
x{B600} @Defop FITSX
|
|
x{B601} @Defop UFITSX
|
|
x{B602} @Defop BITSIZE
|
|
x{B603} @Defop UBITSIZE
|
|
x{B608} @Defop MIN
|
|
x{B609} @Defop MAX
|
|
x{B60A} dup @Defop MINMAX @Defop INTSORT2
|
|
x{B60B} @Defop ABS
|
|
x{B7} @Defop QUIET
|
|
x{B7A0} @Defop QADD
|
|
x{B7A1} @Defop QSUB
|
|
x{B7A2} @Defop QSUBR
|
|
x{B7A3} @Defop QNEGATE
|
|
x{B7A4} @Defop QINC
|
|
x{B7A5} @Defop QDEC
|
|
x{B7A8} @Defop QMUL
|
|
|
|
x{B7A904} @Defop QDIV
|
|
x{B7A905} @Defop QDIVR
|
|
x{B7A906} @Defop QDIVC
|
|
x{B7A908} @Defop QMOD
|
|
x{B7A909} @Defop QMODR
|
|
x{B7A90A} @Defop QMODC
|
|
x{B7A90C} @Defop QDIVMOD
|
|
x{B7A90D} @Defop QDIVMODR
|
|
x{B7A90E} @Defop QDIVMODC
|
|
x{B7A900} @Defop QADDDIVMOD
|
|
x{B7A901} @Defop QADDDIVMODR
|
|
x{B7A902} @Defop QADDDIVMODC
|
|
|
|
x{B7A925} @Defop QRSHIFTR
|
|
x{B7A926} @Defop QRSHIFTC
|
|
x{B7A928} @Defop QMODPOW2
|
|
x{B7A929} @Defop QMODPOW2R
|
|
x{B7A92A} @Defop QMODPOW2C
|
|
x{B7A92C} @Defop QRSHIFTMOD
|
|
x{B7A92D} @Defop QRSHIFTMODR
|
|
x{B7A92E} @Defop QRSHIFTMODC
|
|
x{B7A920} @Defop QADDRSHIFTMOD
|
|
x{B7A921} @Defop QADDRSHIFTMODR
|
|
x{B7A922} @Defop QADDRSHIFTMODC
|
|
|
|
x{B7A935} @Defop(8u+1) QRSHIFTR#
|
|
x{B7A936} @Defop(8u+1) QRSHIFTC#
|
|
x{B7A938} @Defop(8u+1) QMODPOW2#
|
|
x{B7A939} @Defop(8u+1) QMODPOW2R#
|
|
x{B7A93A} @Defop(8u+1) QMODPOW2C#
|
|
x{B7A93C} @Defop(8u+1) QRSHIFT#MOD
|
|
x{B7A93D} @Defop(8u+1) QRSHIFTR#MOD
|
|
x{B7A93E} @Defop(8u+1) QRSHIFTC#MOD
|
|
x{B7A930} @Defop(8u+1) QADDRSHIFT#MOD
|
|
x{B7A931} @Defop(8u+1) QADDRSHIFTR#MOD
|
|
x{B7A932} @Defop(8u+1) QADDRSHIFTC#MOD
|
|
|
|
x{B7A984} @Defop QMULDIV
|
|
x{B7A985} @Defop QMULDIVR
|
|
x{B7A986} @Defop QMULDIVC
|
|
x{B7A988} @Defop QMULMOD
|
|
x{B7A989} @Defop QMULMODR
|
|
x{B7A98A} @Defop QMULMODC
|
|
x{B7A98C} @Defop QMULDIVMOD
|
|
x{B7A98D} @Defop QMULDIVMODR
|
|
x{B7A98E} @Defop QMULDIVMODC
|
|
x{B7A980} @Defop QMULADDDIVMOD
|
|
x{B7A981} @Defop QMULADDDIVMODR
|
|
x{B7A982} @Defop QMULADDDIVMODC
|
|
|
|
x{B7A9A4} @Defop QMULRSHIFT
|
|
x{B7A9A5} @Defop QMULRSHIFTR
|
|
x{B7A9A6} @Defop QMULRSHIFTC
|
|
x{B7A9A8} @Defop QMULMODPOW2
|
|
x{B7A9A9} @Defop QMULMODPOW2R
|
|
x{B7A9AA} @Defop QMULMODPOW2C
|
|
x{B7A9AC} @Defop QMULRSHIFTMOD
|
|
x{B7A9AD} @Defop QMULRSHIFTRMOD
|
|
x{B7A9AE} @Defop QMULRSHIFTCMOD
|
|
x{B7A9A0} @Defop QMULADDRSHIFTMOD
|
|
x{B7A9A1} @Defop QMULADDRSHIFTRMOD
|
|
x{B7A9A2} @Defop QMULADDRSHIFTCMOD
|
|
|
|
x{B7A9B4} @Defop(8u+1) QMULRSHIFT#
|
|
x{B7A9B5} @Defop(8u+1) QMULRSHIFTR#
|
|
x{B7A9B6} @Defop(8u+1) QMULRSHIFTC#
|
|
x{B7A9B8} @Defop(8u+1) QMULMODPOW2#
|
|
x{B7A9B9} @Defop(8u+1) QMULMODPOW2R#
|
|
x{B7A9BA} @Defop(8u+1) QMULMODPOW2C#
|
|
x{B7A9BC} @Defop(8u+1) QMULRSHIFT#MOD
|
|
x{B7A9BD} @Defop(8u+1) QMULRSHIFTR#MOD
|
|
x{B7A9BE} @Defop(8u+1) QMULRSHIFTC#MOD
|
|
x{B7A9B0} @Defop(8u+1) QMULADDRSHIFT#MOD
|
|
x{B7A9B1} @Defop(8u+1) QMULADDRSHIFTR#MOD
|
|
x{B7A9B2} @Defop(8u+1) QMULADDRSHIFTC#MOD
|
|
|
|
x{B7A9C4} @Defop QLSHIFTDIV
|
|
x{B7A9C5} @Defop QLSHIFTDIVR
|
|
x{B7A9C6} @Defop QLSHIFTDIVC
|
|
x{B7A9C8} @Defop QLSHIFTMOD
|
|
x{B7A9C9} @Defop QLSHIFTMODR
|
|
x{B7A9CA} @Defop QLSHIFTMODC
|
|
x{B7A9CC} @Defop QLSHIFTDIVMOD
|
|
x{B7A9CD} @Defop QLSHIFTDIVMODR
|
|
x{B7A9CE} @Defop QLSHIFTDIVMODC
|
|
x{B7A9C0} @Defop QLSHIFTADDDIVMOD
|
|
x{B7A9C1} @Defop QLSHIFTADDDIVMODR
|
|
x{B7A9C2} @Defop QLSHIFTADDDIVMODC
|
|
|
|
x{B7A9D4} @Defop(8u+1) QLSHIFT#DIV
|
|
x{B7A9D5} @Defop(8u+1) QLSHIFT#DIVR
|
|
x{B7A9D6} @Defop(8u+1) QLSHIFT#DIVC
|
|
x{B7A9D8} @Defop(8u+1) QLSHIFT#MOD
|
|
x{B7A9D9} @Defop(8u+1) QLSHIFT#MODR
|
|
x{B7A9DA} @Defop(8u+1) QLSHIFT#MODC
|
|
x{B7A9DC} @Defop(8u+1) QLSHIFT#DIVMOD
|
|
x{B7A9DD} @Defop(8u+1) QLSHIFT#DIVMODR
|
|
x{B7A9DE} @Defop(8u+1) QLSHIFT#DIVMODC
|
|
x{B7A9D0} @Defop(8u+1) QLSHIFT#ADDDIVMOD
|
|
x{B7A9D1} @Defop(8u+1) QLSHIFT#ADDDIVMODR
|
|
x{B7A9D2} @Defop(8u+1) QLSHIFT#ADDDIVMODC
|
|
|
|
x{B7AC} @Defop QLSHIFT
|
|
x{B7AD} @Defop QRSHIFT
|
|
x{B7AE} @Defop QPOW2
|
|
x{B7B0} @Defop QAND
|
|
x{B7B1} @Defop QOR
|
|
x{B7B2} @Defop QXOR
|
|
x{B7B3} @Defop QNOT
|
|
x{B7B4} @Defop(8u+1) QFITS
|
|
x{B7B5} @Defop(8u+1) QUFITS
|
|
x{B7B600} @Defop QFITSX
|
|
x{B7B601} @Defop QUFITSX
|
|
|
|
// advanced integer constants
|
|
{ 0 { over 1 and 0= } { 1+ swap 2/ swap } while } : pow2decomp
|
|
{ dup 8 fits { PUSHINT } {
|
|
dup pow2decomp over 1 = { nip nip PUSHPOW2 } {
|
|
over -1 = { nip nip PUSHNEGPOW2 } {
|
|
dup 20 >= { rot drop -rot PUSHINT swap LSHIFT# } {
|
|
{ drop PUSHINT } {
|
|
not pow2decomp swap -1 = { nip PUSHPOW2DEC } {
|
|
drop PUSHINT
|
|
} cond } cond } cond } cond } cond } cond
|
|
} dup : PUSHINTX : INTX
|
|
|
|
// integer comparison
|
|
x{B8} @Defop SGN
|
|
x{B9} @Defop LESS
|
|
x{BA} @Defop EQUAL
|
|
x{BB} @Defop LEQ
|
|
x{BC} @Defop GREATER
|
|
x{BD} @Defop NEQ
|
|
x{BE} @Defop GEQ
|
|
x{BF} @Defop CMP
|
|
x{C0} x{BA} @Defop(8i,alt) EQINT
|
|
x{C000} @Defop ISZERO
|
|
x{C1} x{B9} @Defop(8i,alt) LESSINT
|
|
{ 1+ LESSINT } : LEQINT
|
|
x{C100} @Defop ISNEG
|
|
x{C101} @Defop ISNPOS
|
|
x{C2} x{BC} @Defop(8i,alt) GTINT
|
|
{ 1- GTINT } : GEQINT
|
|
x{C200} @Defop ISPOS
|
|
x{C2FF} @Defop ISNNEG
|
|
x{C3} x{BD} @Defop(8i,alt) NEQINT
|
|
x{C300} @Defop ISNZERO
|
|
x{C4} @Defop ISNAN
|
|
x{C5} @Defop CHKNAN
|
|
|
|
// other comparison
|
|
x{C700} @Defop SEMPTY
|
|
x{C701} @Defop SDEMPTY
|
|
x{C702} @Defop SREMPTY
|
|
x{C703} @Defop SDFIRST
|
|
x{C704} @Defop SDLEXCMP
|
|
x{C705} @Defop SDEQ
|
|
x{C708} @Defop SDPFX
|
|
x{C709} @Defop SDPFXREV
|
|
x{C70A} @Defop SDPPFX
|
|
x{C70B} @Defop SDPPFXREV
|
|
x{C70C} @Defop SDSFX
|
|
x{C70D} @Defop SDSFXREV
|
|
x{C70E} @Defop SDPSFX
|
|
x{C70F} @Defop SDPSFXREV
|
|
x{C710} @Defop SDCNTLEAD0
|
|
x{C711} @Defop SDCNTLEAD1
|
|
x{C712} @Defop SDCNTTRAIL0
|
|
x{C713} @Defop SDCNTTRAIL1
|
|
|
|
// cell serialization (Builder manipulation primitives)
|
|
x{C8} @Defop NEWC
|
|
x{C9} @Defop ENDC
|
|
x{CA} @Defop(8u+1) STI
|
|
x{CB} @Defop(8u+1) STU
|
|
x{CC} @Defop STREF
|
|
x{CD} dup @Defop STBREFR @Defop ENDCST
|
|
x{CE} @Defop STSLICE
|
|
x{CF00} @Defop STIX
|
|
x{CF01} @Defop STUX
|
|
x{CF02} @Defop STIXR
|
|
x{CF03} @Defop STUXR
|
|
x{CF04} @Defop STIXQ
|
|
x{CF05} @Defop STUXQ
|
|
x{CF06} @Defop STIXRQ
|
|
x{CF07} @Defop STUXRQ
|
|
x{CF08} @Defop(8u+1) STI_l
|
|
x{CF09} @Defop(8u+1) STU_l
|
|
x{CF0A} @Defop(8u+1) STIR
|
|
x{CF0B} @Defop(8u+1) STUR
|
|
x{CF0C} @Defop(8u+1) STIQ
|
|
x{CF0D} @Defop(8u+1) STUQ
|
|
x{CF0E} @Defop(8u+1) STIRQ
|
|
x{CF0F} @Defop(8u+1) STURQ
|
|
x{CF10} @Defop STREF_l
|
|
x{CF11} @Defop STBREF
|
|
x{CF12} @Defop STSLICE_l
|
|
x{CF13} @Defop STB
|
|
x{CF14} @Defop STREFR
|
|
x{CF15} @Defop STBREFR_l
|
|
x{CF16} @Defop STSLICER
|
|
x{CF17} dup @Defop STBR @Defop BCONCAT
|
|
x{CF18} @Defop STREFQ
|
|
x{CF19} @Defop STBREFQ
|
|
x{CF1A} @Defop STSLICEQ
|
|
x{CF1B} @Defop STBQ
|
|
x{CF1C} @Defop STREFRQ
|
|
x{CF1D} @Defop STBREFRQ
|
|
x{CF1E} @Defop STSLICERQ
|
|
x{CF1F} dup @Defop STBRQ @Defop BCONCATQ
|
|
x{CF20} @Defop(ref) STREFCONST
|
|
{ <b x{CF21} s, rot ref, swap ref, @addopb } : STREF2CONST
|
|
x{CF23} @Defop ENDXC
|
|
x{CF28} @Defop STILE4
|
|
x{CF29} @Defop STULE4
|
|
x{CF2A} @Defop STILE8
|
|
x{CF2B} @Defop STULE8
|
|
x{CF30} @Defop BDEPTH
|
|
x{CF31} @Defop BBITS
|
|
x{CF32} @Defop BREFS
|
|
x{CF33} @Defop BBITREFS
|
|
x{CF35} @Defop BREMBITS
|
|
x{CF36} @Defop BREMREFS
|
|
x{CF37} @Defop BREMBITREFS
|
|
x{CF38} @Defop(8u+1) BCHKBITS#
|
|
x{CF39} @Defop BCHKBITS
|
|
x{CF3A} @Defop BCHKREFS
|
|
x{CF3B} @Defop BCHKBITREFS
|
|
x{CF3C} @Defop(8u+1) BCHKBITSQ#
|
|
x{CF3D} @Defop BCHKBITSQ
|
|
x{CF3E} @Defop BCHKREFSQ
|
|
x{CF3F} @Defop BCHKBITREFSQ
|
|
x{CF40} @Defop STZEROES
|
|
x{CF41} @Defop STONES
|
|
x{CF42} @Defop STSAME
|
|
{ tuck sbitrefs swap 22 + swap @havebitrefs not
|
|
{ swap PUSHSLICE STSLICER }
|
|
{ over sbitrefs 2dup 57 3 2x<=
|
|
{ rot x{CFC_} s, swap 2 u, over 6 + 3 >> tuck 3 u, 3 roll s,
|
|
-rot 3 << 2 + swap - @scomplete }
|
|
{ 2drop swap PUSHSLICE STSLICER } cond
|
|
} cond
|
|
} : STSLICECONST
|
|
x{CF81} @Defop STZERO
|
|
x{CF83} @Defop STONE
|
|
|
|
// cell deserialization (CellSlice primitives)
|
|
x{D0} @Defop CTOS
|
|
x{D1} @Defop ENDS
|
|
x{D2} @Defop(8u+1) LDI
|
|
x{D3} @Defop(8u+1) LDU
|
|
x{D4} @Defop LDREF
|
|
x{D5} @Defop LDREFRTOS
|
|
x{D6} @Defop(8u+1) LDSLICE
|
|
x{D700} @Defop LDIX
|
|
x{D701} @Defop LDUX
|
|
x{D702} @Defop PLDIX
|
|
x{D703} @Defop PLDUX
|
|
x{D704} @Defop LDIXQ
|
|
x{D705} @Defop LDUXQ
|
|
x{D706} @Defop PLDIXQ
|
|
x{D707} @Defop PLDUXQ
|
|
x{D708} @Defop(8u+1) LDI_l
|
|
x{D709} @Defop(8u+1) LDU_l
|
|
x{D70A} @Defop(8u+1) PLDI
|
|
x{D70B} @Defop(8u+1) PLDU
|
|
x{D70C} @Defop(8u+1) LDIQ
|
|
x{D70D} @Defop(8u+1) LDUQ
|
|
x{D70E} @Defop(8u+1) PLDIQ
|
|
x{D70F} @Defop(8u+1) PLDUQ
|
|
{ dup 31 and abort"argument must be a multiple of 32" 5 >> 1-
|
|
<b x{D714_} s, swap 3 u, @addopb
|
|
} : PLDUZ
|
|
x{D718} @Defop LDSLICEX
|
|
x{D719} @Defop PLDSLICEX
|
|
x{D71A} @Defop LDSLICEXQ
|
|
x{D71B} @Defop PLDSLICEXQ
|
|
x{D71C} @Defop(8u+1) LDSLICE_l
|
|
x{D71D} @Defop(8u+1) PLDSLICE
|
|
x{D71E} @Defop(8u+1) LDSLICEQ
|
|
x{D71F} @Defop(8u+1) PLDSLICEQ
|
|
x{D720} @Defop SDCUTFIRST
|
|
x{D721} @Defop SDSKIPFIRST
|
|
x{D722} @Defop SDCUTLAST
|
|
x{D723} @Defop SDSKIPLAST
|
|
x{D724} @Defop SDSUBSTR
|
|
x{D726} @Defop SDBEGINSX
|
|
x{D727} @Defop SDBEGINSXQ
|
|
{ tuck sbits tuck 5 + 3 >> swap x{D72A_} s, over 7 u, 3 roll s,
|
|
-rot 3 << 3 + swap - @scomplete } : SDBEGINS:imm
|
|
{ tuck sbitrefs abort"no references allowed in slice" dup 26 <=
|
|
{ drop <b rot SDBEGINS:imm @addopb }
|
|
{ @havebits
|
|
{ swap SDBEGINS:imm }
|
|
{ swap PUSHSLICE SDBEGINSX
|
|
} cond
|
|
} cond
|
|
} : SDBEGINS
|
|
{ tuck sbits tuck 5 + 3 >> swap x{D72E_} s, over 7 u, 3 roll s,
|
|
-rot 3 << 3 + swap - @scomplete } : SDBEGINSQ:imm
|
|
{ tuck sbitrefs abort"no references allowed in slice" dup 26 <=
|
|
{ drop <b rot SDBEGINSQ:imm @addopb }
|
|
{ @havebits
|
|
{ swap SDBEGINSQ:imm }
|
|
{ swap PUSHSLICE SDBEGINSXQ
|
|
} cond
|
|
} cond
|
|
} : SDBEGINSQ
|
|
x{D730} @Defop SCUTFIRST
|
|
x{D731} @Defop SSKIPFIRST
|
|
x{D732} @Defop SCUTLAST
|
|
x{D733} @Defop SSKIPLAST
|
|
x{D734} @Defop SUBSLICE
|
|
x{D736} @Defop SPLIT
|
|
x{D737} @Defop SPLITQ
|
|
x{D739} @Defop XCTOS
|
|
x{D73A} @Defop XLOAD
|
|
x{D73B} @Defop XLOADQ
|
|
x{D741} @Defop SCHKBITS
|
|
x{D742} @Defop SCHKREFS
|
|
x{D743} @Defop SCHKBITREFS
|
|
x{D745} @Defop SCHKBITSQ
|
|
x{D746} @Defop SCHKREFSQ
|
|
x{D747} @Defop SCHKBITREFSQ
|
|
x{D748} @Defop PLDREFVAR
|
|
x{D749} @Defop SBITS
|
|
x{D74A} @Defop SREFS
|
|
x{D74B} @Defop SBITREFS
|
|
{ <b x{D74E_} s, swap 2 u, @addopb } : PLDREFIDX
|
|
x{D74C} @Defop PLDREF
|
|
x{D750} @Defop LDILE4
|
|
x{D751} @Defop LDULE4
|
|
x{D752} @Defop LDILE8
|
|
x{D753} @Defop LDULE8
|
|
x{D754} @Defop PLDILE4
|
|
x{D755} @Defop PLDULE4
|
|
x{D756} @Defop PLDILE8
|
|
x{D757} @Defop PLDULE8
|
|
x{D758} @Defop LDILE4Q
|
|
x{D759} @Defop LDULE4Q
|
|
x{D75A} @Defop LDILE8Q
|
|
x{D75B} @Defop LDULE8Q
|
|
x{D75C} @Defop PLDILE4Q
|
|
x{D75D} @Defop PLDULE4Q
|
|
x{D75E} @Defop PLDILE8Q
|
|
x{D75F} @Defop PLDULE8Q
|
|
x{D760} @Defop LDZEROES
|
|
x{D761} @Defop LDONES
|
|
x{D762} @Defop LDSAME
|
|
x{D764} @Defop SDEPTH
|
|
x{D765} @Defop CDEPTH
|
|
x{D766} @Defop CLEVEL
|
|
x{D767} @Defop CLEVELMASK
|
|
{ <b x{D76A_} s, swap 2 u, @addopb } : CHASHI
|
|
{ <b x{D76E_} s, swap 2 u, @addopb } : CDEPTHI
|
|
x{D770} @Defop CHASHIX
|
|
x{D771} @Defop CDEPTHIX
|
|
//
|
|
// continuation / flow control primitives
|
|
x{D8} dup @Defop EXECUTE @Defop CALLX
|
|
x{D9} @Defop JMPX
|
|
{ dup 1+
|
|
{ <b x{DA} s, rot 4 u, swap 4 u, }
|
|
{ drop <b x{DB0} s, swap 4 u,
|
|
} cond @addopb
|
|
} : CALLXARGS
|
|
x{DB1} @Defop(4u) JMPXARGS
|
|
x{DB2} @Defop(4u) RETARGS
|
|
x{DB30} dup @Defop RET @Defop RETTRUE
|
|
x{DB31} dup @Defop RETALT @Defop RETFALSE
|
|
x{DB32} dup @Defop BRANCH @Defop RETBOOL
|
|
x{DB34} @Defop CALLCC
|
|
x{DB35} @Defop JMPXDATA
|
|
{ dup 1+ 0= { 16 + } if
|
|
<b x{DB36} s, rot 4 u, swap 4 u, @addopb
|
|
} : CALLCCARGS
|
|
x{DB38} @Defop CALLXVARARGS
|
|
x{DB39} @Defop RETVARARGS
|
|
x{DB3A} @Defop JMPXVARARGS
|
|
x{DB3B} @Defop CALLCCVARARGS
|
|
x{DB3C} @Defop(ref) CALLREF
|
|
x{DB3D} @Defop(ref) JMPREF
|
|
x{DB3E} @Defop(ref) JMPREFDATA
|
|
x{DB3F} @Defop RETDATA
|
|
x{DB4} @Defop(12u) RUNVM
|
|
x{DB50} @Defop RUNVMX
|
|
// conditional and iterated execution primitives
|
|
x{DC} @Defop IFRET
|
|
x{DD} @Defop IFNOTRET
|
|
x{DE} @Defop IF
|
|
x{DF} @Defop IFNOT
|
|
' IFNOTRET : IF:
|
|
' IFRET : IFNOT:
|
|
x{E0} @Defop IFJMP
|
|
x{E1} @Defop IFNOTJMP
|
|
x{E2} @Defop IFELSE
|
|
|
|
x{E300} @Defop(ref) IFREF
|
|
x{E301} @Defop(ref) IFNOTREF
|
|
x{E302} @Defop(ref) IFJMPREF
|
|
x{E303} @Defop(ref) IFNOTJMPREF
|
|
x{E30D} @Defop(ref) IFREFELSE
|
|
x{E30E} @Defop(ref) IFELSEREF
|
|
x{E30F} @Defop(ref*2) IFREFELSEREF
|
|
|
|
{ 16 1 @havebitrefs nip } : @refop-fits?
|
|
// b b1 [e0 e1 e2] -- b'
|
|
{ -rot dup @cont-empty? { drop swap 0 } {
|
|
2dup @cont-fits? { rot 1 } {
|
|
over @refop-fits? { b> rot 2 } {
|
|
swap @| swap 2dup @cont-fits? { rot 1 } {
|
|
b> rot 2
|
|
} cond } cond } cond } cond
|
|
[] execute
|
|
} : @run-cont-op
|
|
{ triple 1 ' @run-cont-op does create } : @def-cont-op
|
|
{ DROP } { PUSHCONT IF } { IFREF } @def-cont-op IF-cont
|
|
{ IFRET } { PUSHCONT IFJMP } { IFJMPREF } @def-cont-op IFJMP-cont
|
|
{ DROP } { PUSHCONT IFNOT } { IFNOTREF } @def-cont-op IFNOT-cont
|
|
{ IFNOTRET } { PUSHCONT IFNOTJMP } { IFNOTJMPREF } @def-cont-op IFNOTJMP-cont
|
|
{ dup 2over rot } : 3dup
|
|
|
|
recursive IFELSE-cont2 {
|
|
dup @cont-empty? { drop IF-cont } {
|
|
over @cont-empty? { nip IFNOT-cont } {
|
|
3dup @two-cont-fit? { -rot PUSHCONT swap PUSHCONT IFELSE } {
|
|
3dup nip @cont-ref-fit? { rot swap PUSHCONT swap b> IFREFELSE } {
|
|
3dup drop @cont-ref-fit? { -rot PUSHCONT swap b> IFELSEREF } {
|
|
rot 32 2 @havebitrefs { rot b> rot b> IFREFELSEREF } {
|
|
@| -rot IFELSE-cont2
|
|
} cond } cond } cond } cond } cond } cond
|
|
} swap !
|
|
|
|
{ }> IF-cont } : }>IF
|
|
{ }> IFNOT-cont } : }>IFNOT
|
|
{ }> IFJMP-cont } : }>IFJMP
|
|
{ }> IFNOTJMP-cont } : }>IFNOTJMP
|
|
{ { @normal? IFJMP-cont } @doafter<{ } : IFJMP:<{
|
|
{ { @normal? IFNOTJMP-cont } @doafter<{ } : IFNOTJMP:<{
|
|
{ `else @endblk } : }>ELSE<{
|
|
{ `else: @endblk } : }>ELSE:
|
|
{ 1 { swap @normal? swap IFELSE-cont2 } does @doafter<{ } : @doifelse
|
|
{ 1 { swap @normal? IFELSE-cont2 } does @doafter<{ } : @doifnotelse
|
|
{
|
|
{ dup `else eq?
|
|
{ drop @doifelse }
|
|
{ dup `else: eq?
|
|
{ drop IFJMP-cont }
|
|
{ @normal? IF-cont
|
|
} cond
|
|
} cond
|
|
} @doafter<{
|
|
} : IF:<{
|
|
{
|
|
{ dup `else eq?
|
|
{ drop @doifnotelse }
|
|
{ dup `else: eq?
|
|
{ drop IFNOTJMP-cont }
|
|
{ @normal? IFNOT-cont
|
|
} cond
|
|
} cond
|
|
} @doafter<{
|
|
} : IFNOT:<{
|
|
|
|
x{E304} @Defop CONDSEL
|
|
x{E305} @Defop CONDSELCHK
|
|
x{E308} @Defop IFRETALT
|
|
x{E309} @Defop IFNOTRETALT
|
|
{ <b x{E39_} s, swap 5 u, @addopb } : IFBITJMP
|
|
{ <b x{E3B_} s, swap 5 u, @addopb } : IFNBITJMP
|
|
{ <b x{E3D_} s, swap 5 u, swap ref, @addopb } : IFBITJMPREF
|
|
{ <b x{E3F_} s, swap 5 u, swap ref, @addopb } : IFNBITJMPREF
|
|
|
|
x{E4} @Defop REPEAT
|
|
x{E5} dup @Defop REPEATEND @Defop REPEAT:
|
|
x{E6} @Defop UNTIL
|
|
x{E7} dup @Defop UNTILEND @Defop UNTIL:
|
|
x{E8} @Defop WHILE
|
|
x{E9} @Defop WHILEEND
|
|
x{EA} @Defop AGAIN
|
|
x{EB} dup @Defop AGAINEND @Defop AGAIN:
|
|
|
|
{ `do @endblk } : }>DO<{
|
|
{ `do: @endblk } : }>DO:
|
|
{ }> PUSHCONT REPEAT } : }>REPEAT
|
|
{ { @normal? PUSHCONT REPEAT } @doafter<{ } : REPEAT:<{
|
|
{ }> PUSHCONT UNTIL } : }>UNTIL
|
|
{ { @normal? PUSHCONT UNTIL } @doafter<{ } : UNTIL:<{
|
|
{ PUSHCONT { @normal? PUSHCONT WHILE } @doafter<{ } : @dowhile
|
|
{
|
|
{ dup `do eq?
|
|
{ drop @dowhile }
|
|
{ `do: eq? not abort"`}>DO<{` expected" PUSHCONT WHILEEND
|
|
} cond
|
|
} @doafter<{
|
|
} : WHILE:<{
|
|
{ }> PUSHCONT AGAIN } : }>AGAIN
|
|
{ { @normal? PUSHCONT AGAIN } @doafter<{ } : AGAIN:<{
|
|
|
|
x{E314} @Defop REPEATBRK
|
|
x{E315} @Defop REPEATENDBRK
|
|
x{E316} @Defop UNTILBRK
|
|
x{E317} dup @Defop UNTILENDBRK @Defop UNTILBRK:
|
|
x{E318} @Defop WHILEBRK
|
|
x{E319} @Defop WHILEENDBRK
|
|
x{E31A} @Defop AGAINBRK
|
|
x{E31B} dup @Defop AGAINENDBRK @Defop AGAINBRK:
|
|
|
|
{ }> PUSHCONT REPEATBRK } : }>REPEATBRK
|
|
{ { @normal? PUSHCONT REPEATBRK } @doafter<{ } : REPEATBRK:<{
|
|
{ }> PUSHCONT UNTILBRK } : }>UNTILBRK
|
|
{ { @normal? PUSHCONT UNTILBRK } @doafter<{ } : UNTILBRK:<{
|
|
{ PUSHCONT { @normal? PUSHCONT WHILEBRK } @doafter<{ } : @dowhile
|
|
{
|
|
{ dup `do eq?
|
|
{ drop @dowhile }
|
|
{ `do: eq? not abort"`}>DO<{` expected" PUSHCONT WHILEENDBRK
|
|
} cond
|
|
} @doafter<{
|
|
} : WHILEBRK:<{
|
|
{ }> PUSHCONT AGAINBRK } : }>AGAINBRK
|
|
{ { @normal? PUSHCONT AGAINBRK } @doafter<{ } : AGAINBRK:<{
|
|
|
|
|
|
//
|
|
// continuation stack manipulation and continuation creation
|
|
//
|
|
{ <b x{EC} s, rot 4 u, swap dup 1+ { 16 + } ifnot 4 u, @addopb } : SETCONTARGS
|
|
{ 0 swap SETCONTARGS } : SETNUMARGS
|
|
x{ED0} @Defop(4u) RETURNARGS
|
|
x{ED10} @Defop RETURNVARARGS
|
|
x{ED11} @Defop SETCONTVARARGS
|
|
x{ED12} @Defop SETNUMVARARGS
|
|
x{ED1E} @Defop BLESS
|
|
x{ED1F} @Defop BLESSVARARGS
|
|
{ <b x{EE} s, rot 4 u, swap dup 1+ { 16 + } ifnot 4 u, @addopb } : BLESSARGS
|
|
{ 0 swap BLESSARGS } : BLESSNUMARGS
|
|
//
|
|
// control register and continuation savelist manipulation
|
|
// x{ED4} Defop(c) PUSHCTR
|
|
// x{ED5} Defop(c) POPCTR
|
|
{ c4 PUSHCTR } : PUSHROOT
|
|
{ c4 POPCTR } : POPROOT
|
|
x{ED6} dup @Defop(c) SETCONTCTR @Defop(c) SETCONT
|
|
x{ED7} @Defop(c) SETRETCTR
|
|
x{ED8} @Defop(c) SETALTCTR
|
|
x{ED9} dup @Defop(c) POPSAVE @Defop(c) POPCTRSAVE
|
|
x{EDA} dup @Defop(c) SAVE @Defop(c) SAVECTR
|
|
x{EDB} dup @Defop(c) SAVEALT @Defop(c) SAVEALTCTR
|
|
x{EDC} dup @Defop(c) SAVEBOTH @Defop(c) SAVEBOTHCTR
|
|
x{EDE0} @Defop PUSHCTRX
|
|
x{EDE1} @Defop POPCTRX
|
|
x{EDE2} @Defop SETCONTCTRX
|
|
x{EDF0} dup @Defop BOOLAND @Defop COMPOS
|
|
x{EDF1} dup @Defop BOOLOR @Defop COMPOSALT
|
|
x{EDF2} @Defop COMPOSBOTH
|
|
x{EDF3} @Defop ATEXIT
|
|
{ }> PUSHCONT ATEXIT } : }>ATEXIT
|
|
{ { @normal? PUSHCONT ATEXIT } @doafter<{ } : ATEXIT:<{
|
|
x{EDF4} @Defop ATEXITALT
|
|
{ }> PUSHCONT ATEXITALT } : }>ATEXITALT
|
|
{ { @normal? PUSHCONT ATEXITALT } @doafter<{ } : ATEXITALT:<{
|
|
x{EDF5} @Defop SETEXITALT
|
|
{ }> PUSHCONT SETEXITALT } : }>SETEXITALT
|
|
{ { @normal? PUSHCONT SETEXITALT } @doafter<{ } : SETEXITALT:<{
|
|
x{EDF6} @Defop THENRET
|
|
x{EDF7} @Defop THENRETALT
|
|
x{EDF8} @Defop INVERT
|
|
x{EDF9} @Defop BOOLEVAL
|
|
x{EDFA} @Defop SAMEALT
|
|
x{EDFB} @Defop SAMEALTSAVE
|
|
// x{EE} is BLESSARGS
|
|
//
|
|
// dictionary subroutine call/jump primitives
|
|
{ c3 PUSH EXECUTE } : CALLVAR
|
|
{ c3 PUSH JMPX } : JMPVAR
|
|
{ c3 PUSH } : PREPAREVAR
|
|
{ dup 14 ufits {
|
|
dup 8 ufits {
|
|
<b x{F0} s, swap 8 u, } {
|
|
<b x{F12_} s, swap 14 u,
|
|
} cond @addopb } {
|
|
PUSHINT CALLVAR
|
|
} cond
|
|
} dup : CALL : CALLDICT
|
|
{ dup 14 ufits
|
|
{ <b x{F16_} s, swap 14 u, @addopb }
|
|
{ PUSHINT JMPVAR } cond
|
|
} dup : JMP : JMPDICT
|
|
{ dup 14 ufits
|
|
{ <b x{F1A_} s, swap 14 u, @addopb }
|
|
{ PUSHINT c3 PREPAREVAR } cond
|
|
} dup : PREPARE : PREPAREDICT
|
|
//
|
|
// inline support
|
|
{ dup sbits
|
|
{ @addop }
|
|
{
|
|
dup srefs //
|
|
{ ref@ CALLREF }
|
|
{ drop }
|
|
cond
|
|
}
|
|
cond
|
|
} : INLINE
|
|
//
|
|
// throwing and handling exceptions
|
|
{ dup 6 ufits
|
|
{ <b x{F22_} s, swap 6 u, }
|
|
{ <b x{F2C4_} s, swap 11 u,
|
|
} cond
|
|
@addopb } : THROW
|
|
{ dup 6 ufits
|
|
{ <b x{F26_} s, swap 6 u, }
|
|
{ <b x{F2D4_} s, swap 11 u,
|
|
} cond
|
|
@addopb } : THROWIF
|
|
{ dup 6 ufits
|
|
{ <b x{F2A_} s, swap 6 u, }
|
|
{ <b x{F2E4_} s, swap 11 u,
|
|
} cond
|
|
@addopb } : THROWIFNOT
|
|
{ <b x{F2CC_} s, swap 11 u, @addopb } : THROWARG
|
|
{ <b x{F2DC_} s, swap 11 u, @addopb } : THROWARGIF
|
|
{ <b x{F2EC_} s, swap 11 u, @addopb } : THROWARGIFNOT
|
|
x{F2F0} @Defop THROWANY
|
|
x{F2F1} @Defop THROWARGANY
|
|
x{F2F2} @Defop THROWANYIF
|
|
x{F2F3} @Defop THROWARGANYIF
|
|
x{F2F4} @Defop THROWANYIFNOT
|
|
x{F2F5} @Defop THROWARGANYIFNOT
|
|
x{F2FF} @Defop TRY
|
|
x{F3} @Defop(4u,4u) TRYARGS
|
|
{ `catch @endblk } : }>CATCH<{
|
|
{ PUSHCONT { @normal? PUSHCONT TRY } @doafter<{ } : @trycatch
|
|
{
|
|
{ `catch eq? not abort"`}>CATCH<{` expected" @trycatch
|
|
} @doafter<{
|
|
} : TRY:<{
|
|
//
|
|
// dictionary manipulation
|
|
' NULL : NEWDICT
|
|
' ISNULL : DICTEMPTY
|
|
' STSLICE : STDICTS
|
|
x{F400} dup @Defop STDICT @Defop STOPTREF
|
|
x{F401} dup @Defop SKIPDICT @Defop SKIPOPTREF
|
|
x{F402} @Defop LDDICTS
|
|
x{F403} @Defop PLDDICTS
|
|
x{F404} dup @Defop LDDICT @Defop LDOPTREF
|
|
x{F405} dup @Defop PLDDICT @Defop PLDOPTREF
|
|
x{F406} @Defop LDDICTQ
|
|
x{F407} @Defop PLDDICTQ
|
|
|
|
x{F40A} @Defop DICTGET
|
|
x{F40B} @Defop DICTGETREF
|
|
x{F40C} @Defop DICTIGET
|
|
x{F40D} @Defop DICTIGETREF
|
|
x{F40E} @Defop DICTUGET
|
|
x{F40F} @Defop DICTUGETREF
|
|
|
|
x{F412} @Defop DICTSET
|
|
x{F413} @Defop DICTSETREF
|
|
x{F414} @Defop DICTISET
|
|
x{F415} @Defop DICTISETREF
|
|
x{F416} @Defop DICTUSET
|
|
x{F417} @Defop DICTUSETREF
|
|
x{F41A} @Defop DICTSETGET
|
|
x{F41B} @Defop DICTSETGETREF
|
|
x{F41C} @Defop DICTISETGET
|
|
x{F41D} @Defop DICTISETGETREF
|
|
x{F41E} @Defop DICTUSETGET
|
|
x{F41F} @Defop DICTUSETGETREF
|
|
|
|
x{F422} @Defop DICTREPLACE
|
|
x{F423} @Defop DICTREPLACEREF
|
|
x{F424} @Defop DICTIREPLACE
|
|
x{F425} @Defop DICTIREPLACEREF
|
|
x{F426} @Defop DICTUREPLACE
|
|
x{F427} @Defop DICTUREPLACEREF
|
|
x{F42A} @Defop DICTREPLACEGET
|
|
x{F42B} @Defop DICTREPLACEGETREF
|
|
x{F42C} @Defop DICTIREPLACEGET
|
|
x{F42D} @Defop DICTIREPLACEGETREF
|
|
x{F42E} @Defop DICTUREPLACEGET
|
|
x{F42F} @Defop DICTUREPLACEGETREF
|
|
|
|
x{F432} @Defop DICTADD
|
|
x{F433} @Defop DICTADDREF
|
|
x{F434} @Defop DICTIADD
|
|
x{F435} @Defop DICTIADDREF
|
|
x{F436} @Defop DICTUADD
|
|
x{F437} @Defop DICTUADDREF
|
|
x{F43A} @Defop DICTADDGET
|
|
x{F43B} @Defop DICTADDGETREF
|
|
x{F43C} @Defop DICTIADDGET
|
|
x{F43D} @Defop DICTIADDGETREF
|
|
x{F43E} @Defop DICTUADDGET
|
|
x{F43F} @Defop DICTUADDGETREF
|
|
|
|
x{F441} @Defop DICTSETB
|
|
x{F442} @Defop DICTISETB
|
|
x{F443} @Defop DICTUSETB
|
|
x{F445} @Defop DICTSETGETB
|
|
x{F446} @Defop DICTISETGETB
|
|
x{F447} @Defop DICTUSETGETB
|
|
|
|
x{F449} @Defop DICTREPLACEB
|
|
x{F44A} @Defop DICTIREPLACEB
|
|
x{F44B} @Defop DICTUREPLACEB
|
|
x{F44D} @Defop DICTREPLACEGETB
|
|
x{F44E} @Defop DICTIREPLACEGETB
|
|
x{F44F} @Defop DICTUREPLACEGETB
|
|
|
|
x{F451} @Defop DICTADDB
|
|
x{F452} @Defop DICTIADDB
|
|
x{F453} @Defop DICTUADDB
|
|
x{F455} @Defop DICTADDGETB
|
|
x{F456} @Defop DICTIADDGETB
|
|
x{F457} @Defop DICTUADDGETB
|
|
|
|
x{F459} @Defop DICTDEL
|
|
x{F45A} @Defop DICTIDEL
|
|
x{F45B} @Defop DICTUDEL
|
|
|
|
x{F462} @Defop DICTDELGET
|
|
x{F463} @Defop DICTDELGETREF
|
|
x{F464} @Defop DICTIDELGET
|
|
x{F465} @Defop DICTIDELGETREF
|
|
x{F466} @Defop DICTUDELGET
|
|
x{F467} @Defop DICTUDELGETREF
|
|
|
|
x{F469} @Defop DICTGETOPTREF
|
|
x{F46A} @Defop DICTIGETOPTREF
|
|
x{F46B} @Defop DICTUGETOPTREF
|
|
x{F46D} @Defop DICTSETGETOPTREF
|
|
x{F46E} @Defop DICTISETGETOPTREF
|
|
x{F46F} @Defop DICTUSETGETOPTREF
|
|
|
|
x{F470} @Defop PFXDICTSET
|
|
x{F471} @Defop PFXDICTREPLACE
|
|
x{F472} @Defop PFXDICTADD
|
|
x{F473} @Defop PFXDICTDEL
|
|
|
|
x{F474} @Defop DICTGETNEXT
|
|
x{F475} @Defop DICTGETNEXTEQ
|
|
x{F476} @Defop DICTGETPREV
|
|
x{F477} @Defop DICTGETPREVEQ
|
|
x{F478} @Defop DICTIGETNEXT
|
|
x{F479} @Defop DICTIGETNEXTEQ
|
|
x{F47A} @Defop DICTIGETPREV
|
|
x{F47B} @Defop DICTIGETPREVEQ
|
|
x{F47C} @Defop DICTUGETNEXT
|
|
x{F47D} @Defop DICTUGETNEXTEQ
|
|
x{F47E} @Defop DICTUGETPREV
|
|
x{F47F} @Defop DICTUGETPREVEQ
|
|
|
|
x{F482} @Defop DICTMIN
|
|
x{F483} @Defop DICTMINREF
|
|
x{F484} @Defop DICTIMIN
|
|
x{F485} @Defop DICTIMINREF
|
|
x{F486} @Defop DICTUMIN
|
|
x{F487} @Defop DICTUMINREF
|
|
x{F48A} @Defop DICTMAX
|
|
x{F48B} @Defop DICTMAXREF
|
|
x{F48C} @Defop DICTIMAX
|
|
x{F48D} @Defop DICTIMAXREF
|
|
x{F48E} @Defop DICTUMAX
|
|
x{F48F} @Defop DICTUMAXREF
|
|
|
|
x{F492} @Defop DICTREMMIN
|
|
x{F493} @Defop DICTREMMINREF
|
|
x{F494} @Defop DICTIREMMIN
|
|
x{F495} @Defop DICTIREMMINREF
|
|
x{F496} @Defop DICTUREMMIN
|
|
x{F497} @Defop DICTUREMMINREF
|
|
x{F49A} @Defop DICTREMMAX
|
|
x{F49B} @Defop DICTREMMAXREF
|
|
x{F49C} @Defop DICTIREMMAX
|
|
x{F49D} @Defop DICTIREMMAXREF
|
|
x{F49E} @Defop DICTUREMMAX
|
|
x{F49F} @Defop DICTUREMMAXREF
|
|
|
|
x{F4A0} @Defop DICTIGETJMP
|
|
x{F4A1} @Defop DICTUGETJMP
|
|
x{F4A2} @Defop DICTIGETEXEC
|
|
x{F4A3} @Defop DICTUGETEXEC
|
|
{ dup sbitrefs tuck 1 > swap 1 <> or abort"not a dictionary" swap 1 u@ over <> abort"not a dictionary" } : @chkdicts
|
|
{ dup null? tuck { <s } ifnot drop not } : @chkdict
|
|
{ over @chkdict
|
|
{ swap <b x{F4A6_} s, swap ref, swap 10 u, @addopb }
|
|
{ nip swap NEWDICT swap PUSHINT }
|
|
cond
|
|
} : DICTPUSHCONST
|
|
x{F4A8} @Defop PFXDICTGETQ
|
|
x{F4A9} @Defop PFXDICTGET
|
|
x{F4AA} @Defop PFXDICTGETJMP
|
|
x{F4AB} @Defop PFXDICTGETEXEC
|
|
{ over @chkdict
|
|
{ swap <b x{F4AE_} s, swap ref, swap 10 u, @addopb
|
|
} if
|
|
} dup : PFXDICTCONSTGETJMP : PFXDICTSWITCH
|
|
|
|
x{F4B1} @Defop SUBDICTGET
|
|
x{F4B2} @Defop SUBDICTIGET
|
|
x{F4B3} @Defop SUBDICTUGET
|
|
x{F4B5} @Defop SUBDICTRPGET
|
|
x{F4B6} @Defop SUBDICTIRPGET
|
|
x{F4B7} @Defop SUBDICTURPGET
|
|
|
|
x{F4BC} @Defop DICTIGETJMPZ
|
|
x{F4BD} @Defop DICTUGETJMPZ
|
|
x{F4BE} @Defop DICTIGETEXECZ
|
|
x{F4BF} @Defop DICTUGETEXECZ
|
|
|
|
//
|
|
// blockchain-specific primitives
|
|
|
|
x{F800} @Defop ACCEPT
|
|
x{F801} @Defop SETGASLIMIT
|
|
x{F807} @Defop GASCONSUMED
|
|
x{F80F} @Defop COMMIT
|
|
|
|
x{F810} @Defop RANDU256
|
|
x{F811} @Defop RAND
|
|
x{F814} @Defop SETRAND
|
|
x{F815} dup @Defop ADDRAND @Defop RANDOMIZE
|
|
|
|
x{F82} @Defop(4u) GETPARAM
|
|
x{F823} @Defop NOW
|
|
x{F824} @Defop BLOCKLT
|
|
x{F825} @Defop LTIME
|
|
x{F826} @Defop RANDSEED
|
|
x{F827} @Defop BALANCE
|
|
x{F828} @Defop MYADDR
|
|
x{F829} @Defop CONFIGROOT
|
|
x{F82A} @Defop MYCODE
|
|
x{F82B} @Defop INCOMINGVALUE
|
|
x{F82C} @Defop STORAGEFEES
|
|
x{F82D} @Defop PREVBLOCKSINFOTUPLE
|
|
x{F82E} @Defop UNPACKEDCONFIGTUPLE
|
|
x{F82F} @Defop DUEPAYMENT
|
|
x{F830} @Defop CONFIGDICT
|
|
x{F832} @Defop CONFIGPARAM
|
|
x{F833} @Defop CONFIGOPTPARAM
|
|
x{F83400} @Defop PREVMCBLOCKS
|
|
x{F83401} @Defop PREVKEYBLOCK
|
|
x{F835} @Defop GLOBALID
|
|
x{F836} @Defop GETGASFEE
|
|
x{F837} @Defop GETSTORAGEFEE
|
|
x{F838} @Defop GETFORWARDFEE
|
|
x{F839} @Defop GETPRECOMPILEDGAS
|
|
x{F83A} @Defop GETORIGINALFWDFEE
|
|
x{F83B} @Defop GETGASFEESIMPLE
|
|
x{F83C} @Defop GETFORWARDFEESIMPLE
|
|
|
|
x{F840} @Defop GETGLOBVAR
|
|
{ dup 1 31 @rangechk <b x{F85_} s, swap 5 u, @addopb } : GETGLOB
|
|
x{F860} @Defop SETGLOBVAR
|
|
{ dup 1 31 @rangechk <b x{F87_} s, swap 5 u, @addopb } : SETGLOB
|
|
|
|
x{F900} @Defop HASHCU
|
|
x{F901} @Defop HASHSU
|
|
x{F902} @Defop SHA256U
|
|
|
|
x{F904} @Defop(8u) HASHEXT
|
|
x{F90400} @Defop HASHEXT_SHA256
|
|
x{F90401} @Defop HASHEXT_SHA512
|
|
x{F90402} @Defop HASHEXT_BLAKE2B
|
|
x{F90403} @Defop HASHEXT_KECCAK256
|
|
x{F90404} @Defop HASHEXT_KECCAK512
|
|
x{F905} @Defop(8u) HASHEXTR
|
|
x{F90500} @Defop HASHEXTR_SHA256
|
|
x{F90501} @Defop HASHEXTR_SHA512
|
|
x{F90502} @Defop HASHEXTR_BLAKE2B
|
|
x{F90503} @Defop HASHEXTR_KECCAK256
|
|
x{F90504} @Defop HASHEXTR_KECCAK512
|
|
x{F906} @Defop(8u) HASHEXTA
|
|
x{F90600} @Defop HASHEXTA_SHA256
|
|
x{F90601} @Defop HASHEXTA_SHA512
|
|
x{F90602} @Defop HASHEXTA_BLAKE2B
|
|
x{F90603} @Defop HASHEXTA_KECCAK256
|
|
x{F90604} @Defop HASHEXTA_KECCAK512
|
|
x{F907} @Defop(8u) HASHEXTAR
|
|
x{F90700} @Defop HASHEXTAR_SHA256
|
|
x{F90701} @Defop HASHEXTAR_SHA512
|
|
x{F90702} @Defop HASHEXTAR_BLAKE2B
|
|
x{F90703} @Defop HASHEXTAR_KECCAK256
|
|
x{F90704} @Defop HASHEXTAR_KECCAK512
|
|
|
|
x{F910} @Defop CHKSIGNU
|
|
x{F911} @Defop CHKSIGNS
|
|
x{F912} @Defop ECRECOVER
|
|
x{F914} @Defop P256_CHKSIGNU
|
|
x{F915} @Defop P256_CHKSIGNS
|
|
|
|
x{F920} @Defop RIST255_FROMHASH
|
|
x{F921} @Defop RIST255_VALIDATE
|
|
x{F922} @Defop RIST255_ADD
|
|
x{F923} @Defop RIST255_SUB
|
|
x{F924} @Defop RIST255_MUL
|
|
x{F925} @Defop RIST255_MULBASE
|
|
x{F926} @Defop RIST255_PUSHL
|
|
|
|
x{B7F921} @Defop RIST255_QVALIDATE
|
|
x{B7F922} @Defop RIST255_QADD
|
|
x{B7F923} @Defop RIST255_QSUB
|
|
x{B7F924} @Defop RIST255_QMUL
|
|
x{B7F925} @Defop RIST255_QMULBASE
|
|
|
|
x{F93000} @Defop BLS_VERIFY
|
|
x{F93001} @Defop BLS_AGGREGATE
|
|
x{F93002} @Defop BLS_FASTAGGREGATEVERIFY
|
|
x{F93003} @Defop BLS_AGGREGATEVERIFY
|
|
|
|
x{F93010} @Defop BLS_G1_ADD
|
|
x{F93011} @Defop BLS_G1_SUB
|
|
x{F93012} @Defop BLS_G1_NEG
|
|
x{F93013} @Defop BLS_G1_MUL
|
|
x{F93014} @Defop BLS_G1_MULTIEXP
|
|
x{F93015} @Defop BLS_G1_ZERO
|
|
x{F93016} @Defop BLS_MAP_TO_G1
|
|
x{F93017} @Defop BLS_G1_INGROUP
|
|
x{F93018} @Defop BLS_G1_ISZERO
|
|
|
|
x{F93020} @Defop BLS_G2_ADD
|
|
x{F93021} @Defop BLS_G2_SUB
|
|
x{F93022} @Defop BLS_G2_NEG
|
|
x{F93023} @Defop BLS_G2_MUL
|
|
x{F93024} @Defop BLS_G2_MULTIEXP
|
|
x{F93025} @Defop BLS_G2_ZERO
|
|
x{F93026} @Defop BLS_MAP_TO_G2
|
|
x{F93027} @Defop BLS_G2_INGROUP
|
|
x{F93028} @Defop BLS_G2_ISZERO
|
|
|
|
x{F93030} @Defop BLS_PAIRING
|
|
x{F93031} @Defop BLS_PUSHR
|
|
|
|
x{F940} @Defop CDATASIZEQ
|
|
x{F941} @Defop CDATASIZE
|
|
x{F942} @Defop SDATASIZEQ
|
|
x{F943} @Defop SDATASIZE
|
|
|
|
x{FA00} dup @Defop LDGRAMS @Defop LDVARUINT16
|
|
x{FA01} @Defop LDVARINT16
|
|
x{FA02} dup @Defop STGRAMS @Defop STVARUINT16
|
|
x{FA03} @Defop STVARINT16
|
|
|
|
x{FA04} @Defop LDVARUINT32 // (s -- x s')
|
|
x{FA05} @Defop LDVARINT32 // (s -- x s')
|
|
x{FA06} @Defop STVARUINT32 // (b x -- b')
|
|
x{FA07} @Defop STVARINT32 // (b x -- b')
|
|
|
|
x{FA40} @Defop LDMSGADDR
|
|
x{FA41} @Defop LDMSGADDRQ
|
|
x{FA42} @Defop PARSEMSGADDR
|
|
x{FA43} @Defop PARSEMSGADDRQ
|
|
x{FA44} @Defop REWRITESTDADDR
|
|
x{FA45} @Defop REWRITESTDADDRQ
|
|
x{FA46} @Defop REWRITEVARADDR
|
|
x{FA47} @Defop REWRITEVARADDRQ
|
|
|
|
x{FB00} @Defop SENDRAWMSG
|
|
x{FB02} @Defop RAWRESERVE
|
|
x{FB03} @Defop RAWRESERVEX
|
|
x{FB04} @Defop SETCODE
|
|
x{FB06} @Defop SETLIBCODE
|
|
x{FB07} @Defop CHANGELIB
|
|
x{FB08} @Defop SENDMSG
|
|
|
|
//
|
|
// debug primitives
|
|
|
|
{ dup 0 239 @-range abort"debug selector out of range"
|
|
<b x{FE} s, swap 8 u, @addopb
|
|
} : DEBUG
|
|
{ dup $len 1- <b x{FEF} s, swap 4 u, swap $, @addopb
|
|
} : DEBUGSTR
|
|
{ over $len <b x{FEF} s, swap 4 u, swap 8 u, swap $, @addopb
|
|
} : DEBUGSTRI
|
|
|
|
x{FE00} @Defop DUMPSTK
|
|
{ 1 15 @rangechk <b x{FE0} s, swap 4 u, @addopb
|
|
} : DUMPSTKTOP
|
|
x{FE10} @Defop HEXDUMP
|
|
x{FE11} @Defop HEXPRINT
|
|
x{FE12} @Defop BINDUMP
|
|
x{FE13} @Defop BINPRINT
|
|
x{FE14} @Defop STRDUMP
|
|
x{FE15} @Defop STRPRINT
|
|
x{FE1E} @Defop DEBUGOFF
|
|
x{FE1F} @Defop DEBUGON
|
|
x{FE2} @Defop(s) DUMP
|
|
x{FE3} @Defop(s) PRINT
|
|
' DEBUGSTR : DUMPTOSFMT
|
|
{ 0 DEBUGSTRI } : LOGSTR
|
|
{ 1 DEBUGSTRI } : PRINTSTR
|
|
x{FEF000} @Defop LOGFLUSH
|
|
|
|
//
|
|
// codepage primitives
|
|
x{FF00} @Defop SETCP0
|
|
x{FFF0} @Defop SETCPX
|
|
{ dup -14 239 @-range abort"codepage out of range"
|
|
255 and <b x{FF} s, swap 8 u, @addopb
|
|
} : SETCP
|
|
|
|
' @addop : CUSTOMOP
|
|
|
|
//
|
|
// provisions for defining programs consisting of several mutually-recursive procedures
|
|
//
|
|
variable @proccnt
|
|
variable @proclist
|
|
variable @procdict
|
|
variable @procinfo
|
|
variable @gvarcnt
|
|
variable @parent-state
|
|
variable asm-mode 1 asm-mode !
|
|
19 constant @procdictkeylen
|
|
32 constant @zcount
|
|
{ pair @proclist @ cons @proclist ! } : @proclistadd
|
|
{ @procinfo @ @procdictkeylen idict@ { 16 i@ } { 0 } cond } : @procinfo@
|
|
{ <b rot 16 i, swap @procinfo @ @procdictkeylen b>idict!
|
|
not abort"cannot add key to procedure info dictionary"
|
|
@procinfo !
|
|
} : @procinfo!
|
|
// ( x v1 v2 -- )
|
|
{ not 2 pick @procinfo@ and xor swap @procinfo! } : @procinfo~!
|
|
// ( s i f -- )
|
|
{ over @procdictkeylen fits not abort"procedure index out of range"
|
|
over swap dup @procinfo~! 2dup @proclistadd
|
|
1 'nop does swap 0 (create)
|
|
} : @declproc
|
|
{ 1 'nop does swap 0 (create) } : @declglobvar
|
|
{ @proccnt @ 1+ dup @proccnt ! 1 @declproc } : @newproc
|
|
{ @gvarcnt @ 1+ dup @gvarcnt ! @declglobvar } : @newglobvar
|
|
variable @oldcurrent variable @oldctx
|
|
Fift-wordlist dup @oldcurrent ! @oldctx !
|
|
{ current@ @oldcurrent ! context@ @oldctx ! Asm definitions
|
|
@proccnt @ @proclist @ @procdict @ @procinfo @ @gvarcnt @ @parent-state @ current@ @oldcurrent @ @oldctx @
|
|
9 tuple @parent-state !
|
|
hole current!
|
|
0 =: main @proclist null! @proccnt 0! @gvarcnt 0!
|
|
{ bl word @newproc } : NEWPROC
|
|
{ bl word dup (def?) ' drop ' @newproc cond } : DECLPROC
|
|
{ bl word dup find
|
|
{ nip execute <> abort"method redefined with different id" }
|
|
{ swap 17 @declproc }
|
|
cond } : DECLMETHOD
|
|
{ bl word @newglobvar } : DECLGLOBVAR
|
|
"main" 0 @proclistadd
|
|
dictnew dup @procdict !
|
|
@procinfo ! 16 0 @procinfo!
|
|
} : PROGRAM{
|
|
{ over sbits < { s>c <b swap ref, b> <s } if } : @adj-long-proc
|
|
{ // i s l
|
|
dup 0< {
|
|
negate
|
|
@was-split @ { drop 0 } if
|
|
} if
|
|
@adj-long-proc over @procdict @ @procdictkeylen
|
|
idict!+ not abort"cannot define procedure, redefined?"
|
|
@procdict ! 2 2 @procinfo~!
|
|
} : @def-proc
|
|
{ @procinfo @ null? not } : @have-procinfo?
|
|
{ @have-procinfo? { 4 4 @procinfo~! } { drop } cond } : @proc-inlined
|
|
{ @have-procinfo? { 8 8 @procinfo~! } { drop } cond } : @proc-called
|
|
{ 1000 @def-proc } : PROC
|
|
{ 0 @def-proc } : PROCREF
|
|
{ -1000 @def-proc } : PROCINLINE
|
|
{ @procdict @ @procdictkeylen idict@ abort"procedure already defined"
|
|
} : @fail-ifdef
|
|
{ u@?+ { swap abort"first bits are not zeroes" } if } : @cut-zeroes
|
|
{ over @fail-ifdef
|
|
2 { rot @normal? rot b> <s @zcount @cut-zeroes swap @def-proc drop } does
|
|
null swap @doafter<{ 0 @zcount u,
|
|
} : @PROC:<{
|
|
{ 1000 @PROC:<{ } : PROC:<{
|
|
{ 0 @PROC:<{ } : PROCREF:<{
|
|
{ -1000 @PROC:<{ } : PROCINLINE:<{
|
|
{ dup @proc-called CALLDICT } dup : CALL : CALLDICT
|
|
{ dup @proc-called JMPDICT } dup : JMP : JMPDICT
|
|
{ dup @proc-called PREPAREDICT } dup : PREPARE : PREPAREDICT
|
|
{ dup @procdict @ @procdictkeylen idict@
|
|
{ swap @proc-inlined INLINE } { CALLDICT } cond
|
|
} dup : INLINECALL : INLINECALLDICT
|
|
{ 0 @procdict @ @procdictkeylen idict@ not abort"`main` procedure not defined" drop
|
|
} : @chkmaindef
|
|
{ @procdict @ @procdictkeylen idict- drop @procdict ! } : @remove-proc
|
|
{ ."Procedure `" over type ."` index=" 2 pick . ." flags=0x" dup x. cr } : @showprocinfo
|
|
// ( proc_name proc_idx f -- ) f:+1=declared, +2=defined, +4=inlined, +8=called, +16=method
|
|
{ // @showprocinfo
|
|
dup 0x1a and 2 = asm-mode @ 3 and and ?dup {
|
|
2 and {
|
|
over ."Warning: removing (inlined) procedure `" type ."` from call dictionary" cr
|
|
} if
|
|
2 pick @remove-proc
|
|
} if // remove unused procs
|
|
dup 0xc and 0xc = asm-mode @ 4 and and {
|
|
over ."Warning: inline procedure `" type ."` is not always inlined" cr
|
|
} if
|
|
dup 0x1e and 2 = asm-mode @ 8 and and {
|
|
over ."Warning: procedure `" type ."` defined but not used" cr
|
|
} if
|
|
drop 2drop
|
|
} : @chkprocdef
|
|
{ @chkmaindef
|
|
@proclist @ { dup null? not } {
|
|
uncons swap unpair over find not
|
|
{ drop +": undefined procedure name in list" abort } if
|
|
drop tuck @procdict @ @procdictkeylen idict@ not
|
|
{ +": procedure declared but left undefined" abort } if
|
|
drop swap 2dup @procinfo@ @chkprocdef (forget)
|
|
} while
|
|
drop @proclist null! @procinfo null! @proccnt 0!
|
|
@procdict dup @ swap null!
|
|
@parent-state @ dup null? { drop } {
|
|
9 untuple
|
|
@oldctx ! @oldcurrent ! current! @parent-state ! @gvarcnt ! @procinfo ! @procdict ! @proclist ! @proccnt !
|
|
} cond
|
|
@oldctx @ context! @oldcurrent @ current!
|
|
} : }END
|
|
forget @proclist forget @proccnt
|
|
{ }END <{ SETCP0 swap @procdictkeylen DICTPUSHCONST DICTIGETJMPZ 11 THROWARG }> } : }END>
|
|
{ }END> b> } : }END>c
|
|
{ }END>c <s } : }END>s
|
|
|
|
// This is the way how FunC assigns method_id for reserved functions.
|
|
// Note, that Tolk entrypoints have other names (`onInternalMessage`, etc.),
|
|
// but method_id is assigned not by Fift, but by Tolk code generation.
|
|
0 constant recv_internal
|
|
-1 constant recv_external
|
|
-2 constant run_ticktock
|
|
-3 constant split_prepare
|
|
-4 constant split_install
|
|
|
|
{ asm-mode 0 3 ~! } : asm-no-remove-unused
|
|
{ asm-mode 1 1 ~! } : asm-remove-unused // enabled by default
|
|
{ asm-mode 3 3 ~! } : asm-warn-remove-unused
|
|
{ asm-mode 4 4 ~! } : asm-warn-inline-mix
|
|
{ asm-mode 0 4 ~! } : asm-no-warn-inline-mix // disabled by default
|
|
{ asm-mode 8 8 ~! } : asm-warn-unused
|
|
{ asm-mode 0 8 ~! } : asm-no-warn-unused // disabled by default
|
|
|
|
// ( c -- ) add vm library for later use with runvmcode
|
|
{ <b over ref, b> <s swap hash vmlibs @ 256 udict! not abort"cannot add library" vmlibs ! } : add-lib
|
|
// ( x -- c ) make library reference cell
|
|
{ <b 2 8 u, swap 256 u, b>spec } : hash>libref
|
|
// ( c -- c' )
|
|
{ hash hash>libref } : >libref
|
|
|
|
{ dup "." $pos dup -1 =
|
|
{ drop 0 }
|
|
{ $| 1 $| nip swap (number) 1- abort"invalid version"
|
|
dup dup 0 < swap 999 > or abort"invalid version"
|
|
}
|
|
cond
|
|
} : parse-version-level
|
|
|
|
{
|
|
0 swap
|
|
"." $+
|
|
{ swap 1000 * swap parse-version-level rot + swap } 3 times
|
|
"" $= not abort"invalid version"
|
|
} : parse-asm-fif-version
|
|
|
|
{
|
|
dup =: required-version parse-asm-fif-version
|
|
asm-fif-version parse-asm-fif-version
|
|
= 1+ {
|
|
"Required Asm.fif version: " @' required-version "; actual Asm.fif version: " asm-fif-version $+ $+ $+ abort
|
|
} if
|
|
} : require-asm-fif-version
|
|
|
|
{
|
|
dup =: required-version parse-asm-fif-version
|
|
asm-fif-version parse-asm-fif-version
|
|
swap
|
|
>= 1+ {
|
|
"Required Asm.fif version: " @' required-version "; actual Asm.fif version: " asm-fif-version $+ $+ $+ abort
|
|
} if
|
|
} : require-asm-fif-version>=
|
|
|
|
|
|
Fift definitions Asm
|
|
' <{ : <{
|
|
' PROGRAM{ : PROGRAM{
|
|
' asm-fif-version : asm-fif-version
|
|
' require-asm-fif-version : require-asm-fif-version
|
|
' require-asm-fif-version>= : require-asm-fif-version>=
|
|
Fift
|