Implements cmd_math partially. Sets demo program to count from 0 to 10.
This commit is contained in:
parent
e313356054
commit
9a7e2e8ceb
2 changed files with 99 additions and 8 deletions
|
@ -6,20 +6,86 @@
|
||||||
Instruction code[] =
|
Instruction code[] =
|
||||||
{
|
{
|
||||||
// { VM_EXEC_X, VM_EXEC_X, VM_INPUT_ZERO, VM_INPUT_ZERO, VM_CMD_COPY, 0, VM_FLAG_NO, VM_OUTPUT_DISCARD, 0 },
|
// { VM_EXEC_X, VM_EXEC_X, VM_INPUT_ZERO, VM_INPUT_ZERO, VM_CMD_COPY, 0, VM_FLAG_NO, VM_OUTPUT_DISCARD, 0 },
|
||||||
{
|
{ // push 0
|
||||||
VM_EXEC_X,
|
VM_EXEC_X,
|
||||||
VM_EXEC_X,
|
VM_EXEC_X,
|
||||||
VM_INPUT_ZERO,
|
VM_INPUT_ARG,
|
||||||
VM_INPUT_ZERO,
|
VM_INPUT_ZERO,
|
||||||
VM_CMD_COPY,
|
VM_CMD_COPY,
|
||||||
0,
|
0,
|
||||||
VM_FLAG_NO,
|
VM_FLAG_NO,
|
||||||
|
VM_OUTPUT_PUSH,
|
||||||
|
0
|
||||||
|
},
|
||||||
|
{ // dup
|
||||||
|
VM_EXEC_X,
|
||||||
|
VM_EXEC_X,
|
||||||
|
VM_INPUT_PEEK,
|
||||||
|
VM_INPUT_ZERO,
|
||||||
|
VM_CMD_COPY,
|
||||||
|
0,
|
||||||
|
VM_FLAG_NO,
|
||||||
|
VM_OUTPUT_PUSH,
|
||||||
|
0
|
||||||
|
},
|
||||||
|
{ // cmp 10
|
||||||
|
VM_EXEC_X,
|
||||||
|
VM_EXEC_X,
|
||||||
|
VM_INPUT_ARG,
|
||||||
|
VM_INPUT_POP,
|
||||||
|
VM_CMD_MATH,
|
||||||
|
VM_MATH_SUB,
|
||||||
|
VM_FLAG_YES,
|
||||||
VM_OUTPUT_DISCARD,
|
VM_OUTPUT_DISCARD,
|
||||||
1337 },
|
10
|
||||||
|
},
|
||||||
|
{ // jmp 7
|
||||||
|
VM_EXEC_1,
|
||||||
|
VM_EXEC_X,
|
||||||
|
VM_INPUT_ARG,
|
||||||
|
VM_INPUT_ZERO,
|
||||||
|
VM_CMD_COPY,
|
||||||
|
0,
|
||||||
|
VM_FLAG_NO,
|
||||||
|
VM_OUTPUT_JUMP,
|
||||||
|
7
|
||||||
|
},
|
||||||
|
{ // add 1
|
||||||
|
VM_EXEC_X,
|
||||||
|
VM_EXEC_X,
|
||||||
|
VM_INPUT_ARG,
|
||||||
|
VM_INPUT_POP,
|
||||||
|
VM_CMD_MATH,
|
||||||
|
0,
|
||||||
|
VM_FLAG_NO,
|
||||||
|
VM_OUTPUT_PUSH,
|
||||||
|
1
|
||||||
|
},
|
||||||
|
{ // jmp 1
|
||||||
|
VM_EXEC_X,
|
||||||
|
VM_EXEC_X,
|
||||||
|
VM_INPUT_ARG,
|
||||||
|
VM_INPUT_ZERO,
|
||||||
|
VM_CMD_COPY,
|
||||||
|
0,
|
||||||
|
VM_FLAG_NO,
|
||||||
|
VM_OUTPUT_JUMP,
|
||||||
|
1
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
void dump_proc(Process *process)
|
void dump_proc(Process *process)
|
||||||
{
|
{
|
||||||
|
if(process->flags & VM_FLAG_Z)
|
||||||
|
printf("z");
|
||||||
|
else
|
||||||
|
printf(" ");
|
||||||
|
|
||||||
|
if(process->flags & VM_FLAG_N)
|
||||||
|
printf("n");
|
||||||
|
else
|
||||||
|
printf(" ");
|
||||||
|
|
||||||
printf("[ ");
|
printf("[ ");
|
||||||
for(int i = 1; i <= process->stackPointer; i++) {
|
for(int i = 1; i <= process->stackPointer; i++) {
|
||||||
printf("%d ", process->stack[i]);
|
printf("%d ", process->stack[i]);
|
||||||
|
@ -37,17 +103,16 @@ void vm_assert(int assertion, const char *msg)
|
||||||
|
|
||||||
int main(int argc, const char **argv)
|
int main(int argc, const char **argv)
|
||||||
{
|
{
|
||||||
Module module = { code, 1 };
|
Module module = { code, 6 };
|
||||||
|
|
||||||
Process process = { &module, 0, 0, 0, 0 };
|
Process process = { &module, 0, 0, 0, 0 };
|
||||||
Process *p = &process;
|
Process *p = &process;
|
||||||
|
|
||||||
vm_push(p, 10);
|
|
||||||
dump_proc(p);
|
dump_proc(p);
|
||||||
int stillAlive = vm_step_process(p);
|
while(vm_step_process(p)) {
|
||||||
|
dump_proc(p);
|
||||||
|
}
|
||||||
dump_proc(p);
|
dump_proc(p);
|
||||||
|
|
||||||
printf("Process %s.\n", (stillAlive ? "still running" : "terminated"));
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
|
@ -1,10 +1,13 @@
|
||||||
#include "vm.h"
|
#include "vm.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint32_t input0;
|
uint32_t input0;
|
||||||
uint32_t input1;
|
uint32_t input1;
|
||||||
uint32_t argument;
|
uint32_t argument;
|
||||||
|
uint32_t additional;
|
||||||
|
|
||||||
uint32_t output;
|
uint32_t output;
|
||||||
} CommandInfo;
|
} CommandInfo;
|
||||||
|
@ -14,6 +17,27 @@ static void cmd_copy(CommandInfo *info)
|
||||||
info->output = info->input0;
|
info->output = info->input0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cmd_math(CommandInfo *info)
|
||||||
|
{
|
||||||
|
switch(info->additional)
|
||||||
|
{
|
||||||
|
// IMPORTANT:
|
||||||
|
// input1 - input0 because then input0 can be a fixed value
|
||||||
|
#define S(name, op) case name: info->output = info->input1 op info->input0; break;
|
||||||
|
S(VM_MATH_ADD, +)
|
||||||
|
S(VM_MATH_SUB, -)
|
||||||
|
S(VM_MATH_MUL, *)
|
||||||
|
S(VM_MATH_DIV, /)
|
||||||
|
S(VM_MATH_MOD, %)
|
||||||
|
S(VM_MATH_AND, &)
|
||||||
|
S(VM_MATH_OR, |)
|
||||||
|
S(VM_MATH_XOR, ^)
|
||||||
|
#undef S
|
||||||
|
case VM_MATH_NOT: info->output = ~info->input0; break;
|
||||||
|
default: vm_assert(0, "Invalid instruction: MATH command not defined."); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int vm_step_process(Process *process)
|
int vm_step_process(Process *process)
|
||||||
{
|
{
|
||||||
vm_assert(process != NULL, "process must not be NULL.");
|
vm_assert(process != NULL, "process must not be NULL.");
|
||||||
|
@ -78,10 +102,12 @@ int vm_step_process(Process *process)
|
||||||
}
|
}
|
||||||
|
|
||||||
info.argument = instr.argument;
|
info.argument = instr.argument;
|
||||||
|
info.additional = instr.cmdinfo;
|
||||||
|
|
||||||
switch(instr.command)
|
switch(instr.command)
|
||||||
{
|
{
|
||||||
case VM_CMD_COPY: cmd_copy(&info); break;
|
case VM_CMD_COPY: cmd_copy(&info); break;
|
||||||
|
case VM_CMD_MATH: cmd_math(&info); break;
|
||||||
default: vm_assert(0, "Invalid instruction: command undefined.");
|
default: vm_assert(0, "Invalid instruction: command undefined.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue