summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/ccgexprs.nim12
-rw-r--r--compiler/jsgen.nim29
-rw-r--r--compiler/lexer.nim4
-rw-r--r--compiler/sem.nim5
-rw-r--r--compiler/semstmts.nim3
-rw-r--r--compiler/semtypes.nim6
-rw-r--r--compiler/sigmatch.nim37
7 files changed, 65 insertions, 31 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index 1a5334a98..4fcbeeec2 100644
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -672,9 +672,13 @@ proc genDeref(p: BProc, e: PNode, d: var TLoc; enforceDeref=false) =
     expr(p, e.sons[0], d)
   else:
     var a: TLoc
-    initLocExprSingleUse(p, e.sons[0], a)
+    let typ = skipTypes(e.sons[0].typ, abstractInst)
+    if typ.kind == tyVar and tfVarIsPtr notin typ.flags and p.module.compileToCpp and e.sons[0].kind == nkHiddenAddr:
+      initLocExprSingleUse(p, e[0][0], d)
+      return
+    else:
+      initLocExprSingleUse(p, e.sons[0], a)
     if d.k == locNone:
-      let typ = skipTypes(a.t, abstractInst)
       # dest = *a;  <-- We do not know that 'dest' is on the heap!
       # It is completely wrong to set 'd.s' here, unless it's not yet
       # been assigned to.
@@ -689,9 +693,9 @@ proc genDeref(p: BProc, e: PNode, d: var TLoc; enforceDeref=false) =
           return
       of tyPtr:
         d.s = OnUnknown         # BUGFIX!
-      else: internalError(e.info, "genDeref " & $a.t.kind)
+      else:
+        internalError(e.info, "genDeref " & $typ.kind)
     elif p.module.compileToCpp:
-      let typ = skipTypes(a.t, abstractInst)
       if typ.kind == tyVar and tfVarIsPtr notin typ.flags and
            e.kind == nkHiddenDeref:
         putIntoDest(p, d, e.typ, rdLoc(a), a.s)
diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim
index 8af6239a5..2da7db900 100644
--- a/compiler/jsgen.nim
+++ b/compiler/jsgen.nim
@@ -211,7 +211,6 @@ proc escapeJSString(s: string): string =
     of '\e': result.add("\\e")
     of '\v': result.add("\\v")
     of '\\': result.add("\\\\")
-    of '\'': result.add("\\'")
     of '\"': result.add("\\\"")
     else: add(result, c)
   result.add("\"")
@@ -464,6 +463,22 @@ proc arith(p: PProc, n: PNode, r: var TCompRes, op: TMagic) =
   of mSubU: binaryUintExpr(p, n, r, "-")
   of mMulU: binaryUintExpr(p, n, r, "*")
   of mDivU: binaryUintExpr(p, n, r, "/")
+  of mDivI:
+    if p.target == targetPHP:
+      var x, y: TCompRes
+      gen(p, n.sons[1], x)
+      gen(p, n.sons[2], y)
+      r.res = "intval($1 / $2)" % [x.rdLoc, y.rdLoc]
+    else:
+      arithAux(p, n, r, op, jsOps)
+  of mModI:
+    if p.target == targetPHP:
+      var x, y: TCompRes
+      gen(p, n.sons[1], x)
+      gen(p, n.sons[2], y)
+      r.res = "($1 % $2)" % [x.rdLoc, y.rdLoc]
+    else:
+      arithAux(p, n, r, op, jsOps)
   of mShrI:
     var x, y: TCompRes
     gen(p, n.sons[1], x)
@@ -767,10 +782,17 @@ proc generateHeader(p: PProc, typ: PType): Rope =
         add(result, name)
         add(result, "_Idx")
     elif not (i == 1 and param.name.s == "this"):
-      if param.typ.skipTypes({tyGenericInst}).kind == tyVar:
+      let k = param.typ.skipTypes({tyGenericInst}).kind
+      if k in { tyVar, tyRef, tyPtr, tyPointer }:
         add(result, "&")
       add(result, "$")
       add(result, name)
+      # XXX I think something like this is needed for PHP to really support
+      # ptr "inside" strings and seq
+      #if mapType(param.typ) == etyBaseIndex:
+      #  add(result, ", $")
+      #  add(result, name)
+      #  add(result, "_Idx")
 
 const
   nodeKindsNeedNoCopy = {nkCharLit..nkInt64Lit, nkStrLit..nkTripleStrLit,
@@ -953,10 +975,12 @@ proc genArrayAccess(p: PProc, n: PNode, r: var TCompRes) =
     if n.sons[0].kind in nkCallKinds+{nkStrLit..nkTripleStrLit}:
       useMagic(p, "nimAt")
       if ty.kind in {tyString, tyCString}:
+        # XXX this needs to be more like substr($1,$2)
         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}:
+      # XXX this needs to be more like substr($1,$2)
       r.res = "ord($1[$2])" % [r.address, r.res]
     else:
       r.res = "$1[$2]" % [r.address, r.res]
@@ -1963,6 +1987,7 @@ proc gen(p: PProc, n: PNode, r: var TCompRes) =
       genInfixCall(p, n, r)
     else:
       genCall(p, n, r)
+  of nkClosure: gen(p, n[0], r)
   of nkCurly: genSetConstr(p, n, r)
   of nkBracket: genArrayConstr(p, n, r)
   of nkPar: genTupleConstr(p, n, r)
diff --git a/compiler/lexer.nim b/compiler/lexer.nim
index 69a0fea2a..0032b97df 100644
--- a/compiler/lexer.nim
+++ b/compiler/lexer.nim
@@ -263,7 +263,7 @@ template eatChar(L: var TLexer, t: var TToken) =
   add(t.literal, L.buf[L.bufpos])
   inc(L.bufpos)
 
-proc getNumber(L: var TLexer): TToken =
+proc getNumber(L: var TLexer, result: var TToken) =
   proc matchUnderscoreChars(L: var TLexer, tok: var TToken, chars: set[char]) =
     var pos = L.bufpos              # use registers for pos, buf
     var buf = L.buf
@@ -1061,7 +1061,7 @@ proc rawGetTok*(L: var TLexer, tok: var TToken) =
       getCharacter(L, tok)
       tok.tokType = tkCharLit
     of '0'..'9':
-      tok = getNumber(L)
+      getNumber(L, tok)
     else:
       if c in OpChars:
         getOperator(L, tok)
diff --git a/compiler/sem.nim b/compiler/sem.nim
index e09d49f88..97a20a4da 100644
--- a/compiler/sem.nim
+++ b/compiler/sem.nim
@@ -67,9 +67,12 @@ template semIdeForTemplateOrGeneric(c: PContext; n: PNode;
 
 proc typeMismatch(n: PNode, formal, actual: PType) =
   if formal.kind != tyError and actual.kind != tyError:
+    let named = typeToString(formal)
+    let desc = typeToString(formal, preferDesc)
+    let x = if named == desc: named else: named & " = " & desc
     localError(n.info, errGenerated, msgKindToString(errTypeMismatch) &
         typeToString(actual) & ") " &
-        `%`(msgKindToString(errButExpectedX), [typeToString(formal)]))
+        `%`(msgKindToString(errButExpectedX), [x]))
 
 proc fitNode(c: PContext, formal: PType, arg: PNode): PNode =
   if arg.typ.isNil:
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim
index 5d16f2fba..910267e57 100644
--- a/compiler/semstmts.nim
+++ b/compiler/semstmts.nim
@@ -620,7 +620,8 @@ proc semFor(c: PContext, n: PNode): PNode =
       result.kind = nkParForStmt
     else:
       result = semForFields(c, n, call.sons[0].sym.magic)
-  elif isCallExpr and call.sons[0].typ.callConv == ccClosure:
+  elif isCallExpr and call.sons[0].typ.callConv == ccClosure and
+      tfIterator in call.sons[0].typ.flags:
     # first class iterator:
     result = semForVars(c, n)
   elif not isCallExpr or call.sons[0].kind != nkSym or
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim
index 62d02fe10..ba17cc307 100644
--- a/compiler/semtypes.nim
+++ b/compiler/semtypes.nim
@@ -831,9 +831,11 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
       result.rawAddSon paramType.lastSon
       return addImplicitGeneric(result)
 
-    result = instGenericContainer(c, paramType.sym.info, result,
+    let x = instGenericContainer(c, paramType.sym.info, result,
                                   allowMetaTypes = true)
-    result = newTypeWithSons(c, tyCompositeTypeClass, @[paramType, result])
+    result = newTypeWithSons(c, tyCompositeTypeClass, @[paramType, x])
+    #result = newTypeS(tyCompositeTypeClass, c)
+    #for i in 0..<x.len: result.rawAddSon(x.sons[i])
     result = addImplicitGeneric(result)
 
   of tyGenericInst:
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index 8859c30e4..82f878932 100644
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -847,7 +847,10 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
           inc(c.inheritancePenalty, depth)
           result = isSubtype
   of tyDistinct:
-    if a.kind == tyDistinct and sameDistinctTypes(f, a): result = isEqual
+    if a.kind == tyDistinct:
+      if sameDistinctTypes(f, a): result = isEqual
+      elif f.base.kind == tyAnything: result = isGeneric
+      elif c.coerceDistincts: result = typeRel(c, f.base, a)
     elif c.coerceDistincts: result = typeRel(c, f.base, a)
   of tySet:
     if a.kind == tySet:
@@ -922,19 +925,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
     if a.kind == tyEmpty: result = isEqual
 
   of tyGenericInst:
-    let roota = a.skipGenericAlias
-    let rootf = f.skipGenericAlias
-    if a.kind == tyGenericInst and roota.base == rootf.base:
-      for i in 1 .. rootf.sonsLen-2:
-        let ff = rootf.sons[i]
-        let aa = roota.sons[i]
-        result = typeRel(c, ff, aa)
-        if result == isNone: return
-        if ff.kind == tyRange and result != isEqual: return isNone
-      #result = isGeneric
-      # XXX See bug #2220. A[int] should match A[int] better than some generic X
-    else:
-      result = typeRel(c, lastSon(f), a)
+    result = typeRel(c, lastSon(f), a)
 
   of tyGenericBody:
     considerPreviousT:
@@ -1035,12 +1026,20 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
 
   of tyCompositeTypeClass:
     considerPreviousT:
-      if typeRel(c, f.sons[1], a) != isNone:
-        put(c.bindings, f, a)
-        return isGeneric
+      let roota = a.skipGenericAlias
+      let rootf = f.lastSon.skipGenericAlias
+      if a.kind == tyGenericInst and roota.base == rootf.base:
+        for i in 1 .. rootf.sonsLen-2:
+          let ff = rootf.sons[i]
+          let aa = roota.sons[i]
+          result = typeRel(c, ff, aa)
+          if result == isNone: return
+          if ff.kind == tyRange and result != isEqual: return isNone
       else:
-        return isNone
-
+        result = typeRel(c, rootf.lastSon, a)
+      if result != isNone:
+        put(c.bindings, f, a)
+        result = isGeneric
   of tyGenericParam:
     var x = PType(idTableGet(c.bindings, f))
     if x == nil: