make-type character-type
make-type string-type
make-type nil-type
+make-type none-type
make-type pair-type
make-type symbol-type
make-type primitive-proc-type
: istype? ( obj type -- obj bool )
over = ;
-\ ------ List-structured memory ------ {{{
+\ ---- List-structured memory ---- {{{
10000 constant scheme-memsize
: nil 0 nil-type ;
: nil? nil-type istype? ;
+: none 0 none-type ;
+: none? none-type istype? ;
+
: objvar create nil swap , , ;
: value@ ( objvar -- val ) @ ;
does> dup @ swap 1+ @
;
-create-symbol quote quote-symbol
-create-symbol define define-symbol
-create-symbol set! set!-symbol
-create-symbol ok ok-symbol
-create-symbol if if-symbol
-create-symbol lambda lambda-symbol
-create-symbol λ λ-symbol
+create-symbol quote quote-symbol
+create-symbol define define-symbol
+create-symbol define-macro define-macro-symbol
+create-symbol set! set!-symbol
+create-symbol ok ok-symbol
+create-symbol if if-symbol
+create-symbol lambda lambda-symbol
+create-symbol λ λ-symbol
+create-symbol begin begin-symbol
\ }}}
character-type istype? if true exit then
string-type istype? if true exit then
nil-type istype? if true exit then
+ none-type istype? if true exit then
false
;
ok-symbol
;
+: macro-definition? ( obj -- obj bool )
+ define-macro-symbol tagged-list? ;
+
: if? ( obj -- obj bool )
if-symbol tagged-list? ;
drop compound-proc-type
;
-: application? ( obj -- obj bool)
+: begin? ( obj -- obj bool )
+ begin-symbol tagged-list? ;
+
+: begin-actions ( obj -- actions )
+ cdr ;
+
+: eval-sequence ( explist env -- finalexp env )
+ ( Evaluates all bar the final expressions in
+ an an expression list. The final expression
+ is returned to allow for tail optimization. )
+
+ 2swap ( env explist )
+
+ \ Abort on empty list
+ 2dup nil objeq? if
+ 2drop none
+ 2swap exit
+ then
+
+ begin
+ 2dup cdr ( env explist nextexplist )
+ 2dup nil objeq? false =
+ while
+ -2rot car 2over ( nextexplist env exp env )
+ eval
+ 2drop \ discard result
+ 2swap ( env nextexplist )
+ repeat
+
+ 2drop car 2swap ( finalexp env )
+;
+
+: application? ( obj -- obj bool )
pair-type istype? ;
: operator ( obj -- operator )
: procedure-env ( proc -- body )
drop pair-type cdr cdr car ;
-: apply ( proc args )
+( Ensure terminating symbol arg name is handled
+ specially to allow for variadic procedures. )
+: flatten-proc-args ( argvals argnames -- argvals' argnames' )
+ nil? if exit then
+
+ symbol-type istype? if
+ nil cons
+ 2swap
+ nil cons
+ 2swap
+ exit
+ then
+
+ 2over cdr 2over cdr
+ recurse ( argvals argnames argvals'' argnames'' )
+ 2rot car 2swap cons ( argvals argvals'' argnames' )
+ 2rot car 2rot cons ( argnames' argvals' )
+ 2swap
+;
+
+: apply ( proc argvals )
2swap dup case
primitive-proc-type of
drop execute
endof
compound-proc-type of
- 2dup procedure-body ( args proc body )
- -2rot 2dup procedure-params ( body args proc params )
- -2rot procedure-env ( body params args procenv )
-
- extend-env ( body env )
+ 2dup procedure-body ( argvals proc body )
+ -2rot 2dup procedure-params ( body argvals proc argnames )
+ -2rot procedure-env ( body argnames argvals procenv )
- 2swap ( env body )
+ -2rot 2swap
+ flatten-proc-args
+ 2swap 2rot
- begin
- 2dup cdr 2dup nil objeq? false =
- while
- -2rot car 2over ( nextbody env exp env )
- eval
- 2drop \ discard result
- 2swap ( env nextbody )
- repeat
+ extend-env ( body env )
- 2drop ( env body )
- car 2swap ( exp env )
+ eval-sequence
R> drop ['] eval goto-deferred \ Tail call optimization
endof
exit
then
+ macro-definition? if
+ 2swap eval-define-macro
+ exit
+ then
+
if? if
2over 2over
if-predicate
exit
then
+ begin? if
+ begin-actions 2swap
+ eval-sequence
+ ['] eval goto-deferred
+ then
+
application? if
+
2over 2over
- operator 2swap eval
- -2rot
- operands 2swap list-of-vals
+ operator
- apply
+ find-macro-proc nil objeq? if
+ \ Regular function application
+
+ 2swap eval
+ -2rot
+ operands 2swap list-of-vals
+
+ apply
+ else
+ \ Macro function evaluation
+
+ 2swap 2drop 2swap ( env mproc exp )
+
+ apply 2swap ( expanded-exp env )
+
+ ['] eval goto-deferred
+ then
exit
then
: printcomp ( primobj -- )
2drop ." <compound procedure>" ;
+: printnone ( noneobj -- )
+ 2drop ." Unspecified return value" ;
+
:noname ( obj -- )
fixnum-type istype? if printfixnum exit then
realnum-type istype? if printrealnum exit then
pair-type istype? if ." (" printpair ." )" exit then
primitive-proc-type istype? if printprim exit then
compound-proc-type istype? if printcomp exit then
+ none-type istype? if printnone exit then
bold fg red ." Error printing expression - unrecognized type. Aborting" reset-term cr
abort
read-console
2dup EOF character-type objeq? if
+ 2drop
bold fg blue ." Moriturus te saluto." reset-term cr
exit
then