Added parser and test vo vm
This commit is contained in:
@@ -4,4 +4,4 @@ compiler:
|
|||||||
- clang
|
- clang
|
||||||
- gcc
|
- 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
|
* @brief main
|
||||||
|
* argc -> the argument counter
|
||||||
|
* argv -> the argument vector
|
||||||
*
|
*
|
||||||
* executes code in my dsl.
|
* executes code in my dsl.
|
||||||
*/
|
*/
|
||||||
int main(){
|
int main(int argc, char** argv){
|
||||||
int code[] = { ICONST, 72, PRINT, ICONST, 101, PRINT, ICONST, 108,
|
/*int code[] = { ICONST, 72, PRINT, ICONST, 101, PRINT, ICONST, 108,
|
||||||
PRINT, ICONST, 108, PRINT, ICONST, 111, PRINT, ICONST, 44, PRINT,
|
PRINT, ICONST, 108, PRINT, ICONST, 111, PRINT, ICONST, 44, PRINT,
|
||||||
ICONST, 32, PRINT, ICONST, 119, PRINT, ICONST, 111, PRINT,
|
ICONST, 32, PRINT, ICONST, 119, PRINT, ICONST, 111, PRINT,
|
||||||
ICONST, 114, PRINT, ICONST, 108, PRINT, ICONST, 100, PRINT,
|
ICONST, 114, PRINT, ICONST, 108, PRINT, ICONST, 100, PRINT,
|
||||||
ICONST, 33, GSTORE, 0, GLOAD, 0, PRINT, ICONST, 10, PRINT, HALT };
|
ICONST, 33, GSTORE, 0, GLOAD, 0, PRINT, ICONST, 10, PRINT, HALT };
|
||||||
vm_execute(factorial, 22, 0, sizeof(factorial) / sizeof(factorial[0]));
|
vm_execute(factorial, 22, 0, sizeof(factorial) / sizeof(factorial[0]));
|
||||||
printf("\n");
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -11,7 +11,7 @@
|
|||||||
* Lets the program die and emits an error message.
|
* Lets the program die and emits an error message.
|
||||||
*/
|
*/
|
||||||
static inline void die(int code, const char* message){
|
static inline void die(int code, const char* message){
|
||||||
fprintf(stderr, "%s", message);
|
fprintf(stderr, "%s\n", message);
|
||||||
exit(code);
|
exit(code);
|
||||||
}
|
}
|
||||||
#endif
|
#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");
|
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 data[datasize];
|
||||||
int stack[MAX_SIZE];
|
int stack[MAX_SIZE];
|
||||||
int sp = -1;
|
int sp = -1;
|
||||||
@@ -161,8 +161,101 @@ void vm_execute(int code[], int ip, int datasize, int length){
|
|||||||
sp--;
|
sp--;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "Unrecognized: %d\n", opcode);
|
fprintf(stderr, "Unrecognized: %d\n", opcode);
|
||||||
die(1, "Exit on program failure.");
|
die(127, "Exit on program failure.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
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
|
#define VM_H
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "opcode.h"
|
#include "opcode.h"
|
||||||
|
|
||||||
|
typedef struct{
|
||||||
|
unsigned long length;
|
||||||
|
int* code;
|
||||||
|
} program;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief vm_execute
|
* @brief vm_execute
|
||||||
* @param code -> instructions
|
* @param code -> instructions
|
||||||
@@ -13,6 +20,14 @@
|
|||||||
* @param datasize -> maximum data size
|
* @param datasize -> maximum data size
|
||||||
* @param length -> length of program
|
* @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
|
#endif
|
||||||
|
Reference in New Issue
Block a user