diff options
author | Araq <rumpf_a@web.de> | 2015-01-28 18:58:05 +0100 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2015-01-28 19:31:36 +0100 |
commit | a4b27622491c9844da2ca15bb8cc3ec36356484e (patch) | |
tree | 480313aef9418696a4c2dc2defce8be0da2b1654 /compiler | |
parent | d7023f2be4c9cb93dac91d8e4359c70f52bd5633 (diff) | |
download | Nim-a4b27622491c9844da2ca15bb8cc3ec36356484e.tar.gz |
fixes #325
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/ast.nim | 8 | ||||
-rw-r--r-- | compiler/guards.nim | 6 | ||||
-rw-r--r-- | compiler/lowerings.nim | 1 | ||||
-rw-r--r-- | compiler/semexprs.nim | 55 |
4 files changed, 39 insertions, 31 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim index 00515875f..d487b5380 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -1568,3 +1568,11 @@ proc makeStmtList*(n: PNode): PNode = else: result = newNodeI(nkStmtList, n.info) result.add n + +proc createMagic*(name: string, m: TMagic): PSym = + result = newSym(skProc, getIdent(name), nil, unknownLineInfo()) + result.magic = m + +let + opNot* = createMagic("not", mNot) + opContains* = createMagic("contains", mInSet) diff --git a/compiler/guards.nim b/compiler/guards.nim index fbdd16cb3..3255364c2 100644 --- a/compiler/guards.nim +++ b/compiler/guards.nim @@ -81,18 +81,12 @@ proc isLetLocation(m: PNode, isApprox: bool): bool = proc interestingCaseExpr*(m: PNode): bool = isLetLocation(m, true) -proc createMagic*(name: string, m: TMagic): PSym = - result = newSym(skProc, getIdent(name), nil, unknownLineInfo()) - result.magic = m - let opLe = createMagic("<=", mLeI) opLt = createMagic("<", mLtI) opAnd = createMagic("and", mAnd) opOr = createMagic("or", mOr) - opNot = createMagic("not", mNot) opIsNil = createMagic("isnil", mIsNil) - opContains = createMagic("contains", mInSet) opEq = createMagic("==", mEqI) opAdd = createMagic("+", mAddI) opSub = createMagic("-", mSubI) diff --git a/compiler/lowerings.nim b/compiler/lowerings.nim index a6527c2b4..0f670ae7a 100644 --- a/compiler/lowerings.nim +++ b/compiler/lowerings.nim @@ -13,7 +13,6 @@ const genPrefix* = ":tmp" # prefix for generated names import ast, astalgo, types, idents, magicsys, msgs, options -from guards import createMagic from trees import getMagic proc newTupleAccess*(tup: PNode, i: int): PNode = diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 51e5d6859..6638848df 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -884,7 +884,12 @@ proc isTypeExpr(n: PNode): bool = of nkType, nkTypeOfExpr: result = true of nkSym: result = n.sym.kind == skType else: result = false - + +proc createSetType(c: PContext; baseType: PType): PType = + assert baseType != nil + result = newTypeS(tySet, c) + rawAddSon(result, baseType) + proc lookupInRecordAndBuildCheck(c: PContext, n, r: PNode, field: PIdent, check: var PNode): PSym = # transform in a node that contains the runtime check for the @@ -900,41 +905,43 @@ proc lookupInRecordAndBuildCheck(c: PContext, n, r: PNode, field: PIdent, if (r.sons[0].kind != nkSym): illFormedAst(r) result = lookupInRecordAndBuildCheck(c, n, r.sons[0], field, check) if result != nil: return - var s = newNodeI(nkCurly, r.info) + let setType = createSetType(c, r.sons[0].typ) + var s = newNodeIT(nkCurly, r.info, setType) for i in countup(1, sonsLen(r) - 1): var it = r.sons[i] case it.kind - of nkOfBranch: + of nkOfBranch: result = lookupInRecordAndBuildCheck(c, n, lastSon(it), field, check) - if result == nil: + if result == nil: for j in 0..sonsLen(it)-2: addSon(s, copyTree(it.sons[j])) - else: - if check == nil: + else: + if check == nil: check = newNodeI(nkCheckedFieldExpr, n.info) addSon(check, ast.emptyNode) # make space for access node - s = newNodeI(nkCurly, n.info) + s = newNodeIT(nkCurly, n.info, setType) for j in countup(0, sonsLen(it) - 2): addSon(s, copyTree(it.sons[j])) - var inExpr = newNodeI(nkCall, n.info) - addSon(inExpr, newIdentNode(getIdent("in"), n.info)) + var inExpr = newNodeIT(nkCall, n.info, getSysType(tyBool)) + addSon(inExpr, newSymNode(ast.opContains, n.info)) + addSon(inExpr, s) addSon(inExpr, copyTree(r.sons[0])) - addSon(inExpr, s) #writeln(output, renderTree(inExpr)); - addSon(check, semExpr(c, inExpr)) - return - of nkElse: + addSon(check, inExpr) + #addSon(check, semExpr(c, inExpr)) + return + of nkElse: result = lookupInRecordAndBuildCheck(c, n, lastSon(it), field, check) - if result != nil: - if check == nil: + if result != nil: + if check == nil: check = newNodeI(nkCheckedFieldExpr, n.info) addSon(check, ast.emptyNode) # make space for access node - var inExpr = newNodeI(nkCall, n.info) - addSon(inExpr, newIdentNode(getIdent("in"), n.info)) - addSon(inExpr, copyTree(r.sons[0])) + var inExpr = newNodeIT(nkCall, n.info, getSysType(tyBool)) + addSon(inExpr, newSymNode(ast.opContains, n.info)) addSon(inExpr, s) - var notExpr = newNodeI(nkCall, n.info) - addSon(notExpr, newIdentNode(getIdent("not"), n.info)) + addSon(inExpr, copyTree(r.sons[0])) + var notExpr = newNodeIT(nkCall, n.info, getSysType(tyBool)) + addSon(notExpr, newSymNode(ast.opNot, n.info)) addSon(notExpr, inExpr) - addSon(check, semExpr(c, notExpr)) - return + addSon(check, notExpr) + return else: illFormedAst(it) of nkSym: if r.sym.name.id == field.id: result = r.sym @@ -1715,9 +1722,9 @@ proc semWhen(c: PContext, n: PNode, semCheck = true): PNode = proc semSetConstr(c: PContext, n: PNode): PNode = result = newNodeI(nkCurly, n.info) result.typ = newTypeS(tySet, c) - if sonsLen(n) == 0: + if sonsLen(n) == 0: rawAddSon(result.typ, newTypeS(tyEmpty, c)) - else: + else: # only semantic checking for all elements, later type checking: var typ: PType = nil for i in countup(0, sonsLen(n) - 1): |