diff options
author | Araq <rumpf_a@web.de> | 2012-10-31 02:31:03 +0100 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2012-10-31 02:31:03 +0100 |
commit | ce454fb835827ccefacad2acf79a90ca25560e5a (patch) | |
tree | 8de2d0c68625ac85a3a6028e87cf081ff445db04 | |
parent | 2133fbfccef934ae0f8ffafe0ecf4ef378e4cacf (diff) | |
download | Nim-ce454fb835827ccefacad2acf79a90ca25560e5a.tar.gz |
exception tracking barely works; but disabled
-rwxr-xr-x | compiler/magicsys.nim | 2 | ||||
-rw-r--r-- | compiler/sempass2.nim | 57 | ||||
-rwxr-xr-x | compiler/transf.nim | 3 | ||||
-rwxr-xr-x | todo.txt | 5 |
4 files changed, 40 insertions, 27 deletions
diff --git a/compiler/magicsys.nim b/compiler/magicsys.nim index 19d19b5f9..2681f93d6 100755 --- a/compiler/magicsys.nim +++ b/compiler/magicsys.nim @@ -41,7 +41,7 @@ proc getSysSym(name: string): PSym = if result == nil: rawMessage(errSystemNeeds, name) if result.kind == skStub: loadStub(result) -proc sysTypeFromName(name: string): PType = +proc sysTypeFromName*(name: string): PType = result = getSysSym(name).typ proc getSysType(kind: TTypeKind): PType = diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index 16a035839..bdc4e7028 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -8,7 +8,7 @@ # import - ast, astalgo, msgs, semdata + ast, astalgo, msgs, renderer, magicsys, types, idents, trees, wordrecg # Second semantic checking pass over the AST. Necessary because the old # way had some inherent problems. Performs: @@ -44,13 +44,14 @@ import # done: It essentially requires a built-in 'indexSplit' operation and dependent # typing. -proc sem2call(c: PContext, n: PNode): PNode = - assert n.kind in nkCallKinds - - +when false: + proc sem2call(c: PContext, n: PNode): PNode = + assert n.kind in nkCallKinds + + -proc sem2sym(c: PContext, n: PNode): PNode = - assert n.kind == nkSym + proc sem2sym(c: PContext, n: PNode): PNode = + assert n.kind == nkSym # ------------------------ exception tracking ------------------------------- @@ -96,13 +97,16 @@ proc excType(n: PNode): PType = else: n.sons[0].typ result = skipTypes(t, skipPtrs) -proc mergeEffects(a: PEffects, b: PNode) = +proc addEffect(a: PEffects, e: PNode) = + assert e.kind == nkRaiseStmt var aa = a.exc + for i in a.bottom .. <aa.len: + if sameType(aa[i].excType, e.excType) and aa[i].info == e.info: return + throws(a, e) + +proc mergeEffects(a: PEffects, b: PNode) = for effect in items(b): - block search - for i in a.bottom .. <aa.len: - if sameType(aa[i].excType, b.excType): break search - throws(a, effect) + addEffect(a, effect) proc listEffects(a: PEffects) = var aa = a.exc @@ -111,7 +115,7 @@ proc listEffects(a: PEffects) = proc catches(tracked: PEffects, e: PType) = let e = skipTypes(e, skipPtrs) - let L = tracked.exc.len + var L = tracked.exc.len var i = tracked.bottom while i < L: # e supertype of r? @@ -160,25 +164,29 @@ proc trackPragmaStmt(tracked: PEffects, n: PNode) = proc track(tracked: PEffects, n: PNode) = case n.kind of nkRaiseStmt: throws(tracked, n) - of nkCallNode: + of nkCallKinds: # p's effects are ours too: let op = n.sons[0].typ - InternalAssert op.kind == tyProc and op.n.sons[0].kind == nkEffectList - var effectList = op.n.sons[0] - if effectList.len == 0: - if isIndirectCall(n.sons[0]) or isForwardedProc(n.sons[0]): - # assume the worst: raise of exception 'E_Base': - var rs = newNodeI(nkRaiseStmt, n.info) - var re = newNodeIT(nkType, n.info, sysTypeFromName"E_Base") - rs.add(re) - effectList.add(rs) - mergeEffects(tracked, effectList) + if op != nil and op.kind == tyProc: + InternalAssert op.kind == tyProc and op.n.sons[0].kind == nkEffectList + var effectList = op.n.sons[0] + if effectList.len == 0: + if isIndirectCall(n.sons[0]) or isForwardedProc(n.sons[0]): + # assume the worst: raise of exception 'E_Base': + var rs = newNodeI(nkRaiseStmt, n.info) + var re = newNodeIT(nkType, n.info, sysTypeFromName"E_Base") + rs.add(re) + addEffect(tracked, rs) + else: + effectList = effectList.sons[exceptionEffects] + mergeEffects(tracked, effectList) of nkTryStmt: trackTryStmt(tracked, n) return of nkPragma: trackPragmaStmt(tracked, n) return + of nkMacroDef, nkTemplateDef: return else: nil for i in 0 .. <safeLen(n): track(tracked, n.sons[i]) @@ -189,6 +197,7 @@ proc trackProc*(s: PSym, body: PNode) = # effects already computed? if effects.len == effectListLen: return newSeq(effects.sons, effectListLen) + effects.sons[exceptionEffects] = newNodeI(nkArgList, body.info) var t: TEffects t.exc = effects.sons[exceptionEffects] diff --git a/compiler/transf.nim b/compiler/transf.nim index d1ee76cf1..a99041046 100755 --- a/compiler/transf.nim +++ b/compiler/transf.nim @@ -20,7 +20,7 @@ import intsets, strutils, lists, options, ast, astalgo, trees, treetab, msgs, os, idents, renderer, types, passes, semfold, magicsys, cgmeth, rodread, - lambdalifting + lambdalifting, sempass2 const genPrefix* = ":tmp" # prefix for generated names @@ -691,6 +691,7 @@ proc transformBody*(module: PSym, n: PNode, prc: PSym): PNode = if nfTransf in n.flags or prc.kind in {skTemplate, skMacro}: result = n else: + when false: trackProc(prc, n) var c = openTransf(module, "") result = processTransf(c, n) if prc.kind != skMacro: diff --git a/todo.txt b/todo.txt index ee2bd308c..b88eab249 100755 --- a/todo.txt +++ b/todo.txt @@ -1,6 +1,10 @@ version 0.9.2 ============= +- implement/generalize the effect system; checked exceptions +- overloading based on ASTs: 'constraint' should not be in PType but for the + parameter *symbol* + - document 'mixin' for generics and symbol lookup rules; special rule for ``[]=`` - implement the compiler as a service @@ -135,7 +139,6 @@ Version 2 and beyond troublesome, but maybe we can come up with a simple heuristic. (All procs that `new` shared memory are syncGC() candidates...) -- implement/generalize the effect system; checked exceptions - const ptr/ref - language change: inheritance should only work with reference types, so that |