next steps for object construction expressions
This commit is contained in:
parent
225d657019
commit
f1b8f83495
3 changed files with 49 additions and 29 deletions
|
|
@ -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
|
discard getTypeDesc(p.module, a.t) # fill the record's fields.loc
|
||||||
result = a.t
|
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) =
|
proc genRecordField(p: BProc, e: PNode, d: var TLoc) =
|
||||||
var a: TLoc
|
var a: TLoc
|
||||||
var ty = genRecordFieldAux(p, e, d, a)
|
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])
|
appf(r, ".$1", [field.loc.r])
|
||||||
putIntoDest(p, d, field.typ, 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 genInExprAux(p: BProc, e: PNode, a, b, d: var TLoc)
|
||||||
proc genCheckedRecordField(p: BProc, e: PNode, d: var TLoc) =
|
proc genCheckedRecordField(p: BProc, e: PNode, d: var TLoc) =
|
||||||
var
|
var
|
||||||
|
|
@ -731,6 +731,9 @@ proc genCheckedRecordField(p: BProc, e: PNode, d: var TLoc) =
|
||||||
else:
|
else:
|
||||||
genRecordField(p, e.sons[0], d)
|
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) =
|
proc genArrayElem(p: BProc, e: PNode, d: var TLoc) =
|
||||||
var a, b: TLoc
|
var a, b: TLoc
|
||||||
initLocExpr(p, e.sons[0], a)
|
initLocExpr(p, e.sons[0], a)
|
||||||
|
|
@ -1815,6 +1818,7 @@ proc expr(p: BProc, e: PNode, d: var TLoc) =
|
||||||
exprComplexConst(p, e, d)
|
exprComplexConst(p, e, d)
|
||||||
else:
|
else:
|
||||||
genTupleConstr(p, e, d)
|
genTupleConstr(p, e, d)
|
||||||
|
of nkObjConstr: genObjConstr(p, e, d)
|
||||||
of nkCast: genCast(p, e, d)
|
of nkCast: genCast(p, e, d)
|
||||||
of nkHiddenStdConv, nkHiddenSubConv, nkConv: genConv(p, e, d)
|
of nkHiddenStdConv, nkHiddenSubConv, nkConv: genConv(p, e, d)
|
||||||
of nkHiddenAddr, nkAddr: genAddr(p, e, d)
|
of nkHiddenAddr, nkAddr: genAddr(p, e, d)
|
||||||
|
|
|
||||||
|
|
@ -501,7 +501,7 @@ proc primarySuffix(p: var TParser, r: PNode): PNode =
|
||||||
result = newNodeP(nkCall, p)
|
result = newNodeP(nkCall, p)
|
||||||
addSon(result, a)
|
addSon(result, a)
|
||||||
exprColonEqExprListAux(p, tkParRi, result)
|
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
|
result.kind = nkObjConstr
|
||||||
else:
|
else:
|
||||||
parseDoBlocks(p, result)
|
parseDoBlocks(p, result)
|
||||||
|
|
|
||||||
|
|
@ -602,6 +602,7 @@ proc semDirectCallAnalyseEffects(c: PContext, n: PNode, nOrig: PNode,
|
||||||
flags: TExprFlags): PNode =
|
flags: TExprFlags): PNode =
|
||||||
result = semOverloadedCallAnalyseEffects(c, n, nOrig, flags)
|
result = semOverloadedCallAnalyseEffects(c, n, nOrig, flags)
|
||||||
|
|
||||||
|
proc semObjConstr(c: PContext, n: PNode): PNode
|
||||||
proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
result = nil
|
result = nil
|
||||||
checkMinSonsLen(n, 1)
|
checkMinSonsLen(n, 1)
|
||||||
|
|
@ -655,6 +656,7 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
# has side-effects:
|
# has side-effects:
|
||||||
if tfNoSideEffect notin t.flags: incl(c.p.owner.flags, sfSideEffect)
|
if tfNoSideEffect notin t.flags: incl(c.p.owner.flags, sfSideEffect)
|
||||||
elif t != nil and t.kind == tyTypeDesc:
|
elif t != nil and t.kind == tyTypeDesc:
|
||||||
|
if n.len == 1: return semObjConstr(c, n)
|
||||||
let destType = t.skipTypes({tyTypeDesc, tyGenericInst})
|
let destType = t.skipTypes({tyTypeDesc, tyGenericInst})
|
||||||
result = semConv(c, n, symFromType(destType, n.info))
|
result = semConv(c, n, symFromType(destType, n.info))
|
||||||
return
|
return
|
||||||
|
|
@ -1572,12 +1574,24 @@ proc semObjConstr(c: PContext, n: PNode): PNode =
|
||||||
if ContainsOrIncl(ids, id.id):
|
if ContainsOrIncl(ids, id.id):
|
||||||
localError(it.info, errFieldInitTwice, id.s)
|
localError(it.info, errFieldInitTwice, id.s)
|
||||||
var e = semExprWithType(c, it.sons[1])
|
var e = semExprWithType(c, it.sons[1])
|
||||||
let field = lookupInRecord(t.n, id)
|
|
||||||
if field.isNil:
|
var
|
||||||
localError(it.info, errUndeclaredFieldX, id.s)
|
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:
|
else:
|
||||||
it.sons[0] = newSymNode(field)
|
localError(it.info, errUndeclaredFieldX, id.s)
|
||||||
e = fitNode(c, field.typ, e)
|
|
||||||
it.sons[1] = e
|
it.sons[1] = e
|
||||||
# XXX object field name check for 'case objects' if the kind is static?
|
# 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)
|
# XXX think about this more (``set`` procs)
|
||||||
if n.len == 2:
|
if n.len == 2:
|
||||||
result = semConv(c, n, s)
|
result = semConv(c, n, s)
|
||||||
|
elif n.len == 1:
|
||||||
|
result = semObjConstr(c, n)
|
||||||
elif Contains(c.AmbiguousSymbols, s.id):
|
elif Contains(c.AmbiguousSymbols, s.id):
|
||||||
LocalError(n.info, errUseQualifier, s.name.s)
|
LocalError(n.info, errUseQualifier, s.name.s)
|
||||||
elif s.magic == mNone: result = semDirectOp(c, n, flags)
|
elif s.magic == mNone: result = semDirectOp(c, n, flags)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue