bugfix: optimization of complex constant string concatenations
This commit is contained in:
parent
88f9eff38f
commit
97366d4419
7 changed files with 43 additions and 16 deletions
|
|
@ -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) =
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
2
koch.nim
2
koch.nim
|
|
@ -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) =
|
||||||
|
|
|
||||||
|
|
@ -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
11
tests/run/tconcat.nim
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
discard """
|
||||||
|
output: "DabcD"
|
||||||
|
"""
|
||||||
|
|
||||||
|
const
|
||||||
|
x = "abc"
|
||||||
|
|
||||||
|
var v = "D" & x & "D"
|
||||||
|
|
||||||
|
echo v
|
||||||
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
-----------------
|
-----------------
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue