diff options
| author | Chouser <chouser@n01se.net> | 2015-02-19 19:42:52 -0500 |
|---|---|---|
| committer | Chouser <chouser@n01se.net> | 2015-02-21 13:22:44 -0500 |
| commit | 45c1894b9690b1156ffdc2caeb726bbc9526597a (patch) | |
| tree | 4e75609151fc88e78a2ccf93b0f6d2ac880f92c1 | |
| parent | 6512bd80002eb106a304b035e9592847d90ef23c (diff) | |
| download | mal-45c1894b9690b1156ffdc2caeb726bbc9526597a.tar.gz mal-45c1894b9690b1156ffdc2caeb726bbc9526597a.zip | |
forth: Back-propogate fixes from stepA through step1
| -rw-r--r-- | forth/step1_read_print.fs | 22 | ||||
| -rw-r--r-- | forth/step2_eval.fs | 86 | ||||
| -rw-r--r-- | forth/step3_env.fs | 93 | ||||
| -rw-r--r-- | forth/step4_if_fn_do.fs | 115 | ||||
| -rw-r--r-- | forth/step5_tco.fs | 59 | ||||
| -rw-r--r-- | forth/step6_file.fs | 33 | ||||
| -rw-r--r-- | forth/step7_quote.fs | 33 | ||||
| -rw-r--r-- | forth/step8_macros.fs | 26 | ||||
| -rw-r--r-- | forth/step9_try.fs | 45 | ||||
| -rw-r--r-- | forth/stepA_interop.fs | 27 | ||||
| -rw-r--r-- | forth/types.fs | 2 |
11 files changed, 233 insertions, 308 deletions
diff --git a/forth/step1_read_print.fs b/forth/step1_read_print.fs index 02783bf..9e42995 100644 --- a/forth/step1_read_print.fs +++ b/forth/step1_read_print.fs @@ -3,34 +3,32 @@ require printer.fs : read read-str ; : eval ; -: print pr-str ; +: print + \ ." Type: " dup mal-type @ type-name safe-type cr + pr-str ; -: rep +: rep ( str-addr str-len -- str-addr str-len ) read eval print ; create buff 128 allot +77777777777 constant stack-leak-detect : read-lines begin ." user> " + stack-leak-detect buff 128 stdin read-line throw - while - buff swap + while ( num-bytes-read ) + buff swap ( str-addr str-len ) ['] rep \ execute safe-type - catch 0= if safe-type endif + catch ?dup 0= if safe-type else ." Caught error " . endif cr + stack-leak-detect <> if ." --stack leak--" cr endif repeat ; -\ s" 1 (42 1 (2 12 8)) 35" swap 1+ swap .s read-str .s -\ s" 7" .s read-str .s -\ cr -\ pr-str safe-type cr -\ new-str s" hello" str-append char ! str-append-char safe-type -\ s\" he\nllo" MalString. pr-str safe-type cr - read-lines cr bye diff --git a/forth/step2_eval.fs b/forth/step2_eval.fs index 4963111..2b55ce0 100644 --- a/forth/step2_eval.fs +++ b/forth/step2_eval.fs @@ -13,23 +13,43 @@ MalMap/Empty s" /" MalSymbol. :noname args-as-native / MalInt. ; MalNativeFn. rot assoc value repl-env -def-protocol-method mal-eval ( env ast -- val ) -def-protocol-method mal-eval-ast ( env ast -- val ) -def-protocol-method invoke ( argv argc mal-fn -- ... ) +: read read-str ; +: eval ( env obj ) mal-eval ; +: print + \ ." Type: " dup mal-type @ type-name safe-type cr + pr-str ; -MalDefault extend mal-eval nip ;; drop +MalDefault extend mal-eval nip ;; drop \ By default, evalutate to yourself MalKeyword - extend invoke { argv argc kw -- val } - argc 1 > if argv cell+ @ else mal-nil endif \ not-found - kw \ key - argv @ \ map - get ;; + extend eval-invoke { env list kw -- val } + 0 kw env list MalList/start @ cell+ @ eval get + ?dup 0= if + \ compute not-found value + list MalList/count @ 1 > if + env list MalList/start @ 2 cells + @ eval + else + mal-nil + endif + endif ;; drop +\ eval all but the first item of list +: eval-rest { env list -- argv argc } + list MalList/start @ cell+ { expr-start } + list MalList/count @ 1- { argc } + argc cells allocate throw { target } + argc 0 ?do + env expr-start i cells + @ eval + target i cells + ! + loop + target argc ; + MalNativeFn - extend invoke ( ... mal-fn -- ... ) - MalNativeFn/xt @ execute ;; + extend eval-invoke ( env list this -- list ) + MalNativeFn/xt @ { xt } + eval-rest ( argv argc ) + xt execute ( return-val ) ;; drop MalSymbol @@ -44,62 +64,52 @@ MalSymbol endif ;; drop -MalList - extend mal-eval { env list -- val } - \ Pass args on dictionary stack (!) - \ TODO: consider allocate and free of a real MalList instead - here { val-start } - list MalList/start @ { expr-start } - list MalList/count @ 0 ?do - env expr-start i cells + @ mal-eval , - loop - val-start cell+ here val-start - cell / 1- val-start @ ( argv argc MalNativeFn ) - invoke - val-start here - allot ;; - extend mal-eval-ast { env list -- list } +: eval-ast { env list -- list } here list MalList/start @ { expr-start } list MalList/count @ 0 ?do - env expr-start i cells + @ mal-eval , + env expr-start i cells + @ eval , loop - here>MalList ;; + here>MalList ; + +MalList + extend mal-eval { env list -- val } + env list MalList/start @ @ eval + env list rot eval-invoke ;; drop MalVector extend mal-eval ( env vector -- vector ) - MalVector/list @ mal-eval-ast + MalVector/list @ eval-ast MalVector new swap over MalVector/list ! ;; drop MalMap extend mal-eval ( env map -- map ) - MalMap/list @ mal-eval-ast + MalMap/list @ eval-ast MalMap new swap over MalMap/list ! ;; drop -: read read-str ; -: eval ( env obj ) mal-eval ; -: print - \ ." Type: " dup mal-type @ type-name safe-type cr - pr-str ; - -: rep ( str -- val ) +: rep ( str-addr str-len -- str-addr str-len ) read repl-env swap eval print ; create buff 128 allot +77777777777 constant stack-leak-detect : read-lines begin ." user> " + stack-leak-detect buff 128 stdin read-line throw - while - buff swap + while ( num-bytes-read ) + buff swap ( str-addr str-len ) ['] rep \ execute safe-type - catch 0= if safe-type else ." Caught error" endif + catch ?dup 0= if safe-type else ." Caught error " . endif cr + stack-leak-detect <> if ." --stack leak--" cr endif repeat ; read-lines diff --git a/forth/step3_env.fs b/forth/step3_env.fs index 7dc9d7e..676bfcc 100644 --- a/forth/step3_env.fs +++ b/forth/step3_env.fs @@ -13,44 +13,47 @@ s" -" MalSymbol. :noname args-as-native - MalInt. ; MalNativeFn. repl-env env/ s" *" MalSymbol. :noname args-as-native * MalInt. ; MalNativeFn. repl-env env/set s" /" MalSymbol. :noname args-as-native / MalInt. ; MalNativeFn. repl-env env/set -\ Fully evalutate any Mal object: -def-protocol-method mal-eval ( env ast -- val ) - -\ Invoke an object, given whole env and unevaluated argument forms: -def-protocol-method invoke ( argv argc mal-fn -- ... ) +: read read-str ; +: eval ( env obj ) mal-eval ; +: print + \ ." Type: " dup mal-type @ type-name safe-type cr + pr-str ; -MalDefault extend mal-eval nip ;; drop +MalDefault extend mal-eval nip ;; drop \ By default, evalutate to yourself MalKeyword - extend invoke { env list kw -- val } - 0 kw env list MalList/start @ cell+ @ mal-eval get + extend eval-invoke { env list kw -- val } + 0 kw env list MalList/start @ cell+ @ eval get ?dup 0= if \ compute not-found value list MalList/count @ 1 > if - env list MalList/start @ 2 cells + @ mal-eval + env list MalList/start @ 2 cells + @ eval else mal-nil endif endif ;; drop -MalNativeFn - extend invoke { env list this -- list } - \ Pass args on dictionary stack (!) - \ TODO: consider allocate and free of a real MalList instead - \ Normal list, evaluate and invoke - here { val-start } - list MalList/start @ { expr-start } - list MalList/count @ 1 ?do - env expr-start i cells + @ mal-eval , +\ eval all but the first item of list +: eval-rest { env list -- argv argc } + list MalList/start @ cell+ { expr-start } + list MalList/count @ 1- { argc } + argc cells allocate throw { target } + argc 0 ?do + env expr-start i cells + @ eval + target i cells + ! loop - val-start here val-start - cell / this ( argv argc MalNativeFn ) - MalNativeFn/xt @ execute - val-start here - allot ;; + target argc ; + +MalNativeFn + extend eval-invoke ( env list this -- list ) + MalNativeFn/xt @ { xt } + eval-rest ( argv argc ) + xt execute ( return-val ) ;; drop SpecialOp - extend invoke ( env list this -- list ) + extend eval-invoke ( env list this -- list ) SpecialOp/xt @ execute ;; drop @@ -66,24 +69,23 @@ drop defspecial quote ( env list -- form ) nip MalList/start @ cell+ @ ;; -defspecial def! { env list -- } +defspecial def! { env list -- val } list MalList/start @ cell+ { arg0 } arg0 @ ( key ) - env arg0 cell+ @ mal-eval dup { val } ( key val ) - env env/set - val ;; + env arg0 cell+ @ eval dup { val } ( key val ) + env env/set val ;; -defspecial let* { old-env list -- } +defspecial let* { old-env list -- val } old-env MalEnv. { env } list MalList/start @ cell+ dup { arg0 } @ to-list dup MalList/start @ { bindings-start } ( list ) MalList/count @ 0 +do bindings-start i cells + dup @ swap cell+ @ ( sym expr ) - env swap mal-eval + env swap eval env env/set 2 +loop - env arg0 cell+ @ mal-eval + env arg0 cell+ @ eval \ TODO: dec refcount of env ;; @@ -99,57 +101,52 @@ MalSymbol endif ;; drop -: mal-eval-ast { env list -- list } +: eval-ast { env list -- list } here list MalList/start @ { expr-start } list MalList/count @ 0 ?do - env expr-start i cells + @ mal-eval , + env expr-start i cells + @ eval , loop here>MalList ; MalList extend mal-eval { env list -- val } - env list MalList/start @ @ mal-eval - env list rot invoke ;; + env list MalList/start @ @ eval + env list rot eval-invoke ;; drop MalVector extend mal-eval ( env vector -- vector ) - MalVector/list @ mal-eval-ast + MalVector/list @ eval-ast MalVector new swap over MalVector/list ! ;; drop MalMap extend mal-eval ( env map -- map ) - MalMap/list @ mal-eval-ast + MalMap/list @ eval-ast MalMap new swap over MalMap/list ! ;; drop -: read read-str ; -: eval ( env obj ) mal-eval ; -: print - \ ." Type: " dup mal-type @ type-name safe-type cr - pr-str ; - -: rep ( str -- val ) +: rep ( str-addr str-len -- str-addr str-len ) read repl-env swap eval print ; create buff 128 allot +77777777777 constant stack-leak-detect : read-lines begin ." user> " - 42042042042 + stack-leak-detect buff 128 stdin read-line throw - while - buff swap + while ( num-bytes-read ) + buff swap ( str-addr str-len ) ['] rep - execute safe-type - \ catch 0= if safe-type else ." Caught error" endif + \ execute safe-type + catch ?dup 0= if safe-type else ." Caught error " . endif cr - 42042042042 <> if ." --stack leak--" cr endif + stack-leak-detect <> if ." --stack leak--" cr endif repeat ; read-lines diff --git a/forth/step4_if_fn_do.fs b/forth/step4_if_fn_do.fs index 46163bc..4fd277e 100644 --- a/forth/step4_if_fn_do.fs +++ b/forth/step4_if_fn_do.fs @@ -4,53 +4,47 @@ require core.fs core MalEnv. constant repl-env -\ Fully evalutate any Mal object: -def-protocol-method mal-eval ( env ast -- val ) - -\ Invoke an object, given whole env and unevaluated argument forms: -def-protocol-method invoke ( argv argc mal-fn -- ... ) +: read read-str ; +: eval ( env obj ) mal-eval ; +: print + \ ." Type: " dup mal-type @ type-name safe-type cr + pr-str ; -MalDefault extend mal-eval nip ;; drop +MalDefault extend mal-eval nip ;; drop \ By default, evalutate to yourself MalKeyword - extend invoke { env list kw -- val } - 0 kw env list MalList/start @ cell+ @ mal-eval get + extend eval-invoke { env list kw -- val } + 0 kw env list MalList/start @ cell+ @ eval get ?dup 0= if \ compute not-found value list MalList/count @ 1 > if - env list MalList/start @ 2 cells + @ mal-eval + env list MalList/start @ 2 cells + @ eval else mal-nil endif endif ;; drop -\ eval all but the first item of list, storing in temporary memory -\ that should be freed with free-eval-rest when done. -: eval-rest { env list -- mem-token argv argc } - \ Pass args on dictionary stack (!) - \ TODO: consider allocate and free of a real MalList instead - \ Normal list, evaluate and invoke - here { val-start } +\ eval all but the first item of list +: eval-rest { env list -- argv argc } list MalList/start @ cell+ { expr-start } - list MalList/count @ 1- dup { argc } 0 ?do - env expr-start i cells + @ mal-eval , + list MalList/count @ 1- { argc } + argc cells allocate throw { target } + argc 0 ?do + env expr-start i cells + @ eval + target i cells + ! loop - val-start val-start argc ; - -: free-eval-rest ( mem-token/val-start -- ) - here - allot ; + target argc ; MalNativeFn - extend invoke ( env list this -- list ) + extend eval-invoke ( env list this -- list ) MalNativeFn/xt @ { xt } - eval-rest ( mem-token argv argc ) - xt execute ( mem-token return-val ) - swap free-eval-rest ;; + eval-rest ( argv argc ) + xt execute ( return-val ) ;; drop SpecialOp - extend invoke ( env list this -- list ) + extend eval-invoke ( env list this -- list ) SpecialOp/xt @ execute ;; drop @@ -69,9 +63,8 @@ defspecial quote ( env list -- form ) defspecial def! { env list -- val } list MalList/start @ cell+ { arg0 } arg0 @ ( key ) - env arg0 cell+ @ mal-eval dup { val } ( key val ) - env env/set - val ;; + env arg0 cell+ @ eval dup { val } ( key val ) + env env/set val ;; defspecial let* { old-env list -- val } old-env MalEnv. { env } @@ -80,10 +73,10 @@ defspecial let* { old-env list -- val } dup MalList/start @ { bindings-start } ( list ) MalList/count @ 0 +do bindings-start i cells + dup @ swap cell+ @ ( sym expr ) - env swap mal-eval + env swap eval env env/set 2 +loop - env arg0 cell+ @ mal-eval + env arg0 cell+ @ eval \ TODO: dec refcount of env ;; @@ -92,13 +85,13 @@ defspecial do { env list -- val } 0 list MalList/count @ 1 ?do drop - dup i cells + @ env swap mal-eval + dup i cells + @ env swap eval loop nip ;; defspecial if { env list -- val } list MalList/start @ cell+ { arg0 } - env arg0 @ mal-eval ( test-val ) + env arg0 @ eval ( test-val ) dup mal-false = if drop -1 else @@ -107,30 +100,22 @@ defspecial if { env list -- val } if \ branch to false list MalList/count @ 3 > if - env arg0 cell+ cell+ @ mal-eval + env arg0 cell+ cell+ @ eval else mal-nil endif else \ branch to true - env arg0 cell+ @ mal-eval + env arg0 cell+ @ eval endif ;; s" &" MalSymbol. constant &-sym MalUserFn - extend invoke { call-env list mal-fn -- list } - call-env list eval-rest { mem-token argv argc } + extend eval-invoke { call-env list mal-fn -- list } + call-env list eval-rest { argv argc } mal-fn MalUserFn/formal-args @ { f-args-list } - \ \ This isn't correct for fns with & in their f-args-list: - \ f-args-list MalList/count @ argc 2dup = if - \ 2drop - \ else - \ ." Argument mismatch on user fn. Got " . ." but expected " . cr - \ 1 throw - \ endif - mal-fn MalUserFn/env @ MalEnv. { env } f-args-list MalList/start @ { f-args } @@ -154,9 +139,8 @@ MalUserFn env env/set loop - env mal-fn MalUserFn/body @ mal-eval - - mem-token free-eval-rest ;; + env mal-fn MalUserFn/body @ eval ;; +drop defspecial fn* { env list -- val } list MalList/start @ cell+ { arg0 } @@ -177,57 +161,52 @@ MalSymbol endif ;; drop -: mal-eval-ast { env list -- list } +: eval-ast { env list -- list } here list MalList/start @ { expr-start } list MalList/count @ 0 ?do - env expr-start i cells + @ mal-eval , + env expr-start i cells + @ eval , loop here>MalList ; MalList extend mal-eval { env list -- val } - env list MalList/start @ @ mal-eval - env list rot invoke ;; + env list MalList/start @ @ eval + env list rot eval-invoke ;; drop MalVector extend mal-eval ( env vector -- vector ) - MalVector/list @ mal-eval-ast + MalVector/list @ eval-ast MalVector new swap over MalVector/list ! ;; drop MalMap extend mal-eval ( env map -- map ) - MalMap/list @ mal-eval-ast + MalMap/list @ eval-ast MalMap new swap over MalMap/list ! ;; drop -: read read-str ; -: eval ( env obj ) mal-eval ; -: print - \ ." Type: " dup mal-type @ type-name safe-type cr - pr-str ; - -: rep ( str -- val ) +: rep ( str-addr str-len -- str-addr str-len ) read repl-env swap eval print ; create buff 128 allot +77777777777 constant stack-leak-detect : read-lines begin ." user> " - 77777777777 + stack-leak-detect buff 128 stdin read-line throw - while - buff swap + while ( num-bytes-read ) + buff swap ( str-addr str-len ) ['] rep - execute safe-type - \ catch 0= if safe-type else ." Caught error" endif + \ execute safe-type + catch ?dup 0= if safe-type else ." Caught error " . endif cr - 77777777777 <> if ." --stack leak--" cr endif + stack-leak-detect <> if ." --stack leak--" cr endif repeat ; read-lines diff --git a/forth/step5_tco.fs b/forth/step5_tco.fs index a420719..f7372db 100644 --- a/forth/step5_tco.fs +++ b/forth/step5_tco.fs @@ -4,17 +4,12 @@ require core.fs core MalEnv. constant repl-env -\ Fully evalutate any Mal object: -def-protocol-method mal-eval ( env ast -- val ) - -\ Invoke an object, given whole env and unevaluated argument forms: -def-protocol-method invoke ( argv argc mal-fn -- ... ) - 99999999 constant TCO-eval : read read-str ; : eval ( env obj ) begin + \ ." eval-> " dup pr-str safe-type cr mal-eval dup TCO-eval = while @@ -27,7 +22,7 @@ def-protocol-method invoke ( argv argc mal-fn -- ... ) MalDefault extend mal-eval nip ;; drop \ By default, evalutate to yourself MalKeyword - extend invoke { env list kw -- val } + extend eval-invoke { env list kw -- val } 0 kw env list MalList/start @ cell+ @ eval get ?dup 0= if \ compute not-found value @@ -39,32 +34,26 @@ MalKeyword endif ;; drop -\ eval all but the first item of list, storing in temporary memory -\ that should be freed with free-eval-rest when done. -: eval-rest { env list -- mem-token argv argc } - \ Pass args on dictionary stack (!) - \ TODO: consider allocate and free of a real MalList instead - \ Normal list, evaluate and invoke - here { val-start } +\ eval all but the first item of list +: eval-rest { env list -- argv argc } list MalList/start @ cell+ { expr-start } - list MalList/count @ 1- dup { argc } 0 ?do - env expr-start i cells + @ eval , + list MalList/count @ 1- { argc } + argc cells allocate throw { target } + argc 0 ?do + env expr-start i cells + @ eval + target i cells + ! loop - val-start val-start argc ; - -: free-eval-rest ( mem-token/val-start -- ) - here - allot ; + target argc ; MalNativeFn - extend invoke ( env list this -- list ) + extend eval-invoke ( env list this -- list ) MalNativeFn/xt @ { xt } - eval-rest ( mem-token argv argc ) - xt execute ( mem-token return-val ) - swap free-eval-rest ;; + eval-rest ( argv argc ) + xt execute ( return-val ) ;; drop SpecialOp - extend invoke ( env list this -- list ) + extend eval-invoke ( env list this -- list ) SpecialOp/xt @ execute ;; drop @@ -84,8 +73,7 @@ defspecial def! { env list -- val } list MalList/start @ cell+ { arg0 } arg0 @ ( key ) env arg0 cell+ @ eval dup { val } ( key val ) - env env/set - val ;; + env env/set val ;; defspecial let* { old-env list -- val } old-env MalEnv. { env } @@ -135,8 +123,8 @@ defspecial if { env list -- val } s" &" MalSymbol. constant &-sym MalUserFn - extend invoke { call-env list mal-fn -- list } - call-env list eval-rest { mem-token argv argc } + extend eval-invoke { call-env list mal-fn -- list } + call-env list eval-rest { argv argc } mal-fn MalUserFn/formal-args @ { f-args-list } mal-fn MalUserFn/env @ MalEnv. { env } @@ -162,9 +150,8 @@ MalUserFn env env/set loop - env mal-fn MalUserFn/body @ TCO-eval - - mem-token free-eval-rest ;; + env mal-fn MalUserFn/body @ TCO-eval ;; +drop defspecial fn* { env list -- val } list MalList/start @ cell+ { arg0 } @@ -196,7 +183,7 @@ drop MalList extend mal-eval { env list -- val } env list MalList/start @ @ eval - env list rot invoke ;; + env list rot eval-invoke ;; drop MalVector @@ -211,7 +198,7 @@ MalMap MalMap new swap over MalMap/list ! ;; drop -: rep ( str -- val ) +: rep ( str-addr str-len -- str-addr str-len ) read repl-env swap eval print ; @@ -224,8 +211,8 @@ create buff 128 allot ." user> " stack-leak-detect buff 128 stdin read-line throw - while - buff swap + while ( num-bytes-read ) + buff swap ( str-addr str-len ) ['] rep \ execute safe-type catch ?dup 0= if safe-type else ." Caught error " . endif diff --git a/forth/step6_file.fs b/forth/step6_file.fs index d675f6e..b3945ad 100644 --- a/forth/step6_file.fs +++ b/forth/step6_file.fs @@ -4,12 +4,6 @@ require core.fs core MalEnv. constant repl-env -\ Fully evalutate any Mal object: -def-protocol-method mal-eval ( env ast -- val ) - -\ Invoke an object, given whole env and unevaluated argument forms: -def-protocol-method invoke ( argv argc mal-fn -- ... ) - 99999999 constant TCO-eval : read read-str ; @@ -28,7 +22,7 @@ def-protocol-method invoke ( argv argc mal-fn -- ... ) MalDefault extend mal-eval nip ;; drop \ By default, evalutate to yourself MalKeyword - extend invoke { env list kw -- val } + extend eval-invoke { env list kw -- val } 0 kw env list MalList/start @ cell+ @ eval get ?dup 0= if \ compute not-found value @@ -52,14 +46,14 @@ drop target argc ; MalNativeFn - extend invoke ( env list this -- list ) + extend eval-invoke ( env list this -- list ) MalNativeFn/xt @ { xt } eval-rest ( argv argc ) xt execute ( return-val ) ;; drop SpecialOp - extend invoke ( env list this -- list ) + extend eval-invoke ( env list this -- list ) SpecialOp/xt @ execute ;; drop @@ -79,8 +73,7 @@ defspecial def! { env list -- val } list MalList/start @ cell+ { arg0 } arg0 @ ( key ) env arg0 cell+ @ eval dup { val } ( key val ) - env env/set - val ;; + env env/set val ;; defspecial let* { old-env list -- val } old-env MalEnv. { env } @@ -130,7 +123,7 @@ defspecial if { env list -- val } s" &" MalSymbol. constant &-sym MalUserFn - extend invoke { call-env list mal-fn -- list } + extend eval-invoke { call-env list mal-fn -- list } call-env list eval-rest { argv argc } mal-fn MalUserFn/formal-args @ { f-args-list } @@ -190,7 +183,7 @@ drop MalList extend mal-eval { env list -- val } env list MalList/start @ @ eval - env list rot invoke ;; + env list rot eval-invoke ;; drop MalVector @@ -208,7 +201,7 @@ drop defcore eval ( argv argc ) drop @ repl-env swap eval ;; -: rep ( str-addr str-len -- val ) +: rep ( str-addr str-len -- str-addr str-len ) read repl-env swap eval print ; @@ -221,21 +214,21 @@ defcore eval ( argv argc ) repeat 2drop here>MalList ; -s\" (def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \")\")))))" rep drop - create buff 128 allot 77777777777 constant stack-leak-detect +s\" (def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \")\")))))" rep 2drop + : repl ( -- ) begin ." user> " stack-leak-detect buff 128 stdin read-line throw - while - buff swap + while ( num-bytes-read ) + buff swap ( str-addr str-len ) ['] rep - execute type - \ catch ?dup 0= if safe-type else ." Caught error " . endif + \ execute type + catch ?dup 0= if safe-type else ." Caught error " . endif cr stack-leak-detect <> if ." --stack leak--" cr endif repeat ; diff --git a/forth/step7_quote.fs b/forth/step7_quote.fs index 46c2fb2..0c6b909 100644 --- a/forth/step7_quote.fs +++ b/forth/step7_quote.fs @@ -4,12 +4,6 @@ require core.fs core MalEnv. constant repl-env -\ Fully evalutate any Mal object: -def-protocol-method mal-eval ( env ast -- val ) - -\ Invoke an object, given whole env and unevaluated argument forms: -def-protocol-method invoke ( argv argc mal-fn -- ... ) - 99999999 constant TCO-eval : read read-str ; @@ -28,7 +22,7 @@ def-protocol-method invoke ( argv argc mal-fn -- ... ) MalDefault extend mal-eval nip ;; drop \ By default, evalutate to yourself MalKeyword - extend invoke { env list kw -- val } + extend eval-invoke { env list kw -- val } 0 kw env list MalList/start @ cell+ @ eval get ?dup 0= if \ compute not-found value @@ -52,14 +46,14 @@ drop target argc ; MalNativeFn - extend invoke ( env list this -- list ) + extend eval-invoke ( env list this -- list ) MalNativeFn/xt @ { xt } eval-rest ( argv argc ) xt execute ( return-val ) ;; drop SpecialOp - extend invoke ( env list this -- list ) + extend eval-invoke ( env list this -- list ) SpecialOp/xt @ execute ;; drop @@ -121,8 +115,7 @@ defspecial def! { env list -- val } list MalList/start @ cell+ { arg0 } arg0 @ ( key ) env arg0 cell+ @ eval dup { val } ( key val ) - env env/set - val ;; + env env/set val ;; defspecial let* { old-env list -- val } old-env MalEnv. { env } @@ -172,7 +165,7 @@ defspecial if { env list -- val } s" &" MalSymbol. constant &-sym MalUserFn - extend invoke { call-env list mal-fn -- list } + extend eval-invoke { call-env list mal-fn -- list } call-env list eval-rest { argv argc } mal-fn MalUserFn/formal-args @ { f-args-list } @@ -232,7 +225,7 @@ drop MalList extend mal-eval { env list -- val } env list MalList/start @ @ eval - env list rot invoke ;; + env list rot eval-invoke ;; drop MalVector @@ -250,7 +243,7 @@ drop defcore eval ( argv argc ) drop @ repl-env swap eval ;; -: rep ( str-addr str-len -- val ) +: rep ( str-addr str-len -- str-addr str-len ) read repl-env swap eval print ; @@ -263,21 +256,21 @@ defcore eval ( argv argc ) repeat 2drop here>MalList ; -s\" (def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \")\")))))" rep drop - create buff 128 allot 77777777777 constant stack-leak-detect +s\" (def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \")\")))))" rep 2drop + : repl ( -- ) begin ." user> " stack-leak-detect buff 128 stdin read-line throw - while - buff swap + while ( num-bytes-read ) + buff swap ( str-addr str-len ) ['] rep - execute type - \ catch ?dup 0= if safe-type else ." Caught error " . endif + \ execute type + catch ?dup 0= if safe-type else ." Caught error " . endif cr stack-leak-detect <> if ." --stack leak--" cr endif repeat ; diff --git a/forth/step8_macros.fs b/forth/step8_macros.fs index c0a66c8..f01f3a9 100644 --- a/forth/step8_macros.fs +++ b/forth/step8_macros.fs @@ -4,12 +4,6 @@ require core.fs core MalEnv. constant repl-env -\ Fully evalutate any Mal object: -def-protocol-method mal-eval ( env ast -- val ) - -\ Invoke an object, given whole env and unevaluated argument forms: -def-protocol-method invoke ( argv argc mal-fn -- ... ) - 99999999 constant TCO-eval : read read-str ; @@ -28,7 +22,7 @@ def-protocol-method invoke ( argv argc mal-fn -- ... ) MalDefault extend mal-eval nip ;; drop \ By default, evalutate to yourself MalKeyword - extend invoke { env list kw -- val } + extend eval-invoke { env list kw -- val } 0 kw env list MalList/start @ cell+ @ eval get ?dup 0= if \ compute not-found value @@ -52,14 +46,14 @@ drop target argc ; MalNativeFn - extend invoke ( env list this -- list ) + extend eval-invoke ( env list this -- list ) MalNativeFn/xt @ { xt } eval-rest ( argv argc ) xt execute ( return-val ) ;; drop SpecialOp - extend invoke ( env list this -- list ) + extend eval-invoke ( env list this -- list ) SpecialOp/xt @ execute ;; drop @@ -205,7 +199,7 @@ s" &" MalSymbol. constant &-sym env ; MalUserFn - extend invoke { call-env list mal-fn -- list } + extend eval-invoke { call-env list mal-fn -- list } mal-fn MalUserFn/is-macro? @ if list MalList/start @ cell+ list MalList/count @ 1- else @@ -259,7 +253,7 @@ drop MalList extend mal-eval { env list -- val } env list MalList/start @ @ eval - env list rot invoke ;; + env list rot eval-invoke ;; drop MalVector @@ -277,7 +271,7 @@ drop defcore eval ( argv argc ) drop @ repl-env swap eval ;; -: rep ( str-addr str-len -- val ) +: rep ( str-addr str-len -- str-addr str-len ) read repl-env swap eval print ; @@ -290,13 +284,13 @@ defcore eval ( argv argc ) repeat 2drop here>MalList ; -s\" (def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \")\")))))" rep drop -s\" (defmacro! cond (fn* (& xs) (if (> (count xs) 0) (list 'if (first xs) (if (> (count xs) 1) (nth xs 1) (throw \"odd number of forms to cond\")) (cons 'cond (rest (rest xs)))))))" rep drop -s\" (defmacro! or (fn* (& xs) (if (empty? xs) nil (if (= 1 (count xs)) (first xs) `(let* (or_FIXME ~(first xs)) (if or_FIXME or_FIXME (or ~@(rest xs))))))))" rep drop - create buff 128 allot 77777777777 constant stack-leak-detect +s\" (def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \")\")))))" rep 2drop +s\" (defmacro! cond (fn* (& xs) (if (> (count xs) 0) (list 'if (first xs) (if (> (count xs) 1) (nth xs 1) (throw \"odd number of forms to cond\")) (cons 'cond (rest (rest xs)))))))" rep 2drop +s\" (defmacro! or (fn* (& xs) (if (empty? xs) nil (if (= 1 (count xs)) (first xs) `(let* (or_FIXME ~(first xs)) (if or_FIXME or_FIXME (or ~@(rest xs))))))))" rep 2drop + : repl ( -- ) begin ." user> " diff --git a/forth/step9_try.fs b/forth/step9_try.fs index e7293db..e11c691 100644 --- a/forth/step9_try.fs +++ b/forth/step9_try.fs @@ -4,15 +4,6 @@ require core.fs core MalEnv. constant repl-env -\ Fully evalutate any Mal object: -\ def-protocol-method mal-eval ( env ast -- val ) - -\ Invoke an object, given whole env and unevaluated argument forms: -\ def-protocol-method eval-invoke ( env list obj -- ... ) - -\ Invoke a function, given parameter values -\ def-protocol-method invoke ( argv argc mal-fn -- ... ) - 99999999 constant TCO-eval : read read-str ; @@ -219,21 +210,19 @@ s" &" MalSymbol. constant &-sym MalUserFn extend eval-invoke { call-env list mal-fn -- list } mal-fn MalUserFn/is-macro? @ if - list MalList/start @ cell+ list MalList/count @ 1- + list MalList/start @ cell+ \ argv + list MalList/count @ 1- \ argc + mal-fn new-user-fn-env { env } + env mal-fn MalUserFn/body @ eval + call-env swap TCO-eval else call-env list eval-rest - endif - mal-fn invoke ;; + mal-fn invoke + endif ;; extend invoke ( argv argc mal-fn ) dup { mal-fn } new-user-fn-env { env } - - mal-fn MalUserFn/is-macro? @ if - env mal-fn MalUserFn/body @ eval - env swap TCO-eval - else - env mal-fn MalUserFn/body @ TCO-eval - endif ;; + env mal-fn MalUserFn/body @ TCO-eval ;; drop defspecial fn* { env list -- val } @@ -310,7 +299,7 @@ drop defcore eval ( argv argc ) drop @ repl-env swap eval ;; -: rep ( str-addr str-len -- val ) +: rep ( str-addr str-len -- str-addr str-len ) read repl-env swap eval print ; @@ -339,14 +328,14 @@ defcore map ( argv argc -- list ) here>MalList ;; defcore readline ( argv argc -- mal-string ) - drop @ unpack-str type + drop @ unpack-str type stdout flush-file drop buff 128 stdin read-line throw - if buff swap MalString. else mal-nil endif ;; + if buff swap MalString. else drop mal-nil endif ;; -s\" (def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \")\")))))" rep drop -s\" (defmacro! cond (fn* (& xs) (if (> (count xs) 0) (list 'if (first xs) (if (> (count xs) 1) (nth xs 1) (throw \"odd number of forms to cond\")) (cons 'cond (rest (rest xs)))))))" rep drop -s\" (defmacro! or (fn* (& xs) (if (empty? xs) nil (if (= 1 (count xs)) (first xs) `(let* (or_FIXME ~(first xs)) (if or_FIXME or_FIXME (or ~@(rest xs))))))))" rep drop -s\" (def! swap! (fn* [a f & args] (reset! a (apply f @a args))))" rep drop +s\" (def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \")\")))))" rep 2drop +s\" (defmacro! cond (fn* (& xs) (if (> (count xs) 0) (list 'if (first xs) (if (> (count xs) 1) (nth xs 1) (throw \"odd number of forms to cond\")) (cons 'cond (rest (rest xs)))))))" rep 2drop +s\" (defmacro! or (fn* (& xs) (if (empty? xs) nil (if (= 1 (count xs)) (first xs) `(let* (or_FIXME ~(first xs)) (if or_FIXME or_FIXME (or ~@(rest xs))))))))" rep 2drop +s\" (def! swap! (fn* [a f & args] (reset! a (apply f @a args))))" rep 2drop : repl ( -- ) begin @@ -356,7 +345,7 @@ s\" (def! swap! (fn* [a f & args] (reset! a (apply f @a args))))" rep drop while ( num-bytes-read ) buff swap ( str-addr str-len ) ['] rep - execute ['] nop \ uncomment to see stack traces + \ execute ['] nop \ uncomment to see stack traces catch ?dup 0= if safe-type cr stack-leak-detect <> if ." --stack leak--" cr endif @@ -388,5 +377,3 @@ s\" (def! swap! (fn* [a f & args] (reset! a (apply f @a args))))" rep drop main cr bye - -4
\ No newline at end of file diff --git a/forth/stepA_interop.fs b/forth/stepA_interop.fs index d25d094..0a4050a 100644 --- a/forth/stepA_interop.fs +++ b/forth/stepA_interop.fs @@ -4,15 +4,6 @@ require core.fs core MalEnv. constant repl-env -\ Fully evalutate any Mal object: -\ def-protocol-method mal-eval ( env ast -- val ) - -\ Invoke an object, given whole env and unevaluated argument forms: -\ def-protocol-method eval-invoke ( env list obj -- ... ) - -\ Invoke a function, given parameter values -\ def-protocol-method invoke ( argv argc mal-fn -- ... ) - 99999999 constant TCO-eval : read read-str ; @@ -308,7 +299,7 @@ drop defcore eval ( argv argc ) drop @ repl-env swap eval ;; -: rep ( str-addr str-len -- val ) +: rep ( str-addr str-len -- str-addr str-len ) read repl-env swap eval print ; @@ -341,14 +332,14 @@ defcore readline ( argv argc -- mal-string ) buff 128 stdin read-line throw if buff swap MalString. else drop mal-nil endif ;; -s\" (def! *host-language* \"forth\")" rep drop -s\" (def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \")\")))))" rep drop -s\" (defmacro! cond (fn* (& xs) (if (> (count xs) 0) (list 'if (first xs) (if (> (count xs) 1) (nth xs 1) (throw \"odd number of forms to cond\")) (cons 'cond (rest (rest xs)))))))" rep drop -s\" (defmacro! or (fn* (& xs) (if (empty? xs) nil (if (= 1 (count xs)) (first xs) `(let* (or_FIXME ~(first xs)) (if or_FIXME or_FIXME (or ~@(rest xs))))))))" rep drop -s\" (def! swap! (fn* [a f & args] (reset! a (apply f @a args))))" rep drop +s\" (def! *host-language* \"forth\")" rep 2drop +s\" (def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \")\")))))" rep 2drop +s\" (defmacro! cond (fn* (& xs) (if (> (count xs) 0) (list 'if (first xs) (if (> (count xs) 1) (nth xs 1) (throw \"odd number of forms to cond\")) (cons 'cond (rest (rest xs)))))))" rep 2drop +s\" (defmacro! or (fn* (& xs) (if (empty? xs) nil (if (= 1 (count xs)) (first xs) `(let* (or_FIXME ~(first xs)) (if or_FIXME or_FIXME (or ~@(rest xs))))))))" rep 2drop +s\" (def! swap! (fn* [a f & args] (reset! a (apply f @a args))))" rep 2drop : repl ( -- ) - s\" (println (str \"Mal [\" *host-language* \"]\"))" rep drop + s\" (println (str \"Mal [\" *host-language* \"]\"))" rep 2drop begin ." user> " stack-leak-detect @@ -366,7 +357,7 @@ s\" (def! swap! (fn* [a f & args] (reset! a (apply f @a args))))" rep drop s" forth-errno" MalKeyword. errno MalInt. MalMap/Empty assoc to exception-object endif - ." Uncaught mal or forth exception: " + ." Uncaught exception: " exception-object pr-str safe-type cr endif repeat ; @@ -388,5 +379,3 @@ s\" (def! swap! (fn* [a f & args] (reset! a (apply f @a args))))" rep drop main cr bye - -4
\ No newline at end of file diff --git a/forth/types.fs b/forth/types.fs index b936603..791f327 100644 --- a/forth/types.fs +++ b/forth/types.fs @@ -241,8 +241,6 @@ def-protocol-method eval-invoke ( env list obj -- ... ) def-protocol-method invoke ( argv argc mal-fn -- ... ) - - : m= ( a b -- bool ) 2dup = if 2drop true |
