aboutsummaryrefslogtreecommitdiff
path: root/forth/step3_env.fs
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 /forth/step3_env.fs
parent6512bd80002eb106a304b035e9592847d90ef23c (diff)
downloadmal-45c1894b9690b1156ffdc2caeb726bbc9526597a.tar.gz
mal-45c1894b9690b1156ffdc2caeb726bbc9526597a.zip
forth: Back-propogate fixes from stepA through step1
Diffstat (limited to 'forth/step3_env.fs')
-rw-r--r--forth/step3_env.fs93
1 files changed, 45 insertions, 48 deletions
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