tests are green again

This commit is contained in:
Araq
2011-06-28 01:31:53 +02:00
parent 3091bc4958
commit 5c94a9e1ae
11 changed files with 23 additions and 558 deletions

View File

@@ -176,10 +176,11 @@ proc fillResult(param: PSym) =
param.loc.s = OnUnknown
proc getParamTypeDesc(m: BModule, t: PType, check: var TIntSet): PRope =
if t.Kind in {tyRef, tyPtr, tyVar}:
var b = skipTypes(t.sons[0], abstractInst)
if b.kind == tySet and mapSetType(b) == ctArray:
return getTypeDescAux(m, b, check)
when false:
if t.Kind in {tyRef, tyPtr, tyVar}:
var b = skipTypes(t.sons[0], abstractInst)
if b.kind == tySet and mapSetType(b) == ctArray:
return getTypeDescAux(m, b, check)
result = getTypeDescAux(m, t, check)
proc genProcParams(m: BModule, t: PType, rettype, params: var PRope,

View File

@@ -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)

View File

@@ -63,7 +63,7 @@ proc find*(s, pattern: string, start: int = 0): bool
proc rawCompile(pattern: string, flags: cint): PPcre =
var
msg: CString
offset: int
offset: cint
com = pcre.Compile(pattern, flags, addr(msg), addr(offset), nil)
if com == nil:
var e: ref EInvalidRegEx
@@ -76,7 +76,7 @@ proc matchOrFind(s: string, pattern: PPcre, matches: var openarray[string],
start: cint): cint =
var
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))
dealloc(pattern)
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 =
var
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)
dealloc(pattern)
return res
proc match(s, pattern: string, matches: var openarray[string],
start: int = 0): bool =
return matchOrFind(s, rawCompile(pattern, PCRE_ANCHORED),
return matchOrFind(s, rawCompile(pattern, PCRE.ANCHORED),
matches, start) >= 0'i32
proc matchLen(s, pattern: string, matches: var openarray[string],
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],
start: int = 0): bool =
return matchOrFind(s, rawCompile(pattern, PCRE_MULTILINE),
return matchOrFind(s, rawCompile(pattern, PCRE.MULTILINE),
matches, start) >= 0'i32
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 =
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 =
## This calls ``match`` with an implicit declared ``matches`` array that

View File

@@ -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)

View File

@@ -206,11 +206,8 @@ proc raiseException(e: ref E_Base, ename: CString) {.compilerRtl.} =
when hasSomeStackTrace:
var buf = newStringOfCap(2000)
rawWriteStackTrace(buf)
if not isNil(e.msg):
add(buf, "Error: unhandled exception: ")
add(buf, e.msg)
else:
add(buf, "Error: unhandled exception")
add(buf, "Error: unhandled exception: ")
if not isNil(e.msg): add(buf, e.msg)
add(buf, " [")
add(buf, $ename)
add(buf, "]\n")

View File

@@ -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),
# but this is not type safe:
var f: proc (x: var TA) = bp
var f = cast[proc (x: var TA)](bp)
var a: TA
f(a) # bp expects a TB, but gets a TA

View File

@@ -21,7 +21,7 @@ proc drawCircle(my: var TCircle) = stdout.writeln("o " & $my.radius)
proc init(my: var TCircle) =
init(TFigure(my)) # call base constructor
my.radius = 5
my.draw = drawCircle
my.draw = cast[proc (my: var TFigure)](drawCircle)
type
TRectangle = object of TFigure
@@ -33,7 +33,7 @@ proc init(my: var TRectangle) =
init(TFigure(my)) # call base constructor
my.width = 5
my.height = 10
my.draw = drawRectangle
my.draw = cast[proc (my: var TFigure)](drawRectangle)
macro `!` (n: expr): stmt =
result = newNimNode(nnkCall, n)

View File

@@ -251,8 +251,6 @@ proc sort*[A](t: var TCountTable[A]) =
## first. This is destructive! You must not modify `t` afterwards!
## You can use the iterators `pairs`, `keys`, and `values` to iterate over
## `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
var h = 1
@@ -263,18 +261,11 @@ proc sort*[A](t: var TCountTable[A]) =
h = h div 3
for i in countup(h, high(t.data)):
var j = i
checkTypeInfo(addr(w), 11, GetTypeInfo(w))
while t.data[j-h].val <= t.data[j].val:
checkTypeInfo(addr(w), 12, GetTypeInfo(w))
var xyz = t.data[j]
checkTypeInfo(addr(w), 13, GetTypeInfo(w))
t.data[j] = 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))
t.data[j] = t.data[j-h]
t.data[j-h] = xyz
j = j-h
checkTypeInfo(addr(w), 16, GetTypeInfo(w))
if j < h: break
if h == 1: break
@@ -293,43 +284,19 @@ const
"50": 344490, "60": 344491, "70": 344492,
"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 =
#fake()
var s = initTable[string, int](64)
for key, val in items(data): s[key] = val
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]()
checkTypeInfo(addr(w), 2, GetTypeInfo(w))
for k, v in items(data): t.inc(k)
checkTypeInfo(addr(w), 3, GetTypeInfo(w))
for k in t.keys: assert t[k] == 1
checkTypeInfo(addr(w), 4, GetTypeInfo(w))
t.inc("90", 3)
checkTypeInfo(addr(w), 5, GetTypeInfo(w))
t.inc("12", 2)
checkTypeInfo(addr(w), 6, GetTypeInfo(w))
t.inc("34", 1)
checkTypeInfo(addr(w), 7, GetTypeInfo(w))
assert t.largest()[0] == "90"
checkTypeInfo(addr(w), 8, GetTypeInfo(w))
t.sort()
checkTypeInfo(addr(w), 9, GetTypeInfo(w))
when false:
for k, v in t.pairs:
echo k, ": ", v
var i = 0
for k, v in t.pairs:

View File

@@ -1,6 +1,6 @@
discard """
file: "twrongexc.nim"
outputsub: "Error: unhandled exception [EInvalidValue]"
outputsub: "Error: unhandled exception: [EInvalidValue]"
"""
try:
raise newException(EInvalidValue, "")

View File

@@ -1,7 +1,7 @@
discard """
file: "tatomic.nim"
line: 7
errormsg: "identifier expected, but found \'atomic\'"
errormsg: "identifier expected, but found 'keyword atomic'"
"""
var
atomic: int

View File

@@ -3,7 +3,6 @@ High priority (version 0.8.12)
* test threads on windows; thread analysis needs to be even more restrictive!
* implement message passing built-ins: channels/queues
* bug: {:}.toTable[int, string]()
* test tester
version 0.9.0