aboutsummaryrefslogtreecommitdiff
path: root/src/vm.c
diff options
context:
space:
mode:
authorFranklin Wei <git@fwei.tk>2015-11-25 22:36:40 -0500
committerFranklin Wei <git@fwei.tk>2015-11-25 22:36:40 -0500
commitf9bd70a047c357d7f4ebfadbfe34c30becb380db (patch)
tree7e991c719d0f40a453f9e8a83ccb9760ba6f3a4c /src/vm.c
parent3c13f12ac8279ddccf2a20fbc072d6b918ea2096 (diff)
downloadducky-f9bd70a047c357d7f4ebfadbfe34c30becb380db.zip
ducky-f9bd70a047c357d7f4ebfadbfe34c30becb380db.tar.gz
ducky-f9bd70a047c357d7f4ebfadbfe34c30becb380db.tar.bz2
ducky-f9bd70a047c357d7f4ebfadbfe34c30becb380db.tar.xz
refactor, add simple builtin functions, fix osx bug
Diffstat (limited to 'src/vm.c')
-rw-r--r--src/vm.c77
1 files changed, 41 insertions, 36 deletions
diff --git a/src/vm.c b/src/vm.c
index 3e19c20..407762d 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -15,7 +15,15 @@ static unsigned stack_pointer;
static jmp_buf exit_point;
struct var_t {
- vartype val;
+ enum { TYPE_PLAIN, TYPE_SPECIAL } type;
+
+ union {
+ vartype val;
+ struct {
+ enum special_id special;
+ };
+ };
+
bool constant;
};
@@ -29,9 +37,7 @@ static bool want_quit;
static int repeats_left;
static imm_t repeat_line;
-static void error(const char *fmt, ...) __attribute__((noreturn,format(print,1,2)));
static void vid_write(const char *str);
-static void vid_logf(const char *fmt, ...) __attribute__((format(printf,1,2)));
instr_t read_instr(void)
{
@@ -81,21 +87,6 @@ static void __attribute__((format(printf,1,2))) vid_writef(const char *fmt, ...)
va_end(ap);
}
-static void __attribute__((noreturn,format(printf,1,2))) error(const char *fmt, ...)
-{
- char fmtbuf[256];
-
- va_list ap;
- va_start(ap, fmt);
- vsnprintf(fmtbuf, sizeof(fmtbuf), fmt, ap);
- if(current_line)
- vid_writef("Line %d: ", current_line);
- vid_writef("ERROR: %s\n", fmtbuf);
- va_end(ap);
-
- longjmp(exit_point, 1);
-}
-
static void __attribute__((format(printf,1,2))) warning(const char *fmt, ...)
{
char fmtbuf[256];
@@ -122,7 +113,7 @@ static inline void push(imm_t n)
if(stack_pointer < STACK_SZ)
stack[stack_pointer++] = n;
else
- error("stack overflow");
+ ERROR("stack overflow");
}
static inline imm_t pop(void)
@@ -130,13 +121,19 @@ static inline imm_t pop(void)
if(stack_pointer > 0)
return stack[--stack_pointer];
else
- error("stack underflow");
+ ERROR("stack underflow");
}
static inline vartype getvar(varid_t varid)
{
if(varid < ARRAYLEN(vars))
- return vars[varid].val;
+ {
+ struct var_t *var = vars+varid;
+ if(var->type == TYPE_PLAIN)
+ return vars[varid].val;
+ else
+ return get_special(vars[varid].special);
+ }
}
static inline void setvar(varid_t varid, vartype val)
@@ -144,7 +141,7 @@ static inline void setvar(varid_t varid, vartype val)
if(varid < ARRAYLEN(vars) && !vars[varid].constant)
vars[varid].val = val;
else
- error("cannot modify variable");
+ ERROR("cannot modify variable");
}
static inline void mkconst(varid_t varid)
@@ -161,7 +158,7 @@ static inline void jump(imm_t line)
current_line = line;
}
else
- error("jump target out of bounds");
+ ERROR("jump target out of bounds");
}
static void pushimm_handler(void)
@@ -215,7 +212,7 @@ static void repeat_handler(void)
if(repeats_left > 0)
{
if(repeat_line + 1 != current_line)
- error("nested REPEAT");
+ ERROR("nested REPEAT");
--repeats_left;
if(repeats_left > 0)
{
@@ -243,7 +240,7 @@ static void subcall_handler(void)
jump(pop());
}
else
- error("call stack overflow");
+ ERROR("call stack overflow");
}
static void subret_handler(void)
@@ -253,7 +250,7 @@ static void subret_handler(void)
jump(callstack[--callstack_pointer]);
}
else
- error("call stack underflow");
+ ERROR("call stack underflow");
}
static void if_handler(void)
@@ -459,13 +456,6 @@ static void newline_handler(void)
vid_writef("\n");
}
-static void inc_line_pointer(void)
-{
- ++current_line;
-
- vars[0].val = current_line;
-}
-
static void input_handler(void)
{
vartype val;
@@ -473,6 +463,21 @@ static void input_handler(void)
setvar(read_varid(), val);
}
+static void mkspecial_handler(void)
+{
+ varid_t varid = read_varid();
+ vars[varid].constant = true;
+ vars[varid].type = TYPE_SPECIAL;
+ vars[varid].special = read_imm();
+}
+
+static void inc_line_pointer(void)
+{
+ ++current_line;
+
+ vars[0].val = current_line;
+}
+
static void (*instr_tab[0x100])(void) = {
pushimm_handler, /* 0x0 */
pushvar_handler, /* 0x1 */
@@ -522,7 +527,7 @@ static void (*instr_tab[0x100])(void) = {
NULL, /* 0x2d */
newline_handler, /* 0x2e */
input_handler, /* 0x2f */
- NULL, /* 0x30 */
+ mkspecial_handler, /* 0x30 */
NULL, /* 0x31 */
NULL, /* 0x32 */
NULL, /* 0x33 */
@@ -741,7 +746,7 @@ int ducky_vm(int fd)
init_globals();
if(read_imm() != DUCKY_MAGIC)
- error("unknown format");
+ ERROR("unknown format");
num_lines = read_imm();
line_offset = malloc(num_lines + 1);
@@ -760,7 +765,7 @@ int ducky_vm(int fd)
if(handler)
handler();
else
- error("invalid instruction");
+ ERROR("invalid instruction");
}
return 0;
}