summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2014-11-17 08:54:31 +0100
committerAraq <rumpf_a@web.de>2014-11-17 08:54:31 +0100
commitc5cc20d33797f094a742c0a7f39a59e867a380f7 (patch)
tree207f9a4993bd415fc8273312c9d68bae130a60aa
parent729e048a324a6908b6a2d19a7d0186c05880151c (diff)
downloadNim-c5cc20d33797f094a742c0a7f39a59e867a380f7.tar.gz
fixes #1548
-rw-r--r--compiler/ccgexprs.nim7
-rw-r--r--compiler/jsgen.nim12
-rw-r--r--compiler/semexprs.nim39
-rw-r--r--compiler/vmgen.nim12
-rw-r--r--doc/manual/procs.txt2
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