diff options
Diffstat (limited to 'rod')
-rwxr-xr-x | rod/c2nim/cparse.nim | 46 | ||||
-rwxr-xr-x[-rw-r--r--] | rod/c2nim/manual.txt | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | rod/c2nim/tests/systest.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | rod/c2nim/tests/systest2.c | 0 | ||||
-rwxr-xr-x | rod/ccgexprs.nim | 360 | ||||
-rwxr-xr-x | rod/ccgstmts.nim | 59 | ||||
-rwxr-xr-x | rod/ccgtypes.nim | 37 | ||||
-rwxr-xr-x | rod/cgen.nim | 169 | ||||
-rwxr-xr-x | rod/magicsys.nim | 5 | ||||
-rwxr-xr-x | rod/nimrod.ini | 5 | ||||
-rwxr-xr-x | rod/pragmas.nim | 30 | ||||
-rwxr-xr-x | rod/semstmts.nim | 6 | ||||
-rwxr-xr-x | rod/wordrecg.nim | 8 |
13 files changed, 352 insertions, 373 deletions
diff --git a/rod/c2nim/cparse.nim b/rod/c2nim/cparse.nim index 5da9f3015..28cad2805 100755 --- a/rod/c2nim/cparse.nim +++ b/rod/c2nim/cparse.nim @@ -530,11 +530,10 @@ proc structPragmas(p: TParser, name: PNode, origName: string): PNode = result = newNodeP(nkPragmaExpr, p) addson(result, exportSym(p, name)) var pragmas = newNodep(nkPragma, p) - addSon(pragmas, newIdentNodeP("pure", p)) - addSon(pragmas, newIdentNodeP("final", p)) + addSon(pragmas, newIdentNodeP("pure", p), newIdentNodeP("final", p)) if p.options.header.len > 0: - addSon(pragmas, newIdentStrLitPair("importc", origName, p)) - addSon(pragmas, newIdentStrLitPair("header", p.options.header, p)) + addSon(pragmas, newIdentStrLitPair("importc", origName, p), + newIdentStrLitPair("header", p.options.header, p)) addSon(result, pragmas) proc enumPragmas(p: TParser, name: PNode): PNode = @@ -542,15 +541,13 @@ proc enumPragmas(p: TParser, name: PNode): PNode = addson(result, name) var pragmas = newNodep(nkPragma, p) var e = newNodeP(nkExprColonExpr, p) - addSon(e, newIdentNodeP("size", p)) - addSon(e, newIntNodeP(nkIntLit, 4, p)) + addSon(e, newIdentNodeP("size", p), newIntNodeP(nkIntLit, 4, p)) addSon(pragmas, e) addSon(result, pragmas) proc parseStruct(p: var TParser, isUnion: bool): PNode = result = newNodeP(nkObjectTy, p) - addSon(result, nil) # no pragmas - addSon(result, nil) # no inheritance + addSon(result, nil, nil) # no pragmas, no inheritance if p.tok.xkind == pxCurlyLe: addSon(result, parseStructBody(p, isUnion)) else: @@ -569,8 +566,7 @@ proc parseParam(p: var TParser, params: PNode) = name = newIdentNodeP("a" & $idx, p) typ = parseTypeSuffix(p, typ) var x = newNodeP(nkIdentDefs, p) - addSon(x, name) - addSon(x, typ) + addSon(x, name, typ) if p.tok.xkind == pxAsgn: # we support default parameters for C++: getTok(p, x) @@ -621,15 +617,11 @@ proc parseFunctionPointerDecl(p: var TParser, rettyp: PNode): PNode = if p.inTypeDef == 0: result = newNodeP(nkVarSection, p) var def = newNodeP(nkIdentDefs, p) - addSon(def, name) - addSon(def, procType) - addSon(def, nil) + addSon(def, name, procType, nil) addSon(result, def) else: result = newNodeP(nkTypeDef, p) - addSon(result, name) - addSon(result, nil) # no generics - addSon(result, procType) + addSon(result, name, nil, procType) proc addTypeDef(section, name, t: PNode) = var def = newNodeI(nkTypeDef, name.info) @@ -674,8 +666,7 @@ proc enumFields(p: var TParser): PNode = var c = constantExpression(p) var a = e e = newNodeP(nkEnumFieldDef, p) - addSon(e, a) - addSon(e, c) + addSon(e, a, c) skipCom(p, e) addSon(result, e) @@ -871,10 +862,8 @@ proc declaration(p: var TParser): PNode = addSon(pragmas, newIdentNodeP("cdecl", p)) elif pfStdcall in p.options.flags: addSon(pragmas, newIdentNodeP("stdcall", p)) - addSon(result, exportSym(p, name)) - addSon(result, nil) # no generics - addSon(result, params) - addSon(result, pragmas) + addSon(result, exportSym(p, name), nil) # no generics + addSon(result, params, pragmas) case p.tok.xkind of pxSemicolon: getTok(p) @@ -1175,17 +1164,14 @@ proc asgnExpr(p: var TParser, opr: string, a: PNode): PNode = getTok(p, a) var b = assignmentExpression(p) result = newNodeP(nkAsgn, p) - addSon(result, a) - addSon(result, newBinary(opr, copyTree(a), b, p)) + addSon(result, a, newBinary(opr, copyTree(a), b, p)) proc incdec(p: var TParser, opr: string, a: PNode): PNode = closeContext(p) getTok(p, a) var b = assignmentExpression(p) result = newNodeP(nkCall, p) - addSon(result, newIdentNodeP(getIdent(opr), p)) - addSon(result, a) - addSon(result, b) + addSon(result, newIdentNodeP(getIdent(opr), p), a, b) proc assignmentExpression(p: var TParser): PNode = saveContext(p) @@ -1196,8 +1182,7 @@ proc assignmentExpression(p: var TParser): PNode = getTok(p, a) var b = assignmentExpression(p) result = newNodeP(nkAsgn, p) - addSon(result, a) - addSon(result, b) + addSon(result, a, b) of pxPlusAsgn: result = incDec(p, "inc", a) of pxMinusAsgn: result = incDec(p, "dec", a) of pxStarAsgn: result = asgnExpr(p, "*", a) @@ -1291,8 +1276,7 @@ proc conditionalExpression(p: var TParser): PNode = var c = conditionalExpression(p) result = newNodeP(nkIfExpr, p) var branch = newNodeP(nkElifExpr, p) - addSon(branch, a) - addSon(branch, b) + addSon(branch, a, b) addSon(result, branch) branch = newNodeP(nkElseExpr, p) addSon(branch, c) diff --git a/rod/c2nim/manual.txt b/rod/c2nim/manual.txt index bb89c9567..bb89c9567 100644..100755 --- a/rod/c2nim/manual.txt +++ b/rod/c2nim/manual.txt diff --git a/rod/c2nim/tests/systest.c b/rod/c2nim/tests/systest.c index b2b7646bb..b2b7646bb 100644..100755 --- a/rod/c2nim/tests/systest.c +++ b/rod/c2nim/tests/systest.c diff --git a/rod/c2nim/tests/systest2.c b/rod/c2nim/tests/systest2.c index bf3027cfc..bf3027cfc 100644..100755 --- a/rod/c2nim/tests/systest2.c +++ b/rod/c2nim/tests/systest2.c diff --git a/rod/ccgexprs.nim b/rod/ccgexprs.nim index 1e39508d9..88599f8f4 100755 --- a/rod/ccgexprs.nim +++ b/rod/ccgexprs.nim @@ -1,7 +1,7 @@ # # # The Nimrod Compiler -# (c) Copyright 2009 Andreas Rumpf +# (c) Copyright 2010 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -33,7 +33,7 @@ proc genHexLiteral(v: PNode): PRope = result = intLiteral(v.intVal) proc getStrLit(m: BModule, s: string): PRope = - useMagic(m, "TGenericSeq") + discard cgsym(m, "TGenericSeq") result = con("TMP", toRope(getID())) appf(m.s[cfsData], "STRING_LITERAL($1, $2, $3);$n", [result, makeCString(s), ToRope(len(s))]) @@ -69,10 +69,10 @@ proc genLiteral(p: BProc, v: PNode, ty: PType): PRope = var id = NodeTableTestOrSet(p.module.dataCache, v, gid) if id == gid: # string literal not found in the cache: - useMagic(p.module, "NimStringDesc") - result = ropef("((NimStringDesc*) &$1)", [getStrLit(p.module, v.strVal)]) + result = ropecg(p.module, "((#NimStringDesc*) &$1)", + [getStrLit(p.module, v.strVal)]) else: - result = ropef("((NimStringDesc*) &TMP$1)", [toRope(id)]) + result = ropecg(p.module, "((#NimStringDesc*) &TMP$1)", [toRope(id)]) else: result = makeCString(v.strVal) of nkFloatLit..nkFloat64Lit: @@ -119,13 +119,11 @@ proc genRawSetData(cs: TBitSet, size: int): PRope = # result := toRope('0x' + ToHex(bitSetToWord(cs, size), size * 2)) proc genSetNode(p: BProc, n: PNode): PRope = - var - cs: TBitSet - size, id: int - size = int(getSize(n.typ)) + var cs: TBitSet + var size = int(getSize(n.typ)) toBitSet(n, cs) if size > 8: - id = NodeTableTestOrSet(p.module.dataCache, n, gid) + var id = NodeTableTestOrSet(p.module.dataCache, n, gid) result = con("TMP", toRope(id)) if id == gid: # not found in cache: @@ -201,16 +199,13 @@ proc genRefAssign(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = # end; # appf(p.s[cpsStmts], '$1 = $2;$n', [rdLoc(dest), rdLoc(src)]); if canFormAcycle(dest.t): - UseMagic(p.module, "asgnRef") - appf(p.s[cpsStmts], "asgnRef((void**) $1, $2);$n", + appcg(p.module, p.s[cpsStmts], "#asgnRef((void**) $1, $2);$n", [addrLoc(dest), rdLoc(src)]) else: - UseMagic(p.module, "asgnRefNoCycle") - appf(p.s[cpsStmts], "asgnRefNoCycle((void**) $1, $2);$n", + appcg(p.module, p.s[cpsStmts], "#asgnRefNoCycle((void**) $1, $2);$n", [addrLoc(dest), rdLoc(src)]) else: - UseMagic(p.module, "unsureAsgnRef") - appf(p.s[cpsStmts], "unsureAsgnRef((void**) $1, $2);$n", + appcg(p.module, p.s[cpsStmts], "#unsureAsgnRef((void**) $1, $2);$n", [addrLoc(dest), rdLoc(src)]) proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = @@ -224,70 +219,60 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = if not (needToCopy in flags): genRefAssign(p, dest, src, flags) else: - useMagic(p.module, "genericSeqAssign") # BUGFIX - appf(p.s[cpsStmts], "genericSeqAssign($1, $2, $3);$n", + appcg(p, cpsStmts, "#genericSeqAssign($1, $2, $3);$n", [addrLoc(dest), rdLoc(src), genTypeInfo(p.module, dest.t)]) of tyString: if not (needToCopy in flags): genRefAssign(p, dest, src, flags) else: - useMagic(p.module, "copyString") if (dest.s == OnStack) or not (optRefcGC in gGlobalOptions): - appf(p.s[cpsStmts], "$1 = copyString($2);$n", [rdLoc(dest), rdLoc(src)]) + appcg(p, cpsStmts, "$1 = #copyString($2);$n", [rdLoc(dest), rdLoc(src)]) elif dest.s == OnHeap: - useMagic(p.module, "asgnRefNoCycle") - useMagic(p.module, "copyString") # BUGFIX - appf(p.s[cpsStmts], "asgnRefNoCycle((void**) $1, copyString($2));$n", + appcg(p, cpsStmts, "#asgnRefNoCycle((void**) $1, #copyString($2));$n", [addrLoc(dest), rdLoc(src)]) else: - useMagic(p.module, "unsureAsgnRef") - useMagic(p.module, "copyString") # BUGFIX - appf(p.s[cpsStmts], "unsureAsgnRef((void**) $1, copyString($2));$n", + appcg(p, cpsStmts, "#unsureAsgnRef((void**) $1, #copyString($2));$n", [addrLoc(dest), rdLoc(src)]) of tyTuple: if needsComplexAssignment(dest.t): - useMagic(p.module, "genericAssign") - appf(p.s[cpsStmts], "genericAssign((void*)$1, (void*)$2, $3);$n", + appcg(p, cpsStmts, "#genericAssign((void*)$1, (void*)$2, $3);$n", [addrLoc(dest), addrLoc(src), genTypeInfo(p.module, dest.t)]) else: - appf(p.s[cpsStmts], "$1 = $2;$n", [rdLoc(dest), rdLoc(src)]) + appcg(p, cpsStmts, "$1 = $2;$n", [rdLoc(dest), rdLoc(src)]) of tyArray, tyArrayConstr: if needsComplexAssignment(dest.t): - useMagic(p.module, "genericAssign") - appf(p.s[cpsStmts], "genericAssign((void*)$1, (void*)$2, $3);$n", + appcg(p, cpsStmts, "#genericAssign((void*)$1, (void*)$2, $3);$n", [addrLoc(dest), addrLoc(src), genTypeInfo(p.module, dest.t)]) else: - appf(p.s[cpsStmts], + appcg(p, cpsStmts, "memcpy((void*)$1, (NIM_CONST void*)$2, sizeof($1));$n", [rdLoc(dest), rdLoc(src)]) of tyObject: # XXX: check for subtyping? if needsComplexAssignment(dest.t): - useMagic(p.module, "genericAssign") - appf(p.s[cpsStmts], "genericAssign((void*)$1, (void*)$2, $3);$n", + appcg(p, cpsStmts, "#genericAssign((void*)$1, (void*)$2, $3);$n", [addrLoc(dest), addrLoc(src), genTypeInfo(p.module, dest.t)]) else: - appf(p.s[cpsStmts], "$1 = $2;$n", [rdLoc(dest), rdLoc(src)]) + appcg(p, cpsStmts, "$1 = $2;$n", [rdLoc(dest), rdLoc(src)]) of tyOpenArray: # open arrays are always on the stack - really? What if a sequence is # passed to an open array? if needsComplexAssignment(dest.t): - useMagic(p.module, "genericAssignOpenArray") - appf(p.s[cpsStmts], # XXX: is this correct for arrays? + appcg(p, cpsStmts, # XXX: is this correct for arrays? "genericAssignOpenArray((void*)$1, (void*)$2, $1Len0, $3);$n", [addrLoc(dest), addrLoc(src), genTypeInfo(p.module, dest.t)]) else: - appf(p.s[cpsStmts], + appcg(p, cpsStmts, "memcpy((void*)$1, (NIM_CONST void*)$2, sizeof($1[0])*$1Len0);$n", [rdLoc(dest), rdLoc(src)]) of tySet: if mapType(ty) == ctArray: - appf(p.s[cpsStmts], "memcpy((void*)$1, (NIM_CONST void*)$2, $3);$n", + appcg(p, cpsStmts, "memcpy((void*)$1, (NIM_CONST void*)$2, $3);$n", [rdLoc(dest), rdLoc(src), toRope(getSize(dest.t))]) else: - appf(p.s[cpsStmts], "$1 = $2;$n", [rdLoc(dest), rdLoc(src)]) + appcg(p, cpsStmts, "$1 = $2;$n", [rdLoc(dest), rdLoc(src)]) of tyPtr, tyPointer, tyChar, tyBool, tyProc, tyEnum, tyCString, tyInt..tyFloat128, tyRange: - appf(p.s[cpsStmts], "$1 = $2;$n", [rdLoc(dest), rdLoc(src)]) + appcg(p, cpsStmts, "$1 = $2;$n", [rdLoc(dest), rdLoc(src)]) else: InternalError("genAssignment(" & $ty.kind & ')') proc expr(p: BProc, e: PNode, d: var TLoc) @@ -303,7 +288,7 @@ proc putLocIntoDest(p: BProc, d: var TLoc, s: TLoc) = if lfNoDeepCopy in d.flags: genAssignment(p, d, s, {}) else: genAssignment(p, d, s, {needToCopy}) else: - d = s # ``d`` is free, so fill it with ``s`` + d = s # ``d`` is free, so fill it with ``s`` proc putIntoDest(p: BProc, d: var TLoc, t: PType, r: PRope) = var a: TLoc @@ -319,60 +304,53 @@ proc putIntoDest(p: BProc, d: var TLoc, t: PType, r: PRope) = d.k = locExpr d.t = getUniqueType(t) d.r = r - d.a = - 1 + d.a = -1 -proc binaryStmt(p: BProc, e: PNode, d: var TLoc, magic, frmt: string) = +proc binaryStmt(p: BProc, e: PNode, d: var TLoc, frmt: string) = var a, b: TLoc - if (d.k != locNone): InternalError(e.info, "binaryStmt") - if magic != "": useMagic(p.module, magic) + if d.k != locNone: InternalError(e.info, "binaryStmt") InitLocExpr(p, e.sons[1], a) InitLocExpr(p, e.sons[2], b) - appf(p.s[cpsStmts], frmt, [rdLoc(a), rdLoc(b)]) + appcg(p, cpsStmts, frmt, [rdLoc(a), rdLoc(b)]) -proc unaryStmt(p: BProc, e: PNode, d: var TLoc, magic, frmt: string) = +proc unaryStmt(p: BProc, e: PNode, d: var TLoc, frmt: string) = var a: TLoc if (d.k != locNone): InternalError(e.info, "unaryStmt") - if magic != "": useMagic(p.module, magic) InitLocExpr(p, e.sons[1], a) - appf(p.s[cpsStmts], frmt, [rdLoc(a)]) + appcg(p, cpsStmts, frmt, [rdLoc(a)]) -proc binaryStmtChar(p: BProc, e: PNode, d: var TLoc, magic, frmt: string) = +proc binaryStmtChar(p: BProc, e: PNode, d: var TLoc, frmt: string) = var a, b: TLoc if (d.k != locNone): InternalError(e.info, "binaryStmtChar") - if magic != "": useMagic(p.module, magic) InitLocExpr(p, e.sons[1], a) InitLocExpr(p, e.sons[2], b) - appf(p.s[cpsStmts], frmt, [rdCharLoc(a), rdCharLoc(b)]) + appcg(p, cpsStmts, frmt, [rdCharLoc(a), rdCharLoc(b)]) -proc binaryExpr(p: BProc, e: PNode, d: var TLoc, magic, frmt: string) = +proc binaryExpr(p: BProc, e: PNode, d: var TLoc, frmt: string) = var a, b: TLoc - if magic != "": useMagic(p.module, magic) assert(e.sons[1].typ != nil) assert(e.sons[2].typ != nil) InitLocExpr(p, e.sons[1], a) InitLocExpr(p, e.sons[2], b) - putIntoDest(p, d, e.typ, ropef(frmt, [rdLoc(a), rdLoc(b)])) + putIntoDest(p, d, e.typ, ropecg(p.module, frmt, [rdLoc(a), rdLoc(b)])) -proc binaryExprChar(p: BProc, e: PNode, d: var TLoc, magic, frmt: string) = +proc binaryExprChar(p: BProc, e: PNode, d: var TLoc, frmt: string) = var a, b: TLoc - if magic != "": useMagic(p.module, magic) assert(e.sons[1].typ != nil) assert(e.sons[2].typ != nil) InitLocExpr(p, e.sons[1], a) InitLocExpr(p, e.sons[2], b) - putIntoDest(p, d, e.typ, ropef(frmt, [rdCharLoc(a), rdCharLoc(b)])) + putIntoDest(p, d, e.typ, ropecg(p.module, frmt, [rdCharLoc(a), rdCharLoc(b)])) -proc unaryExpr(p: BProc, e: PNode, d: var TLoc, magic, frmt: string) = +proc unaryExpr(p: BProc, e: PNode, d: var TLoc, frmt: string) = var a: TLoc - if magic != "": useMagic(p.module, magic) InitLocExpr(p, e.sons[1], a) - putIntoDest(p, d, e.typ, ropef(frmt, [rdLoc(a)])) + putIntoDest(p, d, e.typ, ropecg(p.module, frmt, [rdLoc(a)])) -proc unaryExprChar(p: BProc, e: PNode, d: var TLoc, magic, frmt: string) = +proc unaryExprChar(p: BProc, e: PNode, d: var TLoc, frmt: string) = var a: TLoc - if magic != "": useMagic(p.module, magic) InitLocExpr(p, e.sons[1], a) - putIntoDest(p, d, e.typ, ropef(frmt, [rdCharLoc(a)])) + putIntoDest(p, d, e.typ, ropecg(p.module, frmt, [rdCharLoc(a)])) proc binaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) = const @@ -389,22 +367,19 @@ proc binaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) = var t = skipTypes(e.typ, abstractRange) if getSize(t) >= platform.IntSize: if optOverflowCheck in p.options: - useMagic(p.module, prc[m]) - putIntoDest(p, d, e.typ, - ropef("$1($2, $3)", [toRope(prc[m]), rdLoc(a), rdLoc(b)])) + putIntoDest(p, d, e.typ, ropecg(p.module, + "#$1($2, $3)", [toRope(prc[m]), rdLoc(a), rdLoc(b)])) else: putIntoDest(p, d, e.typ, ropef("(NI$4)($2 $1 $3)", [toRope(opr[m]), rdLoc(a), rdLoc(b), toRope(getSize(t) * 8)])) else: if optOverflowCheck in p.options: - useMagic(p.module, "raiseOverflow") if (m == mModI) or (m == mDivI): - useMagic(p.module, "raiseDivByZero") - appf(p.s[cpsStmts], "if (!$1) raiseDivByZero();$n", [rdLoc(b)]) + appcg(p, cpsStmts, "if (!$1) #raiseDivByZero();$n", [rdLoc(b)]) a.r = ropef("((NI)($2) $1 (NI)($3))", [toRope(opr[m]), rdLoc(a), rdLoc(b)]) if d.k == locNone: getTemp(p, getSysType(tyInt), d) genAssignment(p, d, a, {}) - appf(p.s[cpsStmts], "if ($1 < $2 || $1 > $3) raiseOverflow();$n", + appcg(p, cpsStmts, "if ($1 < $2 || $1 > $3) #raiseOverflow();$n", [rdLoc(d), intLiteral(firstOrd(t)), intLiteral(lastOrd(t))]) d.t = e.typ d.r = ropef("(NI$1)($2)", [toRope(getSize(t) * 8), rdLoc(d)]) @@ -425,8 +400,7 @@ proc unaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) = InitLocExpr(p, e.sons[1], a) t = skipTypes(e.typ, abstractRange) if optOverflowCheck in p.options: - useMagic(p.module, "raiseOverflow") - appf(p.s[cpsStmts], "if ($1 == $2) raiseOverflow();$n", + appcg(p, cpsStmts, "if ($1 == $2) #raiseOverflow();$n", [rdLoc(a), intLiteral(firstOrd(t))]) putIntoDest(p, d, e.typ, ropef(opr[m], [rdLoc(a), toRope(getSize(t) * 8)])) @@ -623,8 +597,6 @@ proc genCheckedRecordField(p: BProc, e: PNode, d: var TLoc) = id: int it: PNode if optFieldCheck in p.options: - useMagic(p.module, "raiseFieldError") - useMagic(p.module, "NimStringDesc") ty = genRecordFieldAux(p, e.sons[0], d, a) r = rdLoc(a) f = e.sons[0].sons[1].sym @@ -655,12 +627,12 @@ proc genCheckedRecordField(p: BProc, e: PNode, d: var TLoc) = if id == gid: strLit = getStrLit(p.module, field.name.s) else: strLit = con("TMP", toRope(id)) if op.magic == mNot: - appf(p.s[cpsStmts], - "if ($1) raiseFieldError(((NimStringDesc*) &$2));$n", + appcg(p, cpsStmts, + "if ($1) #raiseFieldError(((#NimStringDesc*) &$2));$n", [rdLoc(test), strLit]) else: - appf(p.s[cpsStmts], - "if (!($1)) raiseFieldError(((NimStringDesc*) &$2));$n", + appcg(p, cpsStmts, + "if (!($1)) #raiseFieldError(((#NimStringDesc*) &$2));$n", [rdLoc(test), strLit]) appf(r, ".$1", [field.loc.r]) putIntoDest(p, d, field.typ, r) @@ -677,13 +649,12 @@ proc genArrayElem(p: BProc, e: PNode, d: var TLoc) = if (optBoundsCheck in p.options): if not isConstExpr(e.sons[1]): # semantic pass has already checked for const index expressions - useMagic(p.module, "raiseIndexError") if firstOrd(ty) == 0: if (firstOrd(b.t) < firstOrd(ty)) or (lastOrd(b.t) > lastOrd(ty)): - appf(p.s[cpsStmts], "if ((NU)($1) > (NU)($2)) raiseIndexError();$n", + appcg(p, cpsStmts, "if ((NU)($1) > (NU)($2)) #raiseIndexError();$n", [rdCharLoc(b), intLiteral(lastOrd(ty))]) else: - appf(p.s[cpsStmts], "if ($1 < $2 || $1 > $3) raiseIndexError();$n", + appcg(p, cpsStmts, "if ($1 < $2 || $1 > $3) #raiseIndexError();$n", [rdCharLoc(b), first, intLiteral(lastOrd(ty))]) if d.k == locNone: d.s = a.s putIntoDest(p, d, elemType(skipTypes(ty, abstractVar)), @@ -703,8 +674,7 @@ proc genOpenArrayElem(p: BProc, e: PNode, d: var TLoc) = initLocExpr(p, e.sons[0], a) initLocExpr(p, e.sons[1], b) # emit range check: if (optBoundsCheck in p.options): - useMagic(p.module, "raiseIndexError") - appf(p.s[cpsStmts], "if ((NU)($1) >= (NU)($2Len0)) raiseIndexError();$n", + appcg(p, cpsStmts, "if ((NU)($1) >= (NU)($2Len0)) #raiseIndexError();$n", [rdLoc(b), rdLoc(a)]) # BUGFIX: ``>=`` and not ``>``! if d.k == locNone: d.s = a.s putIntoDest(p, d, elemType(skipTypes(a.t, abstractVar)), @@ -718,14 +688,13 @@ proc genSeqElem(p: BPRoc, e: PNode, d: var TLoc) = if ty.kind in {tyRef, tyPtr}: ty = skipTypes(ty.sons[0], abstractVarRange) # emit range check: if (optBoundsCheck in p.options): - useMagic(p.module, "raiseIndexError") if ty.kind == tyString: - appf(p.s[cpsStmts], - "if ((NU)($1) > (NU)($2->Sup.len)) raiseIndexError();$n", + appcg(p, cpsStmts, + "if ((NU)($1) > (NU)($2->Sup.len)) #raiseIndexError();$n", [rdLoc(b), rdLoc(a)]) else: - appf(p.s[cpsStmts], - "if ((NU)($1) >= (NU)($2->Sup.len)) raiseIndexError();$n", + appcg(p, cpsStmts, + "if ((NU)($1) >= (NU)($2->Sup.len)) #raiseIndexError();$n", [rdLoc(b), rdLoc(a)]) if d.k == locNone: d.s = OnHeap if skipTypes(a.t, abstractVar).kind in {tyRef, tyPtr}: @@ -811,12 +780,10 @@ proc genIfExpr(p: BProc, n: PNode, d: var TLoc) = proc genEcho(p: BProc, n: PNode) = var a: TLoc - useMagic(p.module, "rawEcho") - useMagic(p.module, "rawEchoNL") for i in countup(1, sonsLen(n) - 1): initLocExpr(p, n.sons[i], a) - appf(p.s[cpsStmts], "rawEcho($1);$n", [rdLoc(a)]) - app(p.s[cpsStmts], "rawEchoNL();" & tnl) + appcg(p, cpsStmts, "#rawEcho($1);$n", [rdLoc(a)]) + appcg(p, cpsStmts, "#rawEchoNL();$n") proc genCall(p: BProc, t: PNode, d: var TLoc) = var @@ -879,7 +846,6 @@ proc genStrConcat(p: BProc, e: PNode, d: var TLoc) = # asgn(s, tmp0); # } var a, tmp: TLoc - useMagic(p.module, "rawNewString") getTemp(p, e.typ, tmp) var L = 0 var appends: PRope = nil @@ -889,16 +855,14 @@ proc genStrConcat(p: BProc, e: PNode, d: var TLoc) = initLocExpr(p, e.sons[i + 1], a) if skipTypes(e.sons[i + 1].Typ, abstractVarRange).kind == tyChar: Inc(L) - useMagic(p.module, "appendChar") - appf(appends, "appendChar($1, $2);$n", [tmp.r, rdLoc(a)]) + appcg(p.module, appends, "#appendChar($1, $2);$n", [tmp.r, rdLoc(a)]) else: if e.sons[i + 1].kind in {nkStrLit..nkTripleStrLit}: Inc(L, len(e.sons[i + 1].strVal)) else: appf(lens, "$1->Sup.len + ", [rdLoc(a)]) - useMagic(p.module, "appendString") - appf(appends, "appendString($1, $2);$n", [tmp.r, rdLoc(a)]) - appf(p.s[cpsStmts], "$1 = rawNewString($2$3);$n", [tmp.r, lens, toRope(L)]) + appcg(p.module, appends, "#appendString($1, $2);$n", [tmp.r, rdLoc(a)]) + appcg(p, cpsStmts, "$1 = #rawNewString($2$3);$n", [tmp.r, lens, toRope(L)]) app(p.s[cpsStmts], appends) if d.k == locNone: d = tmp @@ -922,7 +886,6 @@ proc genStrAppend(p: BProc, e: PNode, d: var TLoc) = L: int appends, lens: PRope assert(d.k == locNone) - useMagic(p.module, "resizeString") L = 0 appends = nil lens = nil @@ -932,16 +895,16 @@ proc genStrAppend(p: BProc, e: PNode, d: var TLoc) = initLocExpr(p, e.sons[i + 2], a) if skipTypes(e.sons[i + 2].Typ, abstractVarRange).kind == tyChar: Inc(L) - useMagic(p.module, "appendChar") - appf(appends, "appendChar($1, $2);$n", [rdLoc(dest), rdLoc(a)]) + appcg(p.module, appends, "#appendChar($1, $2);$n", + [rdLoc(dest), rdLoc(a)]) else: if e.sons[i + 2].kind in {nkStrLit..nkTripleStrLit}: Inc(L, len(e.sons[i + 2].strVal)) else: appf(lens, "$1->Sup.len + ", [rdLoc(a)]) - useMagic(p.module, "appendString") - appf(appends, "appendString($1, $2);$n", [rdLoc(dest), rdLoc(a)]) - appf(p.s[cpsStmts], "$1 = resizeString($1, $2$3);$n", + appcg(p.module, appends, "#appendString($1, $2);$n", + [rdLoc(dest), rdLoc(a)]) + appcg(p, cpsStmts, "$1 = #resizeString($1, $2$3);$n", [rdLoc(dest), lens, toRope(L)]) app(p.s[cpsStmts], appends) @@ -950,10 +913,10 @@ proc genSeqElemAppend(p: BProc, e: PNode, d: var TLoc) = # seq = (typeof seq) incrSeq(&seq->Sup, sizeof(x)); # seq->data[seq->len-1] = x; var a, b, dest: TLoc - useMagic(p.module, "incrSeq") InitLocExpr(p, e.sons[1], a) InitLocExpr(p, e.sons[2], b) - appf(p.s[cpsStmts], "$1 = ($2) incrSeq(&($1)->Sup, sizeof($3));$n", [rdLoc(a), + appcg(p, cpsStmts, "$1 = ($2) #incrSeq(&($1)->Sup, sizeof($3));$n", [ + rdLoc(a), getTypeDesc(p.module, skipTypes(e.sons[1].typ, abstractVar)), getTypeDesc(p.module, skipTypes(e.sons[2].Typ, abstractVar))]) initLoc(dest, locExpr, b.t, OnHeap) @@ -977,20 +940,19 @@ proc genObjectInit(p: BProc, t: PType, a: TLoc, takeAddr: bool) = appf(p.s[cpsStmts], "$1.m_type = $2;$n", [r, genTypeInfo(p.module, t)]) of frEmbedded: # worst case for performance: - useMagic(p.module, "objectInit") if takeAddr: r = addrLoc(a) else: r = rdLoc(a) - appf(p.s[cpsStmts], "objectInit($1, $2);$n", [r, genTypeInfo(p.module, t)]) + appcg(p, cpsStmts, "#objectInit($1, $2);$n", [r, genTypeInfo(p.module, t)]) proc genNew(p: BProc, e: PNode) = var a, b: TLoc reftype, bt: PType - useMagic(p.module, "newObj") refType = skipTypes(e.sons[1].typ, abstractVarRange) InitLocExpr(p, e.sons[1], a) initLoc(b, locExpr, a.t, OnHeap) - b.r = ropef("($1) newObj($2, sizeof($3))", [getTypeDesc(p.module, reftype), + b.r = ropecg(p.module, + "($1) #newObj($2, sizeof($3))", [getTypeDesc(p.module, reftype), genTypeInfo(p.module, refType), getTypeDesc(p.module, skipTypes(reftype.sons[0], abstractRange))]) genAssignment(p, a, b, {}) # set the object type: @@ -1001,13 +963,13 @@ proc genNewSeq(p: BProc, e: PNode) = var a, b, c: TLoc seqtype: PType - useMagic(p.module, "newSeq") seqType = skipTypes(e.sons[1].typ, abstractVarRange) InitLocExpr(p, e.sons[1], a) InitLocExpr(p, e.sons[2], b) initLoc(c, locExpr, a.t, OnHeap) - c.r = ropef("($1) newSeq($2, $3)", [getTypeDesc(p.module, seqtype), - genTypeInfo(p.module, seqType), rdLoc(b)]) + c.r = ropecg(p.module, "($1) #newSeq($2, $3)", [ + getTypeDesc(p.module, seqtype), + genTypeInfo(p.module, seqType), rdLoc(b)]) genAssignment(p, a, c, {}) proc genIs(p: BProc, x: PNode, typ: PType, d: var TLoc) = @@ -1017,7 +979,6 @@ proc genIs(p: BProc, x: PNode, typ: PType, d: var TLoc) = r, nilcheck: PRope initLocExpr(p, x, a) dest = skipTypes(typ, abstractPtrs) - useMagic(p.module, "isObj") r = rdLoc(a) nilCheck = nil t = skipTypes(a.t, abstractInst) @@ -1030,10 +991,10 @@ proc genIs(p: BProc, x: PNode, typ: PType, d: var TLoc) = app(r, ".Sup") t = skipTypes(t.sons[0], abstractInst) if nilCheck != nil: - r = ropef("(($1) && isObj($2.m_type, $3))", + r = ropecg(p.module, "(($1) && #isObj($2.m_type, $3))", [nilCheck, r, genTypeInfo(p.module, dest)]) else: - r = ropef("isObj($1.m_type, $2)", [r, genTypeInfo(p.module, dest)]) + r = ropecg(p.module, "#isObj($1.m_type, $2)", [r, genTypeInfo(p.module, dest)]) putIntoDest(p, d, getSysType(tyBool), r) proc genIs(p: BProc, n: PNode, d: var TLoc) = @@ -1045,7 +1006,6 @@ proc genNewFinalize(p: BProc, e: PNode) = refType, bt: PType ti: PRope oldModule: BModule - useMagic(p.module, "newObj") refType = skipTypes(e.sons[1].typ, abstractVarRange) InitLocExpr(p, e.sons[1], a) # This is a little hack: @@ -1057,7 +1017,8 @@ proc genNewFinalize(p: BProc, e: PNode) = initLoc(b, locExpr, a.t, OnHeap) ti = genTypeInfo(p.module, refType) appf(gNimDat.s[cfsTypeInit3], "$1->finalizer = (void*)$2;$n", [ti, rdLoc(f)]) - b.r = ropef("($1) newObj($2, sizeof($3))", [getTypeDesc(p.module, refType), + b.r = ropecg(p.module, "($1) #newObj($2, sizeof($3))", [ + getTypeDesc(p.module, refType), ti, getTypeDesc(p.module, skipTypes(reftype.sons[0], abstractRange))]) genAssignment(p, a, b, {}) # set the object type: bt = skipTypes(refType.sons[0], abstractRange) @@ -1069,30 +1030,23 @@ proc genRepr(p: BProc, e: PNode, d: var TLoc) = var t = skipTypes(e.sons[1].typ, abstractVarRange) case t.kind of tyInt..tyInt64: - UseMagic(p.module, "reprInt") - putIntoDest(p, d, e.typ, ropef("reprInt($1)", [rdLoc(a)])) + putIntoDest(p, d, e.typ, ropecg(p.module, "#reprInt($1)", [rdLoc(a)])) of tyFloat..tyFloat128: - UseMagic(p.module, "reprFloat") - putIntoDest(p, d, e.typ, ropef("reprFloat($1)", [rdLoc(a)])) + putIntoDest(p, d, e.typ, ropecg(p.module, "#reprFloat($1)", [rdLoc(a)])) of tyBool: - UseMagic(p.module, "reprBool") - putIntoDest(p, d, e.typ, ropef("reprBool($1)", [rdLoc(a)])) + putIntoDest(p, d, e.typ, ropecg(p.module, "#reprBool($1)", [rdLoc(a)])) of tyChar: - UseMagic(p.module, "reprChar") - putIntoDest(p, d, e.typ, ropef("reprChar($1)", [rdLoc(a)])) + putIntoDest(p, d, e.typ, ropecg(p.module, "#reprChar($1)", [rdLoc(a)])) of tyEnum, tyOrdinal: - UseMagic(p.module, "reprEnum") putIntoDest(p, d, e.typ, - ropef("reprEnum($1, $2)", [rdLoc(a), genTypeInfo(p.module, t)])) + ropecg(p.module, "#reprEnum($1, $2)", [ + rdLoc(a), genTypeInfo(p.module, t)])) of tyString: - UseMagic(p.module, "reprStr") - putIntoDest(p, d, e.typ, ropef("reprStr($1)", [rdLoc(a)])) + putIntoDest(p, d, e.typ, ropecg(p.module, "#reprStr($1)", [rdLoc(a)])) of tySet: - useMagic(p.module, "reprSet") - putIntoDest(p, d, e.typ, - ropef("reprSet($1, $2)", [rdLoc(a), genTypeInfo(p.module, t)])) + putIntoDest(p, d, e.typ, ropecg(p.module, "#reprSet($1, $2)", [ + rdLoc(a), genTypeInfo(p.module, t)])) of tyOpenArray: - useMagic(p.module, "reprOpenArray") var b: TLoc case a.t.kind of tyOpenArray: putIntoDest(p, b, e.typ, rdLoc(a)) @@ -1102,23 +1056,22 @@ proc genRepr(p: BProc, e: PNode, d: var TLoc) = putIntoDest(p, b, e.typ, ropef("$1, $2", [rdLoc(a), toRope(lengthOrd(a.t))])) else: InternalError(e.sons[0].info, "genRepr()") - putIntoDest(p, d, e.typ, ropef("reprOpenArray($1, $2)", [rdLoc(b), + putIntoDest(p, d, e.typ, + ropecg(p.module, "#reprOpenArray($1, $2)", [rdLoc(b), genTypeInfo(p.module, elemType(t))])) of tyCString, tyArray, tyArrayConstr, tyRef, tyPtr, tyPointer, tyNil, tySequence: - useMagic(p.module, "reprAny") putIntoDest(p, d, e.typ, - ropef("reprAny($1, $2)", [rdLoc(a), genTypeInfo(p.module, t)])) + ropecg(p.module, "#reprAny($1, $2)", [ + rdLoc(a), genTypeInfo(p.module, t)])) else: - useMagic(p.module, "reprAny") - putIntoDest(p, d, e.typ, ropef("reprAny($1, $2)", + putIntoDest(p, d, e.typ, ropecg(p.module, "#reprAny($1, $2)", [addrLoc(a), genTypeInfo(p.module, t)])) -proc genDollar(p: BProc, n: PNode, d: var TLoc, magic, frmt: string) = +proc genDollar(p: BProc, n: PNode, d: var TLoc, frmt: string) = var a: TLoc InitLocExpr(p, n.sons[1], a) - UseMagic(p.module, magic) - a.r = ropef(frmt, [rdLoc(a)]) + a.r = ropecg(p.module, frmt, [rdLoc(a)]) if d.k == locNone: getTemp(p, n.typ, d) genAssignment(p, d, a, {}) @@ -1127,14 +1080,14 @@ proc genArrayLen(p: BProc, e: PNode, d: var TLoc, op: TMagic) = case typ.kind of tyOpenArray: while e.sons[1].kind == nkPassAsOpenArray: e.sons[1] = e.sons[1].sons[0] - if op == mHigh: unaryExpr(p, e, d, "", "($1Len0-1)") - else: unaryExpr(p, e, d, "", "$1Len0") + if op == mHigh: unaryExpr(p, e, d, "($1Len0-1)") + else: unaryExpr(p, e, d, "$1Len0") of tyCstring: - if op == mHigh: unaryExpr(p, e, d, "", "(strlen($1)-1)") - else: unaryExpr(p, e, d, "", "strlen($1)") + if op == mHigh: unaryExpr(p, e, d, "(strlen($1)-1)") + else: unaryExpr(p, e, d, "strlen($1)") of tyString, tySequence: - if op == mHigh: unaryExpr(p, e, d, "", "($1->Sup.len-1)") - else: unaryExpr(p, e, d, "", "$1->Sup.len") + if op == mHigh: unaryExpr(p, e, d, "($1->Sup.len-1)") + else: unaryExpr(p, e, d, "$1->Sup.len") of tyArray, tyArrayConstr: # YYY: length(sideeffect) is optimized away incorrectly? if op == mHigh: putIntoDest(p, d, e.typ, toRope(lastOrd(Typ))) @@ -1144,16 +1097,15 @@ proc genArrayLen(p: BProc, e: PNode, d: var TLoc, op: TMagic) = proc genSetLengthSeq(p: BProc, e: PNode, d: var TLoc) = var a, b: TLoc assert(d.k == locNone) - useMagic(p.module, "setLengthSeq") InitLocExpr(p, e.sons[1], a) InitLocExpr(p, e.sons[2], b) var t = skipTypes(e.sons[1].typ, abstractVar) - appf(p.s[cpsStmts], "$1 = ($3) setLengthSeq(&($1)->Sup, sizeof($4), $2);$n", [ + appcg(p, cpsStmts, "$1 = ($3) #setLengthSeq(&($1)->Sup, sizeof($4), $2);$n", [ rdLoc(a), rdLoc(b), getTypeDesc(p.module, t), getTypeDesc(p.module, t.sons[0])]) proc genSetLengthStr(p: BProc, e: PNode, d: var TLoc) = - binaryStmt(p, e, d, "setLengthStr", "$1 = setLengthStr($1, $2);$n") + binaryStmt(p, e, d, "$1 = #setLengthStr($1, $2);$n") proc genSwap(p: BProc, e: PNode, d: var TLoc) = # swap(a, b) --> @@ -1257,15 +1209,15 @@ proc genSetOp(p: BProc, e: PNode, d: var TLoc, op: TMagic) = binaryStmtInExcl(p, e, d, "$1 &= ~(1 << ((" & ts & ")($2) % (sizeof(" & ts & ")*8)));$n") of mCard: - if size <= 4: unaryExprChar(p, e, d, "countBits32", "countBits32($1)") - else: unaryExprChar(p, e, d, "countBits64", "countBits64($1)") - of mLtSet: binaryExprChar(p, e, d, "", "(($1 & ~ $2 ==0)&&($1 != $2))") - of mLeSet: binaryExprChar(p, e, d, "", "(($1 & ~ $2)==0)") - of mEqSet: binaryExpr(p, e, d, "", "($1 == $2)") - of mMulSet: binaryExpr(p, e, d, "", "($1 & $2)") - of mPlusSet: binaryExpr(p, e, d, "", "($1 | $2)") - of mMinusSet: binaryExpr(p, e, d, "", "($1 & ~ $2)") - of mSymDiffSet: binaryExpr(p, e, d, "", "($1 ^ $2)") + if size <= 4: unaryExprChar(p, e, d, "#countBits32($1)") + else: unaryExprChar(p, e, d, "#countBits64($1)") + of mLtSet: binaryExprChar(p, e, d, "(($1 & ~ $2 ==0)&&($1 != $2))") + of mLeSet: binaryExprChar(p, e, d, "(($1 & ~ $2)==0)") + of mEqSet: binaryExpr(p, e, d, "($1 == $2)") + of mMulSet: binaryExpr(p, e, d, "($1 & $2)") + of mPlusSet: binaryExpr(p, e, d, "($1 | $2)") + of mMinusSet: binaryExpr(p, e, d, "($1 & ~ $2)") + of mSymDiffSet: binaryExpr(p, e, d, "($1 ^ $2)") of mInSet: genInOp(p, e, d) else: internalError(e.info, "genSetOp()") @@ -1273,7 +1225,7 @@ proc genSetOp(p: BProc, e: PNode, d: var TLoc, op: TMagic) = case op of mIncl: binaryStmtInExcl(p, e, d, "$1[$2/8] |=(1<<($2%8));$n") of mExcl: binaryStmtInExcl(p, e, d, "$1[$2/8] &= ~(1<<($2%8));$n") - of mCard: unaryExprChar(p, e, d, "cardSet", "cardSet($1, " & $size & ')') + of mCard: unaryExprChar(p, e, d, "#cardSet($1, " & $size & ')') of mLtSet, mLeSet: getTemp(p, getSysType(tyInt), i) # our counter initLocExpr(p, e.sons[1], a) @@ -1282,7 +1234,7 @@ proc genSetOp(p: BProc, e: PNode, d: var TLoc, op: TMagic) = appf(p.s[cpsStmts], lookupOpr[op], [rdLoc(i), toRope(size), rdLoc(d), rdLoc(a), rdLoc(b)]) of mEqSet: - binaryExprChar(p, e, d, "", "(memcmp($1, $2, " & $(size) & ")==0)") + binaryExprChar(p, e, d, "(memcmp($1, $2, " & $(size) & ")==0)") of mMulSet, mPlusSet, mMinusSet, mSymDiffSet: # we inline the simple for loop for better code generation: getTemp(p, getSysType(tyInt), i) # our counter @@ -1297,7 +1249,7 @@ proc genSetOp(p: BProc, e: PNode, d: var TLoc, op: TMagic) = else: internalError(e.info, "genSetOp") proc genOrd(p: BProc, e: PNode, d: var TLoc) = - unaryExprChar(p, e, d, "", "$1") + unaryExprChar(p, e, d, "$1") proc genCast(p: BProc, e: PNode, d: var TLoc) = const @@ -1317,14 +1269,13 @@ proc genCast(p: BProc, e: PNode, d: var TLoc) = proc genRangeChck(p: BProc, n: PNode, d: var TLoc, magic: string) = var a: TLoc var dest = skipTypes(n.typ, abstractVar) - if not (optRangeCheck in p.options): + if optRangeCheck notin p.options: InitLocExpr(p, n.sons[0], a) putIntoDest(p, d, n.typ, ropef("(($1) ($2))", [getTypeDesc(p.module, dest), rdCharLoc(a)])) else: InitLocExpr(p, n.sons[0], a) - useMagic(p.module, magic) - putIntoDest(p, d, dest, ropef("(($1)$5($2, $3, $4))", [ + putIntoDest(p, d, dest, ropecg(p.module, "(($1)#$5($2, $3, $4))", [ getTypeDesc(p.module, dest), rdCharLoc(a), genLiteral(p, n.sons[1], dest), genLiteral(p, n.sons[2], dest), toRope(magic)])) @@ -1356,17 +1307,16 @@ proc convStrToCStr(p: BProc, n: PNode, d: var TLoc) = proc convCStrToStr(p: BProc, n: PNode, d: var TLoc) = var a: TLoc - useMagic(p.module, "cstrToNimstr") initLocExpr(p, n.sons[0], a) putIntoDest(p, d, skipTypes(n.typ, abstractVar), - ropef("cstrToNimstr($1)", [rdLoc(a)])) + ropecg(p.module, "#cstrToNimstr($1)", [rdLoc(a)])) proc genStrEquals(p: BProc, e: PNode, d: var TLoc) = var x: TLoc var a = e.sons[1] var b = e.sons[2] if (a.kind == nkNilLit) or (b.kind == nkNilLit): - binaryExpr(p, e, d, "", "($1 == $2)") + binaryExpr(p, e, d, "($1 == $2)") elif (a.kind in {nkStrLit..nkTripleStrLit}) and (a.strVal == ""): initLocExpr(p, e.sons[2], x) putIntoDest(p, d, e.typ, ropef("(($1) && ($1)->Sup.len == 0)", [rdLoc(x)])) @@ -1374,16 +1324,16 @@ proc genStrEquals(p: BProc, e: PNode, d: var TLoc) = initLocExpr(p, e.sons[1], x) putIntoDest(p, d, e.typ, ropef("(($1) && ($1)->Sup.len == 0)", [rdLoc(x)])) else: - binaryExpr(p, e, d, "eqStrings", "eqStrings($1, $2)") + binaryExpr(p, e, d, "#eqStrings($1, $2)") proc genSeqConstr(p: BProc, t: PNode, d: var TLoc) = var newSeq, arr: TLoc - useMagic(p.module, "newSeq") if d.k == locNone: getTemp(p, t.typ, d) # generate call to newSeq before adding the elements per hand: initLoc(newSeq, locExpr, t.typ, OnHeap) - newSeq.r = ropef("($1) newSeq($2, $3)", [getTypeDesc(p.module, t.typ), + newSeq.r = ropecg(p.module, "($1) #newSeq($2, $3)", + [getTypeDesc(p.module, t.typ), genTypeInfo(p.module, t.typ), intLiteral(sonsLen(t))]) genAssignment(p, d, newSeq, {afSrcIsNotNil}) for i in countup(0, sonsLen(t) - 1): @@ -1398,13 +1348,13 @@ proc genArrToSeq(p: BProc, t: PNode, d: var TLoc) = t.sons[1].typ = t.typ genSeqConstr(p, t.sons[1], d) return - useMagic(p.module, "newSeq") if d.k == locNone: getTemp(p, t.typ, d) # generate call to newSeq before adding the elements per hand: var L = int(lengthOrd(t.sons[1].typ)) initLoc(newSeq, locExpr, t.typ, OnHeap) - newSeq.r = ropef("($1) newSeq($2, $3)", [getTypeDesc(p.module, t.typ), + newSeq.r = ropecg(p.module, "($1) #newSeq($2, $3)", + [getTypeDesc(p.module, t.typ), genTypeInfo(p.module, t.typ), intLiteral(L)]) genAssignment(p, d, newSeq, {afSrcIsNotNil}) initLocExpr(p, t.sons[1], a) @@ -1427,11 +1377,9 @@ proc binaryFloatArith(p: BProc, e: PNode, d: var TLoc, m: TMagic) = putIntoDest(p, d, e.typ, ropef("($2 $1 $3)", [ toRope(opr[m]), rdLoc(a), rdLoc(b)])) if optNanCheck in p.options: - useMagic(p.module, "nanCheck") - appf(p.s[cpsStmts], "nanCheck($1);$n", [rdLoc(d)]) + appcg(p, cpsStmts, "#nanCheck($1);$n", [rdLoc(d)]) if optInfCheck in p.options: - useMagic(p.module, "infCheck") - appf(p.s[cpsStmts], "infCheck($1);$n", [rdLoc(d)]) + appcg(p, cpsStmts, "#infCheck($1);$n", [rdLoc(d)]) else: binaryArith(p, e, d, m) @@ -1448,49 +1396,48 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) = of mSwap: genSwap(p, e, d) of mPred: # XXX: range checking? - if not (optOverflowCheck in p.Options): binaryExpr(p, e, d, "", "$1 - $2") - else: binaryExpr(p, e, d, "subInt", "subInt($1, $2)") + if not (optOverflowCheck in p.Options): binaryExpr(p, e, d, "$1 - $2") + else: binaryExpr(p, e, d, "#subInt($1, $2)") of mSucc: # XXX: range checking? - if not (optOverflowCheck in p.Options): binaryExpr(p, e, d, "", "$1 + $2") - else: binaryExpr(p, e, d, "addInt", "addInt($1, $2)") + if not (optOverflowCheck in p.Options): binaryExpr(p, e, d, "$1 + $2") + else: binaryExpr(p, e, d, "#addInt($1, $2)") of mInc: if not (optOverflowCheck in p.Options): - binaryStmt(p, e, d, "", "$1 += $2;$n") + binaryStmt(p, e, d, "$1 += $2;$n") elif skipTypes(e.sons[1].typ, abstractVar).kind == tyInt64: - binaryStmt(p, e, d, "addInt64", "$1 = addInt64($1, $2);$n") + binaryStmt(p, e, d, "$1 = #addInt64($1, $2);$n") else: - binaryStmt(p, e, d, "addInt", "$1 = addInt($1, $2);$n") + binaryStmt(p, e, d, "$1 = #addInt($1, $2);$n") of ast.mDec: if not (optOverflowCheck in p.Options): - binaryStmt(p, e, d, "", "$1 -= $2;$n") + binaryStmt(p, e, d, "$1 -= $2;$n") elif skipTypes(e.sons[1].typ, abstractVar).kind == tyInt64: - binaryStmt(p, e, d, "subInt64", "$1 = subInt64($1, $2);$n") + binaryStmt(p, e, d, "$1 = #subInt64($1, $2);$n") else: - binaryStmt(p, e, d, "subInt", "$1 = subInt($1, $2);$n") + binaryStmt(p, e, d, "$1 = #subInt($1, $2);$n") of mConStrStr: genStrConcat(p, e, d) - of mAppendStrCh: binaryStmt(p, e, d, "addChar", "$1 = addChar($1, $2);$n") + of mAppendStrCh: binaryStmt(p, e, d, "$1 = #addChar($1, $2);$n") of mAppendStrStr: genStrAppend(p, e, d) of mAppendSeqElem: genSeqElemAppend(p, e, d) of mEqStr: genStrEquals(p, e, d) - of mLeStr: binaryExpr(p, e, d, "cmpStrings", "(cmpStrings($1, $2) <= 0)") - of mLtStr: binaryExpr(p, e, d, "cmpStrings", "(cmpStrings($1, $2) < 0)") - of mIsNil: unaryExpr(p, e, d, "", "$1 == 0") - of mIntToStr: genDollar(p, e, d, "nimIntToStr", "nimIntToStr($1)") - of mInt64ToStr: genDollar(p, e, d, "nimInt64ToStr", "nimInt64ToStr($1)") - of mBoolToStr: genDollar(p, e, d, "nimBoolToStr", "nimBoolToStr($1)") - of mCharToStr: genDollar(p, e, d, "nimCharToStr", "nimCharToStr($1)") - of mFloatToStr: genDollar(p, e, d, "nimFloatToStr", "nimFloatToStr($1)") - of mCStrToStr: genDollar(p, e, d, "cstrToNimstr", "cstrToNimstr($1)") + of mLeStr: binaryExpr(p, e, d, "(#cmpStrings($1, $2) <= 0)") + of mLtStr: binaryExpr(p, e, d, "(#cmpStrings($1, $2) < 0)") + of mIsNil: unaryExpr(p, e, d, "$1 == 0") + of mIntToStr: genDollar(p, e, d, "#nimIntToStr($1)") + of mInt64ToStr: genDollar(p, e, d, "#nimInt64ToStr($1)") + of mBoolToStr: genDollar(p, e, d, "#nimBoolToStr($1)") + of mCharToStr: genDollar(p, e, d, "#nimCharToStr($1)") + of mFloatToStr: genDollar(p, e, d, "#nimFloatToStr($1)") + of mCStrToStr: genDollar(p, e, d, "#cstrToNimstr($1)") of mStrToStr: expr(p, e.sons[1], d) of mEnumToStr: genRepr(p, e, d) of mAssert: if (optAssert in p.Options): - useMagic(p.module, "internalAssert") expr(p, e.sons[1], d) line = toRope(toLinenumber(e.info)) filen = makeCString(ToFilename(e.info)) - appf(p.s[cpsStmts], "internalAssert($1, $2, $3);$n", + appcg(p, cpsStmts, "#internalAssert($1, $2, $3);$n", [filen, line, rdLoc(d)]) of mIs: genIs(p, e, d) of mNew: genNew(p, e) @@ -1503,8 +1450,8 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) = of mOrd: genOrd(p, e, d) of mLengthArray, mHigh, mLengthStr, mLengthSeq, mLengthOpenArray: genArrayLen(p, e, d, op) - of mGCref: unaryStmt(p, e, d, "nimGCref", "nimGCref($1);$n") - of mGCunref: unaryStmt(p, e, d, "nimGCunref", "nimGCunref($1);$n") + of mGCref: unaryStmt(p, e, d, "#nimGCref($1);$n") + of mGCunref: unaryStmt(p, e, d, "#nimGCunref($1);$n") of mSetLengthStr: genSetLengthStr(p, e, d) of mSetLengthSeq: genSetLengthSeq(p, e, d) of mIncl, mExcl, mCard, mLtSet, mLeSet, mEqSet, mMulSet, mPlusSet, mMinusSet, @@ -1632,7 +1579,6 @@ proc upConv(p: BProc, n: PNode, d: var TLoc) = initLocExpr(p, n.sons[0], a) dest = skipTypes(n.typ, abstractPtrs) if (optObjCheck in p.options) and not (isPureObject(dest)): - useMagic(p.module, "chckObj") r = rdLoc(a) nilCheck = nil t = skipTypes(a.t, abstractInst) @@ -1645,10 +1591,10 @@ proc upConv(p: BProc, n: PNode, d: var TLoc) = app(r, ".Sup") t = skipTypes(t.sons[0], abstractInst) if nilCheck != nil: - appf(p.s[cpsStmts], "if ($1) chckObj($2.m_type, $3);$n", + appcg(p, cpsStmts, "if ($1) #chckObj($2.m_type, $3);$n", [nilCheck, r, genTypeInfo(p.module, dest)]) else: - appf(p.s[cpsStmts], "chckObj($1.m_type, $2);$n", + appcg(p, cpsStmts, "#chckObj($1.m_type, $2);$n", [r, genTypeInfo(p.module, dest)]) if n.sons[0].typ.kind != tyObject: putIntoDest(p, d, n.typ, diff --git a/rod/ccgstmts.nim b/rod/ccgstmts.nim index 78ef4f24f..9171b5fb8 100755 --- a/rod/ccgstmts.nim +++ b/rod/ccgstmts.nim @@ -1,7 +1,7 @@ # # # The Nimrod Compiler -# (c) Copyright 2009 Andreas Rumpf +# (c) Copyright 2010 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -20,9 +20,7 @@ proc genLineDir(p: BProc, t: PNode) = [toRope(toFilename(t.info)), toRope(line)]) if ({optStackTrace, optEndb} * p.Options == {optStackTrace, optEndb}) and ((p.prc == nil) or not (sfPure in p.prc.flags)): - useMagic(p.module, "endb") # new: endb support - appff(p.s[cpsStmts], "endb($1);$n", "call void @endb(%NI $1)$n", - [toRope(line)]) + appcg(p, cpsStmts, "#endb($1);$n", [toRope(line)]) elif ({optLineTrace, optStackTrace} * p.Options == {optLineTrace, optStackTrace}) and ((p.prc == nil) or not (sfPure in p.prc.flags)): @@ -262,27 +260,24 @@ proc genAsmStmt(p: BProc, t: PNode) = proc getRaiseFrmt(p: BProc): string = if gCmd == cmdCompileToCpp: - result = "throw nimException($1, $2);$n" + result = "throw #nimException($1, $2);$n" else: - useMagic(p.module, "E_Base") - result = "raiseException((E_Base*)$1, $2);$n" + result = "#raiseException((#E_Base*)$1, $2);$n" proc genRaiseStmt(p: BProc, t: PNode) = genLineDir(p, t) if t.sons[0] != nil: - if gCmd != cmdCompileToCpp: useMagic(p.module, "raiseException") var a: TLoc InitLocExpr(p, t.sons[0], a) var e = rdLoc(a) var typ = skipTypes(t.sons[0].typ, abstractPtrs) - appf(p.s[cpsStmts], getRaiseFrmt(p), [e, makeCString(typ.sym.name.s)]) + appcg(p, cpsStmts, getRaiseFrmt(p), [e, makeCString(typ.sym.name.s)]) else: # reraise the last exception: if gCmd == cmdCompileToCpp: - app(p.s[cpsStmts], "throw;" & tnl) + appcg(p, cpsStmts, "throw;" & tnl) else: - useMagic(p.module, "reraiseException") - app(p.s[cpsStmts], "reraiseException();" & tnl) + appcg(p, cpsStmts, "#reraiseException();" & tnl) const stringCaseThreshold = 100000 @@ -300,11 +295,11 @@ proc genCaseGenericBranch(p: BProc, b: PNode, e: TLoc, if b.sons[i].kind == nkRange: initLocExpr(p, b.sons[i].sons[0], x) initLocExpr(p, b.sons[i].sons[1], y) - appf(p.s[cpsStmts], rangeFormat, + appcg(p, cpsStmts, rangeFormat, [rdCharLoc(e), rdCharLoc(x), rdCharLoc(y), labl]) else: initLocExpr(p, b.sons[i], x) - appf(p.s[cpsStmts], eqFormat, [rdCharLoc(e), rdCharLoc(x), labl]) + appcg(p, cpsStmts, eqFormat, [rdCharLoc(e), rdCharLoc(x), labl]) proc genCaseSecondPass(p: BProc, t: PNode, labId: int) = var Lend = getLabel(p) @@ -373,7 +368,7 @@ proc genCaseStringBranch(p: BProc, b: PNode, e: TLoc, labl: TLabel, initLocExpr(p, b.sons[i], x) assert(b.sons[i].kind in {nkStrLit..nkTripleStrLit}) j = int(hashString(b.sons[i].strVal) and high(branches)) - appf(branches[j], "if (eqStrings($1, $2)) goto $3;$n", + appcg(p.module, branches[j], "if (#eqStrings($1, $2)) goto $3;$n", [rdLoc(e), rdLoc(x), labl]) proc genStringCase(p: BProc, t: PNode) = @@ -381,13 +376,11 @@ proc genStringCase(p: BProc, t: PNode) = strings, bitMask, labId: int a: TLoc branches: TRopeSeq - useMagic(p.module, "eqStrings") # count how many constant strings there are in the case: strings = 0 for i in countup(1, sonsLen(t) - 1): if t.sons[i].kind == nkOfBranch: inc(strings, sonsLen(t.sons[i]) - 1) if strings > stringCaseThreshold: - useMagic(p.module, "hashString") bitMask = math.nextPowerOfTwo(strings) - 1 newSeq(branches, bitMask + 1) initLocExpr(p, t.sons[0], a) # fist pass: gnerate ifs+goto: @@ -400,7 +393,7 @@ proc genStringCase(p: BProc, t: PNode) = else: # else statement: nothing to do yet # but we reserved a label, which we use later - appf(p.s[cpsStmts], "switch (hashString($1) & $2) {$n", + appcg(p, cpsStmts, "switch (#hashString($1) & $2) {$n", [rdLoc(a), toRope(bitMask)]) for j in countup(0, high(branches)): if branches[j] != nil: @@ -412,7 +405,7 @@ proc genStringCase(p: BProc, t: PNode) = # third pass: generate statements genCaseSecondPass(p, t, labId) else: - genCaseGeneric(p, t, "", "if (eqStrings($1, $2)) goto $3;$n") + genCaseGeneric(p, t, "", "if (#eqStrings($1, $2)) goto $3;$n") proc branchHasTooBigRange(b: PNode): bool = for i in countup(0, sonsLen(b) - 2): @@ -588,11 +581,9 @@ proc genTryStmt(p: BProc, t: PNode) = # longjmp(excHandler->context, sp.status); genLineDir(p, t) var safePoint = getTempName() - useMagic(p.module, "TSafePoint") - useMagic(p.module, "E_Base") - useMagic(p.module, "excHandler") - appf(p.s[cpsLocals], "TSafePoint $1;$n", [safePoint]) - appf(p.s[cpsStmts], "$1.prev = excHandler;$n" & "excHandler = &$1;$n" & + discard cgsym(p.module, "E_Base") + appcg(p, cpsLocals, "#TSafePoint $1;$n", [safePoint]) + appcg(p, cpsStmts, "$1.prev = #excHandler;$n" & "excHandler = &$1;$n" & "$1.status = setjmp($1.context);$n", [safePoint]) if optStackTrace in p.Options: app(p.s[cpsStmts], "framePtr = (TFrame*)&F;" & tnl) @@ -627,9 +618,8 @@ proc genTryStmt(p: BProc, t: PNode) = dec(p.nestedTryStmts) if (i < length) and (t.sons[i].kind == nkFinally): genStmts(p, t.sons[i].sons[0]) - useMagic(p.module, "raiseException") - appf(p.s[cpsStmts], "if ($1.status != 0) { " & - "raiseException($1.exc, $1.exc->name); }$n", [safePoint]) + appcg(p, cpsStmts, "if ($1.status != 0) { " & + "#raiseException($1.exc, $1.exc->name); }$n", [safePoint]) var breakPointId: int = 0 @@ -643,21 +633,17 @@ proc genBreakPoint(p: BProc, t: PNode) = name = normalize(t.sons[1].strVal) else: inc(breakPointId) - name = "bp" & $(breakPointId) + name = "bp" & $breakPointId genLineDir(p, t) # BUGFIX - appf(gBreakpoints, - "dbgRegisterBreakpoint($1, (NCSTRING)$2, (NCSTRING)$3);$n", [ + appcg(p.module, gBreakpoints, + "#dbgRegisterBreakpoint($1, (NCSTRING)$2, (NCSTRING)$3);$n", [ toRope(toLinenumber(t.info)), makeCString(toFilename(t.info)), makeCString(name)]) proc genPragma(p: BProc, n: PNode) = for i in countup(0, sonsLen(n) - 1): var it = n.sons[i] - var key: PNode - if it.kind == nkExprColonExpr: - key = it.sons[0] - else: - key = it + var key = if it.kind == nkExprColonExpr: it.sons[0] else: it if key.kind == nkIdent: case whichKeyword(key.ident) of wBreakpoint: @@ -667,8 +653,7 @@ proc genPragma(p: BProc, n: PNode) = # we need to keep track of ``deadCodeElim`` pragma if (sfDeadCodeElim in p.module.module.flags): addPendingModule(p.module) - else: - nil + else: nil proc genAsgn(p: BProc, e: PNode) = var a: TLoc diff --git a/rod/ccgtypes.nim b/rod/ccgtypes.nim index 5034bf67b..ca5b3990e 100755 --- a/rod/ccgtypes.nim +++ b/rod/ccgtypes.nim @@ -248,7 +248,7 @@ proc getSimpleTypeDesc(m: BModule, typ: PType): PRope = internalError(typ.sym.info, "getSimpleTypeDesc: " & $(getSize(typ))) result = nil of tyString: - useMagic(m, "NimStringDesc") + discard cgsym(m, "NimStringDesc") result = typeNameOrLiteral(typ, "NimStringDesc*") of tyCstring: result = typeNameOrLiteral(typ, "NCSTRING") of tyBool: result = typeNameOrLiteral(typ, "NIM_BOOL") @@ -342,20 +342,19 @@ proc getRecordDesc(m: BModule, typ: PType, name: PRope, # declare the record: var hasField = false if typ.kind == tyObject: - useMagic(m, "TNimType") if typ.sons[0] == nil: if typ.sym != nil and sfPure in typ.sym.flags or tfFinal in typ.flags: - result = ropef("struct $1 {$n", [name]) + result = ropecg(m, "struct $1 {$n", [name]) else: - result = ropef("struct $1 {$nTNimType* m_type;$n", [name]) + result = ropecg(m, "struct $1 {$n#TNimType* m_type;$n", [name]) hasField = true elif gCmd == cmdCompileToCpp: - result = ropef("struct $1 : public $2 {$n", - [name, getTypeDescAux(m, typ.sons[0], check)]) + result = ropecg(m, "struct $1 : public $2 {$n", + [name, getTypeDescAux(m, typ.sons[0], check)]) hasField = true else: - result = ropef("struct $1 {$n $2 Sup;$n", - [name, getTypeDescAux(m, typ.sons[0], check)]) + result = ropecg(m, "struct $1 {$n $2 Sup;$n", + [name, getTypeDescAux(m, typ.sons[0], check)]) hasField = true else: result = ropef("struct $1 {$n", [name]) @@ -446,11 +445,12 @@ proc getTypeDescAux(m: BModule, typ: PType, check: var TIntSet): PRope = assert(CacheGetType(m.typeCache, t) == nil) IdTablePut(m.typeCache, t, con(result, "*")) if not isImportedType(t): - useMagic(m, "TGenericSeq") if skipTypes(t.sons[0], abstractInst).kind != tyEmpty: - appf(m.s[cfsSeqTypes], "struct $2 {$n" & " TGenericSeq Sup;$n" & - " $1 data[SEQ_DECL_SIZE];$n" & "};$n", - [getTypeDescAux(m, t.sons[0], check), result]) + appcg(m, m.s[cfsSeqTypes], + "struct $2 {$n" & + " #TGenericSeq Sup;$n" & + " $1 data[SEQ_DECL_SIZE];$n" & + "};$n", [getTypeDescAux(m, t.sons[0], check), result]) else: result = toRope("TGenericSeq") app(result, "*") @@ -595,10 +595,9 @@ proc genObjectFields(m: BModule, typ: PType, n: PNode, expr: PRope) = assert(n.sons[0].kind == nkSym) field = n.sons[0].sym tmp = getTempName() - useMagic(m, "chckNil") appf(m.s[cfsTypeInit3], "$1.kind = 3;$n" & "$1.offset = offsetof($2, $3);$n" & "$1.typ = $4;$n" & - "chckNil($1.typ);$n" & "$1.name = $5;$n" & "$1.sons = &$6[0];$n" & + "$1.name = $5;$n" & "$1.sons = &$6[0];$n" & "$1.len = $7;$n", [expr, getTypeDesc(m, typ), field.loc.r, genTypeInfo(m, field.typ), makeCString(field.name.s), tmp, toRope(lengthOrd(field.typ))]) @@ -628,10 +627,9 @@ proc genObjectFields(m: BModule, typ: PType, n: PNode, expr: PRope) = else: internalError(n.info, "genObjectFields(nkRecCase)") of nkSym: field = n.sym - useMagic(m, "chckNil") appf(m.s[cfsTypeInit3], "$1.kind = 1;$n" & "$1.offset = offsetof($2, $3);$n" & "$1.typ = $4;$n" & - "chckNil($1.typ);$n" & "$1.name = $5;$n", [expr, getTypeDesc(m, typ), + "$1.name = $5;$n", [expr, getTypeDesc(m, typ), field.loc.r, genTypeInfo(m, field.typ), makeCString(field.name.s)]) else: internalError(n.info, "genObjectFields") @@ -658,10 +656,9 @@ proc genTupleInfo(m: BModule, typ: PType, name: PRope) = a = typ.sons[i] tmp2 = getNimNode(m) appf(m.s[cfsTypeInit3], "$1[$2] = &$3;$n", [tmp, toRope(i), tmp2]) - useMagic(m, "chckNil") appf(m.s[cfsTypeInit3], "$1.kind = 1;$n" & "$1.offset = offsetof($2, Field$3);$n" & "$1.typ = $4;$n" & - "chckNil($1.typ);$n" & "$1.name = \"Field$3\";$n", + "$1.name = \"Field$3\";$n", [tmp2, getTypeDesc(m, typ), toRope(i), genTypeInfo(m, a)]) appf(m.s[cfsTypeInit3], "$1.len = $2; $1.kind = 2; $1.sons = &$3[0];$n", [expr, toRope(length), tmp]) @@ -735,8 +732,8 @@ proc genTypeInfo(m: BModule, typ: PType): PRope = result = ropef("NTI$1", [toRope(id)]) if not IntSetContainsOrIncl(m.typeInfoMarker, id): # declare type information structures: - useMagic(m, "TNimType") - useMagic(m, "TNimNode") + discard cgsym(m, "TNimType") + discard cgsym(m, "TNimNode") appf(m.s[cfsVars], "extern TNimType* $1; /* $2 */$n", [result, toRope(typeToString(t))]) if dataGenerated: return diff --git a/rod/cgen.nim b/rod/cgen.nim index ad322a1dd..dd1878465 100755 --- a/rod/cgen.nim +++ b/rod/cgen.nim @@ -169,7 +169,68 @@ proc useHeader(m: BModule, sym: PSym) = assert(sym.annex != nil) discard lists.IncludeStr(m.headerFiles, getStr(sym.annex.path)) -proc UseMagic(m: BModule, name: string) +proc cgsym(m: BModule, name: string): PRope + +proc ropecg(m: BModule, frmt: TFormatStr, args: openarray[PRope]): PRope = + var i, j, length, start, num: int + i = 0 + length = len(frmt) + result = nil + num = 0 + while i < length: + if frmt[i] == '$': + inc(i) # skip '$' + case frmt[i] + of '$': + app(result, "$") + inc(i) + of '#': + inc(i) + app(result, args[num]) + inc(num) + of '0'..'9': + j = 0 + while true: + j = (j * 10) + Ord(frmt[i]) - ord('0') + inc(i) + if (i > length + 0 - 1) or not (frmt[i] in {'0'..'9'}): break + num = j + if j > high(args) + 1: + internalError("ropes: invalid format string $" & $(j)) + app(result, args[j - 1]) + of 'N', 'n': + app(result, tnl) + inc(i) + else: InternalError("ropes: invalid format string $" & frmt[i]) + elif frmt[i] == '#' and frmt[i+1] in IdentStartChars: + inc(i) + var j = i + while frmt[j] in IdentChars: inc(j) + var ident = copy(frmt, i, j-1) + i = j + app(result, cgsym(m, ident)) + elif frmt[i] == '#' and frmt[i+1] == '$': + inc(i, 2) + var j = 0 + while frmt[i] in Digits: + j = (j * 10) + Ord(frmt[i]) - ord('0') + inc(i) + app(result, cgsym(m, args[j-1].ropeToStr)) + start = i + while i < length: + if frmt[i] != '$' and frmt[i] != '#': inc(i) + else: break + if i - 1 >= start: + app(result, copy(frmt, start, i - 1)) + +proc appcg(m: BModule, c: var PRope, frmt: TFormatStr, args: openarray[PRope]) = + app(c, ropecg(m, frmt, args)) + + +proc appcg(p: BProc, s: TCProcSection, frmt: TFormatStr, + args: openarray[PRope]) = + app(p.s[s], ropecg(p.module, frmt, args)) + include "ccgtypes.nim" @@ -274,26 +335,21 @@ proc assignLocalVar(p: BProc, s: PSym) = proc assignGlobalVar(p: BProc, s: PSym) = if s.loc.k == locNone: fillLoc(s.loc, locGlobalVar, s.typ, mangleName(s), OnHeap) - if gCmd == cmdCompileToLLVM: - appf(p.module.s[cfsVars], "$1 = linkonce global $2 zeroinitializer$n", - [s.loc.r, getTypeDesc(p.module, s.loc.t)]) - incl(s.loc.flags, lfIndirect) - else: - useHeader(p.module, s) - if lfNoDecl in s.loc.flags: return - if sfImportc in s.flags: app(p.module.s[cfsVars], "extern ") - app(p.module.s[cfsVars], getTypeDesc(p.module, s.loc.t)) - if sfRegister in s.flags: app(p.module.s[cfsVars], " register") - if sfVolatile in s.flags: app(p.module.s[cfsVars], " volatile") - if sfThreadVar in s.flags: app(p.module.s[cfsVars], " NIM_THREADVAR") - appf(p.module.s[cfsVars], " $1;$n", [s.loc.r]) + useHeader(p.module, s) + if lfNoDecl in s.loc.flags: return + if sfImportc in s.flags: app(p.module.s[cfsVars], "extern ") + app(p.module.s[cfsVars], getTypeDesc(p.module, s.loc.t)) + if sfRegister in s.flags: app(p.module.s[cfsVars], " register") + if sfVolatile in s.flags: app(p.module.s[cfsVars], " volatile") + if sfThreadVar in s.flags: app(p.module.s[cfsVars], " NIM_THREADVAR") + appf(p.module.s[cfsVars], " $1;$n", [s.loc.r]) if {optStackTrace, optEndb} * p.module.module.options == {optStackTrace, optEndb}: - useMagic(p.module, "dbgRegisterGlobal") - appff(p.module.s[cfsDebugInit], "dbgRegisterGlobal($1, &$2, $3);$n", - "call void @dbgRegisterGlobal(i8* $1, i8* $2, $4* $3)$n", [cstringLit( - p, p.module.s[cfsDebugInit], normalize(s.owner.name.s & '.' & s.name.s)), - s.loc.r, genTypeInfo(p.module, s.typ), getTypeDesc(p.module, "TNimType")]) + appcg(p.module, p.module.s[cfsDebugInit], + "#dbgRegisterGlobal($1, &$2, $3);$n", + [cstringLit(p, p.module.s[cfsDebugInit], + normalize(s.owner.name.s & '.' & s.name.s)), + s.loc.r, genTypeInfo(p.module, s.typ)]) proc iff(cond: bool, the, els: PRope): PRope = if cond: result = the @@ -352,11 +408,11 @@ proc loadDynamicLib(m: BModule, lib: PLib) = for i in countup(0, high(s)): inc(m.labels) if i > 0: app(loadlib, "||") - appf(loadlib, "($1 = nimLoadLibrary((NimStringDesc*) &$2))$n", - [tmp, getStrLit(m, s[i])]) - appf(m.s[cfsDynLibInit], - "if (!($1)) nimLoadLibraryError((NimStringDesc*) &$2);$n", - [loadlib, getStrLit(m, lib.path.strVal)]) + appcg(m, loadlib, "($1 = #nimLoadLibrary((#NimStringDesc*) &$2))$n", + [tmp, getStrLit(m, s[i])]) + appcg(m, m.s[cfsDynLibInit], + "if (!($1)) #nimLoadLibraryError((#NimStringDesc*) &$2);$n", + [loadlib, getStrLit(m, lib.path.strVal)]) else: var p = newProc(nil, m) var dest: TLoc @@ -364,37 +420,38 @@ proc loadDynamicLib(m: BModule, lib: PLib) = app(m.s[cfsVars], p.s[cpsLocals]) app(m.s[cfsDynLibInit], p.s[cpsInit]) app(m.s[cfsDynLibInit], p.s[cpsStmts]) - appf(m.s[cfsDynLibInit], - "if (!($1 = nimLoadLibrary($2))) nimLoadLibraryError($2);$n", + appcg(m, m.s[cfsDynLibInit], + "if (!($1 = #nimLoadLibrary($2))) #nimLoadLibraryError($2);$n", [tmp, rdLoc(dest)]) - useMagic(m, "nimLoadLibrary") - useMagic(m, "nimUnloadLibrary") - useMagic(m, "NimStringDesc") - useMagic(m, "nimLoadLibraryError") if lib.name == nil: InternalError("loadDynamicLib") +proc mangleDynLibProc(sym: PSym): PRope = + if sfCompilerProc in sym.flags: + # NOTE: sym.loc.r is the external name! + result = toRope(sym.name.s) + else: + result = ropef("Dl_$1", [toRope(sym.id)]) + proc SymInDynamicLib(m: BModule, sym: PSym) = var lib = sym.annex var extname = sym.loc.r loadDynamicLib(m, lib) - useMagic(m, "nimGetProcAddr") + discard cgsym(m, "nimGetProcAddr") if gCmd == cmdCompileToLLVM: incl(sym.loc.flags, lfIndirect) - var tmp = ropeff("Dl_$1", "@Dl_$1", [toRope(sym.id)]) + var tmp = mangleDynLibProc(sym) sym.loc.r = tmp # from now on we only need the internal name sym.typ.sym = nil # generate a new name inc(m.labels, 2) - appff(m.s[cfsDynLibInit], - "$1 = ($2) nimGetProcAddr($3, $4);$n", "%MOC$5 = load i8* $3$n" & - "%MOC$6 = call $2 @nimGetProcAddr(i8* %MOC$5, i8* $4)$n" & - "store $2 %MOC$6, $2* $1$n", [tmp, getTypeDesc(m, sym.typ), - lib.name, cstringLit(m, m.s[cfsDynLibInit], ropeToStr(extname)), - toRope(m.labels), toRope(m.labels - 1)]) + appf(m.s[cfsDynLibInit], + "$1 = ($2) nimGetProcAddr($3, $4);$n", + [tmp, getTypeDesc(m, sym.typ), + lib.name, cstringLit(m, m.s[cfsDynLibInit], ropeToStr(extname))]) appff(m.s[cfsVars], "$2 $1;$n", "$1 = linkonce global $2 zeroinitializer$n", [sym.loc.r, getTypeDesc(m, sym.loc.t)]) -proc UseMagic(m: BModule, name: string) = +proc cgsym(m: BModule, name: string): PRope = var sym = magicsys.getCompilerProc(name) if sym != nil: case sym.kind @@ -402,8 +459,16 @@ proc UseMagic(m: BModule, name: string) = of skVar: genVarPrototype(m, sym) of skType: discard getTypeDesc(m, sym.typ) else: InternalError("useMagic: " & name) - elif not (sfSystemModule in m.module.flags): - rawMessage(errSystemNeeds, name) # don't be too picky here + else: + # we used to exclude the system module from this check, but for DLL + # generation support this sloppyness leads to hard to detect bugs, so + # we're picky here for the system module too: + when false: + if not (sfSystemModule in m.module.flags): + rawMessage(errSystemNeeds, name) + else: + rawMessage(errSystemNeeds, name) + result = sym.loc.r proc generateHeaders(m: BModule) = app(m.s[cfsHeaders], "#include \"nimbase.h\"" & tnl & tnl) @@ -418,7 +483,7 @@ proc generateHeaders(m: BModule) = proc getFrameDecl(p: BProc) = var slots: PRope if p.frameLen > 0: - useMagic(p.module, "TVarSlot") + discard cgsym(p.module, "TVarSlot") slots = ropeff(" TVarSlot s[$1];$n", ", [$1 x %TVarSlot]", [toRope(p.frameLen)]) else: @@ -507,7 +572,7 @@ proc genProcAux(m: BModule, prc: PSym) = if (optProfiler in prc.options) and (gCmd != cmdCompileToLLVM): if gProcProfile >= 64 * 1024: InternalError(prc.info, "too many procedures for profiling") - useMagic(m, "profileData") + discard cgsym(m, "profileData") app(p.s[cpsLocals], "ticks NIM_profilingStart;" & tnl) if prc.loc.a < 0: appf(m.s[cfsDebugInit], "profileData[$1].procname = $2;$n", [ @@ -534,9 +599,9 @@ proc genProcPrototype(m: BModule, sym: PSym) = if lfDynamicLib in sym.loc.Flags: if (sym.owner.id != m.module.id) and not intSetContainsOrIncl(m.declaredThings, sym.id): - appff(m.s[cfsVars], "extern $1 Dl_$2;$n", - "@Dl_$2 = linkonce global $1 zeroinitializer$n", - [getTypeDesc(m, sym.loc.t), toRope(sym.id)]) + appff(m.s[cfsVars], "extern $1 $2;$n", + "@$2 = linkonce global $1 zeroinitializer$n", + [getTypeDesc(m, sym.loc.t), mangleDynLibProc(sym)]) if gCmd == cmdCompileToLLVM: incl(sym.loc.flags, lfIndirect) else: if not IntSetContainsOrIncl(m.declaredProtos, sym.id): @@ -679,7 +744,7 @@ proc genMainProc(m: BModule) = " i8* %lpvReserved) {$n" & " call void @NimMain()$n" & " ret i32 1$n" & "}$n" var nimMain, otherMain: TFormatStr - useMagic(m, "setStackBottom") + discard cgsym(m, "setStackBottom") if (platform.targetOS == osWindows) and (gGlobalOptions * {optGenGuiApp, optGenDynLib} != {}): if optGenGuiApp in gGlobalOptions: @@ -704,7 +769,7 @@ proc genMainProc(m: BModule) = else: nimMain = PosixNimMain otherMain = PosixCMain - if gBreakpoints != nil: useMagic(m, "dbgRegisterBreakpoint") + if gBreakpoints != nil: discard cgsym(m, "dbgRegisterBreakpoint") inc(m.labels) appf(m.s[cfsProcs], nimMain, [gBreakpoints, mainModInit, toRope(m.labels)]) if not (optNoMain in gGlobalOptions): appf(m.s[cfsProcs], otherMain, []) @@ -730,14 +795,10 @@ proc genInitCode(m: BModule) = prc = ropeff("N_NOINLINE(void, $1)(void) {$n", "define void $1() noinline {$n", [initname]) if m.typeNodes > 0: - useMagic(m, "TNimNode") - appff(m.s[cfsTypeInit1], "static TNimNode $1[$2];$n", - "$1 = private alloca [$2 x @TNimNode]$n", + appcg(m, m.s[cfsTypeInit1], "static #TNimNode $1[$2];$n", [m.typeNodesName, toRope(m.typeNodes)]) if m.nimTypes > 0: - useMagic(m, "TNimType") - appff(m.s[cfsTypeInit1], "static TNimType $1[$2];$n", - "$1 = private alloca [$2 x @TNimType]$n", + appcg(m, m.s[cfsTypeInit1], "static #TNimType $1[$2];$n", [m.nimTypesName, toRope(m.nimTypes)]) if optStackTrace in m.initProc.options: getFrameDecl(m.initProc) diff --git a/rod/magicsys.nim b/rod/magicsys.nim index 58de1d795..1d758dcde 100755 --- a/rod/magicsys.nim +++ b/rod/magicsys.nim @@ -1,7 +1,7 @@ # # # The Nimrod Compiler -# (c) Copyright 2009 Andreas Rumpf +# (c) Copyright 2010 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -69,8 +69,7 @@ proc getSysType(kind: TTypeKind): PType = if result == nil: InternalError("type not found: " & $kind) proc getCompilerProc(name: string): PSym = - var ident: PIdent - ident = getIdent(name, getNormalizedHash(name)) + var ident = getIdent(name, getNormalizedHash(name)) result = StrTableGet(compilerprocs, ident) if result == nil: result = StrTableGet(rodCompilerProcs, ident) diff --git a/rod/nimrod.ini b/rod/nimrod.ini index 1574721f1..9e3445c44 100755 --- a/rod/nimrod.ini +++ b/rod/nimrod.ini @@ -1,8 +1,9 @@ [Project] Name: "Nimrod" Version: "$version" -OS: "linux;macosx;freebsd;netbsd;openbsd;solaris" -CPU: "i386;amd64" # ;sparc;powerpc +; Windows and i386 must be first! +OS: "windows" ;linux;macosx;freebsd;netbsd;openbsd;solaris" +CPU: "i386" ;amd64" # ;sparc;powerpc Authors: "Andreas Rumpf" Description: """This is the Nimrod Compiler. Nimrod is a new statically typed, imperative programming language, that supports procedural, functional, object diff --git a/rod/pragmas.nim b/rod/pragmas.nim index 24c5be923..9f84c7f05 100755 --- a/rod/pragmas.nim +++ b/rod/pragmas.nim @@ -21,13 +21,13 @@ const procPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl, wMagic, wNosideEffect, wSideEffect, wNoreturn, wDynLib, wHeader, wCompilerProc, wPure, wProcVar, wDeprecated, wVarargs, wCompileTime, wMerge, - wBorrow} + wBorrow, wExtern} converterPragmas* = procPragmas methodPragmas* = procPragmas macroPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl, - wMagic, wNosideEffect, wCompilerProc, wDeprecated, wTypeCheck} + wMagic, wNosideEffect, wCompilerProc, wDeprecated, wTypeCheck, wExtern} iteratorPragmas* = {FirstCallConv..LastCallConv, wNosideEffect, wSideEffect, - wImportc, wExportc, wNodecl, wMagic, wDeprecated, wBorrow} + wImportc, wExportc, wNodecl, wMagic, wDeprecated, wBorrow, wExtern} stmtPragmas* = {wChecks, wObjChecks, wFieldChecks, wRangechecks, wBoundchecks, wOverflowchecks, wNilchecks, wAssertions, wWarnings, wHints, wLinedir, wStacktrace, wLinetrace, wOptimization, wHint, wWarning, wError, wFatal, @@ -35,13 +35,15 @@ const wCheckpoint, wPassL, wPassC, wDeadCodeElim, wDeprecated, wFloatChecks, wInfChecks, wNanChecks, wPragma} lambdaPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl, - wNosideEffect, wSideEffect, wNoreturn, wDynLib, wHeader, wPure, wDeprecated} + wNosideEffect, wSideEffect, wNoreturn, wDynLib, wHeader, wPure, + wDeprecated, wExtern} typePragmas* = {wImportc, wExportc, wDeprecated, wMagic, wAcyclic, wNodecl, - wPure, wHeader, wCompilerProc, wFinal, wSize} - fieldPragmas* = {wImportc, wExportc, wDeprecated} + wPure, wHeader, wCompilerProc, wFinal, wSize, wExtern} + fieldPragmas* = {wImportc, wExportc, wDeprecated, wExtern} varPragmas* = {wImportc, wExportc, wVolatile, wRegister, wThreadVar, wNodecl, - wMagic, wHeader, wDeprecated, wCompilerProc, wDynLib} - constPragmas* = {wImportc, wExportc, wHeader, wDeprecated, wMagic, wNodecl} + wMagic, wHeader, wDeprecated, wCompilerProc, wDynLib, wExtern} + constPragmas* = {wImportc, wExportc, wHeader, wDeprecated, wMagic, wNodecl, + wExtern} procTypePragmas* = {FirstCallConv..LastCallConv, wVarargs, wNosideEffect} proc pragma*(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) @@ -64,18 +66,17 @@ proc pragmaAsm(c: PContext, n: PNode): char = else: invalidPragma(it) else: invalidPragma(it) - -const - FirstPragmaWord = wMagic - LastPragmaWord = wNoconv + +proc setExternName(s: PSym, extname: string) = + s.loc.r = toRope(extname % s.name.s) proc MakeExternImport(s: PSym, extname: string) = - s.loc.r = toRope(extname) + setExternName(s, extname) incl(s.flags, sfImportc) excl(s.flags, sfForward) proc MakeExternExport(s: PSym, extname: string) = - s.loc.r = toRope(extname) + setExternName(s, extname) incl(s.flags, sfExportc) proc getStrLitNode(c: PContext, n: PNode): PNode = @@ -356,6 +357,7 @@ proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) = makeExternExport(sym, getOptionalStr(c, it, sym.name.s)) incl(sym.flags, sfUsed) # avoid wrong hints of wImportc: makeExternImport(sym, getOptionalStr(c, it, sym.name.s)) + of wExtern: setExternName(sym, expectStrLit(c, it)) of wAlign: if sym.typ == nil: invalidPragma(it) sym.typ.align = expectIntLit(c, it) diff --git a/rod/semstmts.nim b/rod/semstmts.nim index fdf931815..e700f8e71 100755 --- a/rod/semstmts.nim +++ b/rod/semstmts.nim @@ -688,7 +688,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, else: if n.sons[pragmasPos] != nil: liMessage(n.sons[pragmasPos].info, errPragmaOnlyInHeaderOfProc) - if not (sfForward in proto.flags): + if sfForward notin proto.flags: liMessage(n.info, errAttemptToRedefineX, proto.name.s) excl(proto.flags, sfForward) closeScope(c.tab) # close scope with wrong parameter symbols @@ -715,7 +715,9 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, c.p = newProcCon(s) if (s.typ.sons[0] != nil) and (kind != skIterator): addResult(c, s.typ.sons[0], n.info) - n.sons[codePos] = semStmtScope(c, n.sons[codePos]) + if sfImportc notin s.flags: + # no semantic checking for importc: + n.sons[codePos] = semStmtScope(c, n.sons[codePos]) if (s.typ.sons[0] != nil) and (kind != skIterator): addResultNode(c, n) else: if (s.typ.sons[0] != nil) and (kind != skIterator): diff --git a/rod/wordrecg.nim b/rod/wordrecg.nim index ac7265f7d..bf2aa84f7 100755 --- a/rod/wordrecg.nim +++ b/rod/wordrecg.nim @@ -34,6 +34,7 @@ type wColon, wEquals, wDot, wDotDot, wHat, wStar, wMinus, wMagic, wTypeCheck, wFinal, wProfiler, wObjChecks, wImportc, wExportc, + wExtern, wAlign, wNodecl, wPure, wVolatile, wRegister, wSideeffect, wHeader, wNosideeffect, wNoreturn, wMerge, wLib, wDynlib, wCompilerproc, wProcVar, wFatal, wError, wWarning, wHint, wLine, wPush, wPop, wDefine, wUndef, @@ -54,7 +55,7 @@ type wCc, wGenscript, wCheckPoint, wCheckPoints, wNoMain, wSubsChar, wAcyclic, wIndex, wCompileToC, wCompileToCpp, wCompileToEcmaScript, wCompileToLLVM, wPretty, - wDoc, wGenDepend, wListDef, wCheck, wParse, wScan, wBoot, wLazy, + wDoc, wGenDepend, wListDef, wCheck, wParse, wScan, wLazy, wRst2html, wRst2tex, wI, wWrite, wPutEnv, wPrependEnv, wAppendEnv, wThreadVar @@ -78,7 +79,8 @@ const ":", "=", ".", "..", "^", "*", "-", "magic", "typecheck", "final", "profiler", "objchecks", "importc", - "exportc", "align", "nodecl", "pure", "volatile", "register", "sideeffect", + "exportc", "extern", + "align", "nodecl", "pure", "volatile", "register", "sideeffect", "header", "nosideeffect", "noreturn", "merge", "lib", "dynlib", "compilerproc", "procvar", "fatal", "error", "warning", "hint", "line", "push", "pop", "define", "undef", "linedir", "stacktrace", "linetrace", @@ -101,7 +103,7 @@ const "nomain", "subschar", "acyclic", "index", "compiletoc", "compiletocpp", "compiletoecmascript", "compiletollvm", "pretty", "doc", "gendepend", "listdef", "check", "parse", "scan", - "boot", "lazy", "rst2html", "rst2tex", "i", + "lazy", "rst2html", "rst2tex", "i", "write", "putenv", "prependenv", "appendenv", "threadvar"] proc whichKeyword*(id: PIdent): TSpecialWord |