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