From 6f849da4ce369089720d366d3e419d95bb8a1dac Mon Sep 17 00:00:00 2001 From: mar77i Date: Tue, 19 Nov 2024 11:21:58 +0100 Subject: [PATCH] use growable_append, add print builtin --- growable.c | 31 +++++++++++++++++-------------- growable.h | 2 +- parser.c | 20 +++++++++----------- runtime.c | 11 +++++++---- shitscript.c | 6 ++++++ shitscript.h | 3 ++- 6 files changed, 42 insertions(+), 31 deletions(-) diff --git a/growable.c b/growable.c index a05dfc2..05567b8 100644 --- a/growable.c +++ b/growable.c @@ -2,6 +2,7 @@ // growable.c #include +#include #include "growable.h" @@ -16,22 +17,24 @@ 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; } diff --git a/growable.h b/growable.h index ae98ae9..ac67a6f 100644 --- a/growable.h +++ b/growable.h @@ -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]) diff --git a/parser.c b/parser.c index e5d7d2d..8ef121b 100644 --- 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"); diff --git a/runtime.c b/runtime.c index c6baab1..18c8f05 100644 --- 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); diff --git a/shitscript.c b/shitscript.c index e128822..61698f1 100644 --- a/shitscript.c +++ b/shitscript.c @@ -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); } diff --git a/shitscript.h b/shitscript.h index 64dddaa..37d0563 100644 --- a/shitscript.h +++ b/shitscript.h @@ -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; -- 2.47.0