From 48be0c55b20f9cc2db18441226fce2876ac3d364 Mon Sep 17 00:00:00 2001 From: Lukas Krickl Date: Sun, 24 Dec 2023 16:44:45 +0100 Subject: [PATCH] Added basic .rep directive --- include/ulas.h | 3 ++- src/ulas.c | 63 ++++++++++++++++++++++++++++++++++++------------- tests/t0.bin | Bin 186 -> 189 bytes tests/t0.s | 2 ++ 4 files changed, 50 insertions(+), 18 deletions(-) diff --git a/include/ulas.h b/include/ulas.h index c05bfbf..b06e5fb 100644 --- a/include/ulas.h +++ b/include/ulas.h @@ -411,7 +411,7 @@ enum ulas_asmdir { // it requires up to 8 integer expressions between 0 and 3 ULAS_ASMDIR_CHR, // .rep , , - // repeats a line n times + // repeats a line n times ULAS_ASMDIR_REP, }; @@ -629,6 +629,7 @@ int ulas_asminstr(char *dst, unsigned long max, const char **line, // -1 on error int ulas_asmnext(FILE *dst, FILE *src, char *buf, int n); int ulas_asm(FILE *dst, FILE *src); +int ulas_asmline(FILE *dst, FILE *src, const char *line, unsigned long n); // parses and executes a 32 bit signed int math expressions int ulas_intexpr(const char **line, unsigned long n, int *rc); diff --git a/src/ulas.c b/src/ulas.c index 67c4385..0a11ad1 100644 --- a/src/ulas.c +++ b/src/ulas.c @@ -2584,6 +2584,41 @@ int ulas_asmdirchr(FILE *dst, const char **line, unsigned long n, int *rc) { return written; } +int ulas_asmdirrep(FILE *dst, FILE *src, const char **line, unsigned long n) { + int repval = 0; + int rc = 0; + + ULAS_EVALEXPRS(repval = ulas_intexpr(line, n, &rc)); + ulas_tok(&ulas.tok, line, n); + struct ulas_tok t = + ulas_totok(ulas.tok.buf, strnlen(ulas.tok.buf, ulas.tok.maxlen), &rc); + if (rc == -1 || t.type != ',') { + ULASERR("Expected ,\n"); + return 0; + } + + int step = 0; + ULAS_EVALEXPRS(step = ulas_intexpr(line, n, &rc)); + ulas_tok(&ulas.tok, line, n); + t = ulas_totok(ulas.tok.buf, strnlen(ulas.tok.buf, ulas.tok.maxlen), &rc); + if (rc == -1 || t.type != ',') { + ULASERR("Expected ,\n"); + return 0; + } + + unsigned long argline_len = strlen(*line); + + for (int i = 0; i < repval; i += step) { + rc = ulas_asmline(dst, src, *line, argline_len); + if (rc == -1) { + break; + } + } + + *line += argline_len; + return rc; +} + 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]; @@ -2618,22 +2653,14 @@ int ulas_asmline(FILE *dst, FILE *src, const char *line, unsigned long n) { } if (ulas.tok.buf[0] == ULAS_TOK_ASMDIR_BEGIN) { - const char *dirstrs[] = {ULAS_ASMSTR_ORG, - ULAS_ASMSTR_SET, - ULAS_ASMSTR_BYTE, - ULAS_ASMSTR_STR, - ULAS_ASMSTR_FILL, - ULAS_ASMSTR_PAD, - ULAS_ASMSTR_INCBIN, - ULAS_ASMSTR_DEF, - ULAS_ASMSTR_CHKSM, - ULAS_ASMSTR_ADV, - ULAS_ASMSTR_SET_ENUM_DEF, - ULAS_ASMSTR_DEFINE_ENUM, - ULAS_ASMSTR_SETCHRCODE, - ULAS_ASMSTR_CHR, - ULAS_ASMSTR_REP, - NULL}; + const char *dirstrs[] = {ULAS_ASMSTR_ORG, ULAS_ASMSTR_SET, + ULAS_ASMSTR_BYTE, ULAS_ASMSTR_STR, + ULAS_ASMSTR_FILL, ULAS_ASMSTR_PAD, + ULAS_ASMSTR_INCBIN, ULAS_ASMSTR_DEF, + ULAS_ASMSTR_CHKSM, ULAS_ASMSTR_ADV, + ULAS_ASMSTR_SET_ENUM_DEF, ULAS_ASMSTR_DEFINE_ENUM, + ULAS_ASMSTR_SETCHRCODE, ULAS_ASMSTR_CHR, + ULAS_ASMSTR_REP, NULL}; enum ulas_asmdir dirs[] = { ULAS_ASMDIR_ORG, ULAS_ASMDIR_SET, ULAS_ASMDIR_BYTE, ULAS_ASMDIR_STR, @@ -2641,7 +2668,8 @@ int ulas_asmline(FILE *dst, FILE *src, const char *line, unsigned long n) { ULAS_ASMDIR_INCBIN, ULAS_ASMDIR_DEF, ULAS_ASMDIR_CHKSM, ULAS_ASMDIR_ADV, ULAS_ASMDIR_SET_ENUM_DEF, ULAS_ASMDIR_DEFINE_ENUM, - ULAS_ASMDIR_SETCHRCODE, ULAS_ASMDIR_CHR, ULAS_ASMDIR_REP}; + ULAS_ASMDIR_SETCHRCODE, ULAS_ASMDIR_CHR, + ULAS_ASMDIR_REP}; enum ulas_asmdir dir = ULAS_ASMDIR_NONE; @@ -2703,6 +2731,7 @@ int ulas_asmline(FILE *dst, FILE *src, const char *line, unsigned long n) { other_writes += ulas_asmdirchr(dst, &line, n, &rc); break; case ULAS_ASMDIR_REP: + rc = ulas_asmdirrep(dst, src, &line, n); break; case ULAS_ASMDIR_PAD: // TODO: pad is the same as .fill n, $ - n diff --git a/tests/t0.bin b/tests/t0.bin index 612d93adb5f4783ef8949eff6d2bbfa8334aaae0..d480d73b283696097da413d86de46765d34ebc83 100644 GIT binary patch delta 10 RcmdnRxR-IlF6OebG5{AC1StRj delta 6 NcmdnXxQlVZE&vHW0>l6S diff --git a/tests/t0.s b/tests/t0.s index 93ad7b8..296c6fd 100644 --- a/tests/t0.s +++ b/tests/t0.s @@ -130,3 +130,5 @@ l3: .db 1 .str "abc" .db 1, 2, 3 .chr 01233213 + +.rep 6, 2, halt -- 2.30.2