adds an option to interleave the generated code with snippets from the original source

Lines from the original source are outputted as comments next to line directives.
Hopefully, this will make debugging codegen problems easier.

Other changes:
The frame setup code now uses a single-line C macro. My motivation was to reduce
the noise in the generated output and make it easier to step over the boiler-plate
code, but counter-intuitively this also improved the overall compilation speed a
little bit so I applied the same treatment to line tracking too (this reduces the size of
the generated files and the explanation is that probably the I/O overhead dominates
the macro expansion costs).
This commit is contained in:
Zahary Karadjov 2012-12-02 20:36:29 +02:00
commit d0edb1826b
9 changed files with 149 additions and 85 deletions

View file

@ -56,7 +56,7 @@
# To cache them they are inserted in a `cache` array.
import
msgs, strutils, platform, hashes, crc, options
strutils, platform, hashes, crc, options
type
TFormatStr* = string # later we may change it to CString for better
@ -72,6 +72,11 @@ type
TRopeSeq* = seq[PRope]
TRopesError* = enum
rCannotOpenFile
rInvalidFormatStr
rTokenTooLong
proc con*(a, b: PRope): PRope
proc con*(a: PRope, b: string): PRope
proc con*(a: string, b: PRope): PRope
@ -92,6 +97,9 @@ proc RopeInvariant*(r: PRope): bool
# exported for debugging
# implementation
var ErrorHandler*: proc(err: TRopesError, msg: string, useWarning = false)
# avoid dependency on msgs.nim
proc ropeLen(a: PRope): int =
if a == nil: result = 0
else: result = a.length
@ -225,8 +233,7 @@ proc WriteRope*(head: PRope, filename: string, useWarning = false) =
if head != nil: WriteRope(f, head)
close(f)
else:
rawMessage(if useWarning: warnCannotOpenFile else: errCannotOpenFile,
filename)
ErrorHandler(rCannotOpenFile, filename, useWarning)
var
rnl* = tnl.newRope
@ -255,8 +262,8 @@ proc ropef(frmt: TFormatStr, args: varargs[PRope]): PRope =
inc(i)
if (i > length + 0 - 1) or not (frmt[i] in {'0'..'9'}): break
num = j
if j > high(args) + 1:
internalError("ropes: invalid format string $" & $(j))
if j > high(args) + 1:
ErrorHandler(rInvalidFormatStr, $(j))
else:
app(result, args[j - 1])
of 'n':
@ -265,7 +272,8 @@ proc ropef(frmt: TFormatStr, args: varargs[PRope]): PRope =
of 'N':
app(result, rnl)
inc(i)
else: InternalError("ropes: invalid format string $" & frmt[i])
else:
ErrorHandler(rInvalidFormatStr, $(frmt[i]))
var start = i
while i < length:
if frmt[i] != '$': inc(i)
@ -290,8 +298,8 @@ const
proc auxRopeEqualsFile(r: PRope, bin: var tfile, buf: Pointer): bool =
if r.data != nil:
if r.length > bufSize:
internalError("ropes: token too long")
if r.length > bufSize:
ErrorHandler(rTokenTooLong, r.data)
return
var readBytes = readBuffer(bin, buf, r.length)
result = readBytes == r.length and