66#include <stdlib.h>
77#include <string.h>
88
9+ // program = stmt*
10+ // stmt = expr ";"
11+ // expr = assign
12+ // assign = equality ("=" assign)?
13+ // equality = relational ("==" relational | "!=" relational)
14+ // relational = add ("<" add | "<=" add | ">" add | ">=" add)*
15+ // add = mul ("+" mul | "-" mul)*
16+ // mul = unary ("*" unary | "/" unary)*
17+ // unary = ("+" | "-")? primary
18+ // primary = num | ident | "(" expr ")"
19+
20+ // program = stmt*
21+ void program () {
22+ int i = 0 ;
23+ while (!at_eof ())
24+ code [i ++ ] = stmt ();
25+ code [i ] = NULL ;
26+ }
27+
28+ // stmt = expr ";"
29+ Node * stmt () {
30+ Node * node = expr ();
31+ expect (";" );
32+ return node ;
33+ }
34+
35+ // expr = assign
936Node * expr () {
10- return equality ();
37+ return assign ();
38+ }
39+
40+ // assign = equality ("=" assign)?
41+ Node * assign () {
42+ Node * node = equality ();
43+ if (consume ("=" ))
44+ node = new_node (ND_ASSIGN , node , assign ());
45+ return node ;
1146}
1247
1348// equality = relatinal ("==" relational | "!=" relational)
@@ -87,17 +122,49 @@ Node *primary() {
87122 return node ;
88123 }
89124
125+ Token * tok = consume_ident ();
126+ if (tok ) {
127+ // 次のトークンが識別子なら、それは変数のはず
128+ Node * node = calloc (1 , sizeof (Node ));
129+ node -> kind = ND_LVAR ;
130+ node -> offset = (tok -> str [0 ] - 'a' + 1 ) * 8 ;
131+ return node ;
132+ }
133+
90134 // そうでなければ数値のはず
91135 return new_node_num (expect_number ());
92136}
93137
138+ void gen_lval (Node * node ) {
139+ if (node -> kind != ND_LVAR )
140+ error ("代入の左辺値が変数ではありません" );
94141
142+ printf (" mov rax, rbp" );
143+ printf (" sub rax, %d\n" , node -> offset );
144+ printf (" push rax\n" );
145+ }
95146
96147// x86-64のスタック操作命令を使って,スタックマシンを模倣するアセンブリを吐く関数
97148void gen (Node * node ) {
98- if (node -> kind == ND_NUM ) {
149+ switch (node -> kind ) {
150+ case ND_NUM :
99151 printf (" push %d\n" , node -> val );
100152 return ;
153+ case ND_LVAR :
154+ gen_lval (node );
155+ printf (" pop rax\n" );
156+ printf (" mov rax, [rax]\n" );
157+ printf (" push rax\n" );
158+ return ;
159+ case ND_ASSIGN :
160+ gen_lval (node -> lhs );
161+ gen (node -> rhs );
162+
163+ printf (" pop rdi\n" );
164+ printf (" pop rax\n" );
165+ printf (" mov [rax], rdi\n" );
166+ printf (" push rdi\n" );
167+ return ;
101168 }
102169
103170 gen (node -> lhs );
@@ -107,26 +174,6 @@ void gen(Node *node) {
107174 printf (" pop rax\n" );
108175
109176 switch (node -> kind ) {
110- case ND_EQ :
111- printf (" cmp rax, rdi\n" );
112- printf (" sete al\n" );
113- printf (" movzb rax, al\n" );
114- break ;
115- case ND_NE :
116- printf (" cmp rax, rdi\n" );
117- printf (" setne al\n" );
118- printf (" movzb rax, al\n" );
119- break ;
120- case ND_LT :
121- printf (" cmp rax, rdi\n" );
122- printf (" setl al\n" );
123- printf (" movzb rax, al\n" );
124- break ;
125- case ND_LE :
126- printf (" cmp rax, rdi\n" );
127- printf (" setle al\n" );
128- printf (" movzb rax, al\n" );
129- break ;
130177 case ND_ADD :
131178 printf (" add rax, rdi\n" );
132179 break ;
0 commit comments