mirror of
https://github.com/nim-lang/Nim.git
synced 2026-07-19 07:21:19 +00:00
tests are green again
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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 =
|
||||
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
|
||||
|
||||
@@ -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:
|
||||
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")
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
discard """
|
||||
file: "twrongexc.nim"
|
||||
outputsub: "Error: unhandled exception [EInvalidValue]"
|
||||
outputsub: "Error: unhandled exception: [EInvalidValue]"
|
||||
"""
|
||||
try:
|
||||
raise newException(EInvalidValue, "")
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user