diff options
-rwxr-xr-x | rod/ast.nim | 18 | ||||
-rwxr-xr-x | rod/c2nim/c2nim.nim | 4 | ||||
-rwxr-xr-x | rod/c2nim/cparse.nim | 94 | ||||
-rwxr-xr-x | rod/c2nim/cpp.nim | 16 | ||||
-rwxr-xr-x | rod/depends.nim | 1 | ||||
-rwxr-xr-x | rod/docgen.nim | 1 | ||||
-rwxr-xr-x | rod/evals.nim | 22 | ||||
-rwxr-xr-x | rod/main.nim | 1 | ||||
-rwxr-xr-x | rod/msgs.nim | 391 | ||||
-rwxr-xr-x | rod/pas2nim/pasparse.nim | 138 | ||||
-rwxr-xr-x | rod/passes.nim | 9 | ||||
-rwxr-xr-x | rod/pnimsyn.nim | 183 | ||||
-rwxr-xr-x | rod/rnimsyn.nim | 38 | ||||
-rwxr-xr-x | rod/scanner.nim | 8 | ||||
-rwxr-xr-x | rod/semtypes.nim | 4 | ||||
-rwxr-xr-x | rod/syntaxes.nim | 7 | ||||
-rwxr-xr-x | todo.txt | 6 |
17 files changed, 505 insertions, 436 deletions
diff --git a/rod/ast.nim b/rod/ast.nim index 50bd00444..7bdfef82c 100755 --- a/rod/ast.nim +++ b/rod/ast.nim @@ -577,12 +577,10 @@ proc newSons*(father: PNode, length: int) proc newSons*(father: PType, length: int) proc addSon*(father, son: PNode) proc addSon*(father, son: PType) -proc addSonIfNotNil*(father, n: PNode) proc delSon*(father: PNode, idx: int) proc hasSonWith*(n: PNode, kind: TNodeKind): bool proc hasSubnodeWith*(n: PNode, kind: TNodeKind): bool proc replaceSons*(n: PNode, oldKind, newKind: TNodeKind) -proc sonsNotNil*(n: PNode): bool proc copyNode*(src: PNode): PNode # does not copy its sons! proc copyTree*(src: PNode): PNode @@ -590,6 +588,10 @@ proc copyTree*(src: PNode): PNode proc discardSons*(father: PNode) +var emptyNode* = newNode(nkEmpty) +# There is a single empty node that is shared! Do not overwrite it! + + const # for all kind of hash tables: GrowthFactor* = 2 # must be power of 2, > 0 StartSize* = 8 # must be power of 2, > 0 @@ -868,6 +870,7 @@ proc len*(n: PNode): int {.inline.} = else: result = len(n.sons) proc add*(father, son: PNode) = + assert son != nil if isNil(father.sons): father.sons = @[] add(father.sons, son) @@ -879,6 +882,7 @@ proc newSons(father: PNode, length: int) = setlen(father.sons, len(father.sons) + length) proc addSon(father, son: PNode) = + assert son != nil if isNil(father.sons): father.sons = @[] add(father.sons, son) @@ -947,7 +951,7 @@ proc lastSon(n: PType): PType = proc hasSonWith(n: PNode, kind: TNodeKind): bool = for i in countup(0, sonsLen(n) - 1): - if (n.sons[i] != nil) and (n.sons[i].kind == kind): + if n.sons[i].kind == kind: return true result = false @@ -956,9 +960,8 @@ proc hasSubnodeWith(n: PNode, kind: TNodeKind): bool = of nkEmpty..nkNilLit: result = n.kind == kind else: for i in countup(0, sonsLen(n) - 1): - if n.sons[i] != nil: - if (n.sons[i].kind == kind) or hasSubnodeWith(n.sons[i], kind): - return true + if (n.sons[i].kind == kind) or hasSubnodeWith(n.sons[i], kind): + return true result = false proc replaceSons(n: PNode, oldKind, newKind: TNodeKind) = @@ -971,9 +974,6 @@ proc sonsNotNil(n: PNode): bool = return false result = true -proc addSonIfNotNil(father, n: PNode) = - if n != nil: addSon(father, n) - proc getInt*(a: PNode): biggestInt = case a.kind of nkIntLit..nkInt64Lit: result = a.intVal diff --git a/rod/c2nim/c2nim.nim b/rod/c2nim/c2nim.nim index f1cb05920..f4e185445 100755 --- a/rod/c2nim/c2nim.nim +++ b/rod/c2nim/c2nim.nim @@ -1,7 +1,7 @@ # # # c2nim - C to Nimrod source converter -# (c) Copyright 2010 Andreas Rumpf +# (c) Copyright 2011 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -15,7 +15,7 @@ const Version = NimrodVersion Usage = """ c2nim - C to Nimrod source converter - (c) 2010 Andreas Rumpf + (c) 2011 Andreas Rumpf Usage: c2nim [options] inputfile [options] Options: -o, --out:FILE set output filename diff --git a/rod/c2nim/cparse.nim b/rod/c2nim/cparse.nim index 2634e8598..da96de1f4 100755 --- a/rod/c2nim/cparse.nim +++ b/rod/c2nim/cparse.nim @@ -197,7 +197,7 @@ proc parLineInfo(p: TParser): TLineInfo = result = getLineInfo(p.lex) proc skipComAux(p: var TParser, n: PNode) = - if (n != nil): + if n != nil and n.kind != nkEmpty: if pfSkipComments notin p.options.flags: if n.comment == nil: n.comment = p.tok.s else: add(n.comment, "\n" & p.tok.s) @@ -216,8 +216,7 @@ proc getTok(p: var TParser, n: PNode) = skipCom(p, n) proc ExpectIdent(p: TParser) = - if p.tok.xkind != pxSymbol: - parMessage(p, errIdentifierExpected, $(p.tok^)) + if p.tok.xkind != pxSymbol: parMessage(p, errIdentifierExpected, $(p.tok^)) proc Eat(p: var TParser, xkind: TTokKind, n: PNode) = if p.tok.xkind == xkind: getTok(p, n) @@ -375,7 +374,7 @@ proc skipTypeIdentExport(p: var TParser, prefix='T'): PNode = proc markTypeIdent(p: var TParser, typ: PNode) = if pfTypePrefixes in p.options.flags: var prefix = "" - if typ == nil: + if typ == nil or typ.kind == nkEmpty: prefix = "T" else: var t = typ @@ -479,11 +478,12 @@ proc newProcPragmas(p: TParser): PNode = proc addPragmas(father, pragmas: PNode) = if sonsLen(pragmas) > 0: addSon(father, pragmas) - else: addSon(father, nil) + else: addSon(father, ast.emptyNode) proc addReturnType(params, rettyp: PNode) = - if rettyp == nil or rettyp.kind != nkNilLit: addSon(params, rettyp) - else: addson(params, nil) + if rettyp == nil: addSon(params, ast.emptyNode) + elif rettyp.kind != nkNilLit: addSon(params, rettyp) + else: addson(params, ast.emptyNode) proc parseFormalParams(p: var TParser, params, pragmas: PNode) @@ -527,9 +527,6 @@ proc parseTypeSuffix(p: var TParser, typ: PNode): PNode = else: break proc typeDesc(p: var TParser): PNode = - #result = typeAtom(p) - #if result != nil: - # result = pointer(p, result) result = pointer(p, typeAtom(p)) proc parseField(p: var TParser, kind: TNodeKind): PNode = @@ -560,7 +557,7 @@ proc parseStructBody(p: var TParser, isUnion: bool, var t = pointer(p, baseTyp) var i = parseField(p, kind) t = parseTypeSuffix(p, t) - addSon(def, i, t, nil) + addSon(def, i, t, ast.emptyNode) if not takeOnlyFirstField(p, isUnion) or sonsLen(result) < 1: addSon(result, def) if p.tok.xkind != pxComma: break @@ -591,7 +588,7 @@ proc enumPragmas(p: TParser, name: PNode): PNode = proc parseStruct(p: var TParser, isUnion: bool): PNode = result = newNodeP(nkObjectTy, p) - addSon(result, nil, nil) # no pragmas, no inheritance + addSon(result, ast.emptyNode, ast.emptyNode) # no pragmas, no inheritance if p.tok.xkind == pxCurlyLe: addSon(result, parseStructBody(p, isUnion)) else: @@ -616,7 +613,7 @@ proc parseParam(p: var TParser, params: PNode) = getTok(p, x) addSon(x, assignmentExpression(p)) else: - addSon(x, nil) + addSon(x, ast.emptyNode) addSon(params, x) proc parseFormalParams(p: var TParser, params, pragmas: PNode) = @@ -662,15 +659,16 @@ proc parseFunctionPointerDecl(p: var TParser, rettyp: PNode): PNode = if p.inTypeDef == 0: result = newNodeP(nkVarSection, p) var def = newNodeP(nkIdentDefs, p) - addSon(def, name, procType, nil) + addSon(def, name, procType, ast.emptyNode) addSon(result, def) else: result = newNodeP(nkTypeDef, p) - addSon(result, name, nil, procType) + addSon(result, name, ast.emptyNode, procType) + assert result != nil proc addTypeDef(section, name, t: PNode) = var def = newNodeI(nkTypeDef, name.info) - addSon(def, name, nil, t) + addSon(def, name, ast.emptyNode, t) addSon(section, def) proc otherTypeDef(p: var TParser, section, typ: PNode) = @@ -705,7 +703,7 @@ proc parseTrailingDefinedTypes(p: var TParser, section, typ: PNode) = proc enumFields(p: var TParser): PNode = result = newNodeP(nkEnumTy, p) - addSon(result, nil) # enum does not inherit from anything + addSon(result, ast.emptyNode) # enum does not inherit from anything while true: var e = skipIdent(p) if p.tok.xkind == pxAsgn: @@ -846,7 +844,7 @@ proc addInitializer(p: var TParser, def: PNode) = getTok(p, def) addSon(def, parseInitializer(p)) else: - addSon(def, nil) + addSon(def, ast.emptyNode) proc parseVarDecl(p: var TParser, baseTyp, typ: PNode, origName: string): PNode = @@ -921,22 +919,24 @@ proc declaration(p: var TParser): PNode = addSon(pragmas, newIdentNodeP("cdecl", p)) elif pfStdcall in p.options.flags: addSon(pragmas, newIdentNodeP("stdcall", p)) - addSon(result, exportSym(p, name, origName), nil) # no generics + addSon(result, exportSym(p, name, origName), ast.emptyNode) # no generics addSon(result, params, pragmas) case p.tok.xkind of pxSemicolon: getTok(p) - addSon(result, nil) # nobody + addSon(result, ast.emptyNode) # nobody if p.scopeCounter == 0: DoImport(origName, pragmas, p) of pxCurlyLe: addSon(result, compoundStatement(p)) else: parMessage(p, errTokenExpected, ";") - if sonsLen(result.sons[pragmasPos]) == 0: result.sons[pragmasPos] = nil + if sonsLen(result.sons[pragmasPos]) == 0: + result.sons[pragmasPos] = ast.emptyNode of pxAsgn, pxSemicolon, pxComma: result = parseVarDecl(p, baseTyp, rettyp, origName) else: parMessage(p, errTokenExpected, ";") + assert result != nil proc createConst(name, typ, val: PNode, p: TParser): PNode = result = newNodeP(nkConstDef, p) @@ -963,7 +963,7 @@ proc enumSpecifier(p: var TParser): PNode = else: val = newIntNodeP(nkIntLit, i, p) inc(i) - var c = createConst(name, nil, val, p) + var c = createConst(name, ast.emptyNode, val, p) addSon(result, c) if p.tok.xkind != pxComma: break getTok(p, c) @@ -984,7 +984,7 @@ proc enumSpecifier(p: var TParser): PNode = var t = newNodeP(nkTypeDef, p) getTok(p, t) var e = enumFields(p) - addSon(t, exportSym(p, name, origName), nil, e) # nil for generic params + addSon(t, exportSym(p, name, origName), ast.emptyNode, e) addSon(result, t) eat(p, pxCurlyRi, result) eat(p, pxSemicolon) @@ -998,6 +998,7 @@ proc enumSpecifier(p: var TParser): PNode = else: closeContext(p) parMessage(p, errTokenExpected, "{") + result = ast.emptyNode # Expressions @@ -1085,7 +1086,7 @@ proc primaryExpression(p: var TParser): PNode = of pxParLe: result = castExpression(p) else: - result = nil + result = ast.emptyNode proc multiplicativeExpression(p: var TParser): PNode = result = castExpression(p) @@ -1309,7 +1310,7 @@ proc andExpression(p: var TParser): PNode = getTok(p, result) var a = result var b = equalityExpression(p) - result = newBinary("&", a, b, p) + result = newBinary("and", a, b, p) proc exclusiveOrExpression(p: var TParser): PNode = result = andExpression(p) @@ -1390,10 +1391,12 @@ proc expressionStatement(p: var TParser): PNode = # do not skip the comment after a semicolon to make a new nkCommentStmt if p.tok.xkind == pxSemicolon: getTok(p) + result = ast.emptyNode else: result = expression(p) if p.tok.xkind == pxSemicolon: getTok(p) else: parMessage(p, errTokenExpected, ";") + assert result != nil proc parseIf(p: var TParser): PNode = # we parse additional "else if"s too here for better Nimrod code @@ -1431,7 +1434,7 @@ proc parseDoWhile(p: var TParser): PNode = # ``block: stmt`` result = newNodeP(nkBlockStmt, p) getTok(p, result) # skip "do" - addSon(result, nil, nestedStatement(p)) + addSon(result, ast.emptyNode, nestedStatement(p)) eat(p, "while", result) eat(p, pxParLe, result) if p.tok.xkind == pxIntLit and p.tok.iNumber == 0: getTok(p, result) @@ -1465,6 +1468,7 @@ proc declarationOrStatement(p: var TParser): PNode = else: backtrackContext(p) result = expressionStatement(p) + assert result != nil proc parseTuple(p: var TParser, isUnion: bool): PNode = result = parseStructBody(p, isUnion, nkTupleTy) @@ -1516,15 +1520,16 @@ proc parseFor(p: var TParser, result: PNode) = getTok(p, result) eat(p, pxParLe, result) var initStmt = declarationOrStatement(p) - addSonIfNotNil(result, initStmt) + if initStmt.kind != nkEmpty: + addSon(result, initStmt) var w = newNodeP(nkWhileStmt, p) var condition = expressionStatement(p) - if condition == nil: condition = newIdentNodeP("true", p) + if condition.kind == nkEmpty: condition = newIdentNodeP("true", p) addSon(w, condition) - var step = if p.tok.xkind != pxParRi: expression(p) else: nil + var step = if p.tok.xkind != pxParRi: expression(p) else: ast.emptyNode eat(p, pxParRi, step) var loopBody = nestedStatement(p) - if step != nil: + if step.kind != nkEmpty: loopBody = buildStmtList(loopBody) addSon(loopBody, step) addSon(w, loopBody) @@ -1604,7 +1609,7 @@ proc embedStmts(sl, a: PNode) = addStmt(sl, a) else: for i in 0..sonsLen(a)-1: - if a[i] != nil: addStmt(sl, a[i]) + if a[i].kind != nkEmpty: addStmt(sl, a[i]) proc compoundStatement(p: var TParser): PNode = result = newNodeP(nkStmtList, p) @@ -1612,7 +1617,7 @@ proc compoundStatement(p: var TParser): PNode = inc(p.scopeCounter) while p.tok.xkind notin {pxEof, pxCurlyRi}: var a = statement(p) - if a == nil: break + if a.kind == nkEmpty: break embedStmts(result, a) if sonsLen(result) == 0: # translate ``{}`` to Nimrod's ``nil`` statement @@ -1644,12 +1649,12 @@ proc statement(p: var TParser): PNode = result = newNodeP(nkContinueStmt, p) getTok(p) eat(p, pxSemicolon) - addSon(result, nil) + addSon(result, ast.emptyNode) of "break": result = newNodeP(nkBreakStmt, p) getTok(p) eat(p, pxSemicolon) - addSon(result, nil) + addSon(result, ast.emptyNode) of "return": result = newNodeP(nkReturnStmt, p) getTok(p) @@ -1662,18 +1667,13 @@ proc statement(p: var TParser): PNode = elif p.tok.xkind != pxSemicolon: addSon(result, expression(p)) else: - addSon(result, nil) + addSon(result, ast.emptyNode) eat(p, pxSemicolon) - of "enum": - result = enumSpecifier(p) - of "typedef": - result = parseTypeDef(p) - of "struct": - result = parseStandaloneStruct(p, isUnion=false) - of "union": - result = parseStandaloneStruct(p, isUnion=true) - else: - result = declarationOrStatement(p) + of "enum": result = enumSpecifier(p) + of "typedef": result = parseTypeDef(p) + of "struct": result = parseStandaloneStruct(p, isUnion=false) + of "union": result = parseStandaloneStruct(p, isUnion=true) + else: result = declarationOrStatement(p) of pxCurlyLe: result = compoundStatement(p) of pxDirective, pxDirectiveParLe: @@ -1691,12 +1691,12 @@ proc statement(p: var TParser): PNode = result = newNodeP(nkNilLit, p) else: result = expressionStatement(p) - #parMessage(p, errStmtExpected) + assert result != nil proc parseUnit(p: var TParser): PNode = result = newNodeP(nkStmtList, p) getTok(p) # read first token while p.tok.xkind != pxEof: var s = statement(p) - if s != nil: embedStmts(result, s) + if s.kind != nkEmpty: embedStmts(result, s) diff --git a/rod/c2nim/cpp.nim b/rod/c2nim/cpp.nim index f59c86044..e7c7e86b0 100755 --- a/rod/c2nim/cpp.nim +++ b/rod/c2nim/cpp.nim @@ -45,7 +45,7 @@ proc parseDefine(p: var TParser): PNode = eat(p, pxParLe) var params = newNodeP(nkFormalParams, p) # return type; not known yet: - addSon(params, nil) + addSon(params, ast.emptyNode) var identDefs = newNodeP(nkIdentDefs, p) while p.tok.xkind != pxParRi: addSon(identDefs, skipIdent(p)) @@ -53,13 +53,13 @@ proc parseDefine(p: var TParser): PNode = if p.tok.xkind != pxComma: break getTok(p) addSon(identDefs, newIdentNodeP("expr", p)) - addSon(identDefs, nil) + addSon(identDefs, ast.emptyNode) addSon(params, identDefs) eat(p, pxParRi) - addSon(result, nil) # no generic parameters + addSon(result, ast.emptyNode) # no generic parameters addSon(result, params) - addSon(result, nil) # no pragmas + addSon(result, ast.emptyNode) # no pragmas var kind = parseDefineBody(p, result) params.sons[0] = newIdentNodeP(kind, p) eatNewLine(p, result) @@ -70,7 +70,7 @@ proc parseDefine(p: var TParser): PNode = getTok(p) # skip #define var c = newNodeP(nkConstDef, p) addSon(c, skipIdentExport(p)) - addSon(c, nil) + addSon(c, ast.emptyNode) skipStarCom(p, c) if p.tok.xkind in {pxLineComment, pxNewLine, pxEof}: addSon(c, newIdentNodeP("true", p)) @@ -78,6 +78,7 @@ proc parseDefine(p: var TParser): PNode = addSon(c, expression(p)) addSon(result, c) eatNewLine(p, c) + assert result != nil proc parseDefBody(p: var TParser, m: var TMacro, params: seq[string]) = m.body = @[] @@ -147,7 +148,7 @@ proc parseInclude(p: var TParser): PNode = skipLine(p) if sonsLen(result) == 0: # we only parsed includes that we chose to ignore: - result = nil + result = ast.emptyNode proc definedExprAux(p: var TParser): PNode = result = newNodeP(nkCall, p) @@ -226,6 +227,7 @@ proc parseIfdef(p: var TParser): PNode = case p.tok.s of "__cplusplus": skipUntilEndif(p) + result = ast.emptyNode of c2nimSymbol: skipLine(p) result = parseStmtList(p) @@ -238,6 +240,7 @@ proc parseIfdef(p: var TParser): PNode = parseIfDirAux(p, result) proc parseIfndef(p: var TParser): PNode = + result = ast.emptyNode getTok(p) # skip #ifndef ExpectIdent(p) if p.tok.s == c2nimSymbol: @@ -295,6 +298,7 @@ proc parseMangleDir(p: var TParser) = eatNewLine(p, nil) proc parseDir(p: var TParser): PNode = + result = ast.emptyNode assert(p.tok.xkind in {pxDirective, pxDirectiveParLe}) case p.tok.s of "define": result = parseDefine(p) diff --git a/rod/depends.nim b/rod/depends.nim index 4c464f5ec..05d176436 100755 --- a/rod/depends.nim +++ b/rod/depends.nim @@ -29,7 +29,6 @@ proc addDependencyAux(importing, imported: string) = proc addDotDependency(c: PPassContext, n: PNode): PNode = result = n - if n == nil: return var g = PGen(c) case n.kind of nkImportStmt: diff --git a/rod/docgen.nim b/rod/docgen.nim index 73566dbb0..cc31da925 100755 --- a/rod/docgen.nim +++ b/rod/docgen.nim @@ -771,7 +771,6 @@ proc traceDeps(d: PDoc, n: PNode) = "$1", [toRope(getModuleFile(n))]) proc generateDoc(d: PDoc, n: PNode) = - if n == nil: return case n.kind of nkCommentStmt: app(d.modDesc, genComment(d, n)) of nkProcDef: genItem(d, n, n.sons[namePos], skProc) diff --git a/rod/evals.nim b/rod/evals.nim index 4f0aeb6c6..b20c20acf 100755 --- a/rod/evals.nim +++ b/rod/evals.nim @@ -54,8 +54,6 @@ const evalMaxIterations = 10000000 # max iterations of all loops evalMaxRecDepth = 100000 # max recursion depth for evaluation -var emptyNode: PNode - proc newStackFrame(): PStackFrame = new(result) initIdNodeTable(result.mapping) @@ -136,7 +134,7 @@ proc evalWhile(c: PEvalContext, n: PNode): PNode = result = evalAux(c, n.sons[1], {}) case result.kind of nkBreakStmt: - if result.sons[0] == nil: + if result.sons[0].kind == nkEmpty: result = emptyNode # consume ``break`` token break of nkExceptBranch, nkReturnToken: @@ -153,7 +151,7 @@ proc evalBlock(c: PEvalContext, n: PNode): PNode = if result.kind == nkBreakStmt: if result.sons[0] != nil: assert(result.sons[0].kind == nkSym) - if n.sons[0] != nil: + if n.sons[0].kind != nkempty: assert(n.sons[0].kind == nkSym) if result.sons[0].sym.id == n.sons[0].sym.id: result = emptyNode else: @@ -228,7 +226,7 @@ proc evalVar(c: PEvalContext, n: PNode): PNode = assert(a.kind == nkIdentDefs) assert(a.sons[0].kind == nkSym) var v = a.sons[0].sym - if a.sons[2] != nil: + if a.sons[2].kind != nkEmpty: result = evalAux(c, a.sons[2], {}) if isSpecial(result): return else: @@ -507,7 +505,7 @@ proc evalConvCStrToStr(c: PEvalContext, n: PNode): PNode = result.typ = n.typ proc evalRaise(c: PEvalContext, n: PNode): PNode = - if n.sons[0] != nil: + if n.sons[0].kind != nkEmpty: result = evalAux(c, n.sons[0], {}) if isSpecial(result): return var a = result @@ -519,17 +517,17 @@ proc evalRaise(c: PEvalContext, n: PNode): PNode = else: stackTrace(c, n, errExceptionAlreadyHandled) result = newNodeIT(nkExceptBranch, n.info, nil) - addSon(result, nil) + addSon(result, ast.emptyNode) proc evalReturn(c: PEvalContext, n: PNode): PNode = - if n.sons[0] != nil: + if n.sons[0].kind != nkEmpty: result = evalAsgn(c, n.sons[0]) if isSpecial(result): return result = newNodeIT(nkReturnToken, n.info, nil) proc evalProc(c: PEvalContext, n: PNode): PNode = - if n.sons[genericParamsPos] == nil: - if (resultPos < sonsLen(n)) and (n.sons[resultPos] != nil): + if n.sons[genericParamsPos].kind == nkEmpty: + if (resultPos < sonsLen(n)) and (n.sons[resultPos].kind != nkEmpty): var v = n.sons[resultPos].sym result = getNullValue(v.typ, n.info) IdNodeTablePut(c.tos.mapping, v, result) @@ -740,8 +738,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode = if isSpecial(result): return var k = getOrdValue(b) if (k >= 0) and (k < sonsLen(a)) and not (a.kind in {nkEmpty..nkNilLit}): - if result.kind == nkEmpty: a.sons[int(k)] = nil - else: a.sons[int(k)] = result + a.sons[int(k)] = result else: stackTrace(c, n, errIndexOutOfBounds) result = emptyNode @@ -1055,4 +1052,3 @@ proc evalPass(): TPass = result.close = myProcess result.process = myProcess -emptyNode = newNode(nkEmpty) diff --git a/rod/main.nim b/rod/main.nim index 68958acb6..2b391e7dd 100755 --- a/rod/main.nim +++ b/rod/main.nim @@ -109,6 +109,7 @@ proc CommandGenDepend(filename: string) = changeFileExt(filename, "dot")) proc CommandCheck(filename: string) = + msgs.gErrorMax = high(int) # do not stop after first error semanticPasses() # use an empty backend for semantic checking only compileProject(filename) diff --git a/rod/msgs.nim b/rod/msgs.nim index 9e826e127..a3e9c1211 100755 --- a/rod/msgs.nim +++ b/rod/msgs.nim @@ -62,7 +62,7 @@ type errImplOfXexpected, errNoSymbolToBorrowFromFound, errDiscardValue, errInvalidDiscard, errIllegalConvFromXtoY, errCannotBindXTwice, errInvalidOrderInArrayConstructor, - errInvalidOrderInEnumX, errEnumXHasWholes, errExceptExpected, errInvalidTry, + errInvalidOrderInEnumX, errEnumXHasHoles, errExceptExpected, errInvalidTry, errOptionExpected, errXisNoLabel, errNotAllCasesCovered, errUnkownSubstitionVar, errComplexStmtRequiresInd, errXisNotCallable, errNoPragmasAllowedForX, errNoGenericParamsAllowedForX, @@ -96,154 +96,245 @@ type hintProcessing, hintCodeBegin, hintCodeEnd, hintConf, hintPath, hintUser const - MsgKindToStr*: array[TMsgKind, string] = ["unknown error", - "illformed AST: $1", "cannot open \'$1\'", "internal error: $1", "$1", - "\'$1\' compiler does not support C++", "string literal expected", - "integer literal expected", "invalid character constant", - "closing \"\"\" expected, but end of file reached", "closing \" expected", - "tabulators are not allowed", "invalid token: $1", "line too long", - "$1 is not a valid number", "number $1 out of valid range", - "\\n not allowed in character literal", - "closing \']\' expected, but end of file reached", "missing final \'", - "identifier expected, but found \'$1\'", - "operator expected, but found \'$1\'", "\'$1\' expected", - "string after \'include\' expected", "recursive dependency: \'$1\'", - "\'on\' or \'off\' expected", "\'none\', \'speed\' or \'size\' expected", - "invalid pragma", "unknown pragma: \'$1\'", "invalid directive: \'$1\'", - "\'pop\' without a \'push\' pragma", "empty asm statement", - "invalid indentation", "exception expected", "exception already handled", - "\'yield\' only allowed in a loop of an iterator", - "invalid number of \'yield\' expresions", - "current routine cannot return an expression", "attempt to redefine \'$1\'", - "statement not allowed after \'return\', \'break\' or \'raise\'", - "statement expected", "\'$1\' is no label", - "invalid command line option: \'$1\'", - "argument for command line option expected: \'$1\'", - "invalid argument for command line option: \'$1\'", - "invalid variable substitution in \'$1\'", "unknown variable: \'$1\'", - "unknown C compiler: \'$1\'", - "\'on\' or \'off\' expected, but \'$1\' found", - "\'none\', \'boehm\' or \'refc\' expected, but \'$1\' found", - "\'none\', \'speed\' or \'size\' expected, but \'$1\' found", - "\'gui\', \'console\' or \'lib\' expected, but \'$1\' found", - "unknown OS: \'$1\'", "unknown CPU: \'$1\'", - "\'c\', \'c++\' or \'yaml\' expected, but \'$1\' found", - "arguments can only be given if the \'--run\' option is selected", - "multiple assignment is not allowed", - "\':\' or \'=\' expected, but found \'$1\'", - "expression expected, but found \'$1\'", "undeclared identifier: \'$1\'", - "ambiguous identifier: \'$1\' -- use a qualifier", "type expected", - "system module needs \'$1\'", "execution of an external program failed", - "overloaded \'$1\' leads to ambiguous calls", "invalid argument for \'$1\'", - "statement has no effect", "\'$1\' expects a type or value", - "\'$1\' expects an array type", - "\'$1\' cannot be instantiated because its body has not been compiled yet", - "expression \'$1\' ambiguous in this context", "constant division by zero", - "ordinal type expected", "ordinal or float type expected", - "over- or underflow", - "cannot evalutate \'$1\' because type is not defined completely", - "\'chr\' expects an int in the range 0..255", - "\'dynlib\' requires \'exportc\'", "undeclared field: \'$1\'", - "attempt to access a nil address", "index out of bounds", - "index types do not match", "\'[]\' operator invalid for this type", - "value out of set bounds", "field initialized twice: \'$1\'", - "field \'$1\' not initialized", "expression \'$1\' cannot be called", - "expression has no type", "expression \'$1\' has no type (or is ambiguous)", - "\'cast\' not allowed in safe mode", "expression cannot be casted to $1", - "\',\' or \')\' expected", "\'{\' or \'(\' expected", - "section (\'type\', \'proc\', etc.) expected", "range expected", - "attempt to redefine \'$1\'", "\'magic\' only allowed in system module", - "power of two expected", "string literal may not be empty", - "calling convention expected", - "a proc can only have one calling convention", - "symbol must be imported if \'lib\' pragma is used", - "expression must be of type \'bool\'", "constant expression expected", - "duplicate case label", "range is empty", - "selector must be of an ordinal type, real or string", - "selector must be of an ordinal type", "ord($1) must not be negative", - "len($1) must be less than 32768", "wrong number of variables", - "only objects can be raised", "\'break\' only allowed in loop construct", - "type \'$1\' has unknown size", - "a constant can only be initialized with a constant expression", - "a constant needs a value", "the result type cannot be on open array", - "computing the type\'s size produced an overflow", "set is too large", - "base type of a set must be an ordinal", - "inheritance only works with non-final objects", - "inheritance only works with an enum", "illegal recursion in type \'$1\'", - "cannot instantiate: \'$1\'", "expression has no address", - "for a \'var\' type a variable needs to be passed", "type mismatch", - "type mismatch: got (", "but expected one of: ", "but expected \'$1\'", - "ambiguous call; both $1 and $2 match for: $3", "wrong number of arguments", - "\'$1\' cannot be passed to a procvar", - "$1 cannot be declared in parameter declaration", - "pragmas are only in the header of a proc allowed", - "implementation of \'$1\' is not allowed", - "implementation of \'$1\' expected", "no symbol to borrow from found", - "value returned by statement has to be discarded", - "statement returns no value that can be discarded", - "conversion from $1 to $2 is invalid", "cannot bind parameter \'$1\' twice", - "invalid order in array constructor", - "invalid order in enum \'$1\'", "enum \'$1\' has wholes", - "\'except\' or \'finally\' expected", - "after catch all \'except\' or \'finally\' no section may follow", - "option expected, but found \'$1\'", "\'$1\' is not a label", - "not all cases are covered", "unknown substitution variable: \'$1\'", - "complex statement requires indentation", "\'$1\' is not callable", - "no pragmas allowed for $1", "no generic parameters allowed for $1", - "invalid param kind: \'$1\'", "default argument invalid", - "named parameter has to be an identifier", "no return type for $1 allowed", - "a type conversion needs exactly one argument", "invalid pragma: $1", - "$1 not allowed here", "invalid control flow: $1", "a type has no value", - "invalid type: \'$1\'", "\'^\' needs a pointer or reference type", - "invalid expression", "invalid expression: \'$1\'", - "enum has no value \'$1\'", "named expression expected", - "named expression not allowed here", "\'$1\' expects one type parameter", - "array expects two type parameters", "invalid visibility: \'$1\'", - "initialization not allowed here", "\'$1\' cannot be assigned to", - "iterators can only be defined at the module\'s top level", - "$1 needs a return type", "invalid command: \'$1\'", - "\'$1\' is only allowed at top level", - "'$1' needs a parameter that has an object type", - "template/macro instantiation too nested", "instantiation from here", - "invalid index value for tuple subscript", - "command expects a filename argument", "\'$1\' expected", - "invalid section start", "grid table is not implemented", - "general parse error", "new section expected", - "whitespace expected, got \'$1\'", "\'$1\' is no valid index file", - "cannot render reStructuredText element \'$1\'", - "type \'var var\' is not allowed", "\'is\' expects two arguments", - "\'is\' expects object types", "\'$1\' can never be of this subtype", - "interpretation requires too many iterations", - "cannot interpret node kind \'$1\'", "field \'$1\' cannot be found", - "invalid conversion from type \'$1\'", "assertion failed", - "cannot generate code for \'$1\'", "$1 requires one parameter", - "unhandled exception: $1", "macro returned a cyclic abstract syntax tree", - "\'$1\' is no macro or template", "\'$1\' can have side effects", - "iterator within for loop context expected", "$1", - "cannot open \'$1\' [CannotOpenFile]", "octal escape sequences do not exist; leading zero is ignored [OctalEscape]", - "\'$1\' is never read [XIsNeverRead]", - "\'$1\' might not have been initialized [XmightNotBeenInit]", - "cannot write file \'$1\' [CannotWriteMO2]", - "cannot read file \'$1\' [CannotReadMO2]", - "\'$1\' is deprecated [Deprecated]", "\'l\' should not be used as an identifier; may look like \'1\' (one) [SmallLshouldNotBeUsed]", - "unknown magic \'$1\' might crash the compiler [UnknownMagic]", - "redefinition of label \'$1\' [RedefinitionOfLabel]", - "unknown substitution \'$1\' [UnknownSubstitutionX]", - "language \'$1\' not supported [LanguageXNotSupported]", - "comment \'$1\' ignored [CommentXIgnored]", - "\'$1\' is passed to a procvar; deprecated [XisPassedToProcVar]", - "$1 [User]", "operation successful [Success]", - "operation successful ($1 lines compiled; $2 sec total) [SuccessX]", - "line too long [LineTooLong]", - "\'$1\' is declared but not used [XDeclaredButNotUsed]", - "conversion to base object is not needed [ConvToBaseNotNeeded]", - "conversion from $1 to itself is pointless [ConvFromXtoItselfNotNeeded]", - "expression evaluates always to \'$1\' [ExprAlwaysX]", - "quit() called [QuitCalled]", "$1 [Processing]", - "generated code listing: [CodeBegin]", "end of listing [CodeEnd]", - "used config file \'$1\' [Conf]", - "added path: '$1' [Path]", - "$1 [User]"] + MsgKindToStr*: array[TMsgKind, string] = [ + errUnknown: "unknown error", + errIllFormedAstX: "illformed AST: $1", + errCannotOpenFile: "cannot open \'$1\'", + errInternal: "internal error: $1", + errGenerated: "$1", + errXCompilerDoesNotSupportCpp: "\'$1\' compiler does not support C++", + errStringLiteralExpected: "string literal expected", + errIntLiteralExpected: "integer literal expected", + errInvalidCharacterConstant: "invalid character constant", + errClosingTripleQuoteExpected: "closing \"\"\" expected, but end of file reached", + errClosingQuoteExpected: "closing \" expected", + errTabulatorsAreNotAllowed: "tabulators are not allowed", + errInvalidToken: "invalid token: $1", + errLineTooLong: "line too long", + errInvalidNumber: "$1 is not a valid number", + errNumberOutOfRange: "number $1 out of valid range", + errNnotAllowedInCharacter: "\\n not allowed in character literal", + errClosingBracketExpected: "closing ']' expected, but end of file reached", + errMissingFinalQuote: "missing final \'", + errIdentifierExpected: "identifier expected, but found \'$1\'", + errOperatorExpected: "operator expected, but found \'$1\'", + errTokenExpected: "\'$1\' expected", + errStringAfterIncludeExpected: "string after \'include\' expected", + errRecursiveDependencyX: "recursive dependency: \'$1\'", + errOnOrOffExpected: "\'on\' or \'off\' expected", + errNoneSpeedOrSizeExpected: "\'none\', \'speed\' or \'size\' expected", + errInvalidPragma: "invalid pragma", + errUnknownPragma: "unknown pragma: \'$1\'", + errInvalidDirectiveX: "invalid directive: \'$1\'", + errAtPopWithoutPush: "\'pop\' without a \'push\' pragma", + errEmptyAsm: "empty asm statement", + errInvalidIndentation: "invalid indentation", + errExceptionExpected: "exception expected", + errExceptionAlreadyHandled: "exception already handled", + errYieldNotAllowedHere: "\'yield\' only allowed in a loop of an iterator", + errInvalidNumberOfYieldExpr: "invalid number of \'yield\' expresions", + errCannotReturnExpr: "current routine cannot return an expression", + errAttemptToRedefine: "attempt to redefine \'$1\'", + errStmtInvalidAfterReturn: "statement not allowed after \'return\', \'break\' or \'raise\'", + errStmtExpected: "statement expected", + errInvalidLabel: "\'$1\' is no label", + errInvalidCmdLineOption: "invalid command line option: \'$1\'", + errCmdLineArgExpected: "argument for command line option expected: \'$1\'", + errCmdLineNoArgExpected: "invalid argument for command line option: \'$1\'", + errInvalidVarSubstitution: "invalid variable substitution in \'$1\'", + errUnknownVar: "unknown variable: \'$1\'", + errUnknownCcompiler: "unknown C compiler: \'$1\'", + errOnOrOffExpectedButXFound: "\'on\' or \'off\' expected, but \'$1\' found", + errNoneBoehmRefcExpectedButXFound: "'none', 'boehm' or 'refc' expected, but '$1' found", + errNoneSpeedOrSizeExpectedButXFound: "'none', 'speed' or 'size' expected, but '$1' found", + errGuiConsoleOrLibExpectedButXFound: "'gui', 'console' or 'lib' expected, but '$1' found", + errUnknownOS: "unknown OS: '$1'", + errUnknownCPU: "unknown CPU: '$1'", + errGenOutExpectedButXFound: "'c', 'c++' or 'yaml' expected, but '$1' found", + errArgsNeedRunOption: "arguments can only be given if the '--run' option is selected", + errInvalidMultipleAsgn: "multiple assignment is not allowed", + errColonOrEqualsExpected: "\':\' or \'=\' expected, but found \'$1\'", + errExprExpected: "expression expected, but found \'$1\'", + errUndeclaredIdentifier: "undeclared identifier: \'$1\'", + errUseQualifier: "ambiguous identifier: \'$1\' -- use a qualifier", + errTypeExpected: "type expected", + errSystemNeeds: "system module needs \'$1\'", + errExecutionOfProgramFailed: "execution of an external program failed", + errNotOverloadable: "overloaded \'$1\' leads to ambiguous calls", + errInvalidArgForX: "invalid argument for \'$1\'", + errStmtHasNoEffect: "statement has no effect", + errXExpectsTypeOrValue: "\'$1\' expects a type or value", + errXExpectsArrayType: "\'$1\' expects an array type", + errIteratorCannotBeInstantiated: "'$1' cannot be instantiated because its body has not been compiled yet", + errExprXAmbiguous: "expression '$1' ambiguous in this context", + errConstantDivisionByZero: "constant division by zero", + errOrdinalTypeExpected: "ordinal type expected", + errOrdinalOrFloatTypeExpected: "ordinal or float type expected", + errOverOrUnderflow: "over- or underflow", + errCannotEvalXBecauseIncompletelyDefined: "cannot evalutate '$1' because type is not defined completely", + errChrExpectsRange0_255: "\'chr\' expects an int in the range 0..255", + errDynlibRequiresExportc: "\'dynlib\' requires \'exportc\'", + errUndeclaredFieldX: "undeclared field: \'$1\'", + errNilAccess: "attempt to access a nil address", + errIndexOutOfBounds: "index out of bounds", + errIndexTypesDoNotMatch: "index types do not match", + errBracketsInvalidForType: "\'[]\' operator invalid for this type", + errValueOutOfSetBounds: "value out of set bounds", + errFieldInitTwice: "field initialized twice: \'$1\'", + errFieldNotInit: "field \'$1\' not initialized", + errExprXCannotBeCalled: "expression \'$1\' cannot be called", + errExprHasNoType: "expression has no type", + errExprXHasNoType: "expression \'$1\' has no type (or is ambiguous)", + errCastNotInSafeMode: "\'cast\' not allowed in safe mode", + errExprCannotBeCastedToX: "expression cannot be casted to $1", + errCommaOrParRiExpected: "',' or ')' expected", + errCurlyLeOrParLeExpected: "\'{\' or \'(\' expected", + errSectionExpected: "section (\'type\', \'proc\', etc.) expected", + errRangeExpected: "range expected", + errAttemptToRedefineX: "attempt to redefine \'$1\'", + errMagicOnlyInSystem: "\'magic\' only allowed in system module", + errPowerOfTwoExpected: "power of two expected", + errStringMayNotBeEmpty: "string literal may not be empty", + errCallConvExpected: "calling convention expected", + errProcOnlyOneCallConv: "a proc can only have one calling convention", + errSymbolMustBeImported: "symbol must be imported if 'lib' pragma is used", + errExprMustBeBool: "expression must be of type 'bool'", + errConstExprExpected: "constant expression expected", + errDuplicateCaseLabel: "duplicate case label", + errRangeIsEmpty: "range is empty", + errSelectorMustBeOfCertainTypes: "selector must be of an ordinal type, float or string", + errSelectorMustBeOrdinal: "selector must be of an ordinal type", + errOrdXMustNotBeNegative: "ord($1) must not be negative", + errLenXinvalid: "len($1) must be less than 32768", + errWrongNumberOfVariables: "wrong number of variables", + errExprCannotBeRaised: "only objects can be raised", + errBreakOnlyInLoop: "'break' only allowed in loop construct", + errTypeXhasUnknownSize: "type \'$1\' has unknown size", + errConstNeedsConstExpr: "a constant can only be initialized with a constant expression", + errConstNeedsValue: "a constant needs a value", + errResultCannotBeOpenArray: "the result type cannot be on open array", + errSizeTooBig: "computing the type\'s size produced an overflow", + errSetTooBig: "set is too large", + errBaseTypeMustBeOrdinal: "base type of a set must be an ordinal", + errInheritanceOnlyWithNonFinalObjects: "inheritance only works with non-final objects", + errInheritanceOnlyWithEnums: "inheritance only works with an enum", + errIllegalRecursionInTypeX: "illegal recursion in type \'$1\'", + errCannotInstantiateX: "cannot instantiate: \'$1\'", + errExprHasNoAddress: "expression has no address", + errVarForOutParamNeeded: "for a \'var\' type a variable needs to be passed", + errPureTypeMismatch: "type mismatch", + errTypeMismatch: "type mismatch: got (", + errButExpected: "but expected one of: ", + errButExpectedX: "but expected \'$1\'", + errAmbiguousCallXYZ: "ambiguous call; both $1 and $2 match for: $3", + errWrongNumberOfArguments: "wrong number of arguments", + errXCannotBePassedToProcVar: "\'$1\' cannot be passed to a procvar", + errXCannotBeInParamDecl: "$1 cannot be declared in parameter declaration", + errPragmaOnlyInHeaderOfProc: "pragmas are only in the header of a proc allowed", + errImplOfXNotAllowed: "implementation of \'$1\' is not allowed", + errImplOfXexpected: "implementation of \'$1\' expected", + errNoSymbolToBorrowFromFound: "no symbol to borrow from found", + errDiscardValue: "value returned by statement has to be discarded", + errInvalidDiscard: "statement returns no value that can be discarded", + errIllegalConvFromXtoY: "conversion from $1 to $2 is invalid", + errCannotBindXTwice: "cannot bind parameter \'$1\' twice", + errInvalidOrderInArrayConstructor: "invalid order in array constructor", + errInvalidOrderInEnumX: "invalid order in enum \'$1\'", + errEnumXHasHoles: "enum \'$1\' has holes", + errExceptExpected: "\'except\' or \'finally\' expected", + errInvalidTry: "after catch all \'except\' or \'finally\' no section may follow", + errOptionExpected: "option expected, but found \'$1\'", + errXisNoLabel: "\'$1\' is not a label", + errNotAllCasesCovered: "not all cases are covered", + errUnkownSubstitionVar: "unknown substitution variable: \'$1\'", + errComplexStmtRequiresInd: "complex statement requires indentation", + errXisNotCallable: "\'$1\' is not callable", + errNoPragmasAllowedForX: "no pragmas allowed for $1", + errNoGenericParamsAllowedForX: "no generic parameters allowed for $1", + errInvalidParamKindX: "invalid param kind: \'$1\'", + errDefaultArgumentInvalid: "default argument invalid", + errNamedParamHasToBeIdent: "named parameter has to be an identifier", + errNoReturnTypeForX: "no return type for $1 allowed", + errConvNeedsOneArg: "a type conversion needs exactly one argument", + errInvalidPragmaX: "invalid pragma: $1", + errXNotAllowedHere: "$1 not allowed here", + errInvalidControlFlowX: "invalid control flow: $1", + errATypeHasNoValue: "a type has no value", + errXisNoType: "invalid type: \'$1\'", + errCircumNeedsPointer: "\'^\' needs a pointer or reference type", + errInvalidExpression: "invalid expression", + errInvalidExpressionX: "invalid expression: \'$1\'", + errEnumHasNoValueX: "enum has no value \'$1\'", + errNamedExprExpected: "named expression expected", + errNamedExprNotAllowed: "named expression not allowed here", + errXExpectsOneTypeParam: "\'$1\' expects one type parameter", + errArrayExpectsTwoTypeParams: "array expects two type parameters", + errInvalidVisibilityX: "invalid visibility: \'$1\'", + errInitHereNotAllowed: "initialization not allowed here", + errXCannotBeAssignedTo: "\'$1\' cannot be assigned to", + errIteratorNotAllowed: "iterators can only be defined at the module\'s top level", + errXNeedsReturnType: "$1 needs a return type", + errInvalidCommandX: "invalid command: \'$1\'", + errXOnlyAtModuleScope: "\'$1\' is only allowed at top level", + errXNeedsParamObjectType: "'$1' needs a parameter that has an object type", + errTemplateInstantiationTooNested: "template/macro instantiation too nested", + errInstantiationFrom: "instantiation from here", + errInvalidIndexValueForTuple: "invalid index value for tuple subscript", + errCommandExpectsFilename: "command expects a filename argument", + errXExpected: "\'$1\' expected", + errInvalidSectionStart: "invalid section start", + errGridTableNotImplemented: "grid table is not implemented", + errGeneralParseError: "general parse error", + errNewSectionExpected: "new section expected", + errWhitespaceExpected: "whitespace expected, got \'$1\'", + errXisNoValidIndexFile: "\'$1\' is no valid index file", + errCannotRenderX: "cannot render reStructuredText element \'$1\'", + errVarVarTypeNotAllowed: "type \'var var\' is not allowed", + errIsExpectsTwoArguments: "\'is\' expects two arguments", + errIsExpectsObjectTypes: "\'is\' expects object types", + errXcanNeverBeOfThisSubtype: "\'$1\' can never be of this subtype", + errTooManyIterations: "interpretation requires too many iterations", + errCannotInterpretNodeX: "cannot interpret node kind \'$1\'", + errFieldXNotFound: "field \'$1\' cannot be found", + errInvalidConversionFromTypeX: "invalid conversion from type \'$1\'", + errAssertionFailed: "assertion failed", + errCannotGenerateCodeForX: "cannot generate code for \'$1\'", + errXRequiresOneArgument: "$1 requires one parameter", + errUnhandledExceptionX: "unhandled exception: $1", + errCyclicTree: "macro returned a cyclic abstract syntax tree", + errXisNoMacroOrTemplate: "\'$1\' is no macro or template", + errXhasSideEffects: "\'$1\' can have side effects", + errIteratorExpected: "iterator within for loop context expected", + errUser: "$1", + warnCannotOpenFile: "cannot open \'$1\' [CannotOpenFile]", + warnOctalEscape: "octal escape sequences do not exist; leading zero is ignored [OctalEscape]", + warnXIsNeverRead: "\'$1\' is never read [XIsNeverRead]", + warnXmightNotBeenInit: "\'$1\' might not have been initialized [XmightNotBeenInit]", + warnCannotWriteMO2: "cannot write file \'$1\' [CannotWriteMO2]", + warnCannotReadMO2: "cannot read file \'$1\' [CannotReadMO2]", + warnDeprecated: "\'$1\' is deprecated [Deprecated]", + warnSmallLshouldNotBeUsed: "\'l\' should not be used as an identifier; may look like \'1\' (one) [SmallLshouldNotBeUsed]", + warnUnknownMagic: "unknown magic \'$1\' might crash the compiler [UnknownMagic]", + warnRedefinitionOfLabel: "redefinition of label \'$1\' [RedefinitionOfLabel]", + warnUnknownSubstitutionX: "unknown substitution \'$1\' [UnknownSubstitutionX]", + warnLanguageXNotSupported: "language \'$1\' not supported [LanguageXNotSupported]", + warnCommentXIgnored: "comment \'$1\' ignored [CommentXIgnored]", + warnXisPassedToProcVar: "\'$1\' is passed to a procvar; deprecated [XisPassedToProcVar]", + warnUser: "$1 [User]", + hintSuccess: "operation successful [Success]", + hintSuccessX: "operation successful ($1 lines compiled; $2 sec total) [SuccessX]", + hintLineTooLong: "line too long [LineTooLong]", + hintXDeclaredButNotUsed: "\'$1\' is declared but not used [XDeclaredButNotUsed]", + hintConvToBaseNotNeeded: "conversion to base object is not needed [ConvToBaseNotNeeded]", + hintConvFromXtoItselfNotNeeded: "conversion from $1 to itself is pointless [ConvFromXtoItselfNotNeeded]", + hintExprAlwaysX: "expression evaluates always to \'$1\' [ExprAlwaysX]", + hintQuitCalled: "quit() called [QuitCalled]", + hintProcessing: "$1 [Processing]", + hintCodeBegin: "generated code listing: [CodeBegin]", + hintCodeEnd: "end of listing [CodeEnd]", + hintConf: "used config file \'$1\' [Conf]", + hintPath: "added path: '$1' [Path]", + hintUser: "$1 [User]"] const WarningsToStr*: array[0..14, string] = ["CannotOpenFile", "OctalEscape", @@ -353,7 +444,7 @@ proc checkpoint(info: TLineInfo, filename: string, line: int): bool = (ChangeFileExt(extractFilename(filenames[info.fileIndex]), "") == filename) -var checkPoints: seq[TLineInfo] = @ [] +var checkPoints: seq[TLineInfo] = @[] proc addCheckpoint(info: TLineInfo) = var length: int diff --git a/rod/pas2nim/pasparse.nim b/rod/pas2nim/pasparse.nim index 427cdc5ef..a84acc100 100755 --- a/rod/pas2nim/pasparse.nim +++ b/rod/pas2nim/pasparse.nim @@ -141,7 +141,7 @@ proc parseTypeDesc(p: var TParser, definition: PNode = nil): PNode proc parseEmit(p: var TParser, definition: PNode): PNode = getTok(p) # skip 'emit' - result = nil + result = ast.emptyNode if p.tok.xkind != pxCurlyDirRi: case p.context of conExpr: @@ -159,7 +159,7 @@ proc parseEmit(p: var TParser, definition: PNode): PNode = eat(p, pxCurlyDirRi) proc parseCommand(p: var TParser, definition: PNode = nil): PNode = - result = nil + result = ast.emptyNode getTok(p) if p.tok.ident.id == getIdent("discard").id: result = newNodeP(nkDiscardStmt, p) @@ -170,8 +170,8 @@ proc parseCommand(p: var TParser, definition: PNode = nil): PNode = getTok(p) eat(p, pxCurlyDirRi) result = parseExpr(p) + if result.kind == nkEmpty: InternalError("emptyNode modified") result.kind = nkCurly - assert(sonsNotNil(result)) elif p.tok.ident.id == getIdent("cast").id: getTok(p) eat(p, pxCurlyDirRi) @@ -181,7 +181,7 @@ proc parseCommand(p: var TParser, definition: PNode = nil): PNode = addSon(result, a.sons[0]) addSon(result, a.sons[1]) else: - parMessage(p, errInvalidDirectiveX, $(p.tok)) + parMessage(p, errInvalidDirectiveX, $p.tok) result = a elif p.tok.ident.id == getIdent("emit").id: result = parseEmit(p, definition) @@ -216,12 +216,12 @@ proc parseCommand(p: var TParser, definition: PNode = nil): PNode = getTok(p) eat(p, pxCurlyDirRi) else: - parMessage(p, errInvalidDirectiveX, $(p.tok)) + parMessage(p, errInvalidDirectiveX, $p.tok) while true: getTok(p) - if (p.tok.xkind == pxCurlyDirRi) or (p.tok.xkind == pxEof): break + if p.tok.xkind == pxCurlyDirRi or p.tok.xkind == pxEof: break eat(p, pxCurlyDirRi) - result = nil + result = ast.emptyNode proc getPrecedence(kind: TTokKind): int = case kind @@ -295,7 +295,7 @@ proc qualifiedIdent(p: var TParser): PNode = result = createIdentNodeP(p.tok.ident, p) else: parMessage(p, errIdentifierExpected, $p.tok) - return nil + return ast.emptyNode getTok(p) skipCom(p, result) if p.tok.xkind == pxDot: @@ -390,15 +390,15 @@ proc identOrLiteral(p: var TParser): PNode = else: parMessage(p, errExprExpected, $(p.tok)) getTok(p) # we must consume a token here to prevend endless loops! - result = nil - if result != nil: skipCom(p, result) + result = ast.emptyNode + if result.kind != nkEmpty: skipCom(p, result) proc primary(p: var TParser): PNode = # prefix operator? if (p.tok.xkind == pxNot) or (p.tok.xkind == pxMinus) or (p.tok.xkind == pxPlus): result = newNodeP(nkPrefix, p) - var a = newIdentNodeP(getIdent($(p.tok)), p) + var a = newIdentNodeP(getIdent($p.tok), p) addSon(result, a) getTok(p) skipCom(p, a) @@ -406,7 +406,7 @@ proc primary(p: var TParser): PNode = return elif p.tok.xkind == pxAt: result = newNodeP(nkAddr, p) - var a = newIdentNodeP(getIdent($(p.tok)), p) + var a = newIdentNodeP(getIdent($p.tok), p) getTok(p) if p.tok.xkind == pxBracketLe: result = newNodeP(nkPrefix, p) @@ -433,7 +433,7 @@ proc primary(p: var TParser): PNode = addSon(result, createIdentNodeP(p.tok.ident, p)) getTok(p) else: - parMessage(p, errIdentifierExpected, $(p.tok)) + parMessage(p, errIdentifierExpected, $p.tok) of pxHat: var a = result result = newNodeP(nkDerefExpr, p) @@ -490,7 +490,6 @@ proc lowestExprAux(p: var TParser, v: var PNode, limit: int): TTokKind = proc fixExpr(n: PNode): PNode = result = n - if n == nil: return case n.kind of nkInfix: if n.sons[1].kind == nkBracket: n.sons[1].kind = nkCurly @@ -559,7 +558,7 @@ proc parseUsesStmt(p: var TParser): PNode = skipCom(p, a) else: break - if sonsLen(result) == 0: result = nil + if sonsLen(result) == 0: result = ast.emptyNode proc parseIncludeDir(p: var TParser): PNode = result = newNodeP(nkIncludeStmt, p) @@ -568,7 +567,7 @@ proc parseIncludeDir(p: var TParser): PNode = while true: case p.tok.xkind of pxSymbol, pxDot, pxDotDot, pxSlash: - filename = filename & $(p.tok) + add(filename, $p.tok) getTok(p) of pxStrLit: filename = p.tok.literal @@ -577,10 +576,10 @@ proc parseIncludeDir(p: var TParser): PNode = of pxCurlyDirRi: break else: - parMessage(p, errIdentifierExpected, $(p.tok)) + parMessage(p, errIdentifierExpected, $p.tok) break addSon(result, newStrNodeP(nkStrLit, changeFileExt(filename, "nim"), p)) - if filename == "config.inc": result = nil + if filename == "config.inc": result = ast.emptyNode proc definedExprAux(p: var TParser): PNode = result = newNodeP(nkCall, p) @@ -590,7 +589,6 @@ proc definedExprAux(p: var TParser): PNode = getTok(p) proc isHandledDirective(p: TParser): bool = - result = false if p.tok.xkind in {pxCurlyDirLe, pxStarDirLe}: case toLower(p.tok.ident.s) of "else", "endif": result = false @@ -657,7 +655,7 @@ proc parseIfDir(p: var TParser, endMarker: TTokKind): PNode = parseIfDirAux(p, result) proc parseDirective(p: var TParser): PNode = - result = nil + result = ast.emptyNode if not (p.tok.xkind in {pxCurlyDirLe, pxStarDirLe}): return var endMarker = succ(p.tok.xkind) if p.tok.ident != nil: @@ -680,7 +678,7 @@ proc parseRaise(p: var TParser): PNode = getTok(p) skipCom(p, result) if p.tok.xkind != pxSemicolon: addSon(result, parseExpr(p)) - else: addSon(result, nil) + else: addSon(result, ast.emptyNode) proc parseIf(p: var TParser): PNode = result = newNodeP(nkIfStmt, p) @@ -721,14 +719,14 @@ proc parseRepeat(p: var TParser): PNode = skipCom(p, result) addSon(result, newIdentNodeP(getIdent("true"), p)) var s = newNodeP(nkStmtList, p) - while (p.tok.xkind != pxEof) and (p.tok.xkind != pxUntil): + while p.tok.xkind != pxEof and p.tok.xkind != pxUntil: addSon(s, parseStmt(p)) eat(p, pxUntil) var a = newNodeP(nkIfStmt, p) skipCom(p, a) var b = newNodeP(nkElifBranch, p) var c = newNodeP(nkBreakStmt, p) - addSon(c, nil) + addSon(c, ast.emptyNode) addSon(b, parseExpr(p)) skipCom(p, a) addSon(b, c) @@ -809,7 +807,7 @@ proc parseFor(p: var TParser): PNode = getTok(p) eat(p, pxAsgn) var a = parseExpr(p) - var b: PNode = nil + var b = ast.emptyNode var c = newNodeP(nkCall, p) if p.tok.xkind == pxTo: addSon(c, newIdentNodeP(getIdent("countup"), p)) @@ -829,9 +827,9 @@ proc parseFor(p: var TParser): PNode = addSon(result, parseStmt(p)) proc parseParam(p: var TParser): PNode = - var a, v: PNode + var a: PNode result = newNodeP(nkIdentDefs, p) - v = nil + var v = ast.emptyNode case p.tok.xkind of pxConst: getTok(p) @@ -848,7 +846,7 @@ proc parseParam(p: var TParser): PNode = of pxSymbol: a = createIdentNodeP(p.tok.ident, p) of pxColon, pxEof, pxParRi, pxEquals: break else: - parMessage(p, errIdentifierExpected, $(p.tok)) + parMessage(p, errIdentifierExpected, $p.tok) return getTok(p) # skip identifier skipCom(p, a) @@ -859,24 +857,24 @@ proc parseParam(p: var TParser): PNode = if p.tok.xkind == pxColon: getTok(p) skipCom(p, result) - if v != nil: addSon(v, parseTypeDesc(p)) + if v.kind != nkEmpty: addSon(v, parseTypeDesc(p)) else: v = parseTypeDesc(p) addSon(result, v) else: - addSon(result, nil) + addSon(result, ast.emptyNode) if p.tok.xkind != pxEquals: - parMessage(p, errColonOrEqualsExpected, $(p.tok)) + parMessage(p, errColonOrEqualsExpected, $p.tok) if p.tok.xkind == pxEquals: getTok(p) skipCom(p, result) addSon(result, parseExpr(p)) else: - addSon(result, nil) + addSon(result, ast.emptyNode) proc parseParamList(p: var TParser): PNode = var a: PNode result = newNodeP(nkFormalParams, p) - addSon(result, nil) # return type + addSon(result, ast.emptyNode) # return type if p.tok.xkind == pxParLe: p.inParamList = true getTok(p) @@ -903,7 +901,7 @@ proc parseParamList(p: var TParser): PNode = result.sons[0] = parseTypeDesc(p) proc parseCallingConvention(p: var TParser): PNode = - result = nil + result = ast.emptyNode if p.tok.xkind == pxSymbol: case toLower(p.tok.ident.s) of "stdcall", "cdecl", "safecall", "syscall", "inline", "fastcall": @@ -935,7 +933,7 @@ proc parseRoutineSpecifiers(p: var TParser, noBody: var bool): PNode = of "importc": # This is a fake for platform module. There is no ``importc`` # directive in Pascal. - if result == nil: result = newNodeP(nkPragma, p) + if result.kind == nkEmpty: result = newNodeP(nkPragma, p) addSon(result, newIdentNodeP(getIdent("importc"), p)) noBody = true getTok(p) @@ -943,7 +941,7 @@ proc parseRoutineSpecifiers(p: var TParser, noBody: var bool): PNode = of "noconv": # This is a fake for platform module. There is no ``noconv`` # directive in Pascal. - if result == nil: result = newNodeP(nkPragma, p) + if result.kind == nkEmpty: result = newNodeP(nkPragma, p) addSon(result, newIdentNodeP(getIdent("noconv"), p)) noBody = true getTok(p) @@ -951,17 +949,17 @@ proc parseRoutineSpecifiers(p: var TParser, noBody: var bool): PNode = of "procvar": # This is a fake for the Nimrod compiler. There is no ``procvar`` # directive in Pascal. - if result == nil: result = newNodeP(nkPragma, p) + if result.kind == nkEmpty: result = newNodeP(nkPragma, p) addSon(result, newIdentNodeP(getIdent("procvar"), p)) getTok(p) opt(p, pxSemicolon) of "varargs": - if result == nil: result = newNodeP(nkPragma, p) + if result.kind == nkEmpty: result = newNodeP(nkPragma, p) addSon(result, newIdentNodeP(getIdent("varargs"), p)) getTok(p) opt(p, pxSemicolon) of "external": - if result == nil: result = newNodeP(nkPragma, p) + if result.kind == nkEmpty: result = newNodeP(nkPragma, p) getTok(p) noBody = true e = newNodeP(nkExprColonExpr, p) @@ -981,8 +979,8 @@ proc parseRoutineSpecifiers(p: var TParser, noBody: var bool): PNode = opt(p, pxSemicolon) else: e = parseCallingConvention(p) - if e == nil: break - if result == nil: result = newNodeP(nkPragma, p) + if e.kind == nkEmpty: break + if result.kind == nkEmpty: result = newNodeP(nkPragma, p) addSon(result, e.sons[0]) proc parseRoutineType(p: var TParser): PNode = @@ -999,7 +997,7 @@ proc parseEnum(p: var TParser): PNode = result = newNodeP(nkEnumTy, p) getTok(p) skipCom(p, result) - addSon(result, nil) # it does not inherit from any enumeration + addSon(result, ast.emptyNode) # it does not inherit from any enumeration while true: case p.tok.xkind of pxEof, pxParRi: break @@ -1061,7 +1059,7 @@ proc parseIdentColonEquals(p: var TParser, skipCom(p, result) addSon(result, parseTypeDesc(p)) else: - addSon(result, nil) + addSon(result, ast.emptyNode) if p.tok.xkind != pxEquals: parMessage(p, errColonOrEqualsExpected, $(p.tok)) if p.tok.xkind == pxEquals: @@ -1069,20 +1067,20 @@ proc parseIdentColonEquals(p: var TParser, skipCom(p, result) addSon(result, parseExpr(p)) else: - addSon(result, nil) + addSon(result, ast.emptyNode) if p.tok.xkind == pxSemicolon: getTok(p) skipCom(p, result) proc parseRecordCase(p: var TParser): PNode = - var a, b, c: PNode + var b, c: PNode result = newNodeP(nkRecCase, p) getTok(p) - a = newNodeP(nkIdentDefs, p) + var a = newNodeP(nkIdentDefs, p) addSon(a, rawIdent(p)) eat(p, pxColon) addSon(a, parseTypeDesc(p)) - addSon(a, nil) + addSon(a, ast.emptyNode) addSon(result, a) eat(p, pxOf) skipCom(p, result) @@ -1116,9 +1114,9 @@ proc parseRecordCase(p: var TParser): PNode = if b.kind == nkElse: break proc parseRecordPart(p: var TParser): PNode = - result = nil + result = ast.emptyNode while (p.tok.xkind != pxEof) and (p.tok.xkind != pxEnd): - if result == nil: result = newNodeP(nkRecList, p) + if result.kind == nkEmpty: result = newNodeP(nkRecList, p) case p.tok.xkind of pxSymbol: addSon(result, parseIdentColonEquals(p, rawIdent)) @@ -1129,8 +1127,8 @@ proc parseRecordPart(p: var TParser): PNode = of pxComment: skipCom(p, lastSon(result)) else: - parMessage(p, errIdentifierExpected, $(p.tok)) - break + parMessage(p, errIdentifierExpected, $p.tok) + break proc exSymbol(n: var PNode) = case n.kind @@ -1146,7 +1144,6 @@ proc exSymbol(n: var PNode) = else: internalError(n.info, "exSymbol(): " & $n.kind) proc fixRecordDef(n: var PNode) = - if n == nil: return case n.kind of nkRecCase: fixRecordDef(n.sons[0]) @@ -1157,7 +1154,7 @@ proc fixRecordDef(n: var PNode) = for i in countup(0, sonsLen(n) - 1): fixRecordDef(n.sons[i]) of nkIdentDefs: for i in countup(0, sonsLen(n) - 3): exSymbol(n.sons[i]) - of nkNilLit: nil + of nkNilLit, nkEmpty: nil else: internalError(n.info, "fixRecordDef(): " & $n.kind) proc addPragmaToIdent(ident: var PNode, pragma: PNode) = @@ -1202,7 +1199,7 @@ proc parseRecordOrObject(p: var TParser, kind: TNodeKind, definition: PNode): PNode = result = newNodeP(kind, p) getTok(p) - addSon(result, nil) + addSon(result, ast.emptyNode) if p.tok.xkind == pxParLe: var a = newNodeP(nkOfInherit, p) getTok(p) @@ -1210,7 +1207,7 @@ proc parseRecordOrObject(p: var TParser, kind: TNodeKind, addSon(result, a) eat(p, pxParRi) else: - addSon(result, nil) + addSon(result, ast.emptyNode) parseRecordBody(p, result, definition) proc parseTypeDesc(p: var TParser, definition: PNode = nil): PNode = @@ -1234,8 +1231,8 @@ proc parseTypeDesc(p: var TParser, definition: PNode = nil): PNode = else: addSon(result, a.sons[i]) else: result = newNodeP(nkObjectTy, p) - addSon(result, nil) - addSon(result, nil) + addSon(result, ast.emptyNode) + addSon(result, ast.emptyNode) parseRecordBody(p, result, definition) if definition != nil: addPragmaToIdent(definition.sons[0], newIdentNodeP(getIdent("final"), p)) @@ -1288,13 +1285,13 @@ proc parseTypeDesc(p: var TParser, definition: PNode = nil): PNode = proc parseTypeDef(p: var TParser): PNode = result = newNodeP(nkTypeDef, p) addSon(result, identVis(p)) - addSon(result, nil) # generic params + addSon(result, ast.emptyNode) # generic params if p.tok.xkind == pxEquals: getTok(p) skipCom(p, result) addSon(result, parseTypeDesc(p, result)) else: - addSon(result, nil) + addSon(result, ast.emptyNode) if p.tok.xkind == pxSemicolon: getTok(p) skipCom(p, result) @@ -1314,7 +1311,7 @@ proc parseConstant(p: var TParser): PNode = skipCom(p, result) addSon(result, parseTypeDesc(p)) else: - addSon(result, nil) + addSon(result, ast.emptyNode) if p.tok.xkind != pxEquals: parMessage(p, errColonOrEqualsExpected, $(p.tok)) if p.tok.xkind == pxEquals: @@ -1322,7 +1319,7 @@ proc parseConstant(p: var TParser): PNode = skipCom(p, result) addSon(result, parseExpr(p)) else: - addSon(result, nil) + addSon(result, ast.emptyNode) if p.tok.xkind == pxSemicolon: getTok(p) skipCom(p, result) @@ -1349,12 +1346,12 @@ proc parseRoutine(p: var TParser): PNode = skipCom(p, result) expectIdent(p) addSon(result, identVis(p)) - addSon(result, nil) # generic parameters + addSon(result, ast.emptyNode) # generic parameters addSon(result, parseParamList(p)) opt(p, pxSemicolon) addSon(result, parseRoutineSpecifiers(p, noBody)) if (p.section == seInterface) or noBody: - addSon(result, nil) + addSon(result, ast.emptyNode) else: var stmts = newNodeP(nkStmtList, p) while true: @@ -1408,8 +1405,7 @@ proc exSymbols(n: PNode) = of nkTypeSection: for i in countup(0, sonsLen(n) - 1): exSymbol(n.sons[i].sons[0]) - if (n.sons[i].sons[2] != nil) and - (n.sons[i].sons[2].kind == nkObjectTy): + if n.sons[i].sons[2].kind == nkObjectTy: fixRecordDef(n.sons[i].sons[2]) else: nil @@ -1425,13 +1421,15 @@ proc parseBegin(p: var TParser, result: PNode) = break of pxSemicolon: getTok(p) of pxEof: parMessage(p, errExprExpected) - else: addSonIfNotNil(result, parseStmt(p)) + else: + var a = parseStmt(p) + if a.kind != nkEmpty: addSon(result, a) if sonsLen(result) == 0: addSon(result, newNodeP(nkNilLit, p)) proc parseStmt(p: var TParser): PNode = var oldcontext = p.context p.context = conStmt - result = nil + result = ast.emptyNode case p.tok.xkind of pxBegin: result = newNodeP(nkStmtList, p) @@ -1475,23 +1473,23 @@ proc parseStmt(p: var TParser): PNode = result = newNodeP(nkBreakStmt, p) getTok(p) skipCom(p, result) - addSon(result, nil) + addSon(result, ast.emptyNode) elif p.tok.ident.id == getIdent("continue").id: result = newNodeP(nkContinueStmt, p) getTok(p) skipCom(p, result) - addSon(result, nil) + addSon(result, ast.emptyNode) elif p.tok.ident.id == getIdent("exit").id: result = newNodeP(nkReturnStmt, p) getTok(p) skipCom(p, result) - addSon(result, nil) + addSon(result, ast.emptyNode) else: result = parseExprStmt(p) of pxDot: getTok(p) # BUGFIX for ``end.`` in main program else: result = parseExprStmt(p) opt(p, pxSemicolon) - if result != nil: skipCom(p, result) + if result.kind != nkEmpty: skipCom(p, result) p.context = oldcontext proc parseUnit(p: var TParser): PNode = diff --git a/rod/passes.nim b/rod/passes.nim index e35f4d045..40036cb5a 100755 --- a/rod/passes.nim +++ b/rod/passes.nim @@ -104,7 +104,7 @@ proc processTopLevelStmtCached(n: PNode, a: var TPassContextArray) = if not isNil(gPasses[i].openCached): m = gPasses[i].process(a[i], m) proc closePassesCached(a: var TPassContextArray) = - var m: PNode = nil + var m = ast.emptyNode for i in countup(0, gPassesLen - 1): if not isNil(gPasses[i].openCached) and not isNil(gPasses[i].close): m = gPasses[i].close(a[i], m) @@ -114,7 +114,6 @@ proc processModule(module: PSym, filename: string, stream: PLLStream, rd: PRodReader) = var p: TParsers - n: PNode a: TPassContextArray s: PLLStream if rd == nil: @@ -129,8 +128,8 @@ proc processModule(module: PSym, filename: string, stream: PLLStream, while true: openParsers(p, filename, s) while true: - n = parseTopLevelStmt(p) - if n == nil: break + var n = parseTopLevelStmt(p) + if n.kind == nkEmpty: break processTopLevelStmt(n, a) closeParsers(p) if s.kind != llsStdIn: break @@ -139,7 +138,7 @@ proc processModule(module: PSym, filename: string, stream: PLLStream, IDsynchronizationPoint(1000) else: openPassesCached(a, module, filename, rd) - n = loadInitSection(rd) #MessageOut('init section' + renderTree(n)); + var n = loadInitSection(rd) #MessageOut('init section' + renderTree(n)); for i in countup(0, sonsLen(n) - 1): processTopLevelStmtCached(n.sons[i], a) closePassesCached(a) diff --git a/rod/pnimsyn.nim b/rod/pnimsyn.nim index 113f47d34..7734d7490 100755 --- a/rod/pnimsyn.nim +++ b/rod/pnimsyn.nim @@ -28,8 +28,8 @@ proc ParseAll*(p: var TParser): PNode proc openParser*(p: var TParser, filename: string, inputstream: PLLStream) proc closeParser*(p: var TParser) proc parseTopLevelStmt*(p: var TParser): PNode - # implements an iterator. Returns the next top-level statement or nil if end - # of stream. + # implements an iterator. Returns the next top-level statement or + # emtyNode if end of stream. # helpers for the other parsers proc getPrecedence*(tok: PToken): int @@ -94,7 +94,7 @@ proc optInd(p: var TParser, n: PNode) = skipInd(p) proc expectIdentOrKeyw(p: TParser) = - if (p.tok.tokType != tkSymbol) and not isKeyword(p.tok.tokType): + if p.tok.tokType != tkSymbol and not isKeyword(p.tok.tokType): lexMessage(p.lex^, errIdentifierExpected, tokToStr(p.tok)) proc ExpectIdent(p: TParser) = @@ -217,18 +217,17 @@ proc parseSymbol(p: var TParser): PNode = addSon(result, newIdentNodeP(id, p)) else: parMessage(p, errIdentifierExpected, tokToStr(p.tok)) - result = nil + result = ast.emptyNode eat(p, tkAccent) else: parMessage(p, errIdentifierExpected, tokToStr(p.tok)) - result = nil + result = ast.emptyNode proc accExpr(p: var TParser): PNode = - var x, y: PNode result = newNodeP(nkAccQuoted, p) getTok(p) # skip ` - x = nil - y = nil + var x = ast.emptyNode + var y = ast.emptyNode case p.tok.tokType of tkSymbol, tkOpr, tokKeywordLow..tokKeywordHigh: x = newIdentNodeP(p.tok.ident, p) @@ -255,9 +254,9 @@ proc optExpr(p: var TParser): PNode = (p.tok.tokType != tkDotDot): result = parseExpr(p) else: - result = nil + result = ast.emptyNode -proc dotdotExpr(p: var TParser, first: PNode = nil): PNode = +proc dotdotExpr(p: var TParser, first: PNode): PNode = result = newNodeP(nkRange, p) addSon(result, first) getTok(p) @@ -266,20 +265,19 @@ proc dotdotExpr(p: var TParser, first: PNode = nil): PNode = proc indexExpr(p: var TParser): PNode = # indexExpr ::= '..' [expr] | expr ['=' expr | '..' expr] - var a, b: PNode if p.tok.tokType == tkDotDot: - result = dotdotExpr(p) + result = dotdotExpr(p, ast.emptyNode) else: - a = parseExpr(p) + var a = parseExpr(p) case p.tok.tokType of tkEquals: result = newNodeP(nkExprEqExpr, p) addSon(result, a) getTok(p) if p.tok.tokType == tkDotDot: - addSon(result, dotdotExpr(p)) + addSon(result, dotdotExpr(p, ast.emptyNode)) else: - b = parseExpr(p) + var b = parseExpr(p) if p.tok.tokType == tkDotDot: b = dotdotExpr(p, b) addSon(result, b) of tkDotDot: @@ -305,7 +303,8 @@ proc exprColonEqExpr(p: var TParser, kind: TNodeKind, tok: TTokType): PNode = var a = parseExpr(p) if p.tok.tokType == tok: result = newNodeP(kind, p) - getTok(p) #optInd(p, result); + getTok(p) + #optInd(p, result) addSon(result, a) addSon(result, parseExpr(p)) else: @@ -481,14 +480,13 @@ proc identOrLiteral(p: var TParser): PNode = else: parMessage(p, errExprExpected, tokToStr(p.tok)) getTok(p) # we must consume a token here to prevend endless loops! - result = nil + result = ast.emptyNode proc primary(p: var TParser): PNode = - var a: PNode # prefix operator? if (p.tok.tokType == tkNot) or (p.tok.tokType == tkOpr): result = newNodeP(nkPrefix, p) - a = newIdentNodeP(p.tok.ident, p) + var a = newIdentNodeP(p.tok.ident, p) addSon(result, a) getTok(p) optInd(p, a) @@ -504,12 +502,12 @@ proc primary(p: var TParser): PNode = while true: case p.tok.tokType of tkParLe: - a = result + var a = result result = newNodeP(nkCall, p) addSon(result, a) exprColonEqExprListAux(p, nkExprEqExpr, tkParRi, tkEquals, result) of tkDot: - a = result + var a = result result = newNodeP(nkDotExpr, p) addSon(result, a) getTok(p) # skip '.' @@ -517,7 +515,7 @@ proc primary(p: var TParser): PNode = addSon(result, parseSymbol(p)) result = parseGStrLit(p, result) of tkHat: - a = result + var a = result result = newNodeP(nkDerefExpr, p) addSon(result, a) getTok(p) @@ -549,30 +547,28 @@ proc lowestExpr(p: var TParser): PNode = discard lowestExprAux(p, result, - 1) proc parseIfExpr(p: var TParser): PNode = - var branch: PNode result = newNodeP(nkIfExpr, p) while true: getTok(p) # skip `if`, `elif` - branch = newNodeP(nkElifExpr, p) + var branch = newNodeP(nkElifExpr, p) addSon(branch, parseExpr(p)) eat(p, tkColon) addSon(branch, parseExpr(p)) addSon(result, branch) if p.tok.tokType != tkElif: break - branch = newNodeP(nkElseExpr, p) + var branch = newNodeP(nkElseExpr, p) eat(p, tkElse) eat(p, tkColon) addSon(branch, parseExpr(p)) addSon(result, branch) proc parsePragma(p: var TParser): PNode = - var a: PNode result = newNodeP(nkPragma, p) getTok(p) optInd(p, result) while (p.tok.tokType != tkCurlyDotRi) and (p.tok.tokType != tkCurlyRi) and (p.tok.tokType != tkEof) and (p.tok.tokType != tkSad): - a = exprColonEqExpr(p, nkExprColonExpr, tkColon) + var a = exprColonEqExpr(p, nkExprColonExpr, tkColon) addSon(result, a) if p.tok.tokType == tkComma: getTok(p) @@ -583,8 +579,7 @@ proc parsePragma(p: var TParser): PNode = proc identVis(p: var TParser): PNode = # identifier with visability - var a: PNode - a = parseSymbol(p) + var a = parseSymbol(p) if p.tok.tokType == tkOpr: result = newNodeP(nkPostfix, p) addSon(result, newIdentNodeP(p.tok.ident, p)) @@ -594,8 +589,7 @@ proc identVis(p: var TParser): PNode = result = a proc identWithPragma(p: var TParser): PNode = - var a: PNode - a = identVis(p) + var a = identVis(p) if p.tok.tokType == tkCurlyDotLe: result = newNodeP(nkPragmaExpr, p) addSon(result, a) @@ -617,7 +611,7 @@ proc parseIdentColonEquals(p: var TParser, flags: TDeclaredIdentFlags): PNode = of tkSymbol, tkAccent: if withPragma in flags: a = identWithPragma(p) else: a = parseSymbol(p) - if a == nil: return + if a.kind == nkEmpty: return else: break addSon(result, a) if p.tok.tokType != tkComma: break @@ -628,7 +622,7 @@ proc parseIdentColonEquals(p: var TParser, flags: TDeclaredIdentFlags): PNode = optInd(p, result) addSon(result, parseTypeDesc(p)) else: - addSon(result, nil) + addSon(result, ast.emptyNode) if (p.tok.tokType != tkEquals) and not (withBothOptional in flags): parMessage(p, errColonOrEqualsExpected, tokToStr(p.tok)) if p.tok.tokType == tkEquals: @@ -636,16 +630,15 @@ proc parseIdentColonEquals(p: var TParser, flags: TDeclaredIdentFlags): PNode = optInd(p, result) addSon(result, parseExpr(p)) else: - addSon(result, nil) + addSon(result, ast.emptyNode) proc parseTuple(p: var TParser): PNode = - var a: PNode result = newNodeP(nkTupleTy, p) getTok(p) eat(p, tkBracketLe) optInd(p, result) while (p.tok.tokType == tkSymbol) or (p.tok.tokType == tkAccent): - a = parseIdentColonEquals(p, {}) + var a = parseIdentColonEquals(p, {}) addSon(result, a) if p.tok.tokType != tkComma: break getTok(p) @@ -656,7 +649,7 @@ proc parseTuple(p: var TParser): PNode = proc parseParamList(p: var TParser): PNode = var a: PNode result = newNodeP(nkFormalParams, p) - addSon(result, nil) # return type + addSon(result, ast.emptyNode) # return type if p.tok.tokType == tkParLe: getTok(p) optInd(p, result) @@ -689,11 +682,11 @@ proc parseProcExpr(p: var TParser, isExpr: bool): PNode = getTok(p) params = parseParamList(p) if p.tok.tokType == tkCurlyDotLe: pragmas = parsePragma(p) - else: pragmas = nil + else: pragmas = ast.emptyNode if (p.tok.tokType == tkEquals) and isExpr: result = newNodeI(nkLambda, info) - addSon(result, nil) # no name part - addSon(result, nil) # no generic parameters + addSon(result, ast.emptyNode) # no name part + addSon(result, ast.emptyNode) # no generic parameters addSon(result, params) addSon(result, pragmas) getTok(p) @@ -744,12 +737,11 @@ proc isExprStart(p: TParser): bool = else: result = false proc parseExprStmt(p: var TParser): PNode = - var a, b, e: PNode - a = lowestExpr(p) + var a = lowestExpr(p) if p.tok.tokType == tkEquals: getTok(p) optInd(p, result) - b = parseExpr(p) + var b = parseExpr(p) result = newNodeI(nkAsgn, a.info) addSon(result, a) addSon(result, b) @@ -759,7 +751,7 @@ proc parseExprStmt(p: var TParser): PNode = addSon(result, a) while true: if not isExprStart(p): break - e = parseExpr(p) + var e = parseExpr(p) addSon(result, e) if p.tok.tokType != tkComma: break getTok(p) @@ -778,6 +770,7 @@ proc parseExprStmt(p: var TParser): PNode = addSon(result, parseStmt(p)) while true: if p.tok.tokType == tkSad: getTok(p) + var b: PNode case p.tok.tokType of tkOf: b = newNodeP(nkOfBranch, p) @@ -871,7 +864,7 @@ proc parseReturnOrRaise(p: var TParser, kind: TNodeKind): PNode = getTok(p) optInd(p, result) case p.tok.tokType - of tkEof, tkSad, tkDed: addSon(result, nil) + of tkEof, tkSad, tkDed: addSon(result, ast.emptyNode) else: addSon(result, parseExpr(p)) proc parseYieldOrDiscard(p: var TParser, kind: TNodeKind): PNode = @@ -885,15 +878,14 @@ proc parseBreakOrContinue(p: var TParser, kind: TNodeKind): PNode = getTok(p) optInd(p, result) case p.tok.tokType - of tkEof, tkSad, tkDed: addSon(result, nil) + of tkEof, tkSad, tkDed: addSon(result, ast.emptyNode) else: addSon(result, parseSymbol(p)) proc parseIfOrWhen(p: var TParser, kind: TNodeKind): PNode = - var branch: PNode result = newNodeP(kind, p) while true: getTok(p) # skip `if`, `when`, `elif` - branch = newNodeP(nkElifBranch, p) + var branch = newNodeP(nkElifBranch, p) optInd(p, branch) addSon(branch, parseExpr(p)) eat(p, tkColon) @@ -903,7 +895,7 @@ proc parseIfOrWhen(p: var TParser, kind: TNodeKind): PNode = addSon(result, branch) if p.tok.tokType != tkElif: break if p.tok.tokType == tkElse: - branch = newNodeP(nkElse, p) + var branch = newNodeP(nkElse, p) eat(p, tkElse) eat(p, tkColon) skipComment(p, branch) @@ -954,13 +946,12 @@ proc parseCase(p: var TParser): PNode = if b.kind == nkElse: break proc parseTry(p: var TParser): PNode = - var b: PNode result = newNodeP(nkTryStmt, p) getTok(p) eat(p, tkColon) skipComment(p, result) addSon(result, parseStmt(p)) - b = nil + var b: PNode = nil while true: if p.tok.tokType == tkSad: getTok(p) case p.tok.tokType @@ -979,11 +970,10 @@ proc parseTry(p: var TParser): PNode = if b == nil: parMessage(p, errTokenExpected, "except") proc parseFor(p: var TParser): PNode = - var a: PNode result = newNodeP(nkForStmt, p) getTok(p) optInd(p, result) - a = parseSymbol(p) + var a = parseSymbol(p) addSon(result, a) while p.tok.tokType == tkComma: getTok(p) @@ -1001,7 +991,7 @@ proc parseBlock(p: var TParser): PNode = getTok(p) optInd(p, result) case p.tok.tokType - of tkEof, tkSad, tkDed, tkColon: addSon(result, nil) + of tkEof, tkSad, tkDed, tkColon: addSon(result, ast.emptyNode) else: addSon(result, parseSymbol(p)) eat(p, tkColon) skipComment(p, result) @@ -1012,7 +1002,7 @@ proc parseAsm(p: var TParser): PNode = getTok(p) optInd(p, result) if p.tok.tokType == tkCurlyDotLe: addSon(result, parsePragma(p)) - else: addSon(result, nil) + else: addSon(result, ast.emptyNode) case p.tok.tokType of tkStrLit: addSon(result, newStrNodeP(nkStrLit, p.tok.literal, p)) of tkRStrLit: addSon(result, newStrNodeP(nkRStrLit, p.tok.literal, p)) @@ -1020,17 +1010,16 @@ proc parseAsm(p: var TParser): PNode = newStrNodeP(nkTripleStrLit, p.tok.literal, p)) else: parMessage(p, errStringLiteralExpected) - addSon(result, nil) + addSon(result, ast.emptyNode) return getTok(p) proc parseGenericParamList(p: var TParser): PNode = - var a: PNode result = newNodeP(nkGenericParams, p) getTok(p) optInd(p, result) while (p.tok.tokType == tkSymbol) or (p.tok.tokType == tkAccent): - a = parseIdentColonEquals(p, {withBothOptional}) + var a = parseIdentColonEquals(p, {withBothOptional}) addSon(result, a) if p.tok.tokType != tkComma: break getTok(p) @@ -1044,16 +1033,16 @@ proc parseRoutine(p: var TParser, kind: TNodeKind): PNode = optInd(p, result) addSon(result, identVis(p)) if p.tok.tokType == tkBracketLe: addSon(result, parseGenericParamList(p)) - else: addSon(result, nil) + else: addSon(result, ast.emptyNode) addSon(result, parseParamList(p)) if p.tok.tokType == tkCurlyDotLe: addSon(result, parsePragma(p)) - else: addSon(result, nil) + else: addSon(result, ast.emptyNode) if p.tok.tokType == tkEquals: getTok(p) skipComment(p, result) addSon(result, parseStmt(p)) else: - addSon(result, nil) + addSon(result, ast.emptyNode) indAndComment(p, result) # XXX: document this in the grammar! proc newCommentStmt(p: var TParser): PNode = @@ -1065,13 +1054,12 @@ type proc parseSection(p: var TParser, kind: TNodeKind, defparser: TDefParser): PNode = - var a: PNode result = newNodeP(kind, p) getTok(p) skipComment(p, result) case p.tok.tokType of tkInd: - pushInd(p.lex^ , p.tok.indent) + pushInd(p.lex^, p.tok.indent) getTok(p) skipComment(p, result) while true: @@ -1079,7 +1067,7 @@ proc parseSection(p: var TParser, kind: TNodeKind, of tkSad: getTok(p) of tkSymbol, tkAccent: - a = defparser(p) + var a = defparser(p) skipComment(p, a) addSon(result, a) of tkDed: @@ -1088,13 +1076,13 @@ proc parseSection(p: var TParser, kind: TNodeKind, of tkEof: break # BUGFIX of tkComment: - a = newCommentStmt(p) + var a = newCommentStmt(p) skipComment(p, a) addSon(result, a) else: parMessage(p, errIdentifierExpected, tokToStr(p.tok)) break - popInd(p.lex^ ) + popInd(p.lex^) of tkSymbol, tkAccent, tkParLe: # tkParLe is allowed for ``var (x, y) = ...`` tuple parsing addSon(result, defparser(p)) @@ -1108,7 +1096,7 @@ proc parseConstant(p: var TParser): PNode = optInd(p, result) addSon(result, parseTypeDesc(p)) else: - addSon(result, nil) + addSon(result, ast.emptyNode) eat(p, tkEquals) optInd(p, result) addSon(result, parseExpr(p)) @@ -1126,7 +1114,7 @@ proc parseEnum(p: var TParser): PNode = addSon(a, parseTypeDesc(p)) addSon(result, a) else: - addSon(result, nil) + addSon(result, ast.emptyNode) optInd(p, result) while true: case p.tok.tokType @@ -1148,11 +1136,10 @@ proc parseEnum(p: var TParser): PNode = proc parseObjectPart(p: var TParser): PNode proc parseObjectWhen(p: var TParser): PNode = - var branch: PNode result = newNodeP(nkRecWhen, p) while true: getTok(p) # skip `when`, `elif` - branch = newNodeP(nkElifBranch, p) + var branch = newNodeP(nkElifBranch, p) optInd(p, branch) addSon(branch, parseExpr(p)) eat(p, tkColon) @@ -1162,7 +1149,7 @@ proc parseObjectWhen(p: var TParser): PNode = addSon(result, branch) if p.tok.tokType != tkElif: break if p.tok.tokType == tkElse: - branch = newNodeP(nkElse, p) + var branch = newNodeP(nkElse, p) eat(p, tkElse) eat(p, tkColon) skipComment(p, branch) @@ -1170,18 +1157,18 @@ proc parseObjectWhen(p: var TParser): PNode = addSon(result, branch) proc parseObjectCase(p: var TParser): PNode = - var a, b: PNode result = newNodeP(nkRecCase, p) getTok(p) - a = newNodeP(nkIdentDefs, p) + var a = newNodeP(nkIdentDefs, p) addSon(a, identWithPragma(p)) eat(p, tkColon) addSon(a, parseTypeDesc(p)) - addSon(a, nil) + addSon(a, ast.emptyNode) addSon(result, a) skipComment(p, result) while true: if p.tok.tokType == tkSad: getTok(p) + var b: PNode case p.tok.tokType of tkOf: b = newNodeP(nkOfBranch, p) @@ -1200,7 +1187,7 @@ proc parseObjectPart(p: var TParser): PNode = case p.tok.tokType of tkInd: result = newNodeP(nkRecList, p) - pushInd(p.lex^ , p.tok.indent) + pushInd(p.lex^, p.tok.indent) getTok(p) skipComment(p, result) while true: @@ -1228,21 +1215,20 @@ proc parseObjectPart(p: var TParser): PNode = of tkNil: result = newNodeP(nkNilLit, p) getTok(p) - else: result = nil + else: result = ast.emptyNode proc parseObject(p: var TParser): PNode = - var a: PNode result = newNodeP(nkObjectTy, p) getTok(p) if p.tok.tokType == tkCurlyDotLe: addSon(result, parsePragma(p)) - else: addSon(result, nil) + else: addSon(result, ast.emptyNode) if p.tok.tokType == tkOf: - a = newNodeP(nkOfInherit, p) + var a = newNodeP(nkOfInherit, p) getTok(p) addSon(a, parseTypeDesc(p)) addSon(result, a) else: - addSon(result, nil) + addSon(result, ast.emptyNode) skipComment(p, result) addSon(result, parseObjectPart(p)) @@ -1253,14 +1239,14 @@ proc parseDistinct(p: var TParser): PNode = addSon(result, parseTypeDesc(p)) proc parseTypeDef(p: var TParser): PNode = - var a: PNode result = newNodeP(nkTypeDef, p) addSon(result, identWithPragma(p)) if p.tok.tokType == tkBracketLe: addSon(result, parseGenericParamList(p)) - else: addSon(result, nil) + else: addSon(result, ast.emptyNode) if p.tok.tokType == tkEquals: getTok(p) optInd(p, result) + var a: PNode case p.tok.tokType of tkObject: a = parseObject(p) of tkEnum: a = parseEnum(p) @@ -1268,21 +1254,20 @@ proc parseTypeDef(p: var TParser): PNode = else: a = parseTypeDesc(p) addSon(result, a) else: - addSon(result, nil) + addSon(result, ast.emptyNode) indAndComment(p, result) # special extension! proc parseVarTuple(p: var TParser): PNode = - var a: PNode result = newNodeP(nkVarTuple, p) getTok(p) # skip '(' optInd(p, result) while (p.tok.tokType == tkSymbol) or (p.tok.tokType == tkAccent): - a = identWithPragma(p) + var a = identWithPragma(p) addSon(result, a) if p.tok.tokType != tkComma: break getTok(p) optInd(p, a) - addSon(result, nil) # no type desc + addSon(result, ast.emptyNode) # no type desc optPar(p) eat(p, tkParRi) eat(p, tkEquals) @@ -1309,8 +1294,8 @@ proc simpleStmt(p: var TParser): PNode = of tkComment: result = newCommentStmt(p) else: if isExprStart(p): result = parseExprStmt(p) - else: result = nil - if result != nil: skipComment(p, result) + else: result = ast.emptyNode + if result.kind != nkEmpty: skipComment(p, result) proc complexOrSimpleStmt(p: var TParser): PNode = case p.tok.tokType @@ -1334,10 +1319,9 @@ proc complexOrSimpleStmt(p: var TParser): PNode = else: result = simpleStmt(p) proc parseStmt(p: var TParser): PNode = - var a: PNode if p.tok.tokType == tkInd: result = newNodeP(nkStmtList, p) - pushInd(p.lex^ , p.tok.indent) + pushInd(p.lex^, p.tok.indent) getTok(p) while true: case p.tok.tokType @@ -1347,8 +1331,8 @@ proc parseStmt(p: var TParser): PNode = getTok(p) break else: - a = complexOrSimpleStmt(p) - if a == nil: break + var a = complexOrSimpleStmt(p) + if a.kind == nkEmpty: break addSon(result, a) popInd(p.lex^ ) else: @@ -1357,14 +1341,13 @@ proc parseStmt(p: var TParser): PNode = of tkIf, tkWhile, tkCase, tkTry, tkFor, tkBlock, tkAsm, tkProc, tkIterator, tkMacro, tkType, tkConst, tkWhen, tkVar: parMessage(p, errComplexStmtRequiresInd) - result = nil + result = ast.emptyNode else: result = simpleStmt(p) - if result == nil: parMessage(p, errExprExpected, tokToStr(p.tok)) + if result.kind == nkEmpty: parMessage(p, errExprExpected, tokToStr(p.tok)) if p.tok.tokType == tkSad: getTok(p) proc parseAll(p: var TParser): PNode = - var a: PNode result = newNodeP(nkStmtList, p) while true: case p.tok.tokType @@ -1372,20 +1355,20 @@ proc parseAll(p: var TParser): PNode = of tkDed, tkInd: parMessage(p, errInvalidIndentation) of tkEof: break else: - a = complexOrSimpleStmt(p) - if a == nil: parMessage(p, errExprExpected, tokToStr(p.tok)) + var a = complexOrSimpleStmt(p) + if a.kind == nkEmpty: parMessage(p, errExprExpected, tokToStr(p.tok)) addSon(result, a) proc parseTopLevelStmt(p: var TParser): PNode = - result = nil + result = ast.emptyNode while true: case p.tok.tokType of tkSad: getTok(p) of tkDed, tkInd: parMessage(p, errInvalidIndentation) - break + getTok(p) of tkEof: break else: result = complexOrSimpleStmt(p) - if result == nil: parMessage(p, errExprExpected, tokToStr(p.tok)) + if result.kind == nkEmpty: parMessage(p, errExprExpected, tokToStr(p.tok)) break diff --git a/rod/rnimsyn.nim b/rod/rnimsyn.nim index 9424c4519..43b5f4800 100755 --- a/rod/rnimsyn.nim +++ b/rod/rnimsyn.nim @@ -323,13 +323,13 @@ proc lsons(n: PNode, start: int = 0, theEnd: int = - 1): int = proc lsub(n: PNode): int = # computes the length of a tree - if n == nil: return 0 if n.comment != nil: return maxLineLen + 1 case n.kind + of nkEmpty: result = 0 of nkTripleStrLit: if containsNL(n.strVal): result = maxLineLen + 1 else: result = len(atom(n)) - of nkEmpty..pred(nkTripleStrLit), succ(nkTripleStrLit)..nkNilLit: + of succ(nkEmpty)..pred(nkTripleStrLit), succ(nkTripleStrLit)..nkNilLit: result = len(atom(n)) of nkCall, nkBracketExpr, nkConv: result = lsub(n.sons[0]) + lcomma(n, 1) + 2 of nkHiddenStdConv, nkHiddenSubConv, nkHiddenCallConv: result = lsub(n[1]) @@ -348,8 +348,8 @@ proc lsub(n: PNode): int = of nkConstDef, nkIdentDefs: result = lcomma(n, 0, - 3) var L = sonsLen(n) - if n.sons[L - 2] != nil: result = result + lsub(n.sons[L - 2]) + 2 - if n.sons[L - 1] != nil: result = result + lsub(n.sons[L - 1]) + 3 + if n.sons[L - 2].kind != nkEmpty: result = result + lsub(n.sons[L - 2]) + 2 + if n.sons[L - 1].kind != nkEmpty: result = result + lsub(n.sons[L - 1]) + 3 of nkVarTuple: result = lcomma(n, 0, - 3) + len("() = ") + lsub(lastSon(n)) of nkChckRangeF: result = len("chckRangeF") + 2 + lcomma(n) of nkChckRange64: result = len("chckRange64") + 2 + lcomma(n) @@ -401,7 +401,7 @@ proc lsub(n: PNode): int = of nkGenericParams: result = lcomma(n) + 2 of nkFormalParams: result = lcomma(n, 1) + 2 - if n.sons[0] != nil: result = result + lsub(n.sons[0]) + 2 + if n.sons[0].kind != nkEmpty: result = result + lsub(n.sons[0]) + 2 of nkExceptBranch: result = lcomma(n, 0, -2) + lsub(lastSon(n)) + len("except_:_") else: result = maxLineLen + 1 @@ -430,7 +430,6 @@ proc gsub(g: var TSrcGen, n: PNode) = proc hasCom(n: PNode): bool = result = false - if n == nil: return if n.comment != nil: return true case n.kind of nkEmpty..nkNilLit: nil @@ -496,7 +495,7 @@ proc longMode(n: PNode, start: int = 0, theEnd: int = - 1): bool = break proc gstmts(g: var TSrcGen, n: PNode, c: TContext) = - if n == nil: return + if n.kind == nkEmpty: return if (n.kind == nkStmtList) or (n.kind == nkStmtListExpr): indentNL(g) for i in countup(0, sonsLen(n) - 1): @@ -598,7 +597,7 @@ proc gproc(g: var TSrcGen, n: PNode) = gsub(g, n.sons[2]) gsub(g, n.sons[3]) if not (renderNoBody in g.flags): - if n.sons[4] != nil: + if n.sons[4].kind != nkEmpty: put(g, tkSpaces, Space) putWithSpace(g, tkEquals, "=") indentNL(g) @@ -615,7 +614,7 @@ proc gproc(g: var TSrcGen, n: PNode) = proc gblock(g: var TSrcGen, n: PNode) = var c: TContext initContext(c) - if n.sons[0] != nil: + if n.sons[0].kind != nkEmpty: putWithSpace(g, tkBlock, "block") gsub(g, n.sons[0]) else: @@ -656,11 +655,11 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) = var L: int a: TContext - if n == nil: return if n.comment != nil: pushCom(g, n) case n.kind # atoms: of nkTripleStrLit: putRawStr(g, tkTripleStrLit, n.strVal) - of nkEmpty, nkType: put(g, tkInvalid, atom(n)) + of nkEmpty: nil + of nkType: put(g, tkInvalid, atom(n)) of nkSym, nkIdent: gident(g, n) of nkIntLit: put(g, tkIntLit, atom(n)) of nkInt8Lit: put(g, tkInt8Lit, atom(n)) @@ -765,7 +764,7 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) = of nkCheckedFieldExpr, nkHiddenAddr, nkHiddenDeref: gsub(g, n.sons[0]) of nkLambda: - assert(n.sons[genericParamsPos] == nil) + assert(n.sons[genericParamsPos].kind == nkEmpty) putWithSpace(g, tkLambda, "lambda") gsub(g, n.sons[paramsPos]) gsub(g, n.sons[pragmasPos]) @@ -775,10 +774,10 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) = of nkConstDef, nkIdentDefs: gcomma(g, n, 0, - 3) var L = sonsLen(n) - if n.sons[L - 2] != nil: + if n.sons[L - 2].kind != nkEmpty: putWithSpace(g, tkColon, ":") gsub(g, n.sons[L - 2]) - if n.sons[L - 1] != nil: + if n.sons[L - 1].kind != nkEmpty: put(g, tkSpaces, Space) putWithSpace(g, tkEquals, "=") gsub(g, n.sons[L - 1], c) @@ -855,7 +854,7 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) = gsub(g, n.sons[0]) gsub(g, n.sons[1]) put(g, tkSpaces, Space) - if n.sons[2] != nil: + if n.sons[2].kind != nkEmpty: putWithSpace(g, tkEquals, "=") gsub(g, n.sons[2]) of nkObjectTy: @@ -1029,7 +1028,7 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) = put(g, tkParLe, "(") gcomma(g, n, 1) put(g, tkParRi, ")") - if n.sons[0] != nil: + if n.sons[0].kind != nkEmpty: putWithSpace(g, tkColon, ":") gsub(g, n.sons[0]) of nkTupleTy: @@ -1055,10 +1054,9 @@ proc renderModule(n: PNode, filename: string, renderFlags: TRenderFlags = {}) = for i in countup(0, sonsLen(n) - 1): gsub(g, n.sons[i]) optNL(g) - if n.sons[i] != nil: - case n.sons[i].kind - of nkTypeSection, nkConstSection, nkVarSection, nkCommentStmt: putNL(g) - else: nil + case n.sons[i].kind + of nkTypeSection, nkConstSection, nkVarSection, nkCommentStmt: putNL(g) + else: nil gcoms(g) if open(f, filename, fmWrite): write(f, g.buf) diff --git a/rod/scanner.nim b/rod/scanner.nim index f40b8769d..1ef688dd3 100755 --- a/rod/scanner.nim +++ b/rod/scanner.nim @@ -175,7 +175,6 @@ proc findIdent(L: TLexer, indent: int): bool = for i in countdown(len(L.indentStack) - 1, 0): if L.indentStack[i] == indent: return true - result = false proc tokToStr(tok: PToken): string = case tok.tokType @@ -574,7 +573,7 @@ proc getSymbol(L: var TLexer, tok: var TToken) = of '_': if buf[pos+1] notin SymChars: lexMessage(L, errInvalidToken, "_") - return + break else: break Inc(pos) h = h +% h shl 3 @@ -587,11 +586,6 @@ proc getSymbol(L: var TLexer, tok: var TToken) = tok.tokType = tkSymbol else: tok.tokType = TTokType(tok.ident.id + ord(tkSymbol)) - when false: - if buf[pos] == '\"': - getString(L, tok, true) - if tok.tokType == tkRStrLit: tok.tokType = tkCallRStrLit - else: tok.tokType = tkCallTripleStrLit proc getOperator(L: var TLexer, tok: var TToken) = var pos = L.bufpos diff --git a/rod/semtypes.nim b/rod/semtypes.nim index 0fb359170..8585c70a4 100755 --- a/rod/semtypes.nim +++ b/rod/semtypes.nim @@ -133,7 +133,7 @@ proc semRangeAux(c: PContext, n: PNode, prev: PType): PType = {tyInt..tyInt64, tyEnum, tyBool, tyChar, tyFloat..tyFloat128}): liMessage(n.info, errOrdinalTypeExpected) if enumHasWholes(a.typ): - liMessage(n.info, errEnumXHasWholes, a.typ.sym.name.s) + liMessage(n.info, errEnumXHasHoles, a.typ.sym.name.s) if not leValue(a, b): liMessage(n.Info, errRangeIsEmpty) addSon(result.n, a) addSon(result.n, b) @@ -160,7 +160,7 @@ proc semArray(c: PContext, n: PNode, prev: PType): PType = if not isOrdinalType(indx): liMessage(n.sons[1].info, errOrdinalTypeExpected) if enumHasWholes(indx): - liMessage(n.sons[1].info, errEnumXHasWholes, indx.sym.name.s) + liMessage(n.sons[1].info, errEnumXHasHoles, indx.sym.name.s) base = semTypeNode(c, n.sons[2], nil) addSon(result, base) else: diff --git a/rod/syntaxes.nim b/rod/syntaxes.nim index 9361ad2ff..e7217950c 100755 --- a/rod/syntaxes.nim +++ b/rod/syntaxes.nim @@ -1,7 +1,7 @@ # # # The Nimrod Compiler -# (c) Copyright 2010 Andreas Rumpf +# (c) Copyright 2011 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -59,6 +59,7 @@ proc parseAll(p: var TParsers): PNode = result = pbraces.parseAll(p.parser) of skinEndX: InternalError("parser to implement") + result = ast.emptyNode # skinEndX: result := pendx.parseAll(p.parser); proc parseTopLevelStmt(p: var TParsers): PNode = @@ -69,6 +70,7 @@ proc parseTopLevelStmt(p: var TParsers): PNode = result = pbraces.parseTopLevelStmt(p.parser) of skinEndX: InternalError("parser to implement") + result = ast.emptyNode #skinEndX: result := pendx.parseTopLevelStmt(p.parser); proc UTF8_BOM(s: string): int = @@ -84,6 +86,7 @@ proc containsShebang(s: string, i: int): bool = result = s[j] == '/' proc parsePipe(filename: string, inputStream: PLLStream): PNode = + result = ast.emptyNode var s = LLStreamOpen(filename, fmRead) if s != nil: var line = LLStreamReadLine(s) @@ -143,7 +146,7 @@ proc applyFilter(p: var TParsers, n: PNode, filename: string, proc evalPipe(p: var TParsers, n: PNode, filename: string, start: PLLStream): PLLStream = result = start - if n == nil: return + if n.kind == nkEmpty: return if (n.kind == nkInfix) and (n.sons[0].kind == nkIdent) and IdentEq(n.sons[0].ident, "|"): for i in countup(1, 2): diff --git a/todo.txt b/todo.txt index 73f598fd9..476eb01e9 100755 --- a/todo.txt +++ b/todo.txt @@ -1,3 +1,8 @@ +- ban ``nil`` from the AST. This might also fix bugs concerning macros. + TODO: + * semantic checking (keep in mind incremental parsing!) + * code generators + - thread support: threadvar on Windows seems broken; add --deadlock_prevention:on|off switch - built-in serialization @@ -68,7 +73,6 @@ Low priority - fast assignment optimization for TPeg - better error messages for used keywords as identifiers - case statement branches should support constant sets -- ban ``nil`` from the AST. This might also fix bugs concerning macros. Library |