diff options
author | Araq <rumpf_a@web.de> | 2011-04-21 00:54:44 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2011-04-21 00:54:44 +0200 |
commit | 36c67455d4d3e5fa5222937b800f90ef811d8e86 (patch) | |
tree | 3ba25061d5b422ea9c241e98e39a43a352f139bc | |
parent | c3b16311dd7f547c19253af757ae53d58c715ad1 (diff) | |
download | Nim-36c67455d4d3e5fa5222937b800f90ef811d8e86.tar.gz |
got rid of some arcane module names
34 files changed, 326 insertions, 1257 deletions
diff --git a/compiler/c2nim/c2nim.nim b/compiler/c2nim/c2nim.nim index f4e185445..beb4465fc 100755 --- a/compiler/c2nim/c2nim.nim +++ b/compiler/c2nim/c2nim.nim @@ -8,7 +8,7 @@ # import - strutils, os, times, parseopt, llstream, ast, rnimsyn, options, msgs, + strutils, os, times, parseopt, llstream, ast, renderer, options, msgs, clex, cparse const diff --git a/compiler/c2nim/cparse.nim b/compiler/c2nim/cparse.nim index ce9caf7f5..d2b7caff6 100755 --- a/compiler/c2nim/cparse.nim +++ b/compiler/c2nim/cparse.nim @@ -14,7 +14,7 @@ # XXX cleanup of declaration handling. import - os, llstream, rnimsyn, clex, idents, strutils, pegs, ast, astalgo, msgs, + os, llstream, renderer, clex, idents, strutils, pegs, ast, astalgo, msgs, options, strtabs type diff --git a/compiler/cgen.nim b/compiler/cgen.nim index a15c4c4ca..d76793c9a 100755 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -14,7 +14,7 @@ import ast, astalgo, strutils, nhashes, trees, platform, magicsys, extccomp, options, nversion, nimsets, msgs, crc, bitsets, idents, lists, types, ccgutils, os, - times, ropes, math, passes, rodread, wordrecg, rnimsyn, treetab, cgmeth, + times, ropes, math, passes, rodread, wordrecg, treetab, cgmeth, rodutils when options.hasTinyCBackend: diff --git a/compiler/cgmeth.nim b/compiler/cgmeth.nim index f9b12647f..12d58cdc1 100755 --- a/compiler/cgmeth.nim +++ b/compiler/cgmeth.nim @@ -10,7 +10,7 @@ ## This module implements code generation for multi methods. import - options, ast, astalgo, msgs, idents, rnimsyn, types, magicsys + options, ast, astalgo, msgs, idents, renderer, types, magicsys proc genConv(n: PNode, d: PType, downcast: bool): PNode = var diff --git a/compiler/docgen.nim b/compiler/docgen.nim index ed5ca20ed..74316871d 100755 --- a/compiler/docgen.nim +++ b/compiler/docgen.nim @@ -13,7 +13,7 @@ import ast, astalgo, strutils, nhashes, options, nversion, msgs, os, ropes, idents, - wordrecg, math, syntaxes, rnimsyn, scanner, rst, times, highlite + wordrecg, math, syntaxes, renderer, lexer, rst, times, highlite proc CommandDoc*(filename: string) proc CommandRst2Html*(filename: string) diff --git a/compiler/ecmasgen.nim b/compiler/ecmasgen.nim index 6898b01d1..a46c2b805 100755 --- a/compiler/ecmasgen.nim +++ b/compiler/ecmasgen.nim @@ -14,7 +14,7 @@ import ast, astalgo, strutils, nhashes, trees, platform, magicsys, extccomp, options, nversion, nimsets, msgs, crc, bitsets, idents, lists, types, os, - times, ropes, math, passes, ccgutils, wordrecg, rnimsyn, rodread, rodutils + times, ropes, math, passes, ccgutils, wordrecg, renderer, rodread, rodutils proc ecmasgenPass*(): TPass # implementation diff --git a/compiler/evals.nim b/compiler/evals.nim index 7d0f9c801..d9c577367 100755 --- a/compiler/evals.nim +++ b/compiler/evals.nim @@ -15,7 +15,7 @@ import strutils, magicsys, lists, options, ast, astalgo, trees, treetab, nimsets, - msgs, os, condsyms, idents, rnimsyn, types, passes, semfold + msgs, os, condsyms, idents, renderer, types, passes, semfold type PStackFrame* = ref TStackFrame diff --git a/compiler/ptmplsyn.nim b/compiler/filter_tmpl.nim index 9699f1c58..0bb402874 100755 --- a/compiler/ptmplsyn.nim +++ b/compiler/filter_tmpl.nim @@ -11,7 +11,7 @@ import llstream, os, wordrecg, idents, strutils, ast, astalgo, msgs, options, - rnimsyn, filters + renderer, filters proc filterTmpl*(stdin: PLLStream, filename: string, call: PNode): PLLStream # #! template(subsChar='$', metaChar='#') | standard(version="0.7.2") diff --git a/compiler/filters.nim b/compiler/filters.nim index d1c61749d..43ac13c00 100755 --- a/compiler/filters.nim +++ b/compiler/filters.nim @@ -10,7 +10,8 @@ # This module implements Nimrod's simple filters and helpers for filters. import - llstream, os, wordrecg, idents, strutils, ast, astalgo, msgs, options, rnimsyn + llstream, os, wordrecg, idents, strutils, ast, astalgo, msgs, options, + renderer proc filterReplace*(stdin: PLLStream, filename: string, call: PNode): PLLStream proc filterStrip*(stdin: PLLStream, filename: string, call: PNode): PLLStream diff --git a/compiler/highlite.nim b/compiler/highlite.nim index c2fc95da8..c343074e7 100755 --- a/compiler/highlite.nim +++ b/compiler/highlite.nim @@ -12,7 +12,7 @@ # The interface supports one language nested in another. import - nhashes, options, msgs, strutils, platform, idents, lexbase, wordrecg, scanner + nhashes, options, msgs, strutils, platform, idents, lexbase, wordrecg, lexer type TTokenClass* = enum @@ -154,7 +154,7 @@ proc nimNextToken(g: var TGeneralTokenizer) = while not (g.buf[pos] in {'\0', '\x0A', '\x0D'}): inc(pos) of 'a'..'z', 'A'..'Z', '_', '\x80'..'\xFF': var id = "" - while g.buf[pos] in scanner.SymChars + {'_'}: + while g.buf[pos] in lexer.SymChars + {'_'}: add(id, g.buf[pos]) inc(pos) if (g.buf[pos] == '\"'): @@ -247,9 +247,9 @@ proc nimNextToken(g: var TGeneralTokenizer) = of '\0': g.kind = gtEof else: - if g.buf[pos] in scanner.OpChars: + if g.buf[pos] in lexer.OpChars: g.kind = gtOperator - while g.buf[pos] in scanner.OpChars: inc(pos) + while g.buf[pos] in lexer.OpChars: inc(pos) else: inc(pos) g.kind = gtNone @@ -462,10 +462,10 @@ proc clikeNextToken(g: var TGeneralTokenizer, keywords: openarray[string], of '\0': g.kind = gtEof else: - if g.buf[pos] in scanner.OpChars: + if g.buf[pos] in lexer.OpChars: g.kind = gtOperator - while g.buf[pos] in scanner.OpChars: inc(pos) - else: + while g.buf[pos] in lexer.OpChars: inc(pos) + else: inc(pos) g.kind = gtNone g.length = pos - g.pos diff --git a/compiler/scanner.nim b/compiler/lexer.nim index f3d83480d..f3d83480d 100755 --- a/compiler/scanner.nim +++ b/compiler/lexer.nim diff --git a/compiler/lookups.nim b/compiler/lookups.nim index f65fe24b7..80a6cd17e 100755 --- a/compiler/lookups.nim +++ b/compiler/lookups.nim @@ -10,7 +10,7 @@ # This module implements lookup helpers. import - ast, astalgo, idents, semdata, types, msgs, options, rodread, rnimsyn + ast, astalgo, idents, semdata, types, msgs, options, rodread, renderer type TOverloadIterMode* = enum diff --git a/compiler/main.nim b/compiler/main.nim index bd429cad9..c43d35a96 100755 --- a/compiler/main.nim +++ b/compiler/main.nim @@ -11,7 +11,7 @@ # module handling import - llstream, strutils, ast, astalgo, scanner, syntaxes, rnimsyn, options, msgs, + llstream, strutils, ast, astalgo, lexer, syntaxes, renderer, options, msgs, os, lists, condsyms, rodread, rodwrite, ropes, trees, wordrecg, sem, semdata, idents, passes, docgen, extccomp, cgen, ecmasgen, diff --git a/compiler/nimconf.nim b/compiler/nimconf.nim index 31558fe74..5d549c0f4 100755 --- a/compiler/nimconf.nim +++ b/compiler/nimconf.nim @@ -10,7 +10,7 @@ # This module handles the reading of the config file. import - llstream, nversion, commands, os, strutils, msgs, platform, condsyms, scanner, + llstream, nversion, commands, os, strutils, msgs, platform, condsyms, lexer, options, idents, wordrecg # ---------------- configuration file parser ----------------------------- diff --git a/compiler/nimrod.nim b/compiler/nimrod.nim index a1751da7f..05c7a2af1 100755 --- a/compiler/nimrod.nim +++ b/compiler/nimrod.nim @@ -11,7 +11,7 @@ when defined(gcc) and defined(windows): {.link: "icons/nimrod.res".} import - times, commands, scanner, condsyms, options, msgs, nversion, nimconf, ropes, + times, commands, lexer, condsyms, options, msgs, nversion, nimconf, ropes, extccomp, strutils, os, platform, main, parseopt when hasTinyCBackend: diff --git a/compiler/nimsets.nim b/compiler/nimsets.nim index 337aedda9..218cd8b62 100755 --- a/compiler/nimsets.nim +++ b/compiler/nimsets.nim @@ -10,7 +10,7 @@ # this unit handles Nimrod sets; it implements symbolic sets import - ast, astalgo, trees, nversion, msgs, platform, bitsets, types, rnimsyn + ast, astalgo, trees, nversion, msgs, platform, bitsets, types, renderer proc toBitSet*(s: PNode, b: var TBitSet) # this function is used for case statement checking: @@ -172,4 +172,4 @@ proc SetHasRange(s: PNode): bool = proc emptyRange(a, b: PNode): bool = result = not leValue(a, b) # a > b iff not (a <= b) - \ No newline at end of file + diff --git a/compiler/pnimsyn.nim b/compiler/parser.nim index 80adc7824..871f486fc 100755 --- a/compiler/pnimsyn.nim +++ b/compiler/parser.nim @@ -15,7 +15,7 @@ # from the grammar and how comments belong to the AST. import - llstream, scanner, idents, strutils, ast, msgs + llstream, lexer, idents, strutils, ast, msgs type TParser*{.final.} = object # a TParser object represents a module that diff --git a/compiler/pas2nim/pas2nim.nim b/compiler/pas2nim/pas2nim.nim index 5c7b68857..7f66e8e47 100755 --- a/compiler/pas2nim/pas2nim.nim +++ b/compiler/pas2nim/pas2nim.nim @@ -8,7 +8,7 @@ # import - strutils, os, parseopt, llstream, ast, rnimsyn, options, msgs, + strutils, os, parseopt, llstream, ast, renderer, options, msgs, paslex, pasparse const diff --git a/compiler/passes.nim b/compiler/passes.nim index b380cd66f..34e2b03a5 100755 --- a/compiler/passes.nim +++ b/compiler/passes.nim @@ -12,8 +12,8 @@ import strutils, lists, options, ast, astalgo, llstream, msgs, platform, os, - condsyms, idents, rnimsyn, types, extccomp, math, magicsys, nversion, nimsets, - syntaxes, times, rodread + condsyms, idents, renderer, types, extccomp, math, magicsys, nversion, + nimsets, syntaxes, times, rodread type TPassContext* = object of TObject # the pass's context diff --git a/compiler/pbraces.nim b/compiler/pbraces.nim index 45d38e342..18d654d6c 100755 --- a/compiler/pbraces.nim +++ b/compiler/pbraces.nim @@ -8,1194 +8,11 @@ # import - llstream, scanner, idents, strutils, ast, msgs, pnimsyn + llstream, lexer, parser, idents, strutils, ast, msgs -proc ParseAll*(p: var TParser): PNode -proc parseTopLevelStmt*(p: var TParser): PNode - # implements an iterator. Returns the next top-level statement or nil if end - # of stream. -# implementation -# ------------------- Expression parsing ------------------------------------ - -proc parseExpr(p: var TParser): PNode -proc parseStmt(p: var TParser): PNode -proc parseTypeDesc(p: var TParser): PNode -proc parseParamList(p: var TParser): PNode -proc optExpr(p: var TParser): PNode = - # [expr] - if (p.tok.tokType != tkComma) and (p.tok.tokType != tkBracketRi) and - (p.tok.tokType != tkDotDot): - result = parseExpr(p) - else: - result = nil - -proc dotdotExpr(p: var TParser, first: PNode = nil): PNode = - result = newNodeP(nkRange, p) - addSon(result, first) - getTok(p) - optInd(p, result) - addSon(result, optExpr(p)) - -proc indexExpr(p: var TParser): PNode = - # indexExpr ::= '..' [expr] | expr ['=' expr | '..' expr] - var a, b: PNode - if p.tok.tokType == tkDotDot: - result = dotdotExpr(p) - else: - a = parseExpr(p) - case p.tok.tokType - of tkEquals: - result = newNodeP(nkExprEqExpr, p) - addSon(result, a) - getTok(p) - if p.tok.tokType == tkDotDot: - addSon(result, dotdotExpr(p)) - else: - b = parseExpr(p) - if p.tok.tokType == tkDotDot: b = dotdotExpr(p, b) - addSon(result, b) - of tkDotDot: - result = dotdotExpr(p, a) - else: result = a - -proc indexExprList(p: var TParser, first: PNode): PNode = - var a: PNode - result = newNodeP(nkBracketExpr, p) - addSon(result, first) - getTok(p) - optInd(p, result) - while (p.tok.tokType != tkBracketRi) and (p.tok.tokType != tkEof) and - (p.tok.tokType != tkSad): - a = indexExpr(p) - addSon(result, a) - if p.tok.tokType != tkComma: break - getTok(p) - optInd(p, a) - optPar(p) - eat(p, tkBracketRi) - -proc exprColonEqExpr(p: var TParser, kind: TNodeKind, tok: TTokType): PNode = - var a: PNode - a = parseExpr(p) - if p.tok.tokType == tok: - result = newNodeP(kind, p) - getTok(p) #optInd(p, result); - addSon(result, a) - addSon(result, parseExpr(p)) - else: - result = a - -proc exprListAux(p: var TParser, elemKind: TNodeKind, endTok, sepTok: TTokType, - result: PNode) = - var a: PNode - getTok(p) - optInd(p, result) - while (p.tok.tokType != endTok) and (p.tok.tokType != tkEof): - a = exprColonEqExpr(p, elemKind, sepTok) - addSon(result, a) - if p.tok.tokType != tkComma: break - getTok(p) - optInd(p, a) - eat(p, endTok) - -proc qualifiedIdent(p: var TParser): PNode = - var a: PNode - result = parseSymbol(p) - if p.tok.tokType == tkDot: - getTok(p) - optInd(p, result) - a = result - result = newNodeI(nkDotExpr, a.info) - addSon(result, a) - addSon(result, parseSymbol(p)) - -proc qualifiedIdentListAux(p: var TParser, endTok: TTokType, result: PNode) = - var a: PNode - getTok(p) - optInd(p, result) - while (p.tok.tokType != endTok) and (p.tok.tokType != tkEof): - a = qualifiedIdent(p) - addSon(result, a) - if p.tok.tokType != tkComma: break - getTok(p) - optInd(p, a) - eat(p, endTok) - -proc exprColonEqExprListAux(p: var TParser, elemKind: TNodeKind, - endTok, sepTok: TTokType, result: PNode) = - var a: PNode - getTok(p) - optInd(p, result) - while (p.tok.tokType != endTok) and (p.tok.tokType != tkEof) and - (p.tok.tokType != tkSad): - a = exprColonEqExpr(p, elemKind, sepTok) - addSon(result, a) - if p.tok.tokType != tkComma: break - getTok(p) - optInd(p, a) - optPar(p) - eat(p, endTok) - -proc exprColonEqExprList(p: var TParser, kind, elemKind: TNodeKind, - endTok, sepTok: TTokType): PNode = - result = newNodeP(kind, p) - exprColonEqExprListAux(p, elemKind, endTok, sepTok, result) - -proc parseCast(p: var TParser): PNode = - result = newNodeP(nkCast, p) - getTok(p) - eat(p, tkBracketLe) - optInd(p, result) - addSon(result, parseTypeDesc(p)) - optPar(p) - eat(p, tkBracketRi) - eat(p, tkParLe) - optInd(p, result) - addSon(result, parseExpr(p)) - optPar(p) - eat(p, tkParRi) - -proc parseAddr(p: var TParser): PNode = - result = newNodeP(nkAddr, p) - getTok(p) - eat(p, tkParLe) - optInd(p, result) - addSon(result, parseExpr(p)) - optPar(p) - eat(p, tkParRi) - -proc parseGStrLit(p: var TParser, a: PNode): PNode = - case p.tok.tokType - of tkGStrLit: - result = newNodeP(nkCallStrLit, p) - addSon(result, a) - addSon(result, newStrNodeP(nkRStrLit, p.tok.literal, p)) - getTok(p) - of tkGTripleStrLit: - result = newNodeP(nkCallStrLit, p) - addSon(result, a) - addSon(result, newStrNodeP(nkTripleStrLit, p.tok.literal, p)) - getTok(p) - else: - result = a - -proc identOrLiteral(p: var TParser): PNode = - case p.tok.tokType - of tkSymbol: - result = newIdentNodeP(p.tok.ident, p) - getTok(p) - result = parseGStrLit(p, result) - of tkAccent: - result = accExpr(p) # literals - of tkIntLit: - result = newIntNodeP(nkIntLit, p.tok.iNumber, p) - setBaseFlags(result, p.tok.base) - getTok(p) - of tkInt8Lit: - result = newIntNodeP(nkInt8Lit, p.tok.iNumber, p) - setBaseFlags(result, p.tok.base) - getTok(p) - of tkInt16Lit: - result = newIntNodeP(nkInt16Lit, p.tok.iNumber, p) - setBaseFlags(result, p.tok.base) - getTok(p) - of tkInt32Lit: - result = newIntNodeP(nkInt32Lit, p.tok.iNumber, p) - setBaseFlags(result, p.tok.base) - getTok(p) - of tkInt64Lit: - result = newIntNodeP(nkInt64Lit, p.tok.iNumber, p) - setBaseFlags(result, p.tok.base) - getTok(p) - of tkFloatLit: - result = newFloatNodeP(nkFloatLit, p.tok.fNumber, p) - setBaseFlags(result, p.tok.base) - getTok(p) - of tkFloat32Lit: - result = newFloatNodeP(nkFloat32Lit, p.tok.fNumber, p) - setBaseFlags(result, p.tok.base) - getTok(p) - of tkFloat64Lit: - result = newFloatNodeP(nkFloat64Lit, p.tok.fNumber, p) - setBaseFlags(result, p.tok.base) - getTok(p) - of tkStrLit: - result = newStrNodeP(nkStrLit, p.tok.literal, p) - getTok(p) - of tkRStrLit: - result = newStrNodeP(nkRStrLit, p.tok.literal, p) - getTok(p) - of tkTripleStrLit: - result = newStrNodeP(nkTripleStrLit, p.tok.literal, p) - getTok(p) - of tkCharLit: - result = newIntNodeP(nkCharLit, ord(p.tok.literal[0]), p) - getTok(p) - of tkNil: - result = newNodeP(nkNilLit, p) - getTok(p) - of tkParLe: - # () constructor - result = exprColonEqExprList(p, nkPar, nkExprColonExpr, tkParRi, tkColon) - of tkCurlyLe: - # {} constructor - result = exprColonEqExprList(p, nkCurly, nkRange, tkCurlyRi, tkDotDot) - of tkBracketLe: - # [] constructor - result = exprColonEqExprList(p, nkBracket, nkExprColonExpr, tkBracketRi, - tkColon) - of tkCast: - result = parseCast(p) - of tkAddr: - result = parseAddr(p) - else: - parMessage(p, errExprExpected, tokToStr(p.tok)) - getTok(p) # we must consume a token here to prevend endless loops! - result = nil - -proc primary(p: var TParser): PNode = - var a: PNode - # prefix operator? - if (p.tok.tokType == tkNot) or (p.tok.tokType == tkOpr): - result = newNodeP(nkPrefix, p) - a = newIdentNodeP(p.tok.ident, p) - addSon(result, a) - getTok(p) - optInd(p, a) - addSon(result, primary(p)) - return - elif p.tok.tokType == tkBind: - result = newNodeP(nkBind, p) - getTok(p) - optInd(p, result) - addSon(result, primary(p)) - return - result = identOrLiteral(p) - while true: - case p.tok.tokType - of tkParLe: - a = result - result = newNodeP(nkCall, p) - addSon(result, a) - exprColonEqExprListAux(p, nkExprEqExpr, tkParRi, tkEquals, result) - of tkDot: - a = result - result = newNodeP(nkDotExpr, p) - addSon(result, a) - getTok(p) # skip '.' - optInd(p, result) - addSon(result, parseSymbol(p)) - result = parseGStrLit(p, result) - of tkHat: - a = result - result = newNodeP(nkDerefExpr, p) - addSon(result, a) - getTok(p) - of tkBracketLe: - result = indexExprList(p, result) - else: break - -proc lowestExprAux(p: var TParser, v: var PNode, limit: int): PToken = - var - op, nextop: PToken - opPred: int - v2, node, opNode: PNode - v = primary(p) # expand while operators have priorities higher than 'limit' - op = p.tok - opPred = getPrecedence(p.tok) - while (opPred > limit): - node = newNodeP(nkInfix, p) - opNode = newIdentNodeP(op.ident, p) # skip operator: - getTok(p) - optInd(p, opNode) # read sub-expression with higher priority - nextop = lowestExprAux(p, v2, opPred) - addSon(node, opNode) - addSon(node, v) - addSon(node, v2) - v = node - op = nextop - opPred = getPrecedence(nextop) - result = op # return first untreated operator - -proc lowestExpr(p: var TParser): PNode = - discard lowestExprAux(p, result, - 1) - -proc parseIfExpr(p: var TParser): PNode = - # if (expr) expr else expr - var branch: PNode - result = newNodeP(nkIfExpr, p) - while true: - getTok(p) # skip `if`, `elif` - branch = newNodeP(nkElifExpr, p) - eat(p, tkParLe) - addSon(branch, parseExpr(p)) - eat(p, tkParRi) - addSon(branch, parseExpr(p)) - addSon(result, branch) - if p.tok.tokType != tkElif: break - branch = newNodeP(nkElseExpr, p) - eat(p, tkElse) - addSon(branch, parseExpr(p)) - addSon(result, branch) - -proc parsePragma(p: var TParser): PNode = - var a: PNode - result = newNodeP(nkPragma, p) - getTok(p) - optInd(p, result) - while (p.tok.tokType != tkCurlyDotRi) and (p.tok.tokType != tkCurlyRi) and - (p.tok.tokType != tkEof) and (p.tok.tokType != tkSad): - a = exprColonEqExpr(p, nkExprColonExpr, tkColon) - addSon(result, a) - if p.tok.tokType == tkComma: - getTok(p) - optInd(p, a) - optPar(p) - if (p.tok.tokType == tkCurlyDotRi) or (p.tok.tokType == tkCurlyRi): getTok(p) - else: parMessage(p, errTokenExpected, ".}") - -proc identVis(p: var TParser): PNode = - # identifier with visability - var a: PNode - a = parseSymbol(p) - if p.tok.tokType == tkOpr: - result = newNodeP(nkPostfix, p) - addSon(result, newIdentNodeP(p.tok.ident, p)) - addSon(result, a) - getTok(p) - else: - result = a - -proc identWithPragma(p: var TParser): PNode = - var a: PNode - a = identVis(p) - if p.tok.tokType == tkCurlyDotLe: - result = newNodeP(nkPragmaExpr, p) - addSon(result, a) - addSon(result, parsePragma(p)) - else: - result = a - -type - TDeclaredIdentFlag = enum - withPragma, # identifier may have pragma - withBothOptional # both ':' and '=' parts are optional - TDeclaredIdentFlags = set[TDeclaredIdentFlag] - -proc parseIdentColonEquals(p: var TParser, flags: TDeclaredIdentFlags): PNode = - var a: PNode - result = newNodeP(nkIdentDefs, p) - while true: - case p.tok.tokType - of tkSymbol, tkAccent: - if withPragma in flags: a = identWithPragma(p) - else: a = parseSymbol(p) - if a == nil: return - else: break - addSon(result, a) - if p.tok.tokType != tkComma: break - getTok(p) - optInd(p, a) - if p.tok.tokType == tkColon: - getTok(p) - optInd(p, result) - addSon(result, parseTypeDesc(p)) - else: - addSon(result, nil) - if (p.tok.tokType != tkEquals) and not (withBothOptional in flags): - parMessage(p, errColonOrEqualsExpected, tokToStr(p.tok)) - if p.tok.tokType == tkEquals: - getTok(p) - optInd(p, result) - addSon(result, parseExpr(p)) - else: - addSon(result, nil) - -proc parseTuple(p: var TParser): PNode = - var a: PNode - result = newNodeP(nkTupleTy, p) - getTok(p) - eat(p, tkBracketLe) - optInd(p, result) - while (p.tok.tokType == tkSymbol) or (p.tok.tokType == tkAccent): - a = parseIdentColonEquals(p, {}) - addSon(result, a) - if p.tok.tokType != tkComma: break - getTok(p) - optInd(p, a) - optPar(p) - eat(p, tkBracketRi) - -proc parseParamList(p: var TParser): PNode = - var a: PNode - result = newNodeP(nkFormalParams, p) - addSon(result, nil) # return type - if p.tok.tokType == tkParLe: - getTok(p) - optInd(p, result) - while true: - case p.tok.tokType - of tkSymbol, tkAccent: a = parseIdentColonEquals(p, {}) - of tkParRi: break - else: - parMessage(p, errTokenExpected, ")") - break - addSon(result, a) - if p.tok.tokType != tkComma: break - getTok(p) - optInd(p, a) - optPar(p) - eat(p, tkParRi) - if p.tok.tokType == tkColon: - getTok(p) - optInd(p, result) - result.sons[0] = parseTypeDesc(p) - -proc parseProcExpr(p: var TParser, isExpr: bool): PNode = - # either a proc type or a anonymous proc - var - pragmas, params: PNode - info: TLineInfo - info = parLineInfo(p) - getTok(p) - params = parseParamList(p) - if p.tok.tokType == tkCurlyDotLe: pragmas = parsePragma(p) - else: pragmas = nil - if (p.tok.tokType == tkCurlyLe) and isExpr: - result = newNodeI(nkLambda, info) - addSon(result, nil) # no name part - addSon(result, nil) # no generic parameters - addSon(result, params) - addSon(result, pragmas) #getTok(p); skipComment(p, result); - addSon(result, parseStmt(p)) - else: - result = newNodeI(nkProcTy, info) - addSon(result, params) - addSon(result, pragmas) - -proc parseTypeDescKAux(p: var TParser, kind: TNodeKind): PNode = - result = newNodeP(kind, p) - getTok(p) - optInd(p, result) - addSon(result, parseTypeDesc(p)) - -proc parseExpr(p: var TParser): PNode = - # - #expr ::= lowestExpr - # | 'if' expr ':' expr ('elif' expr ':' expr)* 'else' ':' expr - # | 'var' expr - # | 'ref' expr - # | 'ptr' expr - # | 'type' expr - # | 'tuple' tupleDesc - # | 'proc' paramList [pragma] ['=' stmt] - # - case p.tok.toktype - of tkVar: result = parseTypeDescKAux(p, nkVarTy) - of tkRef: result = parseTypeDescKAux(p, nkRefTy) - of tkPtr: result = parseTypeDescKAux(p, nkPtrTy) - of tkType: result = parseTypeDescKAux(p, nkTypeOfExpr) - of tkTuple: result = parseTuple(p) - of tkProc: result = parseProcExpr(p, true) - of tkIf: result = parseIfExpr(p) - else: result = lowestExpr(p) - -proc parseTypeDesc(p: var TParser): PNode = - if p.tok.toktype == tkProc: result = parseProcExpr(p, false) - else: result = parseExpr(p) - -proc isExprStart(p: TParser): bool = - case p.tok.tokType - of tkSymbol, tkAccent, tkOpr, tkNot, tkNil, tkCast, tkIf, tkProc, tkBind, - tkParLe, tkBracketLe, tkCurlyLe, tkIntLit..tkCharLit, tkVar, tkRef, tkPtr, - tkTuple, tkType: - result = true - else: result = false - -proc parseExprStmt(p: var TParser): PNode = - var a, b, e: PNode - a = lowestExpr(p) - if p.tok.tokType == tkEquals: - getTok(p) - optInd(p, result) - b = parseExpr(p) - result = newNodeI(nkAsgn, a.info) - addSon(result, a) - addSon(result, b) - else: - result = newNodeP(nkCommand, p) - result.info = a.info - addSon(result, a) - while true: - if not isExprStart(p): break - e = parseExpr(p) - addSon(result, e) - if p.tok.tokType != tkComma: break - getTok(p) - optInd(p, a) - if sonsLen(result) <= 1: result = a - else: a = result - if p.tok.tokType == tkCurlyLe: - # macro statement - result = newNodeP(nkMacroStmt, p) - result.info = a.info - addSon(result, a) - getTok(p) - skipComment(p, result) - if (p.tok.tokType == tkInd) or - not (p.tok.TokType in {tkOf, tkElif, tkElse, tkExcept}): - addSon(result, parseStmt(p)) - while true: - if p.tok.tokType == tkSad: getTok(p) - case p.tok.tokType - of tkOf: - b = newNodeP(nkOfBranch, p) - exprListAux(p, nkRange, tkCurlyLe, tkDotDot, b) - of tkElif: - b = newNodeP(nkElifBranch, p) - getTok(p) - optInd(p, b) - addSon(b, parseExpr(p)) - eat(p, tkCurlyLe) - of tkExcept: - b = newNodeP(nkExceptBranch, p) - qualifiedIdentListAux(p, tkCurlyLe, b) - skipComment(p, b) - of tkElse: - b = newNodeP(nkElse, p) - getTok(p) - eat(p, tkCurlyLe) - else: break - addSon(b, parseStmt(p)) - eat(p, tkCurlyRi) - addSon(result, b) - if b.kind == nkElse: break - eat(p, tkCurlyRi) - -proc parseImportOrIncludeStmt(p: var TParser, kind: TNodeKind): PNode = - var a: PNode - result = newNodeP(kind, p) - getTok(p) # skip `import` or `include` - optInd(p, result) - while true: - case p.tok.tokType - of tkEof, tkSad, tkDed: - break - of tkSymbol, tkAccent: - a = parseSymbol(p) - of tkRStrLit: - a = newStrNodeP(nkRStrLit, p.tok.literal, p) - getTok(p) - of tkStrLit: - a = newStrNodeP(nkStrLit, p.tok.literal, p) - getTok(p) - of tkTripleStrLit: - a = newStrNodeP(nkTripleStrLit, p.tok.literal, p) - getTok(p) - else: - parMessage(p, errIdentifierExpected, tokToStr(p.tok)) - break - addSon(result, a) - if p.tok.tokType != tkComma: break - getTok(p) - optInd(p, a) - -proc parseFromStmt(p: var TParser): PNode = - var a: PNode - result = newNodeP(nkFromStmt, p) - getTok(p) # skip `from` - optInd(p, result) - case p.tok.tokType - of tkSymbol, tkAccent: - a = parseSymbol(p) - of tkRStrLit: - a = newStrNodeP(nkRStrLit, p.tok.literal, p) - getTok(p) - of tkStrLit: - a = newStrNodeP(nkStrLit, p.tok.literal, p) - getTok(p) - of tkTripleStrLit: - a = newStrNodeP(nkTripleStrLit, p.tok.literal, p) - getTok(p) - else: - parMessage(p, errIdentifierExpected, tokToStr(p.tok)) - return - addSon(result, a) #optInd(p, a); - eat(p, tkImport) - optInd(p, result) - while true: - case p.tok.tokType #optInd(p, a); - of tkEof, tkSad, tkDed: - break - of tkSymbol, tkAccent: - a = parseSymbol(p) - else: - parMessage(p, errIdentifierExpected, tokToStr(p.tok)) - break - addSon(result, a) - if p.tok.tokType != tkComma: break - getTok(p) - optInd(p, a) - -proc parseReturnOrRaise(p: var TParser, kind: TNodeKind): PNode = - result = newNodeP(kind, p) - getTok(p) - optInd(p, result) - case p.tok.tokType - of tkEof, tkSad, tkDed: addSon(result, nil) - else: addSon(result, parseExpr(p)) - -proc parseYieldOrDiscard(p: var TParser, kind: TNodeKind): PNode = - result = newNodeP(kind, p) - getTok(p) - optInd(p, result) - addSon(result, parseExpr(p)) - -proc parseBreakOrContinue(p: var TParser, kind: TNodeKind): PNode = - result = newNodeP(kind, p) - getTok(p) - optInd(p, result) - case p.tok.tokType - of tkEof, tkSad, tkDed: addSon(result, nil) - else: addSon(result, parseSymbol(p)) - -proc parseIfOrWhen(p: var TParser, kind: TNodeKind): PNode = - var branch: PNode - result = newNodeP(kind, p) - while true: - getTok(p) # skip `if`, `when`, `elif` - branch = newNodeP(nkElifBranch, p) - optInd(p, branch) - eat(p, tkParLe) - addSon(branch, parseExpr(p)) - eat(p, tkParRi) - skipComment(p, branch) - addSon(branch, parseStmt(p)) - skipComment(p, branch) - addSon(result, branch) - if p.tok.tokType != tkElif: break - if p.tok.tokType == tkElse: - branch = newNodeP(nkElse, p) - eat(p, tkElse) - skipComment(p, branch) - addSon(branch, parseStmt(p)) - addSon(result, branch) - -proc parseWhile(p: var TParser): PNode = - result = newNodeP(nkWhileStmt, p) - getTok(p) - optInd(p, result) - eat(p, tkParLe) - addSon(result, parseExpr(p)) - eat(p, tkParRi) - skipComment(p, result) - addSon(result, parseStmt(p)) - -proc parseCase(p: var TParser): PNode = - var - b: PNode - inElif: bool - result = newNodeP(nkCaseStmt, p) - getTok(p) - eat(p, tkParLe) - addSon(result, parseExpr(p)) - eat(p, tkParRi) - skipComment(p, result) - inElif = false - while true: - if p.tok.tokType == tkSad: getTok(p) - case p.tok.tokType - of tkOf: - if inElif: break - b = newNodeP(nkOfBranch, p) - exprListAux(p, nkRange, tkColon, tkDotDot, b) - of tkElif: - inElif = true - b = newNodeP(nkElifBranch, p) - getTok(p) - optInd(p, b) - addSon(b, parseExpr(p)) - eat(p, tkColon) - of tkElse: - b = newNodeP(nkElse, p) - getTok(p) - eat(p, tkColon) - else: break - skipComment(p, b) - addSon(b, parseStmt(p)) - addSon(result, b) - if b.kind == nkElse: break - -proc parseTry(p: var TParser): PNode = - var b: PNode - result = newNodeP(nkTryStmt, p) - getTok(p) - eat(p, tkColon) - skipComment(p, result) - addSon(result, parseStmt(p)) - b = nil - while true: - if p.tok.tokType == tkSad: getTok(p) - case p.tok.tokType - of tkExcept: - b = newNodeP(nkExceptBranch, p) - qualifiedIdentListAux(p, tkColon, b) - of tkFinally: - b = newNodeP(nkFinally, p) - getTok(p) - eat(p, tkColon) - else: break - skipComment(p, b) - addSon(b, parseStmt(p)) - addSon(result, b) - if b.kind == nkFinally: break - if b == nil: parMessage(p, errTokenExpected, "except") - -proc parseFor(p: var TParser): PNode = - var a: PNode - result = newNodeP(nkForStmt, p) - getTok(p) - optInd(p, result) - a = parseSymbol(p) - addSon(result, a) - while p.tok.tokType == tkComma: - getTok(p) - optInd(p, a) - a = parseSymbol(p) - addSon(result, a) - eat(p, tkIn) - addSon(result, exprColonEqExpr(p, nkRange, tkDotDot)) - eat(p, tkColon) - skipComment(p, result) - addSon(result, parseStmt(p)) - -proc parseBlock(p: var TParser): PNode = - result = newNodeP(nkBlockStmt, p) - getTok(p) - optInd(p, result) - case p.tok.tokType - of tkEof, tkSad, tkDed, tkColon: addSon(result, nil) - else: addSon(result, parseSymbol(p)) - eat(p, tkColon) - skipComment(p, result) - addSon(result, parseStmt(p)) - -proc parseAsm(p: var TParser): PNode = - result = newNodeP(nkAsmStmt, p) - getTok(p) - optInd(p, result) - if p.tok.tokType == tkCurlyDotLe: addSon(result, parsePragma(p)) - else: addSon(result, nil) - case p.tok.tokType - of tkStrLit: addSon(result, newStrNodeP(nkStrLit, p.tok.literal, p)) - of tkRStrLit: addSon(result, newStrNodeP(nkRStrLit, p.tok.literal, p)) - of tkTripleStrLit: addSon(result, - newStrNodeP(nkTripleStrLit, p.tok.literal, p)) - else: - parMessage(p, errStringLiteralExpected) - addSon(result, nil) - return - getTok(p) - -proc parseGenericParamList(p: var TParser): PNode = - var a: PNode - result = newNodeP(nkGenericParams, p) - getTok(p) - optInd(p, result) - while (p.tok.tokType == tkSymbol) or (p.tok.tokType == tkAccent): - a = parseIdentColonEquals(p, {withBothOptional}) - addSon(result, a) - if p.tok.tokType != tkComma: break - getTok(p) - optInd(p, a) - optPar(p) - eat(p, tkBracketRi) - -proc parseRoutine(p: var TParser, kind: TNodeKind): PNode = - result = newNodeP(kind, p) - getTok(p) - optInd(p, result) - addSon(result, identVis(p)) - if p.tok.tokType == tkBracketLe: addSon(result, parseGenericParamList(p)) - else: addSon(result, nil) - addSon(result, parseParamList(p)) - if p.tok.tokType == tkCurlyDotLe: addSon(result, parsePragma(p)) - else: addSon(result, nil) - if p.tok.tokType == tkEquals: - getTok(p) - skipComment(p, result) - addSon(result, parseStmt(p)) - else: - addSon(result, nil) - indAndComment(p, result) # XXX: document this in the grammar! - -proc newCommentStmt(p: var TParser): PNode = - result = newNodeP(nkCommentStmt, p) - result.info.line = result.info.line - int16(1) - -type - TDefParser = proc (p: var TParser): PNode - -proc parseSection(p: var TParser, kind: TNodeKind, defparser: TDefParser): PNode = - var a: PNode - result = newNodeP(kind, p) - getTok(p) - skipComment(p, result) - case p.tok.tokType - of tkInd: - pushInd(p.lex[] , p.tok.indent) - getTok(p) - skipComment(p, result) - while true: - case p.tok.tokType - of tkSad: - getTok(p) - of tkSymbol, tkAccent: - a = defparser(p) - skipComment(p, a) - addSon(result, a) - of tkDed: - getTok(p) - break - of tkEof: - break # BUGFIX - of tkComment: - a = newCommentStmt(p) - skipComment(p, a) - addSon(result, a) - else: - parMessage(p, errIdentifierExpected, tokToStr(p.tok)) - break - popInd(p.lex[] ) - of tkSymbol, tkAccent, tkParLe: - # tkParLe is allowed for ``var (x, y) = ...`` tuple parsing - addSon(result, defparser(p)) - else: parMessage(p, errIdentifierExpected, tokToStr(p.tok)) - -proc parseConstant(p: var TParser): PNode = - result = newNodeP(nkConstDef, p) - addSon(result, identWithPragma(p)) - if p.tok.tokType == tkColon: - getTok(p) - optInd(p, result) - addSon(result, parseTypeDesc(p)) - else: - addSon(result, nil) - eat(p, tkEquals) - optInd(p, result) - addSon(result, parseExpr(p)) - indAndComment(p, result) # XXX: special extension! - -proc parseConstSection(p: var TParser): PNode = - result = newNodeP(nkConstSection, p) - getTok(p) - skipComment(p, result) - if p.tok.tokType == tkCurlyLe: - getTok(p) - skipComment(p, result) - while (p.tok.tokType != tkCurlyRi) and (p.tok.tokType != tkEof): - addSon(result, parseConstant(p)) - eat(p, tkCurlyRi) - else: - addSon(result, parseConstant(p)) - -proc parseEnum(p: var TParser): PNode = - var a, b: PNode - result = newNodeP(nkEnumTy, p) - a = nil - getTok(p) - optInd(p, result) - if p.tok.tokType == tkOf: - a = newNodeP(nkOfInherit, p) - getTok(p) - optInd(p, a) - addSon(a, parseTypeDesc(p)) - addSon(result, a) - else: - addSon(result, nil) - while true: - case p.tok.tokType - of tkEof, tkSad, tkDed: break - else: a = parseSymbol(p) - optInd(p, a) - if p.tok.tokType == tkEquals: - getTok(p) - optInd(p, a) - b = a - a = newNodeP(nkEnumFieldDef, p) - addSon(a, b) - addSon(a, parseExpr(p)) - skipComment(p, a) - if p.tok.tokType == tkComma: - getTok(p) - optInd(p, a) - addSon(result, a) - -proc parseObjectPart(p: var TParser): PNode -proc parseObjectWhen(p: var TParser): PNode = - var branch: PNode - result = newNodeP(nkRecWhen, p) - while true: - getTok(p) # skip `when`, `elif` - branch = newNodeP(nkElifBranch, p) - optInd(p, branch) - addSon(branch, parseExpr(p)) - eat(p, tkColon) - skipComment(p, branch) - addSon(branch, parseObjectPart(p)) - skipComment(p, branch) - addSon(result, branch) - if p.tok.tokType != tkElif: break - if p.tok.tokType == tkElse: - branch = newNodeP(nkElse, p) - eat(p, tkElse) - eat(p, tkColon) - skipComment(p, branch) - addSon(branch, parseObjectPart(p)) - addSon(result, branch) - -proc parseObjectCase(p: var TParser): PNode = - var a, b: PNode - result = newNodeP(nkRecCase, p) - getTok(p) - a = newNodeP(nkIdentDefs, p) - addSon(a, identWithPragma(p)) - eat(p, tkColon) - addSon(a, parseTypeDesc(p)) - addSon(a, nil) - addSon(result, a) - skipComment(p, result) - while true: - if p.tok.tokType == tkSad: getTok(p) - case p.tok.tokType - of tkOf: - b = newNodeP(nkOfBranch, p) - exprListAux(p, nkRange, tkColon, tkDotDot, b) - of tkElse: - b = newNodeP(nkElse, p) - getTok(p) - eat(p, tkColon) - else: break - skipComment(p, b) - addSon(b, parseObjectPart(p)) - addSon(result, b) - if b.kind == nkElse: break - -proc parseObjectPart(p: var TParser): PNode = - case p.tok.tokType - of tkInd: - result = newNodeP(nkRecList, p) - pushInd(p.lex[] , p.tok.indent) - getTok(p) - skipComment(p, result) - while true: - case p.tok.tokType - of tkSad: - getTok(p) - of tkCase, tkWhen, tkSymbol, tkAccent, tkNil: - addSon(result, parseObjectPart(p)) - of tkDed: - getTok(p) - break - of tkEof: - break - else: - parMessage(p, errIdentifierExpected, tokToStr(p.tok)) - break - popInd(p.lex[] ) - of tkWhen: - result = parseObjectWhen(p) - of tkCase: - result = parseObjectCase(p) - of tkSymbol, tkAccent: - result = parseIdentColonEquals(p, {withPragma}) - skipComment(p, result) - of tkNil: - result = newNodeP(nkNilLit, p) - getTok(p) - else: result = nil - -proc parseObject(p: var TParser): PNode = - var a: PNode - result = newNodeP(nkObjectTy, p) - getTok(p) - if p.tok.tokType == tkCurlyDotLe: addSon(result, parsePragma(p)) - else: addSon(result, nil) - if p.tok.tokType == tkOf: - a = newNodeP(nkOfInherit, p) - getTok(p) - addSon(a, parseTypeDesc(p)) - addSon(result, a) - else: - addSon(result, nil) - skipComment(p, result) - addSon(result, parseObjectPart(p)) - -proc parseDistinct(p: var TParser): PNode = - result = newNodeP(nkDistinctTy, p) - getTok(p) - optInd(p, result) - addSon(result, parseTypeDesc(p)) - -proc parseTypeDef(p: var TParser): PNode = - var a: PNode - result = newNodeP(nkTypeDef, p) - addSon(result, identWithPragma(p)) - if p.tok.tokType == tkBracketLe: addSon(result, parseGenericParamList(p)) - else: addSon(result, nil) - if p.tok.tokType == tkEquals: - getTok(p) - optInd(p, result) - case p.tok.tokType - of tkObject: a = parseObject(p) - of tkEnum: a = parseEnum(p) - of tkDistinct: a = parseDistinct(p) - else: a = parseTypeDesc(p) - addSon(result, a) - else: - addSon(result, nil) - indAndComment(p, result) # special extension! - -proc parseVarTuple(p: var TParser): PNode = - var a: PNode - result = newNodeP(nkVarTuple, p) - getTok(p) # skip '(' - optInd(p, result) - while (p.tok.tokType == tkSymbol) or (p.tok.tokType == tkAccent): - a = identWithPragma(p) - addSon(result, a) - if p.tok.tokType != tkComma: break - getTok(p) - optInd(p, a) - addSon(result, nil) # no type desc - optPar(p) - eat(p, tkParRi) - eat(p, tkEquals) - optInd(p, result) - addSon(result, parseExpr(p)) - -proc parseVariable(p: var TParser): PNode = - if p.tok.tokType == tkParLe: result = parseVarTuple(p) - else: result = parseIdentColonEquals(p, {withPragma}) - indAndComment(p, result) # special extension! - -proc simpleStmt(p: var TParser): PNode = - case p.tok.tokType - of tkReturn: result = parseReturnOrRaise(p, nkReturnStmt) - of tkRaise: result = parseReturnOrRaise(p, nkRaiseStmt) - of tkYield: result = parseYieldOrDiscard(p, nkYieldStmt) - of tkDiscard: result = parseYieldOrDiscard(p, nkDiscardStmt) - of tkBreak: result = parseBreakOrContinue(p, nkBreakStmt) - of tkContinue: result = parseBreakOrContinue(p, nkContinueStmt) - of tkCurlyDotLe: result = parsePragma(p) - of tkImport: result = parseImportOrIncludeStmt(p, nkImportStmt) - of tkFrom: result = parseFromStmt(p) - of tkInclude: result = parseImportOrIncludeStmt(p, nkIncludeStmt) - of tkComment: result = newCommentStmt(p) - else: - if isExprStart(p): result = parseExprStmt(p) - else: result = nil - if result != nil: skipComment(p, result) - -proc parseType(p: var TParser): PNode = - result = newNodeP(nkTypeSection, p) - while true: - case p.tok.tokType - of tkComment: - skipComment(p, result) - of tkType: - # type alias: - of tkEnum: - nil - of tkObject: - nil - of tkTuple: - nil - else: break - -proc complexOrSimpleStmt(p: var TParser): PNode = - case p.tok.tokType - of tkIf: - result = parseIfOrWhen(p, nkIfStmt) - of tkWhile: - result = parseWhile(p) - of tkCase: - result = parseCase(p) - of tkTry: - result = parseTry(p) - of tkFor: - result = parseFor(p) - of tkBlock: - result = parseBlock(p) - of tkAsm: - result = parseAsm(p) - of tkProc: - result = parseRoutine(p, nkProcDef) - of tkMethod: - result = parseRoutine(p, nkMethodDef) - of tkIterator: - result = parseRoutine(p, nkIteratorDef) - of tkMacro: - result = parseRoutine(p, nkMacroDef) - of tkTemplate: - result = parseRoutine(p, nkTemplateDef) - of tkConverter: - result = parseRoutine(p, nkConverterDef) - of tkType, tkEnum, tkObject, tkTuple: - result = nil #result := parseTypeAlias(p, nkTypeSection, parseTypeDef); - of tkConst: - result = parseConstSection(p) - of tkWhen: - result = parseIfOrWhen(p, nkWhenStmt) - of tkVar: - result = parseSection(p, nkVarSection, parseVariable) - else: result = simpleStmt(p) - -proc parseStmt(p: var TParser): PNode = - var a: PNode - if p.tok.tokType == tkCurlyLe: - result = newNodeP(nkStmtList, p) - getTok(p) - while true: - case p.tok.tokType - of tkSad, tkInd, tkDed: getTok(p) - of tkEof, tkCurlyRi: break - else: - a = complexOrSimpleStmt(p) - if a == nil: break - addSon(result, a) - eat(p, tkCurlyRi) - else: - # the case statement is only needed for better error messages: - case p.tok.tokType - of tkIf, tkWhile, tkCase, tkTry, tkFor, tkBlock, tkAsm, tkProc, tkIterator, - tkMacro, tkType, tkConst, tkWhen, tkVar: - parMessage(p, errComplexStmtRequiresInd) - result = nil - else: - result = simpleStmt(p) - if result == nil: parMessage(p, errExprExpected, tokToStr(p.tok)) - if p.tok.tokType in {tkInd, tkDed, tkSad}: getTok(p) - -proc parseAll(p: var TParser): PNode = - var a: PNode - result = newNodeP(nkStmtList, p) - while true: - case p.tok.tokType - of tkDed, tkInd, tkSad: getTok(p) - of tkEof: break - else: - a = complexOrSimpleStmt(p) - if a == nil: parMessage(p, errExprExpected, tokToStr(p.tok)) - addSon(result, a) +proc ParseAll*(p: var TParser): PNode = + result = nil -proc parseTopLevelStmt(p: var TParser): PNode = +proc parseTopLevelStmt*(p: var TParser): PNode = result = nil - while true: - case p.tok.tokType - of tkDed, tkInd, tkSad: getTok(p) - of tkEof: break - else: - result = complexOrSimpleStmt(p) - if result == nil: parMessage(p, errExprExpected, tokToStr(p.tok)) - break + diff --git a/compiler/pendx.nim b/compiler/pendx.nim index debe0d852..72c80126d 100755 --- a/compiler/pendx.nim +++ b/compiler/pendx.nim @@ -8,16 +8,11 @@ # import - llstream, scanner, idents, strutils, ast, msgs, pnimsyn + llstream, lexer, parser, idents, strutils, ast, msgs -proc ParseAll*(p: var TParser): PNode -proc parseTopLevelStmt*(p: var TParser): PNode - # implements an iterator. Returns the next top-level statement or nil if end - # of stream. -# implementation - -proc ParseAll(p: var TParser): PNode = +proc ParseAll*(p: var TParser): PNode = result = nil -proc parseTopLevelStmt(p: var TParser): PNode = +proc parseTopLevelStmt*(p: var TParser): PNode = result = nil + diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index d7bda4099..c94b8b68b 100755 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -10,7 +10,7 @@ # This module implements semantic checking for pragmas import - os, platform, condsyms, ast, astalgo, idents, semdata, msgs, rnimsyn, + os, platform, condsyms, ast, astalgo, idents, semdata, msgs, renderer, wordrecg, ropes, options, strutils, lists, extccomp, math, magicsys, trees, rodread diff --git a/compiler/rnimsyn.nim b/compiler/renderer.nim index 4436467fa..5ba24bbfa 100755 --- a/compiler/rnimsyn.nim +++ b/compiler/renderer.nim @@ -10,7 +10,7 @@ # This module implements the renderer of the standard Nimrod representation. import - scanner, options, idents, strutils, ast, msgs, lists + lexer, options, idents, strutils, ast, msgs, lists type TRenderFlag* = enum @@ -637,7 +637,7 @@ proc gasm(g: var TSrcGen, n: PNode) = proc gident(g: var TSrcGen, n: PNode) = var t: TTokType var s = atom(n) - if (s[0] in scanner.SymChars): + if (s[0] in lexer.SymChars): if (n.kind == nkIdent): if (n.ident.id < ord(tokKeywordLow) - ord(tkSymbol)) or (n.ident.id > ord(tokKeywordHigh) - ord(tkSymbol)): diff --git a/compiler/sem.nim b/compiler/sem.nim index bb948ffc9..5f717f006 100755 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -10,9 +10,9 @@ # This module implements the semantic checking pass. import - strutils, nhashes, lists, options, scanner, ast, astalgo, trees, treetab, - wordrecg, ropes, msgs, os, condsyms, idents, rnimsyn, types, platform, math, - magicsys, pnimsyn, nversion, nimsets, semdata, evals, semfold, importer, + strutils, nhashes, lists, options, lexer, ast, astalgo, trees, treetab, + wordrecg, ropes, msgs, os, condsyms, idents, renderer, types, platform, math, + magicsys, parser, nversion, nimsets, semdata, evals, semfold, importer, procfind, lookups, rodread, pragmas, passes, semtypinst, sigmatch, suggest proc semPass*(): TPass diff --git a/compiler/semdata.nim b/compiler/semdata.nim index e052a0baf..240a783d4 100755 --- a/compiler/semdata.nim +++ b/compiler/semdata.nim @@ -10,9 +10,9 @@ # This module contains the data structures for the semantic checking phase. import - strutils, lists, options, scanner, ast, astalgo, trees, treetab, wordrecg, - ropes, msgs, platform, os, condsyms, idents, rnimsyn, types, extccomp, math, - magicsys, nversion, nimsets, pnimsyn, times, passes, rodread + strutils, lists, options, lexer, ast, astalgo, trees, treetab, wordrecg, + ropes, msgs, platform, os, condsyms, idents, renderer, types, extccomp, math, + magicsys, nversion, nimsets, parser, times, passes, rodread type TOptionEntry* = object of lists.TListEntry # entries to put on a diff --git a/compiler/semfold.nim b/compiler/semfold.nim index bae2a19bc..041655ef6 100755 --- a/compiler/semfold.nim +++ b/compiler/semfold.nim @@ -12,7 +12,7 @@ import strutils, lists, options, ast, astalgo, trees, treetab, nimsets, times, - nversion, platform, math, msgs, os, condsyms, idents, rnimsyn, types, + nversion, platform, math, msgs, os, condsyms, idents, renderer, types, commands proc getConstExpr*(m: PSym, n: PNode): PNode diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 1e61ddfe0..d5b8f3204 100755 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -11,7 +11,7 @@ # the call to overloaded procs, generic procs and operators. import - ast, astalgo, semdata, types, msgs, rnimsyn, lookups, semtypinst, + ast, astalgo, semdata, types, msgs, renderer, lookups, semtypinst, magicsys type diff --git a/compiler/suggest.nim b/compiler/suggest.nim index 6f4babe63..b16c4eba7 100755 --- a/compiler/suggest.nim +++ b/compiler/suggest.nim @@ -9,7 +9,8 @@ ## This file implements features required for IDE support. -import scanner, idents, ast, astalgo, semdata, msgs, types, sigmatch, options +import + lexer, idents, ast, astalgo, semdata, msgs, types, sigmatch, options const sep = '\t' @@ -38,7 +39,7 @@ proc SymToStr(s: PSym, isLocal: bool, section: string): string = result.add($ToColumn(s.info)) proc filterSym(s: PSym): bool {.inline.} = - result = s.name.s[0] in scanner.SymChars + result = s.name.s[0] in lexer.SymChars proc suggestField(s: PSym) = if filterSym(s): diff --git a/compiler/syntaxes.nim b/compiler/syntaxes.nim index adb17efee..b098e4817 100755 --- a/compiler/syntaxes.nim +++ b/compiler/syntaxes.nim @@ -10,8 +10,8 @@ ## Implements the dispatcher for the different parsers. import - strutils, llstream, ast, astalgo, idents, scanner, options, msgs, pnimsyn, - pbraces, ptmplsyn, filters, rnimsyn + strutils, llstream, ast, astalgo, idents, lexer, options, msgs, parser, + pbraces, filters, filter_tmpl, renderer type TFilterKind* = enum @@ -54,7 +54,7 @@ proc ParseFile(filename: string): PNode = proc parseAll(p: var TParsers): PNode = case p.skin of skinStandard: - result = pnimsyn.parseAll(p.parser) + result = parser.parseAll(p.parser) of skinBraces: result = pbraces.parseAll(p.parser) of skinEndX: @@ -65,7 +65,7 @@ proc parseAll(p: var TParsers): PNode = proc parseTopLevelStmt(p: var TParsers): PNode = case p.skin of skinStandard: - result = pnimsyn.parseTopLevelStmt(p.parser) + result = parser.parseTopLevelStmt(p.parser) of skinBraces: result = pbraces.parseTopLevelStmt(p.parser) of skinEndX: @@ -99,7 +99,7 @@ proc parsePipe(filename: string, inputStream: PLLStream): PNode = while line[i] in WhiteSpace: inc(i) var q: TParser OpenParser(q, filename, LLStreamOpen(copy(line, i))) - result = pnimsyn.parseAll(q) + result = parser.parseAll(q) CloseParser(q) LLStreamClose(s) @@ -167,7 +167,7 @@ proc openParsers(p: var TParsers, filename: string, inputstream: PLLStream) = else: s = inputStream case p.skin of skinStandard, skinBraces, skinEndX: - pnimsyn.openParser(p.parser, filename, s) + parser.openParser(p.parser, filename, s) proc closeParsers(p: var TParsers) = - pnimsyn.closeParser(p.parser) + parser.closeParser(p.parser) diff --git a/compiler/transf.nim b/compiler/transf.nim index db5146bb5..cdc89538c 100755 --- a/compiler/transf.nim +++ b/compiler/transf.nim @@ -18,7 +18,7 @@ import strutils, lists, options, ast, astalgo, trees, treetab, evals, msgs, os, - idents, rnimsyn, types, passes, semfold, magicsys, cgmeth + idents, renderer, types, passes, semfold, magicsys, cgmeth const genPrefix* = ":tmp" # prefix for generated names diff --git a/compiler/trees.nim b/compiler/trees.nim index 69b77b8ab..54f688103 100755 --- a/compiler/trees.nim +++ b/compiler/trees.nim @@ -10,7 +10,7 @@ # tree helper routines import - ast, astalgo, scanner, msgs, strutils + ast, astalgo, lexer, msgs, strutils proc getMagic*(op: PNode): TMagic diff --git a/doc/filelist.txt b/doc/filelist.txt index 7bcd424db..ce9923453 100755 --- a/doc/filelist.txt +++ b/doc/filelist.txt @@ -9,16 +9,11 @@ nimrod main module: parses the command line and calls main implements the top-level command dispatching nimconf implements the config file reader syntaxes dispatcher for the different parsers and filters -ptmplsyn standard template filter (``#! stdtempl``) +filter_tmpl standard template filter (``#! stdtempl``) lexbase buffer handling of the lexical analyser -scanner lexical analyser -pnimsyn Nimrod's parser -rnimsyn Nimrod code renderer (AST back to its textual form) - -paslex lexer for Pascal -pasparse parser for Pascal; Pascal's advanced OO features are not - supported - +lexer lexical analyser +parser Nimrod's parser +renderer Nimrod code renderer (AST back to its textual form) options contains global and local compiler options ast type definitions of the abstract syntax tree (AST) and node constructors diff --git a/lib/pure/collections/hashtables.nim b/lib/pure/collections/hashtables.nim index 133db66e1..6730163c2 100644 --- a/lib/pure/collections/hashtables.nim +++ b/lib/pure/collections/hashtables.nim @@ -18,8 +18,8 @@ type TKeyValuePair[A, B] = tuple[slot: TSlotEnum, key: A, val: B] TKeyValuePairSeq[A, B] = seq[TKeyValuePair[A, B]] THashTable[A, B] = object of TObject - counter: int data: TKeyValuePairSeq[A, B] + counter: int PHashTable*[A, B] = ref THashTable[A, B] ## use this type to declare tables @@ -32,12 +32,12 @@ iterator pairs*[A, B](t: PHashTable[A, B]): tuple[key: A, val: B] = for h in 0..high(t.data): if t.data[h].slot == seFilled: yield (t.data[h].key, t.data[h].val) -iterator keys*[A, B](t: PHashTable[A, B]): tuple[key: A, val: B] = +iterator keys*[A, B](t: PHashTable[A, B]): A = ## iterates over any key in the table `t`. for h in 0..high(t.data): if t.data[h].slot == seFilled: yield t.data[h].key -iterator values*[A, B](t: PHashTable[A, B]): tuple[key: A, val: B] = +iterator values*[A, B](t: PHashTable[A, B]): B = ## iterates over any value in the table `t`. for h in 0..high(t.data): if t.data[h].slot == seFilled: yield t.data[h].val @@ -103,6 +103,7 @@ proc del*[A, B](t: PHashTable[A, B], key: A) = var index = RawGet(t, key) if index >= 0: t.data[index].slot = seDeleted + dec(t.counter) proc newHashTable*[A, B](initialSize = 64): PHashTable[A, B] = ## creates a new string table that is empty. `initialSize` needs to be @@ -125,6 +126,110 @@ proc `$`*[A, B](t: PHashTable[A, B]): string = result.add($val) result.add("}") + +# ------------------------------ count tables ------------------------------- + +const + deletedCount = -1 + +type + TCountTable*[A] {.final.} = object + data: seq[tuple[key: A, val: int]] + counter: int + +proc len*[A](t: TCountTable[A]): int = + ## returns the number of keys in `t`. + result = t.counter + +iterator pairs*[A](t: TCountTable[A]): tuple[key: A, val: int] = + ## iterates over any (key, value) pair in the table `t`. + for h in 0..high(t.data): + if t.data[h].slot == seFilled: yield (t.data[h].key, t.data[h].val) + +iterator keys*[A](t: TCountTable[A]): A = + ## iterates over any key in the table `t`. + for h in 0..high(t.data): + if t.data[h].slot == seFilled: yield t.data[h].key + +iterator values*[A](t: TCountTable[A]): int = + ## iterates over any value in the table `t`. + for h in 0..high(t.data): + if t.data[h].slot == seFilled: yield t.data[h].val + +proc RawGet[A](t: TCountTable[A], key: A): int = + var h: THash = hash(key) and high(t.data) # start with real hash value + while t.data[h].slot != seEmpty: + if t.data[h].key == key and t.data[h].slot == seFilled: + return h + h = nextTry(h, high(t.data)) + result = -1 + +proc `[]`*[A](t: TCountTable[A], key: A): B = + ## retrieves the value at ``t[key]``. If `key` is not in `t`, + ## default empty value for the type `B` is returned + ## and no exception is raised. One can check with ``hasKey`` whether the key + ## exists. + var index = RawGet(t, key) + if index >= 0: result = t.data[index].val + +proc hasKey*[A](t: TCountTable[A], key: A): bool = + ## returns true iff `key` is in the table `t`. + result = rawGet(t, key) >= 0 + +proc RawInsert[A](t: TCountTable[A], data: var TKeyValuePairSeq[A, B], + key: A, val: int) = + var h: THash = hash(key) and high(data) + while data[h].slot == seFilled: + h = nextTry(h, high(data)) + data[h].key = key + data[h].val = val + data[h].slot = seFilled + +proc Enlarge[A](t: TCountTable[A]) = + var n: TKeyValuePairSeq[A, B] + newSeq(n, len(t.data) * growthFactor) + for i in countup(0, high(t.data)): + if t.data[i].slot == seFilled: RawInsert(t, n, t.data[i].key, t.data[i].val) + swap(t.data, n) + +proc `[]=`*[A](t: TCountTable[A], key: A, val: int) = + ## puts a (key, value)-pair into `t`. + var index = RawGet(t, key) + if index >= 0: + t.data[index].val = val + else: + if mustRehash(len(t.data), t.counter): Enlarge(t) + RawInsert(t, t.data, key, val) + inc(t.counter) + +proc del*[A](t: TCountTable[A], key: A) = + ## deletes `key` from hash table `t`. + var index = RawGet(t, key) + if index >= 0: + t.data[index].slot = seDeleted + +proc newHashTable*[A, B](initialSize = 64): PHashTable[A, B] = + ## creates a new string table that is empty. `initialSize` needs to be + ## a power of two. + assert isPowerOfTwo(initialSize) + new(result) + result.counter = 0 + newSeq(result.data, initialSize) + +proc `$`*[A](t: TCountTable[A]): string = + ## The `$` operator for string tables. + if t.len == 0: + result = "{:}" + else: + result = "{" + for key, val in pairs(t): + if result.len > 1: result.add(", ") + result.add($key) + result.add(": ") + result.add($val) + result.add("}") + + when isMainModule: var table = newHashTable[string, float]() table["test"] = 1.2345 diff --git a/lib/pure/collections/lists.nim b/lib/pure/collections/lists.nim new file mode 100755 index 000000000..cae6d4620 --- /dev/null +++ b/lib/pure/collections/lists.nim @@ -0,0 +1,155 @@ +# +# +# Nimrod's Runtime Library +# (c) Copyright 2011 Andreas Rumpf +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +## Implementation of singly and doubly linked lists. Because it makes no sense +## to do so, the 'next' and 'prev' pointers are not hidden from you and can +## be manipulated directly for efficiency. + +type + TDoublyLinkedNode[T] {.pure, final.} = object + next*, prev*: ref TDoublyLinkedNode[T] + value*: T + PDoublyLinkedNode*[T] = ref TDoublyLinkedNode[T] + + TSinglyLinkedNode[T] {.pure, final.} = object + next*: ref TSinglyLinkedNode[T] + value*: T + PSinglyLinkedNode*[T] = ref TSinglyLinkedNode[T] + +proc newDoublyLinkedNode*[T](value: T): PDoublyLinkedNode[T] = + ## creates a new doubly linked node with the given `value`. + new(result) + result.value = value + +proc newSinglyLinkedNode*[T](value: T): PSinglyLinkedNode[T] = + ## creates a new singly linked node with the given `value`. + new(result) + result.value = value + +iterator items*[T](n: PDoublyLinkedNode[T]): T = + ## yields every value of `x`. + var it = n + while it != nil: + yield it.value + it = it.next + +iterator items*[T](n: PSinglyLinkedNode[T]): T = + ## yields every value of `x`. + var it = n + while it != nil: + yield it.value + it = it.next + +iterator nodes*[T](n: PSinglyLinkedNode[T]): PSinglyLinkedNode[T] = + ## iterates over every node of `x`. Removing the current node from the + ## list during traversal is supported. + var it = n + while it != nil: + var nxt = it.next + yield it + it = nxt + +iterator nodes*[T](n: PDoublyLinkedNode[T]): PDoublyLinkedNode[T] = + ## iterates over every node of `x`. Removing the current node from the + ## list during traversal is supported. + var it = n + while it != nil: + var nxt = it.next + yield it + it = nxt + +proc `$`*[list: PSinglyLinkedNode|PDoublyLinkedNode](n: list): string = + ## turns a list into its string representation. + result = "[" + for x in nodes(n): + if result.len > 1: result.add(", ") + result.add($x.value) + result.add("]") + +proc find*[list: PSinglyLinkedNode|PDoublyLinkedNode, T]( + n: list, value: T): list = + ## searches in the list for a value. Returns nil if the value does not + ## exist. + for x in nodes(n): + if x.value == value: return x + +proc contains*[list: PSinglyLinkedNode|PDoublyLinkedNode, T]( + n: list, value: T): list = + ## searches in the list for a value. Returns false if the value does not + ## exist, true otherwise. + for x in nodes(n): + if x.value == value: return true + +proc prepend*[T](head: var PSinglyLinkedNode[T], + toAdd: PSinglyLinkedNode[T]) {.inline.} = + ## prepends a node to `head`. Efficiency: O(1). + toAdd.next = head + head = toAdd + +proc prepend*[T](head: var PSinglyLinkedNode[T], x: T) {.inline.} = + ## creates a new node with the value `x` and prepends that node to `head`. + ## Efficiency: O(1). + preprend(head, newSinglyLinkedNode(x)) + +proc append*[T](head: var PSinglyLinkedNode[T], + toAdd: PSinglyLinkedNode[T]) = + ## appends a node to `head`. Efficiency: O(n). + if head == nil: + head = toAdd + else: + var it = head + while it.next != nil: it = it.next + it.next = toAdd + +proc append*[T](head: var PSinglyLinkedNode[T], x: T) {.inline.} = + ## creates a new node with the value `x` and appends that node to `head`. + ## Efficiency: O(n). + append(head, newSinglyLinkedNode(x)) + + +proc prepend*[T](head: var PDoublyLinkedNode[T], + toAdd: PDoublyLinkedNode[T]) {.inline.} = + ## prepends a node to `head`. Efficiency: O(1). + if head == nil: + head = toAdd + # head.prev stores the last node: + head.prev = toAdd + else: + toAdd.next = head + toAdd.prev = head.prev # copy pointer to last element + head.prev = toAdd + head = toAdd + +proc prepend*[T](head: var PDoublyLinkedNode[T], x: T) {.inline.} = + ## creates a new node with the value `x` and prepends that node to `head`. + ## Efficiency: O(1). + preprend(head, newDoublyLinkedNode(x)) + +proc append*[T](head: var PDoublyLinkedNode[T], + toAdd: PDoublyLinkedNode[T]) {.inline.} = + ## appends a node to `head`. Efficiency: O(1). + if head == nil: + head = toAdd + # head.prev stores the last node: + head.prev = toAdd + else: + var last = head.prev + assert last.next == nil + last.next = toAdd + toAdd.prev = last + head.prev = toAdd # new last element + +proc append*[T](head: var PDoublyLinkedNode[T], x: T) {.inline.} = + ## creates a new node with the value `x` and appends that node to `head`. + ## Efficiency: O(1). + append(head, newDoublyLinkedNode(x)) + + + + |