mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-12 06:18:51 +00:00
compiler refactoring, pass config around explicitly
This commit is contained in:
@@ -790,7 +790,7 @@ proc writeOutputJson*(d: PDoc, filename, outExt: string,
|
||||
discard "fixme: error report"
|
||||
|
||||
proc commandDoc*() =
|
||||
var ast = parseFile(gProjectMainIdx.FileIndex, newIdentCache())
|
||||
var ast = parseFile(gProjectMainIdx.FileIndex, newIdentCache(), newConfigRef())
|
||||
if ast == nil: return
|
||||
var d = newDocumentor(gProjectFull, options.gConfigVars)
|
||||
d.hasToc = true
|
||||
@@ -840,7 +840,7 @@ proc commandRst2TeX*() =
|
||||
commandRstAux(gProjectFull, TexExt)
|
||||
|
||||
proc commandJson*() =
|
||||
var ast = parseFile(gProjectMainIdx.FileIndex, newIdentCache())
|
||||
var ast = parseFile(gProjectMainIdx.FileIndex, newIdentCache(), newConfigRef())
|
||||
if ast == nil: return
|
||||
var d = newDocumentor(gProjectFull, options.gConfigVars)
|
||||
d.hasToc = true
|
||||
@@ -855,7 +855,7 @@ proc commandJson*() =
|
||||
writeRope(content, getOutFile(gProjectFull, JsonExt), useWarning = false)
|
||||
|
||||
proc commandTags*() =
|
||||
var ast = parseFile(gProjectMainIdx.FileIndex, newIdentCache())
|
||||
var ast = parseFile(gProjectMainIdx.FileIndex, newIdentCache(), newConfigRef())
|
||||
if ast == nil: return
|
||||
var d = newDocumentor(gProjectFull, options.gConfigVars)
|
||||
d.hasToc = true
|
||||
|
||||
@@ -144,13 +144,12 @@ type
|
||||
cache*: IdentCache
|
||||
when defined(nimsuggest):
|
||||
previousToken: TLineInfo
|
||||
config*: ConfigRef
|
||||
|
||||
when defined(nimpretty):
|
||||
var
|
||||
gIndentationWidth*: int
|
||||
|
||||
var gLinesCompiled*: int # all lines that have been compiled
|
||||
|
||||
proc getLineInfo*(L: TLexer, tok: TToken): TLineInfo {.inline.} =
|
||||
result = newLineInfo(L.fileIdx, tok.line, tok.col)
|
||||
when defined(nimpretty):
|
||||
@@ -222,7 +221,7 @@ proc fillToken(L: var TToken) =
|
||||
L.commentOffsetB = 0
|
||||
|
||||
proc openLexer*(lex: var TLexer, fileIdx: FileIndex, inputstream: PLLStream;
|
||||
cache: IdentCache) =
|
||||
cache: IdentCache; config: ConfigRef) =
|
||||
openBaseLexer(lex, inputstream)
|
||||
lex.fileIdx = fileidx
|
||||
lex.indentAhead = - 1
|
||||
@@ -231,13 +230,14 @@ proc openLexer*(lex: var TLexer, fileIdx: FileIndex, inputstream: PLLStream;
|
||||
lex.cache = cache
|
||||
when defined(nimsuggest):
|
||||
lex.previousToken.fileIndex = fileIdx
|
||||
lex.config = config
|
||||
|
||||
proc openLexer*(lex: var TLexer, filename: string, inputstream: PLLStream;
|
||||
cache: IdentCache) =
|
||||
openLexer(lex, filename.fileInfoIdx, inputstream, cache)
|
||||
cache: IdentCache; config: ConfigRef) =
|
||||
openLexer(lex, filename.fileInfoIdx, inputstream, cache, config)
|
||||
|
||||
proc closeLexer*(lex: var TLexer) =
|
||||
inc(gLinesCompiled, lex.lineNumber)
|
||||
inc(lex.config.linesCompiled, lex.lineNumber)
|
||||
closeBaseLexer(lex)
|
||||
|
||||
proc getLineInfo(L: TLexer): TLineInfo =
|
||||
@@ -576,17 +576,18 @@ proc getNumber(L: var TLexer, result: var TToken) =
|
||||
result.iNumber = parseBiggestInt(result.literal)
|
||||
|
||||
# Explicit bounds checks
|
||||
let outOfRange = case result.tokType:
|
||||
of tkInt8Lit: (result.iNumber < int8.low or result.iNumber > int8.high)
|
||||
of tkUInt8Lit: (result.iNumber < BiggestInt(uint8.low) or
|
||||
result.iNumber > BiggestInt(uint8.high))
|
||||
of tkInt16Lit: (result.iNumber < int16.low or result.iNumber > int16.high)
|
||||
of tkUInt16Lit: (result.iNumber < BiggestInt(uint16.low) or
|
||||
result.iNumber > BiggestInt(uint16.high))
|
||||
of tkInt32Lit: (result.iNumber < int32.low or result.iNumber > int32.high)
|
||||
of tkUInt32Lit: (result.iNumber < BiggestInt(uint32.low) or
|
||||
result.iNumber > BiggestInt(uint32.high))
|
||||
else: false
|
||||
let outOfRange =
|
||||
case result.tokType
|
||||
of tkInt8Lit: (result.iNumber < int8.low or result.iNumber > int8.high)
|
||||
of tkUInt8Lit: (result.iNumber < BiggestInt(uint8.low) or
|
||||
result.iNumber > BiggestInt(uint8.high))
|
||||
of tkInt16Lit: (result.iNumber < int16.low or result.iNumber > int16.high)
|
||||
of tkUInt16Lit: (result.iNumber < BiggestInt(uint16.low) or
|
||||
result.iNumber > BiggestInt(uint16.high))
|
||||
of tkInt32Lit: (result.iNumber < int32.low or result.iNumber > int32.high)
|
||||
of tkUInt32Lit: (result.iNumber < BiggestInt(uint32.low) or
|
||||
result.iNumber > BiggestInt(uint32.high))
|
||||
else: false
|
||||
|
||||
if outOfRange: lexMessageLitNum(L, errNumberOutOfRange, startpos)
|
||||
|
||||
|
||||
@@ -129,9 +129,10 @@ proc commandEval(graph: ModuleGraph; cache: IdentCache; exp: string) =
|
||||
interactivePasses(graph, cache)
|
||||
compileSystemModule(graph, cache)
|
||||
let echoExp = "echo \"eval\\t\", " & "repr(" & exp & ")"
|
||||
evalNim(graph, echoExp.parseString(cache), makeStdinModule(graph), cache)
|
||||
evalNim(graph, echoExp.parseString(cache, graph.config),
|
||||
makeStdinModule(graph), cache)
|
||||
|
||||
proc commandScan(cache: IdentCache) =
|
||||
proc commandScan(cache: IdentCache, config: ConfigRef) =
|
||||
var f = addFileExt(mainCommandArg(), NimExt)
|
||||
var stream = llStreamOpen(f, fmRead)
|
||||
if stream != nil:
|
||||
@@ -139,7 +140,7 @@ proc commandScan(cache: IdentCache) =
|
||||
L: TLexer
|
||||
tok: TToken
|
||||
initToken(tok)
|
||||
openLexer(L, f, stream, cache)
|
||||
openLexer(L, f, stream, cache, config)
|
||||
while true:
|
||||
rawGetTok(L, tok)
|
||||
printTok(tok)
|
||||
@@ -265,11 +266,11 @@ proc mainCommand*(graph: ModuleGraph; cache: IdentCache) =
|
||||
of "parse":
|
||||
gCmd = cmdParse
|
||||
wantMainModule()
|
||||
discard parseFile(FileIndex gProjectMainIdx, cache)
|
||||
discard parseFile(FileIndex gProjectMainIdx, cache, graph.config)
|
||||
of "scan":
|
||||
gCmd = cmdScan
|
||||
wantMainModule()
|
||||
commandScan(cache)
|
||||
commandScan(cache, graph.config)
|
||||
msgWriteln("Beware: Indentation tokens depend on the parser's state!")
|
||||
of "secret":
|
||||
gCmd = cmdInteractive
|
||||
@@ -291,7 +292,7 @@ proc mainCommand*(graph: ModuleGraph; cache: IdentCache) =
|
||||
let usedMem = formatSize(getMaxMem()) & " peakmem"
|
||||
else:
|
||||
let usedMem = formatSize(getTotalMem())
|
||||
rawMessage(hintSuccessX, [$gLinesCompiled,
|
||||
rawMessage(hintSuccessX, [$graph.config.linesCompiled,
|
||||
formatFloat(epochTime() - gLastCmdTime, ffDecimal, 3),
|
||||
usedMem,
|
||||
if condSyms.isDefined("release"): "Release Build"
|
||||
|
||||
@@ -107,7 +107,7 @@ proc importModule*(graph: ModuleGraph; s: PSym, fileIdx: FileIndex;
|
||||
|
||||
proc includeModule*(graph: ModuleGraph; s: PSym, fileIdx: FileIndex;
|
||||
cache: IdentCache): PNode {.procvar.} =
|
||||
result = syntaxes.parseFile(fileIdx, cache)
|
||||
result = syntaxes.parseFile(fileIdx, cache, graph.config)
|
||||
graph.addDep(s, fileIdx)
|
||||
graph.addIncludeDep(s.position.FileIndex, fileIdx)
|
||||
|
||||
|
||||
@@ -205,7 +205,7 @@ proc readConfigFile(filename: string; cache: IdentCache; config: ConfigRef) =
|
||||
stream = llStreamOpen(filename, fmRead)
|
||||
if stream != nil:
|
||||
initToken(tok)
|
||||
openLexer(L, filename, stream, cache)
|
||||
openLexer(L, filename, stream, cache, config)
|
||||
tok.tokType = tkEof # to avoid a pointless warning
|
||||
confTok(L, tok, config) # read in the first token
|
||||
while tok.tokType != tkEof: parseAssignment(L, tok, config)
|
||||
|
||||
@@ -113,6 +113,7 @@ type
|
||||
notnil
|
||||
|
||||
ConfigRef* = ref object ## eventually all global configuration should be moved here
|
||||
linesCompiled*: int # all lines that have been compiled
|
||||
cppDefines*: HashSet[string]
|
||||
headerFile*: string
|
||||
features*: set[Feature]
|
||||
|
||||
@@ -27,7 +27,7 @@ when isMainModule:
|
||||
outp.close
|
||||
|
||||
import
|
||||
llstream, lexer, idents, strutils, ast, astalgo, msgs
|
||||
llstream, lexer, idents, strutils, ast, astalgo, msgs, options
|
||||
|
||||
type
|
||||
TParser* = object # A TParser object represents a file that
|
||||
@@ -84,20 +84,20 @@ proc getTok(p: var TParser) =
|
||||
p.hasProgress = true
|
||||
|
||||
proc openParser*(p: var TParser, fileIdx: FileIndex, inputStream: PLLStream,
|
||||
cache: IdentCache;
|
||||
cache: IdentCache; config: ConfigRef;
|
||||
strongSpaces=false) =
|
||||
## Open a parser, using the given arguments to set up its internal state.
|
||||
##
|
||||
initToken(p.tok)
|
||||
openLexer(p.lex, fileIdx, inputStream, cache)
|
||||
openLexer(p.lex, fileIdx, inputStream, cache, config)
|
||||
getTok(p) # read the first token
|
||||
p.firstTok = true
|
||||
p.strongSpaces = strongSpaces
|
||||
|
||||
proc openParser*(p: var TParser, filename: string, inputStream: PLLStream,
|
||||
cache: IdentCache;
|
||||
cache: IdentCache; config: ConfigRef;
|
||||
strongSpaces=false) =
|
||||
openParser(p, filename.fileInfoIdx, inputStream, cache, strongSpaces)
|
||||
openParser(p, filename.fileInfoIdx, inputStream, cache, config, strongSpaces)
|
||||
|
||||
proc closeParser(p: var TParser) =
|
||||
## Close a parser, freeing up its resources.
|
||||
@@ -2178,8 +2178,8 @@ proc parseTopLevelStmt(p: var TParser): PNode =
|
||||
if result.kind == nkEmpty: parMessage(p, errExprExpected, p.tok)
|
||||
break
|
||||
|
||||
proc parseString*(s: string; cache: IdentCache; filename: string = "";
|
||||
line: int = 0;
|
||||
proc parseString*(s: string; cache: IdentCache; config: ConfigRef;
|
||||
filename: string = ""; line: int = 0;
|
||||
errorHandler: TErrorHandler = nil): PNode =
|
||||
## Parses a string into an AST, returning the top node.
|
||||
## `filename` and `line`, although optional, provide info so that the
|
||||
@@ -2192,7 +2192,7 @@ proc parseString*(s: string; cache: IdentCache; filename: string = "";
|
||||
# XXX for now the builtin 'parseStmt/Expr' functions do not know about strong
|
||||
# spaces...
|
||||
parser.lex.errorHandler = errorHandler
|
||||
openParser(parser, filename, stream, cache, false)
|
||||
openParser(parser, filename, stream, cache, config, false)
|
||||
|
||||
result = parser.parseAll
|
||||
closeParser(parser)
|
||||
|
||||
@@ -207,7 +207,7 @@ proc processModule*(graph: ModuleGraph; module: PSym, stream: PLLStream,
|
||||
else:
|
||||
s = stream
|
||||
while true:
|
||||
openParsers(p, fileIdx, s, cache)
|
||||
openParsers(p, fileIdx, s, cache, graph.config)
|
||||
|
||||
if sfSystemModule notin module.flags:
|
||||
# XXX what about caching? no processing then? what if I change the
|
||||
|
||||
1790
compiler/pbraces.nim
1790
compiler/pbraces.nim
File diff suppressed because it is too large
Load Diff
@@ -137,7 +137,7 @@ proc hasIncludes(n:PNode): bool =
|
||||
|
||||
proc includeModule*(graph: ModuleGraph; s: PSym, fileIdx: FileIndex;
|
||||
cache: IdentCache): PNode {.procvar.} =
|
||||
result = syntaxes.parseFile(fileIdx, cache)
|
||||
result = syntaxes.parseFile(fileIdx, cache, graph.config)
|
||||
graph.addDep(s, fileIdx)
|
||||
graph.addIncludeDep(FileIndex s.position, fileIdx)
|
||||
|
||||
@@ -273,9 +273,9 @@ proc hasCommand(n: PNode): bool =
|
||||
of nkStmtList, nkStmtListExpr, nkWhenStmt, nkElifBranch, nkElse,
|
||||
nkStaticStmt, nkLetSection, nkConstSection, nkVarSection,
|
||||
nkIdentDefs:
|
||||
for a in n:
|
||||
if a.hasCommand:
|
||||
return true
|
||||
for a in n:
|
||||
if a.hasCommand:
|
||||
return true
|
||||
else:
|
||||
return false
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ proc listDirs(a: VmArgs, filter: set[PathComponent]) =
|
||||
proc setupVM*(module: PSym; cache: IdentCache; scriptName: string;
|
||||
config: ConfigRef): PEvalContext =
|
||||
# For Nimble we need to export 'setupVM'.
|
||||
result = newCtx(module, cache)
|
||||
result = newCtx(module, cache, config)
|
||||
result.mode = emRepl
|
||||
registerAdditionalOps(result)
|
||||
|
||||
|
||||
@@ -313,7 +313,7 @@ proc tryConstExpr(c: PContext, n: PNode): PNode =
|
||||
msgs.gErrorMax = high(int)
|
||||
|
||||
try:
|
||||
result = evalConstExpr(c.module, c.cache, e)
|
||||
result = evalConstExpr(c.module, c.cache, c.graph.config, e)
|
||||
if result == nil or result.kind == nkEmpty:
|
||||
result = nil
|
||||
else:
|
||||
@@ -334,7 +334,7 @@ proc semConstExpr(c: PContext, n: PNode): PNode =
|
||||
result = getConstExpr(c.module, e)
|
||||
if result == nil:
|
||||
#if e.kind == nkEmpty: globalError(n.info, errConstExprExpected)
|
||||
result = evalConstExpr(c.module, c.cache, e)
|
||||
result = evalConstExpr(c.module, c.cache, c.graph.config, e)
|
||||
if result == nil or result.kind == nkEmpty:
|
||||
if e.info != n.info:
|
||||
pushInfoContext(n.info)
|
||||
@@ -439,7 +439,7 @@ proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym,
|
||||
|
||||
#if c.evalContext == nil:
|
||||
# c.evalContext = c.createEvalContext(emStatic)
|
||||
result = evalMacroCall(c.module, c.cache, n, nOrig, sym)
|
||||
result = evalMacroCall(c.module, c.cache, c.graph.config, n, nOrig, sym)
|
||||
if efNoSemCheck notin flags:
|
||||
result = semAfterMacroCall(c, n, result, sym, flags)
|
||||
result = wrapInComesFrom(nOrig.info, sym, result)
|
||||
|
||||
@@ -605,12 +605,12 @@ proc evalAtCompileTime(c: PContext, n: PNode): PNode =
|
||||
call.add(a)
|
||||
#echo "NOW evaluating at compile time: ", call.renderTree
|
||||
if sfCompileTime in callee.flags:
|
||||
result = evalStaticExpr(c.module, c.cache, call, c.p.owner)
|
||||
result = evalStaticExpr(c.module, c.cache, c.graph.config, call, c.p.owner)
|
||||
if result.isNil:
|
||||
localError(n.info, errCannotInterpretNodeX, renderTree(call))
|
||||
else: result = fixupTypeAfterEval(c, result, n)
|
||||
else:
|
||||
result = evalConstExpr(c.module, c.cache, call)
|
||||
result = evalConstExpr(c.module, c.cache, c.graph.config, call)
|
||||
if result.isNil: result = n
|
||||
else: result = fixupTypeAfterEval(c, result, n)
|
||||
#if result != n:
|
||||
@@ -619,7 +619,7 @@ proc evalAtCompileTime(c: PContext, n: PNode): PNode =
|
||||
proc semStaticExpr(c: PContext, n: PNode): PNode =
|
||||
let a = semExpr(c, n.sons[0])
|
||||
if a.findUnresolvedStatic != nil: return a
|
||||
result = evalStaticExpr(c.module, c.cache, a, c.p.owner)
|
||||
result = evalStaticExpr(c.module, c.cache, c.graph.config, a, c.p.owner)
|
||||
if result.isNil:
|
||||
localError(n.info, errCannotInterpretNodeX, renderTree(n))
|
||||
result = emptyNode
|
||||
|
||||
@@ -545,7 +545,8 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
|
||||
b.sons[j] = newSymNode(v)
|
||||
checkNilable(v)
|
||||
if sfCompileTime in v.flags: hasCompileTime = true
|
||||
if hasCompileTime: vm.setupCompileTimeVar(c.module, c.cache, result)
|
||||
if hasCompileTime:
|
||||
vm.setupCompileTimeVar(c.module, c.cache, c.graph.config, result)
|
||||
|
||||
proc semConst(c: PContext, n: PNode): PNode =
|
||||
result = copyNode(n)
|
||||
@@ -1755,7 +1756,7 @@ proc semStaticStmt(c: PContext, n: PNode): PNode =
|
||||
#writeStackTrace()
|
||||
let a = semStmt(c, n.sons[0])
|
||||
n.sons[0] = a
|
||||
evalStaticStmt(c.module, c.cache, a, c.p.owner)
|
||||
evalStaticStmt(c.module, c.cache, c.graph.config, a, c.p.owner)
|
||||
result = newNodeI(nkDiscardStmt, n.info, 1)
|
||||
result.sons[0] = emptyNode
|
||||
|
||||
|
||||
@@ -11,17 +11,17 @@
|
||||
|
||||
import
|
||||
strutils, llstream, ast, astalgo, idents, lexer, options, msgs, parser,
|
||||
pbraces, filters, filter_tmpl, renderer
|
||||
filters, filter_tmpl, renderer
|
||||
|
||||
type
|
||||
TFilterKind* = enum
|
||||
filtNone, filtTemplate, filtReplace, filtStrip
|
||||
TParserKind* = enum
|
||||
skinStandard, skinStrongSpaces, skinBraces, skinEndX
|
||||
skinStandard, skinStrongSpaces, skinEndX
|
||||
|
||||
const
|
||||
parserNames*: array[TParserKind, string] = ["standard", "strongspaces",
|
||||
"braces", "endx"]
|
||||
"endx"]
|
||||
filterNames*: array[TFilterKind, string] = ["none", "stdtmpl", "replace",
|
||||
"strip"]
|
||||
|
||||
@@ -34,8 +34,6 @@ proc parseAll*(p: var TParsers): PNode =
|
||||
case p.skin
|
||||
of skinStandard, skinStrongSpaces:
|
||||
result = parser.parseAll(p.parser)
|
||||
of skinBraces:
|
||||
result = pbraces.parseAll(p.parser)
|
||||
of skinEndX:
|
||||
internalError("parser to implement")
|
||||
result = ast.emptyNode
|
||||
@@ -44,8 +42,6 @@ proc parseTopLevelStmt*(p: var TParsers): PNode =
|
||||
case p.skin
|
||||
of skinStandard, skinStrongSpaces:
|
||||
result = parser.parseTopLevelStmt(p.parser)
|
||||
of skinBraces:
|
||||
result = pbraces.parseTopLevelStmt(p.parser)
|
||||
of skinEndX:
|
||||
internalError("parser to implement")
|
||||
result = ast.emptyNode
|
||||
@@ -62,7 +58,8 @@ proc containsShebang(s: string, i: int): bool =
|
||||
while j < s.len and s[j] in Whitespace: inc(j)
|
||||
result = s[j] == '/'
|
||||
|
||||
proc parsePipe(filename: string, inputStream: PLLStream; cache: IdentCache): PNode =
|
||||
proc parsePipe(filename: string, inputStream: PLLStream; cache: IdentCache;
|
||||
config: ConfigRef): PNode =
|
||||
result = ast.emptyNode
|
||||
var s = llStreamOpen(filename, fmRead)
|
||||
if s != nil:
|
||||
@@ -78,7 +75,7 @@ proc parsePipe(filename: string, inputStream: PLLStream; cache: IdentCache): PNo
|
||||
inc(i, 2)
|
||||
while i < line.len and line[i] in Whitespace: inc(i)
|
||||
var q: TParser
|
||||
parser.openParser(q, filename, llStreamOpen(substr(line, i)), cache)
|
||||
parser.openParser(q, filename, llStreamOpen(substr(line, i)), cache, config)
|
||||
result = parser.parseAll(q)
|
||||
parser.closeParser(q)
|
||||
llStreamClose(s)
|
||||
@@ -139,23 +136,23 @@ proc evalPipe(p: var TParsers, n: PNode, filename: string,
|
||||
result = applyFilter(p, n, filename, result)
|
||||
|
||||
proc openParsers*(p: var TParsers, fileIdx: FileIndex, inputstream: PLLStream;
|
||||
cache: IdentCache) =
|
||||
cache: IdentCache; config: ConfigRef) =
|
||||
var s: PLLStream
|
||||
p.skin = skinStandard
|
||||
let filename = fileIdx.toFullPathConsiderDirty
|
||||
var pipe = parsePipe(filename, inputstream, cache)
|
||||
var pipe = parsePipe(filename, inputstream, cache, config)
|
||||
if pipe != nil: s = evalPipe(p, pipe, filename, inputstream)
|
||||
else: s = inputstream
|
||||
case p.skin
|
||||
of skinStandard, skinBraces, skinEndX:
|
||||
parser.openParser(p.parser, fileIdx, s, cache, false)
|
||||
of skinStandard, skinEndX:
|
||||
parser.openParser(p.parser, fileIdx, s, cache, config, false)
|
||||
of skinStrongSpaces:
|
||||
parser.openParser(p.parser, fileIdx, s, cache, true)
|
||||
parser.openParser(p.parser, fileIdx, s, cache, config, true)
|
||||
|
||||
proc closeParsers*(p: var TParsers) =
|
||||
parser.closeParser(p.parser)
|
||||
|
||||
proc parseFile*(fileIdx: FileIndex; cache: IdentCache): PNode {.procvar.} =
|
||||
proc parseFile*(fileIdx: FileIndex; cache: IdentCache; config: ConfigRef): PNode {.procvar.} =
|
||||
var
|
||||
p: TParsers
|
||||
f: File
|
||||
@@ -163,6 +160,6 @@ proc parseFile*(fileIdx: FileIndex; cache: IdentCache): PNode {.procvar.} =
|
||||
if not open(f, filename):
|
||||
rawMessage(errCannotOpenFile, filename)
|
||||
return
|
||||
openParsers(p, fileIdx, llStreamOpen(f), cache)
|
||||
openParsers(p, fileIdx, llStreamOpen(f), cache, config)
|
||||
result = parseAll(p)
|
||||
closeParsers(p)
|
||||
|
||||
@@ -1341,8 +1341,8 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||
decodeB(rkNode)
|
||||
# c.debug[pc].line.int - countLines(regs[rb].strVal) ?
|
||||
var error: string
|
||||
let ast = parseString(regs[rb].node.strVal, c.cache, c.debug[pc].toFullPath,
|
||||
c.debug[pc].line.int,
|
||||
let ast = parseString(regs[rb].node.strVal, c.cache, c.config,
|
||||
c.debug[pc].toFullPath, c.debug[pc].line.int,
|
||||
proc (info: TLineInfo; msg: TMsgKind; arg: string) =
|
||||
if error.isNil and msg <= msgs.errMax:
|
||||
error = formatMsg(info, msg, arg))
|
||||
@@ -1355,8 +1355,8 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||
of opcParseStmtToAst:
|
||||
decodeB(rkNode)
|
||||
var error: string
|
||||
let ast = parseString(regs[rb].node.strVal, c.cache, c.debug[pc].toFullPath,
|
||||
c.debug[pc].line.int,
|
||||
let ast = parseString(regs[rb].node.strVal, c.cache, c.config,
|
||||
c.debug[pc].toFullPath, c.debug[pc].line.int,
|
||||
proc (info: TLineInfo; msg: TMsgKind; arg: string) =
|
||||
if error.isNil and msg <= msgs.errMax:
|
||||
error = formatMsg(info, msg, arg))
|
||||
@@ -1643,9 +1643,9 @@ include vmops
|
||||
var
|
||||
globalCtx*: PCtx
|
||||
|
||||
proc setupGlobalCtx(module: PSym; cache: IdentCache) =
|
||||
proc setupGlobalCtx(module: PSym; cache: IdentCache; config: ConfigRef) =
|
||||
if globalCtx.isNil:
|
||||
globalCtx = newCtx(module, cache)
|
||||
globalCtx = newCtx(module, cache, config)
|
||||
registerAdditionalOps(globalCtx)
|
||||
else:
|
||||
refresh(globalCtx, module)
|
||||
@@ -1656,7 +1656,7 @@ proc myOpen(graph: ModuleGraph; module: PSym; cache: IdentCache): PPassContext =
|
||||
#pushStackFrame(c, newStackFrame())
|
||||
|
||||
# XXX produce a new 'globals' environment here:
|
||||
setupGlobalCtx(module, cache)
|
||||
setupGlobalCtx(module, cache, graph.config)
|
||||
result = globalCtx
|
||||
when hasFFI:
|
||||
globalCtx.features = {allowFFI, allowCast}
|
||||
@@ -1677,10 +1677,11 @@ proc myClose(graph: ModuleGraph; c: PPassContext, n: PNode): PNode =
|
||||
|
||||
const evalPass* = makePass(myOpen, nil, myProcess, myClose)
|
||||
|
||||
proc evalConstExprAux(module: PSym; cache: IdentCache; prc: PSym, n: PNode,
|
||||
proc evalConstExprAux(module: PSym; cache: IdentCache;
|
||||
config: ConfigRef; prc: PSym, n: PNode,
|
||||
mode: TEvalMode): PNode =
|
||||
let n = transformExpr(module, n)
|
||||
setupGlobalCtx(module, cache)
|
||||
setupGlobalCtx(module, cache, config)
|
||||
var c = globalCtx
|
||||
let oldMode = c.mode
|
||||
defer: c.mode = oldMode
|
||||
@@ -1695,17 +1696,17 @@ proc evalConstExprAux(module: PSym; cache: IdentCache; prc: PSym, n: PNode,
|
||||
result = rawExecute(c, start, tos).regToNode
|
||||
if result.info.col < 0: result.info = n.info
|
||||
|
||||
proc evalConstExpr*(module: PSym; cache: IdentCache, e: PNode): PNode =
|
||||
result = evalConstExprAux(module, cache, nil, e, emConst)
|
||||
proc evalConstExpr*(module: PSym; cache: IdentCache, config: ConfigRef; e: PNode): PNode =
|
||||
result = evalConstExprAux(module, cache, config, nil, e, emConst)
|
||||
|
||||
proc evalStaticExpr*(module: PSym; cache: IdentCache, e: PNode, prc: PSym): PNode =
|
||||
result = evalConstExprAux(module, cache, prc, e, emStaticExpr)
|
||||
proc evalStaticExpr*(module: PSym; cache: IdentCache, config: ConfigRef; e: PNode, prc: PSym): PNode =
|
||||
result = evalConstExprAux(module, cache, config, prc, e, emStaticExpr)
|
||||
|
||||
proc evalStaticStmt*(module: PSym; cache: IdentCache, e: PNode, prc: PSym) =
|
||||
discard evalConstExprAux(module, cache, prc, e, emStaticStmt)
|
||||
proc evalStaticStmt*(module: PSym; cache: IdentCache, config: ConfigRef; e: PNode, prc: PSym) =
|
||||
discard evalConstExprAux(module, cache, config, prc, e, emStaticStmt)
|
||||
|
||||
proc setupCompileTimeVar*(module: PSym; cache: IdentCache, n: PNode) =
|
||||
discard evalConstExprAux(module, cache, nil, n, emStaticStmt)
|
||||
proc setupCompileTimeVar*(module: PSym; cache: IdentCache, config: ConfigRef; n: PNode) =
|
||||
discard evalConstExprAux(module, cache, config, nil, n, emStaticStmt)
|
||||
|
||||
proc setupMacroParam(x: PNode, typ: PType): TFullReg =
|
||||
case typ.kind
|
||||
@@ -1733,8 +1734,8 @@ iterator genericParamsInMacroCall*(macroSym: PSym, call: PNode): (PSym, PNode) =
|
||||
const evalMacroLimit = 1000
|
||||
var evalMacroCounter: int
|
||||
|
||||
proc evalMacroCall*(module: PSym; cache: IdentCache, n, nOrig: PNode,
|
||||
sym: PSym): PNode =
|
||||
proc evalMacroCall*(module: PSym; cache: IdentCache; config: ConfigRef;
|
||||
n, nOrig: PNode, sym: PSym): PNode =
|
||||
# XXX globalError() is ugly here, but I don't know a better solution for now
|
||||
inc(evalMacroCounter)
|
||||
if evalMacroCounter > evalMacroLimit:
|
||||
@@ -1746,7 +1747,7 @@ proc evalMacroCall*(module: PSym; cache: IdentCache, n, nOrig: PNode,
|
||||
globalError(n.info, "in call '$#' got $#, but expected $# argument(s)" % [
|
||||
n.renderTree, $(n.safeLen-1), $(sym.typ.len-1)])
|
||||
|
||||
setupGlobalCtx(module, cache)
|
||||
setupGlobalCtx(module, cache, config)
|
||||
var c = globalCtx
|
||||
c.comesFromHeuristic.line = 0'u16
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
## This module contains the type definitions for the new evaluation engine.
|
||||
## An instruction is 1-3 int32s in memory, it is a register based VM.
|
||||
|
||||
import ast, passes, msgs, idents, intsets
|
||||
import ast, passes, msgs, idents, intsets, options
|
||||
|
||||
const
|
||||
byteExcess* = 128 # we use excess-K for immediates
|
||||
@@ -206,17 +206,19 @@ type
|
||||
callbacks*: seq[tuple[key: string, value: VmCallback]]
|
||||
errorFlag*: string
|
||||
cache*: IdentCache
|
||||
config*: ConfigRef
|
||||
|
||||
TPosition* = distinct int
|
||||
|
||||
PEvalContext* = PCtx
|
||||
|
||||
proc newCtx*(module: PSym; cache: IdentCache): PCtx =
|
||||
proc newCtx*(module: PSym; cache: IdentCache; config: ConfigRef = nil): PCtx =
|
||||
let conf = if config != nil: config else: newConfigRef()
|
||||
PCtx(code: @[], debug: @[],
|
||||
globals: newNode(nkStmtListExpr), constants: newNode(nkStmtList), types: @[],
|
||||
prc: PProc(blocks: @[]), module: module, loopIterations: MaxLoopIterations,
|
||||
comesFromHeuristic: unknownLineInfo(), callbacks: @[], errorFlag: "",
|
||||
cache: cache)
|
||||
cache: cache, config: conf)
|
||||
|
||||
proc refresh*(c: PCtx, module: PSym) =
|
||||
c.module = module
|
||||
|
||||
Reference in New Issue
Block a user