bugfix: optimization of complex constant string concatenations

This commit is contained in:
Araq 2012-02-17 02:16:33 +01:00
commit 97366d4419
7 changed files with 43 additions and 16 deletions

View file

@ -512,6 +512,10 @@ proc toFileLine*(info: TLineInfo): string {.inline.} =
proc toFileLineCol*(info: TLineInfo): string {.inline.} = proc toFileLineCol*(info: TLineInfo): string {.inline.} =
result = info.toFilename & "(" & $info.line & "," & $info.col & ")" result = info.toFilename & "(" & $info.line & "," & $info.col & ")"
proc `??`* (info: TLineInfo, filename: string): bool =
# only for debugging purposes
result = filename in info.toFilename
var checkPoints: seq[TLineInfo] = @[] var checkPoints: seq[TLineInfo] = @[]
proc addCheckpoint*(info: TLineInfo) = proc addCheckpoint*(info: TLineInfo) =

View file

@ -588,13 +588,15 @@ proc transformCall(c: PTransf, n: PNode): PTransNode =
add(result, transform(c, n.sons[0])) add(result, transform(c, n.sons[0]))
var j = 1 var j = 1
while j < sonsLen(n): while j < sonsLen(n):
var a = n.sons[j] var a = transform(c, n.sons[j]).pnode
inc(j) inc(j)
if isConstExpr(a): if isConstExpr(a):
while (j < sonsLen(n)) and isConstExpr(n.sons[j]): while (j < sonsLen(n)):
a = evalOp(op.magic, n, a, n.sons[j], nil) let b = transform(c, n.sons[j]).pnode
if not isConstExpr(b): break
a = evalOp(op.magic, n, a, b, nil)
inc(j) inc(j)
add(result, transform(c, a)) add(result, a.ptransnode)
if len(result) == 2: result = result[1] if len(result) == 2: result = result[1]
elif n.sons[0].kind == nkSym and n.sons[0].sym.kind == skMethod: elif n.sons[0].kind == nkSym and n.sons[0].sym.kind == skMethod:
# use the dispatcher for the call: # use the dispatcher for the call:

View file

@ -49,8 +49,6 @@ Boot options:
-d:nativeStacktrace use native stack traces (only for Mac OS X or Linux) -d:nativeStacktrace use native stack traces (only for Mac OS X or Linux)
""" """
proc boot(args: string) # Forward declaration
proc exe(f: string): string = return addFileExt(f, ExeExt) proc exe(f: string): string = return addFileExt(f, ExeExt)
proc exec(cmd: string) = proc exec(cmd: string) =

View file

@ -16,7 +16,7 @@ elif defined(macosx):
Lib = "sqlite-3.6.13.dylib" Lib = "sqlite-3.6.13.dylib"
else: else:
const const
Lib = "libsqlite3.so" Lib = "libsqlite3.so(|.0)"
const const
SQLITE_INTEGER* = 1 SQLITE_INTEGER* = 1

11
tests/run/tconcat.nim Normal file
View file

@ -0,0 +1,11 @@
discard """
output: "DabcD"
"""
const
x = "abc"
var v = "D" & x & "D"
echo v

View file

@ -1,26 +1,35 @@
# Simple tool to merge C projects into a single C file # Simple tool to merge C projects into a single C file
import os, strtabs, pegs import os, sets, pegs
proc process(dir, infile: string, outfile: TFile, processed: PStringTable) = type
if processed.hasKey(infile): return TProcessResult = enum prSkipIncludeDir, prAddIncludeDir
processed[infile] = "True"
echo "adding: ", infile proc process(dir, infile: string, outfile: TFile,
for line in lines(dir / infile): processed: var TSet[string]): TProcessResult =
if processed.containsOrIncl(infile): return prSkipIncludeDir
let toProcess = dir / infile
if not existsFile(toProcess):
echo "Warning: could not process: ", toProcess
return prAddIncludeDir
echo "adding: ", toProcess
for line in lines(toProcess):
if line =~ peg"""s <- ig '#include' ig '"' {[^"]+} '"' ig if line =~ peg"""s <- ig '#include' ig '"' {[^"]+} '"' ig
comment <- '/*' !'*/'* '*/' / '//' .* comment <- '/*' !'*/'* '*/' / '//' .*
ig <- (comment / \s+)* """: ig <- (comment / \s+)* """:
# follow the include file: # follow the include file:
process(dir, matches[0], outfile, processed) if process(dir, matches[0], outfile, processed) == prAddIncludeDir:
writeln(outfile, line)
else: else:
writeln(outfile, line) writeln(outfile, line)
proc main(dir, outfile: string) = proc main(dir, outfile: string) =
var o: TFile var o: TFile
if open(o, outfile, fmWrite): if open(o, outfile, fmWrite):
var processed = newStringTable([outfile, "True"]) var processed = initSet[string]()
processed.incl(outfile)
for infile in walkfiles(dir / "*.c"): for infile in walkfiles(dir / "*.c"):
process(dir, extractFilename(infile), o, processed) discard process(dir, extractFilename(infile), o, processed)
close(o) close(o)
else: else:
quit("Cannot open for writing: " & outfile) quit("Cannot open for writing: " & outfile)

View file

@ -10,6 +10,9 @@ Version 0.8.XX has been released! Get it `here <download.html>`_.
Bugfixes Bugfixes
-------- --------
- Fixed a bug where the compiler would "optimize away" valid constant parts of
a string concatenation.
Library Additions Library Additions
----------------- -----------------