nimeval errorHook support (#15255)

This commit is contained in:
Scott Wadden 2020-09-07 15:05:07 -03:00 • committed by GitHub
commit 098a8a7c52
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 37 additions and 16 deletions

View file

@ -10,9 +10,9 @@
## exposes the Nim VM to clients. ## exposes the Nim VM to clients.
import import
ast, astalgo, modules, passes, condsyms, ast, astalgo, modules, passes, condsyms,
options, sem, semdata, llstream, vm, vmdef, options, sem, semdata, llstream, lineinfos, vm,
modulegraphs, idents, os, pathutils, passaux, vmdef, modulegraphs, idents, os, pathutils,
scriptconfig passaux, scriptconfig
type type
Interpreter* = ref object ## Use Nim as an interpreter with this object Interpreter* = ref object ## Use Nim as an interpreter with this object
@ -134,6 +134,11 @@ proc destroyInterpreter*(i: Interpreter) =
## destructor. ## destructor.
discard "currently nothing to do." discard "currently nothing to do."
proc registerErrorHook*(i: Interpreter, hook:
proc (config: ConfigRef; info: TLineInfo; msg: string;
severity: Severity) {.gcsafe.}) =
i.graph.config.structuredErrorHook = hook
proc runRepl*(r: TLLRepl; proc runRepl*(r: TLLRepl;
searchPaths: openArray[string]; searchPaths: openArray[string];
supportNimscript: bool) = supportNimscript: bool) =

View file

@ -0,0 +1 @@
noSuchProc()

View file

@ -5,6 +5,7 @@ discard """
my secret my secret
11 11
12 12
raising VMQuit
''' '''
joinable: "false" joinable: "false"
""" """
@ -12,34 +13,35 @@ my secret
## Example program that demonstrates how to use the ## Example program that demonstrates how to use the
## compiler as an API to embed into your own projects. ## compiler as an API to embed into your own projects.
import "../../compiler" / [ast, vmdef, vm, nimeval, llstream] import "../../compiler" / [ast, vmdef, vm, nimeval, llstream, lineinfos, options]
import std / [os] import std / [os]
proc main() = proc initInterpreter(script: string): Interpreter =
let std = findNimStdLibCompileTime() let std = findNimStdLibCompileTime()
var intr = createInterpreter("myscript.nim", [std, parentDir(currentSourcePath), result = createInterpreter(script , [std, parentDir(currentSourcePath),
std / "pure", std / "core"]) std / "pure", std / "core"])
intr.implementRoutine("*", "exposed", "addFloats", proc (a: VmArgs) =
proc main() =
let i = initInterpreter("myscript.nim")
i.implementRoutine("*", "exposed", "addFloats", proc (a: VmArgs) =
setResult(a, getFloat(a, 0) + getFloat(a, 1) + getFloat(a, 2)) setResult(a, getFloat(a, 0) + getFloat(a, 1) + getFloat(a, 2))
) )
i.evalScript()
intr.evalScript() let foreignProc = i.selectRoutine("hostProgramRunsThis")
let foreignProc = selectRoutine(intr, "hostProgramRunsThis")
if foreignProc == nil: if foreignProc == nil:
quit "script does not export a proc of the name: 'hostProgramRunsThis'" quit "script does not export a proc of the name: 'hostProgramRunsThis'"
let res = intr.callRoutine(foreignProc, [newFloatNode(nkFloatLit, 0.9), let res = i.callRoutine(foreignProc, [newFloatNode(nkFloatLit, 0.9),
newFloatNode(nkFloatLit, 0.1)]) newFloatNode(nkFloatLit, 0.1)])
doAssert res.kind == nkFloatLit doAssert res.kind == nkFloatLit
echo res.floatVal echo res.floatVal
let foreignValue = selectUniqueSymbol(intr, "hostProgramWantsThis") let foreignValue = i.selectUniqueSymbol("hostProgramWantsThis")
if foreignValue == nil: if foreignValue == nil:
quit "script does not export a global of the name: hostProgramWantsThis" quit "script does not export a global of the name: hostProgramWantsThis"
let val = intr.getGlobalValue(foreignValue) let val = i.getGlobalValue(foreignValue)
doAssert val.kind in {nkStrLit..nkTripleStrLit} doAssert val.kind in {nkStrLit..nkTripleStrLit}
echo val.strVal echo val.strVal
destroyInterpreter(intr) i.destroyInterpreter()
main() main()
@ -54,3 +56,16 @@ block issue9180:
evalString("echo 10+1") evalString("echo 10+1")
evalString("echo 10+2") evalString("echo 10+2")
block error_hook:
type VMQuit = object of CatchableError
let i = initInterpreter("invalid.nim")
i.registerErrorHook proc(config: ConfigRef; info: TLineInfo; msg: string;
severity: Severity) {.gcsafe.} =
if severity == Error and config.errorCounter >= config.errorMax:
echo "raising VMQuit"
raise newException(VMQuit, "Script error")
doAssertRaises(VMQuit):
i.evalScript()