From 51f13aecf010f547fea2f00b80cd544cc9ac5591 Mon Sep 17 00:00:00 2001 From: Anicka Bernathova Date: Thu, 10 Jul 2008 13:51:29 +0200 Subject: [PATCH] part of conditions, printing variables --- brum.c | 2 ++ brum.h | 6 +++++ cond.y | 10 ++++---- int.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---- lex.c | 4 +++- 5 files changed, 89 insertions(+), 9 deletions(-) diff --git a/brum.c b/brum.c index 21ebff6..5172d69 100644 --- a/brum.c +++ b/brum.c @@ -16,6 +16,8 @@ main(void) var_hash = new_var_hash(); interp(input_tree, var_hash); + + print_vars(var_hash); return 0; } diff --git a/brum.h b/brum.h index 7cb6fde..16e4b9e 100644 --- a/brum.h +++ b/brum.h @@ -22,6 +22,10 @@ struct tree { struct { int op; + enum { + OP_REL, + OP_BOOL + } type; struct tree* left; struct tree* right; } cond; /* binary operator */ @@ -62,6 +66,7 @@ struct tree { struct tree* input_tree; /* lex.c */ +#define CC(a,b) ((a<<8)|b) void* xmalloc(size_t size); char* xstrdup(char* s); void __attribute__ ((noreturn)) die(char* msg, ...); @@ -79,3 +84,4 @@ 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); +void print_vars(struct variable** hash); diff --git a/cond.y b/cond.y index 9f42a4b..42a663d 100644 --- a/cond.y +++ b/cond.y @@ -93,29 +93,30 @@ cif: KW_IF cond command KW_ELSE command { cond: '!' cond { $$ = tree_malloc(ST_COND); $$->pt.cond.left = $2; - $$->pt.cond.right = tree_malloc(ST_EMPTY); + $$->pt.cond.right = NULL; $$->pt.cond.op = $1; - + $$->pt.cond.type = OP_BOOL; } | cond '|' cond { $$ = tree_malloc(ST_COND); $$->pt.cond.left = $1; $$->pt.cond.right = $3; $$->pt.cond.op = $2; - + $$->pt.cond.type = OP_BOOL; } | cond '&' cond { $$ = tree_malloc(ST_COND); $$->pt.cond.left = $1; $$->pt.cond.right = $3; $$->pt.cond.op = $2; - + $$->pt.cond.type = OP_BOOL; } | cond '^' cond { $$ = tree_malloc(ST_COND); $$->pt.cond.left = $1; $$->pt.cond.right = $3; $$->pt.cond.op = $2; + $$->pt.cond.type = OP_BOOL; } | '(' cond ')' { $$ = $2; } @@ -124,6 +125,7 @@ cond: '!' cond { $$->pt.cond.left = $1; $$->pt.cond.right = $3; $$->pt.cond.op = $2; + $$->pt.cond.type = OP_REL; } ; diff --git a/int.c b/int.c index 6403e11..73e34ff 100644 --- a/int.c +++ b/int.c @@ -50,7 +50,9 @@ find_var(char* name, char* value, struct variable** hash) if (p && value){ free(p->value); p->value = value; - } else { + } else if (p && !value) + return p; + else { p = xmalloc(sizeof(struct variable)); p->next = hash[n]; hash[n] = p; @@ -179,6 +181,49 @@ interp_ass_right(struct tree* t, struct variable** hash) } } +int +interp_cond(struct tree* t, struct variable** hash) +{ + if (t->st != ST_COND) + die("Muhehehechlemst?"); + + if (t->pt.cond.type == OP_REL){ + if (t->pt.cond.left->st != ST_LEAF || t->pt.cond.right->st != ST_LEAF) + die("Chlemst"); + + char* left = (t->pt.cond.left->pt.leaf.type == L_VAR ? find_var(t->pt.cond.left->pt.leaf.value,NULL,hash)->value : t->pt.cond.left->pt.leaf.value); + char* right = (t->pt.cond.right->pt.leaf.type == L_VAR ? find_var(t->pt.cond.right->pt.leaf.value,NULL,hash)->value : t->pt.cond.right->pt.leaf.value); + switch (t->pt.cond.op){ + case CC('=','='): + return !strcmp(left,right); + case CC('!','='): + return strcmp(left,right); + case CC('~','~'): + return regex_cmp(left,right); + case CC('!','~'): + return !regex_cmp(left,right); + } + + } else { + int left = interp_cond(t->pt.cond.left, hash); + int right; + + if (t->pt.cond.op != '!') + right = interp_cond(t->pt.cond.right, hash); + + switch (t->pt.cond.op){ + case '&': + return left && right; + case '|': + return left || right; + case '^': + return (left || right) && !(left && right); + case '!': + return !left; + } + } +} + void interp(struct tree* t, struct variable** hash) { @@ -189,12 +234,35 @@ interp(struct tree* t, struct variable** hash) case ST_BLOCK: interp(t->pt.block.head, hash); interp(t->pt.block.tail, hash); - break; + break; case ST_ASS: find_var(t->pt.ass.left->pt.leaf.value, interp_ass_right(t->pt.ass.right, hash), hash); - break; + break; + case ST_IF: + if (interp_cond(t->pt.tif.c, hash)) + interp(t->pt.tif.i, hash); + else + interp(t->pt.tif.e, hash); + break; + case ST_EMPTY: + break; default: die("interp: got to default"); } -}; +} + +void +print_vars(struct variable** hash) +{ + int i; + struct variable* p; + + for (i=0; iname, p->value); + p = p->next; + } + } +} diff --git a/lex.c b/lex.c index 8710763..07d86b3 100644 --- a/lex.c +++ b/lex.c @@ -123,7 +123,6 @@ yylex(void) if (c == EOF) return 0; -#define CC(a,b) ((a<<8)|b) int d = getchar(); if (d >= 0) { switch (CC(c,d)) { @@ -153,6 +152,9 @@ yylex(void) case '=': case ';': case '.': + case '|': + case '&': + case '^': yylval.n = c; return c; -- 2.39.2