diff options
author | Zahary Karadjov <zahary@gmail.com> | 2013-12-09 00:26:04 +0200 |
---|---|---|
committer | Zahary Karadjov <zahary@gmail.com> | 2013-12-09 00:26:04 +0200 |
commit | 95a6e01ea8f7409e205455c42a3db9b399b3e353 (patch) | |
tree | f7e3270dd7e631365f1b4ab777464320f6a6352b /compiler | |
parent | de3b7cd413e02498c0ee5554f55f9c92d2baa9ab (diff) | |
parent | 7e9f158494315abff712110a23f1d5ceb3df4206 (diff) | |
download | Nim-95a6e01ea8f7409e205455c42a3db9b399b3e353.tar.gz |
Merge branch 'master' of github.com:Araq/Nimrod into upstream
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/ccgexprs.nim | 6 | ||||
-rw-r--r-- | compiler/cgen.nim | 23 | ||||
-rw-r--r-- | compiler/cgendata.nim | 1 | ||||
-rw-r--r-- | compiler/extccomp.nim | 2 | ||||
-rw-r--r-- | compiler/lists.nim | 18 | ||||
-rw-r--r-- | compiler/nimconf.nim | 5 | ||||
-rw-r--r-- | compiler/nimrod.nimrod.cfg (renamed from compiler/nimrod.cfg) | 0 | ||||
-rw-r--r-- | compiler/sem.nim | 50 | ||||
-rw-r--r-- | compiler/semexprs.nim | 14 | ||||
-rw-r--r-- | compiler/semstmts.nim | 25 |
10 files changed, 93 insertions, 51 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index c50fd4536..873c61ed4 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -240,6 +240,7 @@ proc genGenericAsgn(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = if needToCopy notin flags or tfShallow in skipTypes(dest.t, abstractVarRange).flags: if dest.s == OnStack or not usesNativeGC(): + useStringh(p.module) linefmt(p, cpsStmts, "memcpy((void*)$1, (NIM_CONST void*)$2, sizeof($3));$n", addrLoc(dest), addrLoc(src), rdLoc(dest)) @@ -316,6 +317,7 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = if needsComplexAssignment(dest.t): genGenericAsgn(p, dest, src, flags) else: + useStringh(p.module) linefmt(p, cpsStmts, "memcpy((void*)$1, (NIM_CONST void*)$2, sizeof($1));$n", rdLoc(dest), rdLoc(src)) @@ -327,11 +329,13 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = "#genericAssignOpenArray((void*)$1, (void*)$2, $1Len0, $3);$n", addrLoc(dest), addrLoc(src), genTypeInfo(p.module, dest.t)) else: + useStringh(p.module) linefmt(p, cpsStmts, "memcpy((void*)$1, (NIM_CONST void*)$2, sizeof($1[0])*$1Len0);$n", rdLoc(dest), rdLoc(src)) of tySet: if mapType(ty) == ctArray: + useStringh(p.module) linefmt(p, cpsStmts, "memcpy((void*)$1, (NIM_CONST void*)$2, $3);$n", rdLoc(dest), rdLoc(src), toRope(getSize(dest.t))) else: @@ -1361,6 +1365,7 @@ proc genSetOp(p: BProc, e: PNode, d: var TLoc, op: TMagic) = lineF(p, cpsStmts, lookupOpr[op], [rdLoc(i), toRope(size), rdLoc(d), rdLoc(a), rdLoc(b)]) of mEqSet: + useStringh(p.module) binaryExprChar(p, e, d, "(memcmp($1, $2, " & $(size) & ")==0)") of mMulSet, mPlusSet, mMinusSet, mSymDiffSet: # we inline the simple for loop for better code generation: @@ -1612,6 +1617,7 @@ proc genSetConstr(p: BProc, e: PNode, d: var TLoc) = if d.k == locNone: getTemp(p, e.typ, d) if getSize(e.typ) > 8: # big set: + useStringh(p.module) lineF(p, cpsStmts, "memset($1, 0, sizeof($1));$n", [rdLoc(d)]) for i in countup(0, sonsLen(e) - 1): if e.sons[i].kind == nkRange: diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 910e675e1..ad9ade63c 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -72,6 +72,11 @@ proc isSimpleConst(typ: PType): bool = {tyTuple, tyObject, tyArray, tyArrayConstr, tySet, tySequence} and not (t.kind == tyProc and t.callConv == ccClosure) +proc useStringh(m: BModule) = + if not m.includesStringh: + m.includesStringh = true + discard lists.IncludeStr(m.headerFiles, "<string.h>") + proc useHeader(m: BModule, sym: PSym) = if lfHeader in sym.loc.Flags: assert(sym.annex != nil) @@ -358,19 +363,24 @@ proc resetLoc(p: BProc, loc: var TLoc) = # field, so disabling this should be safe: genObjectInit(p, cpsStmts, loc.t, loc, true) else: + useStringh(p.module) linefmt(p, cpsStmts, "memset((void*)$1, 0, sizeof($2));$n", addrLoc(loc), rdLoc(loc)) # XXX: We can be extra clever here and call memset only # on the bytes following the m_type field? genObjectInit(p, cpsStmts, loc.t, loc, true) -proc constructLoc(p: BProc, loc: TLoc, section = cpsStmts) = +proc constructLoc(p: BProc, loc: TLoc, isTemp = false) = if not isComplexValueType(skipTypes(loc.t, abstractRange)): - linefmt(p, section, "$1 = 0;$n", rdLoc(loc)) + linefmt(p, cpsStmts, "$1 = 0;$n", rdLoc(loc)) else: - linefmt(p, section, "memset((void*)$1, 0, sizeof($2));$n", - addrLoc(loc), rdLoc(loc)) - genObjectInit(p, section, loc.t, loc, true) + if not isTemp or containsGarbageCollectedRef(loc.t): + # don't use memset for temporary values for performance if we can + # avoid it: + useStringh(p.module) + linefmt(p, cpsStmts, "memset((void*)$1, 0, sizeof($2));$n", + addrLoc(loc), rdLoc(loc)) + genObjectInit(p, cpsStmts, loc.t, loc, true) proc initLocalVar(p: BProc, v: PSym, immediateAsgn: bool) = if sfNoInit notin v.flags: @@ -396,7 +406,7 @@ proc getTemp(p: BProc, t: PType, result: var TLoc) = result.t = getUniqueType(t) result.s = OnStack result.flags = {} - constructLoc(p, result) + constructLoc(p, result, isTemp=true) proc keepAlive(p: BProc, toKeepAlive: TLoc) = when false: @@ -418,6 +428,7 @@ proc keepAlive(p: BProc, toKeepAlive: TLoc) = if not isComplexValueType(skipTypes(toKeepAlive.t, abstractVarRange)): linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(result), rdLoc(toKeepAlive)) else: + useStringh(p.module) linefmt(p, cpsStmts, "memcpy((void*)$1, (NIM_CONST void*)$2, sizeof($3));$n", addrLoc(result), addrLoc(toKeepAlive), rdLoc(result)) diff --git a/compiler/cgendata.nim b/compiler/cgendata.nim index b5888d0f4..c156c40fe 100644 --- a/compiler/cgendata.nim +++ b/compiler/cgendata.nim @@ -91,6 +91,7 @@ type FrameDeclared*: bool # hack for ROD support so that we don't declare # a frame var twice in an init proc isHeaderFile*: bool # C source file is the header file + includesStringh*: bool # C source file already includes ``<string.h>`` cfilename*: string # filename of the module (including path, # without extension) typeCache*: TIdTable # cache the generated types diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim index d7f3386e3..13eb972f6 100644 --- a/compiler/extccomp.nim +++ b/compiler/extccomp.nim @@ -583,7 +583,7 @@ proc CallCCompiler*(projectfile: string) = else: rawMessage(errGenerated, " execution of an external program failed; " & "rerun with --parallelBuild:1 to see the error message") - if optNoLinking notin gGlobalOptions and cmds.len > 0: + if optNoLinking notin gGlobalOptions: # call the linker: var it = PStrEntry(toLink.head) var objfiles = "" diff --git a/compiler/lists.nim b/compiler/lists.nim index 67b32f919..22b1a183a 100644 --- a/compiler/lists.nim +++ b/compiler/lists.nim @@ -91,13 +91,17 @@ proc Remove*(list: var TLinkedList, entry: PListEntry) = if entry.prev != nil: entry.prev.next = entry.next proc bringToFront*(list: var TLinkedList, entry: PListEntry) = - if entry == list.head: return - if entry == list.tail: list.tail = entry.prev - if entry.next != nil: entry.next.prev = entry.prev - if entry.prev != nil: entry.prev.next = entry.next - entry.prev = nil - entry.next = list.head - list.head = entry + when true: + list.remove entry + list.prepend entry + else: + if entry == list.head: return + if entry == list.tail: list.tail = entry.prev + if entry.next != nil: entry.next.prev = entry.prev + if entry.prev != nil: entry.prev.next = entry.next + entry.prev = nil + entry.next = list.head + list.head = entry proc ExcludeStr*(list: var TLinkedList, data: string) = var it = list.head diff --git a/compiler/nimconf.nim b/compiler/nimconf.nim index 507812d9c..7ec566a01 100644 --- a/compiler/nimconf.nim +++ b/compiler/nimconf.nim @@ -243,11 +243,6 @@ proc LoadConfigs*(cfg: string) = readConfigFile(pd / cfg) if gProjectName.len != 0: - var conffile = changeFileExt(gProjectFull, "cfg") - if conffile != pd / cfg and existsFile(conffile): - readConfigFile(conffile) - rawMessage(warnConfigDeprecated, conffile) - # new project wide config file: readConfigFile(changeFileExt(gProjectFull, "nimrod.cfg")) diff --git a/compiler/nimrod.cfg b/compiler/nimrod.nimrod.cfg index 9fa1b8cba..9fa1b8cba 100644 --- a/compiler/nimrod.cfg +++ b/compiler/nimrod.nimrod.cfg diff --git a/compiler/sem.nim b/compiler/sem.nim index ea53afbeb..3ace623bc 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -90,6 +90,24 @@ proc commonType*(x, y: PType): PType = let idx = ord(b.kind in {tyArray, tyArrayConstr}) if a.sons[idx].kind == tyEmpty: return y #elif b.sons[idx].kind == tyEmpty: return x + elif a.kind == tyRange and b.kind == tyRange: + # consider: (range[0..3], range[0..4]) here. We should make that + # range[0..4]. But then why is (range[0..4], 6) not range[0..6]? + # But then why is (2,4) not range[2..4]? But I think this would break + # too much code. So ... it's the same range or the base type. This means + # type(if b: 0 else 1) == int and not range[0..1]. For now. In the long + # run people expect ranges to work properly within a tuple. + if not sameType(a, b): + result = skipTypes(a, {tyRange}).skipIntLit + when false: + if a.kind != tyRange and b.kind == tyRange: + # XXX This really needs a better solution, but a proper fix now breaks + # code. + result = a #.skipIntLit + elif a.kind == tyRange and b.kind != tyRange: + result = b #.skipIntLit + elif a.kind in IntegralTypes and a.n != nil: + result = a #.skipIntLit else: var k = tyNone if a.kind in {tyRef, tyPtr}: @@ -103,7 +121,7 @@ proc commonType*(x, y: PType): PType = if result.isNil: return x if k != tyNone: let r = result - result = NewType(k, r.owner) + result = newType(k, r.owner) result.addSonSkipIntLit(r) proc isTopLevel(c: PContext): bool {.inline.} = @@ -140,26 +158,27 @@ proc IsOpImpl(c: PContext, n: PNode): PNode proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym, semCheck: bool = true): PNode -proc symFromType(t: PType, info: TLineInfo): PSym = - if t.sym != nil: return t.sym - result = newSym(skType, getIdent"AnonType", t.owner, info) - result.flags.incl sfAnon - result.typ = t +when false: + proc symFromType(t: PType, info: TLineInfo): PSym = + if t.sym != nil: return t.sym + result = newSym(skType, getIdent"AnonType", t.owner, info) + result.flags.incl sfAnon + result.typ = t -proc symNodeFromType(c: PContext, t: PType, info: TLineInfo): PNode = - result = newSymNode(symFromType(t, info), info) - result.typ = makeTypeDesc(c, t) + proc symNodeFromType(c: PContext, t: PType, info: TLineInfo): PNode = + result = newSymNode(symFromType(t, info), info) + result.typ = makeTypeDesc(c, t) proc createEvalContext(c: PContext, mode: TEvalMode): PEvalContext = result = newEvalContext(c.module, mode) result.getType = proc (n: PNode): PNode = - var e = tryExpr(c, n) - if e == nil: - result = symNodeFromType(c, errorType(c), n.info) - elif e.typ == nil: + result = tryExpr(c, n) + if result == nil: + result = newSymNode(errorSym(c, n)) + elif result.typ == nil: result = newSymNode(getSysSym"void") else: - result = symNodeFromType(c, e.typ, n.info) + result.typ = makeTypeDesc(c, result.typ) result.handleIsOperator = proc (n: PNode): PNode = result = IsOpImpl(c, n) @@ -210,7 +229,8 @@ proc semAfterMacroCall(c: PContext, n: PNode, s: PSym): PNode = of tyTypeDesc: if n.kind == nkStmtList: result.kind = nkStmtListType var typ = semTypeNode(c, result, nil) - result = symNodeFromType(c, typ, n.info) + result.typ = makeTypeDesc(c, typ) + #result = symNodeFromType(c, typ, n.info) else: result = semExpr(c, result) result = fitNode(c, s.typ.sons[0], result) diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 5abe8da83..ccbb1e367 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -191,7 +191,7 @@ proc isCastable(dst, src: PType): bool = proc isSymChoice(n: PNode): bool {.inline.} = result = n.kind in nkSymChoices -proc semConv(c: PContext, n: PNode, s: PSym): PNode = +proc semConv(c: PContext, n: PNode): PNode = if sonsLen(n) != 2: LocalError(n.info, errConvNeedsOneArg) return n @@ -738,8 +738,7 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode = elif t != nil and t.kind == tyTypeDesc: if n.len == 1: return semObjConstr(c, n, flags) let destType = t.skipTypes({tyTypeDesc, tyGenericInst}) - result = semConv(c, n, symFromType(destType, n.info)) - return + return semConv(c, n) else: result = overloadedCallOpr(c, n) # Now that nkSym does not imply an iteration over the proc/iterator space, @@ -1048,7 +1047,9 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode = # The result so far is a tyTypeDesc bound # a tyGenericBody. The line below will substitute # it with the instantiated type. - result = symNodeFromType(c, semTypeNode(c, n, nil), n.info) + result = n + result.typ = makeTypeDesc(c, semTypeNode(c, n, nil)) + #result = symNodeFromType(c, semTypeNode(c, n, nil), n.info) of tyTuple: checkSonsLen(n, 2) n.sons[0] = makeDeref(n.sons[0]) @@ -1883,7 +1884,8 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = result = semExpr(c, n.sons[0], flags) of nkTypeOfExpr, nkTupleTy, nkRefTy..nkEnumTy: var typ = semTypeNode(c, n, nil).skipTypes({tyTypeDesc}) - result = symNodeFromType(c, typ, n.info) + result.typ = makeTypeDesc(c, typ) + #result = symNodeFromType(c, typ, n.info) of nkCall, nkInfix, nkPrefix, nkPostfix, nkCommand, nkCallStrLit: # check if it is an expression macro: checkMinSonsLen(n, 1) @@ -1906,7 +1908,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = of skType: # XXX think about this more (``set`` procs) if n.len == 2: - result = semConv(c, n, s) + result = semConv(c, n) elif n.len == 1: result = semObjConstr(c, n, flags) elif Contains(c.AmbiguousSymbols, s.id): diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index f514a93d7..a1805fdec 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -883,8 +883,9 @@ proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode = openScope(c) if n.sons[genericParamsPos].kind != nkEmpty: illFormedAst(n) # process parameters: - if n.sons[paramsPos].kind != nkEmpty: - semParamList(c, n.sons[ParamsPos], nil, s) + if n.sons[paramsPos].kind != nkEmpty: + var gp = newNodeI(nkGenericParams, n.info) + semParamList(c, n.sons[ParamsPos], gp, s) ParamsTypeCheck(c, s.typ) else: s.typ = newTypeS(tyProc, c) @@ -1086,6 +1087,8 @@ proc semIterator(c: PContext, n: PNode): PNode = # -- at least for 0.9.2. if s.typ.callConv == ccClosure: incl(s.typ.flags, tfCapturesEnv) + else: + s.typ.callConv = ccInline when false: if s.typ.callConv != ccInline: s.typ.callConv = ccClosure @@ -1108,24 +1111,24 @@ proc finishMethod(c: PContext, s: PSym) = methodDef(s, false) proc semMethod(c: PContext, n: PNode): PNode = - if not isTopLevel(c): LocalError(n.info, errXOnlyAtModuleScope, "method") + if not isTopLevel(c): localError(n.info, errXOnlyAtModuleScope, "method") result = semProcAux(c, n, skMethod, methodPragmas) var s = result.sons[namePos].sym - if not isGenericRoutine(s): + if not isGenericRoutine(s) and result.sons[bodyPos].kind != nkEmpty: if hasObjParam(s): - methodDef(s, false) + methodDef(s, fromCache=false) else: - LocalError(n.info, errXNeedsParamObjectType, "method") + localError(n.info, errXNeedsParamObjectType, "method") proc semConverterDef(c: PContext, n: PNode): PNode = - if not isTopLevel(c): LocalError(n.info, errXOnlyAtModuleScope, "converter") + if not isTopLevel(c): localError(n.info, errXOnlyAtModuleScope, "converter") checkSonsLen(n, bodyPos + 1) result = semProcAux(c, n, skConverter, converterPragmas) var s = result.sons[namePos].sym var t = s.typ - if t.sons[0] == nil: LocalError(n.info, errXNeedsReturnType, "converter") - if sonsLen(t) != 2: LocalError(n.info, errXRequiresOneArgument, "converter") + if t.sons[0] == nil: localError(n.info, errXNeedsReturnType, "converter") + if sonsLen(t) != 2: localError(n.info, errXRequiresOneArgument, "converter") addConverter(c, s) proc semMacroDef(c: PContext, n: PNode): PNode = @@ -1133,9 +1136,9 @@ proc semMacroDef(c: PContext, n: PNode): PNode = result = semProcAux(c, n, skMacro, macroPragmas) var s = result.sons[namePos].sym var t = s.typ - if t.sons[0] == nil: LocalError(n.info, errXNeedsReturnType, "macro") + if t.sons[0] == nil: localError(n.info, errXNeedsReturnType, "macro") if n.sons[bodyPos].kind == nkEmpty: - LocalError(n.info, errImplOfXexpected, s.name.s) + localError(n.info, errImplOfXexpected, s.name.s) proc evalInclude(c: PContext, n: PNode): PNode = result = newNodeI(nkStmtList, n.info) |