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