summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--asmmon.c86
-rw-r--r--asmmon.h1
-rw-r--r--assemble.c239
-rw-r--r--lexer.c69
-rw-r--r--programs/sub-suite/declare.s81
-rw-r--r--programs/sub-suite/subasm.s4
-rw-r--r--programs/sub-suite/subeditor.s8
-rw-r--r--sux.c2
-rw-r--r--sux.h9
-rw-r--r--test/struct.s47
10 files changed, 437 insertions, 109 deletions
diff --git a/asmmon.c b/asmmon.c
index eac72d5..876e6f0 100644
--- a/asmmon.c
+++ b/asmmon.c
@@ -1,4 +1,6 @@
#include "asmmon.h"
+#include "lexer.h"
+
uint16_t linenum = 10;
uint16_t lineidx = 0;
uint16_t stridx = 0;
@@ -34,9 +36,9 @@ void viewmem(uint64_t address) {
}
puts("\n");
for (uint8_t hi = 0; hi < 0x10; hi++) {
- printf("$%016"PRIX64":\t", (address & ~0xF)+(hi << 4));
+ printf("$%016"PRIX64":\t", (address)+(hi << 4));
for (uint8_t lo = 0; lo < 0x10; lo++) {
- printf("%02X", addr[(address & ~0xF)+lo+(hi << 4)]);
+ printf("%02X", addr[(address)+lo+(hi << 4)]);
if (lo < 0x0F) {
putchar(' ');
}
@@ -367,6 +369,7 @@ int asmmon(const char *fn) {
char lex_line[0x1000];
uint16_t size = 0;
uint8_t cmds = 0;
+ uint8_t is_valid = 0;
/* Is single character command. */
uint8_t isshcmd = 0;
if (!isinclude) {
@@ -385,20 +388,52 @@ int asmmon(const char *fn) {
memcpy(cmd, lex_line, size);
cmd = strtok_r(cmd, " \t\n", &tmp);
if (cmd != NULL) {
- isshcmd = (cmd[1] == '\0' || cmd[1] == ' ');
- switch (cmd[0]) {
- case 'q': cmds = (isshcmd || !strcasecmp(cmd, "quit" )) << 0; break;
- case 'v': cmds = (isshcmd || !strcasecmp(cmd, "viewmem")) << 1; break;
- case 'l': cmds = (isshcmd || !strcasecmp(cmd, "list" )) << 2; break;
- case 'a': cmds = (isshcmd || !strcasecmp(cmd, "asm" )) << 3; break;
- case 'h': cmds = (isshcmd || !strcasecmp(cmd, "help" )) << 4; break;
- case 'i': cmds = (isshcmd || !strcasecmp(cmd, "inst" )) << 5; break;
- case 'd': cmds = (isshcmd || !strcasecmp(cmd, "done" )) << 6; break;
- case 's': cmds = (isshcmd || !strcasecmp(cmd, "set" )) << 7; break;
- case ' ':
- case '\t':
- cmds = 0xFF;
- break;
+ int cmd_len = strlen(cmd);
+ isshcmd = (cmd_len > 0 && cmd_len <= 3 && (cmd[1] == '\0' || cmd[1] == ' '));
+ if (tmp) {
+ int stop = 0;
+ for (int i = 0; !(isdelm(tmp[i], 0) & 1) && !stop; i++) {
+ switch (get_ptok(tmp[i], 0)) {
+ case PTOK_NUMBER :
+ case PTOK_ALPHA :
+ case PTOK_DOLLAR :
+ case PTOK_PERCENT:
+ case PTOK_DQUOTE :
+ case PTOK_SQUOTE :
+ case PTOK_B :
+ case PTOK_X :
+ case PTOK_Y :
+ case PTOK_S :
+ case PTOK_P :
+ case PTOK_MINUS :
+ case PTOK_PLUS : is_valid = 1; break;
+ default : is_valid = 0; stop = 1; break;
+ }
+ }
+ if (strlen(tmp) <= 1) {
+ is_valid = 1;
+ }
+ }
+ if (is_valid) {
+ switch (cmd[0]) {
+ case 'q': cmds = (isshcmd || !strcasecmp(cmd, "quit" )) << 0; break;
+ case 'v': cmds = (isshcmd || !strcasecmp(cmd, "viewmem")) << 1; break;
+ case 'l': cmds = (isshcmd || !strcasecmp(cmd, "list" )) << 2; break;
+ case 'a': cmds = (isshcmd || !strcasecmp(cmd, "asm" )) << 3; break;
+ case 'h': cmds = (isshcmd || !strcasecmp(cmd, "help" )) << 4; break;
+ case 'i': cmds = (isshcmd || !strcasecmp(cmd, "inst" )) << 5; break;
+ case 'd': cmds = (isshcmd || !strcasecmp(cmd, "done" )) << 6; break;
+ case 's': cmds = (isshcmd || !strcasecmp(cmd, "set" )) << 7; break;
+ case ' ':
+ case '\t':
+ default:
+ is_valid = 0;
+ cmds = 0xFF;
+ break;
+ }
+ if (!cmds) {
+ is_valid = 0;
+ }
}
switch (cmds) {
case 0x01:
@@ -525,13 +560,14 @@ int asmmon(const char *fn) {
}
break;
case 0x40:
- done = 1;
- break;
+ done = 1;
+ break;
case 0x80:
if (tmp != NULL) {
uint16_t i = 0;
uint16_t j = 0;
uint8_t isdebug = 0;
+ is_valid = 0;
while (tmp[i] != '\0') {
if (isspace(tmp[i])) {
for (; isspace(tmp[i]); i++);
@@ -541,6 +577,7 @@ int asmmon(const char *fn) {
j = 0;
isdebug = (arg[j] == 'd' || !strcasecmp(arg, "debug"));
if (isdebug) {
+ is_valid = 1;
dbg = !dbg;
if (dbg) {
puts("Debug mode has been enabled.");
@@ -550,14 +587,15 @@ int asmmon(const char *fn) {
}
i++;
}
+ } else {
+ is_valid = 0;
}
- break;
case 0xFF:
- break;
- default:
- address = lex(lex_line, address, bline, dbg);
- bline = 0;
- break;
+ default : break;
+ }
+ if (!is_valid) {
+ address = lex(lex_line, address, bline, dbg);
+ bline = 0;
}
} else if (lex_line[0] == '\n') {
bline++;
diff --git a/asmmon.h b/asmmon.h
index 7db9b4c..27a6ede 100644
--- a/asmmon.h
+++ b/asmmon.h
@@ -61,6 +61,7 @@ struct sym {
uint16_t count;
uint64_t val;
uint8_t isstruct;
+ uint8_t isanon;
uint8_t def;
char *name;
uint16_t id;
diff --git a/assemble.c b/assemble.c
index 2114456..24037d9 100644
--- a/assemble.c
+++ b/assemble.c
@@ -115,8 +115,6 @@ uint64_t get_val(token *t, uint64_t addr, uint8_t size, uint8_t dbg) {
}
token *skip_expr(token *t, uint8_t dbg) {
- /*if (t->next && t->next->id == TOK_EXPR && isexpr(t->next->type, dbg)) {
- }*/
do {
t = (t->id == TOK_EXPR) ? t->next : t;
switch (t->id) {
@@ -144,7 +142,7 @@ uint8_t get_directivesize(uint8_t type, uint8_t dbg) {
}
uint16_t handle_struct(line **ln, uint64_t address, uint16_t offset, uint8_t dbg) {
- uint8_t type = 0;
+ uint8_t is_struct = 0;
uint8_t done = 0;
uint8_t ismember = 0;
uint16_t size = 0;
@@ -156,11 +154,11 @@ uint16_t handle_struct(line **ln, uint64_t address, uint16_t offset, uint8_t dbg
for (uint8_t found = 0; tok && !found; tok = tok->next) {
switch (tok->id) {
case TOK_DIR:
- type = (tok->type == DIR_UNION);
+ is_struct = (tok->type == DIR_STRUCT);
found = (tok->type == DIR_STRUCT || tok->type == DIR_UNION);
break;
- case TOK_STRUCT:
- case TOK_UNION : type = (tok->id == TOK_UNION); found = 1; break;
+ case TOK_STRUCT: is_struct = 1;
+ case TOK_UNION : found = 1; break;
}
}
if (tok != NULL) {
@@ -180,7 +178,7 @@ uint16_t handle_struct(line **ln, uint64_t address, uint16_t offset, uint8_t dbg
case TOK_MEMBER: ismember = 1; member = t->sym; break;
case TOK_DIR :
ismember = (t->type == DIR_STRUCT || t->type == DIR_UNION) ? 1 : ismember;
- done = ((!type && t->type == DIR_ENDSTRUCT) || (type && t->type == DIR_ENDUNION));
+ done = ((is_struct && t->type == DIR_ENDSTRUCT) || (!is_struct && t->type == DIR_ENDUNION));
if (!done && ismember) {
switch (t->type) {
case DIR_BYTE : member_size = 1; break;
@@ -194,11 +192,9 @@ uint16_t handle_struct(line **ln, uint64_t address, uint16_t offset, uint8_t dbg
if (member && t->type != DIR_UNION && t->type != DIR_STRUCT) {
member->val = offset;
}
- if (size < member_size) {
- size = member_size;
- }
- if (!type) {
- offset += size;
+ size += member_size;
+ if (is_struct) {
+ offset += member_size;
}
}
ismember = 0;
@@ -211,9 +207,9 @@ uint16_t handle_struct(line **ln, uint64_t address, uint16_t offset, uint8_t dbg
}
*ln = l;
if (strct != NULL) {
- strct->val = offset;
+ strct->val = size;
}
- return (!type) ? offset : size;
+ return size;
}
uint64_t handle_directive(token *t, bytecount *bc, uint8_t isasm, uint64_t address, uint8_t dbg) {
@@ -619,6 +615,167 @@ void assemble(line *ln, bytecount *bc, uint8_t dbg) {
}
}
+static void find_dupsym() {
+ symbol *root = symbols;
+ symbol *s = symbols;
+ for (; s; s = s->next) {
+ root = symbols;
+ for (int i = 0; root; root = root->next) {
+ if (root == s) {
+ i++;
+ }
+ if (i > 1) {
+ printf("Found duplicate symbol, s->name: %s, root->name: %s\n", s->name, root->name);
+ i = 0;
+ }
+ }
+ }
+}
+
+static symbol *find_fixup(token *t) {
+ fixup* f = fixups;
+ for (; f && t != f->t; f = f->next);
+ return (f && t == f->t) ? f->s : NULL;
+}
+
+
+static void print_symval(symbol *s) {
+ if (s) {
+ if (s->down) {
+ print_symval(s->down);
+ }
+ if (s->name) {
+ printf("s->name: %s, s->val: $%"PRIX64"\n", s->name, s->val);
+ }
+ print_symval(s->next);
+ }
+}
+
+static void print_symtree(symbol *s, int depth) {
+ if (s) {
+ if (s->name != NULL) {
+ for (int i = depth; i; i--) {
+ printf("|%s", (i > 1) ? " " : "--");
+ }
+ printf("%s: $%"PRIX64"\n", s->name, s->val);
+ }
+ if (s->down != NULL) {
+ print_symtree(s->down, depth+1);
+ }
+ print_symtree(s->next, depth);
+ }
+}
+
+static void fix_symtree(line *l) {
+ symbol *s = symbols;
+ symbol *cur_sym = NULL;
+ symbol *sym_struct = NULL;
+ symbols = NULL;
+ last_sym = NULL;
+ int islocal = 0;
+ int isanon = 0;
+ int is_struct = 0;
+ int is_structsym = 0;
+ for (; l; l = l->next) {
+ token *t = l->tok;
+ token *lt = NULL;
+ for (; t; t = t->next) {
+ int ismember = (t->id == TOK_MEMBER);
+ switch (t->id) {
+ case TOK_STRUCT:
+ case TOK_UNION : islocal = !(is_struct == 1 && lt && lt->id == TOK_DIR);
+ case TOK_SYM :
+ if (t->id == TOK_SYM && t != l->tok) {
+ break;
+ }
+ case TOK_MEMBER:
+ case TOK_LABEL :
+ if (symbols) {
+ (!islocal && s && !s->up) ? (last_sym = s) : (last_loc = s);
+ }
+ if (((t->type == 1 || ismember) && !islocal) || (islocal && ismember && is_structsym)) {
+ is_structsym = 0;
+ last_loc = NULL;
+ islocal = 1;
+ cur_sym = s;
+ s->down = t->sym;
+ s->down->up = s;
+ s = s->down;
+ if (s) {
+ s->next = NULL;
+ s->prev = NULL;
+ s->down = NULL;
+ }
+ locals = s;
+ } else if ((islocal || t->type == 0)) {
+ if (t->type == 0 && !is_struct && islocal && !ismember) {
+ islocal = 0;
+ if (s) {
+ s->up->down = locals;
+ s = s->up;
+ }
+ }
+ symbol *tmp = s;
+ s = t->sym;
+ if (s) {
+ s->prev = (tmp && tmp != s) ? tmp : NULL;
+ s->up = (s->prev) ? s->prev->up : s->up;
+ }
+ if (s && s->next) {
+ s->next = NULL;
+ }
+ }
+ if (!islocal) {
+ last_loc = NULL;
+ (last_sym) ? (last_sym->next = s) : (symbols = s);
+ cur_sym = s;
+ if (last_sym) {
+ last_sym->next->prev = last_sym;
+ last_sym->next->up = last_sym->up;
+ last_sym->next->down = NULL;
+ }
+ } else {
+ (last_loc) ? (last_loc->next = s) : (locals = s);
+ if (last_loc) {
+ last_loc->next->prev = last_loc;
+ last_loc->next->up = last_loc->up;
+ last_loc->next->down = NULL;
+ } else {
+ locals->prev = NULL;
+ locals->down = NULL;
+ }
+ }
+ break;
+ case TOK_DIR:
+ if (t->type == DIR_STRUCT || t->type == DIR_UNION) {
+ is_struct++;
+ is_structsym = (t->next && (t->next->id == TOK_STRUCT || t->next->id == TOK_UNION));
+ if ((!is_structsym) || (isanon && is_structsym)) {
+ isanon++;
+ }
+ } else if (t->type == DIR_ENDSTRUCT || t->type == DIR_ENDUNION) {
+ is_struct--;
+ int skip = 0;
+ if (isanon > 0) {
+ if ((cur_sym->up && !cur_sym->up->isanon) || (sym_struct && sym_struct->isanon)) {
+ isanon--;
+ }
+ skip = (!isanon);
+ }
+ if ((int)(is_struct-isanon) > 0 && !skip && cur_sym->up) {
+ for (sym_struct = s->up; sym_struct->prev && !sym_struct->isanon; sym_struct = sym_struct->prev);
+ s = s->up;
+ cur_sym = (cur_sym->up != NULL) ? cur_sym->up : s;
+ }
+ }
+ break;
+ }
+ lt = t;
+ }
+ }
+}
+
+
static inline void free_tokens(token *t) {
token *tok;
if (t != NULL) {
@@ -640,44 +797,11 @@ void free_lines(line *l) {
}
}
-void print_symtree(symbol *s) {
- int depth = 0;
- int lol = 0;
- while (s) {
- for (int i = depth; i; i--) {
- putchar('|');
- if (i > 1) {
- printf(" ");
- }
- }
- if (depth) {
- printf("--");
- }
- if (s->name != NULL) {
- if (!strcmp(s->name, "printc")) {
- lol = 1;
- }
- printf("%s\n", s->name);
- }
- if (s->down != NULL) {
- s = s->down;
- depth++;
- continue;
- }
- if (s->next == NULL) {
- if (s->up != NULL) {
- for (; !s->next && s->up; s = s->up, depth--);
- }
- }
- s = s->next;
- }
-}
-
-void free_symbols(symbol *s) {
+static void free_symbols(symbol *s) {
symbol *sym;
sym = s;
if (sym != NULL) {
- if (s->down) {
+ if (s && s->down) {
free_symbols(s->down);
}
if (sym->name != NULL) {
@@ -702,14 +826,29 @@ static inline void free_fixups(fixup *f) {
}
}
+uint64_t get_tokmem(token *t) {
+ uint64_t i = 0;
+ for (; t; t = t->next, i++);
+ return i*sizeof(token);
+}
+
+void get_linemem(line *l) {
+ uint64_t i = 0;
+ uint64_t j = 0;
+ for (; l; j += get_tokmem(l->tok), l = l->next, i++);
+ printf("Bytes per line: %"PRIu64", Bytes per token: %"PRIu64", Total size of line table in bytes: %"PRIu64"\n", sizeof(line), sizeof(token), j+(i*sizeof(line)));
+}
+
void cleanup() {
uint16_t i;
if (lines) {
+ /*get_linemem(lines);*/
+ /*fix_symtree(lines);*/
free_lines(lines);
lines = NULL;
}
if (symbols) {
- /*print_symtree(symbols);*/
+ /*print_symtree(symbols, 0);*/
free_symbols(symbols);
symbols = NULL;
}
diff --git a/lexer.c b/lexer.c
index 1c9456e..e239a5e 100644
--- a/lexer.c
+++ b/lexer.c
@@ -8,6 +8,7 @@ token *last_tok = NULL;
symbol *locals = NULL;
symbol *last_loc = NULL;
symbol *cur_sym = NULL;
+symbol *struct_sym = NULL;
line *tmp_line = NULL;
@@ -228,6 +229,7 @@ line *find_line(uint32_t ln, uint8_t dbg) {
}
uint8_t is_struct = 0;
+uint8_t is_anon = 0;
uint64_t lex(char *str, uint64_t address, uint16_t bline, uint8_t dbg) {
char sym[0x100];
@@ -270,6 +272,7 @@ uint64_t lex(char *str, uint64_t address, uint16_t bline, uint8_t dbg) {
token *t = NULL;
token *lt = NULL;
symbol *tmp_sym = NULL;
+ symbol *tsym = NULL;
while (isdigit(str[i]) && isdelm(str[i], dbg) != 16) {
lnum[j++] = str[i++];
@@ -319,8 +322,6 @@ uint64_t lex(char *str, uint64_t address, uint16_t bline, uint8_t dbg) {
offset++;
if ((ptok == PTOK_S && toupper(str[i+1]) == 'P') || (ptok == PTOK_P && toupper(str[i+1]) == 'C')) {
offset++;
- } else if (ptok == PTOK_S || ptok == PTOK_P) {
-
}
switch (get_ptok(str[i+offset], dbg)) {
case PTOK_B :
@@ -331,6 +332,9 @@ uint64_t lex(char *str, uint64_t address, uint16_t bline, uint8_t dbg) {
case PTOK_ALPHA :
case PTOK_NUMBER: ptok = PTOK_ALPHA; break;
}
+ if ((ptok == PTOK_S && toupper(str[i+1]) != 'P') || (ptok == PTOK_P && toupper(str[i+1]) != 'C')) {
+ ptok = PTOK_ALPHA;
+ }
}
switch (ptok) {
case PTOK_DOT:
@@ -343,28 +347,49 @@ uint64_t lex(char *str, uint64_t address, uint16_t bline, uint8_t dbg) {
for (k = 0; k < 11; k++) {
if (tolower(lexeme[0]) == dir_t[k][0] && !strcasecmp(lexeme, dir_t[k])) {
lex_type = TOK_DIR;
+ uint16_t tmp = j;
+ for (j = 0; isdelm(str[i+j], dbg) & 16; j++);
+ uint8_t ret = get_ptok(str[i+j], dbg);
+ j = tmp;
+ if ((k == DIR_STRUCT || k == DIR_UNION) && (ret != PTOK_ALPHA || (is_anon && ret == PTOK_ALPHA))) {
+ is_anon++;
+ }
is_struct += (k == DIR_STRUCT || k == DIR_UNION);
is_struct -= (k == DIR_ENDSTRUCT || k == DIR_ENDUNION);
if ((k == DIR_ENDSTRUCT || k == DIR_ENDUNION)) {
- if (is_struct) {
+ int skip = 0;
+ if ((int)is_anon > 0) {
+ if ((cur_sym->up && !cur_sym->up->isanon) || (struct_sym && struct_sym->isanon)) {
+ is_anon--;
+ }
+ skip = (!is_anon);
+ }
+ if ((int)(is_struct-is_anon) > 0 && !skip && cur_sym->up) {
symbol *s = cur_sym;
for (; s->prev; s = s->prev) {
- if (s->up == NULL) {
+ if (s->up == NULL && cur_sym->up) {
s->up = cur_sym->up;
}
- printf("s: %p, last_loc: %p\n", s, last_loc);
+ if (dbg) {
+ printf("s: %p, s->up: %p, cur_sym->up: %p, last_loc: %p\n", s, s->up, cur_sym->up, last_loc);
+ }
}
for (s = locals; s; s = s->next) {
if (s->up == NULL) {
s->up = cur_sym;
}
+ if (dbg) {
+ printf("s: %p, s->up: %p, cur_sym: %p, last_loc: %p\n", s, s->up, cur_sym, last_loc);
+ }
}
if (cur_sym->down == NULL) {
cur_sym->down = locals;
}
cur_sym = cur_sym->up;
- for (locals = cur_sym->down; locals->prev; locals = locals->prev);
+ for (struct_sym = locals->up; struct_sym->prev && !struct_sym->isanon; struct_sym = struct_sym->prev);
+ for (locals = locals->up; locals->prev; locals = locals->prev);
for (last_loc = locals; last_loc->next; last_loc = last_loc->next);
+ } else if (!is_struct) {
}
}
break;
@@ -440,14 +465,14 @@ uint64_t lex(char *str, uint64_t address, uint16_t bline, uint8_t dbg) {
i += j;
value = strtoull(lexeme, NULL, base);
if (lt->id == TOK_SYM) {
- mksymbol(sym, value, 1, islocal, 0, 0, dbg);
+ tsym = mksymbol(sym, value, 1, islocal, 0, 0, dbg);
if (lt) {
lt->sym = get_sym(sym, address, lt, islocal, dbg);
}
if (!islocal) {
cur_sym = last_sym;
- /*last_loc = NULL;*/
}
+ tsym = NULL;
islocal = 0;
isfixup += (lt->sym == NULL);
if (dbg) {
@@ -595,7 +620,7 @@ uint64_t lex(char *str, uint64_t address, uint16_t bline, uint8_t dbg) {
lexeme[j] = ':';
lexeme[j+1] = '\0';
lex_type = TOK_LABEL;
- mksymbol(sym, address, 1, islocal, 0, 0, dbg);
+ tsym = mksymbol(sym, address, 1, islocal, 0, 0, dbg);
if (isfixup) {
isfixup = reslv_fixups(dbg);
}
@@ -605,14 +630,15 @@ uint64_t lex(char *str, uint64_t address, uint16_t bline, uint8_t dbg) {
lt->sym = get_sym(sym, address, t, islocal, dbg);
isfixup += (lt->sym == NULL);
}
- if (!islocal) {
- cur_sym = last_sym;
+ if (!islocal) {
+ cur_sym = last_sym;
locals = NULL;
- last_loc = NULL;
+ last_loc = NULL;
} else if (cur_sym->down == NULL && cur_sym == last_sym) {
- cur_sym->down = locals;
- cur_sym->down->up = cur_sym;
+ cur_sym->down = locals;
+ cur_sym->down->up = cur_sym;
}
+ tsym = NULL;
islocal = 0;
if (dbg) {
printf("lex(): isfixup: %u\n", isfixup);
@@ -678,7 +704,8 @@ uint64_t lex(char *str, uint64_t address, uint16_t bline, uint8_t dbg) {
if (!isop) {
uint8_t spaces = 0;
for (; isdelm(str[i+spaces], dbg) == 16; spaces++);
- if (get_ptok(str[i+spaces], dbg) == PTOK_COLON) {
+ uint8_t ret = get_ptok(str[i+spaces], dbg);
+ if (ret == PTOK_COLON || ret == PTOK_EQU) {
islocal = (lex_type == TOK_LOCAL);
}
lex_type = TOK_SYM;
@@ -694,18 +721,26 @@ uint64_t lex(char *str, uint64_t address, uint16_t bline, uint8_t dbg) {
if (isfixup) {
isfixup = reslv_fixups(dbg);
}
- t->sym = get_sym(sym, 0, t, islocal, dbg);
+ t->sym = get_sym(sym, 0, t, islocal, dbg);
if (lt && lt->id == TOK_DIR) {
t->sym->isstruct = 1;
t->id = (lt->type == DIR_STRUCT) ? TOK_STRUCT : TOK_UNION;
tmp_line = l;
} else {
t->id = TOK_MEMBER;
+ t->sym->isanon = (is_anon > 0);
}
isfixup += (t->sym == NULL);
+ int is_top = (cur_sym == NULL);
cur_sym = (!islocal && !cur_sym) ? last_sym : cur_sym;
if (!islocal) {
- cur_sym->down = locals;
+ if (!is_top) {
+ cur_sym = t->sym;
+ locals = NULL;
+ last_loc = NULL;
+ } else {
+ cur_sym->down = locals;
+ }
} else {
if (lt && lt->id == TOK_DIR) {
if (lt->type == DIR_UNION || lt->type == DIR_STRUCT) {
diff --git a/programs/sub-suite/declare.s b/programs/sub-suite/declare.s
index 166197b..cd97b60 100644
--- a/programs/sub-suite/declare.s
+++ b/programs/sub-suite/declare.s
@@ -1,4 +1,70 @@
+; Structs, and unions.
+
+; Line struct.
+.struct ln
+ next .qword ; Pointer to next line.
+ tok .qword ; The tokens for this line.
+
+ bline .word ; Number of blank lines.
+ lnum .dword ; Line number.
+
+ addr .qword ; The address of this line.
+.endstruct
+
+; Token struct.
+.struct tok
+ ;ptype .byte ; Pointer type, 0 for token, -1 for end of token.
+ next .qword ; Pointer to next token.
+ id .byte ; Token ID.
+ type .byte ; Token type ID.
+
+ tabs .byte ; Number of tabs.
+ spaces .byte ; Number of spaces.
+ stab .byte ; Number of sub-token tabs.
+ sspace .byte ; Number of sub-token spaces.
+ digits .byte ; Number of digits.
+
+ .union ; Token value.
+ sym .qword ; Symbol.
+ str .qword ; String.
+ val .qword ; Value.
+ .endunion
+.endstruct
+
+; Fixup struct.
+.struct fix
+ next .qword ; Pointer to next fixup.
+
+ s .qword ; Unresolved symbol.
+ t .qword ; Token that used the unresolved symbol.
+
+ addr .qword ; Address of where it happened.
+.endstruct
+
+; Symbol struct.
+.struct sym
+ next .qword ; Pointer to next symbol.
+ prev .qword ; Pointer to previous symbol.
+ down .qword ; Pointer to child symbol.
+ up .qword ; Pointer to parent symbol.
+
+ val .qword ; Value of symbol.
+
+ strct .byte ; Flag that says this symbol is a struct, or union.
+ def .byte ; Flag that says this symbol has been defined.
+
+ name .qword ; Name of symbol.
+ id .word ; ID of symbol.
+.endstruct
+
+; Instruction struct.
+.struct instr
+ am .word ; Addressing modes.
+ op .byte ; Base value used to get the actual opcode.
+.endstruct
+
+
; Enums.
; I/O constants.
@@ -95,6 +161,7 @@ INDX2 = 1 << 11 ; Special case of INDX that uses the indirect table.
ZM2 = 1 << 12 ; Special case of Zero Matrix used by JMP, and JSR.
+
; RAM declarations.
; Linewrap table.
@@ -257,22 +324,22 @@ lexeme:
.res $100
; Symbol table.
-sym:
+symbol:
.res $8000
; Fixup table.
; Fixups are unresolved symbols.
-fix:
+fixup:
.res $2000
; ROM data declarations.
.org $A000
; String Literals/Constants.
-tok:
- .byte "dab"
-msg:
- .byte "oof, you divided a, and b on me.\n"
+;tok:
+; .byte "dab"
+;msg:
+; .byte "oof, you divided a, and b on me.\n"
ed_name:
.byte "SuBEditor"
@@ -714,7 +781,7 @@ cmd_srt:
.word list
.word asm
.word help
- .word inst
+ .word ins
.word run
.word set
diff --git a/programs/sub-suite/subasm.s b/programs/sub-suite/subasm.s
index ec58a40..3957caa 100644
--- a/programs/sub-suite/subasm.s
+++ b/programs/sub-suite/subasm.s
@@ -161,10 +161,10 @@ help:
nop ;
@end:
rts ; End of help.
-inst:
+ins:
nop ;
@end:
- rts ; End of inst.
+ rts ; End of ins.
run:
nop ;
@end:
diff --git a/programs/sub-suite/subeditor.s b/programs/sub-suite/subeditor.s
index aec613e..fdf1e4b 100644
--- a/programs/sub-suite/subeditor.s
+++ b/programs/sub-suite/subeditor.s
@@ -91,10 +91,10 @@ read:
bra read ; Keep looping.
parse:
- lda #0 ;
- tax ;
- jsr subasm ;
- bra start ;
+ and #0 ; Reset A.
+ tax ; Reset X.
+ jsr subasm ; Call SuBAsm, and start parsing this line.
+ bra start ; Go back to reading the keyboard.
getchar:
diff --git a/sux.c b/sux.c
index 1131210..2be2875 100644
--- a/sux.c
+++ b/sux.c
@@ -138,6 +138,7 @@ static inline uint8_t isread(uint8_t opcode) {
}
}
+#if bench
void stop_timer() {
time_done = 1;
}
@@ -159,6 +160,7 @@ void start_timer(int sec, int usec) {
exit(1);
}
}
+#endif
void *run(void *args) {
struct suxthr *thr = (void *)args;
diff --git a/sux.h b/sux.h
index 2432322..1f87be3 100644
--- a/sux.h
+++ b/sux.h
@@ -54,13 +54,15 @@ extern void io(uint64_t address, uint8_t rw);
extern void init_scr();
-static void *memcopy(void *dst, void *src, unsigned int n) {
+static void *memcopy(void *restrict dst, const void *restrict src, unsigned int n) {
#if copy64
- uint64_t *d = dst, *s = src;
+ uint64_t *d = dst;
+ const uint64_t *s = src;
unsigned int r = n % 8;
n /= 8;
#else
- uint8_t *d = dst, *s = src;
+ uint8_t *d = dst;
+ const uint8_t *s = src;
#endif
for (; n; *d++ = *s++, n--);
#if copy64
@@ -72,6 +74,7 @@ static void *memcopy(void *dst, void *src, unsigned int n) {
return dst;
}
+
static inline uint64_t read_value(struct sux *cpu, uint64_t reg, uint64_t address, uint8_t size, uint8_t inc_clk, uint8_t check_io) {
#if (IO || debug) && !branch
#if keypoll
diff --git a/test/struct.s b/test/struct.s
index dce527d..33de1f1 100644
--- a/test/struct.s
+++ b/test/struct.s
@@ -11,9 +11,52 @@
why .word
.endstruct
.endunion
+ .union
+ alkjf .byte
+ lksfja .word
+ .struct a
+ asd .byte
+ dd .byte
+ .struct
+ sdd .byte
+ aas .byte
+ .union no
+ asd .byte
+ ss .word
+ .endunion
+ .endstruct
+ .endstruct
+ aad .byte
+ .endunion
why .word
.endstruct
+.struct oof
+ lol .word
+ .union
+ .struct asd
+ s .word
+ f .byte
+ e .word
+ .endstruct
+ .struct a
+ asd .byte
+ dd .byte
+ .struct
+ sdd .byte
+ aas .byte
+ .union no
+ asd .byte
+ ss .word
+ .endunion
+ .endstruct
+ .endstruct
+ as .word
+ ll .word
+ .endunion
+ ass .word
+.endstruct
+
.org 0
@@ -26,6 +69,6 @@ ldb #lol.asd.aa.lol
ldx #lol.asd.aa.why
ldy #lol.why
a
-l a
-v
+;l a
+;v
q