diff options
author | Scott Wadden <scott.wadden@emc.com> | 2020-09-07 15:05:07 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-09-07 20:05:07 +0200 |
commit | 098a8a7c522986ce250d4e52dc42182e5d9d7352 (patch) | |
tree | 44f27a292a845e968d781ebe140ff5e75d30cfd6 | |
parent | 0b74d26d0c45e0fe16126bd264072783afacd12a (diff) | |
download | Nim-098a8a7c522986ce250d4e52dc42182e5d9d7352.tar.gz |
nimeval errorHook support (#15255)
-rw-r--r-- | compiler/nimeval.nim | 11 | ||||
-rw-r--r-- | tests/compilerapi/invalid.nim | 1 | ||||
-rw-r--r-- | tests/compilerapi/tcompilerapi.nim | 41 |
3 files changed, 37 insertions, 16 deletions
diff --git a/compiler/nimeval.nim b/compiler/nimeval.nim index df3cb2079..5d4fea9f3 100644 --- a/compiler/nimeval.nim +++ b/compiler/nimeval.nim @@ -10,9 +10,9 @@ ## exposes the Nim VM to clients. import ast, astalgo, modules, passes, condsyms, - options, sem, semdata, llstream, vm, vmdef, - modulegraphs, idents, os, pathutils, passaux, - scriptconfig + options, sem, semdata, llstream, lineinfos, vm, + vmdef, modulegraphs, idents, os, pathutils, + passaux, scriptconfig type Interpreter* = ref object ## Use Nim as an interpreter with this object @@ -134,6 +134,11 @@ proc destroyInterpreter*(i: Interpreter) = ## destructor. 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; searchPaths: openArray[string]; supportNimscript: bool) = diff --git a/tests/compilerapi/invalid.nim b/tests/compilerapi/invalid.nim new file mode 100644 index 000000000..3c9364402 --- /dev/null +++ b/tests/compilerapi/invalid.nim @@ -0,0 +1 @@ +noSuchProc() diff --git a/tests/compilerapi/tcompilerapi.nim b/tests/compilerapi/tcompilerapi.nim index 9d5e0e3f2..d8489c763 100644 --- a/tests/compilerapi/tcompilerapi.nim +++ b/tests/compilerapi/tcompilerapi.nim @@ -5,6 +5,7 @@ discard """ my secret 11 12 +raising VMQuit ''' joinable: "false" """ @@ -12,34 +13,35 @@ my secret ## Example program that demonstrates how to use the ## 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] -proc main() = +proc initInterpreter(script: string): Interpreter = let std = findNimStdLibCompileTime() - var intr = createInterpreter("myscript.nim", [std, parentDir(currentSourcePath), + result = createInterpreter(script , [std, parentDir(currentSourcePath), 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)) ) - - intr.evalScript() - - let foreignProc = selectRoutine(intr, "hostProgramRunsThis") + i.evalScript() + let foreignProc = i.selectRoutine("hostProgramRunsThis") if foreignProc == nil: quit "script does not export a proc of the name: 'hostProgramRunsThis'" - let res = intr.callRoutine(foreignProc, [newFloatNode(nkFloatLit, 0.9), - newFloatNode(nkFloatLit, 0.1)]) + let res = i.callRoutine(foreignProc, [newFloatNode(nkFloatLit, 0.9), + newFloatNode(nkFloatLit, 0.1)]) doAssert res.kind == nkFloatLit echo res.floatVal - let foreignValue = selectUniqueSymbol(intr, "hostProgramWantsThis") + let foreignValue = i.selectUniqueSymbol("hostProgramWantsThis") if foreignValue == nil: 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} echo val.strVal - destroyInterpreter(intr) + i.destroyInterpreter() main() @@ -54,3 +56,16 @@ block issue9180: evalString("echo 10+1") 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() |