summaryrefslogtreecommitdiff
path: root/lexer.c
diff options
context:
space:
mode:
Diffstat (limited to 'lexer.c')
-rw-r--r--lexer.c69
1 files changed, 52 insertions, 17 deletions
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) {