plsql: self-hosting. Long strings, refactor io.
[jackhill/mal.git] / plsql / step1_read_print.sql
dissimilarity index 81%
index b5799c9..08107a7 100644 (file)
@@ -1,78 +1,71 @@
-@io.sql
-@types.sql
-@reader.sql
-@printer.sql
-
--- ---------------------------------------------------------
--- step1_read_print.sql
-
--- read
-CREATE OR REPLACE FUNCTION READ(line varchar)
-RETURN mal_type IS
-BEGIN
-    RETURN reader_pkg.read_str(line);
-END;
-/
-
--- eval
-CREATE OR REPLACE FUNCTION EVAL(ast mal_type, env varchar)
-RETURN mal_type IS
-BEGIN
-    RETURN ast;
-END;
-/
-
--- print
-CREATE OR REPLACE FUNCTION PRINT(exp mal_type)
-RETURN varchar IS
-BEGIN
-    RETURN printer_pkg.pr_str(exp);
-END;
-/
-
-
--- repl
-
--- stub to support wrap.sh
-CREATE OR REPLACE PROCEDURE env_vset(env integer, name varchar, val varchar)
-IS
-BEGIN
-    RETURN;
-END;
-/
-
-
-CREATE OR REPLACE FUNCTION REP(line varchar)
-RETURN varchar IS
-BEGIN
-    RETURN PRINT(EVAL(READ(line), ''));
-END;
-/
-
-CREATE OR REPLACE FUNCTION MAIN_LOOP(pwd varchar)
-RETURN integer IS
-    line    varchar2(4000);
-    output  varchar2(4000);
-BEGIN
-    WHILE true
-    LOOP
-        BEGIN
-            line := stream_readline('user> ', 0);
-            -- stream_writeline('line: [' || line || ']', 1);
-            IF line IS NULL THEN RETURN 0; END IF;
-            IF line IS NOT NULL THEN
-                output := REP(line);
-                stream_writeline(output);
-            END IF;
-
-            EXCEPTION WHEN OTHERS THEN
-                IF SQLCODE = -20000 THEN
-                    RETURN 0;
-                END IF;
-                stream_writeline('Error: ' || SQLERRM);
-        END;
-    END LOOP;
-END;
-/
-
-quit;
+@io.sql
+@types.sql
+@reader.sql
+@printer.sql
+
+CREATE OR REPLACE PACKAGE mal IS
+
+FUNCTION MAIN(args varchar DEFAULT '()') RETURN integer;
+
+END mal;
+/
+
+CREATE OR REPLACE PACKAGE BODY mal IS
+
+FUNCTION MAIN(args varchar DEFAULT '()') RETURN integer IS
+    M         mem_type;                 -- general mal value memory pool
+    H         types.map_entry_table;    -- hashmap memory pool
+    line      CLOB;
+
+    -- read
+    FUNCTION READ(line varchar) RETURN integer IS
+    BEGIN
+        RETURN reader.read_str(M, H, line);
+    END;
+
+    -- eval
+    FUNCTION EVAL(ast integer, env varchar) RETURN integer IS
+    BEGIN
+        RETURN ast;
+    END;
+
+    -- print
+    FUNCTION PRINT(exp integer) RETURN varchar IS
+    BEGIN
+        RETURN printer.pr_str(M, H, exp);
+    END;
+
+    -- repl
+    FUNCTION REP(line varchar) RETURN varchar IS
+    BEGIN
+        RETURN PRINT(EVAL(READ(line), ''));
+    END;
+
+BEGIN
+    -- initialize memory pools
+    M := types.mem_new();
+    H := types.map_entry_table();
+
+    WHILE true LOOP
+        BEGIN
+            line := io.readline('user> ', 0);
+            IF line = EMPTY_CLOB() THEN CONTINUE; END IF;
+            IF line IS NOT NULL THEN
+                io.writeline(REP(line));
+            END IF;
+
+            EXCEPTION WHEN OTHERS THEN
+                IF SQLCODE = -20001 THEN  -- io streams closed
+                    RETURN 0;
+                END IF;
+                io.writeline('Error: ' || SQLERRM);
+                io.writeline(dbms_utility.format_error_backtrace);
+        END;
+    END LOOP;
+END;
+
+END mal;
+/
+show errors;
+
+quit;