make-type symbol-type
make-type primitive-proc-type
make-type compound-proc-type
+make-type continuation-type
make-type port-type
: istype? ( obj type -- obj bool )
over = ;
make-exception recoverable-exception
make-exception unrecoverable-exception
-: throw reset-term throw ;
+: throw reset-term cr throw ;
\ }}}
nextfree !
nextfree @ scheme-memsize >= if
- collect-garbage
+ collect-garbage
then
nextfree @ scheme-memsize >= if
cdr-cells + !
;
+variable object-stack-base
+: init-object-stack-base
+ depth object-stack-base ! ;
+
: nil 0 nil-type ;
: nil? nil-type istype? ;
\ }}}
+\ ---- Continuations ---- {{{
+
+: cons-return-stack ( -- listobj )
+ rsp@ 1- rsp0 = if
+ nil exit
+ then
+
+ nil rsp@ 1- rsp0 do
+ i 1+ @ fixnum-type 2swap cons
+ loop
+;
+
+: cons-param-stack ( -- listobj )
+ nil
+
+ depth 2- object-stack-base @ = if
+ exit
+ then
+
+ depth 2- object-stack-base @ do
+ PSP0 i + 1 + @
+ PSP0 i + 2 + @
+
+ 2swap cons
+ 2 +loop
+;
+
+: make-continuation
+
+ cons-param-stack
+ cons-return-stack
+ cons drop continuation-type
+;
+
+: restore-continuation
+ \ TODO: replace current parameter and return stacks with
+ \ contents of continuation object.
+;
+
+\ }}}
+
\ ---- Primitives ---- {{{
: make-primitive ( cfa -- )
exit
then
+ nextchar [char] ) = if
+ inc-parse-idx
+ except-message: ." unmatched closing parenthesis." recoverable-exception throw
+ then
+
\ Anything else is parsed as a symbol
readsymbol charlist>symbol
\ }}}
-\ ---- Eval ---- {{{
+\ ---- Syntax ---- {{{
: self-evaluating? ( obj -- obj bool )
boolean-type istype? if true exit then
: definition-val ( obj -- val )
cdr cdr car ;
-: eval-definition ( obj env -- res )
- 2swap
- 2over 2over
- definition-val 2swap
- eval
-
- 2swap definition-var 2swap
-
- 2rot
- define-var
-
- ok-symbol
-;
-
: assignment? ( obj -- obj bool )
set!-symbol tagged-list? ;
: assignment-val ( obj -- val )
cdr cdr car ;
-: eval-assignment ( obj env -- res )
- 2swap
- 2over 2over ( env obj env obj )
- assignment-val 2swap ( env obj valexp env )
- eval ( env obj val )
-
- 2swap assignment-var 2swap ( env var val )
-
- 2rot ( var val env )
- set-var
-
- ok-symbol
-;
-
: macro-definition? ( obj -- obj bool )
define-macro-symbol tagged-list? ;
: macro-definition-body ( exp -- body )
cdr cdr ;
-objvar env
-: eval-define-macro ( obj env -- res )
- env obj!
-
- 2dup macro-definition-name 2swap ( name obj )
- 2dup macro-definition-params 2swap ( name params obj )
- macro-definition-body ( name params body )
-
- env obj@ ( name params body env )
-
- make-macro
-
- ok-symbol
-;
-hide env
-
: if? ( obj -- obj bool )
if-symbol tagged-list? ;
: lambda-body ( obj -- body )
cdr 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
- nil? if
- 2drop none
- 2swap exit
- then
-
- begin
- 2dup cdr ( env explist nextexplist )
- nil? 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? ;
: rest-operands ( operands -- other-operands )
cdr ;
-: list-of-vals ( args env -- vals )
- 2swap
-
- 2dup nooperands? if
- 2swap 2drop
- else
- 2over 2over first-operand 2swap eval
- -2rot rest-operands 2swap recurse
- cons
- then
-;
-
: procedure-params ( proc -- params )
drop pair-type car ;
\ }}}
-\ ---- Analyze ----
+\ ---- Analyze ---- {{{
: evaluate-eproc ( eproc env --- res )
nil cons cons cons
;
-: if-executor ( cproc aproc pproc env -- res )
- 2swap 2over ( cproc aproc env pproc env -- res )
- evaluate-eproc
-
- true? if
- 2swap 2drop
- else
- 2rot 2drop
- then
-
- evaluate-eproc
-;
-
-: analyze-if ( exp -- eproc )
- 2dup if-predicate analyze
- 2swap 2dup if-consequent analyze
- 2swap if-alternative analyze
-
- ['] if-executor primitive-proc-type
- nil cons cons cons cons
-;
-
: sequence-executor ( eproc-list env -- res )
2swap
2dup cdr ( env elist elist-rest)
nil? invert
while
-
-2rot car 2over ( elist-rest env elist-head env )
evaluate-eproc ( elist-rest env head-res )
2drop 2swap ( env elist-rest )
nil cons cons
;
+
+: macro-definition-executor ( name params bproc env -- ok )
+ make-macro ok-symbol
+;
+
+: analyze-macro-definition ( exp -- eproc )
+ 2dup macro-definition-name
+ 2swap 2dup macro-definition-params
+ 2swap macro-definition-body analyze-sequence
+
+ ['] macro-definition-executor primitive-proc-type
+ nil cons cons cons cons
+;
+
+: if-executor ( cproc aproc pproc env -- res )
+ 2swap 2over ( cproc aproc env pproc env -- res )
+ evaluate-eproc
+
+ true? if
+ 2swap 2drop
+ else
+ 2rot 2drop
+ then
+
+ ['] evaluate-eproc goto
+;
+
+: analyze-if ( exp -- eproc )
+ 2dup if-consequent analyze
+ 2swap 2dup if-alternative analyze
+ 2swap if-predicate analyze
+
+ ['] if-executor primitive-proc-type
+ nil cons cons cons cons
+;
+
: lambda-executor ( params bproc env -- res )
make-procedure
( Although this is packaged up as a regular compound procedure,
then
;
-: application-executor ( operator-proc arg-procs env -- res )
- 2rot 2over ( aprocs env fproc env )
- evaluate-eproc ( aprocs env proc )
-
- -2rot 2swap ( proc env aprocs )
- evaluate-operand-eprocs ( proc vals )
-
- 2swap ( vals proc )
-
+: apply ( vals proc )
dup case
primitive-proc-type of
drop execute
endof
compound-proc-type of
- 2dup procedure-body ( argvals proc body )
+ 2dup procedure-body ( argvals proc bproc )
-2rot 2dup procedure-params ( bproc argvals proc argnames )
-2rot procedure-env ( bproc argnames argvals procenv )
['] evaluate-eproc goto
endof
+ continuation-type of
+ \ TODO: Apply continuation
+ endof
+
except-message: ." object '" drop print ." ' not applicable." recoverable-exception throw
endcase
;
+: application-executor ( operator-proc arg-procs env -- res )
+ 2rot 2over ( aprocs env fproc env )
+ evaluate-eproc ( aprocs env proc )
+
+ -2rot 2swap ( proc env aprocs )
+ evaluate-operand-eprocs ( proc vals )
+
+ 2swap ( vals proc )
+
+ ['] apply goto
+;
+
: analyze-application ( exp -- eproc )
2dup operator analyze
2swap operands operand-eproc-list
:noname ( exp --- eproc )
- self-evaluating? if
- analyze-self-evaluating
- exit
- then
+ self-evaluating? if analyze-self-evaluating exit then
- quote? if
- analyze-quoted
- exit
- then
+ quote? if analyze-quoted exit then
- variable? if
- analyze-variable
- exit
- then
+ variable? if analyze-variable exit then
- definition? if
- analyze-definition
- exit
- then
+ definition? if analyze-definition exit then
-\ macro-definition? if
-\ analyze-macro-definition
-\ exit
-\ then
+ assignment? if analyze-assignment exit then
- assignment? if
- analyze-assignment
- exit
- then
+ macro-definition? if analyze-macro-definition exit then
- if? if
- analyze-if
- exit
- then
+ if? if analyze-if exit then
- lambda? if
- analyze-lambda
- exit
- then
+ lambda? if analyze-lambda exit then
- application? if
- analyze-application
- exit
- then
+ application? if analyze-application exit then
-
except-message: ." tried to analyze unknown expression type." recoverable-exception throw
; is analyze
+\ }}}
\ ---- Macro Expansion ---- {{{
( Simply evaluates the given procedure with expbody as its argument. )
: macro-eval ( proc expbody -- result )
2swap
- 2dup procedure-body ( expbody proc procbody )
- -2rot 2dup procedure-params ( procbody expbody proc argnames )
- -2rot procedure-env ( procbody argnames expbody procenv )
+ 2dup procedure-body ( expbody proc bproc )
+ -2rot 2dup procedure-params ( bproc expbody proc argnames )
+ -2rot procedure-env ( bproc argnames expbody procenv )
-2rot 2swap
flatten-proc-args
2swap 2rot
- extend-env eval-sequence eval
+ extend-env ( bproc env )
+
+ ['] evaluate-eproc goto
;
: expand-macro ( exp -- result )
pair-type istype? invert if exit then
+
2dup car symbol-type istype? invert if 2drop exit then
-
- lookup-macro nil? if
- 2drop exit then
+
+ lookup-macro nil? if 2drop exit then
2over cdr macro-eval
: printcomp ( primobj -- )
2drop ." <compound procedure>" ;
+: printcont ( primobj --)
+ 2drop ." <continuation>" ;
+
: printnone ( noneobj -- )
2drop ." Unspecified return value" ;
pair-type istype? if ." (" printpair ." )" exit then
primitive-proc-type istype? if printprim exit then
compound-proc-type istype? if printcomp exit then
+ continuation-type istype? if printcont exit then
none-type istype? if printnone exit then
port-type istype? if printport exit then
\ ---- Garbage Collection ---- {{{
-variable gc-enabled
-false gc-enabled !
-
-variable gc-stack-depth
-
-: enable-gc
- depth gc-stack-depth !
- true gc-enabled ! ;
-
-: disable-gc
- false gc-enabled ! ;
-
-: gc-enabled?
- gc-enabled @ ;
-
: pairlike? ( obj -- obj bool )
pair-type istype? if true exit then
string-type istype? if true exit then
console-i/o-port obj@ gc-mark-obj
global-env obj@ gc-mark-obj
- depth gc-stack-depth @ do
+ depth object-stack-base @ do
PSP0 i + 1 + @
PSP0 i + 2 + @
ok-symbol ( port res )
begin
+ \ DEBUG
+ \ bold fg blue ." READ from " 2over drop . ." ==> " reset-term
+
2over read-port ( port res obj )
+ \ DEBUG
+ \ 2dup print cr
+
2dup EOF character-type objeq? if
2drop 2swap close-port
exit
include scheme-primitives.4th
- \ s" scheme-library.scm" load 2drop
+ init-object-stack-base
+ s" scheme-library.scm" load 2drop
\ }}}
: repl
empty-parse-str
- enable-gc
+ init-object-stack-base
\ Display welcome message
- \ welcome-symbol nil cons global-env obj@ eval 2drop
+ welcome-symbol nil cons global-env obj@ eval 2drop
begin
['] repl-body catch