summary refs log tree commit diff stats
path: root/compiler/nimlexbase.nim
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/nimlexbase.nim')
-rw-r--r--compiler/nimlexbase.nim44
1 files changed, 27 insertions, 17 deletions
diff --git a/compiler/nimlexbase.nim b/compiler/nimlexbase.nim
index e3e8f1dbb..6708b57f8 100644
--- a/compiler/nimlexbase.nim
+++ b/compiler/nimlexbase.nim
@@ -12,8 +12,12 @@
 # handling that exists! Only at line endings checks are necessary
 # if the buffer needs refilling.
 
-import
-  llstream, strutils
+import llstream
+
+import std/strutils
+
+when defined(nimPreviewSlimSystem):
+  import std/assertions
 
 const
   Lrz* = ' '
@@ -39,7 +43,9 @@ const
 type
   TBaseLexer* = object of RootObj
     bufpos*: int
-    buf*: string
+    buf*: cstring
+    bufStorage: string
+    bufLen: int
     stream*: PLLStream        # we read from this stream
     lineNumber*: int          # the current line number
                               # private data:
@@ -59,7 +65,7 @@ proc handleCR*(L: var TBaseLexer, pos: int): int
   # position to continue the scanning from. `pos` must be the position
   # of the CR.
 proc handleLF*(L: var TBaseLexer, pos: int): int
-  # Call this if you scanned over LF in the buffer; it returns the the
+  # Call this if you scanned over LF in the buffer; it returns the
   # position to continue the scanning from. `pos` must be the position
   # of the LF.
 # implementation
@@ -75,8 +81,8 @@ proc fillBuffer(L: var TBaseLexer) =
     oldBufLen: int
   # we know here that pos == L.sentinel, but not if this proc
   # is called the first time by initBaseLexer()
-  assert(L.sentinel < L.buf.len)
-  toCopy = L.buf.len - L.sentinel - 1
+  assert(L.sentinel < L.bufLen)
+  toCopy = L.bufLen - L.sentinel - 1
   assert(toCopy >= 0)
   if toCopy > 0:
     moveMem(addr L.buf[0], addr L.buf[L.sentinel + 1], toCopy)
@@ -90,7 +96,7 @@ proc fillBuffer(L: var TBaseLexer) =
     # compute sentinel:
     dec(s)                    # BUGFIX (valgrind)
     while true:
-      assert(s < L.buf.len)
+      assert(s < L.bufLen)
       while (s >= 0) and not (L.buf[s] in NewLines): dec(s)
       if s >= 0:
         # we found an appropriate character for a sentinel:
@@ -99,16 +105,18 @@ proc fillBuffer(L: var TBaseLexer) =
       else:
         # rather than to give up here because the line is too long,
         # double the buffer's size and try again:
-        oldBufLen = L.buf.len
-        L.buf.setLen(L.buf.len * 2)
-        assert(L.buf.len - oldBufLen == oldBufLen)
+        oldBufLen = L.bufLen
+        L.bufLen = L.bufLen * 2
+        L.bufStorage.setLen(L.bufLen)
+        L.buf = L.bufStorage.cstring
+        assert(L.bufLen - oldBufLen == oldBufLen)
         charsRead = llStreamRead(L.stream, addr(L.buf[oldBufLen]),
                                  oldBufLen)
         if charsRead < oldBufLen:
           L.buf[oldBufLen + charsRead] = EndOfFile
           L.sentinel = oldBufLen + charsRead
           break
-        s = L.buf.len - 1
+        s = L.bufLen - 1
 
 proc fillBaseLexer(L: var TBaseLexer, pos: int): int =
   assert(pos <= L.sentinel)
@@ -142,7 +150,9 @@ proc openBaseLexer(L: var TBaseLexer, inputstream: PLLStream, bufLen = 8192) =
   assert(bufLen > 0)
   L.bufpos = 0
   L.offsetBase = 0
-  L.buf = newString(bufLen)
+  L.bufStorage = newString(bufLen)
+  L.buf = L.bufStorage.cstring
+  L.bufLen = bufLen
   L.sentinel = bufLen - 1
   L.lineStart = 0
   L.lineNumber = 1            # lines start at 1
@@ -156,9 +166,9 @@ proc getColNumber(L: TBaseLexer, pos: int): int =
 proc getCurrentLine(L: TBaseLexer, marker: bool = true): string =
   result = ""
   var i = L.lineStart
-  while not (L.buf[i] in {CR, LF, EndOfFile}):
-    result.add(L.buf[i])
-    inc(i)
-  result.add("\n")
+  while L.buf[i] notin {CR, LF, EndOfFile}:
+    result.add L.buf[i]
+    inc i
+  result.add "\n"
   if marker:
-    result.add(spaces(getColNumber(L, L.bufpos)) & '^' & "\n")
+    result.add spaces(getColNumber(L, L.bufpos)) & '^' & "\n"