make, swift3: fix parsing empty literal sequences.
[jackhill/mal.git] / ps / step6_file.ps
index 1eff14f..b1a7dde 100644 (file)
@@ -1,11 +1,12 @@
-(types.ps) run
-(reader.ps) run
-(printer.ps) run
-(env.ps) run
-(core.ps) run
+/runlibfile where { pop }{ /runlibfile { run } def } ifelse % 
+(types.ps) runlibfile
+(reader.ps) runlibfile
+(printer.ps) runlibfile
+(env.ps) runlibfile
+(core.ps) runlibfile
 
 % read
-/_readline { print flush (%stdin) (r) file 99 string readline } def
+/_readline { print flush (%stdin) (r) file 1024 string readline } def
 
 /READ {
     /str exch def
@@ -49,7 +50,9 @@ end } def
         ast env eval_ast
     }{ %else apply the list
         /a0 ast 0 _nth def
-        /def! a0 eq { %if def!
+        a0 _nil? { %if ()
+            ast
+        }{ /def! a0 eq { %if def!
             /a1 ast 1 _nth def
             /a2 ast 2 _nth def
             env a1  a2 env EVAL  env_set
@@ -65,7 +68,9 @@ end } def
                     env_set
                     pop % discard the return value
             } for
-            a2 let_env EVAL
+            a2
+            let_env
+            /loop? true def % loop
         }{ /do a0 eq { %if do
             ast _count 2 gt { %if ast has more than 2 elements
                 ast 1 ast _count 2 sub _slice env eval_ast pop
@@ -90,28 +95,19 @@ end } def
         }{ /fn* a0 eq { %if fn*
             /a1 ast 1 _nth def
             /a2 ast 2 _nth def
-            <<
-                /_maltype_ /function % user defined function
-                /params null % close over parameters
-                /ast null    % close over ast
-                /env null    % close over environment
-                /data { __self__ fload EVAL }
-            >>
-            dup length dict copy % make an actual copy/new instance
-            dup /params a1 put  % insert closed over a1 into position 2
-            dup /ast a2 put  % insert closed over a2 into position 3
-            dup /env env put % insert closed over env into position 4
-            dup   dup /data get   exch 0 exch put % insert self reference
+            a2 env a1 _mal_function
         }{
             /el ast env eval_ast def
             el _rest el _first % stack: ast function
-            dup _mal_function? { % if user defined function
+            dup _mal_function? { %if user defined function
                 fload % stack: ast new_env
                 /loop? true def
+            }{ dup _function? { %else if builtin function
+                /data get exec
             }{ %else (regular procedure/function)
-                exec % apply function to args
-            } ifelse
-        } ifelse } ifelse } ifelse } ifelse } ifelse
+                (cannot apply native proc!\n) print quit
+            } ifelse } ifelse
+        } ifelse } ifelse } ifelse } ifelse } ifelse } ifelse
     } ifelse
 
     loop? not { exit } if
@@ -130,27 +126,29 @@ end } def
 
 /RE { READ repl_env EVAL } def
 /REP { READ repl_env EVAL PRINT } def
-/_ref { repl_env 3 1 roll env_set pop } def
 
-core_ns { _ref } forall
-
-(read-string) { 0 _nth read_str } _ref
-(eval) { 0 _nth repl_env EVAL } _ref
-/slurp { (r) file dup bytesavailable string readstring pop } def
-(slurp) { 0 _nth slurp } _ref
+% core.ps: defined using postscript
+/_ref { repl_env 3 1 roll env_set pop } def
+core_ns { _function _ref } forall
+(eval) { 0 _nth repl_env EVAL } _function _ref
+(*ARGV*) [ ] _list_from_array _ref
 
+% core.mal: defined using the language itself
 (\(def! not \(fn* \(a\) \(if a false true\)\)\)) RE pop
 (\(def! load-file \(fn* \(f\) \(eval \(read-string \(str "\(do " \(slurp f\) "\)"\)\)\)\)\)) RE pop
 
 userdict /ARGUMENTS known { %if command line arguments
     ARGUMENTS length 0 gt { %if more than 0 arguments
-        ARGUMENTS {
-            (\(load-file ") exch ("\)) concatenate concatenate RE pop
-        } forall
+        (*ARGV*) ARGUMENTS 1 ARGUMENTS length 1 sub getinterval
+        _list_from_array _ref
+        ARGUMENTS 0 get 
+        (\(load-file ") exch ("\)) concatenate concatenate RE pop
         quit
     } if
 } if
-{ % loop
+
+% repl loop
+{ %loop
     (user> ) _readline
     not { exit } if  % exit if EOF