aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChouser <chouser@n01se.net>2015-02-14 15:44:22 -0500
committerChouser <chouser@n01se.net>2015-02-21 13:22:44 -0500
commite6106d4543fd4917a18ca501ee62a995a152d263 (patch)
tree38f61d4e30c108e495c0ad60b64bae3de034b587
parentc05d35e8dd1ebbc371d7c9239d788ddf844eae31 (diff)
downloadmal-e6106d4543fd4917a18ca501ee62a995a152d263.tar.gz
mal-e6106d4543fd4917a18ca501ee62a995a152d263.zip
forth: Get rid of invoke+
Fold 'invoke+' into 'invoke'. Allows (:k m nf) to evaluate nf lazily!
-rw-r--r--forth/step3_env.fs43
1 files changed, 23 insertions, 20 deletions
diff --git a/forth/step3_env.fs b/forth/step3_env.fs
index 269964d..f609858 100644
--- a/forth/step3_env.fs
+++ b/forth/step3_env.fs
@@ -13,26 +13,29 @@ s" -" MalSymbol. :noname args-as-native - MalInt. ; MalFn. repl-env env/set
s" *" MalSymbol. :noname args-as-native * MalInt. ; MalFn. repl-env env/set
s" /" MalSymbol. :noname args-as-native / MalInt. ; MalFn. repl-env env/set
+\ Fully evalutate any Mal object:
def-protocol-method mal-eval ( env ast -- val )
-def-protocol-method mal-eval-ast ( env ast -- val )
-def-protocol-method invoke+ ( env arty -- ... )
+
+\ Invoke an object, given whole env and unevaluated argument forms:
def-protocol-method invoke ( argv argc mal-fn -- ... )
MalDefault extend mal-eval nip ;; drop
MalKeyword
- extend invoke { argv argc kw -- val }
- argc 1 > if argv cell+ @ else mal-nil endif \ not-found
- kw \ key
- argv @ \ map
- get ;;
+ extend invoke { env list kw -- val }
+ 0 kw env list MalList/start @ cell+ @ mal-eval get
+ ?dup 0= if
+ \ compute not-found value
+ list MalList/count @ 1 > if
+ env list MalList/start @ 2 cells + @ mal-eval
+ else
+ mal-nil
+ endif
+ endif ;;
drop
MalFn
- extend invoke ( ... mal-fn -- ... )
- MalFn/xt @ execute ;;
-
- extend invoke+ { env list this -- list }
+ 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
@@ -42,12 +45,12 @@ MalFn
env expr-start i cells + @ mal-eval ,
loop
val-start here val-start - cell / this ( argv argc MalFn )
- invoke
+ MalFn/xt @ execute
val-start here - allot ;;
drop
SpecialOp
- extend invoke+ ( env list this -- list )
+ extend invoke ( env list this -- list )
SpecialOp/xt @ execute ;;
drop
@@ -89,18 +92,18 @@ MalSymbol
endif ;;
drop
-MalList
- extend mal-eval { env list -- val }
- env list MalList/start @ @ mal-eval
- env list rot invoke+ ;;
-
- extend mal-eval-ast { env list -- list }
+: mal-eval-ast { env list -- list }
here
list MalList/start @ { expr-start }
list MalList/count @ 0 ?do
env expr-start i cells + @ mal-eval ,
loop
- here>MalList ;;
+ here>MalList ;
+
+MalList
+ extend mal-eval { env list -- val }
+ env list MalList/start @ @ mal-eval
+ env list rot invoke ;;
drop
MalVector