%type <tr> 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;
;
-next: /* empty */ {$$ = NULL; }
+next: /* empty */ {$$ = tree_malloc(ST_EMPTY); }
| 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;
}
}
;
-leaves: | VAR {
+leaves: VAR {
$$ = tree_malloc(ST_LEAF);
$$->pt.leaf.type = L_VAR;
$$->pt.leaf.value = $1;
}
;
-left: /* empty */ {$$=NULL;}
+left: /* empty */ { $$ = NULL;}
| KW_COPY { $$ = "copy"; }
;
-right: /* empty */ {$$ = NULL; }
+right: /* empty */ { $$ = NULL; }
| KW_PIPE { $$ = "pipe"; }
| KW_MAIL { $$ = "mail"; }
;
#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)
{
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)
{
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));
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('$');
}
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:
}
}
+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");
}
};