mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-19 05:50:30 +00:00
VM produces objects.
This commit is contained in:
@@ -38,14 +38,16 @@ proc annotateType*(n: PNode, t: PType) =
|
||||
# Note: x can be unequal to t and we need to be careful to use 't'
|
||||
# to not to skip tyGenericInst
|
||||
case n.kind
|
||||
of nkObjConstr:
|
||||
n.typ = t
|
||||
for i in 1 .. <n.len:
|
||||
let field = x.n.ithField(i - 1)
|
||||
if field.isNil: globalError n.info, "invalid field at index " & $i
|
||||
else:
|
||||
internalAssert(n.sons[i].kind == nkExprColonExpr)
|
||||
annotateType(n.sons[i].sons[1], field.typ)
|
||||
of nkPar:
|
||||
if x.kind == tyObject:
|
||||
n.typ = t
|
||||
for i in 0 .. <n.len:
|
||||
let field = x.n.ithField(i)
|
||||
if field.isNil: globalError n.info, "invalid field at index " & $i
|
||||
else: annotateType(n.sons[i], field.typ)
|
||||
elif x.kind == tyTuple:
|
||||
if x.kind == tyTuple:
|
||||
n.typ = t
|
||||
for i in 0 .. <n.len:
|
||||
if i >= x.len: globalError n.info, "invalid field at index " & $i
|
||||
@@ -53,7 +55,7 @@ proc annotateType*(n: PNode, t: PType) =
|
||||
elif x.kind == tyProc and x.callConv == ccClosure:
|
||||
n.typ = t
|
||||
else:
|
||||
globalError(n.info, "() must have an object or tuple type")
|
||||
globalError(n.info, "() must have a tuple type")
|
||||
of nkBracket:
|
||||
if x.kind in {tyArrayConstr, tyArray, tySequence, tyOpenArray}:
|
||||
n.typ = t
|
||||
|
||||
@@ -83,7 +83,7 @@ proc stackTrace(c: PCtx, tos: PStackFrame, pc: int,
|
||||
|
||||
proc bailOut(c: PCtx; tos: PStackFrame) =
|
||||
stackTrace(c, tos, c.exceptionInstr, errUnhandledExceptionX,
|
||||
c.currentExceptionA.sons[2].strVal)
|
||||
c.currentExceptionA.sons[3].skipColon.strVal)
|
||||
|
||||
when not defined(nimComputedGoto):
|
||||
{.pragma: computedGoto.}
|
||||
@@ -383,7 +383,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||
let instr = c.code[pc]
|
||||
let ra = instr.regA
|
||||
#if c.traceActive:
|
||||
# echo "PC ", pc, " ", c.code[pc].opcode, " ra ", ra
|
||||
#echo "PC ", pc, " ", c.code[pc].opcode, " ra ", ra, " rb ", instr.regB, " rc ", instr.regC
|
||||
# message(c.debug[pc], warnUser, "Trace")
|
||||
|
||||
case instr.opcode
|
||||
@@ -475,14 +475,19 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||
decodeBC(rkNode)
|
||||
let src = regs[rb].node
|
||||
if src.kind notin {nkEmpty..nkNilLit}:
|
||||
let n = src.sons[rc].skipColon
|
||||
let n = src.sons[rc + ord(src.kind == nkObjConstr)].skipColon
|
||||
regs[ra].node = n
|
||||
else:
|
||||
stackTrace(c, tos, pc, errNilAccess)
|
||||
of opcWrObj:
|
||||
# a.b = c
|
||||
decodeBC(rkNode)
|
||||
putIntoNode(regs[ra].node.sons[rb], regs[rc])
|
||||
let shiftedRb = rb + ord(regs[ra].node.kind == nkObjConstr)
|
||||
let dest = regs[ra].node
|
||||
if dest.sons[shiftedRb].kind == nkExprColonExpr:
|
||||
putIntoNode(dest.sons[shiftedRb].sons[1], regs[rc])
|
||||
else:
|
||||
putIntoNode(dest.sons[shiftedRb], regs[rc])
|
||||
of opcWrStrIdx:
|
||||
decodeBC(rkNode)
|
||||
let idx = regs[rb].intVal.int
|
||||
|
||||
@@ -1392,7 +1392,10 @@ proc getNullValueAux(obj: PNode, result: PNode) =
|
||||
for i in countup(1, sonsLen(obj) - 1):
|
||||
getNullValueAux(lastSon(obj.sons[i]), result)
|
||||
of nkSym:
|
||||
addSon(result, getNullValue(obj.sym.typ, result.info))
|
||||
let field = newNodeI(nkExprColonExpr, result.info)
|
||||
field.add(obj)
|
||||
field.add(getNullValue(obj.sym.typ, result.info))
|
||||
addSon(result, field)
|
||||
else: globalError(result.info, "cannot create null element for: " & $obj)
|
||||
|
||||
proc getNullValue(typ: PType, info: TLineInfo): PNode =
|
||||
@@ -1418,7 +1421,8 @@ proc getNullValue(typ: PType, info: TLineInfo): PNode =
|
||||
result.add(newNodeIT(nkNilLit, info, t))
|
||||
result.add(newNodeIT(nkNilLit, info, t))
|
||||
of tyObject:
|
||||
result = newNodeIT(nkPar, info, t)
|
||||
result = newNodeIT(nkObjConstr, info, t)
|
||||
result.add(newNodeIT(nkEmpty, info, t))
|
||||
getNullValueAux(t.n, result)
|
||||
# initialize inherited fields:
|
||||
var base = t.sons[0]
|
||||
|
||||
@@ -36,8 +36,8 @@ proc getField(n: PNode; position: int): PSym =
|
||||
proc storeAny(s: var string; t: PType; a: PNode; stored: var IntSet)
|
||||
|
||||
proc storeObj(s: var string; typ: PType; x: PNode; stored: var IntSet) =
|
||||
internalAssert x.kind in {nkObjConstr, nkPar}
|
||||
let start = ord(x.kind == nkObjConstr)
|
||||
internalAssert x.kind == nkObjConstr
|
||||
let start = 1
|
||||
for i in countup(start, sonsLen(x) - 1):
|
||||
if i > start: s.add(", ")
|
||||
var it = x.sons[i]
|
||||
@@ -205,18 +205,23 @@ proc loadAny(p: var JsonParser, t: PType,
|
||||
of tyObject:
|
||||
if p.kind != jsonObjectStart: raiseParseErr(p, "'{' expected for an object")
|
||||
next(p)
|
||||
result = newNode(nkPar)
|
||||
result.sons = @[]
|
||||
result = newNode(nkObjConstr)
|
||||
result.sons = @[newNode(nkEmpty)]
|
||||
while p.kind != jsonObjectEnd and p.kind != jsonEof:
|
||||
if p.kind != jsonString:
|
||||
raiseParseErr(p, "string expected for a field name")
|
||||
let field = lookupInRecord(t.n, getIdent(p.str))
|
||||
let ident = getIdent(p.str)
|
||||
let field = lookupInRecord(t.n, ident)
|
||||
if field.isNil:
|
||||
raiseParseErr(p, "unknown field for object of type " & typeToString(t))
|
||||
next(p)
|
||||
if field.position >= result.sons.len:
|
||||
setLen(result.sons, field.position+1)
|
||||
result.sons[field.position] = loadAny(p, field.typ, tab)
|
||||
let pos = field.position + 1
|
||||
if pos >= result.sons.len:
|
||||
setLen(result.sons, pos + 1)
|
||||
let fieldNode = newNode(nkExprColonExpr)
|
||||
fieldNode.addSon(newSymNode(newSym(skField, ident, nil, unknownLineInfo())))
|
||||
fieldNode.addSon(loadAny(p, field.typ, tab))
|
||||
result.sons[pos] = fieldNode
|
||||
if p.kind == jsonObjectEnd: next(p)
|
||||
else: raiseParseErr(p, "'}' end of object expected")
|
||||
of tySet:
|
||||
|
||||
@@ -46,7 +46,7 @@ template wrap2svoid(op) {.immediate, dirty.} =
|
||||
|
||||
proc getCurrentExceptionMsgWrapper(a: VmArgs) {.nimcall.} =
|
||||
setResult(a, if a.currentException.isNil: ""
|
||||
else: a.currentException.sons[2].strVal)
|
||||
else: a.currentException.sons[3].skipColon.strVal)
|
||||
|
||||
proc registerAdditionalOps*(c: PCtx) =
|
||||
wrap1f(sqrt)
|
||||
|
||||
@@ -62,6 +62,10 @@ News
|
||||
* ``libeay32.dll``: Split into ``libeay32.dll`` and ``libeay64.dll``.
|
||||
|
||||
Compile with ``-d:nimOldDLLs`` to make the stdlib use the old DLL names.
|
||||
- Nim VM now treats objects as nkObjConstr nodes, and not nkPar nodes as it
|
||||
was previously. Macros that generate nkPar nodes when object is expected are
|
||||
likely to break. Macros that expect nkPar nodes to which objects are passed
|
||||
are likely to break as well.
|
||||
|
||||
|
||||
Library additions
|
||||
|
||||
Reference in New Issue
Block a user