This commit is contained in:
Araq 2015-01-28 18:58:05 +01:00
commit a4b2762249
6 changed files with 43 additions and 35 deletions

View file

@ -1568,3 +1568,11 @@ proc makeStmtList*(n: PNode): PNode =
else: else:
result = newNodeI(nkStmtList, n.info) result = newNodeI(nkStmtList, n.info)
result.add n 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)

View file

@ -81,18 +81,12 @@ proc isLetLocation(m: PNode, isApprox: bool): bool =
proc interestingCaseExpr*(m: PNode): bool = isLetLocation(m, true) 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 let
opLe = createMagic("<=", mLeI) opLe = createMagic("<=", mLeI)
opLt = createMagic("<", mLtI) opLt = createMagic("<", mLtI)
opAnd = createMagic("and", mAnd) opAnd = createMagic("and", mAnd)
opOr = createMagic("or", mOr) opOr = createMagic("or", mOr)
opNot = createMagic("not", mNot)
opIsNil = createMagic("isnil", mIsNil) opIsNil = createMagic("isnil", mIsNil)
opContains = createMagic("contains", mInSet)
opEq = createMagic("==", mEqI) opEq = createMagic("==", mEqI)
opAdd = createMagic("+", mAddI) opAdd = createMagic("+", mAddI)
opSub = createMagic("-", mSubI) opSub = createMagic("-", mSubI)

View file

@ -13,7 +13,6 @@ const
genPrefix* = ":tmp" # prefix for generated names genPrefix* = ":tmp" # prefix for generated names
import ast, astalgo, types, idents, magicsys, msgs, options import ast, astalgo, types, idents, magicsys, msgs, options
from guards import createMagic
from trees import getMagic from trees import getMagic
proc newTupleAccess*(tup: PNode, i: int): PNode = proc newTupleAccess*(tup: PNode, i: int): PNode =

View file

@ -884,7 +884,12 @@ proc isTypeExpr(n: PNode): bool =
of nkType, nkTypeOfExpr: result = true of nkType, nkTypeOfExpr: result = true
of nkSym: result = n.sym.kind == skType of nkSym: result = n.sym.kind == skType
else: result = false 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, proc lookupInRecordAndBuildCheck(c: PContext, n, r: PNode, field: PIdent,
check: var PNode): PSym = check: var PNode): PSym =
# transform in a node that contains the runtime check for the # 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) if (r.sons[0].kind != nkSym): illFormedAst(r)
result = lookupInRecordAndBuildCheck(c, n, r.sons[0], field, check) result = lookupInRecordAndBuildCheck(c, n, r.sons[0], field, check)
if result != nil: return 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): for i in countup(1, sonsLen(r) - 1):
var it = r.sons[i] var it = r.sons[i]
case it.kind case it.kind
of nkOfBranch: of nkOfBranch:
result = lookupInRecordAndBuildCheck(c, n, lastSon(it), field, check) 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])) for j in 0..sonsLen(it)-2: addSon(s, copyTree(it.sons[j]))
else: else:
if check == nil: if check == nil:
check = newNodeI(nkCheckedFieldExpr, n.info) check = newNodeI(nkCheckedFieldExpr, n.info)
addSon(check, ast.emptyNode) # make space for access node 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])) for j in countup(0, sonsLen(it) - 2): addSon(s, copyTree(it.sons[j]))
var inExpr = newNodeI(nkCall, n.info) var inExpr = newNodeIT(nkCall, n.info, getSysType(tyBool))
addSon(inExpr, newIdentNode(getIdent("in"), n.info)) addSon(inExpr, newSymNode(ast.opContains, n.info))
addSon(inExpr, s)
addSon(inExpr, copyTree(r.sons[0])) addSon(inExpr, copyTree(r.sons[0]))
addSon(inExpr, s) #writeln(output, renderTree(inExpr)); addSon(check, inExpr)
addSon(check, semExpr(c, inExpr)) #addSon(check, semExpr(c, inExpr))
return return
of nkElse: of nkElse:
result = lookupInRecordAndBuildCheck(c, n, lastSon(it), field, check) result = lookupInRecordAndBuildCheck(c, n, lastSon(it), field, check)
if result != nil: if result != nil:
if check == nil: if check == nil:
check = newNodeI(nkCheckedFieldExpr, n.info) check = newNodeI(nkCheckedFieldExpr, n.info)
addSon(check, ast.emptyNode) # make space for access node addSon(check, ast.emptyNode) # make space for access node
var inExpr = newNodeI(nkCall, n.info) var inExpr = newNodeIT(nkCall, n.info, getSysType(tyBool))
addSon(inExpr, newIdentNode(getIdent("in"), n.info)) addSon(inExpr, newSymNode(ast.opContains, n.info))
addSon(inExpr, copyTree(r.sons[0]))
addSon(inExpr, s) addSon(inExpr, s)
var notExpr = newNodeI(nkCall, n.info) addSon(inExpr, copyTree(r.sons[0]))
addSon(notExpr, newIdentNode(getIdent("not"), n.info)) var notExpr = newNodeIT(nkCall, n.info, getSysType(tyBool))
addSon(notExpr, newSymNode(ast.opNot, n.info))
addSon(notExpr, inExpr) addSon(notExpr, inExpr)
addSon(check, semExpr(c, notExpr)) addSon(check, notExpr)
return return
else: illFormedAst(it) else: illFormedAst(it)
of nkSym: of nkSym:
if r.sym.name.id == field.id: result = r.sym 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 = proc semSetConstr(c: PContext, n: PNode): PNode =
result = newNodeI(nkCurly, n.info) result = newNodeI(nkCurly, n.info)
result.typ = newTypeS(tySet, c) result.typ = newTypeS(tySet, c)
if sonsLen(n) == 0: if sonsLen(n) == 0:
rawAddSon(result.typ, newTypeS(tyEmpty, c)) rawAddSon(result.typ, newTypeS(tyEmpty, c))
else: else:
# only semantic checking for all elements, later type checking: # only semantic checking for all elements, later type checking:
var typ: PType = nil var typ: PType = nil
for i in countup(0, sonsLen(n) - 1): for i in countup(0, sonsLen(n) - 1):

View file

@ -1,13 +1,13 @@
The cross platform calculator illustrates how to use Nimrod to create a backend The cross platform calculator illustrates how to use Nim to create a backend
called by different native user interfaces. called by different native user interfaces.
Since the purpose of the example is to show how the cross platform code Since the purpose of the example is to show how the cross platform code
interacts with Nimrod the actual backend code is just a simple addition proc. interacts with Nimrod the actual backend code is just a simple addition proc.
By keeping your program logic in Nimrod you can easily reuse it in different By keeping your program logic in Nim you can easily reuse it in different
platforms. platforms.
To avoid duplication of code, the backend code lies in a separate directory and To avoid duplication of code, the backend code lies in a separate directory and
each platform compiles it with a different custom build process, usually each platform compiles it with a different custom build process, usually
generating C code in a temporary build directory. generating C code in a temporary build directory.
For a more ellaborate and useful example see the cross_todo example. For a more elaborate and useful example see the cross_todo example.

View file

@ -1,5 +1,5 @@
discard """ discard """
line: 2170 line: 2166
file: "system.nim" file: "system.nim"
errormsg: "can raise an unlisted exception: ref IOError" errormsg: "can raise an unlisted exception: ref IOError"
""" """