summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2013-03-07 08:43:44 +0100
committerAraq <rumpf_a@web.de>2013-03-07 08:43:44 +0100
commitf1b8f834955d40274e017c6f69528eb88e6f0b05 (patch)
tree80a27f9a5a54452d4bb84b51734404ee0d542ef1
parent225d6570192e75371a1a7d6246ae56be784ea140 (diff)
downloadNim-f1b8f834955d40274e017c6f69528eb88e6f0b05.tar.gz
next steps for object construction expressions
-rwxr-xr-xcompiler/ccgexprs.nim48
-rwxr-xr-xcompiler/parser.nim2
-rwxr-xr-xcompiler/semexprs.nim28
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)