ObjPascal: use CTypes for libedit/readline.
authorJoel Martin <github@martintribe.org>
Mon, 14 Mar 2016 05:07:01 +0000 (00:07 -0500)
committerJoel Martin <github@martintribe.org>
Mon, 14 Mar 2016 05:07:01 +0000 (00:07 -0500)
Build with USE_READLINE=1 to switch from libedit to readline.

15 files changed:
objpascal/Makefile
objpascal/core.pas
objpascal/mal_readline.pas [new file with mode: 0644]
objpascal/mal_types.pas
objpascal/step0_repl.pas
objpascal/step1_read_print.pas
objpascal/step2_eval.pas
objpascal/step3_env.pas
objpascal/step4_if_fn_do.pas
objpascal/step5_tco.pas
objpascal/step6_file.pas
objpascal/step7_quote.pas
objpascal/step8_macros.pas
objpascal/step9_try.pas
objpascal/stepA_mal.pas

index a3b46b0..af938fb 100644 (file)
@@ -3,36 +3,25 @@ STEPS = step0_repl.pas step1_read_print.pas step2_eval.pas \
        step6_file.pas step7_quote.pas step8_macros.pas \
        step9_try.pas stepA_mal.pas
 
-STEP0_DEPS = pas-readline/src/readline.pas regexpr/Source/RegExpr.pas
+STEP0_DEPS = mal_readline.pas
 STEP1_DEPS = $(STEP0_DEPS) mal_types.pas reader.pas printer.pas
 STEP3_DEPS = $(STEP1_DEPS) mal_env.pas
 STEP4_DEPS = $(STEP3_DEPS) core.pas
 
-SOURCES = mal_types.pas mal_func.pas reader.pas printer.pas \
-         mal_env.pas core.pas stepA_mal.pas
+SOURCES = mal_readline.pas mal_types.pas mal_func.pas \
+         reader.pas printer.pas mal_env.pas core.pas stepA_mal.pas
 SOURCES_LISP = mal_env.pas core.pas stepA_mal.pas
 
 #####################
 
 DEBUG = -gl
 
-FPC = fpc -MOBJFPC -ve $(DEBUG) -Fupas-readline/src -Furegexpr/Source
+# Set this to link with libreadline instead of libedit
+USE_READLINE =
 
-all: $(patsubst %.pas,%,$(STEPS))
+FPC = fpc -MOBJFPC -ve -Furegexpr/Source $(DEBUG) $(if $(strip $(USE_READLINE)),-dUSE_READLINE,)
 
-# Downloaded units
-pas-readline: pas-readline/src/readline.pas
-pas-readline/src/readline.pas:
-       curl -L https://github.com/hansiglaser/pas-readline/archive/master.tar.gz | tar xzf -
-       mv pas-readline-master pas-readline
-
-#regexpr: regexpr/Source/RegExpr.pas
-#regexpr/Source/RegExpr.pas: regexpr-linux.patch
-#      mkdir -p regexpr
-#      curl -O http://regexpstudio.com/Downloads/regexpr.zip
-#      cd regexpr && unzip ../regexpr.zip
-#      rm regexpr.zip
-#      patch -p1 < regexpr-linux.patch
+all: $(patsubst %.pas,%,$(STEPS))
 
 step%: step%.pas
        $(FPC) $<
index 7eed755..dd5fcb6 100644 (file)
@@ -7,7 +7,7 @@ interface
 uses Classes,
      sysutils,
      fgl,
-     Readline in 'pas-readline/src/readline.pas',
+     mal_readline,
      mal_types,
      mal_func,
      mal_env,
@@ -110,15 +110,16 @@ begin
 end;
 function do_readline(Args: TMalArray) : TMal;
 var
-    Prompt : PChar;
-    Line   : PChar;
+    Prompt : string;
+    Line   : string;
 begin
-    Prompt := PChar((Args[0] as TMalString).Val);
-    Line := Readline.readline(Prompt);
-    if Line = nil then
-        do_readline := TMalNil.Create
-    else
+    Prompt := (Args[0] as TMalString).Val;
+    try
+        Line := _readline(Prompt);
         do_readline := TMalString.Create(Line);
+    except
+        On E : MalEOF do do_readline := TMalNil.Create;
+    end;
 end;
 function slurp(Args: TMalArray) : TMal;
 var
diff --git a/objpascal/mal_readline.pas b/objpascal/mal_readline.pas
new file mode 100644 (file)
index 0000000..6a50469
--- /dev/null
@@ -0,0 +1,43 @@
+unit mal_readline;
+
+{$H+} // Use AnsiString
+
+interface
+
+uses sysutils,
+     CTypes;
+
+{$IFDEF USE_READLINE}
+
+{$LINKLIB readline}
+
+{$ELSE}
+
+{$LINKLIB libedit}
+
+{$ENDIF}
+
+//
+function readline(Prompt: PChar) : PChar; cdecl; external;
+procedure add_history(Line: PChar); cdecl; external;
+
+type MalEOF = class(Exception);
+
+function _readline(Prompt: string) : string;
+
+implementation
+
+function _readline(Prompt: string) : string;
+var
+    Line : PChar;
+begin
+    Line := readline(PChar(Prompt));
+    if Line = Nil then
+        raise MalEOF.Create('MalEOF');
+    if Line <> '' then
+        add_history(Line);
+
+    _readline := Line;
+end;
+
+end.
index 2567e07..a7aacde 100644 (file)
@@ -36,9 +36,9 @@ type TMalFalse = class(TMal);
 
 type TMalInt = class(TMal)
     public
-        Val: Longint;
+        Val: int64;
 
-        constructor Create(V : Longint);
+        constructor Create(V : int64);
 end;
 
 type TMalString = class(TMal)
@@ -127,7 +127,7 @@ end;
 // Mal types
 //
 
-constructor TMalInt.Create(V : Longint);
+constructor TMalInt.Create(V : int64);
 begin
     inherited Create();
     Self.Val := V;
index 6decb28..47ed09e 100644 (file)
@@ -1,12 +1,13 @@
 program Mal;
 
+{$H+} // Use AnsiString
+
 Uses CMem,
-     Readline in 'pas-readline/src/readline.pas',
-     History in 'pas-readline/src/history.pas';
+     mal_readline;
 
 var
     Repl_Env: string = '';
-    Line : PChar;
+    Line : string;
 
 // read
 function READ(const Str: string) : string;
@@ -35,13 +36,12 @@ end;
 begin
     while True do
     begin
-        Line := Readline.readline('user> ');
-        if Line = Nil then
-            Halt(0);
-        if Line[0] = #0 then
-            continue;
-        add_history(Line);
-
-        WriteLn(REP(Line));
+        try
+            Line := _readline('user> ');
+            if Line = '' then continue;
+            WriteLn(REP(Line))
+        except
+            On E : MalEOF do Halt(0);
+        end;
     end;
 end.
index 2e7275a..6d0a0a7 100644 (file)
@@ -1,16 +1,17 @@
 program Mal;
 
+{$H+} // Use AnsiString
+
 Uses sysutils,
      CMem,
-     Readline in 'pas-readline/src/readline.pas',
-     History in 'pas-readline/src/history.pas',
+     mal_readline,
      mal_types,
      reader,
      printer;
 
 var
-    Repl_Env: string = '';
-    Line : PChar;
+    Repl_Env : string = '';
+    Line     : string;
 
 // read
 function READ(const Str: string) : TMal;
@@ -39,16 +40,12 @@ end;
 begin
     while True do
     begin
-        Line := Readline.readline('user> ');
-        if Line = Nil then
-            Halt(0);
-        if Line[0] = #0 then
-            continue;
-        add_history(Line);
-
         try
+            Line := _readline('user> ');
+            if Line = '' then continue;
             WriteLn(REP(Line))
         except
+            On E : MalEOF do Halt(0);
             On E : Exception do
             begin
                 WriteLn('Error: ' + E.message);
index e5a1e80..7749136 100644 (file)
@@ -5,8 +5,7 @@ program Mal;
 Uses sysutils,
      CMem,
      fgl,
-     Readline in 'pas-readline/src/readline.pas',
-     History in 'pas-readline/src/history.pas',
+     mal_readline,
      mal_types,
      mal_func,
      reader,
@@ -17,7 +16,7 @@ type
 
 var
     Repl_Env : TEnv;
-    Line     : PChar;
+    Line     : string;
 
 // read
 function READ(const Str: string) : TMal;
@@ -133,16 +132,12 @@ begin
     Repl_Env.Add('/', TMalFunc.Create(@divide));
     while True do
     begin
-        Line := Readline.readline('user> ');
-        if Line = Nil then
-            Halt(0);
-        if Line[0] = #0 then
-            continue;
-        add_history(Line);
-
         try
+            Line := _readline('user> ');
+            if Line = '' then continue;
             WriteLn(REP(Line))
         except
+            On E : MalEOF do Halt(0);
             On E : Exception do
             begin
                 WriteLn('Error: ' + E.message);
index 6c84682..dfc651f 100644 (file)
@@ -1,10 +1,11 @@
 program Mal;
 
+{$H+} // Use AnsiString
+
 Uses sysutils,
      CMem,
      fgl,
-     Readline in 'pas-readline/src/readline.pas',
-     History in 'pas-readline/src/history.pas',
+     mal_readline,
      mal_types,
      mal_func,
      reader,
@@ -13,7 +14,7 @@ Uses sysutils,
 
 var
     Repl_Env : TEnv;
-    Line     : PChar;
+    Line     : string;
 
 // read
 function READ(const Str: string) : TMal;
@@ -153,16 +154,12 @@ begin
     Repl_Env.Add(TMalSymbol.Create('/'), TMalFunc.Create(@divide));
     while True do
     begin
-        Line := Readline.readline('user> ');
-        if Line = Nil then
-            Halt(0);
-        if Line[0] = #0 then
-            continue;
-        add_history(Line);
-
         try
+            Line := _readline('user> ');
+            if Line = '' then continue;
             WriteLn(REP(Line))
         except
+            On E : MalEOF do Halt(0);
             On E : Exception do
             begin
                 WriteLn('Error: ' + E.message);
index 28df03e..f6ed80a 100644 (file)
@@ -1,10 +1,11 @@
 program Mal;
 
+{$H+} // Use AnsiString
+
 Uses sysutils,
      CMem,
      fgl,
-     Readline in 'pas-readline/src/readline.pas',
-     History in 'pas-readline/src/history.pas',
+     mal_readline,
      mal_types,
      mal_func,
      reader,
@@ -14,7 +15,7 @@ Uses sysutils,
 
 var
     Repl_Env : TEnv;
-    Line     : PChar;
+    Line     : string;
     I        : longint;
     Key      : string;
 
@@ -179,16 +180,12 @@ begin
 
     while True do
     begin
-        Line := Readline.readline('user> ');
-        if Line = Nil then
-            Halt(0);
-        if Line[0] = #0 then
-            continue;
-        add_history(Line);
-
         try
+            Line := _readline('user> ');
+            if Line = '' then continue;
             WriteLn(REP(Line))
         except
+            On E : MalEOF do Halt(0);
             On E : Exception do
             begin
                 WriteLn('Error: ' + E.message);
index e7575d2..b108a8a 100644 (file)
@@ -1,10 +1,11 @@
 program Mal;
 
+{$H+} // Use AnsiString
+
 Uses sysutils,
      CMem,
      fgl,
-     Readline in 'pas-readline/src/readline.pas',
-     History in 'pas-readline/src/history.pas',
+     mal_readline,
      mal_types,
      mal_func,
      reader,
@@ -14,7 +15,7 @@ Uses sysutils,
 
 var
     Repl_Env : TEnv;
-    Line     : PChar;
+    Line     : string;
     I        : longint;
     Key      : string;
 
@@ -182,16 +183,12 @@ begin
 
     while True do
     begin
-        Line := Readline.readline('user> ');
-        if Line = Nil then
-            Halt(0);
-        if Line[0] = #0 then
-            continue;
-        add_history(Line);
-
         try
+            Line := _readline('user> ');
+            if Line = '' then continue;
             WriteLn(REP(Line))
         except
+            On E : MalEOF do Halt(0);
             On E : Exception do
             begin
                 WriteLn('Error: ' + E.message);
index 01ec6b8..e234d37 100644 (file)
@@ -1,11 +1,12 @@
 program Mal;
 
+{$H+} // Use AnsiString
+
 Uses sysutils,
      CMem,
      fgl,
      math,
-     Readline in 'pas-readline/src/readline.pas',
-     History in 'pas-readline/src/history.pas',
+     mal_readline,
      mal_types,
      mal_func,
      reader,
@@ -15,7 +16,7 @@ Uses sysutils,
 
 var
     Repl_Env : TEnv;
-    Line     : PChar;
+    Line     : string;
     I        : longint;
     Key      : string;
     CmdArgs  : TMalArray;
@@ -203,16 +204,12 @@ begin
 
     while True do
     begin
-        Line := Readline.readline('user> ');
-        if Line = Nil then
-            Halt(0);
-        if Line[0] = #0 then
-            continue;
-        add_history(Line);
-
         try
+            Line := _readline('user> ');
+            if Line = '' then continue;
             WriteLn(REP(Line))
         except
+            On E : MalEOF do Halt(0);
             On E : Exception do
             begin
                 WriteLn('Error: ' + E.message);
index 1186c60..8a24e3c 100644 (file)
@@ -1,11 +1,12 @@
 program Mal;
 
+{$H+} // Use AnsiString
+
 Uses sysutils,
      CMem,
      fgl,
      math,
-     Readline in 'pas-readline/src/readline.pas',
-     History in 'pas-readline/src/history.pas',
+     mal_readline,
      mal_types,
      mal_func,
      reader,
@@ -15,7 +16,7 @@ Uses sysutils,
 
 var
     Repl_Env : TEnv;
-    Line     : PChar;
+    Line     : string;
     I        : longint;
     Key      : string;
     CmdArgs  : TMalArray;
@@ -244,16 +245,12 @@ begin
 
     while True do
     begin
-        Line := Readline.readline('user> ');
-        if Line = Nil then
-            Halt(0);
-        if Line[0] = #0 then
-            continue;
-        add_history(Line);
-
         try
+            Line := _readline('user> ');
+            if Line = '' then continue;
             WriteLn(REP(Line))
         except
+            On E : MalEOF do Halt(0);
             On E : Exception do
             begin
                 WriteLn('Error: ' + E.message);
index 36c07ac..767f2bd 100644 (file)
@@ -1,11 +1,12 @@
 program Mal;
 
+{$H+} // Use AnsiString
+
 Uses sysutils,
      CMem,
      fgl,
      math,
-     Readline in 'pas-readline/src/readline.pas',
-     History in 'pas-readline/src/history.pas',
+     mal_readline,
      mal_types,
      mal_func,
      reader,
@@ -15,7 +16,7 @@ Uses sysutils,
 
 var
     Repl_Env : TEnv;
-    Line     : PChar;
+    Line     : string;
     I        : longint;
     Key      : string;
     CmdArgs  : TMalArray;
@@ -299,16 +300,12 @@ begin
 
     while True do
     begin
-        Line := Readline.readline('user> ');
-        if Line = Nil then
-            Halt(0);
-        if Line[0] = #0 then
-            continue;
-        add_history(Line);
-
         try
+            Line := _readline('user> ');
+            if Line = '' then continue;
             WriteLn(REP(Line))
         except
+            On E : MalEOF do Halt(0);
             On E : Exception do
             begin
                 WriteLn('Error: ' + E.message);
index 9424254..b96a098 100644 (file)
@@ -1,11 +1,12 @@
 program Mal;
 
+{$H+} // Use AnsiString
+
 Uses sysutils,
      CMem,
      fgl,
      math,
-     Readline in 'pas-readline/src/readline.pas',
-     History in 'pas-readline/src/history.pas',
+     mal_readline,
      mal_types,
      mal_func,
      reader,
@@ -15,7 +16,7 @@ Uses sysutils,
 
 var
     Repl_Env : TEnv;
-    Line     : PChar;
+    Line     : string;
     I        : longint;
     Key      : string;
     CmdArgs  : TMalArray;
@@ -319,16 +320,12 @@ begin
 
     while True do
     begin
-        Line := Readline.readline('user> ');
-        if Line = Nil then
-            Halt(0);
-        if Line[0] = #0 then
-            continue;
-        add_history(Line);
-
         try
+            Line := _readline('user> ');
+            if Line = '' then continue;
             WriteLn(REP(Line))
         except
+            On E : MalEOF do Halt(0);
             On E : Exception do
             begin
                 WriteLn('Error: ' + E.message);
index 3f38b05..f5ba762 100644 (file)
@@ -1,11 +1,12 @@
 program Mal;
 
+{$H+} // Use AnsiString
+
 Uses sysutils,
      CMem,
      fgl,
      math,
-     Readline in 'pas-readline/src/readline.pas',
-     History in 'pas-readline/src/history.pas',
+     mal_readline,
      mal_types,
      mal_func,
      reader,
@@ -15,7 +16,7 @@ Uses sysutils,
 
 var
     Repl_Env : TEnv;
-    Line     : PChar;
+    Line     : string;
     I        : longint;
     Key      : string;
     CmdArgs  : TMalArray;
@@ -324,16 +325,12 @@ begin
     REP('(println (str "Mal [" *host-language* "]"))');
     while True do
     begin
-        Line := Readline.readline('user> ');
-        if Line = Nil then
-            Halt(0);
-        if Line[0] = #0 then
-            continue;
-        add_history(Line);
-
         try
+            Line := _readline('user> ');
+            if Line = '' then continue;
             WriteLn(REP(Line))
         except
+            On E : MalEOF do Halt(0);
             On E : Exception do
             begin
                 WriteLn('Error: ' + E.message);