nimeval errorHook support (#15255)
This commit is contained in:
parent
0b74d26d0c
commit
098a8a7c52
3 changed files with 37 additions and 16 deletions
|
|
@ -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) =
|
||||||
|
|
|
||||||
1
tests/compilerapi/invalid.nim
Normal file
1
tests/compilerapi/invalid.nim
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
noSuchProc()
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue