ArgoVM is a stack-based virtual machine similar to JVM.
It runs the file provided by ArgoC (Argo Compiler) which transform the argo-lang into an executable byte-code format.
OP | Usage | Function |
---|---|---|
HLT | HLT | Terminate the program |
NOP | NOP | Nothing |
PSH | PSH, value | Pushes value on the stack |
POP | POP | Pops value from stack |
ADD | ADD | Pops the last two values from the stack, it sums then push the result |
SUB | SUB | Pops the last two values from the stack, it subtracts then push the result |
MUL | MUL | Pops the last two values from the stack, it multiplies then push the result |
DIV | DIV | Pops the last two values from the stack, it divides then push the results (value and rest) |
NEG | NEG | Pops the last value from the stack, it negate then push the results |
CMP | CMP | Peeks the last two values from the stack, then set the CMP register to one of these values: (EQUALS, LESSER, GREATER) |
JMP | JMP, idx | Jumps at given instruction index |
JEQ | JEQ, idx | Jumps at given instruction index only if the CMP flag is set to EQUALS |
JNE | JNE, idx | Jumps at given instruction index only if the CMP flag is NOT set to EQUALS |
JMG | JMG, idx | Jumps at given instruction index only if the CMP flag is set to GREATER |
JML | JML, idx | Jumps at given instruction index only if the CMP flag is set to LESSER |
JGE | JGE, idx | Jumps at given instruction index only if the CMP flag is set to EQUALS or GREATER |
JLE | JLE, idx | Jumps at given instruction index only if the CMP flag is set to EQUALS or LESSER |
CLL | CLL, idx | Executes the given routine identifier |
RET | RET | Routine specific instruction, it's used to terminate the current routine flow |
Peeks the last value from the stack and print it. |
Let's see some syntax in action
# sum.argo
#
# Define the main function (entry point)
:main {
PSH, 5
PSH, 4
ADD
PRINT
HLT
}
You can reproduce any conditional-structure you like with the following instructions
# iterate.argo
#
# function main() {
# for(var i = 0; i <= 100; ++i) {
# print(i);
# }
# }
#
:main {
PSH, 1
PRINT
PSH, 1
ADD
PSH, 100
CMP
POP
JLE, 2
HLT
}
Splitting the code workflow among other calls, arguments should be pushed on stack before calling the function meanwhile the return address is managed automatically.
# The following .argo equals to this code:
#
# function printer(var x){
# print(x);
# }
#
# function sum(var a, var b) {
# return a + b;
# }
#
# function main() {
# printer(sum(5, 4));
# return;
# }
#
:main {
PSH, 5
PSH, 4
CLL, sum
HLT
}
:sum {
ADD
CLL, printer
RET
}
:printer {
PRINT
RET
}
This is how its expected to work at the end of development:
Argonauts (Lang) -> Argo (ASM) -> Bytecode (ArgoCode) -> ArgoVM
Currently there is no Argonauts
lang, I'm still working on Argo
.
The current ArgoVM is written in C meanwhile the compiler ArgoC is written using Java, some additionals dev-tools are made in Perl.
src
|
|-- assembler # The ArgoC home directory
|-- vm # The ArgoVM home directory
TODO ...