diff options
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/ccgexprs.nim | 12 | ||||
-rw-r--r-- | compiler/jsgen.nim | 29 | ||||
-rw-r--r-- | compiler/lexer.nim | 4 | ||||
-rw-r--r-- | compiler/sem.nim | 5 | ||||
-rw-r--r-- | compiler/semstmts.nim | 3 | ||||
-rw-r--r-- | compiler/semtypes.nim | 6 | ||||
-rw-r--r-- | compiler/sigmatch.nim | 37 |
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: |