Change to the spec...missed a consistency property. Adding timing option.
[repair.git] / Repair / RepairInterpreter / typeparser.cc
1 #include <stdlib.h>
2 #include "typeparser.h"
3 #include "list.h"
4 #include "common.h"
5 #include "token.h"
6 #include "tmodel.h"
7 #include "amodel.h"
8 #include "omodel.h"
9
10 Typeparser::Typeparser(Reader *r) {
11   reader=r;
12 }
13
14 structure * Typeparser::parsestructure() {
15   Token t=reader->peakahead();
16   while(true) {
17     if (t.token_type==TOKEN_EOF)
18       return NULL;
19     if (t.token_type!=TOKEN_EOL)
20       break;
21     skiptoken();
22     t=reader->peakahead();
23   }
24   needtoken(TOKEN_STRUCTURE);
25   Token typenam=reader->readnext();
26   structure *pstructure=new structure(copystr(typenam.str));
27   /*  needtoken(TOKEN_OPENPAREN);
28   bool continueparse=true;
29   List *list=new List();
30   while(continueparse) {
31     Token t=reader->readnext();
32     switch(t.token_type) {
33     case TOKEN_CLOSEPAREN:
34       continueparse=false;
35       break;
36     case TOKEN_INT:
37       {
38         Token name=reader->readnext();
39         tparam * tpar=new tparam(new ttype(TTYPE_INT),copystr(name.str));
40         list->addobject(tpar);
41         commaorcloseparen();
42         break;
43       }
44     case TOKEN_BIT:
45       {
46         Token name=reader->readnext();
47         tparam * tpar=new tparam(new ttype(TTYPE_BIT),copystr(name.str));
48         list->addobject(tpar);
49         commaorcloseparen();
50         break;
51       }
52     case TOKEN_BYTE:
53       {
54         Token name=reader->readnext();
55         tparam * tpar=new tparam(new ttype(TTYPE_BYTE),copystr(name.str));
56         list->addobject(tpar);
57         commaorcloseparen();
58         break;
59       }
60     default:
61       {
62         Token name=reader->readnext();
63         tparam *tpar=new tparam(new ttype(copystr(typenam.str)),copystr(name.str));
64         list->addobject(tpar);
65         commaorcloseparen();
66         break;
67       }
68     }
69   }
70   tparam **tp=new tparam*[list->size()];
71   list->toArray((void**) tp);
72   pstructure->setparams(tp,list->size());
73   delete(list);*/
74
75   Token t2=reader->peakahead();
76   if (t2.token_type==TOKEN_SUBTYPE) {
77     skiptoken();
78     needtoken(TOKEN_OF);
79     pstructure->setsubtype(parsettype());
80   }
81
82   List *list=new List();
83   List *labellist=new List();
84   needtoken(TOKEN_OPENBRACE);
85   while(true) {
86     while (reader->peakahead().token_type==TOKEN_EOL)
87       skiptoken();
88     Token t=reader->peakahead();
89     if (t.token_type==TOKEN_CLOSEBRACE)
90       break;
91     if (t.token_type==TOKEN_LABEL) {
92       labellist->addobject(parsetlabel());
93     } else  
94       list->addobject(parsetfield());
95   }
96   tfield **tarray=new tfield*[list->size()];
97   tlabel **larray=new tlabel*[labellist->size()];
98   list->toArray((void **)tarray);
99   labellist->toArray((void**)larray);
100   pstructure->setfields(tarray,list->size());
101   pstructure->setlabels(larray,labellist->size());
102   needtoken(TOKEN_CLOSEBRACE);
103   delete(list);
104   delete(labellist);
105   return pstructure;
106 }
107
108 tlabel * Typeparser::parsetlabel() {
109   needtoken(TOKEN_LABEL);
110   Token fieldname=reader->readnext();
111   AElementexpr *index=NULL;
112   if (reader->peakahead().token_type==TOKEN_OPENBRACK) {
113     skiptoken();
114     index=parseaelementexpr(true);
115     needtoken(TOKEN_CLOSEBRACK);
116   }
117   needtoken(TOKEN_COLON);
118   tfield *tf=parsetfield();
119   return new tlabel(tf,copystr(fieldname.str),index);
120 }
121
122 tfield * Typeparser::parsetfield() {
123   static int rcount=0;
124   Token t=reader->peakahead();
125   bool reserved=false;
126   if (t.token_type==TOKEN_RESERVED) {
127     reserved=true;
128     skiptoken();
129   }
130   ttype *tt=parsettype();
131   while(true) {
132     Token isptr=reader->peakahead();
133     if (isptr.token_type==TOKEN_MULT) {
134       tt->makeptr();
135       skiptoken();
136       break; /*Only support direct pointers right now*/
137     } else
138       break;
139   }
140   Token fieldname;
141   if (!reserved)
142     fieldname=reader->readnext();
143   AElementexpr *size=parseindex();
144   tt->setsize(size);
145   needtoken(TOKEN_SEMI);
146   if (reserved) 
147     return new tfield(tt,copystr("RESERVED"+(rcount++)));
148   else
149     return new tfield(tt,copystr(fieldname.str));
150 }
151
152 ttype * Typeparser::parsettype() {
153   Token name=reader->readnext();
154   switch(name.token_type) {
155   case TOKEN_BIT:
156     {
157       return new ttype(TTYPE_BIT);
158     }
159   case TOKEN_INT:
160     {
161       return new ttype(TTYPE_INT);
162     }
163   case TOKEN_SHORT:
164     {
165       return new ttype(TTYPE_SHORT);
166     }
167   case TOKEN_BYTE:
168     {
169       return new ttype(TTYPE_BYTE);
170     }
171   default:
172     {
173       /*
174       needtoken(TOKEN_OPENPAREN);
175       List *list=new List();
176       while(reader->peakahead().token_type!=TOKEN_CLOSEPAREN) {
177         list->addobject(parseaelementexpr(false));
178         commaorcloseparen();
179       }
180       skiptoken();
181       AElementexpr **earray=new AElementexpr*[list->size()];
182       list->toArray((void**)earray);*/
183       ttype *ntt=new ttype(copystr(name.str),NULL);
184       //delete(list);
185       return ntt;
186     }
187   }
188 }
189
190 AElementexpr * Typeparser::parseindex() {
191   Token t=reader->peakahead();
192   if (t.token_type!=TOKEN_OPENBRACK)
193     return NULL;
194   skiptoken();
195   AElementexpr * ae=parseaelementexpr(true);
196   needtoken(TOKEN_CLOSEBRACK);
197   return ae;
198 }
199
200 void Typeparser::commaorcloseparen() {
201   Token t=reader->peakahead();
202   if (t.token_type!=TOKEN_CLOSEPAREN)
203     needtoken(TOKEN_COMMA);
204 }
205
206 AElementexpr * Typeparser::parseaelementexpr(bool isstruct) {
207   AElementexpr *oldee=NULL;
208   int joinop=-1;
209   while(true) {
210   Token t=reader->peakahead();
211   switch(t.token_type) {
212   case TOKEN_LITERAL:
213     {
214       if ((joinop==-1)&&(oldee!=NULL))
215         return oldee;
216       skiptoken();
217       needtoken(TOKEN_OPENPAREN);
218       Token literal=reader->readnext();
219       needtoken(TOKEN_CLOSEPAREN);
220       if (oldee==NULL)
221         oldee=new AElementexpr(new Literal(copystr(literal.str)));
222       else {
223         if (joinop!=-1) {
224           oldee=new AElementexpr(oldee,new AElementexpr(new Literal(copystr(literal.str))),joinop);
225           joinop=-1;
226         } else error();
227       }
228       break;
229     }
230
231   case TOKEN_OPENPAREN:
232     {
233       if ((joinop==-1)&&(oldee!=NULL))
234         return oldee;
235       skiptoken();
236       AElementexpr *ee=parseaelementexpr(false);
237       if (oldee==NULL)
238         oldee=ee;
239       else {
240         if (joinop!=-1) {
241           oldee=new AElementexpr(oldee,ee,joinop);
242           joinop=-1;
243         } else error();
244       }
245       break;
246     }
247   case TOKEN_CLOSEBRACK:
248     if (isstruct)
249       return oldee;
250   case TOKEN_CLOSEPAREN:
251     skiptoken();
252     return checkdot(oldee);
253     break;
254   case TOKEN_SUB:
255     skiptoken();
256     if ((oldee!=NULL)&&(joinop==-1))
257       joinop=AELEMENTEXPR_SUB;
258     else
259       error();
260     break;
261   case TOKEN_ADD:
262     skiptoken();
263     if ((oldee!=NULL)&&(joinop==-1))
264       joinop=AELEMENTEXPR_ADD;
265     else
266       error();
267     break;
268   case TOKEN_MULT:
269     skiptoken();
270     if ((oldee!=NULL)&&(joinop==-1))
271       joinop=AELEMENTEXPR_MULT;
272     else
273       error();
274     break;
275   case TOKEN_DIV:
276     skiptoken();
277     if ((oldee!=NULL)&&(joinop==-1))
278       joinop=AELEMENTEXPR_DIV;
279     else
280       error();
281     break;
282   default:
283     if ((joinop==-1)&&(oldee!=NULL))
284       return oldee;
285     skiptoken();
286     if (oldee==NULL)
287       oldee=checkdot(new AElementexpr(new Label(copystr(t.str))));
288     else {
289       if (joinop!=-1) {
290         oldee=new AElementexpr(oldee,checkdot(new AElementexpr(new Label(copystr(t.str)))),joinop);
291         joinop=-1;
292       } else error();
293     }
294   }
295   }
296 }
297
298 AElementexpr * Typeparser::checkdot(AElementexpr * incoming) {
299   Token tdot=reader->peakahead();
300   if (tdot.token_type!=TOKEN_DOT) return incoming;
301   skiptoken();
302   Token tfield=reader->readnext();
303   Token tpeak=reader->peakahead();
304   if (tpeak.token_type==TOKEN_OPENBRACK) {
305     skiptoken();
306     AElementexpr *index=parseaelementexpr(false);
307     return checkdot(new AElementexpr(incoming, new Field(copystr(tfield.str)),index));
308   } else {
309     return checkdot(new AElementexpr(incoming, new Field(copystr(tfield.str))));
310   }
311 }
312
313 void Typeparser::error() {
314   printf("ERROR\n");
315   reader->error();
316   exit(-1);
317 }
318
319 void Typeparser::skiptoken() {
320   reader->readnext();
321 }
322
323 void Typeparser::needtoken(int token) {
324   Token t=reader->readnext();
325   if (!(t.token_type==token)) {
326     printf("Needed token: ");
327     tokenname(token);
328     printf("\n Got token: %s ",t.str);
329     tokenname(t.token_type);
330     error();
331   }
332 }