aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Martin <github@martintribe.org>2014-03-29 17:01:24 -0500
committerJoel Martin <github@martintribe.org>2014-03-29 17:01:24 -0500
commit55e2bfa8a3a9fb98a405321d1183a3fbc872d118 (patch)
tree8ce077e5d94ff5c37ab2fa55af342af2e310ba9f
parent1b4a9012c540309ebe26b6ffff80ad44f15530d9 (diff)
downloadmal-55e2bfa8a3a9fb98a405321d1183a3fbc872d118.tar.gz
mal-55e2bfa8a3a9fb98a405321d1183a3fbc872d118.zip
PS: step2_eval
-rw-r--r--docs/TODO3
-rw-r--r--ps/reader.ps3
-rw-r--r--ps/step2_eval.ps78
-rw-r--r--ps/types.ps10
4 files changed, 90 insertions, 4 deletions
diff --git a/docs/TODO b/docs/TODO
index 32036fd..f530ef0 100644
--- a/docs/TODO
+++ b/docs/TODO
@@ -48,7 +48,8 @@ Java:
- step9_interop
Postscript:
- - step 1-A
+ - negative numbers
+ - step 3-A
Rust:
- http://www.rustforrubyists.com/book/index.html
diff --git a/ps/reader.ps b/ps/reader.ps
index 4be0c0f..0fa4c02 100644
--- a/ps/reader.ps
+++ b/ps/reader.ps
@@ -86,7 +86,8 @@
exit % EOF
}{
/ch str idx get def % current character
- ch 48 ge ch 57 le and 45 ch eq or { %if number
+ %ch 48 ge ch 57 le and 45 ch eq or { %if number
+ ch 48 ge ch 57 le and { %if number
str idx read_number
}{ ch 34 eq { %elseif double-quote
str idx read_string
diff --git a/ps/step2_eval.ps b/ps/step2_eval.ps
new file mode 100644
index 0000000..60d1906
--- /dev/null
+++ b/ps/step2_eval.ps
@@ -0,0 +1,78 @@
+(types.ps) run
+(reader.ps) run
+
+% read
+/READ {
+ /str exch def
+ str read_str
+} def
+
+
+% eval
+/eval_ast { 2 dict begin
+ /env exch def
+ /ast exch def
+ /nametype ast type eq { %if symbol
+ env ast get
+ }{ /arraytype ast type eq { %elseif list
+ [
+ ast {
+ env EVAL
+ } forall
+ ]
+ }{ % else
+ ast
+ } ifelse } ifelse
+end } def
+
+/EVAL { 5 dict begin
+ /env exch def
+ /ast exch def
+ /arraytype ast type ne { %if not a list
+ ast env eval_ast
+ }{ %else apply the list
+ /el ast env eval_ast def
+ el 1 el length 1 sub getinterval % args array
+ el 0 get cvx % function
+ %(vvv\n) print pstack (^^^\n) print
+ exec % apply function to args
+ } ifelse
+end } def
+
+
+% print
+/PRINT {
+ /exp exch def
+ %(printing: ) print exp ==
+ exp pr_str
+} def
+
+
+% repl
+/repl_env <<
+ (+) { dup 0 get exch 1 get add }
+ (-) { dup 0 get exch 1 get sub }
+ (*) { dup 0 get exch 1 get mul }
+ (/) { dup 0 get exch 1 get idiv }
+>> def
+
+/REP {
+ READ repl_env EVAL PRINT
+} def
+
+/stdin (%stdin) (r) file def
+
+{ % loop
+ (user> ) print flush
+
+ %(%lineedit) (r) file 99 string readline
+ stdin 99 string readline
+
+ not { exit } if % exit if EOF
+
+ %(\ngot line: ) print dup print (\n) print flush
+ REP print (\n) print
+} bind loop
+
+(\n) print % final newline before exit for cleanliness
+quit
diff --git a/ps/types.ps b/ps/types.ps
index a9d5023..2201cd4 100644
--- a/ps/types.ps
+++ b/ps/types.ps
@@ -1,7 +1,5 @@
(in types.ps\n) print
-/MAX_SYM_SIZE 256
-
% concatenate: concatenate two strings or two arrays
% From Thinking in PostScript 1990 Reid
% (string1) (string2) concatenate string3
@@ -24,6 +22,14 @@
% stack: new
} bind def
+% reverse: array1 -> reverse -> array2
+/reverse {
+ [ exch
+ aload % push array onto stack
+ length -1 0 { 1 roll } for % reverse
+ ]
+} def
+
/pr_str {
%(in pr_str\n) print
/obj exch def