]> git.mar77i.info Git - shitscript/commitdiff
more useful accessors
authormar77i <mar77i@protonmail.ch>
Mon, 18 Nov 2024 17:25:19 +0000 (18:25 +0100)
committermar77i <mar77i@protonmail.ch>
Mon, 18 Nov 2024 17:25:19 +0000 (18:25 +0100)
growable.c
growable.h
parser.c
parser.h
runtime.c
runtime.h
shitscript.c
shitscript.h

index 3a0decfb215fda1450f053772c80cf43d8add4f6..a05dfc2ec63771fea4f41e902f8fd4213f329406 100644 (file)
@@ -35,6 +35,6 @@ int growable_grow(struct growable *g, size_t len) {
     return 0;
 }
 
-void growable_cleanup(struct growable *g) {
-    free(g->data);
+void growable_cleanup(const struct growable g) {
+    free(g.data);
 }
index b5e9f89698f86438f632cea4455556c655cfa0c3..ae98ae9b7081585e2f23a5ffa2abc322550947d1 100644 (file)
@@ -15,8 +15,8 @@ struct growable {
     ((struct growable){ .item_size = (is), .len = 0, .allo = 0, .data = NULL })
 
 int growable_grow(struct growable *g, size_t len);
-void growable_cleanup(struct growable *g);
+void growable_cleanup(const struct growable g);
 
-#define GROWABLE_AT(g, t, i) ((t*)(g).data)[i]
+#define GROWABLE_AT(g, t, i) (((t*)(g).data)[i])
 
 #endif // GROWABLE_H
index a0fe82fa23365646e708be2fecce9a31102fb6f0..d22a72f04e77f00ffe387078a980a9f46dce9083 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -6,7 +6,6 @@
 #include <string.h>
 
 #include "growable.h"
-#include "shitscript.h"
 #include "parser.h"
 
 static inline int read_number(struct ast_item *ai) {
@@ -20,7 +19,8 @@ static inline int read_number(struct ast_item *ai) {
         }
         ai->u.i = new_value;
     }
-    ungetc(c, stdin);
+    if (c != EOF)
+        ungetc(c, stdin);
     return 0;
 }
 
@@ -32,13 +32,14 @@ static inline int read_ident_or_keyword(int c, struct ast_item *ai) {
         ((char*)s.data)[s.len++] = c;
         c = getc(stdin);
     } while (isalnum(c) || c == '_');
-    ungetc(c, stdin);
+    if (c != EOF)
+        ungetc(c, stdin);
     if (growable_grow(&s, s.len + 1) < 0)
         return -1;
     ((char*)s.data)[s.len++] = '\0';
     if (strcasecmp(s.data, "goto") == 0) {
         ai->type = AST_ITEM_GOTO;
-        growable_cleanup(&s);
+        growable_cleanup(s);
         return 0;
     }
     ai->type = AST_ITEM_IDENT;
@@ -46,7 +47,7 @@ static inline int read_ident_or_keyword(int c, struct ast_item *ai) {
     return 0;
 }
 
-int parse_input(struct growable *ast_items, struct growable *markers) {
+int parse_input(struct program *p) {
     int c;
     struct ast_item ai;
     while ((c = getc(stdin)) != EOF) {
@@ -65,19 +66,19 @@ int parse_input(struct growable *ast_items, struct growable *markers) {
             ai.type = AST_ITEM_SEMICOLON;
             goto add_item;
         case ':':
-            if (ast_items->len == 0 || (
-                (struct ast_item*)ast_items->data
-            )[ast_items->len - 1].type != AST_ITEM_IDENT) {
+            if (
+                p->ast_items.len == 0
+                || GET_ITEM(*p, p->ast_items.len - 1).type != AST_ITEM_IDENT
+            ) {
                 fprintf(stderr, "Error: Identifier expected before ':'\n");
                 return -1;
             }
-            if (growable_grow(markers, markers->len + 1) < 0)
+            if (growable_grow(&p->markers, p->markers.len + 1) < 0)
                 return -1;
-            GROWABLE_AT(
-                *markers, struct ast_marker, markers->len++
-            ) = (struct ast_marker){
-                GROWABLE_AT(*ast_items, struct ast_item, --ast_items->len).u.s,
-                ast_items->len,
+            p->ast_items.len--;
+            GET_MARKER(*p, p->markers.len++) = (struct ast_marker){
+                GET_ITEM(*p, p->ast_items.len).u.s,
+                p->ast_items.len,
             };
             continue;
         case '*':
@@ -102,9 +103,9 @@ int parse_input(struct growable *ast_items, struct growable *markers) {
         fprintf(stderr, "Error: invalid input: '%c' (0x%02x)\n", c, c & 0xff);
         return -1;
 add_item:
-        if (growable_grow(ast_items, ast_items->len + 1) < 0)
+        if (growable_grow(&p->ast_items, p->ast_items.len + 1) < 0)
             return -1;
-        memcpy(&((struct ast_item*)ast_items->data)[ast_items->len++], &ai, sizeof ai);
+        memcpy(&GET_ITEM(*p, p->ast_items.len++), &ai, sizeof ai);
     }
     if (ferror(stdin)) {
         fprintf(stderr, "Error: read error.\n");
index c1d4806b7ba287665eaef27557e42e1791c85300..9189ab93bf129fc1cfe1b57bd4b284c8108292b0 100644 (file)
--- a/parser.h
+++ b/parser.h
@@ -4,6 +4,8 @@
 #ifndef PARSER_H
 #define PARSER_H
 
-int parse_input(struct growable *ast_items, struct growable *markers);
+#include "shitscript.h"
+
+int parse_input(struct program *p);
 
 #endif // PARSER_H
index 17fd53271fa50026673723dfda23f16d7cb821ab..d8389ebae08d50c532a763192a68e190822d356c 100644 (file)
--- a/runtime.c
+++ b/runtime.c
@@ -21,15 +21,17 @@ struct scope_item {
     struct scope_value value;
 };
 
+#define GET_SCOPE_ITEM(s, i) (GROWABLE_AT((s), struct scope_item, (i)))
+
 enum evaluate_until {
     UNTIL_SEMICOLON,
 };
 
 static inline int maybe_resolve_int(
+    const struct program p,
     struct growable *scope,
-    struct growable markers,
-    intmax_t *result,
-    struct ast_item ai
+    struct ast_item ai,
+    intmax_t *result
 ) {
     size_t i;
     if (ai.type == AST_ITEM_INT) {
@@ -40,40 +42,42 @@ static inline int maybe_resolve_int(
         return -1;
     }
     for (i = 0; i < scope->len; i++)
-        if (strcmp(((struct scope_item*)scope->data)[i].name, ai.u.s) == 0)
+        if (strcmp(GET_SCOPE_ITEM(*scope, i).name, ai.u.s) == 0)
             goto found_in_scope;
-    for (i = 0; i < markers.len; i++)
-        if (strcmp(((struct ast_marker*)markers.data)[i].name, ai.u.s) == 0) {
-            *result = ((struct ast_marker*)markers.data)[i].pos;
+    for (i = 0; i < p.markers.len; i++)
+        if (strcmp(GET_MARKER(p, i).name, ai.u.s) == 0) {
+            *result = GET_MARKER(p, i).pos;
             return 0;
         }
     fprintf(stderr, "Error: unknown identifier: '%s'\n", ai.u.s);
     return -1;
 found_in_scope:
-    if (((struct scope_item*)scope->data)[i].value.type != VALUE_TYPE_INT) {
+    if (GET_SCOPE_ITEM(*scope, i).value.type != VALUE_TYPE_INT) {
         fprintf(stderr, "Error: invalid type: '%s'\n", ai.u.s);
         return -1;
     }
-    *result = ((struct scope_item*)scope->data)[i].value.u.i;
+    *result = GET_SCOPE_ITEM(*scope, i).value.u.i;
     return 0;
 }
 
 static inline int evaluate_arith(
-    struct growable ast_items,
+    const struct program p,
+    struct growable *scope,
     size_t *stmt,
     enum evaluate_until until,
-    intmax_t *result,
-    struct growable *scope,
-    struct growable markers
+    intmax_t *result
 ) {
-    intmax_t accu = 0, other = 0;
-    if (maybe_resolve_int(scope, markers, &accu, ((struct ast_item*)ast_items.data)[*stmt]) < 0)
+    intmax_t accu = 0, other;
+    if (maybe_resolve_int(p, scope, GET_ITEM(p, *stmt), &accu) < 0)
         return -1;
     (*stmt)++;
-    if (until == UNTIL_SEMICOLON && ((struct ast_item*)ast_items.data)[*stmt].type == AST_ITEM_SEMICOLON)
+    if (
+        until == UNTIL_SEMICOLON
+        && GET_ITEM(p, *stmt).type == AST_ITEM_SEMICOLON
+    )
         goto done;
     for (;;) {
-        if (*stmt + 1 >= ast_items.len) {
+        if (*stmt + 1 >= p.ast_items.len) {
             switch (until) {
             case UNTIL_SEMICOLON:
                 fprintf(stderr, "Error: semicolon expected.\n");
@@ -81,35 +85,32 @@ static inline int evaluate_arith(
             }
             return -1;
         }
-        if (((struct ast_item*)ast_items.data)[*stmt].type == AST_ITEM_PLUS) {
-            if (maybe_resolve_int(scope, markers, &other, ((struct ast_item*)ast_items.data)[*stmt + 1]) < 0)
-                return -1;
-            (*stmt) += 2;
+        other = 0;
+        if (maybe_resolve_int(p, scope, GET_ITEM(p, *stmt + 1), &other) < 0)
+            return -1;
+        switch (GET_ITEM(p, *stmt).type) {
+        case AST_ITEM_PLUS:
             accu += other;
-        } else if (((struct ast_item*)ast_items.data)[*stmt].type == AST_ITEM_MINUS) {
-            if (maybe_resolve_int(scope, markers, &other, ((struct ast_item*)ast_items.data)[*stmt + 1]) < 0)
-                return -1;
-            (*stmt) += 2;
+            break;
+        case AST_ITEM_MINUS:
             accu -= other;
-        } else if (((struct ast_item*)ast_items.data)[*stmt].type == AST_ITEM_MULTIPLY) {
-            if (maybe_resolve_int(scope, markers, &other, ((struct ast_item*)ast_items.data)[*stmt + 1]) < 0)
-                return -1;
-            (*stmt) += 2;
+            break;
+        case AST_ITEM_MULTIPLY:
             accu *= other;
-        } else if (((struct ast_item*)ast_items.data)[*stmt].type == AST_ITEM_DIVIDE) {
-            if (maybe_resolve_int(scope, markers, &other, ((struct ast_item*)ast_items.data)[*stmt + 1]) < 0)
-                return -1;
-            (*stmt) += 2;
+            break;
+        case AST_ITEM_DIVIDE:
             accu /= other;
-        } else {
+            break;
+        default:
             fprintf(stderr, "Error: unknown operator: ");
-            ast_item_dump(((struct ast_item*)ast_items.data)[*stmt], stderr);
+            ast_item_dump(stderr, GET_ITEM(p, *stmt));
             fputc('\n', stderr);
             return -1;
         }
+        (*stmt) += 2;
         if (
             until == UNTIL_SEMICOLON
-            && ((struct ast_item*)ast_items.data)[*stmt].type == AST_ITEM_SEMICOLON
+            && GET_ITEM(p, *stmt).type == AST_ITEM_SEMICOLON
         )
             goto done;
     }
@@ -124,71 +125,57 @@ static inline int assign_value(
     size_t i;
     printf("assigning %s value %"PRIdMAX"\n", name, value.u.i);
     for (i = 0; i < scope->len; i++) {
-        if (strcmp(((struct scope_item*)scope->data)[i].name, name) == 0) {
-            ((struct scope_item*)scope->data)[i].value = value;
+        if (strcmp(GET_SCOPE_ITEM(*scope, i).name, name) == 0) {
+            GET_SCOPE_ITEM(*scope, i).value = value;
             return 0;
         }
     }
     if (growable_grow(scope, scope->len + 1) < 0)
         return -1;
-    ((struct scope_item*)scope->data)[scope->len++] = (struct scope_item){
-        name, value
-    };
+    GET_SCOPE_ITEM(*scope, scope->len++) = (struct scope_item){ name, value };
     return 0;
 }
 
-int evaluate_statement(
-    const struct growable ast_items,
-    const struct growable markers,
-    size_t *stmt,
-    struct growable *scope
-) {
+int evaluate_statement(const struct program p, struct growable *scope, size_t *stmt) {
     size_t tmp;
     struct scope_value value = { .type = VALUE_TYPE_INT };
+    struct ast_item *item = &GET_ITEM(p, *stmt);
     if (
-        ((struct ast_item*)ast_items.data)[*stmt].type == AST_ITEM_IDENT
-        && *stmt + 1 < ast_items.len
-        && ((struct ast_item*)ast_items.data)[*stmt + 1].type == AST_ITEM_ASSIGN
+        item->type == AST_ITEM_IDENT
+        && *stmt + 1 < p.ast_items.len
+        && GET_ITEM(p, *stmt + 1).type == AST_ITEM_ASSIGN
     ) {
         tmp = *stmt;
         *stmt += 2;
-        if (
-            evaluate_arith(
-                ast_items, stmt, UNTIL_SEMICOLON, &value.u.i, scope, markers
-            ) < 0
-        )
+        if (evaluate_arith(p, scope, stmt, UNTIL_SEMICOLON, &value.u.i) < 0)
             return -1;
         (*stmt)++;
-        if (assign_value(scope, ((struct ast_item*)ast_items.data)[tmp].u.s, value) < 0)
+        if (assign_value(scope, GET_ITEM(p, tmp).u.s, value) < 0)
             return -1;
-    } else if (((struct ast_item*)ast_items.data)[*stmt].type == AST_ITEM_GOTO) {
+    } else if (item->type == AST_ITEM_GOTO) {
         (*stmt)++;
-        if (
-            evaluate_arith(
-                ast_items, stmt, UNTIL_SEMICOLON, &value.u.i, scope, markers
-            ) < 0
-        )
+        if (evaluate_arith(p, scope, stmt, UNTIL_SEMICOLON, &value.u.i) < 0)
             return -1;
         *stmt = value.u.i;
         printf("goto %zu\n", *stmt);
     } else {
         fprintf(stderr, "Error: canot execute: ");
-        ast_item_dump(((struct ast_item*)ast_items.data)[*stmt], stderr);
+        ast_item_dump(stderr, *item);
         fputc('\n', stderr);
         return -1;
     }
     return 0;
 }
 
-int run_ast_items(const struct growable ast_items, const struct growable markers) {
+int run_ast_items(const struct program p) {
     struct growable scope = EMPTY_GROWABLE(sizeof (struct scope_item));
     size_t stmt = 0;
     int ret = -1;
-    while (stmt < ast_items.len)
-        if (evaluate_statement(ast_items, markers, &stmt, &scope) < 0)
+    while (stmt < p.ast_items.len)
+        if (evaluate_statement(p, &scope, &stmt) < 0)
             goto error;
     ret = 0;
 error:
-    growable_cleanup(&scope);
+    growable_cleanup(scope);
     return ret;
 }
index 8ee99d8e4add597cd6fd9f05b7ca08bd16451b7f..2d2bc59b06dbd6dc16d1b7c992b9f6d02919f062 100644 (file)
--- a/runtime.h
+++ b/runtime.h
@@ -8,6 +8,6 @@
 
 #include "shitscript.h"
 
-int run_ast_items(struct growable ast_items, struct growable markers);
+int run_ast_items(const struct program p);
 
 #endif // RUNTIME_H
index 212869cedf0d35a8e77c03daf41c2e7f72ebd295..28d44780eecef3ed36ff44b95b4d2b8e2046e84e 100644 (file)
@@ -8,7 +8,7 @@
 #include "runtime.h"
 #include "shitscript.h"
 
-void ast_item_dump(const struct ast_item ai, FILE *fh) {
+void ast_item_dump(FILE *fh, const struct ast_item ai) {
     switch (ai.type) {
     case AST_ITEM_PLUS:
         fprintf(fh, "AST_ITEM_PLUS");
@@ -49,20 +49,25 @@ void ast_item_cleanup(struct ast_item ai) {
 
 int main(void) {
     size_t i;
-    struct growable ast_items = EMPTY_GROWABLE(sizeof (struct ast_item));
-    struct growable markers = EMPTY_GROWABLE(sizeof (struct ast_marker));
+    struct program p = {
+        .ast_items = EMPTY_GROWABLE(sizeof (struct ast_item)),
+        .markers = EMPTY_GROWABLE(sizeof (struct ast_marker)),
+        .buffer = EMPTY_GROWABLE(sizeof (char)),
+    };
     int ret = EXIT_FAILURE;
-    if (parse_input(&ast_items, &markers) < 0)
+    if (parse_input(&p) < 0)
         goto error;
-    if (run_ast_items(ast_items, markers) < 0)
+    growable_cleanup(p.buffer);
+    // p.buffer = EMPTY_GROWABLE(sizeof char);
+    if (run_ast_items(p) < 0)
         goto error;
     ret = EXIT_SUCCESS;
 error:
-    for (i = 0; i < ast_items.len; i++)
-        ast_item_cleanup(((struct ast_item*)ast_items.data)[i]);
-    for (i = 0; i < markers.len; i++)
-        free(((struct ast_marker*)markers.data)[i].name);
-    growable_cleanup(&ast_items);
-    growable_cleanup(&markers);
+    for (i = 0; i < p.ast_items.len; i++)
+        ast_item_cleanup(GET_ITEM(p, i));
+    for (i = 0; i < p.markers.len; i++)
+        free(GET_MARKER(p, i).name);
+    growable_cleanup(p.ast_items);
+    growable_cleanup(p.markers);
     return ret;
 }
index 55f619a96eedda58e387abf574d13aabe2e4d0f1..64dddaac5816473f77896a53d9095ec7f83b27c9 100644 (file)
@@ -31,6 +31,15 @@ struct ast_marker {
     size_t pos;
 };
 
-void ast_item_dump(const struct ast_item ai, FILE *fh);
+struct program {
+    struct growable ast_items;
+    struct growable markers;
+    struct growable buffer;
+};
+
+#define GET_ITEM(p, i) (GROWABLE_AT((p).ast_items, struct ast_item, (i)))
+#define GET_MARKER(p, i) (GROWABLE_AT((p).markers, struct ast_marker, (i)))
+
+void ast_item_dump(FILE *fh, const struct ast_item ai);
 
 #endif // SHITSCRIPT_H