summary refs log tree commit diff stats
path: root/tests/compilerapi/tcompilerapi.nim
diff options
context:
space:
mode:
Diffstat (limited to 'tests/compilerapi/tcompilerapi.nim')
-rw-r--r--tests/compilerapi/tcompilerapi.nim103
1 files changed, 77 insertions, 26 deletions
diff --git a/tests/compilerapi/tcompilerapi.nim b/tests/compilerapi/tcompilerapi.nim
index 90d343264..2d6cfa0ca 100644
--- a/tests/compilerapi/tcompilerapi.nim
+++ b/tests/compilerapi/tcompilerapi.nim
@@ -1,47 +1,98 @@
 discard """
   output: '''top level statements are executed!
+(ival: 10, fval: 2.0)
 2.0
 my secret
+11
+12
+raising VMQuit
 '''
+  joinable: "false"
 """
 
 ## Example program that demonstrates how to use the
 ## compiler as an API to embed into your own projects.
 
-import "../../compiler" / [ast, vmdef, vm, nimeval]
+import "../../compiler" / [ast, vmdef, vm, nimeval, llstream, lineinfos, options]
 import std / [os]
 
-proc main() =
-  let std = findNimStdLib()
-  if std.len == 0:
-    quit "cannot find Nim's standard library"
+proc initInterpreter(script: string): Interpreter =
+  let std = findNimStdLibCompileTime()
+  result = createInterpreter(script, [std, parentDir(currentSourcePath),
+    std / "pure", std / "core"])
 
-  var intr = createInterpreter("myscript.nim", [std, getAppDir()])
-  intr.implementRoutine("*", "exposed", "addFloats", proc (a: VmArgs) =
+proc main() =
+  let i = initInterpreter("myscript.nim")
+  i.implementRoutine("nim", "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)])
-  if res.kind == nkFloatLit:
-    echo res.floatVal
-  else:
-    echo "bug!"
-
-  let foreignValue = selectUniqueSymbol(intr, "hostProgramWantsThis")
+  let res = i.callRoutine(foreignProc, [newFloatNode(nkFloatLit, 0.9),
+                                        newFloatNode(nkFloatLit, 0.1)])
+  doAssert res.kind == nkFloatLit
+  echo res.floatVal
+
+  let foreignValue = i.selectUniqueSymbol("hostProgramWantsThis")
   if foreignValue == nil:
     quit "script does not export a global of the name: hostProgramWantsThis"
-  let val = intr.getGlobalValue(foreignValue)
-  if val.kind in {nkStrLit..nkTripleStrLit}:
-    echo val.strVal
-  else:
-    echo "bug!"
+  let val = i.getGlobalValue(foreignValue)
+  doAssert val.kind in {nkStrLit..nkTripleStrLit}
+  echo val.strVal
+  i.destroyInterpreter()
+
+main()
+
+block issue9180:
+  proc evalString(code: string, moduleName = "script.nim") =
+    let stream = llStreamOpen(code)
+    let std = findNimStdLibCompileTime()
+    var intr = createInterpreter(moduleName, [std, std / "pure", std / "core"])
+    intr.evalScript(stream)
+    destroyInterpreter(intr)
+    llStreamClose(stream)
 
-  destroyInterpreter(intr)
+  evalString("echo 10+1")
+  evalString("echo 10+2")
 
-main()
\ No newline at end of file
+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()
+
+block resetmacrocache:
+  let std = findNimStdLibCompileTime()
+  let intr = createInterpreter("script.nim", [std, std / "pure", std / "core"])
+  proc evalString(intr: Interpreter; code: string) =
+    let stream = llStreamOpen(code)
+    intr.evalScript(stream)
+    llStreamClose(stream)
+  let code = """
+import std/[macrocache, macros]
+static:
+  let counter = CacheCounter"valTest"
+  inc counter
+  assert counter.value == 1
+
+  const mySeq = CacheSeq"addTest"
+  mySeq.add(newLit(5))
+  mySeq.add(newLit("hello ic"))
+  assert mySeq.len == 2
+
+  const mcTable = CacheTable"subTest"
+  mcTable["toAdd"] = newStmtList() #would crash if not empty
+  assert mcTable.len == 1
+"""
+  intr.evalString(code)
+  intr.evalString(code)
+  destroyInterpreter(intr)
\ No newline at end of file