From 750fd80227df1eaf0bc1edf82677219f5a54bb1d Mon Sep 17 00:00:00 2001 From: Anicka Bernathova Date: Thu, 10 Jul 2008 12:31:48 +0200 Subject: [PATCH] interpreting assignments, cleanup in printing function --- brum.c | 2 +- brum.h | 13 +++++-- cond.y | 14 +++---- int.c | 113 ++++++++++++++++++++++++++++++--------------------------- 4 files changed, 77 insertions(+), 65 deletions(-) diff --git a/brum.c b/brum.c index 2a67c19..21ebff6 100644 --- a/brum.c +++ b/brum.c @@ -15,7 +15,7 @@ main(void) print_tree(input_tree,0); var_hash = new_var_hash(); - interp(input_tree); + interp(input_tree, var_hash); return 0; } diff --git a/brum.h b/brum.h index 59c4328..7cb6fde 100644 --- a/brum.h +++ b/brum.h @@ -64,11 +64,18 @@ struct tree* input_tree; /* lex.c */ void* xmalloc(size_t size); char* xstrdup(char* s); +void __attribute__ ((noreturn)) die(char* msg, ...); int line; /* int.c */ -void print_tree(struct tree* t, int ind); -void interp(struct tree* t); -struct variable** new_var_hash(void); +struct variable { + char* name; + char* value; + struct variable* next; +}; struct variable** var_hash; + +void print_tree(struct tree* t, int ind); +void interp(struct tree* t, struct variable** hash); +struct variable** new_var_hash(void); diff --git a/cond.y b/cond.y index 7355a42..9f42a4b 100644 --- a/cond.y +++ b/cond.y @@ -47,7 +47,7 @@ static struct tree* tree_malloc(int type); %type leaves %% -input: /* empty */ { $$ = input_tree = NULL; } +input: /* empty */ { $$ = input_tree = tree_malloc(ST_EMPTY); } | command input { $$ = tree_malloc(ST_BLOCK); $$->pt.block.head = $1; $$->pt.block.tail = $2; @@ -70,7 +70,7 @@ command: ';' { $$ = tree_malloc(ST_EMPTY); } ; -next: /* empty */ {$$ = NULL; } +next: /* empty */ {$$ = tree_malloc(ST_EMPTY); } | command @@ -86,14 +86,14 @@ cif: KW_IF cond command KW_ELSE command { $$ = tree_malloc(ST_IF); $$->pt.tif.c = $2; $$->pt.tif.i = $3; - $$->pt.tif.e = NULL; + $$->pt.tif.e = tree_malloc(ST_EMPTY); } ; cond: '!' cond { $$ = tree_malloc(ST_COND); $$->pt.cond.left = $2; - $$->pt.cond.right = NULL; + $$->pt.cond.right = tree_malloc(ST_EMPTY); $$->pt.cond.op = $1; } @@ -149,7 +149,7 @@ ass: } ; -leaves: | VAR { +leaves: VAR { $$ = tree_malloc(ST_LEAF); $$->pt.leaf.type = L_VAR; $$->pt.leaf.value = $1; @@ -169,12 +169,12 @@ arrow: left ARROW right ass_right { } ; -left: /* empty */ {$$=NULL;} +left: /* empty */ { $$ = NULL;} | KW_COPY { $$ = "copy"; } ; -right: /* empty */ {$$ = NULL; } +right: /* empty */ { $$ = NULL; } | KW_PIPE { $$ = "pipe"; } | KW_MAIL { $$ = "mail"; } ; diff --git a/int.c b/int.c index 5f0a936..6403e11 100644 --- a/int.c +++ b/int.c @@ -6,16 +6,9 @@ #include "brum.h" #define OVECCOUNT 3 - #define HASHSIZE 103 #define MAGIC 19 -struct variable { - char* name; - char* value; - struct variable* next; -}; - struct variable** new_var_hash(void) { @@ -54,33 +47,20 @@ find_var(char* name, char* value, struct variable** hash) while(p && strcmp(p->name,name)) p = p->next; - if (!value) - return p; - if (p) + if (p && value){ free(p->value); - else { + p->value = value; + } else { p = xmalloc(sizeof(struct variable)); - p->next = hash[n]->next; - hash[n]->next = p; + p->next = hash[n]; + hash[n] = p; p->name = xstrdup(name); + p->value = (value? value:xstrdup("")); } - p->value = xstrdup(value); - return p; } -static void -print_ind(int num, char c) -{ - int i; - - for (i = 0; i < num; i++){ - putchar(c); - } -//printf("%*s", num, ""); -} - static int regex_cmp(char* s, char* r) { @@ -107,22 +87,18 @@ print_tree(struct tree* t, int ind) switch (t->st){ case ST_IF: - print_ind(ind,' '); - puts("if"); + printf("%*s if\n", ind, ""); print_tree(t->pt.tif.c,ind+1); - print_ind(ind,' '); - puts("then"); + printf("%*s then\n", ind, ""); print_tree(t->pt.tif.i,ind+1); - print_ind(ind,' '); - puts("else"); + printf("%*s else\n", ind, ""); print_tree(t->pt.tif.e,ind+1); break; case ST_COND: #define UPPER(a) ((a) >> 8) #define LOWER(a) ((a) & 0xFF) print_tree(t->pt.cond.left, ind+1); - print_ind(ind,' '); - + printf("%*s", ind, ""); if (UPPER(t->pt.cond.op) > 0) putchar(UPPER(t->pt.cond.op)); putchar(LOWER(t->pt.cond.op)); @@ -135,12 +111,11 @@ print_tree(struct tree* t, int ind) break; case ST_ASS: print_tree(t->pt.ass.left, ind+1); - print_ind(ind,' '); - puts("="); + printf("%*s =\n", ind, ""); print_tree(t->pt.ass.right, ind+1); break; case ST_LEAF: - print_ind(ind, ' '); + printf("%*s", ind, ""); switch (t->pt.leaf.type){ case L_VAR: putchar('$'); @@ -150,23 +125,16 @@ print_tree(struct tree* t, int ind) } break; case ST_ARROW: - if (t->pt.arrow.kw_left){ - print_ind(ind+1, ' '); - puts(t->pt.arrow.kw_left); - } - print_ind(ind, ' '); - printf("->\n"); - if (t->pt.arrow.kw_right){ - print_ind(ind+1, ' '); - puts(t->pt.arrow.kw_right); - } + if (t->pt.arrow.kw_left) + printf("%*s%s\n", ind+1, "", t->pt.arrow.kw_left); + printf("%*s ->\n", ind, ""); + if (t->pt.arrow.kw_right) + printf("%*s%s\n", ind+1, "", t->pt.arrow.kw_right); print_tree(t->pt.arrow.s,ind+1); break; case ST_OP: print_tree(t->pt.op.left, ind+1); - print_ind(ind,' '); - putchar(t->pt.op.op); - putchar('\n'); + printf("%*s%c\n", ind, "", t->pt.op.op); print_tree(t->pt.op.right, ind+1); break; case ST_EMPTY: @@ -176,20 +144,57 @@ print_tree(struct tree* t, int ind) } } +static char* +xcat(char* left, char* right) +{ + char* res = xmalloc(strlen(left) + strlen(right) + 1); + + strcpy(res,left); + strcat(left,right); + + free(left); + free(right); + + return res; +} + +char* +interp_ass_right(struct tree* t, struct variable** hash) +{ + switch (t->st){ + case ST_LEAF: + if (t->pt.leaf.type == L_VAR) + return xstrdup(find_var(t->pt.leaf.value,NULL,hash)->value); + else + return xstrdup(t->pt.leaf.value); + case ST_OP: + switch (t->pt.op.op){ + case '.': + return xcat(interp_ass_right(t->pt.op.left, hash),interp_ass_right(t->pt.op.right, hash)); + } + case ST_EMPTY: + return xstrdup(""); + default: + die("interp_ass_right: got to default"); + } +} + void -interp(struct tree* t) +interp(struct tree* t, struct variable** hash) { if (!t) return; switch(t->st){ case ST_BLOCK: - interp(t->pt.block.head); - interp(t->pt.block.tail); + interp(t->pt.block.head, hash); + interp(t->pt.block.tail, hash); break; case ST_ASS: - // find_name(t->pt.ass.left->pt.leaf.value.s, interp_ass_right(t->pt.ass.right), var_hash); + find_var(t->pt.ass.left->pt.leaf.value, interp_ass_right(t->pt.ass.right, hash), hash); break; + default: + die("interp: got to default"); } }; -- 2.39.2