aboutsummaryrefslogtreecommitdiff
path: root/forth/step2_eval.fs
diff options
context:
space:
mode:
authorChouser <chouser@n01se.net>2015-02-12 19:27:00 -0500
committerChouser <chouser@n01se.net>2015-02-21 13:22:44 -0500
commit9da223a35a176d94fbb75cbcc1000871ff5aff0b (patch)
treeab7d1e75f8b567c0dd0a84c507e8415dd83ada0b /forth/step2_eval.fs
parent2e78e94eb894e511e583db03286a3c13b9ecc780 (diff)
downloadmal-9da223a35a176d94fbb75cbcc1000871ff5aff0b.tar.gz
mal-9da223a35a176d94fbb75cbcc1000871ff5aff0b.zip
forth: Add step 2
Diffstat (limited to 'forth/step2_eval.fs')
-rw-r--r--forth/step2_eval.fs106
1 files changed, 106 insertions, 0 deletions
diff --git a/forth/step2_eval.fs b/forth/step2_eval.fs
new file mode 100644
index 0000000..51d1f6f
--- /dev/null
+++ b/forth/step2_eval.fs
@@ -0,0 +1,106 @@
+require reader.fs
+require printer.fs
+
+: args-as-native { argv argc -- entry*argc... }
+ argc 0 ?do
+ argv i cells + @ as-native
+ loop ;
+
+MalMap/Empty
+ s" +" MalSymbol. :noname args-as-native + MalInt. ; MalFn. rot assoc
+ s" -" MalSymbol. :noname args-as-native - MalInt. ; MalFn. rot assoc
+ s" *" MalSymbol. :noname args-as-native * MalInt. ; MalFn. rot assoc
+ s" /" MalSymbol. :noname args-as-native / MalInt. ; MalFn. rot assoc
+value repl-env
+
+def-protocol-method mal-eval ( env ast -- val )
+def-protocol-method mal-eval-ast ( env ast -- val )
+
+MalDefault extend mal-eval nip ;; drop
+
+MalSymbol
+ extend mal-eval { env sym -- val }
+ 0 sym env get
+ dup 0= if
+ drop
+ ." Symbol '"
+ sym as-native safe-type
+ ." ' not found." cr
+ 1 throw
+ endif ;;
+drop
+
+MalArray
+ extend mal-eval { env ary -- val }
+ \ Pass args on dictionary stack (!)
+ \ TODO: consider allocate and free of a real MalArray instead
+ here { val-start }
+ ary MalArray/start @ { expr-start }
+ ary MalArray/count @ 0 ?do
+ env expr-start i cells + @ mal-eval ,
+ loop
+ val-start cell+ here val-start - cell / 1- val-start @ ( argv argc MalFn )
+ invoke
+ val-start here - allot ;;
+ extend mal-eval-ast { env ary -- ary }
+ here
+ ary MalArray/start @ { expr-start }
+ ary MalArray/count @ 0 ?do
+ env expr-start i cells + @ mal-eval ,
+ loop
+ here>MalArray ;;
+drop
+
+MalList
+ extend mal-eval-ast { env list -- ary }
+ here
+ list
+ begin ( list )
+ dup mal-nil <>
+ while
+ env over MalList/car @ mal-eval ,
+ MalList/cdr @
+ repeat
+ drop here>MalArray ;;
+drop
+
+MalVector
+ extend mal-eval ( env vector -- vector )
+ MalVector/list @ mal-eval-ast
+ MalVector new swap over MalVector/list ! ;;
+drop
+
+MalMap
+ extend mal-eval ( env map -- map )
+ MalMap/list @ mal-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 )
+ read
+ repl-env swap eval
+ print ;
+
+create buff 128 allot
+
+: read-lines
+ begin
+ ." user> "
+ buff 128 stdin read-line throw
+ while
+ buff swap
+ ['] rep
+ \ execute safe-type
+ catch 0= if safe-type else ." Caught error" endif
+ cr
+ repeat ;
+
+read-lines
+cr
+bye