Added parser and test vo vm

This commit is contained in:
Veit Heller
2014-10-08 11:51:34 +02:00
parent 359d460e3a
commit 0f81682eb8
5 changed files with 122 additions and 8 deletions

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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