]> mj.ucw.cz Git - umpf.git/blob - code.c
compile assignment
[umpf.git] / code.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <ctype.h>
5
6 #include "umpf.h"
7
8 #define HASHSIZE 103
9 #define MAGIC 19
10 #define BUFSIZE 1024
11
12 static struct list* 
13 new_var_hash(void)
14 {
15         struct list* res;
16         int i;
17
18         res = xmalloc (HASHSIZE * sizeof(struct list));
19         for (i = 0; i < HASHSIZE; i++)
20                 list_init(res + i);
21         
22         return res;
23 }
24
25 static int
26 get_bucket_number(char* name)
27 {
28         unsigned int n = 0;
29         unsigned char* p = name;
30
31         while (*p != '\0'){
32                 n = n * MAGIC + toupper(*p++);
33         }
34         n %= HASHSIZE;
35
36         return n;
37 }
38
39 /* if not found, variable with value "" is created  */ 
40 static int
41 find_var(char* name, struct list* hash)
42 {
43         int n;
44         struct variable *p;
45
46         n = get_bucket_number(name);
47         int nocase = isupper(*name);
48         LIST_FOREACH(p, hash + n)
49                 if (!(nocase ? strcasecmp : strcmp)(p->name,name))
50                         return p->varcode;
51
52         p = xmalloc(sizeof(struct variable));
53         p->name = xstrdup(name);
54         p->varcode = current_varcode++;
55         list_add_last(hash+n, &p->car);
56         return p->varcode;
57 }
58
59 void
60 init(void)
61 {
62         list_init(&input_code);
63         var_hash = new_var_hash();
64         const_tab = xmalloc(BUFSIZE);
65         cur_const_s = BUFSIZE;
66 }
67
68 static int
69 store_const(char* c)
70 {
71         if (cur_const_n >= cur_const_s) {
72                 cur_const_s *= 2;
73                 const_tab = xrealloc(const_tab, cur_const_s);
74         }
75
76         const_tab[cur_const_n] = c;
77
78         return -cur_const_n++;  
79 }
80
81 static void
82 new_instr(struct code c)
83 {
84         struct code* p = xmalloc(sizeof(struct code));
85         *p = c;
86         list_add_last(&input_code, &p->car);
87 }
88
89 static void
90 do_ass(struct tree* t)
91 {
92         int var_l, var_r;
93         struct code ins;
94         var_l = find_var(t->pt.ass.left->pt.leaf.value, var_hash);
95
96         if (t->st == ST_LEAF) { 
97                 if (t->pt.leaf.type == L_VAR)
98                         var_r = find_var(t->pt.leaf.value, var_hash);
99                 else
100                         var_r = store_const(t->pt.leaf.value);
101                 ins.opc = SET;
102                 ins.op1.i = var_l;
103                 ins.op2.i = var_r;
104                 new_instr(ins);
105         }
106 }
107
108 void
109 compile(struct tree* t)
110 {
111         if (!t)
112                 return;
113         switch(t->st) {
114                 case ST_BLOCK:
115                         compile(t->pt.block.head);
116                         compile(t->pt.block.tail);
117                         break;
118                 case ST_EMPTY:
119                         break;
120                 case ST_ASS:
121                         do_ass(t);
122                         break;
123                 default:
124                         die("compile: got to default");
125         }
126 }
127
128 void
129 print_code(struct tree* t)
130 {
131
132 }