Merge branch 'master' of github.com:Araq/Nimrod
This commit is contained in:
commit
635ad3b336
31 changed files with 460 additions and 331 deletions
|
|
@ -52,12 +52,12 @@ proc semAsm(con: PContext, n: PNode): PNode =
|
|||
proc semWhile(c: PContext, n: PNode): PNode =
|
||||
result = n
|
||||
checkSonsLen(n, 2)
|
||||
openScope(c.tab)
|
||||
openScope(c)
|
||||
n.sons[0] = forceBool(c, semExprWithType(c, n.sons[0]))
|
||||
inc(c.p.nestedLoopCounter)
|
||||
n.sons[1] = semStmt(c, n.sons[1])
|
||||
dec(c.p.nestedLoopCounter)
|
||||
closeScope(c.tab)
|
||||
closeScope(c)
|
||||
if n.sons[1].typ == EnforceVoidContext:
|
||||
result.typ = EnforceVoidContext
|
||||
|
||||
|
|
@ -103,9 +103,9 @@ proc semExprBranch(c: PContext, n: PNode): PNode =
|
|||
semDestructorCheck(c, result, {})
|
||||
|
||||
proc semExprBranchScope(c: PContext, n: PNode): PNode =
|
||||
openScope(c.tab)
|
||||
openScope(c)
|
||||
result = semExprBranch(c, n)
|
||||
closeScope(c.tab)
|
||||
closeScope(c)
|
||||
|
||||
const
|
||||
skipForDiscardable = {nkIfStmt, nkIfExpr, nkCaseStmt, nkOfBranch,
|
||||
|
|
@ -150,12 +150,12 @@ proc semIf(c: PContext, n: PNode): PNode =
|
|||
for i in countup(0, sonsLen(n) - 1):
|
||||
var it = n.sons[i]
|
||||
if it.len == 2:
|
||||
when newScopeForIf: openScope(c.tab)
|
||||
when newScopeForIf: openScope(c)
|
||||
it.sons[0] = forceBool(c, semExprWithType(c, it.sons[0]))
|
||||
when not newScopeForIf: openScope(c.tab)
|
||||
when not newScopeForIf: openScope(c)
|
||||
it.sons[1] = semExprBranch(c, it.sons[1])
|
||||
typ = commonType(typ, it.sons[1].typ)
|
||||
closeScope(c.tab)
|
||||
closeScope(c)
|
||||
elif it.len == 1:
|
||||
hasElse = true
|
||||
it.sons[0] = semExprBranchScope(c, it.sons[0])
|
||||
|
|
@ -176,7 +176,7 @@ proc semIf(c: PContext, n: PNode): PNode =
|
|||
proc semCase(c: PContext, n: PNode): PNode =
|
||||
result = n
|
||||
checkMinSonsLen(n, 2)
|
||||
openScope(c.tab)
|
||||
openScope(c)
|
||||
n.sons[0] = semExprWithType(c, n.sons[0])
|
||||
var chckCovered = false
|
||||
var covered: biggestint = 0
|
||||
|
|
@ -202,12 +202,12 @@ proc semCase(c: PContext, n: PNode): PNode =
|
|||
of nkElifBranch:
|
||||
chckCovered = false
|
||||
checkSonsLen(x, 2)
|
||||
when newScopeForIf: openScope(c.tab)
|
||||
when newScopeForIf: openScope(c)
|
||||
x.sons[0] = forceBool(c, semExprWithType(c, x.sons[0]))
|
||||
when not newScopeForIf: openScope(c.tab)
|
||||
when not newScopeForIf: openScope(c)
|
||||
x.sons[1] = semExprBranch(c, x.sons[1])
|
||||
typ = commonType(typ, x.sons[1].typ)
|
||||
closeScope(c.tab)
|
||||
closeScope(c)
|
||||
of nkElse:
|
||||
chckCovered = false
|
||||
checkSonsLen(x, 1)
|
||||
|
|
@ -221,7 +221,7 @@ proc semCase(c: PContext, n: PNode): PNode =
|
|||
hasElse = true
|
||||
else:
|
||||
localError(n.info, errNotAllCasesCovered)
|
||||
closeScope(c.tab)
|
||||
closeScope(c)
|
||||
if isEmptyType(typ) or typ.kind == tyNil or not hasElse:
|
||||
for i in 1..n.len-1: discardCheck(n.sons[i].lastSon)
|
||||
# propagate any enforced VoidContext:
|
||||
|
|
@ -289,8 +289,9 @@ proc fitRemoveHiddenConv(c: PContext, typ: Ptype, n: PNode): PNode =
|
|||
changeType(result, typ, check=false)
|
||||
|
||||
proc findShadowedVar(c: PContext, v: PSym): PSym =
|
||||
for i in countdown(c.tab.tos - 2, ModuleTablePos+1):
|
||||
let shadowed = StrTableGet(c.tab.stack[i], v.name)
|
||||
for scope in walkScopes(c.currentScope.parent):
|
||||
if scope == c.topLevelScope: break
|
||||
let shadowed = StrTableGet(scope.symbols, v.name)
|
||||
if shadowed != nil and shadowed.kind in skLocalVars:
|
||||
return shadowed
|
||||
|
||||
|
|
@ -472,12 +473,12 @@ proc semForObjectFields(c: TFieldsCtx, typ, forLoop, father: PNode) =
|
|||
var fc: TFieldInstCtx # either 'tup[i]' or 'field' is valid
|
||||
fc.field = typ.sym
|
||||
fc.replaceByFieldName = c.m == mFieldPairs
|
||||
openScope(c.c.tab)
|
||||
openScope(c.c)
|
||||
inc c.c.InUnrolledContext
|
||||
let body = instFieldLoopBody(fc, lastSon(forLoop), forLoop)
|
||||
father.add(SemStmt(c.c, body))
|
||||
dec c.c.InUnrolledContext
|
||||
closeScope(c.c.tab)
|
||||
closeScope(c.c)
|
||||
of nkNilLit: nil
|
||||
of nkRecCase:
|
||||
let L = forLoop.len
|
||||
|
|
@ -541,7 +542,7 @@ proc semForFields(c: PContext, n: PNode, m: TMagic): PNode =
|
|||
if tupleTypeA.kind == tyTuple:
|
||||
var loopBody = n.sons[length-1]
|
||||
for i in 0..sonsLen(tupleTypeA)-1:
|
||||
openScope(c.tab)
|
||||
openScope(c)
|
||||
var fc: TFieldInstCtx
|
||||
fc.tupleType = tupleTypeA
|
||||
fc.tupleIndex = i
|
||||
|
|
@ -550,7 +551,7 @@ proc semForFields(c: PContext, n: PNode, m: TMagic): PNode =
|
|||
inc c.InUnrolledContext
|
||||
stmts.add(SemStmt(c, body))
|
||||
dec c.InUnrolledContext
|
||||
closeScope(c.tab)
|
||||
closeScope(c)
|
||||
else:
|
||||
var fc: TFieldsCtx
|
||||
fc.m = m
|
||||
|
|
@ -618,7 +619,7 @@ proc semFor(c: PContext, n: PNode): PNode =
|
|||
result = n
|
||||
checkMinSonsLen(n, 3)
|
||||
var length = sonsLen(n)
|
||||
openScope(c.tab)
|
||||
openScope(c)
|
||||
n.sons[length-2] = semExprNoDeref(c, n.sons[length-2], {efWantIterator})
|
||||
var call = n.sons[length-2]
|
||||
if call.kind in nkCallKinds and call.sons[0].typ.callConv == ccClosure:
|
||||
|
|
@ -644,7 +645,7 @@ proc semFor(c: PContext, n: PNode): PNode =
|
|||
# propagate any enforced VoidContext:
|
||||
if n.sons[length-1].typ == EnforceVoidContext:
|
||||
result.typ = EnforceVoidContext
|
||||
closeScope(c.tab)
|
||||
closeScope(c)
|
||||
|
||||
proc semRaise(c: PContext, n: PNode): PNode =
|
||||
result = n
|
||||
|
|
@ -694,7 +695,7 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) =
|
|||
if a.sons[1].kind != nkEmpty:
|
||||
# We have a generic type declaration here. In generic types,
|
||||
# symbol lookup needs to be done here.
|
||||
openScope(c.tab)
|
||||
openScope(c)
|
||||
pushOwner(s)
|
||||
if s.magic == mNone: s.typ.kind = tyGenericBody
|
||||
# XXX for generic type aliases this is not correct! We need the
|
||||
|
|
@ -719,7 +720,7 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) =
|
|||
body.size = -1 # could not be computed properly
|
||||
s.typ.sons[sonsLen(s.typ) - 1] = body
|
||||
popOwner()
|
||||
closeScope(c.tab)
|
||||
closeScope(c)
|
||||
elif a.sons[2].kind != nkEmpty:
|
||||
# process the type's body:
|
||||
pushOwner(s)
|
||||
|
|
@ -776,7 +777,7 @@ proc addParams(c: PContext, n: PNode, kind: TSymKind) =
|
|||
|
||||
proc semBorrow(c: PContext, n: PNode, s: PSym) =
|
||||
# search for the correct alias:
|
||||
var b = SearchForBorrowProc(c, s, c.tab.tos - 2)
|
||||
var b = SearchForBorrowProc(c, c.currentScope.parent, s)
|
||||
if b != nil:
|
||||
# store the alias:
|
||||
n.sons[bodyPos] = newSymNode(b)
|
||||
|
|
@ -804,7 +805,7 @@ proc lookupMacro(c: PContext, n: PNode): PSym =
|
|||
result = n.sym
|
||||
if result.kind notin {skMacro, skTemplate}: result = nil
|
||||
else:
|
||||
result = SymtabGet(c.Tab, considerAcc(n), {skMacro, skTemplate})
|
||||
result = searchInScopes(c, considerAcc(n), {skMacro, skTemplate})
|
||||
|
||||
proc semProcAnnotation(c: PContext, prc: PNode): PNode =
|
||||
var n = prc.sons[pragmasPos]
|
||||
|
|
@ -839,7 +840,7 @@ proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
|||
else:
|
||||
s = n[namePos].sym
|
||||
pushOwner(s)
|
||||
openScope(c.tab)
|
||||
openScope(c)
|
||||
if n.sons[genericParamsPos].kind != nkEmpty:
|
||||
illFormedAst(n) # process parameters:
|
||||
if n.sons[paramsPos].kind != nkEmpty:
|
||||
|
|
@ -865,7 +866,7 @@ proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
|||
sideEffectsCheck(c, s)
|
||||
else:
|
||||
LocalError(n.info, errImplOfXexpected, s.name.s)
|
||||
closeScope(c.tab) # close scope for parameters
|
||||
closeScope(c) # close scope for parameters
|
||||
popOwner()
|
||||
result.typ = s.typ
|
||||
|
||||
|
|
@ -888,17 +889,48 @@ proc maybeAddResult(c: PContext, s: PSym, n: PNode) =
|
|||
addResult(c, s.typ.sons[0], n.info, s.kind)
|
||||
addResultNode(c, n)
|
||||
|
||||
proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
||||
validPragmas: TSpecialWords): PNode =
|
||||
type
|
||||
TProcCompilationSteps = enum
|
||||
stepRegisterSymbol,
|
||||
stepDetermineType,
|
||||
stepCompileBody
|
||||
|
||||
proc isForwardDecl(s: PSym): bool =
|
||||
InternalAssert s.kind == skProc
|
||||
result = s.ast[bodyPos].kind != nkEmpty
|
||||
|
||||
proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
||||
validPragmas: TSpecialWords,
|
||||
phase = stepRegisterSymbol): PNode =
|
||||
result = semProcAnnotation(c, n)
|
||||
if result != nil: return result
|
||||
result = n
|
||||
checkSonsLen(n, bodyPos + 1)
|
||||
var s = semIdentDef(c, n.sons[0], kind)
|
||||
n.sons[namePos] = newSymNode(s)
|
||||
s.ast = n
|
||||
var s: PSym
|
||||
var typeIsDetermined = false
|
||||
if n[namePos].kind != nkSym:
|
||||
assert phase == stepRegisterSymbol
|
||||
s = semIdentDef(c, n.sons[0], kind)
|
||||
n.sons[namePos] = newSymNode(s)
|
||||
s.ast = n
|
||||
s.scope = c.currentScope
|
||||
|
||||
if sfNoForward in c.module.flags and
|
||||
sfSystemModule notin c.module.flags:
|
||||
addInterfaceOverloadableSymAt(c, c.currentScope, s)
|
||||
s.flags.incl sfForward
|
||||
return
|
||||
else:
|
||||
s = n[namePos].sym
|
||||
typeIsDetermined = s.typ == nil
|
||||
# if typeIsDetermined: assert phase == stepCompileBody
|
||||
# else: assert phase == stepDetermineType
|
||||
# before compiling the proc body, set as current the scope
|
||||
# where the proc was declared
|
||||
let oldScope = c.currentScope
|
||||
c.currentScope = s.scope
|
||||
pushOwner(s)
|
||||
openScope(c.tab)
|
||||
openScope(c)
|
||||
var gp: PNode
|
||||
if n.sons[genericParamsPos].kind != nkEmpty:
|
||||
n.sons[genericParamsPos] = semGenericParamList(c, n.sons[genericParamsPos])
|
||||
|
|
@ -921,17 +953,17 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
|||
n.sons[patternPos] = semPattern(c, n.sons[patternPos])
|
||||
if s.kind == skIterator: s.typ.flags.incl(tfIterator)
|
||||
|
||||
var proto = SearchForProc(c, s, c.tab.tos-2) # -2 because we have a scope
|
||||
# open for parameters
|
||||
var proto = SearchForProc(c, s.scope, s)
|
||||
if proto == nil:
|
||||
s.typ.callConv = lastOptionEntry(c).defaultCC
|
||||
# add it here, so that recursive procs are possible:
|
||||
# -2 because we have a scope open for parameters
|
||||
if sfGenSym in s.flags: nil
|
||||
elif kind in OverloadableSyms:
|
||||
addInterfaceOverloadableSymAt(c, s, c.tab.tos - 2)
|
||||
else:
|
||||
addInterfaceDeclAt(c, s, c.tab.tos - 2)
|
||||
elif kind in OverloadableSyms:
|
||||
if not typeIsDetermined:
|
||||
addInterfaceOverloadableSymAt(c, s.scope, s)
|
||||
else:
|
||||
if not typeIsDetermined:
|
||||
addInterfaceDeclAt(c, s.scope, s)
|
||||
if n.sons[pragmasPos].kind != nkEmpty:
|
||||
pragma(c, s, n.sons[pragmasPos], validPragmas)
|
||||
else:
|
||||
|
|
@ -942,8 +974,8 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
|||
if sfForward notin proto.flags:
|
||||
WrongRedefinition(n.info, proto.name.s)
|
||||
excl(proto.flags, sfForward)
|
||||
closeScope(c.tab) # close scope with wrong parameter symbols
|
||||
openScope(c.tab) # open scope for old (correct) parameter symbols
|
||||
closeScope(c) # close scope with wrong parameter symbols
|
||||
openScope(c) # open scope for old (correct) parameter symbols
|
||||
if proto.ast.sons[genericParamsPos].kind != nkEmpty:
|
||||
addGenericParamListToScope(c, proto.ast.sons[genericParamsPos])
|
||||
addParams(c, proto.typ.n, proto.kind)
|
||||
|
|
@ -992,11 +1024,17 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
|||
incl(s.flags, sfForward)
|
||||
elif sfBorrow in s.flags: semBorrow(c, n, s)
|
||||
sideEffectsCheck(c, s)
|
||||
closeScope(c.tab) # close scope for parameters
|
||||
closeScope(c) # close scope for parameters
|
||||
c.currentScope = oldScope
|
||||
popOwner()
|
||||
if n.sons[patternPos].kind != nkEmpty:
|
||||
c.patterns.add(s)
|
||||
|
||||
|
||||
proc determineType(c: PContext, s: PSym) =
|
||||
if s.typ != nil: return
|
||||
#if s.magic != mNone: return
|
||||
discard semProcAux(c, s.ast, s.kind, {}, stepDetermineType)
|
||||
|
||||
proc semIterator(c: PContext, n: PNode): PNode =
|
||||
result = semProcAux(c, n, skIterator, iteratorPragmas)
|
||||
var s = result.sons[namePos].sym
|
||||
|
|
@ -1059,7 +1097,7 @@ proc semMacroDef(c: PContext, n: PNode): PNode =
|
|||
if n.sons[bodyPos].kind == nkEmpty:
|
||||
LocalError(n.info, errImplOfXexpected, s.name.s)
|
||||
|
||||
proc evalInclude(c: PContext, n: PNode): PNode =
|
||||
proc evalInclude(c: PContext, n: PNode): PNode =
|
||||
result = newNodeI(nkStmtList, n.info)
|
||||
addSon(result, n)
|
||||
for i in countup(0, sonsLen(n) - 1):
|
||||
|
|
@ -1183,6 +1221,6 @@ proc SemStmt(c: PContext, n: PNode): PNode =
|
|||
result = semExprNoType(c, n)
|
||||
|
||||
proc semStmtScope(c: PContext, n: PNode): PNode =
|
||||
openScope(c.tab)
|
||||
openScope(c)
|
||||
result = semStmt(c, n)
|
||||
closeScope(c.tab)
|
||||
closeScope(c)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue