2017-02-09 20:02:59 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include "datatypes.h"
|
|
|
|
#include "vm.h"
|
|
|
|
#include "parse.h"
|
|
|
|
#include "compile.h"
|
|
|
|
#include "value.h"
|
2017-02-11 19:01:06 +00:00
|
|
|
#include "disasm.h"
|
2017-02-09 20:02:59 +00:00
|
|
|
|
2017-02-13 05:11:30 +00:00
|
|
|
void StringPut(uint8_t * string) {
|
|
|
|
uint32_t i;
|
|
|
|
uint32_t len = VStringSize(string);
|
|
|
|
for (i = 0; i < len; ++i)
|
|
|
|
fputc(string[i], stdout);
|
|
|
|
}
|
|
|
|
|
2017-02-12 20:53:52 +00:00
|
|
|
/* Test c function */
|
2017-02-10 04:28:11 +00:00
|
|
|
Value print(VM * vm) {
|
2017-02-13 05:11:30 +00:00
|
|
|
uint32_t j, count;
|
2017-02-13 04:45:52 +00:00
|
|
|
Value nil;
|
|
|
|
count = VMCountArgs(vm);
|
|
|
|
for (j = 0; j < count; ++j) {
|
|
|
|
uint8_t * string = ValueToString(vm, VMGetArg(vm, j));
|
2017-02-13 05:11:30 +00:00
|
|
|
StringPut(string);
|
2017-02-13 04:45:52 +00:00
|
|
|
fputc('\n', stdout);
|
|
|
|
}
|
|
|
|
nil.type = TYPE_NIL;
|
|
|
|
return nil;
|
2017-02-10 04:28:11 +00:00
|
|
|
}
|
|
|
|
|
2017-02-09 20:02:59 +00:00
|
|
|
/* A simple repl for debugging */
|
|
|
|
void debugRepl() {
|
2017-02-13 05:11:30 +00:00
|
|
|
char buffer[1024] = {0};
|
2017-02-13 04:45:52 +00:00
|
|
|
const char * reader = buffer;
|
|
|
|
Value func;
|
|
|
|
VM vm;
|
|
|
|
Parser p;
|
|
|
|
Compiler c;
|
2017-02-09 20:02:59 +00:00
|
|
|
|
2017-02-13 04:45:52 +00:00
|
|
|
VMInit(&vm);
|
2017-02-09 20:02:59 +00:00
|
|
|
|
2017-02-13 04:45:52 +00:00
|
|
|
for (;;) {
|
2017-02-09 20:02:59 +00:00
|
|
|
|
2017-02-13 04:45:52 +00:00
|
|
|
/* Reset state */
|
|
|
|
ParserInit(&p, &vm);
|
2017-02-09 20:02:59 +00:00
|
|
|
|
2017-02-13 04:45:52 +00:00
|
|
|
/* Get and parse input until we have a full form */
|
|
|
|
while (p.status == PARSER_PENDING) {
|
|
|
|
/* Get some input if we are done */
|
|
|
|
if (*reader == '\0') {
|
2017-02-13 05:11:30 +00:00
|
|
|
printf(">> ");
|
2017-02-13 04:45:52 +00:00
|
|
|
if (!fgets(buffer, sizeof(buffer), stdin)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
p.index = 0;
|
|
|
|
reader = buffer;
|
|
|
|
}
|
|
|
|
reader += ParserParseCString(&p, reader);
|
2017-02-09 20:02:59 +00:00
|
|
|
}
|
|
|
|
|
2017-02-13 04:45:52 +00:00
|
|
|
/* Check for parsing errors */
|
|
|
|
if (p.error) {
|
|
|
|
unsigned i;
|
|
|
|
printf("\n");
|
|
|
|
printf("%s\n", buffer);
|
|
|
|
for (i = 0; i < p.index; ++i) {
|
|
|
|
printf(" ");
|
|
|
|
}
|
|
|
|
printf("^\n");
|
|
|
|
printf("\nParse error: %s\n", p.error);
|
|
|
|
reader = buffer; /* Flush the input buffer */
|
|
|
|
buffer[0] = '\0';
|
|
|
|
continue;
|
|
|
|
}
|
2017-02-09 20:02:59 +00:00
|
|
|
|
2017-02-13 04:45:52 +00:00
|
|
|
/* Try to compile generated AST */
|
|
|
|
CompilerInit(&c, &vm);
|
|
|
|
CompilerAddGlobalCFunc(&c, "print", print);
|
|
|
|
func.type = TYPE_FUNCTION;
|
|
|
|
func.data.func = CompilerCompile(&c, p.value);
|
2017-02-09 20:02:59 +00:00
|
|
|
|
2017-02-13 04:45:52 +00:00
|
|
|
/* Check for compilation errors */
|
|
|
|
if (c.error) {
|
|
|
|
printf("Compiler error: %s\n", c.error);
|
|
|
|
reader = buffer;
|
|
|
|
buffer[0] = 0;
|
|
|
|
continue;
|
|
|
|
}
|
2017-02-11 19:01:06 +00:00
|
|
|
|
2017-02-13 04:45:52 +00:00
|
|
|
/* Print asm */
|
2017-02-13 05:11:30 +00:00
|
|
|
//printf("\n");
|
|
|
|
//dasmFunc(stdout, func.data.func);
|
|
|
|
//printf("\n");
|
2017-02-13 02:54:18 +00:00
|
|
|
|
2017-02-13 04:45:52 +00:00
|
|
|
/* Execute function */
|
|
|
|
VMLoad(&vm, func);
|
|
|
|
if (VMStart(&vm)) {
|
|
|
|
printf("VM error: %s\n", vm.error);
|
|
|
|
reader = buffer;
|
|
|
|
buffer[0] = 0;
|
|
|
|
continue;
|
|
|
|
} else {
|
2017-02-13 05:11:30 +00:00
|
|
|
uint8_t * string = ValueToString(&vm, vm.ret);
|
|
|
|
StringPut(string);
|
2017-02-13 04:45:52 +00:00
|
|
|
printf("\n");
|
|
|
|
}
|
2017-02-09 20:02:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
int main() {
|
2017-02-13 04:45:52 +00:00
|
|
|
printf("Super cool interpreter v0.0\n");
|
|
|
|
debugRepl();
|
|
|
|
return 0;
|
2017-02-09 20:02:59 +00:00
|
|
|
}
|