aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChouser <chouser@n01se.net>2015-02-19 19:42:52 -0500
committerChouser <chouser@n01se.net>2015-02-21 13:22:44 -0500
commit45c1894b9690b1156ffdc2caeb726bbc9526597a (patch)
tree4e75609151fc88e78a2ccf93b0f6d2ac880f92c1
parent6512bd80002eb106a304b035e9592847d90ef23c (diff)
downloadmal-45c1894b9690b1156ffdc2caeb726bbc9526597a.tar.gz
mal-45c1894b9690b1156ffdc2caeb726bbc9526597a.zip
forth: Back-propogate fixes from stepA through step1
-rw-r--r--forth/step1_read_print.fs22
-rw-r--r--forth/step2_eval.fs86
-rw-r--r--forth/step3_env.fs93
-rw-r--r--forth/step4_if_fn_do.fs115
-rw-r--r--forth/step5_tco.fs59
-rw-r--r--forth/step6_file.fs33
-rw-r--r--forth/step7_quote.fs33
-rw-r--r--forth/step8_macros.fs26
-rw-r--r--forth/step9_try.fs45
-rw-r--r--forth/stepA_interop.fs27
-rw-r--r--forth/types.fs2
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