Imported Upstream version 2.9.0
[debian/cc1111] / sim / ucsim / cmd.src / cmdpars.y
1 %name cl_ucsim_parser
2
3 %{
4 #include "cmdlexcl.h"
5 #include "memcl.h"
6 #include "globals.h"
7 #include "stypes.h"
8 %}
9
10 %pure_parser
11
12 %define INHERIT : public cl_base
13
14 %define MEMBERS class cl_ucsim_lexer *lexer_object;\
15 virtual ~YY_cl_ucsim_parser_CLASS(void) { delete lexer_object; }
16
17 %define CONSTRUCTOR_PARAM \
18 class cl_ucsim_lexer *the_lexer
19
20 %define CONSTRUCTOR_CODE \
21 lexer_object= the_lexer;
22
23 %token PTOK_PLUS PTOK_MINUS PTOK_ASTERIX PTOK_SLASH PTOK_EQUAL
24 %token PTOK_LEFT_PAREN PTOK_RIGHT_PAREN
25 %token PTOK_LEFT_BRACKET PTOK_RIGHT_BRACKET
26 %token PTOK_DOT PTOK_AMPERSAND
27
28 %token <memory_object> PTOK_MEMORY_OBJECT
29 %token <memory> PTOK_MEMORY
30 %token <number> PTOK_NUMBER
31 %token <bit> PTOK_BIT
32
33 %right PTOK_EQUAL
34 %left PTOK_MINUS PTOK_PLUS
35 %left PTOK_ASTERIX PTOK_SLASH
36 %nonassoc UNARYMINUS PTOK_AMPERSAND
37 %nonassoc PTOK_LEFT_PAREN PTOK_RIGHT_PAREN
38
39 %type <number> ucsim_grammar assignment expression address_of_expression
40 %type <memory> memory
41 %type <bit> bit
42
43 %union {
44   long number;
45   class cl_memory *memory_object;
46   struct {
47     class cl_memory *memory;
48     long address;
49   } memory;
50   struct {
51     class cl_memory *memory;
52     long mem_address, bit_address;
53     long mask;
54   } bit;
55 }
56
57 %%
58
59 ucsim_grammar:
60         expression { application->dd_printf("%d\n", $1); }
61         ;
62
63 assignment:
64           memory PTOK_EQUAL expression
65           {
66             $1.memory->write($1.address, $3);
67             $$= $3;
68           }
69         | bit PTOK_EQUAL expression
70           {
71             if ($3)
72               {
73                 $1.memory->write($1.mem_address,
74                                  $1.memory->read($1.mem_address) | $1.mask);
75                 $$= 1;
76               }
77             else
78               {
79                 $1.memory->write($1.mem_address,
80                                  $1.memory->read($1.mem_address) & ~($1.mask));
81                 $$= 0;
82               }
83           }
84         ;
85
86 expression:
87           assignment { $$= $1; }
88         | expression PTOK_PLUS expression { $$= $1 + $3; }
89         | expression PTOK_MINUS expression { $$= $1 - $3; }
90         | expression PTOK_ASTERIX expression { $$= $1 * $3; }
91         | expression PTOK_SLASH expression
92           {
93             if ($3 == 0)
94               yyerror((char *)"Divide by zero");
95             else
96               $$= $1 / $3;
97           }
98         | PTOK_MINUS expression %prec UNARYMINUS { $$= -$2; }
99         | address_of_expression { $$= $1; }
100         | PTOK_LEFT_PAREN expression PTOK_RIGHT_PAREN { $$= $2; }
101         | PTOK_NUMBER { $$= $1; }
102         | memory { $$= $1.memory->read($1.address); }
103         | bit { $$= ($1.memory->read($1.mem_address) & $1.mask)?1:0; }
104         ;
105
106 address_of_expression:
107           PTOK_AMPERSAND memory { $$= $2.address; }
108         | PTOK_AMPERSAND bit
109         {
110           $$= $2.bit_address;
111           if ($$ < 0)
112             {
113               yyerror((char *)"Bit has no address.");
114               $$= 0;
115             }
116         }
117         ;
118
119 memory:
120           PTOK_MEMORY
121         | PTOK_MEMORY_OBJECT PTOK_LEFT_BRACKET expression PTOK_RIGHT_BRACKET
122           {
123             $$.memory= $1;
124             $$.address= $3;
125           }
126
127 bit:
128           PTOK_BIT
129         | memory PTOK_DOT expression
130           {
131             $$.memory= $1.memory;
132             $$.mem_address= $1.address;
133             $$.mask= 1 << $3;
134             $$.bit_address= -1;
135             class cl_uc *uc= application->get_uc();
136             if (uc)
137               $$.bit_address= uc->bit_address($1.memory, $1.address, $3);
138           }
139         ;
140
141 %%
142
143 int
144 YY_cl_ucsim_parser_CLASS::yylex(YY_cl_ucsim_parser_STYPE *yylval)
145 {
146   lexer_object->activate_lexer_to_parse_into(yylval);
147   return(lexer_object->yylex());
148 }
149
150 void
151 YY_cl_ucsim_parser_CLASS::yyerror(char *msg)
152 {
153   application->dd_printf("Parser error: %s\n", msg);
154 }