diff options
-rw-r--r-- | compiler/ast.nim | 6 | ||||
-rw-r--r-- | compiler/astalgo.nim | 33 | ||||
-rw-r--r-- | compiler/lookups.nim | 14 | ||||
-rw-r--r-- | compiler/sem.nim | 4 | ||||
-rw-r--r-- | compiler/semdata.nim | 1 | ||||
-rw-r--r-- | compiler/semstmts.nim | 4 | ||||
-rw-r--r-- | compiler/semtypes.nim | 35 | ||||
-rw-r--r-- | compiler/semtypinst.nim | 2 | ||||
-rw-r--r-- | compiler/sigmatch.nim | 19 | ||||
-rw-r--r-- | compiler/types.nim | 4 | ||||
-rw-r--r-- | compiler/vmgen.nim | 23 | ||||
-rw-r--r-- | lib/pure/asyncio.nim | 2 | ||||
-rw-r--r-- | lib/pure/htmlparser.nim | 4 | ||||
-rw-r--r-- | lib/pure/irc.nim | 4 | ||||
-rw-r--r-- | lib/pure/matchers.nim | 2 | ||||
-rw-r--r-- | lib/pure/oids.nim | 2 | ||||
-rw-r--r-- | lib/pure/os.nim | 4 | ||||
-rw-r--r-- | lib/pure/osproc.nim | 4 | ||||
-rw-r--r-- | lib/pure/parsecsv.nim | 2 | ||||
-rw-r--r-- | lib/pure/parsesql.nim | 6 | ||||
-rw-r--r-- | lib/pure/xmlparser.nim | 4 | ||||
-rw-r--r-- | lib/windows/winlean.nim | 6 | ||||
-rw-r--r-- | tests/macros/tdebugstmt.nim | 29 | ||||
-rw-r--r-- | tests/template/tprefer_immediate.nim | 17 | ||||
-rw-r--r-- | todo.txt | 7 |
25 files changed, 163 insertions, 75 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim index 7138b5f52..cd002eef1 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -1129,7 +1129,7 @@ proc newType(kind: TTypeKind, owner: PSym): PType = result.align = 2 # default alignment result.id = getID() when debugIds: - RegisterId(result) + registerId(result) #if result.id < 2000 then # MessageOut(typeKindToStr[kind] & ' has id: ' & toString(result.id)) @@ -1166,7 +1166,7 @@ proc copyType(t: PType, owner: PSym, keepId: bool): PType = if keepId: result.id = t.id else: - when debugIds: RegisterId(result) + when debugIds: registerId(result) result.sym = t.sym # backend-info should not be copied proc copySym(s: PSym, keepId: bool = false): PSym = @@ -1177,7 +1177,7 @@ proc copySym(s: PSym, keepId: bool = false): PSym = result.id = s.id else: result.id = getID() - when debugIds: RegisterId(result) + when debugIds: registerId(result) result.flags = s.flags result.magic = s.magic if s.kind == skModule: diff --git a/compiler/astalgo.nim b/compiler/astalgo.nim index 2505bc687..64c1b717c 100644 --- a/compiler/astalgo.nim +++ b/compiler/astalgo.nim @@ -561,14 +561,31 @@ proc strTableContains(t: TStrTable, n: PSym): bool = proc strTableRawInsert(data: var TSymSeq, n: PSym) = var h: THash = n.name.h and high(data) - while data[h] != nil: - if data[h] == n: - # allowed for 'export' feature: - #InternalError(n.info, "StrTableRawInsert: " & n.name.s) - return - h = nextTry(h, high(data)) - assert(data[h] == nil) - data[h] = n + if sfImmediate notin n.flags: + # fast path: + while data[h] != nil: + if data[h] == n: + # allowed for 'export' feature: + #InternalError(n.info, "StrTableRawInsert: " & n.name.s) + return + h = nextTry(h, high(data)) + assert(data[h] == nil) + data[h] = n + else: + # slow path; we have to ensure immediate symbols are preferred for + # symbol lookups. + # consider the chain: foo (immediate), foo, bar, bar (immediate) + # then bar (immediate) gets replaced with foo (immediate) and the non + # immediate foo is picked! Thus we need to replace it with the first + # slot that has in fact the same identifier stored in it! + var favPos = -1 + while data[h] != nil: + if data[h] == n: return + if favPos < 0 and data[h].name.id == n.name.id: favPos = h + h = nextTry(h, high(data)) + assert(data[h] == nil) + data[h] = n + if favPos >= 0: swap data[h], data[favPos] proc symTabReplaceRaw(data: var TSymSeq, prevSym: PSym, newSym: PSym) = assert prevSym.name.h == newSym.name.h diff --git a/compiler/lookups.nim b/compiler/lookups.nim index 6dfd25968..c31eb3121 100644 --- a/compiler/lookups.nim +++ b/compiler/lookups.nim @@ -339,4 +339,16 @@ proc nextOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym = n.sons[0].sym.name, o.inSymChoice) if result != nil and result.kind == skStub: loadStub(result) - + +when false: + proc qualifiedLookUpPreferImmediate*(c: PContext, n: PNode, + flags = {checkUndeclared}): PSym = + var o: TOverloadIter + result = initOverloadIter(o, c, n) + var a = result + while a != nil: + if sfImmediate in a.flags: return a + a = nextOverloadIter(o, c, n) + if result == nil and checkUndeclared in flags: + localError(n.info, errUndeclaredIdentifier, n.considerAcc.s) + result = errorSym(c, n) diff --git a/compiler/sem.nim b/compiler/sem.nim index e89e32f4e..00ac79716 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -83,7 +83,9 @@ proc commonType*(x, y: PType): PType = elif a.kind == tyTypeDesc: # turn any concrete typedesc into the abstract typedesc type if a.sons == nil: result = a - else: result = newType(tyTypeDesc, a.owner) + else: + result = newType(tyTypeDesc, a.owner) + rawAddSon(result, newType(tyNone, a.owner)) elif b.kind in {tyArray, tyArrayConstr, tySet, tySequence} and a.kind == b.kind: # check for seq[empty] vs. seq[int] diff --git a/compiler/semdata.nim b/compiler/semdata.nim index 8b97f3685..c9d95e1bf 100644 --- a/compiler/semdata.nim +++ b/compiler/semdata.nim @@ -211,6 +211,7 @@ proc makeTypeDesc*(c: PContext, typ: PType): PType = proc makeTypeSymNode*(c: PContext, typ: PType, info: TLineInfo): PNode = let typedesc = makeTypeDesc(c, typ) + rawAddSon(typedesc, newTypeS(tyNone, c)) let sym = newSym(skType, idAnon, getCurrOwner(), info).linkTo(typedesc) return newSymNode(sym, info) diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index d3cc1a12e..0871b7fb7 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -740,7 +740,7 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) = # we fill it out later. For magic generics like 'seq', it won't be filled # so we use tyEmpty instead of nil to not crash for strange conversions # like: mydata.seq - rawAddSon(s.typ, newTypeS(tyEmpty, c)) + rawAddSon(s.typ, newTypeS(tyNone, c)) s.ast = a inc c.inGenericContext var body = semTypeNode(c, a.sons[2], nil) @@ -748,7 +748,7 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) = if body != nil: body.sym = s body.size = -1 # could not be computed properly - s.typ.sons[sonsLen(s.typ) - 1] = body + s.typ.sons[sonsLen(s.typ) - 1] = body popOwner() closeScope(c) elif a.sons[2].kind != nkEmpty: diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 789ff55f0..44e414e9c 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -681,12 +681,12 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, of tySequence, tySet, tyArray, tyOpenArray, tyVar, tyPtr, tyRef, tyProc: # XXX: this is a bit strange, but proc(s: seq) - # produces tySequence(tyGenericParam, null). + # produces tySequence(tyGenericParam, tyNone). # This also seems to be true when creating aliases # like: type myseq = distinct seq. # Maybe there is another better place to associate # the seq type class with the seq identifier. - if paramType.kind == tySequence and paramType.lastSon == nil: + if paramType.kind == tySequence and paramType.lastSon.kind == tyNone: let typ = c.newTypeWithSons(tyBuiltInTypeClass, @[newTypeS(paramType.kind, c)]) result = addImplicitGeneric(typ) @@ -1137,15 +1137,26 @@ proc processMagicType(c: PContext, m: PSym) = of mNil: setMagicType(m, tyNil, ptrSize) of mExpr: setMagicType(m, tyExpr, 0) of mStmt: setMagicType(m, tyStmt, 0) - of mTypeDesc: setMagicType(m, tyTypeDesc, 0) + of mTypeDesc: + setMagicType(m, tyTypeDesc, 0) + rawAddSon(m.typ, newTypeS(tyNone, c)) of mVoidType: setMagicType(m, tyEmpty, 0) - of mArray: setMagicType(m, tyArray, 0) - of mOpenArray: setMagicType(m, tyOpenArray, 0) - of mVarargs: setMagicType(m, tyVarargs, 0) - of mRange: setMagicType(m, tyRange, 0) - of mSet: setMagicType(m, tySet, 0) - of mSeq: setMagicType(m, tySequence, 0) - of mOrdinal: setMagicType(m, tyOrdinal, 0) + of mArray: + setMagicType(m, tyArray, 0) + of mOpenArray: + setMagicType(m, tyOpenArray, 0) + of mVarargs: + setMagicType(m, tyVarargs, 0) + of mRange: + setMagicType(m, tyRange, 0) + rawAddSon(m.typ, newTypeS(tyNone, c)) + of mSet: + setMagicType(m, tySet, 0) + of mSeq: + setMagicType(m, tySequence, 0) + of mOrdinal: + setMagicType(m, tyOrdinal, 0) + rawAddSon(m.typ, newTypeS(tyNone, c)) of mPNimrodNode: discard else: localError(m.info, errTypeExpected) @@ -1169,8 +1180,8 @@ proc semGenericParamList(c: PContext, n: PNode, father: PType = nil): PNode = typ = semTypeNode(c, constraint, nil) if typ.kind != tyStatic or typ.len == 0: if typ.kind == tyTypeDesc: - if typ.len == 0: - typ = newTypeS(tyTypeDesc, c) + if typ.sons[0].kind == tyNone: + typ = newTypeWithSons(c, tyTypeDesc, @[newTypeS(tyNone, c)]) else: typ = semGenericConstraints(c, typ) diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim index 1158335a8..a07d91241 100644 --- a/compiler/semtypinst.nim +++ b/compiler/semtypinst.nim @@ -358,7 +358,7 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType = if lookup != nil: result = lookup if tfUnresolved in t.flags: result = result.base - elif t.sonsLen > 0: + elif t.sons[0].kind != tyNone: result = makeTypeDesc(cl.c, replaceTypeVarsT(cl, t.sons[0])) of tyUserTypeClass: diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index d269e9e69..f9200ea0c 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -562,10 +562,11 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation = #if result < isGeneric: result = isNone if result notin {isNone, isGeneric}: result = typeRangeRel(f, a) - elif skipTypes(f, {tyRange}).kind == a.kind: - result = isIntConv - elif isConvertibleToRange(skipTypes(f, {tyRange}), a): - result = isConvertible # a convertible to f + else: + if skipTypes(f, {tyRange}).kind == a.kind: + result = isIntConv + elif isConvertibleToRange(skipTypes(f, {tyRange}), a): + result = isConvertible # a convertible to f of tyInt: result = handleRange(f, a, tyInt8, tyInt32) of tyInt8: result = handleRange(f, a, tyInt8, tyInt8) of tyInt16: result = handleRange(f, a, tyInt8, tyInt16) @@ -636,7 +637,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation = of tyOrdinal: if isOrdinalType(a): var x = if a.kind == tyOrdinal: a.sons[0] else: a - if f.sonsLen == 0: + if f.sons[0].kind == tyNone: result = isGeneric else: result = typeRel(c, f.sons[0], x) @@ -736,7 +737,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation = of tyGenericInst: let roota = a.skipGenericAlias let rootf = f.skipGenericAlias - if a.kind == tyGenericInst and roota.base == rootf.base : + if a.kind == tyGenericInst and roota.base == rootf.base: for i in 1 .. rootf.sonsLen-2: let ff = rootf.sons[i] let aa = roota.sons[i] @@ -845,7 +846,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation = # by a tyTypeDesc params. Unfortunately, this requires more substantial # changes in semtypinst and elsewhere. if a.kind == tyTypeDesc: - if f.sons == nil or f.sons.len == 0: + if f.sonsLen == 0: result = isGeneric else: internalAssert a.sons != nil and a.sons.len > 0 @@ -854,7 +855,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation = else: result = isNone else: - if f.sonsLen > 0: + if f.sonsLen > 0 and f.sons[0].kind != tyNone: result = typeRel(c, f.lastSon, a) else: result = isGeneric @@ -883,7 +884,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation = var prev = PType(idTableGet(c.bindings, f)) if prev == nil: if a.kind == tyTypeDesc: - if f.sonsLen == 0: + if f.sons[0].kind == tyNone: result = isGeneric else: result = typeRel(c, f.sons[0], a.sons[0]) diff --git a/compiler/types.nim b/compiler/types.nim index 812cd4e93..db75cd3c0 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -47,7 +47,7 @@ proc equalParams*(a, b: PNode): TParamsEquality # returns whether the parameter lists of the procs a, b are exactly the same proc isOrdinalType*(t: PType): bool proc enumHasHoles*(t: PType): bool -# XXX it is WRONG to include tyTypeDesc here as that might not have any child! + const abstractPtrs* = {tyVar, tyPtr, tyRef, tyGenericInst, tyDistinct, tyOrdinal, tyConst, tyMutable, tyTypeDesc} @@ -1258,7 +1258,7 @@ proc containsGenericTypeIter(t: PType, closure: PObject): bool = return true if t.kind == tyTypeDesc: - if t.sonsLen == 0: return true + if t.sons[0].kind == tyNone: return true if containsGenericTypeIter(t.base, closure): return true return false diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index be32f990f..313c43dc4 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -946,6 +946,14 @@ proc genAsgn(c: PCtx; dest: TDest; ri: PNode; requiresCopy: bool) = template isGlobal(s: PSym): bool = sfGlobal in s.flags and s.kind != skForVar +proc setSlot(c: PCtx; v: PSym) = + # XXX generate type initialization here? + if v.position == 0: + v.position = c.prc.maxSlots + c.prc.slots[v.position] = (inUse: true, + kind: if v.kind == skLet: slotFixedLet else: slotFixedVar) + inc c.prc.maxSlots + proc genAsgn(c: PCtx; le, ri: PNode; requiresCopy: bool) = case le.kind of nkBracketExpr: @@ -973,8 +981,9 @@ proc genAsgn(c: PCtx; le, ri: PNode; requiresCopy: bool) = gen(c, ri, tmp) c.gABx(le, whichAsgnOpc(le, opcWrGlobal), tmp, s.position) else: + if s.kind == skForVar and c.mode == emRepl: c.setSlot s internalAssert s.position > 0 or (s.position == 0 and - s.kind in {skParam,skResult,skForVar}) + s.kind in {skParam,skResult}) var dest: TRegister = s.position + ord(s.kind == skParam) gen(c, ri, dest) else: @@ -1035,8 +1044,9 @@ proc genRdVar(c: PCtx; n: PNode; dest: var TDest) = else: c.gABx(n, opcLdGlobal, dest, s.position) else: + if s.kind == skForVar and c.mode == emRepl: c.setSlot s if s.position > 0 or (s.position == 0 and - s.kind in {skParam,skResult,skForVar}): + s.kind in {skParam,skResult}): if dest < 0: dest = s.position + ord(s.kind == skParam) else: @@ -1045,7 +1055,6 @@ proc genRdVar(c: PCtx; n: PNode; dest: var TDest) = else: # see tests/t99bott for an example that triggers it: cannotEval(n) - #InternalError(n.info, s.name.s & " " & $s.position) proc genAccess(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode; flags: TGenFlags) = @@ -1123,14 +1132,6 @@ proc getNullValue(typ: PType, info: TLineInfo): PNode = result = newNodeIT(nkCurly, info, t) else: internalError("getNullValue: " & $t.kind) -proc setSlot(c: PCtx; v: PSym) = - # XXX generate type initialization here? - if v.position == 0: - v.position = c.prc.maxSlots - c.prc.slots[v.position] = (inUse: true, - kind: if v.kind == skLet: slotFixedLet else: slotFixedVar) - inc c.prc.maxSlots - proc genVarSection(c: PCtx; n: PNode) = for a in n: if a.kind == nkCommentStmt: continue diff --git a/lib/pure/asyncio.nim b/lib/pure/asyncio.nim index f13cadaa2..96afc6f4f 100644 --- a/lib/pure/asyncio.nim +++ b/lib/pure/asyncio.nim @@ -689,5 +689,5 @@ when isMainModule: server.listen() d.register(server) - while d.poll(-1): nil + while d.poll(-1): discard diff --git a/lib/pure/htmlparser.nim b/lib/pure/htmlparser.nim index 060f0e386..c38eb7063 100644 --- a/lib/pure/htmlparser.nim +++ b/lib/pure/htmlparser.nim @@ -480,7 +480,7 @@ proc untilElementEnd(x: var TXmlParser, result: PXmlNode, if htmlTag(x.elemName) in {tagOption, tagOptgroup}: errors.add(expected(x, result)) break - else: nil + else: discard result.addNode(parse(x, errors)) of xmlElementEnd: if cmpIgnoreCase(x.elemName, result.tag) == 0: @@ -547,7 +547,7 @@ proc parse(x: var TXmlParser, errors: var seq[string]): PXmlNode = var u = entityToUtf8(x.rawData) if u.len != 0: result = newText(u) next(x) - of xmlEof: nil + of xmlEof: discard proc parseHtml*(s: PStream, filename: string, errors: var seq[string]): PXmlNode = diff --git a/lib/pure/irc.nim b/lib/pure/irc.nim index 750c98516..c1b519b0b 100644 --- a/lib/pure/irc.nim +++ b/lib/pure/irc.nim @@ -476,12 +476,12 @@ when isMainModule: var client = irc("amber.tenthbit.net", nick="TestBot1234", joinChans = @["#flood"]) client.connect() - while True: + while true: var event: TIRCEvent if client.poll(event): case event.typ of EvConnected: - nil + discard of EvDisconnected: break of EvMsg: diff --git a/lib/pure/matchers.nim b/lib/pure/matchers.nim index b57e0c45a..2db7fa660 100644 --- a/lib/pure/matchers.nim +++ b/lib/pure/matchers.nim @@ -54,7 +54,7 @@ proc parseInt*(s: string, value: var int, validRange: TSlice[int]) {. try: discard parseutils.parseInt(s, x, 0) except EOverflow: - nil + discard if x in validRange: value = x when isMainModule: diff --git a/lib/pure/oids.nim b/lib/pure/oids.nim index fbe0dda95..b3e74d2a1 100644 --- a/lib/pure/oids.nim +++ b/lib/pure/oids.nim @@ -28,7 +28,7 @@ proc hexbyte*(hex: char): int = of '0'..'9': result = (ord(hex) - ord('0')) of 'a'..'f': result = (ord(hex) - ord('a') + 10) of 'A'..'F': result = (ord(hex) - ord('A') + 10) - else: nil + else: discard proc parseOid*(str: cstring): TOid = ## parses an OID. diff --git a/lib/pure/os.nim b/lib/pure/os.nim index 245a8446b..bb70f28b6 100644 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -1078,9 +1078,9 @@ when defined(windows): while true: var eend = strEnd(e) add(environment, $e) - e = cast[CString](cast[TAddress](eend)+1) + e = cast[cstring](cast[TAddress](eend)+1) if eend[1] == '\0': break - discard FreeEnvironmentStringsA(env) + discard freeEnvironmentStringsA(env) envComputed = true else: diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim index 9975bfcb3..6df85bbc6 100644 --- a/lib/pure/osproc.nim +++ b/lib/pure/osproc.nim @@ -455,7 +455,7 @@ when defined(Windows) and not defined(useNimRtl): ee, wwd, si, procInfo) else: success = winlean.createProcessA(nil, - cmdl, nil, nil, 1, NORMAL_PRIORITY_CLASS, e, wd, SI, ProcInfo) + cmdl, nil, nil, 1, NORMAL_PRIORITY_CLASS, e, wd, si, procInfo) let lastError = osLastError() if poParentStreams notin options: @@ -534,7 +534,7 @@ when defined(Windows) and not defined(useNimRtl): NORMAL_PRIORITY_CLASS, nil, nil, si, procInfo) else: var res = winlean.createProcessA(nil, command, nil, nil, 0, - NORMAL_PRIORITY_CLASS, nil, nil, SI, ProcInfo) + NORMAL_PRIORITY_CLASS, nil, nil, si, procInfo) if res == 0: osError(osLastError()) else: diff --git a/lib/pure/parsecsv.nim b/lib/pure/parsecsv.nim index 5970f2090..4b25babec 100644 --- a/lib/pure/parsecsv.nim +++ b/lib/pure/parsecsv.nim @@ -149,7 +149,7 @@ proc readRow*(my: var TCsvParser, columns = 0): bool = of '\c': my.bufpos = handleCR(my, my.bufpos) of '\l': my.bufpos = handleLF(my, my.bufpos) else: break - of '\0': nil + of '\0': discard else: error(my, my.bufpos, my.sep & " expected") break diff --git a/lib/pure/parsesql.nim b/lib/pure/parsesql.nim index 31951e966..3f9686e1e 100644 --- a/lib/pure/parsesql.nim +++ b/lib/pure/parsesql.nim @@ -79,7 +79,7 @@ proc handleHexChar(c: var TSqlLexer, xi: var int) = xi = (xi shl 4) or (ord(c.buf[c.bufpos]) - ord('A') + 10) inc(c.bufpos) else: - nil + discard proc handleOctChar(c: var TSqlLexer, xi: var int) = if c.buf[c.bufpos] in {'0'..'7'}: @@ -373,7 +373,7 @@ proc getOperator(c: var TSqlLexer, tok: var TToken) = of '+': if not trailingPlusMinus and buf[pos+1] notin operators and tok.literal.len > 0: break - of '*', '<', '>', '=': nil + of '*', '<', '>', '=': discard else: break add(tok.literal, buf[pos]) inc(pos) @@ -1120,7 +1120,7 @@ proc rs(n: PSqlNode, s: var string, indent: int, proc ra(n: PSqlNode, s: var string, indent: int) = if n == nil: return case n.kind - of nkNone: nil + of nkNone: discard of nkIdent: if allCharsInSet(n.strVal, {'\33'..'\127'}): s.add(n.strVal) diff --git a/lib/pure/xmlparser.nim b/lib/pure/xmlparser.nim index 16bbe1455..8b8bb3b03 100644 --- a/lib/pure/xmlparser.nim +++ b/lib/pure/xmlparser.nim @@ -96,7 +96,7 @@ proc parse(x: var TXmlParser, errors: var seq[string]): PXmlNode = ## &entity; errors.add(errorMsg(x, "unknown entity: " & x.entityName)) next(x) - of xmlEof: nil + of xmlEof: discard proc parseXml*(s: PStream, filename: string, errors: var seq[string]): PXmlNode = @@ -110,7 +110,7 @@ proc parseXml*(s: PStream, filename: string, of xmlElementOpen, xmlElementStart: result = parse(x, errors) break - of xmlComment, xmlWhitespace, xmlSpecial, xmlPI: nil # just skip it + of xmlComment, xmlWhitespace, xmlSpecial, xmlPI: discard # just skip it of xmlError: errors.add(errorMsg(x)) else: diff --git a/lib/windows/winlean.nim b/lib/windows/winlean.nim index ee5fe0647..5b641185e 100644 --- a/lib/windows/winlean.nim +++ b/lib/windows/winlean.nim @@ -195,14 +195,14 @@ else: importc: "GetCurrentDirectoryA", dynlib: "kernel32", stdcall.} proc setCurrentDirectoryA*(lpPathName: cstring): int32 {. importc: "SetCurrentDirectoryA", dynlib: "kernel32", stdcall.} - proc createDirectoryA*(pathName: cstring, security: Pointer=nil): int32 {. + proc createDirectoryA*(pathName: cstring, security: pointer=nil): int32 {. importc: "CreateDirectoryA", dynlib: "kernel32", stdcall.} proc removeDirectoryA*(lpPathName: cstring): int32 {. importc: "RemoveDirectoryA", dynlib: "kernel32", stdcall.} proc setEnvironmentVariableA*(lpName, lpValue: cstring): int32 {. stdcall, dynlib: "kernel32", importc: "SetEnvironmentVariableA".} - proc getModuleFileNameA*(handle: THandle, buf: CString, size: int32): int32 {. + proc getModuleFileNameA*(handle: THandle, buf: cstring, size: int32): int32 {. importc: "GetModuleFileNameA", dynlib: "kernel32", stdcall.} when useWinUnicode: @@ -300,7 +300,7 @@ else: dwFileAttributes: int32): WINBOOL {. stdcall, dynlib: "kernel32", importc: "SetFileAttributesA".} - proc copyFileA*(lpExistingFileName, lpNewFileName: CString, + proc copyFileA*(lpExistingFileName, lpNewFileName: cstring, bFailIfExists: cint): cint {. importc: "CopyFileA", stdcall, dynlib: "kernel32".} diff --git a/tests/macros/tdebugstmt.nim b/tests/macros/tdebugstmt.nim new file mode 100644 index 000000000..865dc436a --- /dev/null +++ b/tests/macros/tdebugstmt.nim @@ -0,0 +1,29 @@ +discard """ + output: '''a[0]: 42 +a[1]: 45 +x: some string''' +""" + +import macros + +macro debug(n: varargs[expr]): stmt = + # `n` is a Nimrod AST that contains the whole macro invocation + # this macro returns a list of statements: + result = newNimNode(nnkStmtList, n) + # iterate over any argument that is passed to this macro: + for i in 0..n.len-1: + # add a call to the statement list that writes the expression; + # `toStrLit` converts an AST to its string representation: + add(result, newCall("write", newIdentNode("stdout"), toStrLit(n[i]))) + # add a call to the statement list that writes ": " + add(result, newCall("write", newIdentNode("stdout"), newStrLitNode(": "))) + # add a call to the statement list that writes the expressions value: + add(result, newCall("writeln", newIdentNode("stdout"), n[i])) + +var + a: array [0..10, int] + x = "some string" +a[0] = 42 +a[1] = 45 + +debug(a[0], a[1], x) diff --git a/tests/template/tprefer_immediate.nim b/tests/template/tprefer_immediate.nim new file mode 100644 index 000000000..578f447b0 --- /dev/null +++ b/tests/template/tprefer_immediate.nim @@ -0,0 +1,17 @@ +discard """ + output: '''immediate''' +""" + +# Test that immediate templates are preferred over non-immediate templates + +template foo(a, b: expr) = echo "foo expr" + +template foo(a, b: int) = echo "foo int" +template foo(a, b: float) = echo "foo float" +template foo(a, b: string) = echo "foo string" +template foo(a, b: expr) {.immediate.} = echo "immediate" +template foo(a, b: bool) = echo "foo bool" +template foo(a, b: char) = echo "foo char" + +foo(undeclaredIdentifier, undeclaredIdentifier2) + diff --git a/todo.txt b/todo.txt index fd424ad5e..a9f2e80e5 100644 --- a/todo.txt +++ b/todo.txt @@ -1,11 +1,9 @@ version 0.9.4 ============= -- fix macros\tstringinterp.nim -- test and fix showoff; add debug example to showoff -- test and fix stdlib -- test and fix misc - fix GC issues +- fix macros\tstringinterp.nim +- test and fix showoff - test C source code generation - test and fix closures - test and fix exception handling @@ -22,7 +20,6 @@ Bugs - compilation of niminst takes way too long. looks like a regression - docgen: sometimes effects are listed twice - 'result' is not properly cleaned for NRVO --> use uninit checking instead -- sneaking with qualifiedLookup() is really broken! - blocks can "export" an identifier but the CCG generates {} for them ... - osproc execProcesses can deadlock if all processes fail (as experienced in c++ mode) |