hardcoded string implementation
This commit is contained in:
parent
d03c5ba983
commit
8e9ab93151
|
|
@ -2,16 +2,18 @@
|
||||||
#include "../../../tools/compiler/compiler.h"
|
#include "../../../tools/compiler/compiler.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#define CODE_SIZE 8192
|
|
||||||
#define MEMORY_SIZE 65536
|
#define MEMORY_SIZE 65536
|
||||||
|
#define CODE_SIZE 8192
|
||||||
|
#define STACK_SIZE 1024
|
||||||
|
|
||||||
u8 lmem[MEMORY_SIZE] = {0};
|
u8 lmem[MEMORY_SIZE] = {0};
|
||||||
u8 lcode[CODE_SIZE] = {0};
|
u8 lcode[CODE_SIZE] = {0};
|
||||||
u32 lstack[CODE_SIZE] = {0};
|
u32 lstack[STACK_SIZE] = {0};
|
||||||
|
|
||||||
void reset() {
|
void reset() {
|
||||||
pc = 0;
|
pc = 0;
|
||||||
cp = 0;
|
cp = 0;
|
||||||
mp = 0;
|
mp = 255; // hardcoded for now, 255 locals
|
||||||
fp = 0;
|
fp = 0;
|
||||||
sp = 0;
|
sp = 0;
|
||||||
interrupt = 0;
|
interrupt = 0;
|
||||||
|
|
@ -84,6 +86,8 @@ static void repl() {
|
||||||
|
|
||||||
while(step_vm()) {}
|
while(step_vm()) {}
|
||||||
|
|
||||||
|
syscall(SYSCALL_CONSOLE_WRITE, 255);
|
||||||
|
|
||||||
printf("Result at top of stack: %d\n", stack[0]);
|
printf("Result at top of stack: %d\n", stack[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -277,7 +277,7 @@ static void binary() {
|
||||||
code[cp++] = OP_DIV_INT;
|
code[cp++] = OP_DIV_INT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TOKEN_EQ_EQ:{
|
case TOKEN_EQ_EQ: {
|
||||||
code[cp++] = OP_EQ;
|
code[cp++] = OP_EQ;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -324,6 +324,49 @@ static void literal() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void string() {
|
||||||
|
u32 addr = mp;
|
||||||
|
const char *src = parser.previous.start + 1;
|
||||||
|
i32 len = 0;
|
||||||
|
i32 i = 0;
|
||||||
|
|
||||||
|
while (i < parser.previous.length - 2) {
|
||||||
|
char c = src[i++];
|
||||||
|
if (c == '\\' && i < parser.previous.length - 2) {
|
||||||
|
switch (src[i++]) {
|
||||||
|
case 'n':
|
||||||
|
c = '\n';
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
c = '\t';
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
c = '\r';
|
||||||
|
break;
|
||||||
|
case '\\':
|
||||||
|
case '"':
|
||||||
|
case '\'':
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
i--; /* Rewind for unknown escapes */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WRITE_U8(addr + 4 + len, c);
|
||||||
|
len++;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 size = len + 5; /* 4 (len) + dst_len + 1 (null) */
|
||||||
|
mp += size;
|
||||||
|
|
||||||
|
WRITE_U32(addr, len);
|
||||||
|
WRITE_U8(addr + 4 + len, '\0');
|
||||||
|
|
||||||
|
// TODO: this really should always be tied to a global or local variable
|
||||||
|
// we can fake it for now
|
||||||
|
WRITE_U32(fp + lp, addr);
|
||||||
|
lp++;
|
||||||
|
}
|
||||||
|
|
||||||
ParseRule rules[] = {
|
ParseRule rules[] = {
|
||||||
[TOKEN_LPAREN] = {grouping, NULL, PREC_NONE},
|
[TOKEN_LPAREN] = {grouping, NULL, PREC_NONE},
|
||||||
[TOKEN_RPAREN] = {NULL, NULL, PREC_NONE},
|
[TOKEN_RPAREN] = {NULL, NULL, PREC_NONE},
|
||||||
|
|
@ -345,7 +388,7 @@ ParseRule rules[] = {
|
||||||
[TOKEN_LT] = {NULL, binary, PREC_COMPARISON},
|
[TOKEN_LT] = {NULL, binary, PREC_COMPARISON},
|
||||||
[TOKEN_LTE] = {NULL, binary, PREC_COMPARISON},
|
[TOKEN_LTE] = {NULL, binary, PREC_COMPARISON},
|
||||||
[TOKEN_IDENTIFIER] = {NULL, NULL, PREC_NONE},
|
[TOKEN_IDENTIFIER] = {NULL, NULL, PREC_NONE},
|
||||||
[TOKEN_LITERAL_STR] = {NULL, NULL, PREC_NONE},
|
[TOKEN_LITERAL_STR] = {string, NULL, PREC_NONE},
|
||||||
[TOKEN_LITERAL_INT] = {number, NULL, PREC_NONE},
|
[TOKEN_LITERAL_INT] = {number, NULL, PREC_NONE},
|
||||||
[TOKEN_LITERAL_NAT] = {number, NULL, PREC_NONE},
|
[TOKEN_LITERAL_NAT] = {number, NULL, PREC_NONE},
|
||||||
[TOKEN_LITERAL_REAL] = {number, NULL, PREC_NONE},
|
[TOKEN_LITERAL_REAL] = {number, NULL, PREC_NONE},
|
||||||
|
|
@ -395,5 +438,8 @@ bool compile(ScopeTable *st, char *source) {
|
||||||
expression();
|
expression();
|
||||||
consume(TOKEN_EOF, "Cannot find end of expression.");
|
consume(TOKEN_EOF, "Cannot find end of expression.");
|
||||||
|
|
||||||
return false;
|
// technically should not need, but just in case
|
||||||
|
code[cp++] = OP_HALT;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
13
vm/vm.c
13
vm/vm.c
|
|
@ -5,7 +5,8 @@ u32 pc; /* program counter */
|
||||||
u32 cp; /* code pointer */
|
u32 cp; /* code pointer */
|
||||||
u32 mp; /* memory pointer */
|
u32 mp; /* memory pointer */
|
||||||
u32 fp; /* frame pointer */
|
u32 fp; /* frame pointer */
|
||||||
u32 sp; /* frame pointer */
|
u32 sp; /* stack pointer */
|
||||||
|
u8 lp; /* locals pointer */
|
||||||
u8 status; /* status flag */
|
u8 status; /* status flag */
|
||||||
u8 interrupt; /* device interrupt */
|
u8 interrupt; /* device interrupt */
|
||||||
u32 *stack; /* stack */
|
u32 *stack; /* stack */
|
||||||
|
|
@ -388,6 +389,11 @@ bool step_vm() {
|
||||||
stack[sp++] = result;
|
stack[sp++] = result;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
case OP_NOT: {
|
||||||
|
u32 a = !stack[--sp];
|
||||||
|
stack[sp++] = a;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
case OP_BIT_SHIFT_LEFT: {
|
case OP_BIT_SHIFT_LEFT: {
|
||||||
MATH_OP_NO_CAST(<<);
|
MATH_OP_NO_CAST(<<);
|
||||||
}
|
}
|
||||||
|
|
@ -406,11 +412,6 @@ bool step_vm() {
|
||||||
case OP_BIT_XOR: {
|
case OP_BIT_XOR: {
|
||||||
MATH_OP_NO_CAST(^);
|
MATH_OP_NO_CAST(^);
|
||||||
}
|
}
|
||||||
case OP_NOT: {
|
|
||||||
u32 a = !stack[--sp];
|
|
||||||
stack[sp++] = a;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case OP_EQ: {
|
case OP_EQ: {
|
||||||
MATH_OP_NO_CAST(==);
|
MATH_OP_NO_CAST(==);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
1
vm/vm.h
1
vm/vm.h
|
|
@ -96,6 +96,7 @@ extern u32 cp; /* code pointer */
|
||||||
extern u32 mp; /* memory pointer */
|
extern u32 mp; /* memory pointer */
|
||||||
extern u32 fp; /* frame pointer */
|
extern u32 fp; /* frame pointer */
|
||||||
extern u32 sp; /* stack pointer */
|
extern u32 sp; /* stack pointer */
|
||||||
|
extern u8 lp; /* locals pointer */
|
||||||
extern u8 status; /* status flag */
|
extern u8 status; /* status flag */
|
||||||
extern u8 interrupt; /* device interrupt */
|
extern u8 interrupt; /* device interrupt */
|
||||||
extern u32 *stack; /* stack */
|
extern u32 *stack; /* stack */
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue