-
-
Save zacharycarter/2b4a6fc3740f33a8be18ea24d8c03d7b to your computer and use it in GitHub Desktop.
macro for vm hooks
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# from https://github.com/Serenitor/embeddedNimScript/blob/master/scripts/api.nim | |
template builtin = discard | |
proc add (a, b: int): int = builtin | |
proc modifyState (str: string) = builtin | |
proc fooBar (foo: var Foo) = builtin |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# from https://github.com/Serenitor/embeddedNimScript/blob/master/embeddedNims/apiImpl.nim | |
from compiler/idents import IdentCache | |
from compiler/vmdef import registerCallback, VmArgs, PCtx | |
from compiler/modulegraphs import ModuleGraph | |
from compiler/vm import | |
# Getting values from VmArgs | |
getInt, getFloat, getString, getBool, getNode, | |
# Setting result (return value) | |
setResult | |
from compiler/ast import | |
# Types | |
PSym, PNode, TNodeKind, | |
# Getting values from PNodes | |
getInt, getFloat, | |
# Creating new PNodes | |
newNode, newFloatNode, addSon, newTree | |
from os import splitFile | |
from threadpool import FlowVar | |
# Assume location of shared state type in ../state | |
import ../state | |
type | |
Script* = ref object | |
filename*: string | |
moduleName*: string | |
mainModule*: PSym | |
graph*: ModuleGraph | |
context*: PCtx | |
watcher*: FlowVar[int] | |
Foo = object | |
bar: string | |
proc exposeScriptApi* (script: Script) = | |
bindObject(Foo) # here we invoke our theoretical macro | |
template expose (procName, procBody: untyped) {.dirty.} = | |
script.context.registerCallback script.moduleName & "." & astToStr(procName), | |
proc (a: VmArgs) = | |
procBody | |
expose add: | |
# We need to use procs like getInt to retrieve the argument values from VmArgs | |
# Instead of using the return statement we need to use setResult | |
setResult(a, | |
getInt(a, 0) + | |
getInt(a, 1)) | |
expose modifyState: | |
modifyMe = getString(a, 0) | |
echo "`", script.moduleName, "` has changed state.modifyMe to `", modifyMe, "`" | |
expose fooBar: # here we are adding a new callback to the VM hooks | |
foo = getFoo(a, 0) # here we call the getFoo proc that our macro generates - a: VmArgs, 0: index into register | |
echo foo.bar # this should print "intial value" | |
foo.bar = "modified value" | |
setFoo(foo) # here we call the setFoo proc that our macro generates which will in turn create a PNode and call setResult |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var foo = Foo(bar: "initial value") | |
fooBar(foo) | |
echo foo.bar # should print "modified value" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment