Add a self-made readline implementation
authorVasilij Schneidermann <v.schneidermann@gmail.com>
Sat, 6 Aug 2016 15:42:56 +0000 (17:42 +0200)
committerVasilij Schneidermann <v.schneidermann@gmail.com>
Sat, 6 Aug 2016 15:47:13 +0000 (17:47 +0200)
chuck/readline.ck [new file with mode: 0644]
chuck/step0_repl.ck
chuck/step1_read_print.ck
chuck/step2_eval.ck
chuck/step3_env.ck
chuck/step4_if_fn_do.ck
chuck/step5_tco.ck
chuck/step6_file.ck
chuck/step7_quote.ck
chuck/step8_macros.ck
chuck/step9_try.ck

diff --git a/chuck/readline.ck b/chuck/readline.ck
new file mode 100644 (file)
index 0000000..8aefe0d
--- /dev/null
@@ -0,0 +1,63 @@
+public class Readline
+{
+    fun static string readline(string prompt)
+    {
+        int done;
+        string input;
+        KBHit kb;
+        int char;
+        string repr;
+
+        ["NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL",
+         "BS", "HT", "LF", "VT", "FF", "CR", "SO", "SI",
+         "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB",
+         "CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US",
+         " ", "!", "\"", "#", "$", "%", "&", "'",
+         "(", ")", "*", "+", ",", "-", ".", "/",
+         "0", "1", "2", "3", "4", "5", "6", "7",
+         "8", "9", ":", ";", "<", "=", ">", "?",
+         "@", "A", "B", "C", "D", "E", "F", "G",
+         "H", "I", "J", "K", "L", "M", "N", "O",
+         "P", "Q", "R", "S", "T", "U", "V", "W",
+         "X", "Y", "Z", "[", "\\", "]", "^", "_",
+         "`", "a", "b", "c", "d", "e", "f", "g",
+         "h", "i", "j", "k", "l", "m", "n", "o",
+         "p", "q", "r", "s", "t", "u", "v", "w",
+         "x", "y", "z", "{", "|", "}", "~", "DEL"] @=> string asciiTable[];
+
+        chout <= prompt;
+        chout.flush();
+
+        while( !done )
+        {
+            kb => now;
+
+            while( kb.more() && !done )
+            {
+                kb.getchar() => char;
+                asciiTable[char] => repr;
+
+                if( repr == "EOT" || repr == "LF" || repr == "CR" )
+                {
+                    true => done;
+                }
+                else
+                {
+                    chout <= repr;
+                    chout.flush();
+                    repr +=> input;
+                }
+            }
+        }
+
+        chout <= "\n";
+
+        if( repr == "EOT" )
+        {
+            return null;
+        }
+
+        return input;
+    }
+}
+
index 9e05a75..7591170 100644 (file)
@@ -1,3 +1,5 @@
+// @import readline.ck
+
 fun string READ(string input)
 {
     return input;
@@ -20,14 +22,20 @@ fun string rep(string input)
 
 fun void main()
 {
-    ConsoleInput stdin;
-    string input;
+    int done;
 
-    while( true )
+    while( !done )
     {
-        stdin.prompt("user>") => now;
-        stdin.getLine() => input;
-        chout <= rep(input) + "\n";
+        Readline.readline("user> ") => string input;
+
+        if( input != null )
+        {
+            chout <= rep(input) + "\n";
+        }
+        else
+        {
+            true => done;
+        }
     }
 }
 
index 3234783..b173cf3 100644 (file)
@@ -1,3 +1,4 @@
+// @import readline.ck
 // @import types/boxed/*.ck
 // @import types/MalObject.ck
 // @import types/mal/MalAtom.ck
@@ -61,22 +62,28 @@ fun string rep(string input)
 
 fun void main()
 {
-    ConsoleInput stdin;
-    string input;
+    int done;
 
-    while( true )
+    while( !done )
     {
-        stdin.prompt("user>") => now;
-        stdin.getLine() => input;
-        rep(input) => string output;
+        Readline.readline("user> ") => string input;
 
-        if( output == "empty input" )
+        if( input != null )
         {
-            // proceed immediately with prompt
+            rep(input) => string output;
+
+            if( output == "empty input" )
+            {
+                // proceed immediately with prompt
+            }
+            else
+            {
+                Util.println(output);
+            }
         }
         else
         {
-            chout <= output + "\n";
+            true => done;
         }
     }
 }
index 9134d24..6795783 100644 (file)
@@ -1,3 +1,4 @@
+// @import readline.ck
 // @import types/boxed/*.ck
 // @import types/MalObject.ck
 // @import types/mal/MalAtom.ck
@@ -167,22 +168,28 @@ fun string rep(string input)
 
 fun void main()
 {
-    ConsoleInput stdin;
-    string input;
+    int done;
 
-    while( true )
+    while( !done )
     {
-        stdin.prompt("user>") => now;
-        stdin.getLine() => input;
-        rep(input) => string output;
+        Readline.readline("user> ") => string input;
 
-        if( output == "empty input" )
+        if( input != null )
         {
-            // proceed immediately with prompt
+            rep(input) => string output;
+
+            if( output == "empty input" )
+            {
+                // proceed immediately with prompt
+            }
+            else
+            {
+                Util.println(output);
+            }
         }
         else
         {
-            chout <= output + "\n";
+            true => done;
         }
     }
 }
index a552ee3..2d2b1ba 100644 (file)
@@ -1,3 +1,4 @@
+// @import readline.ck
 // @import types/boxed/*.ck
 // @import types/MalObject.ck
 // @import types/mal/MalAtom.ck
@@ -196,22 +197,28 @@ fun string rep(string input)
 
 fun void main()
 {
-    ConsoleInput stdin;
-    string input;
+    int done;
 
-    while( true )
+    while( !done )
     {
-        stdin.prompt("user>") => now;
-        stdin.getLine() => input;
-        rep(input) => string output;
+        Readline.readline("user> ") => string input;
 
-        if( output == "empty input" )
+        if( input != null )
         {
-            // proceed immediately with prompt
+            rep(input) => string output;
+
+            if( output == "empty input" )
+            {
+                // proceed immediately with prompt
+            }
+            else
+            {
+                Util.println(output);
+            }
         }
         else
         {
-            chout <= output + "\n";
+            true => done;
         }
     }
 }
index 5ea4f9b..09c0ae5 100644 (file)
@@ -1,3 +1,4 @@
+// @import readline.ck
 // @import types/boxed/*.ck
 // @import types/MalObject.ck
 // @import types/mal/MalAtom.ck
@@ -268,22 +269,28 @@ rep("(def! not (fn* (a) (if a false true)))");
 
 fun void main()
 {
-    ConsoleInput stdin;
-    string input;
+    int done;
 
-    while( true )
+    while( !done )
     {
-        stdin.prompt("user>") => now;
-        stdin.getLine() => input;
-        rep(input) => string output;
+        Readline.readline("user> ") => string input;
 
-        if( output == "empty input" )
+        if( input != null )
         {
-            // proceed immediately with prompt
+            rep(input) => string output;
+
+            if( output == "empty input" )
+            {
+                // proceed immediately with prompt
+            }
+            else
+            {
+                Util.println(output);
+            }
         }
         else
         {
-            Util.println(output);
+            true => done;
         }
     }
 }
index b701fb1..da2a230 100644 (file)
@@ -1,3 +1,4 @@
+// @import readline.ck
 // @import types/boxed/*.ck
 // @import types/MalObject.ck
 // @import types/mal/MalAtom.ck
@@ -274,22 +275,28 @@ rep("(def! not (fn* (a) (if a false true)))");
 
 fun void main()
 {
-    ConsoleInput stdin;
-    string input;
+    int done;
 
-    while( true )
+    while( !done )
     {
-        stdin.prompt("user>") => now;
-        stdin.getLine() => input;
-        rep(input) => string output;
+        Readline.readline("user> ") => string input;
 
-        if( output == "empty input" )
+        if( input != null )
         {
-            // proceed immediately with prompt
+            rep(input) => string output;
+
+            if( output == "empty input" )
+            {
+                // proceed immediately with prompt
+            }
+            else
+            {
+                Util.println(output);
+            }
         }
         else
         {
-            Util.println(output);
+            true => done;
         }
     }
 }
index fe4b3a6..31d2d8a 100644 (file)
@@ -1,3 +1,4 @@
+// @import readline.ck
 // @import types/boxed/*.ck
 // @import types/MalObject.ck
 // @import types/mal/MalAtom.ck
@@ -319,22 +320,28 @@ rep("(def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \")\"))
 
 fun void main()
 {
-    ConsoleInput stdin;
-    string input;
+    int done;
 
-    while( true )
+    while( !done )
     {
-        stdin.prompt("user>") => now;
-        stdin.getLine() => input;
-        rep(input) => string output;
+        Readline.readline("user> ") => string input;
 
-        if( output == "empty input" )
+        if( input != null )
         {
-            // proceed immediately with prompt
+            rep(input) => string output;
+
+            if( output == "empty input" )
+            {
+                // proceed immediately with prompt
+            }
+            else
+            {
+                Util.println(output);
+            }
         }
         else
         {
-            Util.println(output);
+            true => done;
         }
     }
 }
index a1f5082..9c9fb38 100644 (file)
@@ -1,3 +1,4 @@
+// @import readline.ck
 // @import types/boxed/*.ck
 // @import types/MalObject.ck
 // @import types/mal/MalAtom.ck
@@ -374,22 +375,28 @@ rep("(def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \")\"))
 
 fun void main()
 {
-    ConsoleInput stdin;
-    string input;
+    int done;
 
-    while( true )
+    while( !done )
     {
-        stdin.prompt("user>") => now;
-        stdin.getLine() => input;
-        rep(input) => string output;
+        Readline.readline("user> ") => string input;
 
-        if( output == "empty input" )
+        if( input != null )
         {
-            // proceed immediately with prompt
+            rep(input) => string output;
+
+            if( output == "empty input" )
+            {
+                // proceed immediately with prompt
+            }
+            else
+            {
+                Util.println(output);
+            }
         }
         else
         {
-            Util.println(output);
+            true => done;
         }
     }
 }
index 5964458..704669a 100644 (file)
@@ -1,3 +1,4 @@
+// @import readline.ck
 // @import types/boxed/*.ck
 // @import types/MalObject.ck
 // @import types/mal/MalAtom.ck
@@ -448,22 +449,28 @@ rep("(defmacro! or (fn* (& xs) (if (empty? xs) nil (if (= 1 (count xs)) (first x
 
 fun void main()
 {
-    ConsoleInput stdin;
-    string input;
+    int done;
 
-    while( true )
+    while( !done )
     {
-        stdin.prompt("user>") => now;
-        stdin.getLine() => input;
-        rep(input) => string output;
+        Readline.readline("user> ") => string input;
 
-        if( output == "empty input" )
+        if( input != null )
         {
-            // proceed immediately with prompt
+            rep(input) => string output;
+
+            if( output == "empty input" )
+            {
+                // proceed immediately with prompt
+            }
+            else
+            {
+                Util.println(output);
+            }
         }
         else
         {
-            Util.println(output);
+            true => done;
         }
     }
 }
index 543090d..392812d 100644 (file)
@@ -1,3 +1,4 @@
+// @import readline.ck
 // @import types/boxed/*.ck
 // @import types/MalObject.ck
 // @import types/mal/MalAtom.ck
@@ -465,22 +466,28 @@ rep("(defmacro! or (fn* (& xs) (if (empty? xs) nil (if (= 1 (count xs)) (first x
 
 fun void main()
 {
-    ConsoleInput stdin;
-    string input;
+    int done;
 
-    while( true )
+    while( !done )
     {
-        stdin.prompt("user>") => now;
-        stdin.getLine() => input;
-        rep(input) => string output;
+        Readline.readline("user> ") => string input;
 
-        if( output == "empty input" )
+        if( input != null )
         {
-            // proceed immediately with prompt
+            rep(input) => string output;
+
+            if( output == "empty input" )
+            {
+                // proceed immediately with prompt
+            }
+            else
+            {
+                Util.println(output);
+            }
         }
         else
         {
-            Util.println(output);
+            true => done;
         }
     }
 }