X-Git-Url: https://thelambdalab.xyz/gitweb/index.cgi?a=blobdiff_plain;f=scheme.4th;h=5a049d4fe930fcff80ebd21f404f5be70dea251d;hb=35821ce20b4614368e7983ccc1132a74e5f9eacb;hp=b2efe17d61781da4fb1f5dea617a3784ae98bf08;hpb=cf26585a7a3b4bcbc7e5a234c9d5c9ff999922da;p=scheme.forth.jl.git diff --git a/scheme.4th b/scheme.4th index b2efe17..5a049d4 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 \ }}} @@ -885,6 +891,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 +971,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? ; @@ -1007,7 +1017,39 @@ parse-idx-stack parse-idx-sp ! 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 ) @@ -1046,32 +1088,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 +1164,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 +1191,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 - 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 @@ -1216,6 +1296,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 +1310,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 @@ -1412,24 +1496,36 @@ include scheme-primitives.4th swap - ; -: load ( addr n -- ) +: load ( addr n -- finalResult ) open-input-file empty-parse-str + ok-symbol ( port res ) + begin - 2dup read-port + 2over read-port ( port res obj ) 2dup EOF character-type objeq? if - 2drop close-port + 2drop 2swap close-port exit then - global-env obj@ eval - 2drop + 2swap 2drop ( port obj ) + + global-env obj@ eval ( port res ) 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 ---- @@ -1447,6 +1543,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 @@ -1457,9 +1554,6 @@ include scheme-primitives.4th again ; -: test s" fact.scm" ; -test load - forth definitions \ vim:fdm=marker