diff options
author | Araq <rumpf_a@web.de> | 2013-03-07 08:43:44 +0100 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2013-03-07 08:43:44 +0100 |
commit | f1b8f834955d40274e017c6f69528eb88e6f0b05 (patch) | |
tree | 80a27f9a5a54452d4bb84b51734404ee0d542ef1 | |
parent | 225d6570192e75371a1a7d6246ae56be784ea140 (diff) | |
download | Nim-f1b8f834955d40274e017c6f69528eb88e6f0b05.tar.gz |
next steps for object construction expressions
-rwxr-xr-x | compiler/ccgexprs.nim | 48 | ||||
-rwxr-xr-x | compiler/parser.nim | 2 | ||||
-rwxr-xr-x | compiler/semexprs.nim | 28 |
3 files changed, 49 insertions, 29 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 5e5d22fb2..ccabb3600 100755 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -633,6 +633,28 @@ proc genRecordFieldAux(p: BProc, e: PNode, d, a: var TLoc): PType = discard getTypeDesc(p.module, a.t) # fill the record's fields.loc result = a.t +proc genTupleElem(p: BProc, e: PNode, d: var TLoc) = + var + a: TLoc + i: int + initLocExpr(p, e.sons[0], a) + d.inheritLocation(a) + discard getTypeDesc(p.module, a.t) # fill the record's fields.loc + var ty = a.t + var r = rdLoc(a) + case e.sons[1].kind + of nkIntLit..nkUInt64Lit: i = int(e.sons[1].intVal) + else: internalError(e.info, "genTupleElem") + when false: + if ty.n != nil: + var field = ty.n.sons[i].sym + if field == nil: InternalError(e.info, "genTupleElem") + if field.loc.r == nil: InternalError(e.info, "genTupleElem") + appf(r, ".$1", [field.loc.r]) + else: + appf(r, ".Field$1", [toRope(i)]) + putIntoDest(p, d, ty.sons[i], r) + proc genRecordField(p: BProc, e: PNode, d: var TLoc) = var a: TLoc var ty = genRecordFieldAux(p, e, d, a) @@ -657,28 +679,6 @@ proc genRecordField(p: BProc, e: PNode, d: var TLoc) = appf(r, ".$1", [field.loc.r]) putIntoDest(p, d, field.typ, r) -proc genTupleElem(p: BProc, e: PNode, d: var TLoc) = - var - a: TLoc - i: int - initLocExpr(p, e.sons[0], a) - d.inheritLocation(a) - discard getTypeDesc(p.module, a.t) # fill the record's fields.loc - var ty = a.t - var r = rdLoc(a) - case e.sons[1].kind - of nkIntLit..nkUInt64Lit: i = int(e.sons[1].intVal) - else: internalError(e.info, "genTupleElem") - when false: - if ty.n != nil: - var field = ty.n.sons[i].sym - if field == nil: InternalError(e.info, "genTupleElem") - if field.loc.r == nil: InternalError(e.info, "genTupleElem") - appf(r, ".$1", [field.loc.r]) - else: - appf(r, ".Field$1", [toRope(i)]) - putIntoDest(p, d, ty.sons[i], r) - proc genInExprAux(p: BProc, e: PNode, a, b, d: var TLoc) proc genCheckedRecordField(p: BProc, e: PNode, d: var TLoc) = var @@ -731,6 +731,9 @@ proc genCheckedRecordField(p: BProc, e: PNode, d: var TLoc) = else: genRecordField(p, e.sons[0], d) +proc genObjConstr(p: BProc, e: PNode, d: var TLoc) = + internalError(e.info, "too implement") + proc genArrayElem(p: BProc, e: PNode, d: var TLoc) = var a, b: TLoc initLocExpr(p, e.sons[0], a) @@ -1815,6 +1818,7 @@ proc expr(p: BProc, e: PNode, d: var TLoc) = exprComplexConst(p, e, d) else: genTupleConstr(p, e, d) + of nkObjConstr: genObjConstr(p, e, d) of nkCast: genCast(p, e, d) of nkHiddenStdConv, nkHiddenSubConv, nkConv: genConv(p, e, d) of nkHiddenAddr, nkAddr: genAddr(p, e, d) diff --git a/compiler/parser.nim b/compiler/parser.nim index f820c38db..00675c5ba 100755 --- a/compiler/parser.nim +++ b/compiler/parser.nim @@ -501,7 +501,7 @@ proc primarySuffix(p: var TParser, r: PNode): PNode = result = newNodeP(nkCall, p) addSon(result, a) exprColonEqExprListAux(p, tkParRi, result) - if result.len > 1 and result.sons[0].kind == nkExprColonExpr: + if result.len > 1 and result.sons[1].kind == nkExprColonExpr: result.kind = nkObjConstr else: parseDoBlocks(p, result) diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 1c95a7452..762a1973f 100755 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -602,6 +602,7 @@ proc semDirectCallAnalyseEffects(c: PContext, n: PNode, nOrig: PNode, flags: TExprFlags): PNode = result = semOverloadedCallAnalyseEffects(c, n, nOrig, flags) +proc semObjConstr(c: PContext, n: PNode): PNode proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode = result = nil checkMinSonsLen(n, 1) @@ -655,9 +656,10 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode = # has side-effects: if tfNoSideEffect notin t.flags: incl(c.p.owner.flags, sfSideEffect) elif t != nil and t.kind == tyTypeDesc: + if n.len == 1: return semObjConstr(c, n) let destType = t.skipTypes({tyTypeDesc, tyGenericInst}) result = semConv(c, n, symFromType(destType, n.info)) - return + return else: result = overloadedCallOpr(c, n) # Now that nkSym does not imply an iteration over the proc/iterator space, @@ -1572,12 +1574,24 @@ proc semObjConstr(c: PContext, n: PNode): PNode = if ContainsOrIncl(ids, id.id): localError(it.info, errFieldInitTwice, id.s) var e = semExprWithType(c, it.sons[1]) - let field = lookupInRecord(t.n, id) - if field.isNil: - localError(it.info, errUndeclaredFieldX, id.s) + + var + check: PNode = nil + f: PSym + while true: + check = nil + f = lookupInRecordAndBuildCheck(c, it, t.n, id, check) + if f != nil: break + if t.sons[0] == nil: break + t = skipTypes(t.sons[0], {tyGenericInst}) + if f != nil and fieldVisible(c, f): + it.sons[0] = newSymNode(f) + e = fitNode(c, f.typ, e) + # small hack here in a nkObjConstr the ``nkExprColonExpr`` node can have + # 3 childen the last being the field check + if check != nil: it.add(check) else: - it.sons[0] = newSymNode(field) - e = fitNode(c, field.typ, e) + localError(it.info, errUndeclaredFieldX, id.s) it.sons[1] = e # XXX object field name check for 'case objects' if the kind is static? @@ -1788,6 +1802,8 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = # XXX think about this more (``set`` procs) if n.len == 2: result = semConv(c, n, s) + elif n.len == 1: + result = semObjConstr(c, n) elif Contains(c.AmbiguousSymbols, s.id): LocalError(n.info, errUseQualifier, s.name.s) elif s.magic == mNone: result = semDirectOp(c, n, flags) |