navm 0.1.4
A simple VM intended to be used in scripting languages
To use this package, run the following command in your project's root directory:
Manual usage
Put the following dependency into your project's dependences section:
NaVM
A VM designed to be fast, intended for use in scripting languages.
It's sometimes written navm instead of NaVM, both are the same
Getting Started
These instructions will get you a copy of NaVM with its very basic instuctions, which will serve as a demo.
Remember, NaVM is not built to be a standalone application, it's meant to be used as a library (originally built
for QScript, but everyone's free to use it).
See source/app.d
to see how to add external functions, and use it in your program.
Prerequisites
You need to have these present on your machine:
- dub
- dlang compiler (only dmd is tested)
- Internet connection (for dub to fetch NaVM and its dependencies)
Building
Run:
dub fetch navm
to download this package, and then run:
dub build navm -b=release -c=demo
to fetch dependencies and build NaVM.
Following this, you will have the NaVM binary (named demo
) with very basic functionality.
You can now run NaVM bytecode using:
~/.dub/packages/navm-*/navm/demo path/to/bytecodefile
This binary also has 5 external functions:
- ID: 0, call using `ExecuteFunctionExternal 0 n` where n is number of integers to pop from stack and writeln(int) to terminal
- ID: 1, call using `ExecuteFunctionExternal 1 n` where n is number of doubles (floats) to pop from stack and writeln(double) to terminal
- ID: 2, call using `ExecuteFunctionExternal 2 n` where n is number of strings to pop from stack and write to terminal
- ID: 3, call using `ExecuteFunctionExternal 3 n` writes n number of newline characters to terminal
- ID: 4, call using `ExecuteFunctionExternal 4 0` reads a line from stdin, pushes it to stack
Syntax
Although you do not need to actually write following this if you are using NaVM in a library, you can programmatically add instructions to functions, this still exists.(See source/bytecodedefs.d : NaFunction
)
The syntax is as follows:
def 20 # this defines function with function id = 0, which has space for 20 elements on stack
FirstInstruction [InstructionArgument0] [Argument1]
SecondInstruction # comment
ThirdInstruction
# comment
FourthInstruction
def 15 # another function begins from here (id = 1), which has space for 15 elements on stack
FirstInstruction # Indentation is not necesarry, go crazy (i don't recommend it tho)
SecondInstructions
...
The bytecode is divided into functions.
Each function definition begins with the keyword def
, followed by the required stack length (separate using whitespace).
Function ID is automatically assigned, starting with 0. This is to avoid using assoc_arrays, to improve performace.
After that, each line is an instruction or a comment, or whitespace, until the next function definition is found.
Instructions are written in either of these ways:
Tab %instruction% %arguments%
or:
%instruction% %arguments%
Tabs or spaces can be used to indent, but indentation is not necesary, and you can use more than 1 tab/space to indent.
Instructions are not case sensitive, ExecuteFunction
is the same as eXeCuTeFuNcTiOn
.
License
NaVM is licensed under the MIT License - see LICENSE for details
Instructions
Here's a list of instructions that NaVM has out of the box. You can easily add more (Add name, argument count, and other info to source/navm/bytecodedefs.d
and implement those instructions in source/navm/navm.d
Calling functions:
- `ExecuteFunction [function id - integer>=0] [n - integer>=0]` pops `n` number of elements from stack. Calls a function defined in bytecode, pushes the elements in that function's stack in the same order they were. Pushes the return value from that function to stack.
- `ExecuteFunctionExternal [function id - integer>=0] [n - integer>=0]` pops `n` number of elements from stack. Calls an external function with the elements popped as arguments. Pushes the return value from that function to stack.
Keep in mind that these functions push `NaData()` to stack if function did not return any meaningful data, so if you don't need to use the return value, or the function doesn't return meaningful data, follow these instructions with a `Pop` instruction.
Arithmetic operators
For integers
- `MathAddInt`
Pops
A (integer)
, thenB (integer)
. PushesA + B (integer)
to stack. - `MathSubtractInt`
Pops
A (integer)
, thenB (integer)
. PushesA - B (integer)
to stack. - `MathMultiplyInt`
Pops
A (integer)
, thenB (integer)
. PushesA * B (integer)
to stack. - `MathDivideInt`
Pops
A (integer)
, thenB (integer)
. PushesA / B (integer)
to stack. - `MathModInt`
Pops
A (integer)
, thenB (integer)
. PushesA % B (integer)
to stack.
For floating point (double)
- `MathAddDouble`
Pops
A (double)
, thenB (double)
. PushesA + B (double)
to stack. - `MathSubtractDouble`
Pops
A (double)
, thenB (double)
. PushesA - B (double)
to stack. - `MathMultiplyDouble`
Pops
A (double)
, thenB (double)
. PushesA * B (double)
to stack. - `MathDivideDouble`
Pops
A (double)
, thenB (double)
. PushesA / B (double)
to stack. - `MathModDouble`
Pops
A (double)
, thenB (double)
. PushesA % B (double)
to stack.
Comparison Operators
- `IsSame`
Pops 2 values from stack, pushes
1 (integer)
to stack if both have same value, else, pushes0 (integer)
. - `IsSameArray`
Pops 2 arrays from stack (arrays, not referece to array). Pushes
1 (integer)
to stack if both are same (length, and elements), else, pushes0 (integer)
- `IsSameArrayRef`
Pops 2 references to arrays from stack. Pushes
1 (integer)
to stack if both are same (length, and elements), else, pushes0 (integer)
- `IsGreaterInt`
Pops
A (integer)
, thenB (integer)
. Pushes1 (integer)
ifA > B
, else, pushes0 (integer)
- `IsGreaterSameInt`
Pops
A (integer)
, thenB (integer)
. Pushes1 (integer)
ifA >= B
, else, pushes0 (integer)
- `IsGreaterDouble`
Pops
A (double)
, thenB (double)
. Pushes1 (integer)
ifA > B
, else, pushes0 (integer)
- `IsGreaterSameDouble`
Pops
A (double)
, thenB (double)
. Pushes1 (integer)
ifA >= B
, else, pushes0 (integer)
- `Not`
Pops
A (integer)
. Pushes!A
- `And`
Pops
A (integer)
and thenB (integer)
. PushesA && B
- `Or`
Pops
A (integer)
and thenB (integer)
. PushesA || B
Stack
- `Push [arg0 - any data type]`
Pushes
arg0
to stack - `PushFrom [index - integer>=0]`
Reads value at
index
on stack, pushes it. Value atindex
is not removed from stack. - `PushRefFrom [index - integer>=0]`
Pushes reference to value at
index
on stack. - `WriteTo [index - integer>=0]`
Pops a value from stack, writes it to
index
on stack. - `WriteToRef` Pops a reference, then pops a value. Writes value to reference.
- `Deref` Pops a reference from stack. Pushes the value being referenced
- `Pop` Pops 1 value from stack
- `PopN [n - integer >= 0]` Pops n number of values from stack
Jumps
- `Jump [index - integer>=0]`
Jump execution to instruction at
index
. Be careful using this, make sure you have used `Pop` to clear stack of unneeded elements - `JumpIf [index - integer>=0]`
Pops integer from stack. If it is
1
, jumps execution to instruction atindex
. Be careful using this, make sure you have used `Pop` to clear stack of unneeded elements
Arrays
- `MakeArray [n - integer>0]`
Pops
n
number of elements from stack, puts them in an array (in the order they were added to stack). Pushes array to stack. - `ArrayRefElement`
Pops a reference to array, then an
index (integer)
. Pushes reference-to-element atindex
on array. - `ArrayElement`
Pops an array, then an
index (integer)
. Pushes reference-to-element atindex
on array. - `ArrayLength` Pops an array. Pushes length of stack (integer) to stack.
- `ArrayLengthSet`
Pops a reference to array, then
length (integer)
. Sets length of array tolength
- `Concatenate`
Pops an array
a1
(not reference, array), then pops another arraya2
. Pushes new arraya1 ~ a2
. - `AppendElement` Pops a reference to array, then an element. Appends element at end of array.
- `AppendArrayRef`
Pops reference to array
r1
, pops anotherr2
. Then does*r1 = *r1 ~ *r2
- `AppendArray`
Pops reference to array
r1
, then pops an array (not reference). Then does*r1 = *r1 ~ r2
Data type conversion
- `IntToDouble` Pops an integer from stack. Pushes a double with same value.
- `IntToString` Pops an integer from stack. Pushes a string representation of it.
- `DoubleToInt` Pops a double from stack. Pushes integer part of it (as a integer) to stack.
- `DoubleToString` Pops a double from stack. Pushes string representation of it.
- `StringToInt` Pops a string, reads integer from it, pushes the integer.
- `StringToDouble` Pops a string, reads a double from it, pushes the double.
Misc.
- `ReturnVal` Pops a value from stack, sets it as the return value of currently executing function. Does NOT terminate execution
- `Terminate` Terminates execution of function. Must be called at end of function, or it'll segfault
- 0.1.4 released 4 years ago
- Nafees10/navm
- MIT
- Copyright © 2019, Nafees
- Authors:
- Dependencies:
- utils
- Versions:
-
2.0.2 2024-Apr-10 2.0.1 2024-Jan-28 2.0.0 2024-Jan-28 2.0.0-beta-1 2024-Jan-21 1.4.1 2023-Apr-14 - Download Stats:
-
-
0 downloads today
-
0 downloads this week
-
0 downloads this month
-
124 downloads total
-
- Score:
- 1.5
- Short URL:
- navm.dub.pm