slc/examples/if.slc
2025-01-28 16:46:17 +01:00

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.