]> mj.ucw.cz Git - umpf.git/blob - int.c
interpreting assignments, cleanup in printing function
[umpf.git] / int.c
1 #include <stdio.h>
2 #include <string.h>
3 #include <pcre.h>
4
5 #include "cond.tab.h"
6 #include "brum.h"
7
8 #define OVECCOUNT 3
9 #define HASHSIZE 103
10 #define MAGIC 19
11
12 struct variable**
13 new_var_hash(void)
14 {
15         struct variable** res;
16
17         res = xmalloc (HASHSIZE * sizeof(struct variable*));
18         memset(res, 0, sizeof(struct variable*)*HASHSIZE);
19
20         return res;
21 }
22
23 static int
24 get_bucket_number(char* name)
25 {
26         unsigned int n = 0;
27         unsigned char* p = name;
28
29         while (*p != '\0'){
30                 n = n * MAGIC + *p++;
31         }
32         n %= HASHSIZE;
33
34         return n;
35 }
36
37 /* value NULL for finding without modyfiing */
38 static struct variable*
39 find_var(char* name, char* value, struct variable** hash)
40 {
41         int n;
42         struct variable *p;
43
44         n = get_bucket_number(name);
45
46         p = hash[n];
47         while(p && strcmp(p->name,name))
48                 p = p->next;
49
50         if (p && value){
51                 free(p->value);
52                 p->value = value;
53         } else {
54                 p = xmalloc(sizeof(struct variable));
55                 p->next = hash[n];
56                 hash[n] = p;
57                 p->name = xstrdup(name);
58                 p->value = (value? value:xstrdup(""));
59         }
60
61         return p;
62 }
63
64 static int 
65 regex_cmp(char* s, char* r)
66 {
67         pcre *brum;
68         int erroroffset;
69         const char* error;
70         int ovector[OVECCOUNT];
71         
72         brum = pcre_compile(r,0,&error,&erroroffset,NULL);
73         if (!brum)
74                 return -1;
75         
76         int res = pcre_exec(brum,NULL,s,strlen(s),0,0,ovector,OVECCOUNT);
77         pcre_free(brum);
78
79         return res;
80 }
81
82 void
83 print_tree(struct tree* t, int ind)
84 {
85         if (!t)
86                 return; 
87
88         switch (t->st){
89                 case ST_IF:
90                         printf("%*s if\n", ind, "");
91                         print_tree(t->pt.tif.c,ind+1);
92                         printf("%*s then\n", ind, "");
93                         print_tree(t->pt.tif.i,ind+1);
94                         printf("%*s else\n", ind, "");
95                         print_tree(t->pt.tif.e,ind+1);
96                         break;
97                 case ST_COND:
98 #define UPPER(a) ((a) >> 8)
99 #define LOWER(a) ((a) & 0xFF)
100                         print_tree(t->pt.cond.left, ind+1);
101                         printf("%*s", ind, "");
102                         if (UPPER(t->pt.cond.op) > 0)
103                                 putchar(UPPER(t->pt.cond.op));
104                         putchar(LOWER(t->pt.cond.op));
105                         putchar('\n'); 
106                         print_tree(t->pt.cond.right, ind+1);    
107                         break;
108                 case ST_BLOCK:
109                         print_tree(t->pt.block.head,ind);
110                         print_tree(t->pt.block.tail,ind);
111                         break;
112                 case ST_ASS:
113                         print_tree(t->pt.ass.left, ind+1);
114                         printf("%*s =\n", ind, "");
115                         print_tree(t->pt.ass.right, ind+1);
116                         break;
117                 case ST_LEAF:
118                         printf("%*s", ind, "");
119                         switch (t->pt.leaf.type){
120                                 case L_VAR:
121                                         putchar('$');
122                                 case L_CONST:
123                                         puts(t->pt.leaf.value);
124                                         break;
125                         }
126                         break;
127                 case ST_ARROW:
128                         if (t->pt.arrow.kw_left)
129                                 printf("%*s%s\n", ind+1, "", t->pt.arrow.kw_left);
130                         printf("%*s ->\n", ind, "");
131                         if (t->pt.arrow.kw_right)
132                                 printf("%*s%s\n", ind+1, "", t->pt.arrow.kw_right);
133                         print_tree(t->pt.arrow.s,ind+1);
134                         break;
135                 case ST_OP:
136                         print_tree(t->pt.op.left, ind+1);
137                         printf("%*s%c\n", ind, "", t->pt.op.op);
138                         print_tree(t->pt.op.right, ind+1);
139                         break;  
140                 case ST_EMPTY:
141                         break;  
142
143
144         }
145 }
146
147 static char*
148 xcat(char* left, char* right)
149 {
150         char* res = xmalloc(strlen(left) + strlen(right) + 1);
151
152         strcpy(res,left);
153         strcat(left,right);
154
155         free(left);
156         free(right);    
157
158         return res;
159 }
160
161 char*
162 interp_ass_right(struct tree* t, struct variable** hash)
163 {
164         switch (t->st){
165                 case ST_LEAF:
166                         if (t->pt.leaf.type == L_VAR)
167                                 return xstrdup(find_var(t->pt.leaf.value,NULL,hash)->value);
168                         else 
169                                 return xstrdup(t->pt.leaf.value);
170                 case ST_OP:
171                         switch (t->pt.op.op){
172                                 case '.':
173                                         return xcat(interp_ass_right(t->pt.op.left, hash),interp_ass_right(t->pt.op.right, hash));
174                         }       
175                 case ST_EMPTY:
176                         return xstrdup("");
177                 default:
178                         die("interp_ass_right: got to default");        
179                 }
180 }       
181
182 void
183 interp(struct tree* t, struct variable** hash)
184 {
185         if (!t)
186                 return;
187
188         switch(t->st){
189                 case ST_BLOCK:
190                         interp(t->pt.block.head, hash);
191                         interp(t->pt.block.tail, hash);
192                 break;
193                 case ST_ASS:
194                         find_var(t->pt.ass.left->pt.leaf.value, interp_ass_right(t->pt.ass.right, hash), hash);
195                 break;
196                 default:
197                         die("interp: got to default");
198         }
199
200 };