77 lines
1.5 KiB
Plaintext
77 lines
1.5 KiB
Plaintext
// Implementing if statement if its not a built-in in SLC!
|
|
// Not compiler writing in SLC language, but SLCs builtin itself...
|
|
|
|
::builtin if @cmp @then @else
|
|
"" parseblock() // (*)
|
|
if@cmp(.)
|
|
"" parseblock{}
|
|
if@then(_)
|
|
// returns 0 if there was no [] block!
|
|
// Calling 0 means just calling the
|
|
// intstruction pointer ("avoiding call")
|
|
"" parseblock[]
|
|
if@else(_)
|
|
|
|
// (*) cmp result at top of stack
|
|
gen(!) gen(skipif) if@then
|
|
gen(skipif) if@else
|
|
;
|
|
|
|
// Alternatively - by adding "branchcall" to the builtins
|
|
::builtin if
|
|
"" parseblock()
|
|
genpush(_)
|
|
"" parseblock{}
|
|
genpush(_)
|
|
"" parseblock[] // returns 0 if there was no block (its SKIP to 'call' 0)
|
|
genpush(_)
|
|
gen(branchcall)
|
|
;
|
|
|
|
// Rem.: "branchcall" can be used in "real" code to split which word to call...
|
|
|
|
: smaller
|
|
"smaller"
|
|
;
|
|
|
|
: bigger
|
|
"bigger-or-eq"
|
|
;
|
|
|
|
// Gets a b
|
|
// returns "smaller" or "bigger-or-eq"
|
|
: smaller_or_bigger
|
|
<
|
|
gen(smaller)
|
|
gen(bigger)
|
|
branchcall
|
|
;
|
|
|
|
// Better example
|
|
|
|
: one 1 ;
|
|
: zero 0 ;
|
|
|
|
// Gets a b
|
|
// returns 1 if a < b, 0 otherwise
|
|
: smaller_or_bigger
|
|
<
|
|
gen(one)
|
|
gen(zero)
|
|
branchcall
|
|
;
|
|
|
|
// Alternatively I can just add a "branchskip" to the list of predefined words and way to just count words and geninline(..)
|
|
::builtin if
|
|
geninline()
|
|
genpush(_)
|
|
countwords{}
|
|
genpush(_)
|
|
countwords[] // returns 0 if there was no block (its SKIP to 'branchskip' 0)
|
|
genpush(_)
|
|
gen(branchskip)
|
|
;
|
|
|
|
// This is not only simpler, but one can implement branchcall via a tiny bit of branchskip and a call to be honest...
|
|
// Also I feel like this results in bytecode with much better cache locality.
|