semstmts compiles again

This commit is contained in:
Andreas Rumpf 2018-05-12 19:45:19 +02:00
commit dd35111ff2
6 changed files with 192 additions and 198 deletions

View file

@ -185,7 +185,6 @@ errIntLiteralExpected: "integer literal expected",
errIdentifierExpected: "identifier expected, but found '$1'", errIdentifierExpected: "identifier expected, but found '$1'",
errNewlineExpected: "newline expected, but found '$1'", errNewlineExpected: "newline expected, but found '$1'",
errInvalidModuleName: "invalid module name: '$1'", errInvalidModuleName: "invalid module name: '$1'",
errRecursiveDependencyX: "recursive dependency: '$1'",
errOnOrOffExpected: "'on' or 'off' expected", errOnOrOffExpected: "'on' or 'off' expected",
errNoneSpeedOrSizeExpected: "'none', 'speed' or 'size' expected", errNoneSpeedOrSizeExpected: "'none', 'speed' or 'size' expected",
errInvalidPragma: "invalid pragma", errInvalidPragma: "invalid pragma",
@ -193,11 +192,7 @@ errUnknownPragma: "unknown pragma: '$1'",
errAtPopWithoutPush: "'pop' without a 'push' pragma", errAtPopWithoutPush: "'pop' without a 'push' pragma",
errEmptyAsm: "empty asm statement", errEmptyAsm: "empty asm statement",
errInvalidIndentation: "invalid indentation", errInvalidIndentation: "invalid indentation",
errExceptionAlreadyHandled: "exception already handled",
errYieldNotAllowedHere: "'yield' only allowed in an iterator",
errYieldNotAllowedInTryStmt: "'yield' cannot be used within 'try' in a non-inlined iterator",
errInvalidNumberOfYieldExpr: "invalid number of 'yield' expressions",
errCannotReturnExpr: "current routine cannot return an expression",
errNoReturnWithReturnTypeNotAllowed: "routines with NoReturn pragma are not allowed to have return type", errNoReturnWithReturnTypeNotAllowed: "routines with NoReturn pragma are not allowed to have return type",
errAttemptToRedefine: , errAttemptToRedefine: ,
errStmtInvalidAfterReturn: "statement not allowed after 'return', 'break', 'raise', 'continue' or proc call with noreturn pragma", errStmtInvalidAfterReturn: "statement not allowed after 'return', 'break', 'raise', 'continue' or proc call with noreturn pragma",
@ -261,13 +256,10 @@ errExprMustBeBool: "expression must be of type 'bool'",
errConstExprExpected: "constant expression expected", errConstExprExpected: "constant expression expected",
errDuplicateCaseLabel: "duplicate case label", errDuplicateCaseLabel: "duplicate case label",
errRangeIsEmpty: "range is empty", errRangeIsEmpty: "range is empty",
errSelectorMustBeOfCertainTypes: "selector must be of an ordinal type, float or string", ,
errSelectorMustBeOrdinal: "selector must be of an ordinal type", errSelectorMustBeOrdinal: "selector must be of an ordinal type",
errOrdXMustNotBeNegative: "ord($1) must not be negative", errOrdXMustNotBeNegative: "ord($1) must not be negative",
errLenXinvalid: "len($1) must be less than 32768", errLenXinvalid: "len($1) must be less than 32768",
errWrongNumberOfVariables: "wrong number of variables",
errExprCannotBeRaised: "only a 'ref object' can be raised",
errBreakOnlyInLoop: "'break' only allowed in loop construct",
errTypeXhasUnknownSize: "type '$1' has unknown size", errTypeXhasUnknownSize: "type '$1' has unknown size",
errConstNeedsConstExpr: "a constant can only be initialized with a constant expression", errConstNeedsConstExpr: "a constant can only be initialized with a constant expression",
errConstNeedsValue: "a constant needs a value", errConstNeedsValue: "a constant needs a value",
@ -288,11 +280,9 @@ errWrongNumberOfArguments: "wrong number of arguments",
errWrongNumberOfArgumentsInCall: "wrong number of arguments in call to '$1'", errWrongNumberOfArgumentsInCall: "wrong number of arguments in call to '$1'",
errMissingGenericParamsForTemplate: "'$1' has unspecified generic parameters", errMissingGenericParamsForTemplate: "'$1' has unspecified generic parameters",
errXCannotBePassedToProcVar: , errXCannotBePassedToProcVar: ,
errPragmaOnlyInHeaderOfProcX: "pragmas are only allowed in the header of a proc; redefinition of $1", ,
errImplOfXexpected: , errImplOfXexpected: ,
errNoSymbolToBorrowFromFound: "no symbol to borrow from found",
errDiscardValueX: "value of type '$1' has to be discarded",
errInvalidDiscard: "statement returns no value that can be discarded",
errIllegalConvFromXtoY: , errIllegalConvFromXtoY: ,
errCannotBindXTwice: "cannot bind parameter '$1' twice", errCannotBindXTwice: "cannot bind parameter '$1' twice",
errInvalidOrderInArrayConstructor: "invalid order in array constructor", errInvalidOrderInArrayConstructor: "invalid order in array constructor",
@ -315,7 +305,6 @@ errNoReturnTypeForX: "no return type allowed for $1",
errConvNeedsOneArg: "a type conversion needs exactly one argument", errConvNeedsOneArg: "a type conversion needs exactly one argument",
errInvalidPragmaX: , errInvalidPragmaX: ,
errXNotAllowedHere: "$1 not allowed here", errXNotAllowedHere: "$1 not allowed here",
errInvalidControlFlowX: "invalid control flow: $1",
errXisNoType: "invalid type: '$1'", errXisNoType: "invalid type: '$1'",
errCircumNeedsPointer: "'[]' needs a pointer or reference type", errCircumNeedsPointer: "'[]' needs a pointer or reference type",
errInvalidExpression: "invalid expression", errInvalidExpression: "invalid expression",
@ -325,7 +314,7 @@ errNamedExprExpected: "named expression expected",
errNamedExprNotAllowed: "named expression not allowed here", errNamedExprNotAllowed: "named expression not allowed here",
errNoCommand: "no command given", errNoCommand: "no command given",
errInvalidCommandX: "invalid command: '$1'", errInvalidCommandX: "invalid command: '$1'",
errXNeedsParamObjectType: "'$1' needs a parameter that has an object type", errXNeedsParamObjectType: ,
errTemplateInstantiationTooNested: "template instantiation too nested, try --evalTemplateLimit:N", errTemplateInstantiationTooNested: "template instantiation too nested, try --evalTemplateLimit:N",
errMacroInstantiationTooNested: "macro instantiation too nested, try --evalMacroLimit:N", errMacroInstantiationTooNested: "macro instantiation too nested, try --evalMacroLimit:N",
errInstantiationFrom: "template/generic instantiation from here", errInstantiationFrom: "template/generic instantiation from here",
@ -344,7 +333,7 @@ errXisNoValidIndexFile: "'$1' is no valid index file",
errCannotRenderX: "cannot render reStructuredText element '$1'", errCannotRenderX: "cannot render reStructuredText element '$1'",
errVarVarTypeNotAllowed: , errVarVarTypeNotAllowed: ,
errInstantiateXExplicitly: "instantiate '$1' explicitly", errInstantiateXExplicitly: "instantiate '$1' explicitly",
errOnlyACallOpCanBeDelegator: "only a call operator can be a delegator", errOnlyACallOpCanBeDelegator: ,
errUsingNoSymbol: "'$1' is not a variable, constant or a proc name", errUsingNoSymbol: "'$1' is not a variable, constant or a proc name",
errMacroBodyDependsOnGenericTypes: "the macro body cannot be compiled, " & errMacroBodyDependsOnGenericTypes: "the macro body cannot be compiled, " &
"because the parameter '$1' has a generic type", "because the parameter '$1' has a generic type",
@ -368,18 +357,9 @@ errUnhandledExceptionX: "unhandled exception: $1",
errCyclicTree: "macro returned a cyclic abstract syntax tree", errCyclicTree: "macro returned a cyclic abstract syntax tree",
errXisNoMacroOrTemplate: "'$1' is no macro or template", errXisNoMacroOrTemplate: "'$1' is no macro or template",
errXhasSideEffects: "'$1' can have side effects", errXhasSideEffects: "'$1' can have side effects",
errIteratorExpected: "iterator within for loop context expected",
errLetNeedsInit: "'let' symbol requires an initialization",
errThreadvarCannotInit: "a thread var cannot be initialized explicitly; this would only run for the main thread",
errWrongSymbolX:, errWrongSymbolX:,
errIllegalCaptureX: "illegal capture '$1'", errIllegalCaptureX: "illegal capture '$1'",
errXCannotBeClosure: "'$1' cannot have 'closure' calling convention", errXCannotBeClosure: "'$1' cannot have 'closure' calling convention",
errXMustBeCompileTime: "'$1' can only be used in compile-time context", errXMustBeCompileTime: "'$1' can only be used in compile-time context",
errCannotInferTypeOfTheLiteral: "cannot infer the type of the $1", ,
errCannotInferReturnType: "cannot infer the return type of the proc",
errCannotInferStaticParam: "cannot infer the value of the static param `$1`",
errGenericLambdaNotAllowed: "A nested proc can have generic parameters only when " &
"it is used as an operand to another routine and the types " &
"of the generic paramers can be inferred from the expected signature.",
errProcHasNoConcreteType: "'$1' doesn't have a concrete type, due to unspecified generic parameters.",
]# ]#

View file

@ -33,7 +33,7 @@ proc at(a, i: PNode, elemType: PType): PNode =
proc liftBodyTup(c: var TLiftCtx; t: PType; body, x, y: PNode) = proc liftBodyTup(c: var TLiftCtx; t: PType; body, x, y: PNode) =
for i in 0 ..< t.len: for i in 0 ..< t.len:
let lit = lowerings.newIntLit(i) let lit = lowerings.newIntLit(c.c.graph, x.info, i)
liftBodyAux(c, t.sons[i], body, x.at(lit, t.sons[i]), y.at(lit, t.sons[i])) liftBodyAux(c, t.sons[i], body, x.at(lit, t.sons[i]), y.at(lit, t.sons[i]))
proc dotField(x: PNode, f: PSym): PNode = proc dotField(x: PNode, f: PSym): PNode =
@ -66,15 +66,15 @@ proc liftBodyObj(c: var TLiftCtx; n, body, x, y: PNode) =
liftBodyObj(c, n[i].lastSon, branch.sons[L-1], x, y) liftBodyObj(c, n[i].lastSon, branch.sons[L-1], x, y)
caseStmt.add(branch) caseStmt.add(branch)
body.add(caseStmt) body.add(caseStmt)
localError(c.info, "cannot lift assignment operator to 'case' object") localError(c.c.config, c.info, "cannot lift assignment operator to 'case' object")
of nkRecList: of nkRecList:
for t in items(n): liftBodyObj(c, t, body, x, y) for t in items(n): liftBodyObj(c, t, body, x, y)
else: else:
illFormedAstLocal(n) illFormedAstLocal(n, c.c.config)
proc genAddr(c: PContext; x: PNode): PNode = proc genAddr(c: PContext; x: PNode): PNode =
if x.kind == nkHiddenDeref: if x.kind == nkHiddenDeref:
checkSonsLen(x, 1) checkSonsLen(x, 1, c.config)
result = x.sons[0] result = x.sons[0]
else: else:
result = newNodeIT(nkHiddenAddr, x.info, makeVarType(c, x.typ)) result = newNodeIT(nkHiddenAddr, x.info, makeVarType(c, x.typ))
@ -82,7 +82,7 @@ proc genAddr(c: PContext; x: PNode): PNode =
proc newAsgnCall(c: PContext; op: PSym; x, y: PNode): PNode = proc newAsgnCall(c: PContext; op: PSym; x, y: PNode): PNode =
if sfError in op.flags: if sfError in op.flags:
localError(x.info, errWrongSymbolX, op.name.s) localError(c.config, x.info, "usage of '$1' is a user-defined error" % op.name.s)
result = newNodeI(nkCall, x.info) result = newNodeI(nkCall, x.info)
result.add newSymNode(op) result.add newSymNode(op)
result.add genAddr(c, x) result.add genAddr(c, x)
@ -124,7 +124,7 @@ proc considerAsgnOrSink(c: var TLiftCtx; t: PType; body, x, y: PNode;
op = field op = field
if op == nil: if op == nil:
op = liftBody(c.c, t, c.kind, c.info) op = liftBody(c.c, t, c.kind, c.info)
markUsed(c.info, op, c.c.graph.usageSym) markUsed(c.c.config, c.info, op, c.c.graph.usageSym)
styleCheckUse(c.info, op) styleCheckUse(c.info, op)
body.add newAsgnCall(c.c, op, x, y) body.add newAsgnCall(c.c, op, x, y)
result = true result = true
@ -134,7 +134,7 @@ proc considerOverloadedOp(c: var TLiftCtx; t: PType; body, x, y: PNode): bool =
of attachedDestructor: of attachedDestructor:
let op = t.destructor let op = t.destructor
if op != nil: if op != nil:
markUsed(c.info, op, c.c.graph.usageSym) markUsed(c.c.config, c.info, op, c.c.graph.usageSym)
styleCheckUse(c.info, op) styleCheckUse(c.info, op)
body.add destructorCall(c.c, op, x) body.add destructorCall(c.c, op, x)
result = true result = true
@ -145,7 +145,7 @@ proc considerOverloadedOp(c: var TLiftCtx; t: PType; body, x, y: PNode): bool =
of attachedDeepCopy: of attachedDeepCopy:
let op = t.deepCopy let op = t.deepCopy
if op != nil: if op != nil:
markUsed(c.info, op, c.c.graph.usageSym) markUsed(c.c.config, c.info, op, c.c.graph.usageSym)
styleCheckUse(c.info, op) styleCheckUse(c.info, op)
body.add newDeepCopyCall(op, x, y) body.add newDeepCopyCall(op, x, y)
result = true result = true
@ -163,37 +163,37 @@ proc addVar(father, v, value: PNode) =
proc declareCounter(c: var TLiftCtx; body: PNode; first: BiggestInt): PNode = proc declareCounter(c: var TLiftCtx; body: PNode; first: BiggestInt): PNode =
var temp = newSym(skTemp, getIdent(lowerings.genPrefix), c.fn, c.info) var temp = newSym(skTemp, getIdent(lowerings.genPrefix), c.fn, c.info)
temp.typ = getSysType(tyInt) temp.typ = getSysType(c.c.graph, body.info, tyInt)
incl(temp.flags, sfFromGeneric) incl(temp.flags, sfFromGeneric)
var v = newNodeI(nkVarSection, c.info) var v = newNodeI(nkVarSection, c.info)
result = newSymNode(temp) result = newSymNode(temp)
v.addVar(result, lowerings.newIntLit(first)) v.addVar(result, lowerings.newIntLit(c.c.graph, body.info, first))
body.add v body.add v
proc genBuiltin(magic: TMagic; name: string; i: PNode): PNode = proc genBuiltin(g: ModuleGraph; magic: TMagic; name: string; i: PNode): PNode =
result = newNodeI(nkCall, i.info) result = newNodeI(nkCall, i.info)
result.add createMagic(name, magic).newSymNode result.add createMagic(g, name, magic).newSymNode
result.add i result.add i
proc genWhileLoop(c: var TLiftCtx; i, dest: PNode): PNode = proc genWhileLoop(c: var TLiftCtx; i, dest: PNode): PNode =
result = newNodeI(nkWhileStmt, c.info, 2) result = newNodeI(nkWhileStmt, c.info, 2)
let cmp = genBuiltin(mLeI, "<=", i) let cmp = genBuiltin(c.c.graph, mLeI, "<=", i)
cmp.add genHigh(dest) cmp.add genHigh(c.c.graph, dest)
cmp.typ = getSysType(tyBool) cmp.typ = getSysType(c.c.graph, c.info, tyBool)
result.sons[0] = cmp result.sons[0] = cmp
result.sons[1] = newNodeI(nkStmtList, c.info) result.sons[1] = newNodeI(nkStmtList, c.info)
proc addIncStmt(body, i: PNode) = proc addIncStmt(c: var TLiftCtx; body, i: PNode) =
let incCall = genBuiltin(mInc, "inc", i) let incCall = genBuiltin(c.c.graph, mInc, "inc", i)
incCall.add lowerings.newIntLit(1) incCall.add lowerings.newIntLit(c.c.graph, c.info, 1)
body.add incCall body.add incCall
proc newSeqCall(c: PContext; x, y: PNode): PNode = proc newSeqCall(c: PContext; x, y: PNode): PNode =
# don't call genAddr(c, x) here: # don't call genAddr(c, x) here:
result = genBuiltin(mNewSeq, "newSeq", x) result = genBuiltin(c.graph, mNewSeq, "newSeq", x)
let lenCall = genBuiltin(mLengthSeq, "len", y) let lenCall = genBuiltin(c.graph, mLengthSeq, "len", y)
lenCall.typ = getSysType(tyInt) lenCall.typ = getSysType(c.graph, x.info, tyInt)
result.add lenCall result.add lenCall
proc liftBodyAux(c: var TLiftCtx; t: PType; body, x, y: PNode) = proc liftBodyAux(c: var TLiftCtx; t: PType; body, x, y: PNode) =
@ -212,7 +212,7 @@ proc liftBodyAux(c: var TLiftCtx; t: PType; body, x, y: PNode) =
let elemType = t.lastSon let elemType = t.lastSon
liftBodyAux(c, elemType, whileLoop.sons[1], x.at(i, elemType), liftBodyAux(c, elemType, whileLoop.sons[1], x.at(i, elemType),
y.at(i, elemType)) y.at(i, elemType))
addIncStmt(whileLoop.sons[1], i) addIncStmt(c, whileLoop.sons[1], i)
body.add whileLoop body.add whileLoop
else: else:
defaultOp(c, t, body, x, y) defaultOp(c, t, body, x, y)
@ -231,20 +231,20 @@ proc liftBodyAux(c: var TLiftCtx; t: PType; body, x, y: PNode) =
# have to go through some indirection; we delegate this to the codegen: # have to go through some indirection; we delegate this to the codegen:
let call = newNodeI(nkCall, c.info, 2) let call = newNodeI(nkCall, c.info, 2)
call.typ = t call.typ = t
call.sons[0] = newSymNode(createMagic("deepCopy", mDeepCopy)) call.sons[0] = newSymNode(createMagic(c.c.graph, "deepCopy", mDeepCopy))
call.sons[1] = y call.sons[1] = y
body.add newAsgnStmt(x, call) body.add newAsgnStmt(x, call)
of tyVarargs, tyOpenArray: of tyVarargs, tyOpenArray:
localError(c.info, errGenerated, "cannot copy openArray") localError(c.c.config, c.info, "cannot copy openArray")
of tyFromExpr, tyProxy, tyBuiltInTypeClass, tyUserTypeClass, of tyFromExpr, tyProxy, tyBuiltInTypeClass, tyUserTypeClass,
tyUserTypeClassInst, tyCompositeTypeClass, tyAnd, tyOr, tyNot, tyAnything, tyUserTypeClassInst, tyCompositeTypeClass, tyAnd, tyOr, tyNot, tyAnything,
tyGenericParam, tyGenericBody, tyNil, tyExpr, tyStmt, tyGenericParam, tyGenericBody, tyNil, tyExpr, tyStmt,
tyTypeDesc, tyGenericInvocation, tyForward: tyTypeDesc, tyGenericInvocation, tyForward:
internalError(c.info, "assignment requested for type: " & typeToString(t)) internalError(c.c.config, c.info, "assignment requested for type: " & typeToString(t))
of tyOrdinal, tyRange, tyInferred, of tyOrdinal, tyRange, tyInferred,
tyGenericInst, tyStatic, tyVar, tyLent, tyAlias, tySink: tyGenericInst, tyStatic, tyVar, tyLent, tyAlias, tySink:
liftBodyAux(c, lastSon(t), body, x, y) liftBodyAux(c, lastSon(t), body, x, y)
of tyUnused, tyOptAsRef: internalError("liftBodyAux") of tyUnused, tyOptAsRef: internalError(c.c.config, "liftBodyAux")
proc newProcType(info: TLineInfo; owner: PSym): PType = proc newProcType(info: TLineInfo; owner: PSym): PType =
result = newType(tyProc, owner) result = newType(tyProc, owner)

View file

@ -215,7 +215,7 @@ proc semConv(c: PContext, n: PNode): PNode =
elif op.kind in {nkPar, nkTupleConstr} and targetType.kind == tyTuple: elif op.kind in {nkPar, nkTupleConstr} and targetType.kind == tyTuple:
op = fitNode(c, targetType, op, result.info) op = fitNode(c, targetType, op, result.info)
of convNotNeedeed: of convNotNeedeed:
message(n.info, hintConvFromXtoItselfNotNeeded, result.typ.typeToString) message(c.config, n.info, hintConvFromXtoItselfNotNeeded, result.typ.typeToString)
of convNotLegal: of convNotLegal:
result = fitNode(c, result.typ, result.sons[1], result.info) result = fitNode(c, result.typ, result.sons[1], result.info)
if result == nil: if result == nil:
@ -1494,7 +1494,7 @@ proc semProcBody(c: PContext, n: PNode): PNode =
# nil # nil
# # comment # # comment
# are not expressions: # are not expressions:
fixNilType(result) fixNilType(c, result)
else: else:
var a = newNodeI(nkAsgn, n.info, 2) var a = newNodeI(nkAsgn, n.info, 2)
a.sons[0] = newSymNode(c.p.resultSym) a.sons[0] = newSymNode(c.p.resultSym)
@ -2264,7 +2264,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
result.kind = nkCall result.kind = nkCall
result = semExpr(c, result, flags) result = semExpr(c, result, flags)
of nkBind: of nkBind:
message(n.info, warnDeprecated, "bind") message(c.config, n.info, warnDeprecated, "bind")
result = semExpr(c, n.sons[0], flags) result = semExpr(c, n.sons[0], flags)
of nkTypeOfExpr, nkTupleTy, nkTupleClassTy, nkRefTy..nkEnumTy, nkStaticTy: of nkTypeOfExpr, nkTupleTy, nkTupleClassTy, nkRefTy..nkEnumTy, nkStaticTy:
if c.matchedConcept != nil and n.len == 1: if c.matchedConcept != nil and n.len == 1:

View file

@ -16,16 +16,17 @@ type
tupleIndex: int tupleIndex: int
field: PSym field: PSym
replaceByFieldName: bool replaceByFieldName: bool
c: PContext
proc instFieldLoopBody(c: TFieldInstCtx, n: PNode, forLoop: PNode): PNode = proc instFieldLoopBody(c: TFieldInstCtx, n: PNode, forLoop: PNode): PNode =
case n.kind case n.kind
of nkEmpty..pred(nkIdent), succ(nkSym)..nkNilLit: result = n of nkEmpty..pred(nkIdent), succ(nkSym)..nkNilLit: result = n
of nkIdent, nkSym: of nkIdent, nkSym:
result = n result = n
let ident = considerQuotedIdent(n) let ident = considerQuotedIdent(c.c.config, n)
var L = sonsLen(forLoop) var L = sonsLen(forLoop)
if c.replaceByFieldName: if c.replaceByFieldName:
if ident.id == considerQuotedIdent(forLoop[0]).id: if ident.id == considerQuotedIdent(c.c.config, forLoop[0]).id:
let fieldName = if c.tupleType.isNil: c.field.name.s let fieldName = if c.tupleType.isNil: c.field.name.s
elif c.tupleType.n.isNil: "Field" & $c.tupleIndex elif c.tupleType.n.isNil: "Field" & $c.tupleIndex
else: c.tupleType.n.sons[c.tupleIndex].sym.name.s else: c.tupleType.n.sons[c.tupleIndex].sym.name.s
@ -33,7 +34,7 @@ proc instFieldLoopBody(c: TFieldInstCtx, n: PNode, forLoop: PNode): PNode =
return return
# other fields: # other fields:
for i in ord(c.replaceByFieldName)..L-3: for i in ord(c.replaceByFieldName)..L-3:
if ident.id == considerQuotedIdent(forLoop[i]).id: if ident.id == considerQuotedIdent(c.c.config, forLoop[i]).id:
var call = forLoop.sons[L-2] var call = forLoop.sons[L-2]
var tupl = call.sons[i+1-ord(c.replaceByFieldName)] var tupl = call.sons[i+1-ord(c.replaceByFieldName)]
if c.field.isNil: if c.field.isNil:
@ -47,7 +48,7 @@ proc instFieldLoopBody(c: TFieldInstCtx, n: PNode, forLoop: PNode): PNode =
break break
else: else:
if n.kind == nkContinueStmt: if n.kind == nkContinueStmt:
localError(c.config, n.info, errGenerated, localError(c.c.config, n.info,
"'continue' not supported in a 'fields' loop") "'continue' not supported in a 'fields' loop")
result = copyNode(n) result = copyNode(n)
newSons(result, sonsLen(n)) newSons(result, sonsLen(n))
@ -63,6 +64,7 @@ proc semForObjectFields(c: TFieldsCtx, typ, forLoop, father: PNode) =
case typ.kind case typ.kind
of nkSym: of nkSym:
var fc: TFieldInstCtx # either 'tup[i]' or 'field' is valid var fc: TFieldInstCtx # either 'tup[i]' or 'field' is valid
fc.c = c.c
fc.field = typ.sym fc.field = typ.sym
fc.replaceByFieldName = c.m == mFieldPairs fc.replaceByFieldName = c.m == mFieldPairs
openScope(c.c) openScope(c.c)
@ -76,7 +78,7 @@ proc semForObjectFields(c: TFieldsCtx, typ, forLoop, father: PNode) =
let L = forLoop.len let L = forLoop.len
let call = forLoop.sons[L-2] let call = forLoop.sons[L-2]
if call.len > 2: if call.len > 2:
localError(c.config, forLoop.info, errGenerated, localError(c.c.config, forLoop.info,
"parallel 'fields' iterator does not work for 'case' objects") "parallel 'fields' iterator does not work for 'case' objects")
return return
# iterate over the selector: # iterate over the selector:
@ -99,17 +101,17 @@ proc semForObjectFields(c: TFieldsCtx, typ, forLoop, father: PNode) =
of nkRecList: of nkRecList:
for t in items(typ): semForObjectFields(c, t, forLoop, father) for t in items(typ): semForObjectFields(c, t, forLoop, father)
else: else:
illFormedAstLocal(typ) illFormedAstLocal(typ, c.c.config)
proc semForFields(c: PContext, n: PNode, m: TMagic): PNode = proc semForFields(c: PContext, n: PNode, m: TMagic): PNode =
# so that 'break' etc. work as expected, we produce # so that 'break' etc. work as expected, we produce
# a 'while true: stmt; break' loop ... # a 'while true: stmt; break' loop ...
result = newNodeI(nkWhileStmt, n.info, 2) result = newNodeI(nkWhileStmt, n.info, 2)
var trueSymbol = strTableGet(magicsys.systemModule.tab, getIdent"true") var trueSymbol = strTableGet(c.graph.systemModule.tab, getIdent"true")
if trueSymbol == nil: if trueSymbol == nil:
localError(c.config, n.info, errSystemNeeds, "true") localError(c.config, n.info, "system needs: 'true'")
trueSymbol = newSym(skUnknown, getIdent"true", getCurrOwner(c), n.info) trueSymbol = newSym(skUnknown, getIdent"true", getCurrOwner(c), n.info)
trueSymbol.typ = getSysType(tyBool) trueSymbol.typ = getSysType(c.graph, n.info, tyBool)
result.sons[0] = newSymNode(trueSymbol, n.info) result.sons[0] = newSymNode(trueSymbol, n.info)
var stmts = newNodeI(nkStmtList, n.info) var stmts = newNodeI(nkStmtList, n.info)
@ -129,7 +131,7 @@ proc semForFields(c: PContext, n: PNode, m: TMagic): PNode =
for i in 1..call.len-1: for i in 1..call.len-1:
var tupleTypeB = skipTypes(call.sons[i].typ, skippedTypesForFields) var tupleTypeB = skipTypes(call.sons[i].typ, skippedTypesForFields)
if not sameType(tupleTypeA, tupleTypeB): if not sameType(tupleTypeA, tupleTypeB):
typeMismatch(call.sons[i].info, tupleTypeA, tupleTypeB) typeMismatch(c.config, call.sons[i].info, tupleTypeA, tupleTypeB)
inc(c.p.nestedLoopCounter) inc(c.p.nestedLoopCounter)
if tupleTypeA.kind == tyTuple: if tupleTypeA.kind == tyTuple:
@ -139,6 +141,7 @@ proc semForFields(c: PContext, n: PNode, m: TMagic): PNode =
var fc: TFieldInstCtx var fc: TFieldInstCtx
fc.tupleType = tupleTypeA fc.tupleType = tupleTypeA
fc.tupleIndex = i fc.tupleIndex = i
fc.c = c
fc.replaceByFieldName = m == mFieldPairs fc.replaceByFieldName = m == mFieldPairs
var body = instFieldLoopBody(fc, loopBody, n) var body = instFieldLoopBody(fc, loopBody, n)
inc c.inUnrolledContext inc c.inUnrolledContext

View file

@ -17,13 +17,13 @@
# included from sem.nim # included from sem.nim
proc getIdentNode(n: PNode): PNode = proc getIdentNode(c: PContext; n: PNode): PNode =
case n.kind case n.kind
of nkPostfix: result = getIdentNode(n.sons[1]) of nkPostfix: result = getIdentNode(c, n.sons[1])
of nkPragmaExpr: result = getIdentNode(n.sons[0]) of nkPragmaExpr: result = getIdentNode(c, n.sons[0])
of nkIdent, nkAccQuoted, nkSym: result = n of nkIdent, nkAccQuoted, nkSym: result = n
else: else:
illFormedAst(n) illFormedAst(n, c.config)
result = n result = n
type type
@ -103,8 +103,8 @@ proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym,
proc lookup(c: PContext, n: PNode, flags: TSemGenericFlags, proc lookup(c: PContext, n: PNode, flags: TSemGenericFlags,
ctx: var GenericCtx): PNode = ctx: var GenericCtx): PNode =
result = n result = n
let ident = considerQuotedIdent(n) let ident = considerQuotedIdent(c.config, n)
var s = searchInScopes(c, ident).skipAlias(n) var s = searchInScopes(c, ident).skipAlias(n, c.config)
if s == nil: if s == nil:
s = strTableGet(c.pureEnumFields, ident) s = strTableGet(c.pureEnumFields, ident)
if s != nil and contains(c.ambiguousSymbols, s.id): if s != nil and contains(c.ambiguousSymbols, s.id):
@ -140,8 +140,8 @@ proc fuzzyLookup(c: PContext, n: PNode, flags: TSemGenericFlags,
n.sons[0] = semGenericStmt(c, n.sons[0], flags, ctx) n.sons[0] = semGenericStmt(c, n.sons[0], flags, ctx)
result = n result = n
let n = n[1] let n = n[1]
let ident = considerQuotedIdent(n) let ident = considerQuotedIdent(c.config, n)
var s = searchInScopes(c, ident).skipAlias(n) var s = searchInScopes(c, ident).skipAlias(n, c.config)
if s != nil and s.kind in routineKinds: if s != nil and s.kind in routineKinds:
isMacro = s.kind in {skTemplate, skMacro} isMacro = s.kind in {skTemplate, skMacro}
if withinBind in flags: if withinBind in flags:
@ -158,7 +158,7 @@ proc fuzzyLookup(c: PContext, n: PNode, flags: TSemGenericFlags,
result = newDot(result, syms) result = newDot(result, syms)
proc addTempDecl(c: PContext; n: PNode; kind: TSymKind) = proc addTempDecl(c: PContext; n: PNode; kind: TSymKind) =
let s = newSymS(skUnknown, getIdentNode(n), c) let s = newSymS(skUnknown, getIdentNode(c, n), c)
addPrelimDecl(c, s) addPrelimDecl(c, s)
styleCheckDef(n.info, s, kind) styleCheckDef(n.info, s, kind)
@ -201,13 +201,13 @@ proc semGenericStmt(c: PContext, n: PNode,
result = semMixinStmt(c, n, ctx.toMixin) result = semMixinStmt(c, n, ctx.toMixin)
of nkCall, nkHiddenCallConv, nkInfix, nkPrefix, nkCommand, nkCallStrLit: of nkCall, nkHiddenCallConv, nkInfix, nkPrefix, nkCommand, nkCallStrLit:
# check if it is an expression macro: # check if it is an expression macro:
checkMinSonsLen(n, 1) checkMinSonsLen(n, 1, c.config)
let fn = n.sons[0] let fn = n.sons[0]
var s = qualifiedLookUp(c, fn, {}) var s = qualifiedLookUp(c, fn, {})
if s == nil and if s == nil and
{withinMixin, withinConcept}*flags == {} and {withinMixin, withinConcept}*flags == {} and
fn.kind in {nkIdent, nkAccQuoted} and fn.kind in {nkIdent, nkAccQuoted} and
considerQuotedIdent(fn).id notin ctx.toMixin: considerQuotedIdent(c.config, fn).id notin ctx.toMixin:
errorUndeclaredIdentifier(c, n.info, fn.renderTree) errorUndeclaredIdentifier(c, n.info, fn.renderTree)
var first = int ord(withinConcept in flags) var first = int ord(withinConcept in flags)
@ -285,7 +285,7 @@ proc semGenericStmt(c: PContext, n: PNode,
withBracketExpr ctx, n.sons[0]: withBracketExpr ctx, n.sons[0]:
result = semGenericStmt(c, result, flags, ctx) result = semGenericStmt(c, result, flags, ctx)
of nkAsgn, nkFastAsgn: of nkAsgn, nkFastAsgn:
checkSonsLen(n, 2) checkSonsLen(n, 2, c.config)
let a = n.sons[0] let a = n.sons[0]
let b = n.sons[1] let b = n.sons[1]
@ -323,7 +323,7 @@ proc semGenericStmt(c: PContext, n: PNode,
n.sons[0] = semGenericStmt(c, n.sons[0], flags, ctx) n.sons[0] = semGenericStmt(c, n.sons[0], flags, ctx)
for i in countup(1, sonsLen(n)-1): for i in countup(1, sonsLen(n)-1):
var a = n.sons[i] var a = n.sons[i]
checkMinSonsLen(a, 1) checkMinSonsLen(a, 1, c.config)
var L = sonsLen(a) var L = sonsLen(a)
for j in countup(0, L-2): for j in countup(0, L-2):
a.sons[j] = semGenericStmt(c, a.sons[j], flags, ctx) a.sons[j] = semGenericStmt(c, a.sons[j], flags, ctx)
@ -340,23 +340,23 @@ proc semGenericStmt(c: PContext, n: PNode,
closeScope(c) closeScope(c)
closeScope(c) closeScope(c)
of nkBlockStmt, nkBlockExpr, nkBlockType: of nkBlockStmt, nkBlockExpr, nkBlockType:
checkSonsLen(n, 2) checkSonsLen(n, 2, c.config)
openScope(c) openScope(c)
if n.sons[0].kind != nkEmpty: if n.sons[0].kind != nkEmpty:
addTempDecl(c, n.sons[0], skLabel) addTempDecl(c, n.sons[0], skLabel)
n.sons[1] = semGenericStmt(c, n.sons[1], flags, ctx) n.sons[1] = semGenericStmt(c, n.sons[1], flags, ctx)
closeScope(c) closeScope(c)
of nkTryStmt: of nkTryStmt:
checkMinSonsLen(n, 2) checkMinSonsLen(n, 2, c.config)
n.sons[0] = semGenericStmtScope(c, n.sons[0], flags, ctx) n.sons[0] = semGenericStmtScope(c, n.sons[0], flags, ctx)
for i in countup(1, sonsLen(n)-1): for i in countup(1, sonsLen(n)-1):
var a = n.sons[i] var a = n.sons[i]
checkMinSonsLen(a, 1) checkMinSonsLen(a, 1, c.config)
var L = sonsLen(a) var L = sonsLen(a)
openScope(c) openScope(c)
for j in countup(0, L-2): for j in countup(0, L-2):
if a.sons[j].isInfixAs(): if a.sons[j].isInfixAs():
addTempDecl(c, getIdentNode(a.sons[j][2]), skLet) addTempDecl(c, getIdentNode(c, a.sons[j][2]), skLet)
a.sons[j].sons[1] = semGenericStmt(c, a.sons[j][1], flags+{withinTypeDesc}, ctx) a.sons[j].sons[1] = semGenericStmt(c, a.sons[j][1], flags+{withinTypeDesc}, ctx)
else: else:
a.sons[j] = semGenericStmt(c, a.sons[j], flags+{withinTypeDesc}, ctx) a.sons[j] = semGenericStmt(c, a.sons[j], flags+{withinTypeDesc}, ctx)
@ -367,44 +367,44 @@ proc semGenericStmt(c: PContext, n: PNode,
for i in countup(0, sonsLen(n) - 1): for i in countup(0, sonsLen(n) - 1):
var a = n.sons[i] var a = n.sons[i]
if a.kind == nkCommentStmt: continue if a.kind == nkCommentStmt: continue
if (a.kind != nkIdentDefs) and (a.kind != nkVarTuple): illFormedAst(a) if (a.kind != nkIdentDefs) and (a.kind != nkVarTuple): illFormedAst(a, c.config)
checkMinSonsLen(a, 3) checkMinSonsLen(a, 3, c.config)
var L = sonsLen(a) var L = sonsLen(a)
a.sons[L-2] = semGenericStmt(c, a.sons[L-2], flags+{withinTypeDesc}, ctx) a.sons[L-2] = semGenericStmt(c, a.sons[L-2], flags+{withinTypeDesc}, ctx)
a.sons[L-1] = semGenericStmt(c, a.sons[L-1], flags, ctx) a.sons[L-1] = semGenericStmt(c, a.sons[L-1], flags, ctx)
for j in countup(0, L-3): for j in countup(0, L-3):
addTempDecl(c, getIdentNode(a.sons[j]), skVar) addTempDecl(c, getIdentNode(c, a.sons[j]), skVar)
of nkGenericParams: of nkGenericParams:
for i in countup(0, sonsLen(n) - 1): for i in countup(0, sonsLen(n) - 1):
var a = n.sons[i] var a = n.sons[i]
if (a.kind != nkIdentDefs): illFormedAst(a) if (a.kind != nkIdentDefs): illFormedAst(a, c.config)
checkMinSonsLen(a, 3) checkMinSonsLen(a, 3, c.config)
var L = sonsLen(a) var L = sonsLen(a)
a.sons[L-2] = semGenericStmt(c, a.sons[L-2], flags+{withinTypeDesc}, ctx) a.sons[L-2] = semGenericStmt(c, a.sons[L-2], flags+{withinTypeDesc}, ctx)
# do not perform symbol lookup for default expressions # do not perform symbol lookup for default expressions
for j in countup(0, L-3): for j in countup(0, L-3):
addTempDecl(c, getIdentNode(a.sons[j]), skType) addTempDecl(c, getIdentNode(c, a.sons[j]), skType)
of nkConstSection: of nkConstSection:
for i in countup(0, sonsLen(n) - 1): for i in countup(0, sonsLen(n) - 1):
var a = n.sons[i] var a = n.sons[i]
if a.kind == nkCommentStmt: continue if a.kind == nkCommentStmt: continue
if (a.kind != nkConstDef): illFormedAst(a) if (a.kind != nkConstDef): illFormedAst(a, c.config)
checkSonsLen(a, 3) checkSonsLen(a, 3, c.config)
addTempDecl(c, getIdentNode(a.sons[0]), skConst) addTempDecl(c, getIdentNode(c, a.sons[0]), skConst)
a.sons[1] = semGenericStmt(c, a.sons[1], flags+{withinTypeDesc}, ctx) a.sons[1] = semGenericStmt(c, a.sons[1], flags+{withinTypeDesc}, ctx)
a.sons[2] = semGenericStmt(c, a.sons[2], flags, ctx) a.sons[2] = semGenericStmt(c, a.sons[2], flags, ctx)
of nkTypeSection: of nkTypeSection:
for i in countup(0, sonsLen(n) - 1): for i in countup(0, sonsLen(n) - 1):
var a = n.sons[i] var a = n.sons[i]
if a.kind == nkCommentStmt: continue if a.kind == nkCommentStmt: continue
if (a.kind != nkTypeDef): illFormedAst(a) if (a.kind != nkTypeDef): illFormedAst(a, c.config)
checkSonsLen(a, 3) checkSonsLen(a, 3, c.config)
addTempDecl(c, getIdentNode(a.sons[0]), skType) addTempDecl(c, getIdentNode(c, a.sons[0]), skType)
for i in countup(0, sonsLen(n) - 1): for i in countup(0, sonsLen(n) - 1):
var a = n.sons[i] var a = n.sons[i]
if a.kind == nkCommentStmt: continue if a.kind == nkCommentStmt: continue
if (a.kind != nkTypeDef): illFormedAst(a) if (a.kind != nkTypeDef): illFormedAst(a, c.config)
checkSonsLen(a, 3) checkSonsLen(a, 3, c.config)
if a.sons[1].kind != nkEmpty: if a.sons[1].kind != nkEmpty:
openScope(c) openScope(c)
a.sons[1] = semGenericStmt(c, a.sons[1], flags, ctx) a.sons[1] = semGenericStmt(c, a.sons[1], flags, ctx)
@ -421,28 +421,28 @@ proc semGenericStmt(c: PContext, n: PNode,
case n.sons[i].kind case n.sons[i].kind
of nkEnumFieldDef: a = n.sons[i].sons[0] of nkEnumFieldDef: a = n.sons[i].sons[0]
of nkIdent: a = n.sons[i] of nkIdent: a = n.sons[i]
else: illFormedAst(n) else: illFormedAst(n, c.config)
addDecl(c, newSymS(skUnknown, getIdentNode(a), c)) addDecl(c, newSymS(skUnknown, getIdentNode(c, a), c))
of nkObjectTy, nkTupleTy, nkTupleClassTy: of nkObjectTy, nkTupleTy, nkTupleClassTy:
discard discard
of nkFormalParams: of nkFormalParams:
checkMinSonsLen(n, 1) checkMinSonsLen(n, 1, c.config)
if n.sons[0].kind != nkEmpty: if n.sons[0].kind != nkEmpty:
n.sons[0] = semGenericStmt(c, n.sons[0], flags+{withinTypeDesc}, ctx) n.sons[0] = semGenericStmt(c, n.sons[0], flags+{withinTypeDesc}, ctx)
for i in countup(1, sonsLen(n) - 1): for i in countup(1, sonsLen(n) - 1):
var a = n.sons[i] var a = n.sons[i]
if (a.kind != nkIdentDefs): illFormedAst(a) if (a.kind != nkIdentDefs): illFormedAst(a, c.config)
checkMinSonsLen(a, 3) checkMinSonsLen(a, 3, c.config)
var L = sonsLen(a) var L = sonsLen(a)
a.sons[L-2] = semGenericStmt(c, a.sons[L-2], flags+{withinTypeDesc}, ctx) a.sons[L-2] = semGenericStmt(c, a.sons[L-2], flags+{withinTypeDesc}, ctx)
a.sons[L-1] = semGenericStmt(c, a.sons[L-1], flags, ctx) a.sons[L-1] = semGenericStmt(c, a.sons[L-1], flags, ctx)
for j in countup(0, L-3): for j in countup(0, L-3):
addTempDecl(c, getIdentNode(a.sons[j]), skParam) addTempDecl(c, getIdentNode(c, a.sons[j]), skParam)
of nkProcDef, nkMethodDef, nkConverterDef, nkMacroDef, nkTemplateDef, of nkProcDef, nkMethodDef, nkConverterDef, nkMacroDef, nkTemplateDef,
nkFuncDef, nkIteratorDef, nkLambdaKinds: nkFuncDef, nkIteratorDef, nkLambdaKinds:
checkSonsLen(n, bodyPos + 1) checkSonsLen(n, bodyPos + 1, c.config)
if n.sons[namePos].kind != nkEmpty: if n.sons[namePos].kind != nkEmpty:
addTempDecl(c, getIdentNode(n.sons[0]), skProc) addTempDecl(c, getIdentNode(c, n.sons[0]), skProc)
openScope(c) openScope(c)
n.sons[genericParamsPos] = semGenericStmt(c, n.sons[genericParamsPos], n.sons[genericParamsPos] = semGenericStmt(c, n.sons[genericParamsPos],
flags, ctx) flags, ctx)
@ -463,7 +463,7 @@ proc semGenericStmt(c: PContext, n: PNode,
closeScope(c) closeScope(c)
of nkPragma, nkPragmaExpr: discard of nkPragma, nkPragmaExpr: discard
of nkExprColonExpr, nkExprEqExpr: of nkExprColonExpr, nkExprEqExpr:
checkMinSonsLen(n, 2) checkMinSonsLen(n, 2, c.config)
result.sons[1] = semGenericStmt(c, n.sons[1], flags, ctx) result.sons[1] = semGenericStmt(c, n.sons[1], flags, ctx)
else: else:
for i in countup(0, sonsLen(n) - 1): for i in countup(0, sonsLen(n) - 1):

View file

@ -10,7 +10,33 @@
## this module does the semantic checking of statements ## this module does the semantic checking of statements
# included from sem.nim # included from sem.nim
var enforceVoidContext = PType(kind: tyStmt) const
errNoSymbolToBorrowFromFound = "no symbol to borrow from found"
errDiscardValueX = "value of type '$1' has to be discarded"
errInvalidDiscard = "statement returns no value that can be discarded"
errInvalidControlFlowX = "invalid control flow: $1"
errSelectorMustBeOfCertainTypes = "selector must be of an ordinal type, float or string"
errExprCannotBeRaised = "only a 'ref object' can be raised"
errBreakOnlyInLoop = "'break' only allowed in loop construct"
errExceptionAlreadyHandled = "exception already handled"
errYieldNotAllowedHere = "'yield' only allowed in an iterator"
errYieldNotAllowedInTryStmt = "'yield' cannot be used within 'try' in a non-inlined iterator"
errInvalidNumberOfYieldExpr = "invalid number of 'yield' expressions"
errCannotReturnExpr = "current routine cannot return an expression"
errGenericLambdaNotAllowed = "A nested proc can have generic parameters only when " &
"it is used as an operand to another routine and the types " &
"of the generic paramers can be inferred from the expected signature."
errCannotInferTypeOfTheLiteral = "cannot infer the type of the $1"
errCannotInferReturnType = "cannot infer the return type of the proc"
errCannotInferStaticParam = "cannot infer the value of the static param '$1'"
errProcHasNoConcreteType = "'$1' doesn't have a concrete type, due to unspecified generic parameters."
errLetNeedsInit = "'let' symbol requires an initialization"
errThreadvarCannotInit = "a thread var cannot be initialized explicitly; this would only run for the main thread"
errImplOfXexpected = "implementation of '$1' expected"
errRecursiveDependencyX = "recursive dependency: '$1'"
errPragmaOnlyInHeaderOfProcX = "pragmas are only allowed in the header of a proc; redefinition of $1"
var enforceVoidContext = PType(kind: tyStmt) # XXX global variable here
proc semDiscard(c: PContext, n: PNode): PNode = proc semDiscard(c: PContext, n: PNode): PNode =
result = n result = n
@ -39,18 +65,18 @@ proc semBreakOrContinue(c: PContext, n: PNode): PNode =
suggestSym(x.info, s, c.graph.usageSym) suggestSym(x.info, s, c.graph.usageSym)
styleCheckUse(x.info, s) styleCheckUse(x.info, s)
else: else:
localError(c.config, n.info, errInvalidControlFlowX, s.name.s) localError(c.config, n.info, errInvalidControlFlowX % s.name.s)
else: else:
localError(c.config, n.info, errGenerated, "'continue' cannot have a label") localError(c.config, n.info, errGenerated, "'continue' cannot have a label")
elif (c.p.nestedLoopCounter <= 0) and (c.p.nestedBlockCounter <= 0): elif (c.p.nestedLoopCounter <= 0) and (c.p.nestedBlockCounter <= 0):
localError(c.config, n.info, errInvalidControlFlowX, localError(c.config, n.info, errInvalidControlFlowX %
renderTree(n, {renderNoComments})) renderTree(n, {renderNoComments}))
proc semAsm(con: PContext, n: PNode): PNode = proc semAsm(c: PContext, n: PNode): PNode =
checkSonsLen(n, 2, c.config) checkSonsLen(n, 2, c.config)
var marker = pragmaAsm(con, n.sons[0]) var marker = pragmaAsm(c, n.sons[0])
if marker == '\0': marker = '`' # default marker if marker == '\0': marker = '`' # default marker
result = semAsmOrEmit(con, n, marker) result = semAsmOrEmit(c, n, marker)
proc semWhile(c: PContext, n: PNode): PNode = proc semWhile(c: PContext, n: PNode): PNode =
result = n result = n
@ -95,13 +121,13 @@ proc implicitlyDiscardable(n: PNode): bool =
result = isCallExpr(n) and n.sons[0].kind == nkSym and result = isCallExpr(n) and n.sons[0].kind == nkSym and
sfDiscardable in n.sons[0].sym.flags sfDiscardable in n.sons[0].sym.flags
proc fixNilType(n: PNode) = proc fixNilType(c: PContext; n: PNode) =
if isAtom(n): if isAtom(n):
if n.kind != nkNilLit and n.typ != nil: if n.kind != nkNilLit and n.typ != nil:
localError(c.config, n.info, errDiscardValueX, n.typ.typeToString) localError(c.config, n.info, errDiscardValueX % n.typ.typeToString)
elif n.kind in {nkStmtList, nkStmtListExpr}: elif n.kind in {nkStmtList, nkStmtListExpr}:
n.kind = nkStmtList n.kind = nkStmtList
for it in n: fixNilType(it) for it in n: fixNilType(c, it)
n.typ = nil n.typ = nil
proc discardCheck(c: PContext, result: PNode) = proc discardCheck(c: PContext, result: PNode) =
@ -207,7 +233,7 @@ proc semCase(c: PContext, n: PNode): PNode =
if covered == toCover(n.sons[0].typ): if covered == toCover(n.sons[0].typ):
hasElse = true hasElse = true
else: else:
localError(c.config, n.info, errNotAllCasesCovered) localError(c.config, n.info, "not all cases covered")
closeScope(c) closeScope(c)
if isEmptyType(typ) or typ.kind in {tyNil, tyExpr} or not hasElse: if isEmptyType(typ) or typ.kind in {tyNil, tyExpr} or not hasElse:
for i in 1..n.len-1: discardCheck(c, n.sons[i].lastSon) for i in 1..n.len-1: discardCheck(c, n.sons[i].lastSon)
@ -339,16 +365,16 @@ proc semIdentDef(c: PContext, n: PNode, kind: TSymKind): PSym =
result = semIdentWithPragma(c, kind, n, {}) result = semIdentWithPragma(c, kind, n, {})
if result.owner.kind == skModule: if result.owner.kind == skModule:
incl(result.flags, sfGlobal) incl(result.flags, sfGlobal)
suggestSym(c.config, n.info, result, c.graph.usageSym) suggestSym(n.info, result, c.graph.usageSym)
styleCheckDef(result) styleCheckDef(result)
proc checkNilable(v: PSym) = proc checkNilable(c: PContext; v: PSym) =
if {sfGlobal, sfImportC} * v.flags == {sfGlobal} and if {sfGlobal, sfImportC} * v.flags == {sfGlobal} and
{tfNotNil, tfNeedsInit} * v.typ.flags != {}: {tfNotNil, tfNeedsInit} * v.typ.flags != {}:
if v.ast.isNil: if v.ast.isNil:
message(v.info, warnProveInit, v.name.s) message(c.config, v.info, warnProveInit, v.name.s)
elif tfNotNil in v.typ.flags and tfNotNil notin v.ast.typ.flags: elif tfNotNil in v.typ.flags and tfNotNil notin v.ast.typ.flags:
message(v.info, warnProveInit, v.name.s) message(c.config, v.info, warnProveInit, v.name.s)
include semasgn include semasgn
@ -369,7 +395,7 @@ proc isDiscardUnderscore(v: PSym): bool =
proc semUsing(c: PContext; n: PNode): PNode = proc semUsing(c: PContext; n: PNode): PNode =
result = ast.emptyNode result = ast.emptyNode
if not isTopLevel(c): localError(c.config, n.info, errXOnlyAtModuleScope, "using") if not isTopLevel(c): localError(c.config, n.info, errXOnlyAtModuleScope % "using")
for i in countup(0, sonsLen(n)-1): for i in countup(0, sonsLen(n)-1):
var a = n.sons[i] var a = n.sons[i]
if gCmd == cmdIdeTools: suggestStmt(c, a) if gCmd == cmdIdeTools: suggestStmt(c, a)
@ -432,7 +458,7 @@ proc fillPartialObject(c: PContext; n: PNode; typ: PType) =
else: else:
localError(c.config, n.info, "nkDotNode requires 2 children") localError(c.config, n.info, "nkDotNode requires 2 children")
proc setVarType(v: PSym, typ: PType) = proc setVarType(c: PContext; v: PSym, typ: PType) =
if v.typ != nil and not sameTypeOrNil(v.typ, typ): if v.typ != nil and not sameTypeOrNil(v.typ, typ):
localError(c.config, v.info, "inconsistent typing for reintroduced symbol '" & localError(c.config, v.info, "inconsistent typing for reintroduced symbol '" &
v.name.s & "': previous type was: " & typeToString(v.typ) & v.name.s & "': previous type was: " & typeToString(v.typ) &
@ -476,16 +502,16 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
if typ.kind in tyUserTypeClasses and typ.isResolvedUserTypeClass: if typ.kind in tyUserTypeClasses and typ.isResolvedUserTypeClass:
typ = typ.lastSon typ = typ.lastSon
if hasEmpty(typ): if hasEmpty(typ):
localError(c.config, def.info, errCannotInferTypeOfTheLiteral, localError(c.config, def.info, errCannotInferTypeOfTheLiteral %
($typ.kind).substr(2).toLowerAscii) ($typ.kind).substr(2).toLowerAscii)
elif typ.kind == tyProc and tfUnresolved in typ.flags: elif typ.kind == tyProc and tfUnresolved in typ.flags:
localError(c.config, def.info, errProcHasNoConcreteType, def.renderTree) localError(c.config, def.info, errProcHasNoConcreteType % def.renderTree)
else: else:
if symkind == skLet: localError(c.config, a.info, errLetNeedsInit) if symkind == skLet: localError(c.config, a.info, errLetNeedsInit)
# this can only happen for errornous var statements: # this can only happen for errornous var statements:
if typ == nil: continue if typ == nil: continue
typeAllowedCheck(a.info, typ, symkind, if c.matchedConcept != nil: {taConcept} else: {}) typeAllowedCheck(c.config, a.info, typ, symkind, if c.matchedConcept != nil: {taConcept} else: {})
liftTypeBoundOps(c, typ, a.info) liftTypeBoundOps(c, typ, a.info)
var tup = skipTypes(typ, {tyGenericInst, tyAlias, tySink}) var tup = skipTypes(typ, {tyGenericInst, tyAlias, tySink})
if a.kind == nkVarTuple: if a.kind == nkVarTuple:
@ -500,7 +526,7 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
addToVarSection(c, result, n, b) addToVarSection(c, result, n, b)
elif tup.kind == tyTuple and def.kind in {nkPar, nkTupleConstr} and elif tup.kind == tyTuple and def.kind in {nkPar, nkTupleConstr} and
a.kind == nkIdentDefs and a.len > 3: a.kind == nkIdentDefs and a.len > 3:
message(a.info, warnEachIdentIsTuple) message(c.config, a.info, warnEachIdentIsTuple)
for j in countup(0, length-3): for j in countup(0, length-3):
if a[j].kind == nkDotExpr: if a[j].kind == nkDotExpr:
@ -518,17 +544,17 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
if shadowed != nil: if shadowed != nil:
shadowed.flags.incl(sfShadowed) shadowed.flags.incl(sfShadowed)
if shadowed.kind == skResult and sfGenSym notin v.flags: if shadowed.kind == skResult and sfGenSym notin v.flags:
message(a.info, warnResultShadowed) message(c.config, a.info, warnResultShadowed)
# a shadowed variable is an error unless it appears on the right # a shadowed variable is an error unless it appears on the right
# side of the '=': # side of the '=':
if warnShadowIdent in gNotes and not identWithin(def, v.name): if warnShadowIdent in c.config.notes and not identWithin(def, v.name):
message(a.info, warnShadowIdent, v.name.s) message(c.config, a.info, warnShadowIdent, v.name.s)
if a.kind != nkVarTuple: if a.kind != nkVarTuple:
if def.kind != nkEmpty: if def.kind != nkEmpty:
# this is needed for the evaluation pass and for the guard checking: # this is needed for the evaluation pass and for the guard checking:
v.ast = def v.ast = def
if sfThread in v.flags: localError(c.config, def.info, errThreadvarCannotInit) if sfThread in v.flags: localError(c.config, def.info, errThreadvarCannotInit)
setVarType(v, typ) setVarType(c, v, typ)
b = newNodeI(nkIdentDefs, a.info) b = newNodeI(nkIdentDefs, a.info)
if importantComments(c.config): if importantComments(c.config):
# keep documentation information: # keep documentation information:
@ -540,13 +566,13 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
else: else:
if def.kind in {nkPar, nkTupleConstr}: v.ast = def[j] if def.kind in {nkPar, nkTupleConstr}: v.ast = def[j]
# bug #7663, for 'nim check' this can be a non-tuple: # bug #7663, for 'nim check' this can be a non-tuple:
if tup.kind == tyTuple: setVarType(v, tup.sons[j]) if tup.kind == tyTuple: setVarType(c, v, tup.sons[j])
else: v.typ = tup else: v.typ = tup
b.sons[j] = newSymNode(v) b.sons[j] = newSymNode(v)
checkNilable(v) checkNilable(c, v)
if sfCompileTime in v.flags: hasCompileTime = true if sfCompileTime in v.flags: hasCompileTime = true
if hasCompileTime: if hasCompileTime:
vm.setupCompileTimeVar(c.module, c.cache, c.graph.config, result) vm.setupCompileTimeVar(c.module, c.cache, c.graph, result)
proc semConst(c: PContext, n: PNode): PNode = proc semConst(c: PContext, n: PNode): PNode =
result = copyNode(n) result = copyNode(n)
@ -575,11 +601,11 @@ proc semConst(c: PContext, n: PNode): PNode =
if typeAllowed(typ, skConst) != nil and def.kind != nkNilLit: if typeAllowed(typ, skConst) != nil and def.kind != nkNilLit:
localError(c.config, a.info, "invalid type for const: " & typeToString(typ)) localError(c.config, a.info, "invalid type for const: " & typeToString(typ))
continue continue
setVarType(v, typ) setVarType(c, v, typ)
v.ast = def # no need to copy v.ast = def # no need to copy
if sfGenSym notin v.flags: addInterfaceDecl(c, v) if sfGenSym notin v.flags: addInterfaceDecl(c, v)
var b = newNodeI(nkConstDef, a.info) var b = newNodeI(nkConstDef, a.info)
if importantComments(): b.comment = a.comment if importantComments(c.config): b.comment = a.comment
addSon(b, newSymNode(v)) addSon(b, newSymNode(v))
addSon(b, a.sons[1]) addSon(b, a.sons[1])
addSon(b, copyTree(def)) addSon(b, copyTree(def))
@ -588,12 +614,12 @@ proc semConst(c: PContext, n: PNode): PNode =
include semfields include semfields
proc addForVarDecl(c: PContext, v: PSym) = proc addForVarDecl(c: PContext, v: PSym) =
if warnShadowIdent in gNotes: if warnShadowIdent in c.config.notes:
let shadowed = findShadowedVar(c, v) let shadowed = findShadowedVar(c, v)
if shadowed != nil: if shadowed != nil:
# XXX should we do this here? # XXX should we do this here?
#shadowed.flags.incl(sfShadowed) #shadowed.flags.incl(sfShadowed)
message(v.info, warnShadowIdent, v.name.s) message(c.config, v.info, warnShadowIdent, v.name.s)
addDecl(c, v) addDecl(c, v)
proc symForVar(c: PContext, n: PNode): PSym = proc symForVar(c: PContext, n: PNode): PSym =
@ -658,7 +684,7 @@ proc handleForLoopMacro(c: PContext; n: PNode): PNode =
# n := for a, b, c in m(x, y, z): Y # n := for a, b, c in m(x, y, z): Y
# to # to
# m(n) # m(n)
let forLoopStmt = magicsys.getCompilerProc("ForLoopStmt") let forLoopStmt = magicsys.getCompilerProc(c.graph, "ForLoopStmt")
if forLoopStmt == nil: return if forLoopStmt == nil: return
let headSymbol = iterExpr[0] let headSymbol = iterExpr[0]
@ -715,7 +741,7 @@ proc semFor(c: PContext, n: PNode): PNode =
elif length == 4: elif length == 4:
n.sons[length-2] = implicitIterator(c, "pairs", n.sons[length-2]) n.sons[length-2] = implicitIterator(c, "pairs", n.sons[length-2])
else: else:
localError(c.config, n.sons[length-2].info, errIteratorExpected) localError(c.config, n.sons[length-2].info, "iterator within for loop context expected")
result = semForVars(c, n) result = semForVars(c, n)
else: else:
result = semForVars(c, n) result = semForVars(c, n)
@ -744,7 +770,7 @@ proc addGenericParamListToScope(c: PContext, n: PNode) =
if a.kind == nkSym: addDecl(c, a.sym) if a.kind == nkSym: addDecl(c, a.sym)
else: illFormedAst(a, c.config) else: illFormedAst(a, c.config)
proc typeSectionTypeName(n: PNode): PNode = proc typeSectionTypeName(c: PContext; n: PNode): PNode =
if n.kind == nkPragmaExpr: if n.kind == nkPragmaExpr:
if n.len == 0: illFormedAst(n, c.config) if n.len == 0: illFormedAst(n, c.config)
result = n.sons[0] result = n.sons[0]
@ -818,14 +844,12 @@ proc typeSectionLeftSidePass(c: PContext, n: PNode) =
else: else:
a.sons[0] = newSymNode(s) a.sons[0] = newSymNode(s)
proc checkCovariantParamsUsages(genericType: PType) = proc checkCovariantParamsUsages(c: PContext; genericType: PType) =
var body = genericType[^1] var body = genericType[^1]
proc traverseSubTypes(t: PType): bool = proc traverseSubTypes(c: PContext; t: PType): bool =
template error(msg) = localError(c.config, genericType.sym.info, msg) template error(msg) = localError(c.config, genericType.sym.info, msg)
result = false result = false
template subresult(r) = template subresult(r) =
let sub = r let sub = r
result = result or sub result = result or sub
@ -834,24 +858,19 @@ proc checkCovariantParamsUsages(genericType: PType) =
of tyGenericParam: of tyGenericParam:
t.flags.incl tfWeakCovariant t.flags.incl tfWeakCovariant
return true return true
of tyObject: of tyObject:
for field in t.n: for field in t.n:
subresult traverseSubTypes(field.typ) subresult traverseSubTypes(c, field.typ)
of tyArray: of tyArray:
return traverseSubTypes(t[1]) return traverseSubTypes(c, t[1])
of tyProc: of tyProc:
for subType in t.sons: for subType in t.sons:
if subType != nil: if subType != nil:
subresult traverseSubTypes(subType) subresult traverseSubTypes(c, subType)
if result: if result:
error("non-invariant type param used in a proc type: " & $t) error("non-invariant type param used in a proc type: " & $t)
of tySequence: of tySequence:
return traverseSubTypes(t[0]) return traverseSubTypes(c, t[0])
of tyGenericInvocation: of tyGenericInvocation:
let targetBody = t[0] let targetBody = t[0]
for i in 1 ..< t.len: for i in 1 ..< t.len:
@ -872,32 +891,24 @@ proc checkCovariantParamsUsages(genericType: PType) =
"' used in a non-contravariant position") "' used in a non-contravariant position")
result = true result = true
else: else:
subresult traverseSubTypes(param) subresult traverseSubTypes(c, param)
of tyAnd, tyOr, tyNot, tyStatic, tyBuiltInTypeClass, tyCompositeTypeClass: of tyAnd, tyOr, tyNot, tyStatic, tyBuiltInTypeClass, tyCompositeTypeClass:
error("non-invariant type parameters cannot be used with types such '" & $t & "'") error("non-invariant type parameters cannot be used with types such '" & $t & "'")
of tyUserTypeClass, tyUserTypeClassInst: of tyUserTypeClass, tyUserTypeClassInst:
error("non-invariant type parameters are not supported in concepts") error("non-invariant type parameters are not supported in concepts")
of tyTuple: of tyTuple:
for fieldType in t.sons: for fieldType in t.sons:
subresult traverseSubTypes(fieldType) subresult traverseSubTypes(c, fieldType)
of tyPtr, tyRef, tyVar, tyLent: of tyPtr, tyRef, tyVar, tyLent:
if t.base.kind == tyGenericParam: return true if t.base.kind == tyGenericParam: return true
return traverseSubTypes(t.base) return traverseSubTypes(c, t.base)
of tyDistinct, tyAlias, tySink: of tyDistinct, tyAlias, tySink:
return traverseSubTypes(t.lastSon) return traverseSubTypes(c, t.lastSon)
of tyGenericInst: of tyGenericInst:
internalAssert false internalAssert c.config, false
else: else:
discard discard
discard traverseSubTypes(c, body)
discard traverseSubTypes(body)
proc typeSectionRightSidePass(c: PContext, n: PNode) = proc typeSectionRightSidePass(c: PContext, n: PNode) =
for i in countup(0, sonsLen(n) - 1): for i in countup(0, sonsLen(n) - 1):
@ -905,10 +916,10 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) =
if a.kind == nkCommentStmt: continue if a.kind == nkCommentStmt: continue
if a.kind != nkTypeDef: illFormedAst(a, c.config) if a.kind != nkTypeDef: illFormedAst(a, c.config)
checkSonsLen(a, 3, c.config) checkSonsLen(a, 3, c.config)
let name = typeSectionTypeName(a.sons[0]) let name = typeSectionTypeName(c, a.sons[0])
var s = name.sym var s = name.sym
if s.magic == mNone and a.sons[2].kind == nkEmpty: if s.magic == mNone and a.sons[2].kind == nkEmpty:
localError(c.config, a.info, errImplOfXexpected, s.name.s) localError(c.config, a.info, errImplOfXexpected % s.name.s)
if s.magic != mNone: processMagicType(c, s) if s.magic != mNone: processMagicType(c, s)
if a.sons[1].kind != nkEmpty: if a.sons[1].kind != nkEmpty:
# We have a generic type declaration here. In generic types, # We have a generic type declaration here. In generic types,
@ -939,7 +950,7 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) =
body.size = -1 # could not be computed properly body.size = -1 # could not be computed properly
s.typ.sons[sonsLen(s.typ) - 1] = body s.typ.sons[sonsLen(s.typ) - 1] = body
if tfCovariant in s.typ.flags: if tfCovariant in s.typ.flags:
checkCovariantParamsUsages(s.typ) checkCovariantParamsUsages(c, s.typ)
# XXX: This is a temporary limitation: # XXX: This is a temporary limitation:
# The codegen currently produces various failures with # The codegen currently produces various failures with
# generic imported types that have fields, but we need # generic imported types that have fields, but we need
@ -974,8 +985,8 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) =
# give anonymous object a dummy symbol: # give anonymous object a dummy symbol:
var st = s.typ var st = s.typ
if st.kind == tyGenericBody: st = st.lastSon if st.kind == tyGenericBody: st = st.lastSon
internalAssert st.kind in {tyPtr, tyRef} internalAssert c.config, st.kind in {tyPtr, tyRef}
internalAssert st.lastSon.sym == nil internalAssert c.config, st.lastSon.sym == nil
incl st.flags, tfRefsAnonObj incl st.flags, tfRefsAnonObj
let obj = newSym(skType, getIdent(s.name.s & ":ObjectType"), let obj = newSym(skType, getIdent(s.name.s & ":ObjectType"),
getCurrOwner(c), s.info) getCurrOwner(c), s.info)
@ -983,17 +994,17 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) =
st.lastSon.sym = obj st.lastSon.sym = obj
proc checkForMetaFields(n: PNode) = proc checkForMetaFields(c: PContext; n: PNode) =
template checkMeta(t) = template checkMeta(t) =
if t != nil and t.isMetaType and tfGenericTypeParam notin t.flags: if t != nil and t.isMetaType and tfGenericTypeParam notin t.flags:
localError(c.config, n.info, errTIsNotAConcreteType, t.typeToString) localError(c.config, n.info, errTIsNotAConcreteType % t.typeToString)
if n.isNil: return if n.isNil: return
case n.kind case n.kind
of nkRecList, nkRecCase: of nkRecList, nkRecCase:
for s in n: checkForMetaFields(s) for s in n: checkForMetaFields(c, s)
of nkOfBranch, nkElse: of nkOfBranch, nkElse:
checkForMetaFields(n.lastSon) checkForMetaFields(c, n.lastSon)
of nkSym: of nkSym:
let t = n.sym.typ let t = n.sym.typ
case t.kind case t.kind
@ -1005,13 +1016,13 @@ proc checkForMetaFields(n: PNode) =
else: else:
checkMeta(t) checkMeta(t)
else: else:
internalAssert false internalAssert c.config, false
proc typeSectionFinalPass(c: PContext, n: PNode) = proc typeSectionFinalPass(c: PContext, n: PNode) =
for i in countup(0, sonsLen(n) - 1): for i in countup(0, sonsLen(n) - 1):
var a = n.sons[i] var a = n.sons[i]
if a.kind == nkCommentStmt: continue if a.kind == nkCommentStmt: continue
let name = typeSectionTypeName(a.sons[0]) let name = typeSectionTypeName(c, a.sons[0])
var s = name.sym var s = name.sym
# compute the type's size and check for illegal recursions: # compute the type's size and check for illegal recursions:
if a.sons[1].kind == nkEmpty: if a.sons[1].kind == nkEmpty:
@ -1031,9 +1042,9 @@ proc typeSectionFinalPass(c: PContext, n: PNode) =
assert s.typ != nil assert s.typ != nil
assignType(s.typ, t) assignType(s.typ, t)
s.typ.id = t.id # same id s.typ.id = t.id # same id
checkConstructedType(s.info, s.typ) checkConstructedType(c.config, s.info, s.typ)
if s.typ.kind in {tyObject, tyTuple} and not s.typ.n.isNil: if s.typ.kind in {tyObject, tyTuple} and not s.typ.n.isNil:
checkForMetaFields(s.typ.n) checkForMetaFields(c, s.typ.n)
instAllTypeBoundOp(c, n.info) instAllTypeBoundOp(c, n.info)
@ -1042,10 +1053,10 @@ proc semAllTypeSections(c: PContext; n: PNode): PNode =
case n.kind case n.kind
of nkIncludeStmt: of nkIncludeStmt:
for i in 0..<n.len: for i in 0..<n.len:
var f = checkModuleName(n.sons[i]) var f = checkModuleName(c.config, n.sons[i])
if f != InvalidFileIDX: if f != InvalidFileIDX:
if containsOrIncl(c.includedFiles, f.int): if containsOrIncl(c.includedFiles, f.int):
localError(c.config, n.info, errRecursiveDependencyX, f.toFilename) localError(c.config, n.info, errRecursiveDependencyX % f.toFilename)
else: else:
let code = gIncludeFile(c.graph, c.module, f, c.cache) let code = gIncludeFile(c.graph, c.module, f, c.cache)
gatherStmts c, code, result gatherStmts c, code, result
@ -1154,7 +1165,7 @@ proc semProcAnnotation(c: PContext, prc: PNode;
prc.sons[namePos] = newIdentNode(c.cache.idDelegator, prc.info) prc.sons[namePos] = newIdentNode(c.cache.idDelegator, prc.info)
prc.sons[pragmasPos] = copyExcept(n, i) prc.sons[pragmasPos] = copyExcept(n, i)
else: else:
localError(c.config, prc.info, errOnlyACallOpCanBeDelegator) localError(c.config, prc.info, "only a call operator can be a delegator")
continue continue
elif sfCustomPragma in m.flags: elif sfCustomPragma in m.flags:
continue # semantic check for custom pragma happens later in semProcAux continue # semantic check for custom pragma happens later in semProcAux
@ -1236,13 +1247,13 @@ proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode =
addResult(c, s.typ.sons[0], n.info, skProc) addResult(c, s.typ.sons[0], n.info, skProc)
addResultNode(c, n) addResultNode(c, n)
let semBody = hloBody(c, semProcBody(c, n.sons[bodyPos])) let semBody = hloBody(c, semProcBody(c, n.sons[bodyPos]))
n.sons[bodyPos] = transformBody(c.module, semBody, s) n.sons[bodyPos] = transformBody(c.graph, c.module, semBody, s)
popProcCon(c) popProcCon(c)
elif efOperand notin flags: elif efOperand notin flags:
localError(c.config, n.info, errGenericLambdaNotAllowed) localError(c.config, n.info, errGenericLambdaNotAllowed)
sideEffectsCheck(c, s) sideEffectsCheck(c, s)
else: else:
localError(c.config, n.info, errImplOfXexpected, s.name.s) localError(c.config, n.info, errImplOfXexpected % s.name.s)
closeScope(c) # close scope for parameters closeScope(c) # close scope for parameters
popOwner(c) popOwner(c)
result.typ = s.typ result.typ = s.typ
@ -1277,7 +1288,7 @@ proc semInferredLambda(c: PContext, pt: TIdTable, n: PNode): PNode =
addResult(c, n.typ.sons[0], n.info, skProc) addResult(c, n.typ.sons[0], n.info, skProc)
addResultNode(c, n) addResultNode(c, n)
let semBody = hloBody(c, semProcBody(c, n.sons[bodyPos])) let semBody = hloBody(c, semProcBody(c, n.sons[bodyPos]))
n.sons[bodyPos] = transformBody(c.module, semBody, s) n.sons[bodyPos] = transformBody(c.graph, c.module, semBody, s)
popProcCon(c) popProcCon(c)
popOwner(c) popOwner(c)
closeScope(c) closeScope(c)
@ -1426,7 +1437,7 @@ proc semMethodPrototype(c: PContext; s: PSym; n: PNode) =
foundObj = true foundObj = true
x.methods.safeAdd((col,s)) x.methods.safeAdd((col,s))
if not foundObj: if not foundObj:
message(n.info, warnDeprecated, "generic method not attachable to object type") message(c.config, n.info, warnDeprecated, "generic method not attachable to object type")
else: else:
# why check for the body? bug #2400 has none. Checking for sfForward makes # why check for the body? bug #2400 has none. Checking for sfForward makes
# no sense either. # no sense either.
@ -1434,7 +1445,7 @@ proc semMethodPrototype(c: PContext; s: PSym; n: PNode) =
if hasObjParam(s): if hasObjParam(s):
methodDef(c.graph, s, fromCache=false) methodDef(c.graph, s, fromCache=false)
else: else:
localError(c.config, n.info, errXNeedsParamObjectType, "method") localError(c.config, n.info, "'method' needs a parameter that has an object type")
proc semProcAux(c: PContext, n: PNode, kind: TSymKind, proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
validPragmas: TSpecialWords, validPragmas: TSpecialWords,
@ -1547,7 +1558,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
n.sons[genericParamsPos] = proto.ast.sons[genericParamsPos] n.sons[genericParamsPos] = proto.ast.sons[genericParamsPos]
n.sons[paramsPos] = proto.ast.sons[paramsPos] n.sons[paramsPos] = proto.ast.sons[paramsPos]
n.sons[pragmasPos] = proto.ast.sons[pragmasPos] n.sons[pragmasPos] = proto.ast.sons[pragmasPos]
if n.sons[namePos].kind != nkSym: internalError(n.info, "semProcAux") if n.sons[namePos].kind != nkSym: internalError(c.config, n.info, "semProcAux")
n.sons[namePos].sym = proto n.sons[namePos].sym = proto
if importantComments(c.config) and not isNil(proto.ast.comment): if importantComments(c.config) and not isNil(proto.ast.comment):
n.comment = proto.ast.comment n.comment = proto.ast.comment
@ -1606,7 +1617,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
popProcCon(c) popProcCon(c)
else: else:
if s.kind == skMethod: semMethodPrototype(c, s, n) if s.kind == skMethod: semMethodPrototype(c, s, n)
if proto != nil: localError(c.config, n.info, errImplOfXexpected, proto.name.s) if proto != nil: localError(c.config, n.info, errImplOfXexpected % proto.name.s)
if {sfImportc, sfBorrow} * s.flags == {} and s.magic == mNone: if {sfImportc, sfBorrow} * s.flags == {} and s.magic == mNone:
incl(s.flags, sfForward) incl(s.flags, sfForward)
elif sfBorrow in s.flags: semBorrow(c, n, s) elif sfBorrow in s.flags: semBorrow(c, n, s)
@ -1655,7 +1666,7 @@ proc semIterator(c: PContext, n: PNode): PNode =
else: else:
s.typ.callConv = ccInline s.typ.callConv = ccInline
if n.sons[bodyPos].kind == nkEmpty and s.magic == mNone: if n.sons[bodyPos].kind == nkEmpty and s.magic == mNone:
localError(c.config, n.info, errImplOfXexpected, s.name.s) localError(c.config, n.info, errImplOfXexpected % s.name.s)
proc semProc(c: PContext, n: PNode): PNode = proc semProc(c: PContext, n: PNode): PNode =
result = semProcAux(c, n, skProc, procPragmas) result = semProcAux(c, n, skProc, procPragmas)
@ -1664,7 +1675,7 @@ proc semFunc(c: PContext, n: PNode): PNode =
result = semProcAux(c, n, skFunc, procPragmas) result = semProcAux(c, n, skFunc, procPragmas)
proc semMethod(c: PContext, n: PNode): PNode = proc semMethod(c: PContext, n: PNode): PNode =
if not isTopLevel(c): localError(c.config, n.info, errXOnlyAtModuleScope, "method") if not isTopLevel(c): localError(c.config, n.info, errXOnlyAtModuleScope % "method")
result = semProcAux(c, n, skMethod, methodPragmas) result = semProcAux(c, n, skMethod, methodPragmas)
# macros can transform converters to nothing: # macros can transform converters to nothing:
if namePos >= result.safeLen: return result if namePos >= result.safeLen: return result
@ -1685,7 +1696,7 @@ proc semMethod(c: PContext, n: PNode): PNode =
else: disp.ast[resultPos].sym.typ = ret else: disp.ast[resultPos].sym.typ = ret
proc semConverterDef(c: PContext, n: PNode): PNode = proc semConverterDef(c: PContext, n: PNode): PNode =
if not isTopLevel(c): localError(c.config, n.info, errXOnlyAtModuleScope, "converter") if not isTopLevel(c): localError(c.config, n.info, errXOnlyAtModuleScope % "converter")
checkSonsLen(n, bodyPos + 1, c.config) checkSonsLen(n, bodyPos + 1, c.config)
result = semProcAux(c, n, skConverter, converterPragmas) result = semProcAux(c, n, skConverter, converterPragmas)
# macros can transform converters to nothing: # macros can transform converters to nothing:
@ -1696,8 +1707,8 @@ proc semConverterDef(c: PContext, n: PNode): PNode =
if result.kind != nkConverterDef: return if result.kind != nkConverterDef: return
var s = result.sons[namePos].sym var s = result.sons[namePos].sym
var t = s.typ var t = s.typ
if t.sons[0] == nil: localError(c.config, n.info, errXNeedsReturnType, "converter") if t.sons[0] == nil: localError(c.config, n.info, errXNeedsReturnType % "converter")
if sonsLen(t) != 2: localError(c.config, n.info, errXRequiresOneArgument, "converter") if sonsLen(t) != 2: localError(c.config, n.info, "a converter takes exactly one argument")
addConverter(c, s) addConverter(c, s)
proc semMacroDef(c: PContext, n: PNode): PNode = proc semMacroDef(c: PContext, n: PNode): PNode =
@ -1718,7 +1729,7 @@ proc semMacroDef(c: PContext, n: PNode): PNode =
if allUntyped: incl(s.flags, sfAllUntyped) if allUntyped: incl(s.flags, sfAllUntyped)
if t.sons[0] == nil: localError(c.config, n.info, "macro needs a return type") if t.sons[0] == nil: localError(c.config, n.info, "macro needs a return type")
if n.sons[bodyPos].kind == nkEmpty: if n.sons[bodyPos].kind == nkEmpty:
localError(c.config, n.info, errImplOfXexpected, s.name.s) localError(c.config, 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) result = newNodeI(nkStmtList, n.info)
@ -1756,7 +1767,7 @@ proc semStaticStmt(c: PContext, n: PNode): PNode =
#writeStackTrace() #writeStackTrace()
let a = semStmt(c, n.sons[0]) let a = semStmt(c, n.sons[0])
n.sons[0] = a n.sons[0] = a
evalStaticStmt(c.module, c.cache, c.graph.config, a, c.p.owner) evalStaticStmt(c.module, c.cache, c.graph, a, c.p.owner)
result = newNodeI(nkDiscardStmt, n.info, 1) result = newNodeI(nkDiscardStmt, n.info, 1)
result.sons[0] = emptyNode result.sons[0] = emptyNode
@ -1839,7 +1850,7 @@ proc semStmtList(c: PContext, n: PNode, flags: TExprFlags): PNode =
case n.sons[j].kind case n.sons[j].kind
of nkPragma, nkCommentStmt, nkNilLit, nkEmpty, nkBlockExpr, of nkPragma, nkCommentStmt, nkNilLit, nkEmpty, nkBlockExpr,
nkBlockStmt, nkState: discard nkBlockStmt, nkState: discard
else: localError(c.config, n.sons[j].info, errStmtInvalidAfterReturn) else: localError(c.config, n.sons[j].info, "unreachable statement after 'return'")
else: discard else: discard
if result.len == 1 and if result.len == 1 and