summary refs log tree commit diff stats
path: root/rod/pas2nim
diff options
context:
space:
mode:
Diffstat (limited to 'rod/pas2nim')
-rwxr-xr-xrod/pas2nim/pas2nim.nim103
-rwxr-xr-xrod/pas2nim/paslex.nim130
-rwxr-xr-xrod/pas2nim/pasparse.nim352
3 files changed, 308 insertions, 277 deletions
diff --git a/rod/pas2nim/pas2nim.nim b/rod/pas2nim/pas2nim.nim
index 54e4784c8..b41455d6d 100755
--- a/rod/pas2nim/pas2nim.nim
+++ b/rod/pas2nim/pas2nim.nim
@@ -7,61 +7,58 @@
 #    distribution, for details about the copyright.
 #
 
-# 
-
 import 
-  llstream, strutils, os, ast, rnimsyn, options, msgs, 
+  strutils, os, parseopt, llstream, ast, rnimsyn, options, msgs,
   paslex, pasparse
-  
-proc exSymbols(n: PNode) = 
-  case n.kind
-  of nkEmpty..nkNilLit: nil
-  of nkProcDef..nkIteratorDef: exSymbol(n.sons[namePos])
-  of nkWhenStmt, nkStmtList: 
-    for i in countup(0, sonsLen(n) - 1): exSymbols(n.sons[i])
-  of nkVarSection, nkConstSection: 
-    for i in countup(0, sonsLen(n) - 1): exSymbol(n.sons[i].sons[0])
-  of nkTypeSection: 
-    for i in countup(0, sonsLen(n) - 1): 
-      exSymbol(n.sons[i].sons[0])
-      if (n.sons[i].sons[2] != nil) and
-          (n.sons[i].sons[2].kind == nkObjectTy): 
-        fixRecordDef(n.sons[i].sons[2])
-  else: nil
-
-proc CommandExportSymbols(filename: string) = 
-  # now unused!
-  var module = parseFile(addFileExt(filename, NimExt))
-  if module != nil: 
-    exSymbols(module)
-    renderModule(module, getOutFile(filename, "pretty." & NimExt))
-
-proc CommandLexPas(filename: string) = 
-  var f = addFileExt(filename, "pas")
-  var stream = LLStreamOpen(f, fmRead)
-  if stream != nil: 
-    var 
-      L: TPasLex
-      tok: TPasTok
-    OpenLexer(L, f, stream)
-    getPasTok(L, tok)
-    while tok.xkind != pxEof: 
-      printPasTok(tok)
-      getPasTok(L, tok)
-    closeLexer(L)
-  else: rawMessage(errCannotOpenFile, f)
 
-proc CommandPas(filename: string) = 
-  var f = addFileExt(filename, "pas")
-  var stream = LLStreamOpen(f, fmRead)
-  if stream != nil: 
-    var p: TPasParser
-    OpenPasParser(p, f, stream)
-    var module = parseUnit(p)
-    closePasParser(p)
-    renderModule(module, getOutFile(filename, NimExt))
-  else: 
-    rawMessage(errCannotOpenFile, f)
-  
+const
+  Version = "0.8"
+  Usage = """
+pas2nim - Pascal to Nimrod source converter
+  (c) 2010 Andreas Rumpf
+Usage: pas2nim [options] inputfile [options]
+Options: 
+  -o, --out:FILE         set output filename
+  --ref                  convert ^typ to ref typ (default: ptr typ)
+  --boot                 use special translation rules for the Nimrod compiler
+  -v, --version          write pas2nim's version
+  -h, --help             show this help
+"""
 
+proc main(infile, outfile: string, flags: set[TParserFlag]) = 
+  var stream = LLStreamOpen(infile, fmRead)
+  if stream == nil: rawMessage(errCannotOpenFile, infile)
+  var p: TParser
+  OpenParser(p, infile, stream, flags)
+  var module = parseUnit(p)
+  closeParser(p)
+  renderModule(module, outfile)
 
+var
+  infile = ""
+  outfile = ""
+  flags: set[TParserFlag] = {}
+for kind, key, val in getopt():
+  case kind
+  of cmdArgument: infile = key
+  of cmdLongOption, cmdShortOption:
+    case key
+    of "help", "h":
+      stdout.write(Usage)
+      quit(0)
+    of "version", "v":
+      stdout.write(Version & "\n")
+      quit(0)
+    of "o", "out": outfile = key
+    of "ref": incl(flags, pfRefs)
+    of "boot": flags = flags + {pfRefs, pfMoreReplacements, pfImportBlackList}
+    else: stdout.write("[Error] unknown option: " & key)
+  of cmdEnd: assert(false)
+if infile.len == 0:
+  # no filename has been given, so we show the help:
+  stdout.write(Usage)
+else:
+  if outfile.len == 0:
+    outfile = changeFileExt(infile, "nim")
+  infile = addFileExt(infile, "pas")
+  main(infile, outfile, flags)
diff --git a/rod/pas2nim/paslex.nim b/rod/pas2nim/paslex.nim
index 9159c5de7..193a45001 100755
--- a/rod/pas2nim/paslex.nim
+++ b/rod/pas2nim/paslex.nim
@@ -11,7 +11,7 @@
 # the scanner module.
 
 import 
-  nhashes, options, msgs, strutils, platform, idents, lexbase
+  nhashes, options, msgs, strutils, platform, idents, lexbase, llstream
 
 const 
   MaxLineLength* = 80         # lines longer than this lead to a warning
@@ -24,7 +24,7 @@ const
 # keywords are sorted!
 
 type
-  TPasTokKind* = enum 
+  TTokKind* = enum 
     pxInvalid, pxEof,         
     pxAnd, pxArray, pxAs, pxAsm, pxBegin, pxCase, pxClass, pxConst, 
     pxConstructor, pxDestructor, pxDiv, pxDo, pxDownto, pxElse, pxEnd, pxExcept, 
@@ -46,7 +46,7 @@ type
     pxAsgn, pxEquals, pxDot, pxDotDot, pxHat, pxPlus, pxMinus, pxStar, pxSlash, 
     pxLe, pxLt, pxGe, pxGt, pxNeq, pxAt, pxStarDirLe, pxStarDirRi, pxCurlyDirLe, 
     pxCurlyDirRi
-  TPasTokKinds* = set[TPasTokKind]
+  TTokKinds* = set[TTokKind]
 
 const 
   Keywords = ["and", "array", "as", "asm", "begin", "case", "class", "const", 
@@ -62,9 +62,10 @@ const
   firstKeyword = pxAnd
   lastKeyword = pxXor
 
-type 
-  TPasTok* = object
-    xkind*: TPasTokKind       # the type of the token
+type
+  TNumericalBase* = enum base10, base2, base8, base16
+  TToken* = object
+    xkind*: TTokKind          # the type of the token
     ident*: PIdent            # the parsed identifier
     iNumber*: BiggestInt      # the parsed integer literal
     fNumber*: BiggestFloat    # the parsed floating point literal
@@ -72,79 +73,104 @@ type
                               # or float literals
     literal*: string          # the parsed (string) literal
   
-  TPasLex* = object 
+  TLexer* = object of TBaseLexer
     filename*: string
   
 
-proc getPasTok*(L: var TPasLex, tok: var TPasTok)
-proc PrintPasTok*(tok: TPasTok)
-proc pasTokToStr*(tok: TPasTok): string
+proc getTok*(L: var TLexer, tok: var TToken)
+proc PrintTok*(tok: TToken)
+proc `$`*(tok: TToken): string
 # implementation
 
-var dummyIdent: PIdent
+var
+  dummyIdent: PIdent
+  gLinesCompiled: int
 
 proc fillToken(L: var TToken) = 
-  L.TokType = tkInvalid
+  L.xkind = pxInvalid
   L.iNumber = 0
-  L.Indent = 0
   L.literal = ""
   L.fNumber = 0.0
   L.base = base10
   L.ident = dummyIdent        # this prevents many bugs!
   
-proc openLexer(lex: var TLexer, filename: string, inputstream: PLLStream) = 
+proc openLexer*(lex: var TLexer, filename: string, inputstream: PLLStream) = 
   openBaseLexer(lex, inputstream)
-  lex.indentStack = @[0]
   lex.filename = filename
-  lex.indentAhead = - 1
 
-proc closeLexer(lex: var TLexer) = 
+proc closeLexer*(lex: var TLexer) = 
   inc(gLinesCompiled, lex.LineNumber)
   closeBaseLexer(lex)
 
 proc getColumn(L: TLexer): int = 
   result = getColNumber(L, L.bufPos)
 
-proc getLineInfo(L: TLexer): TLineInfo = 
+proc getLineInfo*(L: TLexer): TLineInfo = 
   result = newLineInfo(L.filename, L.linenumber, getColNumber(L, L.bufpos))
 
-proc lexMessage(L: TLexer, msg: TMsgKind, arg = "") = 
+proc lexMessage*(L: TLexer, msg: TMsgKind, arg = "") = 
   msgs.liMessage(getLineInfo(L), msg, arg)
 
 proc lexMessagePos(L: var TLexer, msg: TMsgKind, pos: int, arg = "") = 
   var info = newLineInfo(L.filename, L.linenumber, pos - L.lineStart)
   msgs.liMessage(info, msg, arg)
 
-proc binaryStrSearch(x: openarray[string], y: string): int =
-  var a = 0
-  var b = len(x)
-  while a < b:
-     var mid = (a + b) div 2
-     if x[mid] < y: a = mid + 1
-     else: b = mid
-  if a < len(x) and x[a] == y: result = a
-  else: result = -1
+proc TokKindToStr*(k: TTokKind): string =
+  case k
+  of pxEof: result = "[EOF]"
+  of firstKeyword..lastKeyword:
+    result = keywords[ord(k)-ord(firstKeyword)]
+  of pxInvalid, pxComment, pxStrLit: result = "string literal"
+  of pxCommand: result = "{@"
+  of pxAmp: result = "{&"
+  of pxPer: result = "{%"
+  of pxSymbol: result = "identifier"
+  of pxIntLit, pxInt64Lit: result = "integer literal"
+  of pxFloatLit: result = "floating point literal"
+  of pxParLe: result = "("
+  of pxParRi: result = ")"
+  of pxBracketLe: result = "["
+  of pxBracketRi: result = "]"
+  of pxComma: result = ","
+  of pxSemiColon: result = ";"
+  of pxColon: result = ":"
+  of pxAsgn: result = ":="
+  of pxEquals: result = "="
+  of pxDot: result = "."
+  of pxDotDot: result = ".."
+  of pxHat: result = "^"
+  of pxPlus: result = "+"
+  of pxMinus: result = "-"
+  of pxStar: result = "*"
+  of pxSlash: result = "/"
+  of pxLe: result = "<="
+  of pxLt: result = "<"
+  of pxGe: result = ">="
+  of pxGt: result = ">"
+  of pxNeq: result = "<>"
+  of pxAt: result = "@"
+  of pxStarDirLe: result = "(*$"
+  of pxStarDirRi: result = "*)"
+  of pxCurlyDirLe: result = "{$"
+  of pxCurlyDirRi: result = "}"
 
-proc pastokToStr(tok: TPasTok): string = 
+proc `$`(tok: TToken): string = 
   case tok.xkind
-  of pxIntLit, pxInt64Lit: result = $(tok.iNumber)
-  of pxFloatLit: result = $(tok.fNumber)
-  of pxInvalid, pxComment..pxStrLit: result = tok.literal
-  else: 
-    if (tok.ident.s != ""): result = tok.ident.s
-    else: result = pasTokKindToStr[tok.xkind]
+  of pxInvalid, pxComment, pxStrLit: result = tok.literal
+  of pxSymbol: result = tok.ident.s
+  of pxIntLit, pxInt64Lit: result = $tok.iNumber
+  of pxFloatLit: result = $tok.fNumber
+  else: result = TokKindToStr(tok.xkind)
   
-proc PrintPasTok(tok: TPasTok) = 
-  write(stdout, pasTokKindToStr[tok.xkind])
-  write(stdout, ' ')
-  writeln(stdout, pastokToStr(tok))
+proc PrintTok(tok: TToken) = 
+  writeln(stdout, $tok)
 
-proc setKeyword(L: var TPasLex, tok: var TPasTok) = 
+proc setKeyword(L: var TLexer, tok: var TToken) = 
   var x = binaryStrSearch(keywords, toLower(tok.ident.s))
   if x < 0: tok.xkind = pxSymbol
-  else: tok.xKind = TPasTokKind(x + ord(firstKeyword))
+  else: tok.xKind = TTokKind(x + ord(firstKeyword))
   
-proc matchUnderscoreChars(L: var TPasLex, tok: var TPasTok, chars: TCharSet) = 
+proc matchUnderscoreChars(L: var TLexer, tok: var TToken, chars: TCharSet) = 
   # matches ([chars]_)*
   var pos = L.bufpos              # use registers for pos, buf
   var buf = L.buf
@@ -164,7 +190,7 @@ proc isFloatLiteral(s: string): bool =
     if s[i] in {'.', 'e', 'E'}: 
       return true
 
-proc getNumber2(L: var TPasLex, tok: var TPasTok) = 
+proc getNumber2(L: var TLexer, tok: var TToken) = 
   var pos = L.bufpos + 1 # skip %
   if not (L.buf[pos] in {'0'..'1'}): 
     # BUGFIX for %date%
@@ -192,7 +218,7 @@ proc getNumber2(L: var TPasLex, tok: var TPasTok) =
   else: tok.xkind = pxIntLit
   L.bufpos = pos
 
-proc getNumber16(L: var TPasLex, tok: var TPasTok) = 
+proc getNumber16(L: var TLexer, tok: var TToken) = 
   var pos = L.bufpos + 1          # skip $
   tok.base = base16
   var xi: biggestInt = 0
@@ -223,7 +249,7 @@ proc getNumber16(L: var TPasLex, tok: var TPasTok) =
     tok.xkind = pxIntLit
   L.bufpos = pos
 
-proc getNumber10(L: var TPasLex, tok: var TPasTok) = 
+proc getNumber10(L: var TLexer, tok: var TToken) = 
   tok.base = base10
   matchUnderscoreChars(L, tok, {'0'..'9'})
   if (L.buf[L.bufpos] == '.') and (L.buf[L.bufpos + 1] in {'0'..'9'}): 
@@ -251,7 +277,7 @@ proc HandleCRLF(L: var TLexer, pos: int): int =
   of LF: result = lexbase.HandleLF(L, pos)
   else: result = pos
   
-proc getString(L: var TPasLex, tok: var TPasTok) = 
+proc getString(L: var TLexer, tok: var TToken) = 
   var xi: int
   var pos = L.bufPos
   var buf = L.buf
@@ -300,7 +326,7 @@ proc getString(L: var TPasLex, tok: var TPasTok) =
   tok.xkind = pxStrLit
   L.bufpos = pos
 
-proc getSymbol(L: var TPasLex, tok: var TPasTok) = 
+proc getSymbol(L: var TLexer, tok: var TToken) = 
   var h: THash = 0
   var pos = L.bufpos
   var buf = L.buf
@@ -326,7 +352,7 @@ proc getSymbol(L: var TPasLex, tok: var TPasTok) =
   L.bufpos = pos
   setKeyword(L, tok)
 
-proc scanLineComment(L: var TPasLex, tok: var TPasTok) = 
+proc scanLineComment(L: var TLexer, tok: var TToken) = 
   var pos = L.bufpos
   var buf = L.buf 
   # a comment ends if the next line does not start with the // on the same
@@ -351,7 +377,7 @@ proc scanLineComment(L: var TPasLex, tok: var TPasTok) =
       break 
   L.bufpos = pos
 
-proc scanCurlyComment(L: var TPasLex, tok: var TPasTok) = 
+proc scanCurlyComment(L: var TLexer, tok: var TToken) = 
   var pos = L.bufpos
   var buf = L.buf
   tok.literal = "#"
@@ -371,7 +397,7 @@ proc scanCurlyComment(L: var TPasLex, tok: var TPasTok) =
       inc(pos)
   L.bufpos = pos
 
-proc scanStarComment(L: var TPasLex, tok: var TPasTok) = 
+proc scanStarComment(L: var TLexer, tok: var TToken) = 
   var pos = L.bufpos
   var buf = L.buf
   tok.literal = "#"
@@ -396,7 +422,7 @@ proc scanStarComment(L: var TPasLex, tok: var TPasTok) =
       inc(pos)
   L.bufpos = pos
 
-proc skip(L: var TPasLex, tok: var TPasTok) = 
+proc skip(L: var TLexer, tok: var TToken) = 
   var pos = L.bufpos
   var buf = L.buf
   while true: 
@@ -410,7 +436,7 @@ proc skip(L: var TPasLex, tok: var TPasTok) =
       break                   # EndOfFile also leaves the loop
   L.bufpos = pos
 
-proc getPasTok(L: var TPasLex, tok: var TPasTok) = 
+proc getTok(L: var TLexer, tok: var TToken) = 
   tok.xkind = pxInvalid
   fillToken(tok)
   skip(L, tok)
diff --git a/rod/pas2nim/pasparse.nim b/rod/pas2nim/pasparse.nim
index 79d5620e7..14d02518c 100755
--- a/rod/pas2nim/pasparse.nim
+++ b/rod/pas2nim/pasparse.nim
@@ -15,18 +15,23 @@ import
   os, llstream, paslex, idents, strutils, ast, astalgo, msgs, options
 
 type 
-  TPasSection* = enum 
+  TSection = enum 
     seImplementation, seInterface
-  TPasContext* = enum 
+  TContext = enum 
     conExpr, conStmt, conTypeDesc
-  TPasParser*{.final.} = object 
-    section*: TPasSection
-    inParamList*: bool
-    context*: TPasContext     # needed for the @emit command
-    lastVarSection*: PNode
-    lex*: TPasLex
-    tok*: TPasTok
-    repl*: TIdTable           # replacements
+  TParserFlag* = enum
+    pfRefs,             ## use "ref" instead of "ptr" for Pascal's ^typ
+    pfMoreReplacements, ## use more than the default replacements
+    pfImportBlackList   ## use import blacklist
+  TParser*{.final.} = object
+    section: TSection
+    inParamList: bool
+    context: TContext     # needed for the @emit command
+    lastVarSection: PNode
+    lex: TLexer
+    tok: TToken
+    repl: TIdTable           # replacements
+    flags: set[TParserFlag]
   
   TReplaceTuple* = array[0..1, string]
 
@@ -49,49 +54,42 @@ const
     ["ltu", "`<%`"], ["leu", "`<=%`"], ["shlu", "`shl`"], ["shru", "`shr`"], 
     ["assigned", "not isNil"], ["eintoverflow", "EOverflow"], ["format", "`%`"], 
     ["snil", "nil"], ["tostringf", "$"], ["ttextfile", "tfile"], 
-    ["tbinaryfile", "tfile"], ["strstart", "0"], ["nl", "\"\\n\""], ["tostring", 
-      "$"]]                   #,
-                              #    ('NL', '"\n"'),
-                              #    ('tabulator', '''\t'''),
-                              #    ('esc', '''\e'''),
-                              #    ('cr', '''\r'''),
-                              #    ('lf', '''\l'''),
-                              #    ('ff', '''\f'''),
-                              #    ('bel', '''\a'''),
-                              #    ('backspace', '''\b'''),
-                              #    ('vt', '''\v''') 
+    ["tbinaryfile", "tfile"], ["strstart", "0"], ["nl", "\"\\n\""],
+    ["tostring", "$"]]
 
-proc ParseUnit*(p: var TPasParser): PNode
-proc openPasParser*(p: var TPasParser, filename: string, inputStream: PLLStream)
-proc closePasParser*(p: var TPasParser)
+proc ParseUnit*(p: var TParser): PNode
+proc openParser*(p: var TParser, filename: string, inputStream: PLLStream,
+                 flags: set[TParserFlag] = {})
+proc closeParser*(p: var TParser)
 proc exSymbol*(n: var PNode)
 proc fixRecordDef*(n: var PNode)
   # XXX: move these two to an auxiliary module
 
 # implementation
 
-proc OpenPasParser(p: var TPasParser, filename: string, 
-                   inputStream: PLLStream) = 
+proc OpenParser(p: var TParser, filename: string, 
+                inputStream: PLLStream, flags: set[TParserFlag] = {}) = 
   OpenLexer(p.lex, filename, inputStream)
   initIdTable(p.repl)
   for i in countup(low(stdReplacements), high(stdReplacements)): 
     IdTablePut(p.repl, getIdent(stdReplacements[i][0]), 
                getIdent(stdReplacements[i][1]))
-  if gCmd == cmdBoot: 
+  if pfMoreReplacements in flags: 
     for i in countup(low(nimReplacements), high(nimReplacements)): 
       IdTablePut(p.repl, getIdent(nimReplacements[i][0]), 
                  getIdent(nimReplacements[i][1]))
+  p.flags = flags
   
-proc ClosePasParser(p: var TPasParser) = CloseLexer(p.lex)
-proc getTok(p: var TPasParser) = getPasTok(p.lex, p.tok)
+proc CloseParser(p: var TParser) = CloseLexer(p.lex)
+proc getTok(p: var TParser) = getTok(p.lex, p.tok)
 
-proc parMessage(p: TPasParser, msg: TMsgKind, arg = "") = 
+proc parMessage(p: TParser, msg: TMsgKind, arg = "") = 
   lexMessage(p.lex, msg, arg)
 
-proc parLineInfo(p: TPasParser): TLineInfo = 
+proc parLineInfo(p: TParser): TLineInfo = 
   result = getLineInfo(p.lex)
 
-proc skipCom(p: var TPasParser, n: PNode) = 
+proc skipCom(p: var TParser, n: PNode) = 
   while p.tok.xkind == pxComment: 
     if (n != nil): 
       if n.comment == nil: n.comment = p.tok.literal
@@ -100,48 +98,48 @@ proc skipCom(p: var TPasParser, n: PNode) =
       parMessage(p, warnCommentXIgnored, p.tok.literal)
     getTok(p)
 
-proc ExpectIdent(p: TPasParser) = 
+proc ExpectIdent(p: TParser) = 
   if p.tok.xkind != pxSymbol: 
-    lexMessage(p.lex, errIdentifierExpected, pasTokToStr(p.tok))
+    lexMessage(p.lex, errIdentifierExpected, $(p.tok))
   
-proc Eat(p: var TPasParser, xkind: TPasTokKind) = 
+proc Eat(p: var TParser, xkind: TTokKind) = 
   if p.tok.xkind == xkind: getTok(p)
-  else: lexMessage(p.lex, errTokenExpected, PasTokKindToStr[xkind])
+  else: lexMessage(p.lex, errTokenExpected, TokKindToStr(xkind))
   
-proc Opt(p: var TPasParser, xkind: TPasTokKind) = 
+proc Opt(p: var TParser, xkind: TTokKind) = 
   if p.tok.xkind == xkind: getTok(p)
   
-proc newNodeP(kind: TNodeKind, p: TPasParser): PNode = 
+proc newNodeP(kind: TNodeKind, p: TParser): PNode = 
   result = newNodeI(kind, getLineInfo(p.lex))
 
-proc newIntNodeP(kind: TNodeKind, intVal: BiggestInt, p: TPasParser): PNode = 
+proc newIntNodeP(kind: TNodeKind, intVal: BiggestInt, p: TParser): PNode = 
   result = newNodeP(kind, p)
   result.intVal = intVal
 
 proc newFloatNodeP(kind: TNodeKind, floatVal: BiggestFloat, 
-                   p: TPasParser): PNode = 
+                   p: TParser): PNode = 
   result = newNodeP(kind, p)
   result.floatVal = floatVal
 
-proc newStrNodeP(kind: TNodeKind, strVal: string, p: TPasParser): PNode = 
+proc newStrNodeP(kind: TNodeKind, strVal: string, p: TParser): PNode = 
   result = newNodeP(kind, p)
   result.strVal = strVal
 
-proc newIdentNodeP(ident: PIdent, p: TPasParser): PNode = 
+proc newIdentNodeP(ident: PIdent, p: TParser): PNode = 
   result = newNodeP(nkIdent, p)
   result.ident = ident
 
-proc createIdentNodeP(ident: PIdent, p: TPasParser): PNode = 
+proc createIdentNodeP(ident: PIdent, p: TParser): PNode = 
   result = newNodeP(nkIdent, p)
   var x = PIdent(IdTableGet(p.repl, ident))
   if x != nil: result.ident = x
   else: result.ident = ident
   
-proc parseExpr(p: var TPasParser): PNode
-proc parseStmt(p: var TPasParser): PNode
-proc parseTypeDesc(p: var TPasParser, definition: PNode = nil): PNode
+proc parseExpr(p: var TParser): PNode
+proc parseStmt(p: var TParser): PNode
+proc parseTypeDesc(p: var TParser, definition: PNode = nil): PNode
 
-proc parseEmit(p: var TPasParser, definition: PNode): PNode = 
+proc parseEmit(p: var TParser, definition: PNode): PNode = 
   getTok(p)                   # skip 'emit'
   result = nil
   if p.tok.xkind != pxCurlyDirRi: 
@@ -160,7 +158,7 @@ proc parseEmit(p: var TPasParser, definition: PNode): PNode =
       result = parseTypeDesc(p, definition)
   eat(p, pxCurlyDirRi)
 
-proc parseCommand(p: var TPasParser, definition: PNode = nil): PNode = 
+proc parseCommand(p: var TParser, definition: PNode = nil): PNode = 
   result = nil
   getTok(p)
   if p.tok.ident.id == getIdent("discard").id: 
@@ -183,7 +181,7 @@ proc parseCommand(p: var TPasParser, definition: PNode = nil): PNode =
       addSon(result, a.sons[0])
       addSon(result, a.sons[1])
     else: 
-      parMessage(p, errInvalidDirectiveX, pasTokToStr(p.tok))
+      parMessage(p, errInvalidDirectiveX, $(p.tok))
       result = a
   elif p.tok.ident.id == getIdent("emit").id: 
     result = parseEmit(p, definition)
@@ -218,24 +216,21 @@ proc parseCommand(p: var TPasParser, definition: PNode = nil): PNode =
     getTok(p)
     eat(p, pxCurlyDirRi)
   else: 
-    parMessage(p, errInvalidDirectiveX, pasTokToStr(p.tok))
+    parMessage(p, errInvalidDirectiveX, $(p.tok))
     while true: 
       getTok(p)
       if (p.tok.xkind == pxCurlyDirRi) or (p.tok.xkind == pxEof): break 
     eat(p, pxCurlyDirRi)
     result = nil
 
-proc getPrecedence(kind: TPasTokKind): int = 
+proc getPrecedence(kind: TTokKind): int = 
   case kind
-  of pxDiv, pxMod, pxStar, pxSlash, pxShl, pxShr, pxAnd: 
-    result = 5
-  of pxPlus, pxMinus, pxOr, pxXor: 
-    result = 4
-  of pxIn, pxEquals, pxLe, pxLt, pxGe, pxGt, pxNeq, pxIs: 
-    result = 3
+  of pxDiv, pxMod, pxStar, pxSlash, pxShl, pxShr, pxAnd: result = 5
+  of pxPlus, pxMinus, pxOr, pxXor: result = 4
+  of pxIn, pxEquals, pxLe, pxLt, pxGe, pxGt, pxNeq, pxIs: result = 3
   else: result = -1
   
-proc rangeExpr(p: var TPasParser): PNode = 
+proc rangeExpr(p: var TParser): PNode = 
   var a = parseExpr(p)
   if p.tok.xkind == pxDotDot: 
     result = newNodeP(nkRange, p)
@@ -246,7 +241,7 @@ proc rangeExpr(p: var TPasParser): PNode =
   else: 
     result = a
   
-proc bracketExprList(p: var TPasParser, first: PNode): PNode = 
+proc bracketExprList(p: var TParser, first: PNode): PNode = 
   result = newNodeP(nkBracketExpr, p)
   addSon(result, first)
   getTok(p)
@@ -256,7 +251,7 @@ proc bracketExprList(p: var TPasParser, first: PNode): PNode =
       getTok(p)
       break 
     if p.tok.xkind == pxEof: 
-      parMessage(p, errTokenExpected, PasTokKindToStr[pxBracketRi])
+      parMessage(p, errTokenExpected, TokKindToStr(pxBracketRi))
       break 
     var a = rangeExpr(p)
     skipCom(p, a)
@@ -265,8 +260,8 @@ proc bracketExprList(p: var TPasParser, first: PNode): PNode =
       skipCom(p, a)
     addSon(result, a)
 
-proc exprColonEqExpr(p: var TPasParser, kind: TNodeKind, 
-                     tok: TPasTokKind): PNode = 
+proc exprColonEqExpr(p: var TParser, kind: TNodeKind, 
+                     tok: TTokKind): PNode = 
   var a = parseExpr(p)
   if p.tok.xkind == tok: 
     result = newNodeP(kind, p)
@@ -277,8 +272,8 @@ proc exprColonEqExpr(p: var TPasParser, kind: TNodeKind,
   else: 
     result = a
   
-proc exprListAux(p: var TPasParser, elemKind: TNodeKind, 
-                 endTok, sepTok: TPasTokKind, result: PNode) = 
+proc exprListAux(p: var TParser, elemKind: TNodeKind, 
+                 endTok, sepTok: TTokKind, result: PNode) = 
   getTok(p)
   skipCom(p, result)
   while true: 
@@ -286,7 +281,7 @@ proc exprListAux(p: var TPasParser, elemKind: TNodeKind,
       getTok(p)
       break 
     if p.tok.xkind == pxEof: 
-      parMessage(p, errTokenExpected, PasTokKindToStr[endtok])
+      parMessage(p, errTokenExpected, TokKindToStr(endtok))
       break 
     var a = exprColonEqExpr(p, elemKind, sepTok)
     skipCom(p, a)
@@ -295,11 +290,11 @@ proc exprListAux(p: var TPasParser, elemKind: TNodeKind,
       skipCom(p, a)
     addSon(result, a)
 
-proc qualifiedIdent(p: var TPasParser): PNode = 
+proc qualifiedIdent(p: var TParser): PNode = 
   if p.tok.xkind == pxSymbol: 
     result = createIdentNodeP(p.tok.ident, p)
   else: 
-    parMessage(p, errIdentifierExpected, pasTokToStr(p.tok))
+    parMessage(p, errIdentifierExpected, $p.tok)
     return nil
   getTok(p)
   skipCom(p, result)
@@ -313,9 +308,9 @@ proc qualifiedIdent(p: var TPasParser): PNode =
       addSon(result, createIdentNodeP(p.tok.ident, p))
       getTok(p)
     else: 
-      parMessage(p, errIdentifierExpected, pasTokToStr(p.tok))
+      parMessage(p, errIdentifierExpected, $p.tok)
   
-proc qualifiedIdentListAux(p: var TPasParser, endTok: TPasTokKind, 
+proc qualifiedIdentListAux(p: var TParser, endTok: TTokKind, 
                            result: PNode) = 
   getTok(p)
   skipCom(p, result)
@@ -324,7 +319,7 @@ proc qualifiedIdentListAux(p: var TPasParser, endTok: TPasTokKind,
       getTok(p)
       break 
     if p.tok.xkind == pxEof: 
-      parMessage(p, errTokenExpected, PasTokKindToStr[endtok])
+      parMessage(p, errTokenExpected, TokKindToStr(endtok))
       break 
     var a = qualifiedIdent(p)
     skipCom(p, a)
@@ -333,8 +328,8 @@ proc qualifiedIdentListAux(p: var TPasParser, endTok: TPasTokKind,
       skipCom(p, a)
     addSon(result, a)
 
-proc exprColonEqExprList(p: var TPasParser, kind, elemKind: TNodeKind, 
-                         endTok, sepTok: TPasTokKind): PNode = 
+proc exprColonEqExprList(p: var TParser, kind, elemKind: TNodeKind, 
+                         endTok, sepTok: TTokKind): PNode = 
   result = newNodeP(kind, p)
   exprListAux(p, elemKind, endTok, sepTok, result)
 
@@ -345,7 +340,7 @@ proc setBaseFlags(n: PNode, base: TNumericalBase) =
   of base8: incl(n.flags, nfBase8)
   of base16: incl(n.flags, nfBase16)
   
-proc identOrLiteral(p: var TPasParser): PNode = 
+proc identOrLiteral(p: var TParser): PNode = 
   case p.tok.xkind
   of pxSymbol: 
     result = createIdentNodeP(p.tok.ident, p)
@@ -393,17 +388,17 @@ proc identOrLiteral(p: var TPasParser): PNode =
   of pxCommand: 
     result = parseCommand(p)
   else: 
-    parMessage(p, errExprExpected, pasTokToStr(p.tok))
+    parMessage(p, errExprExpected, $(p.tok))
     getTok(p) # we must consume a token here to prevend endless loops!
     result = nil
   if result != nil: skipCom(p, result)
   
-proc primary(p: var TPasParser): PNode = 
+proc primary(p: var TParser): PNode = 
   # prefix operator?
   if (p.tok.xkind == pxNot) or (p.tok.xkind == pxMinus) or
       (p.tok.xkind == pxPlus): 
     result = newNodeP(nkPrefix, p)
-    var a = newIdentNodeP(getIdent(pasTokToStr(p.tok)), p)
+    var a = newIdentNodeP(getIdent($(p.tok)), p)
     addSon(result, a)
     getTok(p)
     skipCom(p, a)
@@ -411,7 +406,7 @@ proc primary(p: var TPasParser): PNode =
     return 
   elif p.tok.xkind == pxAt: 
     result = newNodeP(nkAddr, p)
-    var a = newIdentNodeP(getIdent(pasTokToStr(p.tok)), p)
+    var a = newIdentNodeP(getIdent($(p.tok)), p)
     getTok(p)
     if p.tok.xkind == pxBracketLe: 
       result = newNodeP(nkPrefix, p)
@@ -438,7 +433,7 @@ proc primary(p: var TPasParser): PNode =
         addSon(result, createIdentNodeP(p.tok.ident, p))
         getTok(p)
       else: 
-        parMessage(p, errIdentifierExpected, pasTokToStr(p.tok))
+        parMessage(p, errIdentifierExpected, $(p.tok))
     of pxHat: 
       var a = result
       result = newNodeP(nkDerefExpr, p)
@@ -448,16 +443,16 @@ proc primary(p: var TPasParser): PNode =
       result = bracketExprList(p, result)
     else: break 
   
-proc lowestExprAux(p: var TPasParser, v: var PNode, limit: int): TPasTokKind = 
+proc lowestExprAux(p: var TParser, v: var PNode, limit: int): TTokKind = 
   var 
-    nextop: TPasTokKind
+    nextop: TTokKind
     v2, node, opNode: PNode
   v = primary(p) # expand while operators have priorities higher than 'limit'
   var op = p.tok.xkind
   var opPred = getPrecedence(op)
   while (opPred > limit): 
     node = newNodeP(nkInfix, p)
-    opNode = newIdentNodeP(getIdent(pasTokToStr(p.tok)), p) # skip operator:
+    opNode = newIdentNodeP(getIdent($(p.tok)), p) # skip operator:
     getTok(p)
     case op
     of pxPlus: 
@@ -498,10 +493,8 @@ proc fixExpr(n: PNode): PNode =
   if n == nil: return 
   case n.kind
   of nkInfix: 
-    if n.sons[1].kind == nkBracket: 
-      n.sons[1].kind = nkCurly
-    if n.sons[2].kind == nkBracket: 
-      n.sons[2].kind = nkCurly
+    if n.sons[1].kind == nkBracket: n.sons[1].kind = nkCurly
+    if n.sons[2].kind == nkBracket: n.sons[2].kind = nkCurly
     if (n.sons[0].kind == nkIdent): 
       if (n.sons[0].ident.id == getIdent("+").id): 
         if (n.sons[1].kind == nkCharLit) and (n.sons[2].kind == nkStrLit) and
@@ -517,7 +510,7 @@ proc fixExpr(n: PNode): PNode =
   if not (n.kind in {nkEmpty..nkNilLit}): 
     for i in countup(0, sonsLen(n) - 1): result.sons[i] = fixExpr(n.sons[i])
   
-proc parseExpr(p: var TPasParser): PNode = 
+proc parseExpr(p: var TParser): PNode = 
   var oldcontext = p.context
   p.context = conExpr
   if p.tok.xkind == pxCommand: 
@@ -527,7 +520,7 @@ proc parseExpr(p: var TPasParser): PNode =
     result = fixExpr(result)
   p.context = oldcontext
 
-proc parseExprStmt(p: var TPasParser): PNode = 
+proc parseExprStmt(p: var TParser): PNode = 
   var info = parLineInfo(p)
   var a = parseExpr(p)
   if p.tok.xkind == pxAsgn: 
@@ -545,7 +538,7 @@ proc inImportBlackList(ident: PIdent): bool =
     if ident.id == getIdent(ImportBlackList[i]).id: 
       return true
 
-proc parseUsesStmt(p: var TPasParser): PNode = 
+proc parseUsesStmt(p: var TParser): PNode = 
   var a: PNode
   result = newNodeP(nkImportStmt, p)
   getTok(p)                   # skip `import`
@@ -555,11 +548,11 @@ proc parseUsesStmt(p: var TPasParser): PNode =
     of pxEof: break 
     of pxSymbol: a = newIdentNodeP(p.tok.ident, p)
     else: 
-      parMessage(p, errIdentifierExpected, pasTokToStr(p.tok))
+      parMessage(p, errIdentifierExpected, $(p.tok))
       break 
     getTok(p)                 # skip identifier, string
     skipCom(p, a)
-    if (gCmd != cmdBoot) or not inImportBlackList(a.ident): 
+    if pfImportBlackList notin p.flags or not inImportBlackList(a.ident): 
       addSon(result, createIdentNodeP(a.ident, p))
     if p.tok.xkind == pxComma: 
       getTok(p)
@@ -568,14 +561,14 @@ proc parseUsesStmt(p: var TPasParser): PNode =
       break 
   if sonsLen(result) == 0: result = nil
   
-proc parseIncludeDir(p: var TPasParser): PNode = 
+proc parseIncludeDir(p: var TParser): PNode = 
   result = newNodeP(nkIncludeStmt, p)
   getTok(p)                   # skip `include`
   var filename = ""
   while true: 
     case p.tok.xkind
     of pxSymbol, pxDot, pxDotDot, pxSlash: 
-      filename = filename & pasTokToStr(p.tok)
+      filename = filename & $(p.tok)
       getTok(p)
     of pxStrLit: 
       filename = p.tok.literal
@@ -584,26 +577,26 @@ proc parseIncludeDir(p: var TPasParser): PNode =
     of pxCurlyDirRi: 
       break 
     else: 
-      parMessage(p, errIdentifierExpected, pasTokToStr(p.tok))
+      parMessage(p, errIdentifierExpected, $(p.tok))
       break 
   addSon(result, newStrNodeP(nkStrLit, changeFileExt(filename, "nim"), p))
   if filename == "config.inc": result = nil
   
-proc definedExprAux(p: var TPasParser): PNode = 
+proc definedExprAux(p: var TParser): PNode = 
   result = newNodeP(nkCall, p)
   addSon(result, newIdentNodeP(getIdent("defined"), p))
   ExpectIdent(p)
   addSon(result, createIdentNodeP(p.tok.ident, p))
   getTok(p)
 
-proc isHandledDirective(p: TPasParser): bool = 
+proc isHandledDirective(p: TParser): bool = 
   result = false
   if p.tok.xkind in {pxCurlyDirLe, pxStarDirLe}: 
-    case whichKeyword(p.tok.ident)
-    of wElse, wEndif: result = false
+    case toLower(p.tok.ident.s)
+    of "else", "endif": result = false
     else: result = true
   
-proc parseStmtList(p: var TPasParser): PNode = 
+proc parseStmtList(p: var TParser): PNode = 
   result = newNodeP(nkStmtList, p)
   while true: 
     case p.tok.xkind
@@ -616,27 +609,27 @@ proc parseStmtList(p: var TPasParser): PNode =
     addSon(result, parseStmt(p))
   if sonsLen(result) == 1: result = result.sons[0]
   
-proc parseIfDirAux(p: var TPasParser, result: PNode) = 
+proc parseIfDirAux(p: var TParser, result: PNode) = 
   addSon(result.sons[0], parseStmtList(p))
   if p.tok.xkind in {pxCurlyDirLe, pxStarDirLe}: 
     var endMarker = succ(p.tok.xkind)
-    if whichKeyword(p.tok.ident) == wElse: 
+    if toLower(p.tok.ident.s) == "else": 
       var s = newNodeP(nkElse, p)
-      while (p.tok.xkind != pxEof) and (p.tok.xkind != endMarker): getTok(p)
+      while p.tok.xkind != pxEof and p.tok.xkind != endMarker: getTok(p)
       eat(p, endMarker)
       addSon(s, parseStmtList(p))
       addSon(result, s)
     if p.tok.xkind in {pxCurlyDirLe, pxStarDirLe}: 
       endMarker = succ(p.tok.xkind)
-      if whichKeyword(p.tok.ident) == wEndif: 
-        while (p.tok.xkind != pxEof) and (p.tok.xkind != endMarker): getTok(p)
+      if toLower(p.tok.ident.s) == "endif": 
+        while p.tok.xkind != pxEof and p.tok.xkind != endMarker: getTok(p)
         eat(p, endMarker)
       else: 
         parMessage(p, errXExpected, "{$endif}")
   else: 
     parMessage(p, errXExpected, "{$endif}")
   
-proc parseIfdefDir(p: var TPasParser, endMarker: TPasTokKind): PNode = 
+proc parseIfdefDir(p: var TParser, endMarker: TTokKind): PNode = 
   result = newNodeP(nkWhenStmt, p)
   addSon(result, newNodeP(nkElifBranch, p))
   getTok(p)
@@ -644,7 +637,7 @@ proc parseIfdefDir(p: var TPasParser, endMarker: TPasTokKind): PNode =
   eat(p, endMarker)
   parseIfDirAux(p, result)
 
-proc parseIfndefDir(p: var TPasParser, endMarker: TPasTokKind): PNode = 
+proc parseIfndefDir(p: var TParser, endMarker: TTokKind): PNode = 
   result = newNodeP(nkWhenStmt, p)
   addSon(result, newNodeP(nkElifBranch, p))
   getTok(p)
@@ -655,7 +648,7 @@ proc parseIfndefDir(p: var TPasParser, endMarker: TPasTokKind): PNode =
   addSon(result.sons[0], e)
   parseIfDirAux(p, result)
 
-proc parseIfDir(p: var TPasParser, endMarker: TPasTokKind): PNode = 
+proc parseIfDir(p: var TParser, endMarker: TTokKind): PNode = 
   result = newNodeP(nkWhenStmt, p)
   addSon(result, newNodeP(nkElifBranch, p))
   getTok(p)
@@ -663,33 +656,33 @@ proc parseIfDir(p: var TPasParser, endMarker: TPasTokKind): PNode =
   eat(p, endMarker)
   parseIfDirAux(p, result)
 
-proc parseDirective(p: var TPasParser): PNode = 
+proc parseDirective(p: var TParser): PNode = 
   result = nil
   if not (p.tok.xkind in {pxCurlyDirLe, pxStarDirLe}): return 
   var endMarker = succ(p.tok.xkind)
   if p.tok.ident != nil: 
-    case whichKeyword(p.tok.ident)
-    of wInclude: 
+    case toLower(p.tok.ident.s)
+    of "include": 
       result = parseIncludeDir(p)
       eat(p, endMarker)
-    of wIf: result = parseIfDir(p, endMarker)
-    of wIfdef: result = parseIfdefDir(p, endMarker)
-    of wIfndef: result = parseIfndefDir(p, endMarker)
+    of "if": result = parseIfDir(p, endMarker)
+    of "ifdef": result = parseIfdefDir(p, endMarker)
+    of "ifndef": result = parseIfndefDir(p, endMarker)
     else: 
       # skip unknown compiler directive
-      while (p.tok.xkind != pxEof) and (p.tok.xkind != endMarker): getTok(p)
+      while p.tok.xkind != pxEof and p.tok.xkind != endMarker: getTok(p)
       eat(p, endMarker)
   else: 
     eat(p, endMarker)
   
-proc parseRaise(p: var TPasParser): PNode = 
+proc parseRaise(p: var TParser): PNode = 
   result = newNodeP(nkRaiseStmt, p)
   getTok(p)
   skipCom(p, result)
   if p.tok.xkind != pxSemicolon: addSon(result, parseExpr(p))
   else: addSon(result, nil)
   
-proc parseIf(p: var TPasParser): PNode = 
+proc parseIf(p: var TParser): PNode = 
   result = newNodeP(nkIfStmt, p)
   while true: 
     getTok(p)                 # skip ``if``
@@ -713,7 +706,7 @@ proc parseIf(p: var TPasParser): PNode =
     else: 
       break 
   
-proc parseWhile(p: var TPasParser): PNode = 
+proc parseWhile(p: var TParser): PNode = 
   result = newNodeP(nkWhileStmt, p)
   getTok(p)
   skipCom(p, result)
@@ -722,7 +715,7 @@ proc parseWhile(p: var TPasParser): PNode =
   skipCom(p, result)
   addSon(result, parseStmt(p))
 
-proc parseRepeat(p: var TPasParser): PNode = 
+proc parseRepeat(p: var TParser): PNode = 
   result = newNodeP(nkWhileStmt, p)
   getTok(p)
   skipCom(p, result)
@@ -746,7 +739,7 @@ proc parseRepeat(p: var TPasParser): PNode =
     addSon(s, a)
   addSon(result, s)
 
-proc parseCase(p: var TPasParser): PNode = 
+proc parseCase(p: var TParser): PNode = 
   var b: PNode
   result = newNodeP(nkCaseStmt, p)
   getTok(p)
@@ -770,7 +763,7 @@ proc parseCase(p: var TPasParser): PNode =
     if b.kind == nkElse: break 
   eat(p, pxEnd)
 
-proc parseTry(p: var TPasParser): PNode = 
+proc parseTry(p: var TParser): PNode = 
   result = newNodeP(nkTryStmt, p)
   getTok(p)
   skipCom(p, result)
@@ -807,8 +800,7 @@ proc parseTry(p: var TPasParser): PNode =
     addSon(result, e)
   eat(p, pxEnd)
 
-proc parseFor(p: var TPasParser): PNode = 
-  var a, b, c: PNode
+proc parseFor(p: var TParser): PNode = 
   result = newNodeP(nkForStmt, p)
   getTok(p)
   skipCom(p, result)
@@ -816,9 +808,9 @@ proc parseFor(p: var TPasParser): PNode =
   addSon(result, createIdentNodeP(p.tok.ident, p))
   getTok(p)
   eat(p, pxAsgn)
-  a = parseExpr(p)
-  b = nil
-  c = newNodeP(nkCall, p)
+  var a = parseExpr(p)
+  var b: PNode = nil
+  var c = newNodeP(nkCall, p)
   if p.tok.xkind == pxTo: 
     addSon(c, newIdentNodeP(getIdent("countup"), p))
     getTok(p)
@@ -828,7 +820,7 @@ proc parseFor(p: var TPasParser): PNode =
     getTok(p)
     b = parseExpr(p)
   else: 
-    parMessage(p, errTokenExpected, PasTokKindToStr[pxTo])
+    parMessage(p, errTokenExpected, TokKindToStr(pxTo))
   addSon(c, a)
   addSon(c, b)
   eat(p, pxDo)
@@ -836,7 +828,7 @@ proc parseFor(p: var TPasParser): PNode =
   addSon(result, c)
   addSon(result, parseStmt(p))
 
-proc parseParam(p: var TPasParser): PNode = 
+proc parseParam(p: var TParser): PNode = 
   var a, v: PNode
   result = newNodeP(nkIdentDefs, p)
   v = nil
@@ -856,7 +848,7 @@ proc parseParam(p: var TPasParser): PNode =
     of pxSymbol: a = createIdentNodeP(p.tok.ident, p)
     of pxColon, pxEof, pxParRi, pxEquals: break 
     else: 
-      parMessage(p, errIdentifierExpected, pasTokToStr(p.tok))
+      parMessage(p, errIdentifierExpected, $(p.tok))
       return 
     getTok(p)                 # skip identifier
     skipCom(p, a)
@@ -873,7 +865,7 @@ proc parseParam(p: var TPasParser): PNode =
   else: 
     addSon(result, nil)
     if p.tok.xkind != pxEquals: 
-      parMessage(p, errColonOrEqualsExpected, pasTokToStr(p.tok))
+      parMessage(p, errColonOrEqualsExpected, $(p.tok))
   if p.tok.xkind == pxEquals: 
     getTok(p)
     skipCom(p, result)
@@ -881,7 +873,7 @@ proc parseParam(p: var TPasParser): PNode =
   else: 
     addSon(result, nil)
   
-proc parseParamList(p: var TPasParser): PNode = 
+proc parseParamList(p: var TParser): PNode = 
   var a: PNode
   result = newNodeP(nkFormalParams, p)
   addSon(result, nil)         # return type
@@ -910,16 +902,16 @@ proc parseParamList(p: var TPasParser): PNode =
     skipCom(p, result)
     result.sons[0] = parseTypeDesc(p)
 
-proc parseCallingConvention(p: var TPasParser): PNode = 
+proc parseCallingConvention(p: var TParser): PNode = 
   result = nil
   if p.tok.xkind == pxSymbol: 
-    case whichKeyword(p.tok.ident)
-    of wStdcall, wCDecl, wSafeCall, wSysCall, wInline, wFastCall: 
+    case toLower(p.tok.ident.s)
+    of "stdcall", "cdecl", "safecall", "syscall", "inline", "fastcall": 
       result = newNodeP(nkPragma, p)
       addSon(result, newIdentNodeP(p.tok.ident, p))
       getTok(p)
       opt(p, pxSemicolon)
-    of wRegister: 
+    of "register": 
       result = newNodeP(nkPragma, p)
       addSon(result, newIdentNodeP(getIdent("fastcall"), p))
       getTok(p)
@@ -927,20 +919,20 @@ proc parseCallingConvention(p: var TPasParser): PNode =
     else: 
       nil
 
-proc parseRoutineSpecifiers(p: var TPasParser, noBody: var bool): PNode = 
+proc parseRoutineSpecifiers(p: var TParser, noBody: var bool): PNode = 
   var e: PNode
   result = parseCallingConvention(p)
   noBody = false
   while p.tok.xkind == pxSymbol: 
-    case whichKeyword(p.tok.ident)
-    of wAssembler, wOverload, wFar: 
+    case toLower(p.tok.ident.s)
+    of "assembler", "overload", "far": 
       getTok(p)
       opt(p, pxSemicolon)
-    of wForward: 
+    of "forward": 
       noBody = true
       getTok(p)
       opt(p, pxSemicolon)
-    of wImportc: 
+    of "importc": 
       # This is a fake for platform module. There is no ``importc``
       # directive in Pascal.
       if result == nil: result = newNodeP(nkPragma, p)
@@ -948,7 +940,7 @@ proc parseRoutineSpecifiers(p: var TPasParser, noBody: var bool): PNode =
       noBody = true
       getTok(p)
       opt(p, pxSemicolon)
-    of wNoConv: 
+    of "noconv": 
       # This is a fake for platform module. There is no ``noconv``
       # directive in Pascal.
       if result == nil: result = newNodeP(nkPragma, p)
@@ -956,19 +948,19 @@ proc parseRoutineSpecifiers(p: var TPasParser, noBody: var bool): PNode =
       noBody = true
       getTok(p)
       opt(p, pxSemicolon)
-    of wProcVar: 
+    of "procvar": 
       # This is a fake for the Nimrod compiler. There is no ``procvar``
       # directive in Pascal.
       if result == nil: result = newNodeP(nkPragma, p)
       addSon(result, newIdentNodeP(getIdent("procvar"), p))
       getTok(p)
       opt(p, pxSemicolon)
-    of wVarargs: 
+    of "varargs": 
       if result == nil: result = newNodeP(nkPragma, p)
       addSon(result, newIdentNodeP(getIdent("varargs"), p))
       getTok(p)
       opt(p, pxSemicolon)
-    of wExternal: 
+    of "external": 
       if result == nil: result = newNodeP(nkPragma, p)
       getTok(p)
       noBody = true
@@ -993,7 +985,7 @@ proc parseRoutineSpecifiers(p: var TPasParser, noBody: var bool): PNode =
       if result == nil: result = newNodeP(nkPragma, p)
       addSon(result, e.sons[0])
 
-proc parseRoutineType(p: var TPasParser): PNode = 
+proc parseRoutineType(p: var TParser): PNode = 
   result = newNodeP(nkProcTy, p)
   getTok(p)
   skipCom(p, result)
@@ -1002,8 +994,8 @@ proc parseRoutineType(p: var TPasParser): PNode =
   addSon(result, parseCallingConvention(p))
   skipCom(p, result)
 
-proc parseEnum(p: var TPasParser): PNode = 
-  var a, b: PNode
+proc parseEnum(p: var TParser): PNode = 
+  var a: PNode
   result = newNodeP(nkEnumTy, p)
   getTok(p)
   skipCom(p, result)
@@ -1013,14 +1005,14 @@ proc parseEnum(p: var TPasParser): PNode =
     of pxEof, pxParRi: break 
     of pxSymbol: a = newIdentNodeP(p.tok.ident, p)
     else: 
-      parMessage(p, errIdentifierExpected, pasTokToStr(p.tok))
+      parMessage(p, errIdentifierExpected, $(p.tok))
       break 
     getTok(p)                 # skip identifier
     skipCom(p, a)
     if (p.tok.xkind == pxEquals) or (p.tok.xkind == pxAsgn): 
       getTok(p)
       skipCom(p, a)
-      b = a
+      var b = a
       a = newNodeP(nkEnumFieldDef, p)
       addSon(a, b)
       addSon(a, parseExpr(p))
@@ -1030,7 +1022,7 @@ proc parseEnum(p: var TPasParser): PNode =
     addSon(result, a)
   eat(p, pxParRi)
 
-proc identVis(p: var TPasParser): PNode = 
+proc identVis(p: var TParser): PNode = 
   # identifier with visability
   var a = createIdentNodeP(p.tok.ident, p)
   if p.section == seInterface: 
@@ -1042,13 +1034,13 @@ proc identVis(p: var TPasParser): PNode =
   getTok(p)
 
 type 
-  TSymbolParser = proc (p: var TPasParser): PNode
+  TSymbolParser = proc (p: var TParser): PNode
 
-proc rawIdent(p: var TPasParser): PNode = 
+proc rawIdent(p: var TParser): PNode = 
   result = createIdentNodeP(p.tok.ident, p)
   getTok(p)
 
-proc parseIdentColonEquals(p: var TPasParser, 
+proc parseIdentColonEquals(p: var TParser, 
                            identParser: TSymbolParser): PNode = 
   var a: PNode
   result = newNodeP(nkIdentDefs, p)
@@ -1057,7 +1049,7 @@ proc parseIdentColonEquals(p: var TPasParser,
     of pxSymbol: a = identParser(p)
     of pxColon, pxEof, pxParRi, pxEquals: break 
     else: 
-      parMessage(p, errIdentifierExpected, pasTokToStr(p.tok))
+      parMessage(p, errIdentifierExpected, $(p.tok))
       return 
     skipCom(p, a)
     if p.tok.xkind == pxComma: 
@@ -1071,7 +1063,7 @@ proc parseIdentColonEquals(p: var TPasParser,
   else: 
     addSon(result, nil)
     if p.tok.xkind != pxEquals: 
-      parMessage(p, errColonOrEqualsExpected, pasTokToStr(p.tok))
+      parMessage(p, errColonOrEqualsExpected, $(p.tok))
   if p.tok.xkind == pxEquals: 
     getTok(p)
     skipCom(p, result)
@@ -1082,7 +1074,7 @@ proc parseIdentColonEquals(p: var TPasParser,
     getTok(p)
     skipCom(p, result)
 
-proc parseRecordCase(p: var TPasParser): PNode = 
+proc parseRecordCase(p: var TParser): PNode = 
   var a, b, c: PNode
   result = newNodeP(nkRecCase, p)
   getTok(p)
@@ -1123,7 +1115,7 @@ proc parseRecordCase(p: var TPasParser): PNode =
     addSon(result, b)
     if b.kind == nkElse: break 
   
-proc parseRecordPart(p: var TPasParser): PNode = 
+proc parseRecordPart(p: var TParser): PNode = 
   result = nil
   while (p.tok.xkind != pxEof) and (p.tok.xkind != pxEnd): 
     if result == nil: result = newNodeP(nkRecList, p)
@@ -1137,7 +1129,7 @@ proc parseRecordPart(p: var TPasParser): PNode =
     of pxComment: 
       skipCom(p, lastSon(result))
     else: 
-      parMessage(p, errIdentifierExpected, pasTokToStr(p.tok))
+      parMessage(p, errIdentifierExpected, $(p.tok))
       break 
 
 proc exSymbol(n: var PNode) = 
@@ -1182,7 +1174,7 @@ proc addPragmaToIdent(ident: var PNode, pragma: PNode) =
       InternalError(ident.info, "addPragmaToIdent")
   addSon(pragmasNode, pragma)
 
-proc parseRecordBody(p: var TPasParser, result, definition: PNode) = 
+proc parseRecordBody(p: var TParser, result, definition: PNode) = 
   skipCom(p, result)
   var a = parseRecordPart(p)
   if result.kind != nkTupleTy: fixRecordDef(a)
@@ -1206,7 +1198,7 @@ proc parseRecordBody(p: var TPasParser, result, definition: PNode) =
   opt(p, pxSemicolon)
   skipCom(p, result)
 
-proc parseRecordOrObject(p: var TPasParser, kind: TNodeKind, 
+proc parseRecordOrObject(p: var TParser, kind: TNodeKind, 
                          definition: PNode): PNode = 
   result = newNodeP(kind, p)
   getTok(p)
@@ -1221,7 +1213,7 @@ proc parseRecordOrObject(p: var TPasParser, kind: TNodeKind,
     addSon(result, nil)
   parseRecordBody(p, result, definition)
 
-proc parseTypeDesc(p: var TPasParser, definition: PNode = nil): PNode = 
+proc parseTypeDesc(p: var TParser, definition: PNode = nil): PNode = 
   var oldcontext = p.context
   p.context = conTypeDesc
   if p.tok.xkind == pxPacked: getTok(p)
@@ -1273,7 +1265,7 @@ proc parseTypeDesc(p: var TPasParser, definition: PNode = nil): PNode =
   of pxHat: 
     getTok(p)
     if p.tok.xkind == pxCommand: result = parseCommand(p)
-    elif gCmd == cmdBoot: result = newNodeP(nkRefTy, p)
+    elif pfRefs in p.flags: result = newNodeP(nkRefTy, p)
     else: result = newNodeP(nkPtrTy, p)
     addSon(result, parseTypeDesc(p))
   of pxType: 
@@ -1293,7 +1285,7 @@ proc parseTypeDesc(p: var TPasParser, definition: PNode = nil): PNode =
       result = a
   p.context = oldcontext
 
-proc parseTypeDef(p: var TPasParser): PNode = 
+proc parseTypeDef(p: var TParser): PNode = 
   result = newNodeP(nkTypeDef, p)
   addSon(result, identVis(p))
   addSon(result, nil)         # generic params
@@ -1307,14 +1299,14 @@ proc parseTypeDef(p: var TPasParser): PNode =
     getTok(p)
     skipCom(p, result)
 
-proc parseTypeSection(p: var TPasParser): PNode = 
+proc parseTypeSection(p: var TParser): PNode = 
   result = newNodeP(nkTypeSection, p)
   getTok(p)
   skipCom(p, result)
   while p.tok.xkind == pxSymbol: 
     addSon(result, parseTypeDef(p))
 
-proc parseConstant(p: var TPasParser): PNode = 
+proc parseConstant(p: var TParser): PNode = 
   result = newNodeP(nkConstDef, p)
   addSon(result, identVis(p))
   if p.tok.xkind == pxColon: 
@@ -1324,7 +1316,7 @@ proc parseConstant(p: var TPasParser): PNode =
   else: 
     addSon(result, nil)
     if p.tok.xkind != pxEquals: 
-      parMessage(p, errColonOrEqualsExpected, pasTokToStr(p.tok))
+      parMessage(p, errColonOrEqualsExpected, $(p.tok))
   if p.tok.xkind == pxEquals: 
     getTok(p)
     skipCom(p, result)
@@ -1335,14 +1327,14 @@ proc parseConstant(p: var TPasParser): PNode =
     getTok(p)
     skipCom(p, result)
 
-proc parseConstSection(p: var TPasParser): PNode = 
+proc parseConstSection(p: var TParser): PNode = 
   result = newNodeP(nkConstSection, p)
   getTok(p)
   skipCom(p, result)
   while p.tok.xkind == pxSymbol: 
     addSon(result, parseConstant(p))
 
-proc parseVar(p: var TPasParser): PNode = 
+proc parseVar(p: var TParser): PNode = 
   result = newNodeP(nkVarSection, p)
   getTok(p)
   skipCom(p, result)
@@ -1350,7 +1342,7 @@ proc parseVar(p: var TPasParser): PNode =
     addSon(result, parseIdentColonEquals(p, identVis))
   p.lastVarSection = result
 
-proc parseRoutine(p: var TPasParser): PNode = 
+proc parseRoutine(p: var TParser): PNode = 
   var 
     stmts: PNode
     noBody: bool
@@ -1381,7 +1373,7 @@ proc parseRoutine(p: var TPasParser): PNode =
     for i in countup(0, sonsLen(a) - 1): addSon(stmts, a.sons[i])
     addSon(result, stmts)
 
-proc fixExit(p: var TPasParser, n: PNode): bool = 
+proc fixExit(p: var TParser, n: PNode): bool = 
   result = false
   if (p.tok.ident.id == getIdent("exit").id): 
     var length = sonsLen(n)
@@ -1396,7 +1388,7 @@ proc fixExit(p: var TPasParser, n: PNode): bool =
       opt(p, pxSemicolon)
       skipCom(p, a)
 
-proc fixVarSection(p: var TPasParser, counter: PNode) = 
+proc fixVarSection(p: var TParser, counter: PNode) = 
   if p.lastVarSection == nil: return 
   assert(counter.kind == nkIdent)
   for i in countup(0, sonsLen(p.lastVarSection) - 1): 
@@ -1408,7 +1400,23 @@ proc fixVarSection(p: var TPasParser, counter: PNode) =
           delSon(p.lastVarSection, i)
         return 
 
-proc parseBegin(p: var TPasParser, result: PNode) = 
+proc exSymbols(n: PNode) = 
+  case n.kind
+  of nkEmpty..nkNilLit: nil
+  of nkProcDef..nkIteratorDef: exSymbol(n.sons[namePos])
+  of nkWhenStmt, nkStmtList: 
+    for i in countup(0, sonsLen(n) - 1): exSymbols(n.sons[i])
+  of nkVarSection, nkConstSection: 
+    for i in countup(0, sonsLen(n) - 1): exSymbol(n.sons[i].sons[0])
+  of nkTypeSection: 
+    for i in countup(0, sonsLen(n) - 1): 
+      exSymbol(n.sons[i].sons[0])
+      if (n.sons[i].sons[2] != nil) and
+          (n.sons[i].sons[2].kind == nkObjectTy): 
+        fixRecordDef(n.sons[i].sons[2])
+  else: nil
+
+proc parseBegin(p: var TParser, result: PNode) = 
   getTok(p)
   while true: 
     case p.tok.xkind
@@ -1423,7 +1431,7 @@ proc parseBegin(p: var TPasParser, result: PNode) =
     else: addSonIfNotNil(result, parseStmt(p))
   if sonsLen(result) == 0: addSon(result, newNodeP(nkNilLit, p))
   
-proc parseStmt(p: var TPasParser): PNode = 
+proc parseStmt(p: var TParser): PNode = 
   var oldcontext = p.context
   p.context = conStmt
   result = nil
@@ -1489,7 +1497,7 @@ proc parseStmt(p: var TPasParser): PNode =
   if result != nil: skipCom(p, result)
   p.context = oldcontext
 
-proc parseUnit(p: var TPasParser): PNode = 
+proc parseUnit(p: var TParser): PNode = 
   result = newNodeP(nkStmtList, p)
   getTok(p)                   # read first token
   while true: