tests are green again
This commit is contained in:
parent
3091bc4958
commit
5c94a9e1ae
11 changed files with 23 additions and 558 deletions
|
|
@ -176,10 +176,11 @@ proc fillResult(param: PSym) =
|
||||||
param.loc.s = OnUnknown
|
param.loc.s = OnUnknown
|
||||||
|
|
||||||
proc getParamTypeDesc(m: BModule, t: PType, check: var TIntSet): PRope =
|
proc getParamTypeDesc(m: BModule, t: PType, check: var TIntSet): PRope =
|
||||||
if t.Kind in {tyRef, tyPtr, tyVar}:
|
when false:
|
||||||
var b = skipTypes(t.sons[0], abstractInst)
|
if t.Kind in {tyRef, tyPtr, tyVar}:
|
||||||
if b.kind == tySet and mapSetType(b) == ctArray:
|
var b = skipTypes(t.sons[0], abstractInst)
|
||||||
return getTypeDescAux(m, b, check)
|
if b.kind == tySet and mapSetType(b) == ctArray:
|
||||||
|
return getTypeDescAux(m, b, check)
|
||||||
result = getTypeDescAux(m, t, check)
|
result = getTypeDescAux(m, t, check)
|
||||||
|
|
||||||
proc genProcParams(m: BModule, t: PType, rettype, params: var PRope,
|
proc genProcParams(m: BModule, t: PType, rettype, params: var PRope,
|
||||||
|
|
|
||||||
|
|
@ -1,144 +0,0 @@
|
||||||
#
|
|
||||||
#
|
|
||||||
# Nimrod's Runtime Library
|
|
||||||
# (c) Copyright 2009 Andreas Rumpf
|
|
||||||
#
|
|
||||||
# See the file "copying.txt", included in this
|
|
||||||
# distribution, for details about the copyright.
|
|
||||||
#
|
|
||||||
|
|
||||||
## This module implements a simple logger. It is based on the following design:
|
|
||||||
## * Runtime log formating is a bug: Sooner or later every log file is parsed.
|
|
||||||
## * Keep it simple: If this library does not fullfill your needs, write your
|
|
||||||
## own. Trying to support every logging feature just leads to bloat.
|
|
||||||
##
|
|
||||||
## Format is::
|
|
||||||
##
|
|
||||||
## DEBUG|INFO|... (2009-11-02 00:00:00)? (Component: )? Message
|
|
||||||
##
|
|
||||||
##
|
|
||||||
|
|
||||||
type
|
|
||||||
TLevel* = enum ## logging level
|
|
||||||
lvlAll, ## all levels active
|
|
||||||
lvlDebug, ## debug level (and any above) active
|
|
||||||
lvlInfo, ## info level (and any above) active
|
|
||||||
lvlWarn, ## warn level (and any above) active
|
|
||||||
lvlError, ## error level (and any above) active
|
|
||||||
lvlFatal ## fatal level (and any above) active
|
|
||||||
|
|
||||||
const
|
|
||||||
LevelNames*: array [TLevel, string] = [
|
|
||||||
"DEBUG", "DEBUG", "INFO", "WARN", "ERROR", "FATAL"
|
|
||||||
]
|
|
||||||
|
|
||||||
type
|
|
||||||
TLogger* = object of TObject ## abstract logger; the base type of all loggers
|
|
||||||
levelThreshold*: TLevel ## only messages of level >= levelThreshold
|
|
||||||
## should be processed
|
|
||||||
TConsoleLogger* = object of TLogger ## logger that writes the messages to the
|
|
||||||
## console
|
|
||||||
|
|
||||||
TFileLogger* = object of TLogger ## logger that writes the messages to a file
|
|
||||||
f: TFile
|
|
||||||
|
|
||||||
TRollingFileLogger* = object of
|
|
||||||
TFileLogger ## logger that writes the message to a file
|
|
||||||
maxlines: int # maximum number of lines
|
|
||||||
lines: seq[string]
|
|
||||||
|
|
||||||
method log*(L: ref TLogger, level: TLevel,
|
|
||||||
frmt: string, args: openArray[string]) =
|
|
||||||
## override this method in custom loggers. Default implementation does
|
|
||||||
## nothing.
|
|
||||||
nil
|
|
||||||
|
|
||||||
method log*(L: ref TConsoleLogger, level: TLevel,
|
|
||||||
frmt: string, args: openArray[string]) =
|
|
||||||
Writeln(stdout, LevelNames[level], " ", frmt % args)
|
|
||||||
|
|
||||||
method log*(L: ref TFileLogger, level: TLevel,
|
|
||||||
frmt: string, args: openArray[string]) =
|
|
||||||
Writeln(L.f, LevelNames[level], " ", frmt % args)
|
|
||||||
|
|
||||||
proc defaultFilename*(): string =
|
|
||||||
## returns the default filename for a logger
|
|
||||||
var (path, name, ext) = splitFile(getAppFilename())
|
|
||||||
result = changeFileExt(path / name & "_" & getDateStr(), "log")
|
|
||||||
|
|
||||||
proc substituteLog*(frmt: string): string =
|
|
||||||
## converts $date to the current date
|
|
||||||
## converts $time to the current time
|
|
||||||
## converts $app to getAppFilename()
|
|
||||||
## converts
|
|
||||||
result = ""
|
|
||||||
var i = 0
|
|
||||||
while i < frmt.len:
|
|
||||||
if frmt[i] != '$':
|
|
||||||
result.add(frmt[i])
|
|
||||||
inc(i)
|
|
||||||
else:
|
|
||||||
inc(i)
|
|
||||||
var v = ""
|
|
||||||
var app = getAppFilename()
|
|
||||||
while frmt[i] in IdentChars:
|
|
||||||
v.add(toLower(frmt[i]))
|
|
||||||
inc(i)
|
|
||||||
case v
|
|
||||||
of "date": result.add(getDateStr())
|
|
||||||
of "time": result.add(getClockStr())
|
|
||||||
of "app": result.add(app)
|
|
||||||
of "appdir": result.add(app.splitFile.dir)
|
|
||||||
of "appname": result.add(app.splitFile.name)
|
|
||||||
|
|
||||||
|
|
||||||
proc newFileLogger(filename = defaultFilename(),
|
|
||||||
mode: TFileMode = fmAppend,
|
|
||||||
levelThreshold = lvlNone): ref TFileLogger =
|
|
||||||
new(result)
|
|
||||||
result.levelThreshold = levelThreshold
|
|
||||||
result.f = open(filename, mode)
|
|
||||||
|
|
||||||
proc newRollingFileLogger(filename = defaultFilename(),
|
|
||||||
mode: TFileMode = fmAppend,
|
|
||||||
levelThreshold = lvlNone,
|
|
||||||
maxLines = 1000): ref TFileLogger =
|
|
||||||
new(result)
|
|
||||||
result.levelThreshold = levelThreshold
|
|
||||||
result.maxLines = maxLines
|
|
||||||
result.f = open(filename, mode)
|
|
||||||
|
|
||||||
var
|
|
||||||
level* = lvlNone
|
|
||||||
handlers*: seq[ref TLogger] = @[]
|
|
||||||
|
|
||||||
proc logLoop(level: TLevel, msg: string) =
|
|
||||||
for logger in items(handlers):
|
|
||||||
if level >= logger.levelThreshold:
|
|
||||||
log(logger, level, msg)
|
|
||||||
|
|
||||||
template log*(level: TLevel, msg: string) =
|
|
||||||
## logs a message of the given level
|
|
||||||
if level >= logging.Level:
|
|
||||||
(bind logLoop)(level, frmt, args)
|
|
||||||
|
|
||||||
template debug*(msg: string) =
|
|
||||||
## logs a debug message
|
|
||||||
log(lvlDebug, msg)
|
|
||||||
|
|
||||||
template info*(msg: string) =
|
|
||||||
## logs an info message
|
|
||||||
log(lvlInfo, msg)
|
|
||||||
|
|
||||||
template warn*(msg: string) =
|
|
||||||
## logs a warning message
|
|
||||||
log(lvlWarn, msg)
|
|
||||||
|
|
||||||
template error*(msg: string) =
|
|
||||||
## logs an error message
|
|
||||||
log(lvlError, msg)
|
|
||||||
|
|
||||||
template fatal*(msg: string) =
|
|
||||||
## logs a fatal error message and calls ``quit(msg)``
|
|
||||||
log(lvlFatal, msg)
|
|
||||||
|
|
||||||
|
|
@ -63,7 +63,7 @@ proc find*(s, pattern: string, start: int = 0): bool
|
||||||
proc rawCompile(pattern: string, flags: cint): PPcre =
|
proc rawCompile(pattern: string, flags: cint): PPcre =
|
||||||
var
|
var
|
||||||
msg: CString
|
msg: CString
|
||||||
offset: int
|
offset: cint
|
||||||
com = pcre.Compile(pattern, flags, addr(msg), addr(offset), nil)
|
com = pcre.Compile(pattern, flags, addr(msg), addr(offset), nil)
|
||||||
if com == nil:
|
if com == nil:
|
||||||
var e: ref EInvalidRegEx
|
var e: ref EInvalidRegEx
|
||||||
|
|
@ -76,7 +76,7 @@ proc matchOrFind(s: string, pattern: PPcre, matches: var openarray[string],
|
||||||
start: cint): cint =
|
start: cint): cint =
|
||||||
var
|
var
|
||||||
rawMatches: array [0..maxSubpatterns * 3 - 1, cint]
|
rawMatches: array [0..maxSubpatterns * 3 - 1, cint]
|
||||||
res = int(pcreExec(pattern, nil, s, len(s), start, 0,
|
res = int(pcre.Exec(pattern, nil, s, len(s), start, 0,
|
||||||
cast[ptr cint](addr(rawMatches)), maxSubpatterns * 3))
|
cast[ptr cint](addr(rawMatches)), maxSubpatterns * 3))
|
||||||
dealloc(pattern)
|
dealloc(pattern)
|
||||||
if res < 0: return res
|
if res < 0: return res
|
||||||
|
|
@ -91,30 +91,30 @@ proc matchOrFind(s: string, pattern: PPcre, matches: var openarray[string],
|
||||||
proc matchOrFind(s: string, pattern: PPcre, start: cint): cint =
|
proc matchOrFind(s: string, pattern: PPcre, start: cint): cint =
|
||||||
var
|
var
|
||||||
rawMatches: array [0..maxSubpatterns * 3 - 1, cint]
|
rawMatches: array [0..maxSubpatterns * 3 - 1, cint]
|
||||||
res = pcreExec(pattern, nil, s, len(s), start, 0,
|
res = pcre.Exec(pattern, nil, s, len(s), start, 0,
|
||||||
cast[ptr cint](addr(rawMatches)), maxSubpatterns * 3)
|
cast[ptr cint](addr(rawMatches)), maxSubpatterns * 3)
|
||||||
dealloc(pattern)
|
dealloc(pattern)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
proc match(s, pattern: string, matches: var openarray[string],
|
proc match(s, pattern: string, matches: var openarray[string],
|
||||||
start: int = 0): bool =
|
start: int = 0): bool =
|
||||||
return matchOrFind(s, rawCompile(pattern, PCRE_ANCHORED),
|
return matchOrFind(s, rawCompile(pattern, PCRE.ANCHORED),
|
||||||
matches, start) >= 0'i32
|
matches, start) >= 0'i32
|
||||||
|
|
||||||
proc matchLen(s, pattern: string, matches: var openarray[string],
|
proc matchLen(s, pattern: string, matches: var openarray[string],
|
||||||
start: int = 0): int =
|
start: int = 0): int =
|
||||||
return matchOrFind(s, rawCompile(pattern, PCRE_ANCHORED), matches, start)
|
return matchOrFind(s, rawCompile(pattern, PCRE.ANCHORED), matches, start)
|
||||||
|
|
||||||
proc find(s, pattern: string, matches: var openarray[string],
|
proc find(s, pattern: string, matches: var openarray[string],
|
||||||
start: int = 0): bool =
|
start: int = 0): bool =
|
||||||
return matchOrFind(s, rawCompile(pattern, PCRE_MULTILINE),
|
return matchOrFind(s, rawCompile(pattern, PCRE.MULTILINE),
|
||||||
matches, start) >= 0'i32
|
matches, start) >= 0'i32
|
||||||
|
|
||||||
proc match(s, pattern: string, start: int = 0): bool =
|
proc match(s, pattern: string, start: int = 0): bool =
|
||||||
return matchOrFind(s, rawCompile(pattern, PCRE_ANCHORED), start) >= 0'i32
|
return matchOrFind(s, rawCompile(pattern, PCRE.ANCHORED), start) >= 0'i32
|
||||||
|
|
||||||
proc find(s, pattern: string, start: int = 0): bool =
|
proc find(s, pattern: string, start: int = 0): bool =
|
||||||
return matchOrFind(s, rawCompile(pattern, PCRE_MULTILINE), start) >= 0'i32
|
return matchOrFind(s, rawCompile(pattern, PCRE.MULTILINE), start) >= 0'i32
|
||||||
|
|
||||||
template `=~` *(s, pattern: expr): expr =
|
template `=~` *(s, pattern: expr): expr =
|
||||||
## This calls ``match`` with an implicit declared ``matches`` array that
|
## This calls ``match`` with an implicit declared ``matches`` array that
|
||||||
|
|
|
||||||
|
|
@ -1,355 +0,0 @@
|
||||||
#
|
|
||||||
#
|
|
||||||
# Nimrod's Runtime Library
|
|
||||||
# (c) Copyright 2010 Andreas Rumpf
|
|
||||||
#
|
|
||||||
# See the file "copying.txt", included in this
|
|
||||||
# distribution, for details about the copyright.
|
|
||||||
#
|
|
||||||
|
|
||||||
## This module implements a simple high performance `YAML`:idx:
|
|
||||||
## lexer. This is used by the ``yamlparser`` module, but it can be useful
|
|
||||||
## to avoid ``yamlparser`` for its overhead.
|
|
||||||
|
|
||||||
import
|
|
||||||
hashes, strutils, lexbase, streams, unicode
|
|
||||||
|
|
||||||
type
|
|
||||||
TTokenKind* = enum ## YAML tokens
|
|
||||||
tkError,
|
|
||||||
tkEof,
|
|
||||||
tkString,
|
|
||||||
tkNumber,
|
|
||||||
tkTrue,
|
|
||||||
tkFalse,
|
|
||||||
tkNull,
|
|
||||||
tkCurlyLe,
|
|
||||||
tkCurlyRi,
|
|
||||||
tkBracketLe,
|
|
||||||
tkBracketRi,
|
|
||||||
tkColon,
|
|
||||||
tkComma
|
|
||||||
|
|
||||||
TYamlLexer* = object of TBaseLexer ## the lexer object.
|
|
||||||
a: string
|
|
||||||
kind: TJsonEventKind
|
|
||||||
err: TJsonError
|
|
||||||
state: seq[TParserState]
|
|
||||||
filename: string
|
|
||||||
|
|
||||||
proc open*(my: var TYamlLexer, input: PStream, filename: string) =
|
|
||||||
## initializes the parser with an input stream. `Filename` is only used
|
|
||||||
## for nice error messages.
|
|
||||||
lexbase.open(my, input)
|
|
||||||
my.filename = filename
|
|
||||||
my.state = @[stateNormal]
|
|
||||||
my.kind = jsonError
|
|
||||||
my.a = ""
|
|
||||||
|
|
||||||
proc close*(my: var TYamlLexer) {.inline.} =
|
|
||||||
## closes the parser `my` and its associated input stream.
|
|
||||||
lexbase.close(my)
|
|
||||||
|
|
||||||
proc getColumn*(my: TYamlLexer): int {.inline.} =
|
|
||||||
## get the current column the parser has arrived at.
|
|
||||||
result = getColNumber(my, my.bufPos)
|
|
||||||
|
|
||||||
proc getLine*(my: TYamlLexer): int {.inline.} =
|
|
||||||
## get the current line the parser has arrived at.
|
|
||||||
result = my.linenumber
|
|
||||||
|
|
||||||
proc getFilename*(my: TYamlLexer): string {.inline.} =
|
|
||||||
## get the filename of the file that the parser processes.
|
|
||||||
result = my.filename
|
|
||||||
|
|
||||||
proc handleHexChar(c: Char, x: var TRune): bool =
|
|
||||||
result = true # Success
|
|
||||||
case c
|
|
||||||
of '0'..'9': x = (x shl 4) or (ord(c) - ord('0'))
|
|
||||||
of 'a'..'f': x = (x shl 4) or (ord(c) - ord('a') + 10)
|
|
||||||
of 'A'..'F': x = (x shl 4) or (ord(c) - ord('A') + 10)
|
|
||||||
else: result = false # error
|
|
||||||
|
|
||||||
proc parseString(my: var TYamlLexer): TTokKind =
|
|
||||||
result = tkString
|
|
||||||
var pos = my.bufpos + 1
|
|
||||||
var buf = my.buf
|
|
||||||
while true:
|
|
||||||
case buf[pos]
|
|
||||||
of '\0':
|
|
||||||
my.err = errQuoteExpected
|
|
||||||
result = tkError
|
|
||||||
break
|
|
||||||
of '"':
|
|
||||||
inc(pos)
|
|
||||||
break
|
|
||||||
of '\\':
|
|
||||||
case buf[pos+1]
|
|
||||||
of '\\', '"', '\'', '/':
|
|
||||||
add(my.a, buf[pos+1])
|
|
||||||
inc(pos, 2)
|
|
||||||
of 'b':
|
|
||||||
add(my.a, '\b')
|
|
||||||
inc(pos, 2)
|
|
||||||
of 'f':
|
|
||||||
add(my.a, '\f')
|
|
||||||
inc(pos, 2)
|
|
||||||
of 'n':
|
|
||||||
add(my.a, '\L')
|
|
||||||
inc(pos, 2)
|
|
||||||
of 'r':
|
|
||||||
add(my.a, '\C')
|
|
||||||
inc(pos, 2)
|
|
||||||
of 't':
|
|
||||||
add(my.a, '\t')
|
|
||||||
inc(pos, 2)
|
|
||||||
of 'u':
|
|
||||||
inc(pos, 2)
|
|
||||||
var r: TRune
|
|
||||||
if handleHexChar(buf[pos], r): inc(pos)
|
|
||||||
if handleHexChar(buf[pos], r): inc(pos)
|
|
||||||
if handleHexChar(buf[pos], r): inc(pos)
|
|
||||||
if handleHexChar(buf[pos], r): inc(pos)
|
|
||||||
add(my.a, toUTF8(r))
|
|
||||||
else:
|
|
||||||
# don't bother with the error
|
|
||||||
add(my.a, buf[pos])
|
|
||||||
inc(pos)
|
|
||||||
of '\c':
|
|
||||||
pos = lexbase.HandleCR(my, pos)
|
|
||||||
buf = my.buf
|
|
||||||
add(my.a, '\c')
|
|
||||||
of '\L':
|
|
||||||
pos = lexbase.HandleLF(my, pos)
|
|
||||||
buf = my.buf
|
|
||||||
add(my.a, '\L')
|
|
||||||
else:
|
|
||||||
add(my.a, buf[pos])
|
|
||||||
inc(pos)
|
|
||||||
my.bufpos = pos # store back
|
|
||||||
|
|
||||||
proc skip(my: var TYamlLexer) =
|
|
||||||
var pos = my.bufpos
|
|
||||||
var buf = my.buf
|
|
||||||
while true:
|
|
||||||
case buf[pos]
|
|
||||||
of '#':
|
|
||||||
# skip line comment:
|
|
||||||
inc(pos)
|
|
||||||
while true:
|
|
||||||
case buf[pos]
|
|
||||||
of '\0': break
|
|
||||||
of '\c':
|
|
||||||
pos = lexbase.HandleCR(my, pos)
|
|
||||||
buf = my.buf
|
|
||||||
break
|
|
||||||
of '\L':
|
|
||||||
pos = lexbase.HandleLF(my, pos)
|
|
||||||
buf = my.buf
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
inc(pos)
|
|
||||||
of '/':
|
|
||||||
if buf[pos+1] == '/':
|
|
||||||
# skip line comment:
|
|
||||||
inc(pos, 2)
|
|
||||||
while true:
|
|
||||||
case buf[pos]
|
|
||||||
of '\0':
|
|
||||||
break
|
|
||||||
of '\c':
|
|
||||||
pos = lexbase.HandleCR(my, pos)
|
|
||||||
buf = my.buf
|
|
||||||
break
|
|
||||||
of '\L':
|
|
||||||
pos = lexbase.HandleLF(my, pos)
|
|
||||||
buf = my.buf
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
inc(pos)
|
|
||||||
elif buf[pos+1] == '*':
|
|
||||||
# skip long comment:
|
|
||||||
inc(pos, 2)
|
|
||||||
while true:
|
|
||||||
case buf[pos]
|
|
||||||
of '\0':
|
|
||||||
my.err = errEOC_Expected
|
|
||||||
break
|
|
||||||
of '\c':
|
|
||||||
pos = lexbase.HandleCR(my, pos)
|
|
||||||
buf = my.buf
|
|
||||||
of '\L':
|
|
||||||
pos = lexbase.HandleLF(my, pos)
|
|
||||||
buf = my.buf
|
|
||||||
of '*':
|
|
||||||
inc(pos)
|
|
||||||
if buf[pos] == '/':
|
|
||||||
inc(pos)
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
inc(pos)
|
|
||||||
else:
|
|
||||||
break
|
|
||||||
of ' ', '\t':
|
|
||||||
Inc(pos)
|
|
||||||
of '\c':
|
|
||||||
pos = lexbase.HandleCR(my, pos)
|
|
||||||
buf = my.buf
|
|
||||||
of '\L':
|
|
||||||
pos = lexbase.HandleLF(my, pos)
|
|
||||||
buf = my.buf
|
|
||||||
else:
|
|
||||||
break
|
|
||||||
my.bufpos = pos
|
|
||||||
|
|
||||||
proc parseDirective(my: var TYamlLexer) =
|
|
||||||
var pos = my.bufpos
|
|
||||||
var buf = my.buf
|
|
||||||
inc(pos)
|
|
||||||
while buf[pos] in {'\t', ' '}: inc(pos)
|
|
||||||
while true:
|
|
||||||
case buf[pos]
|
|
||||||
of '\0': break
|
|
||||||
of '\c':
|
|
||||||
pos = lexbase.HandleCR(my, pos)
|
|
||||||
buf = my.buf
|
|
||||||
break
|
|
||||||
of '\L':
|
|
||||||
pos = lexbase.HandleLF(my, pos)
|
|
||||||
buf = my.buf
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
add(my.a, buf[pos])
|
|
||||||
inc(pos)
|
|
||||||
|
|
||||||
proc parseNumber(my: var TYamlLexer) =
|
|
||||||
var pos = my.bufpos
|
|
||||||
var buf = my.buf
|
|
||||||
if buf[pos] == '-':
|
|
||||||
add(my.a, '-')
|
|
||||||
inc(pos)
|
|
||||||
if buf[pos] == '.':
|
|
||||||
add(my.a, "0.")
|
|
||||||
inc(pos)
|
|
||||||
else:
|
|
||||||
while buf[pos] in Digits:
|
|
||||||
add(my.a, buf[pos])
|
|
||||||
inc(pos)
|
|
||||||
if buf[pos] == '.':
|
|
||||||
add(my.a, '.')
|
|
||||||
inc(pos)
|
|
||||||
# digits after the dot:
|
|
||||||
while buf[pos] in Digits:
|
|
||||||
add(my.a, buf[pos])
|
|
||||||
inc(pos)
|
|
||||||
if buf[pos] in {'E', 'e'}:
|
|
||||||
add(my.a, buf[pos])
|
|
||||||
inc(pos)
|
|
||||||
if buf[pos] in {'+', '-'}:
|
|
||||||
add(my.a, buf[pos])
|
|
||||||
inc(pos)
|
|
||||||
while buf[pos] in Digits:
|
|
||||||
add(my.a, buf[pos])
|
|
||||||
inc(pos)
|
|
||||||
my.bufpos = pos
|
|
||||||
|
|
||||||
proc parseName(my: var TYamlLexer) =
|
|
||||||
var pos = my.bufpos
|
|
||||||
var buf = my.buf
|
|
||||||
if buf[pos] in IdentStartChars:
|
|
||||||
while buf[pos] in IdentChars:
|
|
||||||
add(my.a, buf[pos])
|
|
||||||
inc(pos)
|
|
||||||
my.bufpos = pos
|
|
||||||
|
|
||||||
proc getTok(my: var TYamlLexer): TTokKind =
|
|
||||||
setLen(my.a, 0)
|
|
||||||
skip(my) # skip whitespace, comments
|
|
||||||
case my.buf[my.bufpos]
|
|
||||||
of '-':
|
|
||||||
inc(my.bufpos)
|
|
||||||
result = tkHyphen
|
|
||||||
of '-', '.', '0'..'9':
|
|
||||||
parseNumber(my)
|
|
||||||
result = tkNumber
|
|
||||||
of '"':
|
|
||||||
result = parseString(my)
|
|
||||||
of '\'':
|
|
||||||
result = parseSingleQuote(my)
|
|
||||||
of '[':
|
|
||||||
inc(my.bufpos)
|
|
||||||
result = tkBracketLe
|
|
||||||
of '{':
|
|
||||||
inc(my.bufpos)
|
|
||||||
result = tkCurlyLe
|
|
||||||
of ']':
|
|
||||||
inc(my.bufpos)
|
|
||||||
result = tkBracketRi
|
|
||||||
of '}':
|
|
||||||
inc(my.bufpos)
|
|
||||||
result = tkCurlyRi
|
|
||||||
of ',':
|
|
||||||
inc(my.bufpos)
|
|
||||||
result = tkComma
|
|
||||||
of ':':
|
|
||||||
inc(my.bufpos)
|
|
||||||
result = tkColon
|
|
||||||
of '?':
|
|
||||||
inc(my.bufpos)
|
|
||||||
result = tkQust
|
|
||||||
of '!':
|
|
||||||
inc(my.bufpos)
|
|
||||||
result = tkExcl
|
|
||||||
of '&':
|
|
||||||
inc(my.bufpos)
|
|
||||||
result = tkAmp
|
|
||||||
of '*':
|
|
||||||
inc(my.bufpos)
|
|
||||||
result = tkStar
|
|
||||||
of '|':
|
|
||||||
parseLiteralBlockScalar(my)
|
|
||||||
result = tkLiteralBlockScalar
|
|
||||||
of '>':
|
|
||||||
parseFoldedBlockScalar(my)
|
|
||||||
result = tkFoldedBlockScalar
|
|
||||||
of '%':
|
|
||||||
parseDirective(my)
|
|
||||||
result = tkDirective
|
|
||||||
of '@', '`':
|
|
||||||
inc(my.bufpos)
|
|
||||||
result = tkReserved
|
|
||||||
of 'a'..'z', 'A'..'Z', '_':
|
|
||||||
parseName(my)
|
|
||||||
case my.a
|
|
||||||
of "null": result = tkNull
|
|
||||||
of "true": result = tkTrue
|
|
||||||
of "false": result = tkFalse
|
|
||||||
else: result = tkError
|
|
||||||
of '\0':
|
|
||||||
result = tkEof
|
|
||||||
else:
|
|
||||||
inc(my.bufpos)
|
|
||||||
result = tkError
|
|
||||||
|
|
||||||
when isMainModule:
|
|
||||||
import os
|
|
||||||
var s = newFileStream(ParamStr(1), fmRead)
|
|
||||||
if s == nil: quit("cannot open the file" & ParamStr(1))
|
|
||||||
var x: TYamlLexer
|
|
||||||
open(x, s, ParamStr(1))
|
|
||||||
while true:
|
|
||||||
next(x)
|
|
||||||
case x.kind
|
|
||||||
of jsonError: Echo(x.errorMsg())
|
|
||||||
of jsonEof: break
|
|
||||||
of jsonString, jsonNumber: echo(x.str)
|
|
||||||
of jsonTrue: Echo("!TRUE")
|
|
||||||
of jsonFalse: Echo("!FALSE")
|
|
||||||
of jsonNull: Echo("!NULL")
|
|
||||||
of jsonObjectStart: Echo("{")
|
|
||||||
of jsonObjectEnd: Echo("}")
|
|
||||||
of jsonArrayStart: Echo("[")
|
|
||||||
of jsonArrayEnd: Echo("]")
|
|
||||||
|
|
||||||
close(x)
|
|
||||||
|
|
||||||
|
|
@ -206,11 +206,8 @@ proc raiseException(e: ref E_Base, ename: CString) {.compilerRtl.} =
|
||||||
when hasSomeStackTrace:
|
when hasSomeStackTrace:
|
||||||
var buf = newStringOfCap(2000)
|
var buf = newStringOfCap(2000)
|
||||||
rawWriteStackTrace(buf)
|
rawWriteStackTrace(buf)
|
||||||
if not isNil(e.msg):
|
add(buf, "Error: unhandled exception: ")
|
||||||
add(buf, "Error: unhandled exception: ")
|
if not isNil(e.msg): add(buf, e.msg)
|
||||||
add(buf, e.msg)
|
|
||||||
else:
|
|
||||||
add(buf, "Error: unhandled exception")
|
|
||||||
add(buf, " [")
|
add(buf, " [")
|
||||||
add(buf, $ename)
|
add(buf, $ename)
|
||||||
add(buf, "]\n")
|
add(buf, "]\n")
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ proc bp(x: var TB) = x.b[high(x.b)] = -1
|
||||||
|
|
||||||
# in Nimrod proc (x: TB) is compatible to proc (x: TA),
|
# in Nimrod proc (x: TB) is compatible to proc (x: TA),
|
||||||
# but this is not type safe:
|
# but this is not type safe:
|
||||||
var f: proc (x: var TA) = bp
|
var f = cast[proc (x: var TA)](bp)
|
||||||
var a: TA
|
var a: TA
|
||||||
f(a) # bp expects a TB, but gets a TA
|
f(a) # bp expects a TB, but gets a TA
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ proc drawCircle(my: var TCircle) = stdout.writeln("o " & $my.radius)
|
||||||
proc init(my: var TCircle) =
|
proc init(my: var TCircle) =
|
||||||
init(TFigure(my)) # call base constructor
|
init(TFigure(my)) # call base constructor
|
||||||
my.radius = 5
|
my.radius = 5
|
||||||
my.draw = drawCircle
|
my.draw = cast[proc (my: var TFigure)](drawCircle)
|
||||||
|
|
||||||
type
|
type
|
||||||
TRectangle = object of TFigure
|
TRectangle = object of TFigure
|
||||||
|
|
@ -33,7 +33,7 @@ proc init(my: var TRectangle) =
|
||||||
init(TFigure(my)) # call base constructor
|
init(TFigure(my)) # call base constructor
|
||||||
my.width = 5
|
my.width = 5
|
||||||
my.height = 10
|
my.height = 10
|
||||||
my.draw = drawRectangle
|
my.draw = cast[proc (my: var TFigure)](drawRectangle)
|
||||||
|
|
||||||
macro `!` (n: expr): stmt =
|
macro `!` (n: expr): stmt =
|
||||||
result = newNimNode(nnkCall, n)
|
result = newNimNode(nnkCall, n)
|
||||||
|
|
|
||||||
|
|
@ -251,8 +251,6 @@ proc sort*[A](t: var TCountTable[A]) =
|
||||||
## first. This is destructive! You must not modify `t` afterwards!
|
## first. This is destructive! You must not modify `t` afterwards!
|
||||||
## You can use the iterators `pairs`, `keys`, and `values` to iterate over
|
## You can use the iterators `pairs`, `keys`, and `values` to iterate over
|
||||||
## `t` in the sorted order.
|
## `t` in the sorted order.
|
||||||
var w: type(t.data[0])
|
|
||||||
checkTypeInfo(addr(w), 10, GetTypeInfo(w))
|
|
||||||
|
|
||||||
# we use shellsort here; fast enough and simple
|
# we use shellsort here; fast enough and simple
|
||||||
var h = 1
|
var h = 1
|
||||||
|
|
@ -263,18 +261,11 @@ proc sort*[A](t: var TCountTable[A]) =
|
||||||
h = h div 3
|
h = h div 3
|
||||||
for i in countup(h, high(t.data)):
|
for i in countup(h, high(t.data)):
|
||||||
var j = i
|
var j = i
|
||||||
checkTypeInfo(addr(w), 11, GetTypeInfo(w))
|
|
||||||
while t.data[j-h].val <= t.data[j].val:
|
while t.data[j-h].val <= t.data[j].val:
|
||||||
checkTypeInfo(addr(w), 12, GetTypeInfo(w))
|
|
||||||
var xyz = t.data[j]
|
var xyz = t.data[j]
|
||||||
checkTypeInfo(addr(w), 13, GetTypeInfo(w))
|
t.data[j] = t.data[j-h]
|
||||||
t.data[j] = xyz
|
t.data[j-h] = xyz
|
||||||
checkTypeInfo(addr(w), 14, GetTypeInfo(w))
|
|
||||||
t.data[j-h] = t.data[j]
|
|
||||||
#swap(t.data[j], t.data[j-h])
|
|
||||||
checkTypeInfo(addr(w), 15, GetTypeInfo(w))
|
|
||||||
j = j-h
|
j = j-h
|
||||||
checkTypeInfo(addr(w), 16, GetTypeInfo(w))
|
|
||||||
if j < h: break
|
if j < h: break
|
||||||
if h == 1: break
|
if h == 1: break
|
||||||
|
|
||||||
|
|
@ -293,43 +284,19 @@ const
|
||||||
"50": 344490, "60": 344491, "70": 344492,
|
"50": 344490, "60": 344491, "70": 344492,
|
||||||
"80": 344497}
|
"80": 344497}
|
||||||
|
|
||||||
proc fake() =
|
|
||||||
#var s: TTable[string, int]
|
|
||||||
#var otherCountTable: TCountTable[string]
|
|
||||||
#var w: type(otherCountTable.data[0])
|
|
||||||
#checkTypeInfo(addr(w), nil, GetTypeInfo(w))
|
|
||||||
|
|
||||||
proc countTableTest1 =
|
proc countTableTest1 =
|
||||||
#fake()
|
|
||||||
var s = initTable[string, int](64)
|
var s = initTable[string, int](64)
|
||||||
for key, val in items(data): s[key] = val
|
for key, val in items(data): s[key] = val
|
||||||
var w: tuple[key: string, val: int] #type(otherCountTable.data[0])
|
var w: tuple[key: string, val: int] #type(otherCountTable.data[0])
|
||||||
checkTypeInfo(addr(w), 0, GetTypeInfo(w))
|
|
||||||
|
|
||||||
#var s = data.toTable
|
|
||||||
#var otherCountTable: TCountTable[string]
|
|
||||||
#var w: tuple[key: string, val: int] #type(otherCountTable.data[0])
|
|
||||||
checkTypeInfo(addr(w), 1, GetTypeInfo(w))
|
|
||||||
|
|
||||||
var t = initCountTable[string]()
|
var t = initCountTable[string]()
|
||||||
checkTypeInfo(addr(w), 2, GetTypeInfo(w))
|
|
||||||
for k, v in items(data): t.inc(k)
|
for k, v in items(data): t.inc(k)
|
||||||
checkTypeInfo(addr(w), 3, GetTypeInfo(w))
|
|
||||||
for k in t.keys: assert t[k] == 1
|
for k in t.keys: assert t[k] == 1
|
||||||
checkTypeInfo(addr(w), 4, GetTypeInfo(w))
|
|
||||||
t.inc("90", 3)
|
t.inc("90", 3)
|
||||||
checkTypeInfo(addr(w), 5, GetTypeInfo(w))
|
|
||||||
t.inc("12", 2)
|
t.inc("12", 2)
|
||||||
checkTypeInfo(addr(w), 6, GetTypeInfo(w))
|
|
||||||
t.inc("34", 1)
|
t.inc("34", 1)
|
||||||
checkTypeInfo(addr(w), 7, GetTypeInfo(w))
|
|
||||||
assert t.largest()[0] == "90"
|
assert t.largest()[0] == "90"
|
||||||
checkTypeInfo(addr(w), 8, GetTypeInfo(w))
|
|
||||||
t.sort()
|
t.sort()
|
||||||
checkTypeInfo(addr(w), 9, GetTypeInfo(w))
|
|
||||||
when false:
|
|
||||||
for k, v in t.pairs:
|
|
||||||
echo k, ": ", v
|
|
||||||
|
|
||||||
var i = 0
|
var i = 0
|
||||||
for k, v in t.pairs:
|
for k, v in t.pairs:
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
discard """
|
discard """
|
||||||
file: "twrongexc.nim"
|
file: "twrongexc.nim"
|
||||||
outputsub: "Error: unhandled exception [EInvalidValue]"
|
outputsub: "Error: unhandled exception: [EInvalidValue]"
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
raise newException(EInvalidValue, "")
|
raise newException(EInvalidValue, "")
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
discard """
|
discard """
|
||||||
file: "tatomic.nim"
|
file: "tatomic.nim"
|
||||||
line: 7
|
line: 7
|
||||||
errormsg: "identifier expected, but found \'atomic\'"
|
errormsg: "identifier expected, but found 'keyword atomic'"
|
||||||
"""
|
"""
|
||||||
var
|
var
|
||||||
atomic: int
|
atomic: int
|
||||||
|
|
|
||||||
1
todo.txt
1
todo.txt
|
|
@ -3,7 +3,6 @@ High priority (version 0.8.12)
|
||||||
* test threads on windows; thread analysis needs to be even more restrictive!
|
* test threads on windows; thread analysis needs to be even more restrictive!
|
||||||
* implement message passing built-ins: channels/queues
|
* implement message passing built-ins: channels/queues
|
||||||
* bug: {:}.toTable[int, string]()
|
* bug: {:}.toTable[int, string]()
|
||||||
* test tester
|
|
||||||
|
|
||||||
|
|
||||||
version 0.9.0
|
version 0.9.0
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue