Merge branch 'master' into newparser

This commit is contained in:
Araq 2013-05-04 19:10:12 +02:00
commit 23bd3ccd8b
31 changed files with 277 additions and 63 deletions

View file

@ -60,7 +60,7 @@ iterator chosen(packages: PStringTable): string =
proc addBabelPath(p: string, info: TLineInfo) = proc addBabelPath(p: string, info: TLineInfo) =
if not contains(options.searchPaths, p): if not contains(options.searchPaths, p):
Message(info, hintPath, p) if gVerbosity >= 1: Message(info, hintPath, p)
lists.PrependStr(options.lazyPaths, p) lists.PrependStr(options.lazyPaths, p)
proc addPathWithNimFiles(p: string, info: TLineInfo) = proc addPathWithNimFiles(p: string, info: TLineInfo) =
@ -83,7 +83,7 @@ proc addPathRec(dir: string, info: TLineInfo) =
if k == pcDir and p[pos] != '.': if k == pcDir and p[pos] != '.':
addPackage(packages, p) addPackage(packages, p)
for p in packages.chosen: for p in packages.chosen:
addPathWithNimFiles(p, info) addBabelPath(p, info)
proc babelPath*(path: string, info: TLineInfo) = proc babelPath*(path: string, info: TLineInfo) =
addPathRec(path, info) addPathRec(path, info)

View file

@ -11,7 +11,7 @@
## is needed for incremental compilation. ## is needed for incremental compilation.
import import
ast, astalgo, ropes, options, strutils, lexbase, msgs, cgendata, rodutils, ast, astalgo, ropes, options, strutils, nimlexbase, msgs, cgendata, rodutils,
intsets, platform, llstream intsets, platform, llstream
# Careful! Section marks need to contain a tabulator so that they cannot # Careful! Section marks need to contain a tabulator so that they cannot
@ -119,8 +119,8 @@ proc skipWhite(L: var TBaseLexer) =
var pos = L.bufpos var pos = L.bufpos
while true: while true:
case ^pos case ^pos
of CR: pos = lexbase.HandleCR(L, pos) of CR: pos = nimlexbase.HandleCR(L, pos)
of LF: pos = lexbase.HandleLF(L, pos) of LF: pos = nimlexbase.HandleLF(L, pos)
of ' ': inc pos of ' ': inc pos
else: break else: break
L.bufpos = pos L.bufpos = pos
@ -129,8 +129,8 @@ proc skipUntilCmd(L: var TBaseLexer) =
var pos = L.bufpos var pos = L.bufpos
while true: while true:
case ^pos case ^pos
of CR: pos = lexbase.HandleCR(L, pos) of CR: pos = nimlexbase.HandleCR(L, pos)
of LF: pos = lexbase.HandleLF(L, pos) of LF: pos = nimlexbase.HandleLF(L, pos)
of '\0': break of '\0': break
of '/': of '/':
if ^(pos+1) == '*' and ^(pos+2) == '\t': if ^(pos+1) == '*' and ^(pos+2) == '\t':
@ -153,11 +153,11 @@ when false:
while true: while true:
case buf[pos] case buf[pos]
of CR: of CR:
pos = lexbase.HandleCR(L, pos) pos = nimlexbase.HandleCR(L, pos)
buf = L.buf buf = L.buf
result.data.add(tnl) result.data.add(tnl)
of LF: of LF:
pos = lexbase.HandleLF(L, pos) pos = nimlexbase.HandleLF(L, pos)
buf = L.buf buf = L.buf
result.data.add(tnl) result.data.add(tnl)
of '\0': of '\0':
@ -179,11 +179,11 @@ proc readVerbatimSection(L: var TBaseLexer): PRope =
while true: while true:
case buf[pos] case buf[pos]
of CR: of CR:
pos = lexbase.HandleCR(L, pos) pos = nimlexbase.HandleCR(L, pos)
buf = L.buf buf = L.buf
r.add(tnl) r.add(tnl)
of LF: of LF:
pos = lexbase.HandleLF(L, pos) pos = nimlexbase.HandleLF(L, pos)
buf = L.buf buf = L.buf
r.add(tnl) r.add(tnl)
of '\0': of '\0':

View file

@ -197,8 +197,11 @@ proc testCompileOption*(switch: string, info: TLineInfo): bool =
else: InvalidCmdLineOption(passCmd1, switch, info) else: InvalidCmdLineOption(passCmd1, switch, info)
proc processPath(path: string, notRelativeToProj = false): string = proc processPath(path: string, notRelativeToProj = false): string =
let p = if notRelativeToProj or os.isAbsolute(path) or '$' in path: path let p = if notRelativeToProj or os.isAbsolute(path) or
else: options.gProjectPath / path '$' in path or path[0] == '.':
path
else:
options.gProjectPath / path
result = UnixToNativePath(p % ["nimrod", getPrefixDir(), "lib", libpath, result = UnixToNativePath(p % ["nimrod", getPrefixDir(), "lib", libpath,
"home", removeTrailingDirSep(os.getHomeDir()), "home", removeTrailingDirSep(os.getHomeDir()),
"projectname", options.gProjectName, "projectname", options.gProjectName,

View file

@ -10,7 +10,7 @@
# This module handles the conditional symbols. # This module handles the conditional symbols.
import import
ast, astalgo, msgs, hashes, platform, strutils, idents ast, astalgo, hashes, platform, strutils, idents
var gSymbols*: TStrTable var gSymbols*: TStrTable
@ -35,14 +35,12 @@ proc isDefined*(symbol: PIdent): bool =
proc isDefined*(symbol: string): bool = proc isDefined*(symbol: string): bool =
result = isDefined(getIdent(symbol)) result = isDefined(getIdent(symbol))
proc ListSymbols*() = iterator definedSymbolNames*: string =
var it: TTabIter var it: TTabIter
var s = InitTabIter(it, gSymbols) var s = InitTabIter(it, gSymbols)
OutWriteln("-- List of currently defined symbols --") while s != nil:
while s != nil: if s.position == 1: yield s.name.s
if s.position == 1: OutWriteln(s.name.s)
s = nextIter(it, gSymbols) s = nextIter(it, gSymbols)
OutWriteln("-- End of list --")
proc countDefinedSymbols*(): int = proc countDefinedSymbols*(): int =
var it: TTabIter var it: TTabIter

View file

@ -1099,7 +1099,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
result = evalAux(c, n.sons[2], {efLValue}) result = evalAux(c, n.sons[2], {efLValue})
if isSpecial(result): return if isSpecial(result): return
addSon(a, result) addSon(a, result)
result = emptyNode result = a
of mNAddMultiple: of mNAddMultiple:
result = evalAux(c, n.sons[1], {efLValue}) result = evalAux(c, n.sons[1], {efLValue})
if isSpecial(result): return if isSpecial(result): return
@ -1107,7 +1107,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
result = evalAux(c, n.sons[2], {efLValue}) result = evalAux(c, n.sons[2], {efLValue})
if isSpecial(result): return if isSpecial(result): return
for i in countup(0, sonsLen(result) - 1): addSon(a, result.sons[i]) for i in countup(0, sonsLen(result) - 1): addSon(a, result.sons[i])
result = emptyNode result = a
of mNDel: of mNDel:
result = evalAux(c, n.sons[1], {efLValue}) result = evalAux(c, n.sons[1], {efLValue})
if isSpecial(result): return if isSpecial(result): return

View file

@ -16,7 +16,7 @@
# DOS or Macintosh text files, even when it is not the native format. # DOS or Macintosh text files, even when it is not the native format.
import import
hashes, options, msgs, strutils, platform, idents, lexbase, llstream, hashes, options, msgs, strutils, platform, idents, nimlexbase, llstream,
wordrecg wordrecg
const const
@ -508,10 +508,10 @@ proc HandleCRLF(L: var TLexer, pos: int): int =
case L.buf[pos] case L.buf[pos]
of CR: of CR:
registerLine() registerLine()
result = lexbase.HandleCR(L, pos) result = nimlexbase.HandleCR(L, pos)
of LF: of LF:
registerLine() registerLine()
result = lexbase.HandleLF(L, pos) result = nimlexbase.HandleLF(L, pos)
else: result = pos else: result = pos
proc getString(L: var TLexer, tok: var TToken, rawMode: bool) = proc getString(L: var TLexer, tok: var TToken, rawMode: bool) =
@ -537,7 +537,7 @@ proc getString(L: var TLexer, tok: var TToken, rawMode: bool) =
pos = HandleCRLF(L, pos) pos = HandleCRLF(L, pos)
buf = L.buf buf = L.buf
add(tok.literal, tnl) add(tok.literal, tnl)
of lexbase.EndOfFile: of nimlexbase.EndOfFile:
var line2 = L.linenumber var line2 = L.linenumber
L.LineNumber = line L.LineNumber = line
lexMessagePos(L, errClosingTripleQuoteExpected, L.lineStart) lexMessagePos(L, errClosingTripleQuoteExpected, L.lineStart)
@ -559,7 +559,7 @@ proc getString(L: var TLexer, tok: var TToken, rawMode: bool) =
else: else:
inc(pos) # skip '"' inc(pos) # skip '"'
break break
elif c in {CR, LF, lexbase.EndOfFile}: elif c in {CR, LF, nimlexbase.EndOfFile}:
lexMessage(L, errClosingQuoteExpected) lexMessage(L, errClosingQuoteExpected)
break break
elif (c == '\\') and not rawMode: elif (c == '\\') and not rawMode:
@ -640,7 +640,7 @@ proc scanComment(L: var TLexer, tok: var TToken) =
var col = getColNumber(L, pos) var col = getColNumber(L, pos)
while true: while true:
var lastBackslash = -1 var lastBackslash = -1
while buf[pos] notin {CR, LF, lexbase.EndOfFile}: while buf[pos] notin {CR, LF, nimlexbase.EndOfFile}:
if buf[pos] == '\\': lastBackslash = pos+1 if buf[pos] == '\\': lastBackslash = pos+1
add(tok.literal, buf[pos]) add(tok.literal, buf[pos])
inc(pos) inc(pos)
@ -648,7 +648,7 @@ proc scanComment(L: var TLexer, tok: var TToken) =
# a backslash is a continuation character if only followed by spaces # a backslash is a continuation character if only followed by spaces
# plus a newline: # plus a newline:
while buf[lastBackslash] == ' ': inc(lastBackslash) while buf[lastBackslash] == ' ': inc(lastBackslash)
if buf[lastBackslash] notin {CR, LF, lexbase.EndOfFile}: if buf[lastBackslash] notin {CR, LF, nimlexbase.EndOfFile}:
# false positive: # false positive:
lastBackslash = -1 lastBackslash = -1
@ -795,7 +795,7 @@ proc rawGetTok(L: var TLexer, tok: var TToken) =
else: else:
if c in OpChars: if c in OpChars:
getOperator(L, tok) getOperator(L, tok)
elif c == lexbase.EndOfFile: elif c == nimlexbase.EndOfFile:
tok.toktype = tkEof tok.toktype = tkEof
tok.indent = 0 tok.indent = 0
else: else:

View file

@ -14,7 +14,7 @@ import
llstream, strutils, ast, astalgo, lexer, syntaxes, renderer, options, msgs, llstream, strutils, ast, astalgo, lexer, syntaxes, renderer, options, msgs,
os, lists, condsyms, rodread, rodwrite, ropes, trees, times, os, lists, condsyms, rodread, rodwrite, ropes, trees, times,
wordrecg, sem, semdata, idents, passes, docgen, extccomp, wordrecg, sem, semdata, idents, passes, docgen, extccomp,
cgen, jsgen, cgendata, cgen, jsgen, cgendata, json, nversion,
platform, nimconf, importer, passaux, depends, evals, types, idgen, platform, nimconf, importer, passaux, depends, evals, types, idgen,
tables, docgen2, service, magicsys, parser, crc, ccgutils tables, docgen2, service, magicsys, parser, crc, ccgutils
@ -392,6 +392,15 @@ proc wantMainModule =
gProjectMainIdx = addFileExt(gProjectFull, nimExt).fileInfoIdx gProjectMainIdx = addFileExt(gProjectFull, nimExt).fileInfoIdx
proc requireMainModuleOption =
if optMainModule.len == 0:
Fatal(gCmdLineInfo, errMainModuleMustBeSpecified)
else:
gProjectName = optMainModule
gProjectFull = gProjectPath / gProjectName
gProjectMainIdx = addFileExt(gProjectFull, nimExt).fileInfoIdx
proc resetMemory = proc resetMemory =
resetCompilationLists() resetCompilationLists()
ccgutils.resetCaches() ccgutils.resetCaches()
@ -529,9 +538,30 @@ proc MainCommand =
wantMainModule() wantMainModule()
CommandGenDepend() CommandGenDepend()
of "dump": of "dump":
gCmd = cmdDump gcmd = cmdDump
condsyms.ListSymbols() if getconfigvar("dump.format") == "json":
for it in iterSearchPath(searchPaths): MsgWriteln(it) requireMainModuleOption()
var definedSymbols = newJArray()
for s in definedSymbolNames(): definedSymbols.elems.add(%s)
var libpaths = newJArray()
for dir in itersearchpath(searchpaths): libpaths.elems.add(%dir)
var dumpdata = % [
(key: "version", val: %VersionAsString),
(key: "project_path", val: %gProjectFull),
(key: "defined_symbols", val: definedSymbols),
(key: "lib_paths", val: libpaths)
]
outWriteLn($dumpdata)
else:
outWriteLn("-- list of currently defined symbols --")
for s in definedSymbolNames(): outWriteLn(s)
outWriteLn("-- end of list --")
for it in iterSearchPath(searchpaths): msgWriteLn(it)
of "check": of "check":
gCmd = cmdCheck gCmd = cmdCheck
wantMainModule() wantMainModule()
@ -568,7 +598,7 @@ proc MainCommand =
else: else:
rawMessage(errInvalidCommandX, command) rawMessage(errInvalidCommandX, command)
if msgs.gErrorCounter == 0 and gCmd notin {cmdInterpret, cmdRun}: if msgs.gErrorCounter == 0 and gCmd notin {cmdInterpret, cmdRun, cmdDump}:
rawMessage(hintSuccessX, [$gLinesCompiled, rawMessage(hintSuccessX, [$gLinesCompiled,
formatFloat(epochTime() - gLastCmdTime, ffDecimal, 3), formatFloat(epochTime() - gLastCmdTime, ffDecimal, 3),
formatSize(getTotalMem())]) formatSize(getTotalMem())])

View file

@ -83,7 +83,9 @@ type
errInvalidCommandX, errXOnlyAtModuleScope, errInvalidCommandX, errXOnlyAtModuleScope,
errXNeedsParamObjectType, errXNeedsParamObjectType,
errTemplateInstantiationTooNested, errInstantiationFrom, errTemplateInstantiationTooNested, errInstantiationFrom,
errInvalidIndexValueForTuple, errCommandExpectsFilename, errXExpected, errInvalidIndexValueForTuple, errCommandExpectsFilename,
errMainModuleMustBeSpecified,
errXExpected,
errInvalidSectionStart, errGridTableNotImplemented, errGeneralParseError, errInvalidSectionStart, errGridTableNotImplemented, errGeneralParseError,
errNewSectionExpected, errWhitespaceExpected, errXisNoValidIndexFile, errNewSectionExpected, errWhitespaceExpected, errXisNoValidIndexFile,
errCannotRenderX, errVarVarTypeNotAllowed, errInstantiateXExplicitely, errCannotRenderX, errVarVarTypeNotAllowed, errInstantiateXExplicitely,
@ -301,6 +303,7 @@ const
errInstantiationFrom: "instantiation from here", errInstantiationFrom: "instantiation from here",
errInvalidIndexValueForTuple: "invalid index value for tuple subscript", errInvalidIndexValueForTuple: "invalid index value for tuple subscript",
errCommandExpectsFilename: "command expects a filename argument", errCommandExpectsFilename: "command expects a filename argument",
errMainModuleMustBeSpecified: "please, specify a main module in the project configuration file",
errXExpected: "\'$1\' expected", errXExpected: "\'$1\' expected",
errInvalidSectionStart: "invalid section start", errInvalidSectionStart: "invalid section start",
errGridTableNotImplemented: "grid table is not implemented", errGridTableNotImplemented: "grid table is not implemented",

View file

@ -98,13 +98,13 @@ proc ToTreeSet(s: TBitSet, settype: PType, info: TLineInfo): PNode =
result.typ = settype result.typ = settype
result.info = info result.info = info
e = 0 e = 0
while e < high(s) * elemSize: while e < len(s) * elemSize:
if bitSetIn(s, e): if bitSetIn(s, e):
a = e a = e
b = e b = e
while true: while true:
Inc(b) Inc(b)
if (b > high(s) * elemSize) or not bitSetIn(s, b): break if (b >= len(s) * elemSize) or not bitSetIn(s, b): break
Dec(b) Dec(b)
if a == b: if a == b:
addSon(result, newIntTypeNode(nkIntLit, a + first, elemType)) addSon(result, newIntTypeNode(nkIntLit, a + first, elemType))

View file

@ -100,14 +100,14 @@ var
searchPaths*, lazyPaths*: TLinkedList searchPaths*, lazyPaths*: TLinkedList
outFile*: string = "" outFile*: string = ""
headerFile*: string = "" headerFile*: string = ""
gVerbosity*: int # how verbose the compiler is gVerbosity* = 1 # how verbose the compiler is
gNumberOfProcessors*: int # number of processors gNumberOfProcessors*: int # number of processors
gWholeProject*: bool # for 'doc2': output any dependency gWholeProject*: bool # for 'doc2': output any dependency
gEvalExpr* = "" # expression for idetools --eval gEvalExpr* = "" # expression for idetools --eval
gLastCmdTime*: float # when caas is enabled, we measure each command gLastCmdTime*: float # when caas is enabled, we measure each command
gListFullPaths*: bool gListFullPaths*: bool
isServing*: bool = false isServing*: bool = false
proc importantComments*(): bool {.inline.} = gCmd in {cmdDoc, cmdIdeTools} proc importantComments*(): bool {.inline.} = gCmd in {cmdDoc, cmdIdeTools}
proc usesNativeGC*(): bool {.inline.} = gSelectedGC >= gcRefc proc usesNativeGC*(): bool {.inline.} = gSelectedGC >= gcRefc

View file

@ -12,7 +12,7 @@
# standard library. # standard library.
import import
llstream, nhashes, strutils, lexbase llstream, nhashes, strutils, nimlexbase
type type
TCfgEventKind* = enum TCfgEventKind* = enum

View file

@ -23,9 +23,10 @@ proc expectIntLit(c: PContext, n: PNode): int =
proc semInstantiationInfo(c: PContext, n: PNode): PNode = proc semInstantiationInfo(c: PContext, n: PNode): PNode =
result = newNodeIT(nkPar, n.info, n.typ) result = newNodeIT(nkPar, n.info, n.typ)
let idx = expectIntLit(c, n.sons[1]) let idx = expectIntLit(c, n.sons[1])
let useFullPaths = expectIntLit(c, n.sons[2])
let info = getInfoContext(idx) let info = getInfoContext(idx)
var filename = newNodeIT(nkStrLit, n.info, getSysType(tyString)) var filename = newNodeIT(nkStrLit, n.info, getSysType(tyString))
filename.strVal = ToFilename(info) filename.strVal = if useFullPaths != 0: info.toFullPath else: info.ToFilename
var line = newNodeIT(nkIntLit, n.info, getSysType(tyInt)) var line = newNodeIT(nkIntLit, n.info, getSysType(tyInt))
line.intVal = ToLinenumber(info) line.intVal = ToLinenumber(info)
result.add(filename) result.add(filename)

View file

@ -73,6 +73,9 @@ proc serve*(action: proc (){.nimcall.}) =
var line = stdin.readLine.string var line = stdin.readLine.string
if line == "quit": quit() if line == "quit": quit()
execute line execute line
echo ""
FlushFile(stdout)
of "tcp", "": of "tcp", "":
var server = Socket() var server = Socket()
let p = getConfigVar("server.port") let p = getConfigVar("server.port")

View file

@ -55,7 +55,6 @@ path="$lib/pure/unidecode"
@end @end
# additional options always passed to the compiler: # additional options always passed to the compiler:
--verbosity: "1"
--parallel_build: "0" # 0 to auto-detect number of processors --parallel_build: "0" # 0 to auto-detect number of processors
hint[LineTooLong]=off hint[LineTooLong]=off

View file

@ -130,12 +130,14 @@ proc `==`*(a, b: PNimrodNode): bool {.magic: "EqNimrodNode", noSideEffect.}
proc len*(n: PNimrodNode): int {.magic: "NLen".} proc len*(n: PNimrodNode): int {.magic: "NLen".}
## returns the number of children of `n`. ## returns the number of children of `n`.
proc add*(father, child: PNimrodNode) {.magic: "NAdd".} proc add*(father, child: PNimrodNode): PNimrodNode {.magic: "NAdd", discardable.}
## adds the `child` to the `father` node ## Adds the `child` to the `father` node. Returns the
## father node so that calls can be nested.
proc add*(father: PNimrodNode, children: varargs[PNimrodNode]) {. proc add*(father: PNimrodNode, children: varargs[PNimrodNode]): PNimrodNode {.
magic: "NAddMultiple".} magic: "NAddMultiple", discardable.}
## adds each child of `children` to the `father` node ## Adds each child of `children` to the `father` node.
## Returns the `father` node so that calls can be nested.
proc del*(father: PNimrodNode, idx = 0, n = 1) {.magic: "NDel".} proc del*(father: PNimrodNode, idx = 0, n = 1) {.magic: "NDel".}
## deletes `n` children of `father` starting at index `idx`. ## deletes `n` children of `father` starting at index `idx`.

View file

@ -34,7 +34,10 @@ const
proc getIdent(e: PNimrodNode): string {.compileTime.} = proc getIdent(e: PNimrodNode): string {.compileTime.} =
case e.kind case e.kind
of nnkIdent: result = normalize($e.ident) of nnkIdent: result = normalize($e.ident)
of nnkAccQuoted: result = getIdent(e[0]) of nnkAccQuoted:
result = getIdent(e[0])
for i in 1 .. e.len-1:
result.add getIdent(e[i])
else: error("cannot extract identifier from node: " & toStrLit(e).strVal) else: error("cannot extract identifier from node: " & toStrLit(e).strVal)
proc delete[T](s: var seq[T], attr: T): bool = proc delete[T](s: var seq[T], attr: T): bool =
@ -478,4 +481,5 @@ macro `var`*(e: expr): expr {.immediate.} =
when isMainModule: when isMainModule:
var nim = "Nimrod" var nim = "Nimrod"
echo h1(a(href="http://nimrod-code.org", nim)) echo h1(a(href="http://nimrod-code.org", nim))
echo form(action="test", `accept-charset` = "Content-Type")

View file

@ -106,6 +106,12 @@ proc write*(s: PStream, x: string) =
## terminating zero is written. ## terminating zero is written.
writeData(s, cstring(x), x.len) writeData(s, cstring(x), x.len)
proc writeln*(s: PStream, args: varargs[string, `$`]) =
## writes one or more strings to the the stream `s` followed
## by a new line. No length field or terminating zero is written.
for str in args: write(s, str)
write(s, "\n")
proc read[T](s: PStream, result: var T) = proc read[T](s: PStream, result: var T) =
## generic read procedure. Reads `result` from the stream `s`. ## generic read procedure. Reads `result` from the stream `s`.
if readData(s, addr(result), sizeof(T)) != sizeof(T): if readData(s, addr(result), sizeof(T)) != sizeof(T):

View file

@ -2407,8 +2407,8 @@ proc astToStr*[T](x: T): string {.magic: "AstToStr", noSideEffect.}
## converts the AST of `x` into a string representation. This is very useful ## converts the AST of `x` into a string representation. This is very useful
## for debugging. ## for debugging.
proc InstantiationInfo*(index = -1): tuple[filename: string, line: int] {. proc InstantiationInfo*(index = -1, fullPaths = false): tuple[
magic: "InstantiationInfo", noSideEffect.} filename: string, line: int] {. magic: "InstantiationInfo", noSideEffect.}
## provides access to the compiler's instantiation stack line information. ## provides access to the compiler's instantiation stack line information.
## ##
## This proc is mostly useful for meta programming (eg. ``assert`` template) ## This proc is mostly useful for meta programming (eg. ``assert`` template)
@ -2438,6 +2438,9 @@ proc InstantiationInfo*(index = -1): tuple[filename: string, line: int] {.
## testException(EInvalidIndex, tester(1)) ## testException(EInvalidIndex, tester(1))
## # --> Test failure at example.nim:20 with 'tester(1)' ## # --> Test failure at example.nim:20 with 'tester(1)'
template CurrentSourcePath*: string = InstantiationInfo(-1, true).filename
## returns the full file-system path of the current source
proc raiseAssert*(msg: string) {.noinline.} = proc raiseAssert*(msg: string) {.noinline.} =
raise newException(EAssertionFailed, msg) raise newException(EAssertionFailed, msg)

View file

@ -0,0 +1,7 @@
main.nim
> c
SuccessX
> c
! Processing
SuccessX

View file

@ -0,0 +1,9 @@
main.nim
> c
SuccessX
> idetools --track:main.nim,5,18 --def main.nim
strutils.toUpper
SuccessX
> idetools --track:main.nim,5,18 --def main.nim
strutils.toUpper
SuccessX

View file

@ -0,0 +1,7 @@
main.nim
> idetools --track:main.nim,5,18 --def main.nim
strutils.toUpper
SuccessX
> c
SuccessX

3
tests/caas/imported.nim Normal file
View file

@ -0,0 +1,3 @@
proc `+++`*(a,b: string): string =
return a & " " & b

7
tests/caas/main.nim Normal file
View file

@ -0,0 +1,7 @@
import imported, strutils
proc main =
var t1 = "text"
var t2 = t1.toUpper
echo(t1 +++ t2)

86
tests/caasdriver.nim Normal file
View file

@ -0,0 +1,86 @@
import osproc, streams, os, strutils, re
type
TNimrodSession* = object
nim: PProcess
proc dirname(path: string): string = path.splitPath()[0]
var
TesterDir = getAppDir()
NimrodBin = TesterDir / "../bin/nimrod"
proc startNimrodSession*(project: string): TNimrodSession =
result.nim = startProcess(NimrodBin,
workingDir = project.dirname,
args = ["serve", "--server.type:stdin", project])
proc doCommand*(session: var TNimrodSession, command: string): string =
session.nim.inputStream.write(command & "\n")
session.nim.inputStream.flush
result = ""
while true:
var line = TaintedString("")
if session.nim.outputStream.readLine(line):
if line.string == "": break
result.add(line.string & "\n")
else:
result = "FAILED TO EXECUTE: " & command & "\n" & result
break
proc close(session: var TNimrodSession) {.destructor.} =
session.nim.close
proc doScenario(script: string, output: PStream): bool =
result = true
var f = open(script)
var project = TaintedString("")
if f.readLine(project):
var
s = startNimrodSession(script.dirname / project.string)
tline = TaintedString("")
lastOutput = ""
ln = 1
while f.readLine(tline):
var line = tline.string
inc ln
if line.strip.len == 0: continue
if line.startsWith(">"):
lastOutput = s.doCommand(line.substr(1).strip)
output.writeln line, "\n", lastOutput
else:
var expectMatch = true
var pattern = line
if line.startsWith("!"):
pattern = line.substr(1).strip
expectMatch = false
var actualMatch = lastOutput.find(re(pattern)) != -1
if expectMatch == actualMatch:
output.writeln "SUCCESS ", line
else:
output.writeln "FAILURE ", line
result = false
iterator caasTestsRunner*(filter = ""): tuple[test, output: string,
status: bool] =
for scenario in os.walkFiles(TesterDir / "caas/*.txt"):
if filter.len > 0 and find(scenario, filter) == -1: continue
var outStream = newStringStream()
let r = doScenario(scenario, outStream)
yield (scenario, outStream.data, r)
when isMainModule:
var filter = ""
if paramCount() > 0: filter = paramStr(1)
for t, o, r in caasTestsRunner(filter):
echo t, "\n", o

View file

@ -1,12 +1,14 @@
discard """ discard """
file: "tbug499771.nim" file: "tbug499771.nim"
output: "TSubRange: 5 from 1 to 10" output: '''TSubRange: 5 from 1 to 10
true true true'''
""" """
type TSubRange = range[1 .. 10] type
TSubRange = range[1 .. 10]
TEnum = enum A, B, C
var sr: TSubRange = 5 var sr: TSubRange = 5
echo("TSubRange: " & $sr & " from " & $low(TSubRange) & " to " & echo("TSubRange: " & $sr & " from " & $low(TSubRange) & " to " &
$high(TSubRange)) $high(TSubRange))
const cset = {A} + {B}
echo A in cset, " ", B in cset, " ", C notin cset

View file

@ -1,7 +0,0 @@
discard """
file: "tlenopenarray.nim"
output: "1"
"""
echo len([1_000_000]) #OUT 1

View file

@ -0,0 +1,26 @@
discard """
output: "direct\nopenarray\nvarargs"
"""
proc withDirectType(args: string) =
echo "direct"
proc withDirectType[T](arg: T) =
echo "generic"
proc withOpenArray(args: openarray[string]) =
echo "openarray"
proc withOpenArray[T](arg: T) =
echo "generic"
proc withVarargs(args: varargs[string]) =
echo "varargs"
proc withVarargs[T](arg: T) =
echo "generic"
withDirectType "string"
withOpenArray "string"
withVarargs "string"

14
tests/run/tvarious1.nim Normal file
View file

@ -0,0 +1,14 @@
discard """
file: "tlenopenarray.nim"
output: '''1
0'''
"""
echo len([1_000_000]) #OUT 1
type
TArray = array[0..3, int]
TVector = distinct array[0..3, int]
proc `[]`(v: TVector; idx: int): int = TArray(v)[idx]
var v: TVector
echo v[2]

View file

@ -11,7 +11,7 @@
import import
parseutils, strutils, pegs, os, osproc, streams, parsecfg, browsers, json, parseutils, strutils, pegs, os, osproc, streams, parsecfg, browsers, json,
marshal, cgi, parseopt marshal, cgi, parseopt, caasdriver
const const
cmdTemplate = r"nimrod cc --hints:on $# $#" cmdTemplate = r"nimrod cc --hints:on $# $#"
@ -38,6 +38,7 @@ type
reExeNotFound, reExeNotFound,
reIgnored, # test is ignored reIgnored, # test is ignored
reSuccess # test was successful reSuccess # test was successful
TTarget = enum TTarget = enum
targetC, targetCpp, targetObjC, targetJS targetC, targetCpp, targetObjC, targetJS
@ -363,6 +364,10 @@ proc outputJSON(reject, compile, run: TResults) =
var s = pretty(doc) var s = pretty(doc)
writeFile(jsonFile, s) writeFile(jsonFile, s)
proc runCaasTests(r: var TResults) =
for test, output, status in caasTestsRunner():
r.addResult(test, "", output, if status: reSuccess else: reOutputsDiffer)
proc main() = proc main() =
os.putenv "NIMTEST_NO_COLOR", "1" os.putenv "NIMTEST_NO_COLOR", "1"
os.putenv "NIMTEST_OUTPUT_LVL", "PRINT_FAILURES" os.putenv "NIMTEST_OUTPUT_LVL", "PRINT_FAILURES"
@ -404,6 +409,7 @@ proc main() =
writeResults(runJson, r) writeResults(runJson, r)
of "special": of "special":
runSpecialTests(r, p.cmdLineRest.string) runSpecialTests(r, p.cmdLineRest.string)
runCaasTests(r)
writeResults(runJson, r) writeResults(runJson, r)
of "rodfiles": of "rodfiles":
runRodFiles(r, p.cmdLineRest.string) runRodFiles(r, p.cmdLineRest.string)

View file

@ -29,6 +29,8 @@ Library Additions
- Added ``system.unsafeNew`` to support hacky variable length objects. - Added ``system.unsafeNew`` to support hacky variable length objects.
- ``system.fields`` and ``system.fieldPairs`` support ``object`` too; they - ``system.fields`` and ``system.fieldPairs`` support ``object`` too; they
used to only support tuples. used to only support tuples.
- Added ``system.CurrentSourcePath`` returning the full file-system path of
the current source file
Changes affecting backwards compatibility Changes affecting backwards compatibility