: objeq? ( obj obj -- bool )
rot = -rot = and ;
+: 2rot ( a1 a2 b1 b2 c1 c2 -- b1 b2 c1 c2 a1 a2 )
+ >R >R ( a1 a2 b1 b2 )
+ 2swap ( b1 b2 a1 a2 )
+ R> R> ( b1 b2 a1 a2 c1 c2 )
+ 2swap
+;
+
+: -2rot ( a1 a2 b1 b2 c1 c2 -- c1 c2 a1 a2 b1 b2 )
+ 2swap ( a1 a2 c1 c2 b1 b2 )
+ >R >R ( a1 a2 c1 c2 )
+ 2swap ( c1 c2 a1 a2 )
+ R> R>
+;
+
\ }}}
\ ---- Pre-defined symbols ---- {{{
create-symbol define define-symbol
create-symbol set! set!-symbol
create-symbol ok ok-symbol
+create-symbol if if-symbol
\ }}}
\ ---- Environments ---- {{{
-objvar global-env
-
: enclosing-env ( env -- env )
cdr ;
: add-binding ( var val frame -- )
2swap 2over frame-vals cons
- 2over set-car!
+ 2over set-cdr!
2swap 2over frame-vars cons
- swap set-cdr!
+ 2swap set-car!
;
: extend-env ( vars vals env -- env )
2dup nil objeq? false =
while
2over 2over first-frame
- lookup-var-frame if
+ get-vars-vals-frame if
2drop 2drop
vars fetchobj vals fetchobj true
exit
get-vars-vals if
2swap 2drop car
else
- bold fg red ." Tried to read unbound variable." reset-term abort
+ bold fg red ." Tried to read unbound variable." reset-term cr abort
then
;
2swap 2drop ( val vals )
set-car!
else
- bold fg red ." Tried to set unbound variable." reset-term abort
+ bold fg red ." Tried to set unbound variable." reset-term cr abort
then
;
objvar env
: define-var ( var val env -- )
- env objset
+ env setobj
- 2over env objfetch ( var val var env )
+ 2over env fetchobj ( var val var env )
get-vars-vals if
2swap 2drop ( var val vals )
set-car!
2drop
else
- env objfetch
+ env fetchobj
first-frame ( var val frame )
add-binding
then
hide env
+objvar global-env
+nil nil nil extend-env
+global-env setobj
+
\ }}}
\ ---- Read ---- {{{
\ ---- Eval ---- {{{
+defer eval
+
: self-evaluating? ( obj -- obj bool )
boolean-type istype? if true exit then
number-type istype? if true exit then
cdr cdr car ;
: assignment? ( obj -- obj bool )
- set-symbol tagged-list? ;
+ set!-symbol tagged-list? ;
: assignment-var ( obj -- var )
cdr car ;
2swap definition-var 2swap ( env var val )
- >R >R 2swap R> R> 2swap ( var val env )
+ 2rot ( var val env )
define-var
ok-symbol
2swap assignment-var 2swap ( env var val )
- >R >R 2swap R> R> 2swap ( var val env )
+ 2rot ( var val env )
set-var
ok-symbol
;
-: eval ( obj env -- result )
+
+: if? ( obj -- obj bool )
+ if-symbol tagged-list? ;
+
+: if-predicate ( ifobj -- pred )
+ cdr car ;
+
+: if-consequent ( ifobj -- conseq )
+ cdr cdr car ;
+
+: if-alternative ( ifobj -- alt|false )
+ cdr cdr cdr
+ 2dup nil objeq? if
+ 2drop false
+ else
+ car
+ then ;
+
+: false? ( boolobj -- boolean )
+ boolean-type istype? if
+ false boolean-type objeq?
+ else
+ 2drop false
+ then
+;
+
+: true? ( boolobj -- boolean )
+ false? invert ;
+
+:noname ( obj env -- result )
2swap
self-evaluating? if
exit
then
+ if? if
+ 2over 2over
+ if-predicate
+ 2swap eval
+
+ true? if
+ if-consequent
+ else
+ if-alternative
+ then
+
+ 2swap ['] eval goto
+ then
+
bold fg red ." Error evaluating expression - unrecognized type. Aborting." reset-term cr
abort
-;
+; is eval
\ }}}
;
forth definitions
+
+\ vim:fdm=marker