Improved string parser, added license.
authorTim Vaughan <tgvaughan@gmail.com>
Sun, 26 Feb 2017 01:14:11 +0000 (14:14 +1300)
committerTim Vaughan <tgvaughan@gmail.com>
Sun, 26 Feb 2017 01:14:11 +0000 (14:14 +1300)
Previous string parser used recursion to make it easy to cons
up the character list.  Unfortunately this led to stack overflows
for longer strings (such as the license agreement!).  It is now
replaced with a loop and calls to set-cdr!.

src/scheme-library.scm
src/scheme.4th

index 85580fd..68debca 100644 (file)
   (if (= n 0)
     0
     (+ n (sum-recurse (- n 1)))))
+
+;; MISC
+
+(define (license)
+  (display
+"This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see http://www.gnu.org/licenses/.
+"))
+
+(define (welcome)
+  (display
+"Welcome to scheme.forth.jl!
+
+Copyright (C) 2016 Tim Vaughan.
+This program comes with ABSOLUTELY NO WARRANTY; for details type '(license)'.
+Use Ctrl-D to exit.
+"))
index 16939d3..52fcbcc 100644 (file)
@@ -306,6 +306,9 @@ create-symbol lambda            lambda-symbol
 create-symbol λ                 λ-symbol
 create-symbol begin             begin-symbol
 
+\ Symbol to be bound to welcome message procedure by library
+create-symbol welcome           welcome-symbol
+
 \ }}}
 
 \ ---- Environments ---- {{{
@@ -989,35 +992,51 @@ parse-idx-stack parse-idx-sp !
 ;
 
 : readstring ( -- charlist )
-    nextchar [char] " = if
-        inc-parse-idx
 
-        delim? false = if
-            bold fg red
-            ." No delimiter following right double quote. Aborting." cr
-            reset-term abort
+    nil nil
+
+    begin
+        nextchar [char] " <>
+    while
+        nextchar [char] \ = if
+            inc-parse-idx
+            nextchar case
+                [char] n of '\n' endof
+                [char] " of [char] " endof
+                [char] \
+            endcase
+        else
+            nextchar
         then
+        inc-parse-idx character-type
+        nil cons
 
-        dec-parse-idx
+        ( firstchar prevchar thischar )
 
-        0 nil-type exit
-    then
+        2swap nil? if
+            2drop 2swap 2drop 2dup  ( thischar thischar )
+        else
+            ( firstchar thischar prevchar )
+            2over 2swap  set-cdr! ( firstchar thischar )
+        then
+    repeat
 
-    nextchar [char] \ = if
-        inc-parse-idx
-        nextchar case
-            [char] n of '\n' endof
-            [char] " of [char] " endof
-            [char] \
-        endcase
-    else
-        nextchar
+    \ Discard previous character
+    2drop
+
+    inc-parse-idx
+    delim? false = if
+        bold fg red
+        ." No delimiter following right double quote. Aborting." cr
+        reset-term abort
     then
-    inc-parse-idx character-type
 
-    recurse
+    dec-parse-idx
 
-    cons
+    nil? if
+        nil cons
+    then
+    drop string-type
 ;
 
 : readsymbol ( -- charlist )
@@ -1106,7 +1125,6 @@ parse-idx-stack parse-idx-sp !
         inc-parse-idx
 
         readstring
-        drop string-type
 
         nextchar [char] " <> if
             bold red ." Missing closing double-quote." reset-term cr
@@ -1945,13 +1963,14 @@ variable gc-stack-depth
 ;
 
 : repl
-    cr ." Welcome to scheme.forth.jl!" cr
-       ." Use Ctrl-D to exit." cr
 
     empty-parse-str
 
     enable-gc
 
+    \ Display welcome message
+    welcome-symbol nil cons global-env obj@ eval 2drop
+
     begin
         ['] repl-body catch
         case