Added parser and test vo vm
This commit is contained in:
@@ -4,4 +4,4 @@ compiler:
|
||||
- clang
|
||||
- gcc
|
||||
|
||||
script: cd vvm && make && bin/vvm && make clean && cd ../nbfi && make && bash test.sh && make clean
|
||||
script: cd vvm && make && bash test.sh && make clean && cd ../nbfi && make && bash test.sh && make clean
|
||||
|
@@ -23,17 +23,23 @@ int factorial[] = {
|
||||
|
||||
/**
|
||||
* @brief main
|
||||
* argc -> the argument counter
|
||||
* argv -> the argument vector
|
||||
*
|
||||
* executes code in my dsl.
|
||||
*/
|
||||
int main(){
|
||||
int code[] = { ICONST, 72, PRINT, ICONST, 101, PRINT, ICONST, 108,
|
||||
int main(int argc, char** argv){
|
||||
/*int code[] = { ICONST, 72, PRINT, ICONST, 101, PRINT, ICONST, 108,
|
||||
PRINT, ICONST, 108, PRINT, ICONST, 111, PRINT, ICONST, 44, PRINT,
|
||||
ICONST, 32, PRINT, ICONST, 119, PRINT, ICONST, 111, PRINT,
|
||||
ICONST, 114, PRINT, ICONST, 108, PRINT, ICONST, 100, PRINT,
|
||||
ICONST, 33, GSTORE, 0, GLOAD, 0, PRINT, ICONST, 10, PRINT, HALT };
|
||||
vm_execute(factorial, 22, 0, sizeof(factorial) / sizeof(factorial[0]));
|
||||
printf("\n");
|
||||
vm_execute(code, 0, 1, sizeof(code) / sizeof(code[0]));
|
||||
vm_execute(code, 0, 1, sizeof(code) / sizeof(code[0]));*/
|
||||
if(argc != 2)
|
||||
die(127, "Please specify exactly one file to execute.");
|
||||
program prog = vm_parse(argv[1]);
|
||||
vm_execute(prog.code, 22, 0, prog.length);
|
||||
return 0;
|
||||
}
|
||||
|
@@ -11,7 +11,7 @@
|
||||
* Lets the program die and emits an error message.
|
||||
*/
|
||||
static inline void die(int code, const char* message){
|
||||
fprintf(stderr, "%s", message);
|
||||
fprintf(stderr, "%s\n", message);
|
||||
exit(code);
|
||||
}
|
||||
#endif
|
||||
|
97
vvm/src/vm.c
97
vvm/src/vm.c
@@ -32,7 +32,7 @@ static inline void disassemble(int sp, int fp, int ip, int opcode, instruction*
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void vm_execute(int code[], int ip, int datasize, int length){
|
||||
void vm_execute(int code[], int ip, int datasize, unsigned long length){
|
||||
int data[datasize];
|
||||
int stack[MAX_SIZE];
|
||||
int sp = -1;
|
||||
@@ -161,8 +161,101 @@ void vm_execute(int code[], int ip, int datasize, int length){
|
||||
sp--;
|
||||
default:
|
||||
fprintf(stderr, "Unrecognized: %d\n", opcode);
|
||||
die(1, "Exit on program failure.");
|
||||
die(127, "Exit on program failure.");
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
program vm_parse(char *filename){
|
||||
FILE* file = fopen(filename, "r");
|
||||
char* line = NULL;
|
||||
char** command;
|
||||
unsigned long size = 100;
|
||||
int* code = malloc(size * sizeof(int));
|
||||
unsigned long codep = 0;
|
||||
register int i;
|
||||
instruction* ins = setup_instructions();
|
||||
unsigned int len = IDEC;
|
||||
size_t linelength = 0;
|
||||
|
||||
if(!file)
|
||||
die(127, "Could not open file.");
|
||||
|
||||
while(getline(&line, &linelength, file) != -1){
|
||||
short found = FALSE;
|
||||
strtok(line, "\n");
|
||||
command = str_split(line, ' ');
|
||||
|
||||
if(codep == size){
|
||||
size += 100;
|
||||
code = (int *) realloc(code, size * sizeof(int));
|
||||
if(code == NULL)
|
||||
die(127, "Program too big, could not allocate enough storage.");
|
||||
}
|
||||
|
||||
for(i = 1; i < len; i++)
|
||||
if(strcmp(ins[i].name, command[0]) == 0){
|
||||
code[codep++] = i;
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
if(found && ins[i].operands > 0){
|
||||
int nargs = ins[i].operands;
|
||||
for(i = 1; i <= nargs; i++){
|
||||
code[codep++] = (int) strtol(command[i], (char **) NULL, 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
|
||||
if(line)
|
||||
free(line);
|
||||
|
||||
code = (int *) realloc(code, codep * sizeof(int));
|
||||
|
||||
program prog = {codep, code};
|
||||
|
||||
return prog;
|
||||
}
|
||||
|
||||
char** str_split(char* a_str, const char a_delim){
|
||||
char** result = 0;
|
||||
size_t count = 0;
|
||||
char* tmp = a_str;
|
||||
char* last_comma = 0;
|
||||
char delim[2];
|
||||
delim[0] = a_delim;
|
||||
delim[1] = 0;
|
||||
|
||||
while (*tmp){
|
||||
if (a_delim == *tmp){
|
||||
count++;
|
||||
last_comma = tmp;
|
||||
}
|
||||
tmp++;
|
||||
}
|
||||
|
||||
count += last_comma < (a_str + strlen(a_str) - 1);
|
||||
|
||||
count++;
|
||||
|
||||
result = malloc(sizeof(char*) * count);
|
||||
|
||||
if (result){
|
||||
size_t idx = 0;
|
||||
char* token = strtok(a_str, delim);
|
||||
|
||||
while (token){
|
||||
assert(idx < count);
|
||||
*(result + idx++) = strdup(token);
|
||||
token = strtok(0, delim);
|
||||
}
|
||||
assert(idx == count - 1);
|
||||
*(result + idx) = 0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
17
vvm/src/vm.h
17
vvm/src/vm.h
@@ -2,10 +2,17 @@
|
||||
#define VM_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "util.h"
|
||||
#include "opcode.h"
|
||||
|
||||
typedef struct{
|
||||
unsigned long length;
|
||||
int* code;
|
||||
} program;
|
||||
|
||||
/**
|
||||
* @brief vm_execute
|
||||
* @param code -> instructions
|
||||
@@ -13,6 +20,14 @@
|
||||
* @param datasize -> maximum data size
|
||||
* @param length -> length of program
|
||||
*/
|
||||
void vm_execute(int[], int, int, int);
|
||||
void vm_execute(int[], int, int, unsigned long);
|
||||
|
||||
/**
|
||||
* @brief vm_parse
|
||||
* @param file -> filename
|
||||
*/
|
||||
program vm_parse(char*);
|
||||
|
||||
char** str_split(char*, const char);
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user