string: Added new .strp directive. master origin/HEAD origin/master
authorLukas Krickl <lukas@krickl.dev>
Mon, 27 Apr 2026 07:54:43 +0000 (09:54 +0200)
committerLukas Krickl <lukas@krickl.dev>
Mon, 27 Apr 2026 07:54:43 +0000 (09:54 +0200)
This directive allows the user to create a string of at least n bytes
length.

makefile
man/ulas.1
man/ulas.5
src/test.c
src/ulas.c
src/ulas.h
tests/strp.bin [new file with mode: 0644]
tests/strp.s [new file with mode: 0644]

index c2e00f862e556bcc05dffc73f7441151b268d2af..7602651e4762d1913e11b4d6024799031e7f0063 100644 (file)
--- a/makefile
+++ b/makefile
@@ -60,3 +60,4 @@ buildtests: bin
        ./$(NAME) tests/multiline.s -D ULAS_PREDEF -l - -o tests/multiline.bin
        ./$(NAME) tests/t0.bin -d - -o tests/t0_dasm.s
        ./$(NAME) tests/macroexpandnested.s  -o tests/macroexpandnested.bin
+       ./$(NAME) tests/strp.s  -o tests/strp.bin
index 35e477f889b7c27851f17ad64ea535fe01802732..9145073bf0f0c98fd2f9c0c74995b30f3e25ffed 100644 (file)
@@ -1,7 +1,7 @@
 .\" Manpage for ulas.
 .\" Contact lukas@krickl.dev to correct errors or typos.
 
-.TH man 1 "19 January 2025" "0.0.1" "ulas manual"
+.TH man 1 "27 April 2026" "1.1.0" "ulas manual"
 
 .SH NAME
   ulas
index 30b093f7621900f639e952ef7cab412f72460b9a..3a60b233cafeb05e10bb2d7bd88ec0c3bd3f8218 100644 (file)
@@ -1,7 +1,7 @@
 .\" Manpage for ulas.
 .\" Contact lukas@krickl.dev to correct errors or typos.
 
-.TH man 5 "19 January 2025" "0.0.1" "ulas language reference"
+.TH man 5 "27 April 2026" "1.1.0" "ulas language reference"
 
 .SH PREPROCESSOR 
 
@@ -92,6 +92,12 @@ The special value $ will evaluate to the current address.
   \.str "String"
   Defines a literal string
 
+.SH strp
+  \.strp <n>, "String"
+  Defines a literal string.
+       Ensures the resulting string is at least <n> bytes long.
+       The remaining bytes are padded with 00.
+
 .SH fill
   \.fill <value>, <n>
   \.fill <value>, $ - n
index 043aabfdb88302176b0c511f8043e034e521d615..a9addfe95819c04384c27de59f7d9d281e43bb34 100644 (file)
@@ -435,6 +435,7 @@ void test_full_asm(void) {
   ASSERT_FULL_ASM(0, "tests/multiline.s", "tests/multiline.bin");
   ASSERT_FULL_ASM(0, "tests/macroexpandnested.s", 
                        "tests/macroexpandnested.bin");
+  ASSERT_FULL_ASM(0, "tests/strp.s", "tests/strp.bin");
 
   TESTEND("testfullasm");
 }
index 16f11ef84cdbd6dc348c1be79fbb6305186ef137..c052052e5d502a89d7ae4e02a3cc18b37a4dfd2e 100644 (file)
@@ -2694,7 +2694,8 @@ int ulas_asmdirfill(FILE *dst, const char **line, unsigned long n, int *rc) {
   return written;
 }
 
-int ulas_asmdirstr(FILE *dst, const char **line, unsigned long n, int *rc) {
+int ulas_asmdirstr_and_pad(FILE *dst, const char **line, unsigned long n, int *rc, 
+               unsigned int pad_to) {
   /* .str expr, expr, expr */
   struct ulas_tok t;
        int i;
@@ -2714,8 +2715,14 @@ int ulas_asmdirstr(FILE *dst, const char **line, unsigned long n, int *rc) {
     for (i = 0; i < (int)len; i++) {
       s[i] = ulas.charcodemap[(int)s[i]];
     }
+    
+               ulas_asmout(dst, s, len);
+
+               for (i = pad_to-len; i > 0; i--) {
+                       ulas_asmout(dst, "\0", 1);
+                       written++;
+               }
 
-    ulas_asmout(dst, s, len);
 
     written += len;
     if (ulas_tok(&ulas.tok, line, n) > 0) {
@@ -2728,6 +2735,40 @@ int ulas_asmdirstr(FILE *dst, const char **line, unsigned long n, int *rc) {
   return (int)written;
 }
 
+int ulas_asmdirstr(FILE *dst, const char **line, unsigned long n, int *rc) {
+       return ulas_asmdirstr_and_pad(dst, line, n, rc, 0);
+}
+
+int ulas_asmdirstr_pad(FILE *dst, const char **line, unsigned long n, int *rc) {
+       int written;
+       int pad_n;
+       struct ulas_tok t;
+       
+
+  ULAS_EVALEXPRS_BEGIN
+               pad_n = ulas_intexpr(line, n, rc);
+       ULAS_EVALEXPRS_END
+
+  if (*rc == -1) {
+    return 0;
+  }
+
+  ulas_tok(&ulas.tok, line, n);
+  t =
+      ulas_totok(ulas.tok.buf, ulas_strnlen(ulas.tok.buf, ulas.tok.maxlen), rc);
+
+  if (*rc == -1 || t.type != ',') {
+    ULASERR("Expected ,\n");
+    return 0;
+  }
+
+
+       written = ulas_asmdirstr_and_pad(dst, line, n, rc, pad_n);
+
+       return written;
+}
+
+
 int ulas_asmdirincbin(FILE *dst, const char **line, unsigned long n, int *rc) {
   char *path = ulas_strexpr(line, n, rc);
   char buf[256];
@@ -2992,7 +3033,8 @@ int ulas_asmline(FILE *dst, FILE *src, const char *line, unsigned long n) {
                              ULAS_ASMSTR_SETCHRCODE,   ULAS_ASMSTR_CHR,
                              ULAS_ASMSTR_REP,          ULAS_ASMSTR_SECTION,
                              ULAS_ASMSTR_BANK,         ULAS_ASMSTR_BEGIN_SCOPE,
-                             ULAS_ASMSTR_END_SCOPE,    NULL};
+                             ULAS_ASMSTR_END_SCOPE,    ULAS_ASMSTR_STR_PAD,
+                                                                                                                NULL};
     enum ulas_asmdir dirs[] = {
         ULAS_ASMDIR_ORG,          ULAS_ASMDIR_SET,
         ULAS_ASMDIR_BYTE,         ULAS_ASMDIR_STR,
@@ -3003,7 +3045,7 @@ int ulas_asmline(FILE *dst, FILE *src, const char *line, unsigned long n) {
         ULAS_ASMDIR_SETCHRCODE,   ULAS_ASMDIR_CHR,
         ULAS_ASMDIR_REP,          ULAS_ASMDIR_SECTION,
         ULAS_ASMDIR_BANK,         ULAS_ASMDIR_BEGIN_SCOPE,
-        ULAS_ASMDIR_END_SCOPE};
+        ULAS_ASMDIR_END_SCOPE, ULAS_ASMDIR_STR_PAD};
 
     enum ulas_asmdir dir = ULAS_ASMDIR_NONE;
 
@@ -3045,6 +3087,9 @@ int ulas_asmline(FILE *dst, FILE *src, const char *line, unsigned long n) {
     case ULAS_ASMDIR_STR:
       other_writes += ulas_asmdirstr(dst, &line, n, &rc);
       break;
+    case ULAS_ASMDIR_STR_PAD:
+      other_writes += ulas_asmdirstr_pad(dst, &line, n, &rc);
+      break;
     case ULAS_ASMDIR_INCBIN:
       other_writes += ulas_asmdirincbin(dst, &line, n, &rc);
       break;
index 1636b7b5430d4009fdada9dd7176eb76c694c918..c648d068c3f711163a8dc9fad9fafdc2ee15d30e 100644 (file)
@@ -7,7 +7,7 @@
 #include "archs.h"
 
 #define ULAS_NAME "ulas"
-#define ULAS_VER "1.0.0"
+#define ULAS_VER "1.1.0"
 
 /* args without value */
 #define ULAS_OPTS "hvVpdA"
@@ -65,6 +65,7 @@ extern unsigned long defslen;
 #define ULAS_ASMSTR_SET ".set"
 #define ULAS_ASMSTR_BYTE ".db"
 #define ULAS_ASMSTR_STR ".str"
+#define ULAS_ASMSTR_STR_PAD ".strp"
 #define ULAS_ASMSTR_FILL ".fill"
 #define ULAS_ASMSTR_PAD ".pad"
 #define ULAS_ASMSTR_INCBIN ".incbin"
@@ -502,7 +503,13 @@ enum ulas_asmdir {
   /* .endscope 
    * decrements scope index by 1
         */
-  ULAS_ASMDIR_END_SCOPE
+  ULAS_ASMDIR_END_SCOPE,
+
+       /* .strp <n>, "<str>"
+        * same as .str but pads with 00 bytes up to n 
+        * bytes
+        */
+       ULAS_ASMDIR_STR_PAD
 };
 
 #define ULAS_INSTRTOKMAX 16
diff --git a/tests/strp.bin b/tests/strp.bin
new file mode 100644 (file)
index 0000000..89728aa
Binary files /dev/null and b/tests/strp.bin differ
diff --git a/tests/strp.s b/tests/strp.s
new file mode 100644 (file)
index 0000000..7c35b54
--- /dev/null
@@ -0,0 +1,2 @@
+.strp 8, "123"
+.db 0xFF