]> git.mar77i.info Git - shitscript/commitdiff
use growable_append, add print builtin
authormar77i <mar77i@protonmail.ch>
Tue, 19 Nov 2024 10:21:58 +0000 (11:21 +0100)
committermar77i <mar77i@protonmail.ch>
Tue, 19 Nov 2024 10:21:58 +0000 (11:21 +0100)
growable.c
growable.h
parser.c
runtime.c
shitscript.c
shitscript.h

index a05dfc2ec63771fea4f41e902f8fd4213f329406..05567b8eec53ab56e1cf72813fdde06572a003a6 100644 (file)
@@ -2,6 +2,7 @@
 // growable.c
 
 #include <stdio.h>
+#include <string.h>
 
 #include "growable.h"
 
     v++; \
 } while(0)
 
-int growable_grow(struct growable *g, size_t len) {
+int growable_append(struct growable *g, void *item) {
+    size_t old_len = g->len++;
     void *np;
-    if (len < g->allo)
-        return 0;
-    if (g->allo == 0)
-        g->allo = 8;
-    else {
-        ROUND_UP_TO_POW2(len);
-        g->allo = len;
+    if (g->len > g->allo) {
+        if (g->allo == 0)
+            g->allo = 8;
+        else {
+            g->allo = g->len;
+            ROUND_UP_TO_POW2(g->allo);
+        }
+        np = realloc(g->data, g->allo * g->item_size);
+        if (np == NULL) {
+            perror("realloc");
+            return -1;
+        }
+        g->data = np;
     }
-    np = realloc(g->data, g->allo * g->item_size);
-    if (np == NULL) {
-        perror("realloc");
-        return -1;
-    }
-    g->data = np;
+    memcpy((char*)g->data + old_len * g->item_size, item, g->item_size);
     return 0;
 }
 
index ae98ae9b7081585e2f23a5ffa2abc322550947d1..ac67a6f455cf7dfb9d34a122f578377efb14d1b4 100644 (file)
@@ -14,7 +14,7 @@ struct growable {
 #define EMPTY_GROWABLE(is) \
     ((struct growable){ .item_size = (is), .len = 0, .allo = 0, .data = NULL })
 
-int growable_grow(struct growable *g, size_t len);
+int growable_append(struct growable *g, void *item);
 void growable_cleanup(const struct growable g);
 
 #define GROWABLE_AT(g, t, i) (((t*)(g).data)[i])
index e5d7d2d73c37c7088d57bc54a2d5ae56844167e4..8ef121bdb836f27a68cd7c4d0a4ba0ae88fdde29 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -29,18 +29,18 @@ static inline int read_ident_or_keyword(
 ) {
     buffer->len = 0;
     do {
-        if (growable_grow(buffer, buffer->len + 1) < 0)
+        if (growable_append(buffer, &c) < 0)
             return -1;
-        ((char*)buffer->data)[buffer->len++] = c;
         c = getc(fh);
     } while (isalnum(c) || c == '_');
     if (c != EOF)
         ungetc(c, fh);
-    if (growable_grow(buffer, buffer->len + 1) < 0)
-        return -1;
     if (buffer->len == 4 && strncasecmp(buffer->data, "goto", 4) == 0) {
         ai->type = AST_ITEM_GOTO;
         return 0;
+    } else if (buffer->len == 5 && strncasecmp(buffer->data, "print", 5) == 0) {
+        ai->type = AST_ITEM_PRINT;
+        return 0;
     }
     ai->type = AST_ITEM_IDENT;
     ai->u.s = strndup(buffer->data, buffer->len);
@@ -55,7 +55,7 @@ int parse_input(FILE *fh, struct program *p) {
     int c;
     struct ast_item ai;
     while ((c = getc(fh)) != EOF) {
-        memset(&ai.u, 0, sizeof ai.u);
+        memset(&ai, 0, sizeof ai);
         switch (c) {
         case '+':
             ai.type = AST_ITEM_PLUS;
@@ -77,13 +77,12 @@ int parse_input(FILE *fh, struct program *p) {
                 fprintf(stderr, "Error: Identifier expected before ':'\n");
                 return -1;
             }
-            if (growable_grow(&p->markers, p->markers.len + 1) < 0)
-                return -1;
             p->ast_items.len--;
-            GET_MARKER(*p, p->markers.len++) = (struct ast_marker){
+            if (growable_append(&p->markers, &(struct ast_marker){
                 GET_ITEM(*p, p->ast_items.len).u.s,
                 p->ast_items.len,
-            };
+            }) < 0)
+                return -1;
             continue;
         case '*':
             ai.type = AST_ITEM_MULTIPLY;
@@ -107,9 +106,8 @@ int parse_input(FILE *fh, struct program *p) {
         fprintf(stderr, "Error: invalid input: '%c' (0x%02x)\n", c, c & 0xff);
         return -1;
 add_item:
-        if (growable_grow(&p->ast_items, p->ast_items.len + 1) < 0)
+        if (growable_append(&p->ast_items, &ai) < 0)
             return -1;
-        memcpy(&GET_ITEM(*p, p->ast_items.len++), &ai, sizeof ai);
     }
     if (ferror(fh)) {
         fprintf(stderr, "Error: read error.\n");
index c6baab11a1444fba144e7002a26b48da7758f2ef..18c8f05fc22f919d76e58be1f9dfd1ffc76d7dd4 100644 (file)
--- a/runtime.c
+++ b/runtime.c
@@ -129,10 +129,7 @@ static inline int assign_value(
             return 0;
         }
     }
-    if (growable_grow(scope, scope->len + 1) < 0)
-        return -1;
-    GET_SCOPE_ITEM(*scope, scope->len++) = (struct scope_item){ name, value };
-    return 0;
+    return growable_append(scope, &(struct scope_item){ name, value });
 }
 
 int evaluate_statement(const struct program p, struct growable *scope, size_t *stmt) {
@@ -156,6 +153,12 @@ int evaluate_statement(const struct program p, struct growable *scope, size_t *s
         if (evaluate_arith(p, scope, stmt, UNTIL_SEMICOLON, &value.u.i) < 0)
             return -1;
         *stmt = value.u.i;
+    } else if (item->type == AST_ITEM_PRINT) {
+        (*stmt)++;
+        if (evaluate_arith(p, scope, stmt, UNTIL_SEMICOLON, &value.u.i) < 0)
+            return -1;
+        printf("%"PRIdMAX"\n", value.u.i);
+        (*stmt)++;
     } else {
         fprintf(stderr, "Error: canot execute: ");
         ast_item_dump(stderr, *item);
index e12882219194c238c9595264171628b946ecd821..61698f111785bdccd0636fe48610e6d8be7bd299 100644 (file)
@@ -37,6 +37,12 @@ void ast_item_dump(FILE *fh, const struct ast_item ai) {
     case AST_ITEM_DIVIDE:
         fprintf(fh, "AST_ITEM_DIVIDE");
         break;
+    case AST_ITEM_GOTO:
+        fprintf(fh, "AST_ITEM_GOTO");
+        break;
+    case AST_ITEM_PRINT:
+        fprintf(fh, "AST_ITEM_PRINT");
+        break;
     default:
         fprintf(fh, "ast_item_type UNKNOWN(%d)", ai.type);
     }
index 64dddaac5816473f77896a53d9095ec7f83b27c9..37d0563cb2f5aafefd84aaca80ddc97b82305f22 100644 (file)
@@ -16,9 +16,10 @@ struct ast_item {
         AST_ITEM_EQUALS,
         AST_ITEM_IDENT,
         AST_ITEM_SEMICOLON,
-        AST_ITEM_GOTO,
         AST_ITEM_MULTIPLY,
         AST_ITEM_DIVIDE,
+        AST_ITEM_GOTO,
+        AST_ITEM_PRINT,
     } type;
     union {
         intmax_t i;