X-Git-Url: https://thelambdalab.xyz/gitweb/index.cgi?a=blobdiff_plain;f=scheme.4th;h=7ac6355287f14b249c1a201d0de7d517756fc81d;hb=a966a509dd23259423e21c55d973403b88b86ea4;hp=7626be8f14da773387cdf2a3b821399ce2c157ef;hpb=aad554fc41d2b418e63b4320e8f793f28ffac6bf;p=scheme.forth.jl.git diff --git a/scheme.4th b/scheme.4th index 7626be8..7ac6355 100644 --- a/scheme.4th +++ b/scheme.4th @@ -28,6 +28,7 @@ make-type boolean-type 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 @@ -36,7 +37,7 @@ make-type fileport-type : istype? ( obj type -- obj bool ) over = ; -\ ------ List-structured memory ------ {{{ +\ ---- List-structured memory ---- {{{ 10000 constant scheme-memsize @@ -112,6 +113,9 @@ variable nextfree : nil 0 nil-type ; : nil? nil-type istype? ; +: none 0 none-type ; +: none? none-type istype? ; + : objvar create nil swap , , ; : value@ ( objvar -- val ) @ ; @@ -264,13 +268,15 @@ objvar symbol-table 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 \ }}} @@ -386,12 +392,67 @@ objvar env hide env +: make-procedure ( params body env -- proc ) + nil + cons cons cons + drop compound-proc-type +; + objvar global-env nil nil nil extend-env global-env obj! \ }}} +\ ---- Macros ---- {{{ + +objvar macro-table + +: lookup-macro ( name_symbol -- proc? bool ) + macro-table obj@ + + begin + nil? false = + while + 2over 2over + car car objeq? if + 2swap 2drop + car cdr + true exit + then + repeat + + 2drop false +; + +: make-macro ( name_symbol params body env -- ) + make-procedure + + 2swap ( proc name_symbol ) + + macro-table obj@ + + begin + nil? false = + while + 2over 2over ( proc name table name table ) + car car objeq? if + 2swap 2drop ( proc table ) + car ( proc entry ) + set-cdr! + exit + then + repeat + + 2drop + + 2swap cons + macro-table obj@ cons + macro-table obj! +; + +\ }}} + \ ---- Read ---- {{{ variable parse-idx @@ -885,6 +946,7 @@ parse-idx-stack parse-idx-sp ! 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 ; @@ -964,6 +1026,9 @@ parse-idx-stack parse-idx-sp ! ok-symbol ; +: macro-definition? ( obj -- obj bool ) + define-macro-symbol tagged-list? ; + : if? ( obj -- obj bool ) if-symbol tagged-list? ; @@ -1001,13 +1066,39 @@ parse-idx-stack parse-idx-sp ! : lambda-body ( obj -- body ) cdr cdr ; -: make-procedure ( params body env -- proc ) - nil - cons cons cons - drop compound-proc-type +: 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) +: application? ( obj -- obj bool ) pair-type istype? ; : operator ( obj -- operator ) @@ -1046,32 +1137,44 @@ parse-idx-stack parse-idx-sp ! : 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 ) + 2dup procedure-body ( argvals proc body ) + -2rot 2dup procedure-params ( body argvals proc argnames ) + -2rot procedure-env ( body argnames argvals procenv ) - extend-env ( body env ) - - 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 @@ -1110,6 +1213,11 @@ parse-idx-stack parse-idx-sp ! exit then + macro-definition? if + 2swap eval-define-macro + exit + then + if? if 2over 2over if-predicate @@ -1132,13 +1240,34 @@ parse-idx-stack parse-idx-sp ! 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 + + find-macro-proc nil objeq? if + \ Regular function application - apply + 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 @@ -1216,6 +1345,9 @@ parse-idx-stack parse-idx-sp ! : printcomp ( primobj -- ) 2drop ." " ; +: printnone ( noneobj -- ) + 2drop ." Unspecified return value" ; + :noname ( obj -- ) fixnum-type istype? if printfixnum exit then realnum-type istype? if printrealnum exit then @@ -1227,6 +1359,7 @@ parse-idx-stack parse-idx-sp ! 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 @@ -1321,6 +1454,7 @@ variable gc-stack-depth gc-unmark symbol-table obj@ gc-mark-obj + macro-table obj@ gc-mark-obj global-env obj@ gc-mark-obj depth gc-stack-depth @ do @@ -1433,6 +1567,15 @@ include scheme-primitives.4th again ; +:noname ( args -- finalResult ) + 2dup 1 ensure-arg-count + car string-type ensure-arg-type + + drop pair-type + pad charlist>cstr + pad swap load +; make-primitive load + \ }}} \ ---- REPL ---- @@ -1450,6 +1593,7 @@ include scheme-primitives.4th read-console 2dup EOF character-type objeq? if + 2drop bold fg blue ." Moriturus te saluto." reset-term cr exit then @@ -1460,9 +1604,6 @@ include scheme-primitives.4th again ; -: test s" fact.scm" ; -test load 2drop - forth definitions \ vim:fdm=marker