summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/jsgen.nim13
-rw-r--r--compiler/renderer.nim48
-rw-r--r--compiler/sigmatch.nim11
-rw-r--r--compiler/typesrenderer.nim1
-rw-r--r--compiler/vm.nim9
5 files changed, 55 insertions, 27 deletions
diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim
index e80147bd0..5ae01a67d 100644
--- a/compiler/jsgen.nim
+++ b/compiler/jsgen.nim
@@ -948,8 +948,17 @@ proc genArrayAccess(p: PProc, n: PNode, r: var TCompRes) =
   else: internalError(n.info, "expr(nkBracketExpr, " & $ty.kind & ')')
   r.typ = etyNone
   if r.res == nil: internalError(n.info, "genArrayAccess")
-  if p.target == targetPHP and ty.kind in {tyString, tyCString}:
-    r.res = "ord($1[$2])" % [r.address, r.res]
+  if p.target == targetPHP:
+    if n.sons[0].kind in nkCallKinds+{nkStrLit..nkTripleStrLit}:
+      useMagic(p, "nimAt")
+      if ty.kind in {tyString, tyCString}:
+        r.res = "ord(nimAt($1, $2))" % [r.address, r.res]
+      else:
+        r.res = "nimAt($1, $2)" % [r.address, r.res]
+    elif ty.kind in {tyString, tyCString}:
+      r.res = "ord($1[$2])" % [r.address, r.res]
+    else:
+      r.res = "$1[$2]" % [r.address, r.res]
   else:
     r.res = "$1[$2]" % [r.address, r.res]
   r.address = nil
diff --git a/compiler/renderer.nim b/compiler/renderer.nim
index 12852ba3d..03f6d4832 100644
--- a/compiler/renderer.nim
+++ b/compiler/renderer.nim
@@ -812,6 +812,13 @@ proc gsub(g: var TSrcGen; n: PNode; i: int) =
   else:
     put(g, tkOpr, "<<" & $i & "th child missing for " & $n.kind & " >>")
 
+proc isBracket*(n: PNode): bool =
+  case n.kind
+  of nkClosedSymChoice, nkOpenSymChoice:
+    if n.len > 0: result = isBracket(n[0])
+  of nkSym: result = n.sym.name.s == "[]"
+  else: result = false
+
 proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
   if isNil(n): return
   var
@@ -841,10 +848,16 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
   of nkCharLit: put(g, tkCharLit, atom(n))
   of nkNilLit: put(g, tkNil, atom(n))    # complex expressions
   of nkCall, nkConv, nkDotCall, nkPattern, nkObjConstr:
-    if sonsLen(n) >= 1: gsub(g, n.sons[0])
-    put(g, tkParLe, "(")
-    gcomma(g, n, 1)
-    put(g, tkParRi, ")")
+    if n.len > 0 and isBracket(n[0]):
+      gsub(g, n, 1)
+      put(g, tkBracketLe, "[")
+      gcomma(g, n, 2)
+      put(g, tkBracketRi, "]")
+    else:
+      if sonsLen(n) >= 1: gsub(g, n.sons[0])
+      put(g, tkParLe, "(")
+      gcomma(g, n, 1)
+      put(g, tkParRi, ")")
   of nkCallStrLit:
     gsub(g, n, 0)
     if n.len > 1 and n.sons[1].kind == nkRStrLit:
@@ -913,18 +926,21 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
     gcomma(g, n, 1)
     put(g, tkParRi, ")")
   of nkClosedSymChoice, nkOpenSymChoice:
-    put(g, tkParLe, "(")
-    for i in countup(0, sonsLen(n) - 1):
-      if i > 0: put(g, tkOpr, "|")
-      if n.sons[i].kind == nkSym:
-        let s = n[i].sym
-        if s.owner != nil:
-          put g, tkSymbol, n[i].sym.owner.name.s
-          put g, tkOpr, "."
-        put g, tkSymbol, n[i].sym.name.s
-      else:
-        gsub(g, n.sons[i], c)
-    put(g, tkParRi, if n.kind == nkOpenSymChoice: "|...)" else: ")")
+    if renderIds in g.flags:
+      put(g, tkParLe, "(")
+      for i in countup(0, sonsLen(n) - 1):
+        if i > 0: put(g, tkOpr, "|")
+        if n.sons[i].kind == nkSym:
+          let s = n[i].sym
+          if s.owner != nil:
+            put g, tkSymbol, n[i].sym.owner.name.s
+            put g, tkOpr, "."
+          put g, tkSymbol, n[i].sym.name.s
+        else:
+          gsub(g, n.sons[i], c)
+      put(g, tkParRi, if n.kind == nkOpenSymChoice: "|...)" else: ")")
+    else:
+      gsub(g, n, 0)
   of nkPar, nkClosure:
     put(g, tkParLe, "(")
     gcomma(g, n, c)
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index e67942cb2..8859c30e4 100644
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -1589,8 +1589,11 @@ proc matchesAux(c: PContext, n, nOrig: PNode,
         m.state = csNoMatch
         return
       if containsOrIncl(marker, formal.position):
-        # already in namedParams:
-        localError(n.sons[a].info, errCannotBindXTwice, formal.name.s)
+        # already in namedParams, so no match
+        # we used to produce 'errCannotBindXTwice' here but see
+        # bug #3836 of why that is not sound (other overload with
+        # different parameter names could match later on):
+        when false: localError(n.sons[a].info, errCannotBindXTwice, formal.name.s)
         m.state = csNoMatch
         return
       m.baseTypeMatch = false
@@ -1647,8 +1650,8 @@ proc matchesAux(c: PContext, n, nOrig: PNode,
           return
         formal = m.callee.n.sons[f].sym
         if containsOrIncl(marker, formal.position) and container.isNil:
-          # already in namedParams:
-          localError(n.sons[a].info, errCannotBindXTwice, formal.name.s)
+          # already in namedParams: (see above remark)
+          when false: localError(n.sons[a].info, errCannotBindXTwice, formal.name.s)
           m.state = csNoMatch
           return
         m.baseTypeMatch = false
diff --git a/compiler/typesrenderer.nim b/compiler/typesrenderer.nim
index 700356ab7..d050a86b2 100644
--- a/compiler/typesrenderer.nim
+++ b/compiler/typesrenderer.nim
@@ -100,7 +100,6 @@ proc renderParamTypes(found: var seq[string], n: PNode) =
       if not typ.isNil: typeStr = typeToString(typ, preferExported)
       if typeStr.len < 1: return
     for i in 0 .. <typePos:
-      assert ((n[i].kind == nkIdent) or (n[i].kind == nkAccQuoted))
       found.add(typeStr)
   else:
     internalError(n.info, "renderParamTypes(found,n) with " & $n.kind)
diff --git a/compiler/vm.nim b/compiler/vm.nim
index b537700fa..7220e1b8e 100644
--- a/compiler/vm.nim
+++ b/compiler/vm.nim
@@ -1590,12 +1590,13 @@ proc evalMacroCall*(module: PSym, n, nOrig: PNode, sym: PSym): PNode =
   for i in 1.. <sym.typ.len:
     tos.slots[i] = setupMacroParam(n.sons[i], sym.typ.sons[i])
 
-  if sfImmediate notin sym.flags:
-    let gp = sym.ast[genericParamsPos]
-    for i in 0 .. <gp.len:
+  let gp = sym.ast[genericParamsPos]
+  for i in 0 .. <gp.len:
+    if sfImmediate notin sym.flags:
       let idx = sym.typ.len + i
       tos.slots[idx] = setupMacroParam(n.sons[idx], gp[i].sym.typ)
-
+    elif gp[i].sym.typ.kind in {tyStatic, tyTypeDesc}:
+      globalError(n.info, "static[T] or typedesc nor supported for .immediate macros")
   # temporary storage:
   #for i in L .. <maxSlots: tos.slots[i] = newNode(nkEmpty)
   result = rawExecute(c, start, tos).regToNode