diff options
author | Araq <rumpf_a@web.de> | 2014-11-17 08:54:31 +0100 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2014-11-17 08:54:31 +0100 |
commit | c5cc20d33797f094a742c0a7f39a59e867a380f7 (patch) | |
tree | 207f9a4993bd415fc8273312c9d68bae130a60aa | |
parent | 729e048a324a6908b6a2d19a7d0186c05880151c (diff) | |
download | Nim-c5cc20d33797f094a742c0a7f39a59e867a380f7.tar.gz |
fixes #1548
-rw-r--r-- | compiler/ccgexprs.nim | 7 | ||||
-rw-r--r-- | compiler/jsgen.nim | 12 | ||||
-rw-r--r-- | compiler/semexprs.nim | 39 | ||||
-rw-r--r-- | compiler/vmgen.nim | 12 | ||||
-rw-r--r-- | doc/manual/procs.txt | 2 |
5 files changed, 27 insertions, 45 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index b91c54e8b..7d704c15b 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -916,14 +916,15 @@ proc genAndOr(p: BProc, e: PNode, d: var TLoc, m: TMagic) = proc genEcho(p: BProc, n: PNode) = # this unusal way of implementing it ensures that e.g. ``echo("hallo", 45)`` # is threadsafe. + internalAssert n.kind == nkBracket discard lists.includeStr(p.module.headerFiles, "<stdio.h>") var args: PRope = nil var a: TLoc - for i in countup(1, n.len-1): + for i in countup(0, n.len-1): initLocExpr(p, n.sons[i], a) appf(args, ", ($1)->data", [rdLoc(a)]) linefmt(p, cpsStmts, "printf($1$2);$n", - makeCString(repeatStr(n.len-1, "%s") & tnl), args) + makeCString(repeatStr(n.len, "%s") & tnl), args) proc gcUsage(n: PNode) = if gSelectedGC == gcNone: message(n.info, warnGcMem, n.renderTree) @@ -1693,7 +1694,7 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) = discard cgsym(p.module, opr.loc.r.ropeToStr) genCall(p, e, d) of mReset: genReset(p, e) - of mEcho: genEcho(p, e) + of mEcho: genEcho(p, e[1].skipConv) of mArrToSeq: genArrToSeq(p, e, d) of mNLen..mNError: localError(e.info, errCannotGenerateCodeForX, e.sons[0].sym.name.s) diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index 37eaa9fb7..8fc2ec1d2 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -1078,8 +1078,16 @@ proc genInfixCall(p: PProc, n: PNode, r: var TCompRes) = proc genEcho(p: PProc, n: PNode, r: var TCompRes) = useMagic(p, "rawEcho") - app(r.res, "rawEcho") - genArgs(p, n, r) + app(r.res, "rawEcho(") + let n = n[1].skipConv + internalAssert n.kind == nkBracket + for i in countup(0, sonsLen(n) - 1): + let it = n.sons[i] + if it.typ.isCompileTimeOnly: continue + if i > 0: app(r.res, ", ") + genArg(p, it, r) + app(r.res, ")") + r.kind = resExpr proc putToSeq(s: string, indirect: bool): PRope = result = toRope(s) diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index bf2344f11..73c778530 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -840,45 +840,17 @@ proc semDirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode = if result != nil: result = afterCallActions(c, result, nOrig, flags) else: result = errorNode(c, n) -proc buildStringify(c: PContext, arg: PNode): PNode = - if arg.typ != nil and - skipTypes(arg.typ, abstractInst-{tyTypeDesc}).kind == tyString: - result = arg - else: - result = newNodeI(nkCall, arg.info) - addSon(result, newIdentNode(getIdent"$", arg.info)) - addSon(result, arg) - -proc semEcho(c: PContext, n: PNode): PNode = - # this really is a macro - checkMinSonsLen(n, 1) - for i in countup(1, sonsLen(n) - 1): - var arg = semExprWithType(c, n.sons[i]) - arg = semExprWithType(c, buildStringify(c, arg)) - n.sons[i] = arg - let t = arg.typ - if (t == nil or t.skipTypes(abstractInst).kind != tyString) and - arg.kind != nkEmpty: - localError(n.info, errGenerated, - "implicitly invoked '$' does not return string") - let t = n.sons[0].typ - if tfNoSideEffect notin t.flags: incl(c.p.owner.flags, sfSideEffect) - result = n - proc buildEchoStmt(c: PContext, n: PNode): PNode = - # we MUST not check 'n' for semantics again here! + # we MUST not check 'n' for semantics again here! But for now we give up: result = newNodeI(nkCall, n.info) var e = strTableGet(magicsys.systemModule.tab, getIdent"echo") if e != nil: - addSon(result, newSymNode(e)) + add(result, newSymNode(e)) else: localError(n.info, errSystemNeeds, "echo") - addSon(result, errorNode(c, n)) - var arg = buildStringify(c, n) - # problem is: implicit '$' is not checked for semantics yet. So we give up - # and check 'arg' for semantics again: - arg = semExpr(c, arg) - if arg != nil: addSon(result, arg) + add(result, errorNode(c, n)) + add(result, n) + result = semExpr(c, result) proc semExprNoType(c: PContext, n: PNode): PNode = result = semExpr(c, n, {efWantStmt}) @@ -1650,7 +1622,6 @@ proc semMagic(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode = of mSizeOf: result = semSizeof(c, setMs(n, s)) of mIs: result = semIs(c, setMs(n, s)) of mOf: result = semOf(c, setMs(n, s)) - of mEcho: result = semEcho(c, setMs(n, s)) of mShallowCopy: result = semShallowCopy(c, n, flags) of mExpandToAst: result = semExpandToAst(c, n, s, flags) of mQuoteAst: result = semQuoteAst(c, n) diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index da31eab3d..8b7dc293c 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -899,12 +899,14 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest) = c.freeTemp(tmp) of mEcho: unused(n, dest) - let x = c.getTempRange(n.len-1, slotTempUnknown) - for i in 1.. <n.len: - var r: TRegister = x+i-1 + let n = n[1].skipConv + let x = c.getTempRange(n.len, slotTempUnknown) + internalAssert n.kind == nkBracket + for i in 0.. <n.len: + var r: TRegister = x+i c.gen(n.sons[i], r) - c.gABC(n, opcEcho, x, n.len-1) - c.freeTempRange(x, n.len-1) + c.gABC(n, opcEcho, x, n.len) + c.freeTempRange(x, n.len) of mAppendStrCh: unused(n, dest) genBinaryStmtVar(c, n, opcAddStrCh) diff --git a/doc/manual/procs.txt b/doc/manual/procs.txt index 9ddae6230..f48203c3b 100644 --- a/doc/manual/procs.txt +++ b/doc/manual/procs.txt @@ -237,7 +237,7 @@ The following builtin procs cannot be overloaded for reasons of implementation simplicity (they require specialized semantic checking):: declared, defined, definedInScope, compiles, low, high, sizeOf, - is, of, echo, shallowCopy, getAst, astToStr, spawn + is, of, shallowCopy, getAst, astToStr, spawn Thus they act more like keywords than like ordinary identifiers; unlike a keyword however, a redefinition may `shadow`:idx: the definition in |