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