From: Lukas Krickl Date: Fri, 15 Dec 2023 08:14:18 +0000 (+0100) Subject: Added .de and .se for simple enum-like definitions X-Git-Url: https://git.krickl.dev/?a=commitdiff_plain;h=f2a63d792b6ba8ed4f32bcfe346b3668531efd39;p=ulas%2F.git Added .de and .se for simple enum-like definitions --- diff --git a/include/ulas.h b/include/ulas.h index 1b9ec11..8ea8f14 100644 --- a/include/ulas.h +++ b/include/ulas.h @@ -46,6 +46,8 @@ #define ULAS_ASMSTR_DEF ".def" #define ULAS_ASMSTR_CHKSM ".chksm" #define ULAS_ASMSTR_ADV ".adv" +#define ULAS_ASMSTR_SET_ENUM_DEF ".se" +#define ULAS_ASMSTR_DEFINE_ENUM ".de" // configurable tokens #define ULAS_TOK_COMMENT ';' @@ -245,6 +247,7 @@ struct ulas { struct ulas_symbuf syms; unsigned int address; + int enumv; // current scope index // each global-label increments the scope @@ -374,6 +377,13 @@ enum ulas_asmdir { // .adv // advance .org by n bytes without writing to rom ULAS_ASMDIR_ADV, + // .setenum + // sets the internal _ENUM counter + ULAS_ASMDIR_SET_ENUM_DEF, + // .de + // acts like .def but sets the value to the current _ENUM counter + // and increments it by size + ULAS_ASMDIR_DEFINE_ENUM, }; // amount of registers diff --git a/src/main.c b/src/main.c index c5a24c0..94d7b8b 100644 --- a/src/main.c +++ b/src/main.c @@ -12,7 +12,8 @@ * TODO: Write documentation * TODO: process defined variables inside defines correctly * TODO: Implement struct, union and enum syntax - * TODO: Add warning levels such as: warning when literal is too large for register with -w syntax + * TODO: Add warning levels such as: warning when literal is too large for + * register with -w syntax */ #define ULAS_NAME "ulas" diff --git a/src/ulas.c b/src/ulas.c index b622d4d..d8ed1f2 100644 --- a/src/ulas.c +++ b/src/ulas.c @@ -294,9 +294,10 @@ int ulas_symbolset(const char *cname, int scope, struct ulas_tok tok, if (!existing) { // def new symbol - struct ulas_sym new_sym = {strndup(name, len), tok, scope, ulas.pass, constant}; + struct ulas_sym new_sym = {strndup(name, len), tok, scope, ulas.pass, + constant}; ulas_symbufpush(&ulas.syms, new_sym); - + rc = ulas_symbolout(ulassymout, &new_sym); } else if (existing->lastdefin != ulas.pass || !existing->constant) { // redefine if not defined this pass @@ -2344,6 +2345,40 @@ int ulas_asmdirdef(const char **line, unsigned long n) { return ulas_asmdirset(line, n, t); } +int ulas_asmdirdefenum(const char **line, unsigned long n) { + char name[ULAS_SYMNAMEMAX]; + ulas_tok(&ulas.tok, line, n); + if (!ulas_isname(ulas.tok.buf, ulas.tok.maxlen)) { + ULASERR("Unexpected token '%s'\n", ulas.tok.buf); + return -1; + } + strncpy(name, ulas.tok.buf, ULAS_SYMNAMEMAX); + + // consume , + ulas_tok(&ulas.tok, line, n); + if (strncmp(ulas.tok.buf, ",", ulas.tok.maxlen) != 0) { + ULASERR("Unexpected token '%s'. Expected ','\n", ulas.tok.buf); + return -1; + } + + union ulas_val val = {0}; + val.intv = ulas.enumv; + + int rc = 0; + ulas.enumv += ulas_intexpr(line, n, &rc); + if (rc == -1) { + goto fail; + } + struct ulas_tok tok = {ULAS_INT, val}; + + if (ulas.pass == ULAS_PASS_FINAL) { + // only really define in final pass + ulas_symbolset(name, -1, tok, 1); + } +fail: + return rc; +} + int ulas_asmdirfill(FILE *dst, const char **line, unsigned long n, int *rc) { // fill , int written = 0; @@ -2432,6 +2467,11 @@ int ulas_asmdiradv(FILE *dst, const char **line, unsigned long n, int *rc) { return 0; } +int ulas_asmdirsetenum(FILE *dst, const char **line, unsigned long n, int *rc) { + ULAS_EVALEXPRS(ulas.enumv = ulas_intexpr(line, strnlen(*line, n), rc)); + return 0; +} + int ulas_asmline(FILE *dst, FILE *src, const char *line, unsigned long n) { // this buffer is written both to dst and to verbose output char outbuf[ULAS_OUTBUFMAX]; @@ -2476,11 +2516,14 @@ int ulas_asmline(FILE *dst, FILE *src, const char *line, unsigned long n) { ULAS_ASMSTR_DEF, ULAS_ASMSTR_CHKSM, ULAS_ASMSTR_ADV, + ULAS_ASMSTR_SET_ENUM_DEF, + ULAS_ASMSTR_DEFINE_ENUM, NULL}; enum ulas_asmdir dirs[] = { - ULAS_ASMDIR_ORG, ULAS_ASMDIR_SET, ULAS_ASMDIR_BYTE, ULAS_ASMDIR_STR, - ULAS_ASMDIR_FILL, ULAS_ASMDIR_PAD, ULAS_ASMDIR_INCBIN, ULAS_ASMDIR_DEF, - ULAS_ASMDIR_CHKSM, ULAS_ASMDIR_ADV}; + ULAS_ASMDIR_ORG, ULAS_ASMDIR_SET, ULAS_ASMDIR_BYTE, + ULAS_ASMDIR_STR, ULAS_ASMDIR_FILL, ULAS_ASMDIR_PAD, + ULAS_ASMDIR_INCBIN, ULAS_ASMDIR_DEF, ULAS_ASMDIR_CHKSM, + ULAS_ASMDIR_ADV, ULAS_ASMDIR_SET_ENUM_DEF, ULAS_ASMDIR_DEFINE_ENUM}; enum ulas_asmdir dir = ULAS_ASMDIR_NONE; @@ -2529,6 +2572,12 @@ int ulas_asmline(FILE *dst, FILE *src, const char *line, unsigned long n) { case ULAS_ASMDIR_ADV: ulas_asmdiradv(dst, &line, n, &rc); break; + case ULAS_ASMDIR_SET_ENUM_DEF: + ulas_asmdirsetenum(dst, &line, n, &rc); + break; + case ULAS_ASMDIR_DEFINE_ENUM: + rc = ulas_asmdirdefenum(&line, n); + break; case ULAS_ASMDIR_PAD: // TODO: pad is the same as .fill n, $ - n case ULAS_ASMDIR_NONE: diff --git a/tests/t0.bin b/tests/t0.bin index c6b2e04..86f977a 100644 Binary files a/tests/t0.bin and b/tests/t0.bin differ diff --git a/tests/t0.s b/tests/t0.s index c68724f..8e4ec05 100644 --- a/tests/t0.s +++ b/tests/t0.s @@ -114,3 +114,9 @@ l3: .db 1 .def int dbtest = 0x213 .db (dbtest & 0xFF) .db (dbtest >> 8) & 0xFF + +.se 0x21 +.de de1, 2 +.de de2, 1 + ld a, de1 + ld a, de2