• Stars
    star
    142
  • Rank 251,051 (Top 6 %)
  • Language
    Nim
  • License
    MIT License
  • Created over 3 years ago
  • Updated 3 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Quick and easy Nim <-> Nimscript interop

Nimscripter

Nimscripter is enables easy interop between Nim and Nimscript for realtime scriptable applications.

How to use

Install Nimscripter(nimble install nimscripter) with Nimble then create a .nim file with the following.

import nimscripter
proc doThing(): int = 42
exportTo(myImpl, doThing) # The name of our "nimscript module" is `myImpl`
const 
  scriptProcs = implNimScriptModule(myImpl) # This emits our exported code
  ourScript = NimScriptFile("assert doThing() == 42") # Convert to `NimScriptFile` for loading from strings
let intr = loadScript(ourScript, scriptProcs) # Load our script with our code and using our system `stdlib`(not portable)

Note that exportTo can take in multiple procedures, types, or global variables at once.

proc doThing(): int = 42
var myGlobal = 30
type MyType = enum
  a, b, c
exportTo(myImpl,
  doThing
  myGlobal,
  myType)

Calling code from Nim

Any exported non overloaded and non generic procedures can be called from Nim

const script = NimScriptFile"proc fancyStuff*(a: int) = assert a in [10, 300]" # Notice `fancyStuff` is exported
let intr = loadScript(script) # We are not exposing any procedures hence single parameter
intr.invoke(fancyStuff, 10) # Calls `fancyStuff(10)` in vm
intr.invoke(fancyStuff, 300) # Calls `fancyStuff(300)` in vm

The above works but does not impose any safety on the VM code, to do that the following can be done

addCallable(test3):
  proc fancyStuff(a: int) # Has checks for the nimscript to ensure it's definition doesnt change to something unexpected.
const
  addins = implNimscriptModule(test3)
  script = NimScriptFile"proc fancyStuff*(a: int) = assert a in [10, 300]" # Notice `fancyStuff` is exported
let intr = loadScript(script, addins) # This adds in out checks for the proc
intr.invoke(fancyStuff, 10) # Calls `fancyStuff(10)` in vm
intr.invoke(fancyStuff, 300) # Calls `fancyStuff(300)` in vm

Getting global variables from nimscript

One may extract global variables from a nimscript file using a convenience macro.

import nimscripter, nimscripter/variables

let script = NimScriptFile"""
let required* = "main"
let defaultValueExists* = "foo"
"""
let intr = loadScript script

getGlobalNimsVars intr:
  required: string # required variable
  optional: Option[string] # optional variable
  defaultValue: int = 1 # optional variable with default value
  defaultValueExists = "bar" # You may omit the type if there is a default value

check required == "main"
check optional.isNone
check defaultValue == 1
check defaultValueExists == "foo"

Basic types are supported, such as string, int, bool, etc..

Exporting code verbatim

nimscriptr/expose has exportCode and exportCodeAndKeep they both work the same, except the latter keeps the code so it can be used inside Nim.

exportCode(nimScripter):
 proc doThing(a, b: int) = echo a, " ", b # This runs on nimscript if called there

Keeping state inbetween loads

loadScriptWithState will load a script, if it loads a valid script it will reset any global exported variables in the script with their preload values.

safeloadScriptWithState will attempt to load a script keeping global state, if it fails it does not change the interpeter, else it'll load the script and set it's state to the interpreters.

saveState/loadState can be used to manually manage the state inbetween loaded scripts.

VmOps

A subset of the nimscript interopped procedures are available inside nimscripter/vmops. If you feel a new op should be added feel free to PR it.

import nimscripter
import nimscripter/vmops

const script = """
proc build*(): bool =
  echo "building nim... "
  echo getCurrentDir()
  echo "done"
  true

when isMainModule:
  discard build()
"""
addVmops(buildpackModule)
addCallable(buildpackModule):
  proc build(): bool
const addins = implNimscriptModule(buildpackModule)
discard loadScript(NimScriptFile(script), addins)

Using a custom/shipped stdlib

Make a folder entitled stdlib and copy all Nim files you wish to ship as a stdlib from Nim's stdlib and any of your own files. system.nim and the system folder are required. You can copy any other pure libraries and ship them, though they're only usable if they support Nimscript. If you use choosenim you can find the the Nim stdlib to copy from inside ~/.choosenim/toolchains/nim-version/lib. When using a custom search paths add the root file only, if you provide more than that it will break modules.

Overriding the error hook

The error hook can be overridden for more behaviour like showing the error in the program, the builtin error hook is as follows:

proc errorHook(config: ConfigRef; info: TLineInfo; msg: string; severity: Severity) {.gcsafe.} =
  if severity == Error and config.error_counter >= config.error_max:
    var fileName: string
    for k, v in config.m.filenameToIndexTbl.pairs:
      if v == info.fileIndex:
        fileName = k
    echo "Script Error: $1:$2:$3 $4." % [fileName, $info.line, $(info.col + 1), msg]
    raise (ref VMQuit)(info: info, msg: msg)

More Repositories

1

fungus

Object variants done like other langugaes
Nim
68
star
2

constructor

Nim macros to aid in object construction including event programming, and constructors.
Nim
52
star
3

slicerator

A simple iterator library to enable more efficient iterators
Nim
48
star
4

kashae

A Calculation caching Nim library
Nim
37
star
5

micros

typesafe-ish macro library
Nim
29
star
6

traitor

Trait/interface system for Nim, allowing semi-checked generics or dynamic dispatch on signatures.
Nim
26
star
7

wasm3

Yet another wasm runtime to toy with
Nim
21
star
8

picotemplate

A Nim raspberry pi pico project template
CMake
20
star
9

Unity-Controller-Manager

Unity Controller Manager - Allows easy quick controller setups
C#
19
star
10

nimtrest

A collection of simple things I make on a whim with nowhere else to go
JavaScript
15
star
11

sumtypes

Easy to use Nim sum type library
Nim
14
star
12

gooey

It's ooey and gooey. No clue what this really is aside from a GUI framework basis?
Nim
14
star
13

graffiti

A Nimble git tagger, it creates tags for your nimble versions so you do not need to
Nim
12
star
14

truss3d

Small implementation using opengl
Nim
10
star
15

pointRenderer

Point cloud like 3D scene renderer for unity.
ShaderLab
9
star
16

nettyrpc

Implements an RPC like system using netty.
Nim
9
star
17

nicoscript

An example nico program that shows how to use nimscripter's dll API for a resuable compilable environment
Nim
9
star
18

unity-auto-builder

A Unity build tool that automate building multiple desktop builds.
Nim
7
star
19

PyrotonWineManager

Proton Wine Manager for managing proton wine prefixes, now with 100% more snakes!
Python
7
star
20

seeya

Quickly generate Nim headers from exported Nim code
Nim
7
star
21

aiarena

Place to play around with wasm in a scripted AI arena
Nim
7
star
22

quicktimer

Simple and easy to use unity timer.
C#
6
star
23

nvg

Nico Vector Graphics Editor
Nim
5
star
24

stringlights

Simple string light generator and shader for Unity.
C#
5
star
25

wasmedge_playground

Nim
4
star
26

mindthegap3D

Nim
4
star
27

oopsie

Nim oop helper module
Nim
4
star
28

miniaudio

Wrapping of miniaudio for truss3D
C
4
star
29

ProtonWineManager

A Dotnetcore CLI for easy management of Steam Proton Prefixes
C#
3
star
30

goodwm

Nim
3
star
31

dusty

Toy multithreaded sand "game"
Nim
3
star
32

libnimib

This builds ontop of nimib allowing any language to use it.
Nim
3
star
33

unityflub

Unity hub front end for installing versions on linux, working around xdg-open issues.
Nim
2
star
34

dodger

A matrix api wrapper
Nim
2
star
35

unitydrawing

Unity drawing toy to explain how blitting is done.
C#
2
star
36

ingest

A basic tracking program for any variety of incremental tracking of values.
Nim
2
star
37

reflector

A simple inotify daemon that's non destructive.
Nim
2
star
38

aoc2021

Nim
1
star
39

nico-helper

Nim
1
star
40

rdldd

A really dumb ldd written just to play with injecting code
Nim
1
star
41

tinynimwl

Reimplementation of tinywl in Nim to test the wayland bindings
Nim
1
star
42

strviewutils

Experimental testing with views to reduce multiple allocations
Nim
1
star
43

photonstomp

As the name implies, some silly raymarch toy.
Nim
1
star
44

GlobalShaderVarEditor

A global shader variable editor for unity.
C#
1
star