Skip to content

Commit 112716a

Browse files
committed
比較演算子に対応
1 parent cf636b6 commit 112716a

File tree

8 files changed

+148
-8
lines changed

8 files changed

+148
-8
lines changed

BNF.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
program = expr ("," expr | "\n" expr)*
2-
expr = ident "=" add | add
2+
expr = ident "=" compare | compare
3+
compare = add | add ("==" | "!=" | "<" | "<=" | ">" | ">=") add
34
add = mul ("+" mul | "-" mul)*
45
mul = unary ("*" unary | "/" unary)*
56
unary = ("+" | "-")? primary
6-
primary = ident | num | "(" add ")"
7+
primary = ident | num | "(" compare ")"

generator.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,46 @@ void Generator::gen(Node* node)
9292

9393
break;
9494

95+
case ND_EQ:
96+
gen(node->left);
97+
gen(node->right);
98+
99+
operations.push_back( Operation{ OP_POP, REG_GR0 } );
100+
operations.push_back( Operation{ OP_POP, REG_GR1 } );
101+
operations.push_back( Operation{ OP_EQ, REG_GR1, REG_GR0 } );
102+
103+
break;
104+
105+
case ND_NEQ:
106+
gen(node->left);
107+
gen(node->right);
108+
109+
operations.push_back( Operation{ OP_POP, REG_GR0 } );
110+
operations.push_back( Operation{ OP_POP, REG_GR1 } );
111+
operations.push_back( Operation{ OP_NEQ, REG_GR1, REG_GR0 } );
112+
113+
break;
114+
115+
case ND_LESS:
116+
gen(node->left);
117+
gen(node->right);
118+
119+
operations.push_back( Operation{ OP_POP, REG_GR0 } );
120+
operations.push_back( Operation{ OP_POP, REG_GR1 } );
121+
operations.push_back( Operation{ OP_LESS, REG_GR1, REG_GR0 } );
122+
123+
break;
124+
125+
case ND_EQLESS:
126+
gen(node->left);
127+
gen(node->right);
128+
129+
operations.push_back( Operation{ OP_POP, REG_GR0 } );
130+
operations.push_back( Operation{ OP_POP, REG_GR1 } );
131+
operations.push_back( Operation{ OP_EQLESS, REG_GR1, REG_GR0 } );
132+
133+
break;
134+
95135
case ND_ASSIGN:
96136
gen_var(node->left);
97137
gen(node->right);

parser.cpp

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,47 @@ vector<Node*> Parser::program(void)
2222

2323
Node* Parser::expr(void)
2424
{
25-
if(TK_IDENT == token->kind && strncmp((token+1)->str, "=", 1) == 0){
25+
if(TK_IDENT == token->kind && strncmp((token+1)->str, "=", 1) == 0 && (token+1)->len == 1){
2626
Node* ident = new Node();
2727
ident->kind = ND_IDENT;
2828
ident->name = token->str;
2929
ident->len = token->len;
3030
token++;
3131
expect("=");
32-
Node* setNode = new Node{ ND_ASSIGN, ident, add() };
33-
return setNode;
32+
Node* node = new Node{ ND_ASSIGN, ident, compare() };
33+
return node;
3434
}
3535

36-
return add();
36+
return compare();
37+
};
38+
39+
Node* Parser::compare(void)
40+
{
41+
Node* addNode = add();
42+
Node* node;
43+
if(consume("==")){
44+
node = new Node{ ND_EQ, addNode, add()};
45+
}
46+
else if(consume("!=")){
47+
node = new Node{ ND_NEQ, addNode, add()};
48+
}
49+
else if(consume("<")){
50+
node = new Node{ ND_LESS, addNode, add()};
51+
}
52+
else if(consume("<=")){
53+
node = new Node{ ND_EQLESS, addNode, add()};
54+
}
55+
else if(consume(">")){
56+
node = new Node{ ND_LESS, add(), addNode}; // 右左辺を入れ替え
57+
}
58+
else if(consume(">=")){
59+
node = new Node{ ND_EQLESS, add(), addNode}; // 右左辺を入れ替え
60+
}
61+
else{
62+
return addNode;
63+
}
64+
65+
return node;
3766
};
3867

3968
Node* Parser::num(void)
@@ -104,9 +133,9 @@ Node* Parser::unary(void)
104133
Node* Parser::primary(void)
105134
{
106135
if(consume("(")){
107-
Node* addNode = add();
136+
Node* node = compare();
108137
expect(")");
109-
return addNode;
138+
return node;
110139
}
111140
else if(TK_IDENT == token->kind){
112141
Node* ident = new Node();

parser.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ class Parser
1313

1414
vector<Node*> program(void);
1515
Node* expr(void);
16+
Node* compare(void);
1617
Node* num(void);
1718
Node* add(void);
1819
Node* mul(void);

rook.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ typedef enum {
2929
ND_DIV, // /
3030
ND_ASSIGN, // =
3131
ND_IDENT, // 識別子
32+
ND_EQ, // ==
33+
ND_NEQ, // !=
34+
ND_LESS, // <
35+
ND_EQLESS, // <=
3236
} NodeKind;
3337

3438
typedef struct Node Node;
@@ -52,6 +56,10 @@ typedef enum {
5256
OP_SUB, // 減算
5357
OP_MUL, // 乗算
5458
OP_DIV, // 除算
59+
OP_EQ, // ==
60+
OP_NEQ, // !=
61+
OP_LESS, // <
62+
OP_EQLESS, // <=
5563
OP_STORE, // レジスタ→メモリへの書き込み
5664
OP_LOAD, // メモリ→レジスタへの読み込み
5765
} OP_CODE;

test.sh

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,16 @@ test 9 "num = 3, num * num"
3838
test 10 "a = 5, b = 2, c = a * b"
3939
test 2 "a = -3, a + 5"
4040
test 12 "n = 2, ret = 3 * (n + 2)"
41+
test 1 "1==1"
42+
test 0 "1==2"
43+
test 0 "1!=1"
44+
test 1 "1!=0"
45+
test 1 "0<1"
46+
test 0 "1<1"
47+
test 1 "1<=1"
48+
test 0 "1<=0"
49+
test 1 "1>=1"
50+
test 0 "0>=1"
51+
test 1 "num = 1, num = num + 1, num == 2"
4152

4253
echo "OK"

tokenizer.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,36 @@ vector<Token> Tokenizer::tokenize(char* input)
6666
tokens.push_back(token);
6767
input++;
6868
}
69+
else if(strncmp(input, "==", 2) == 0){
70+
Token token = { TK_RESERVED, input, 2 };
71+
tokens.push_back(token);
72+
input += 2;
73+
}
74+
else if(strncmp(input, "!=", 2) == 0){
75+
Token token = { TK_RESERVED, input, 2 };
76+
tokens.push_back(token);
77+
input += 2;
78+
}
79+
else if(strncmp(input, "<=", 2) == 0){
80+
Token token = { TK_RESERVED, input, 2 };
81+
tokens.push_back(token);
82+
input += 2;
83+
}
84+
else if(strncmp(input, "<", 1) == 0){
85+
Token token = { TK_RESERVED, input, 1 };
86+
tokens.push_back(token);
87+
input++;
88+
}
89+
else if(strncmp(input, ">=", 2) == 0){
90+
Token token = { TK_RESERVED, input, 2 };
91+
tokens.push_back(token);
92+
input += 2;
93+
}
94+
else if(strncmp(input, ">", 1) == 0){
95+
Token token = { TK_RESERVED, input, 1 };
96+
tokens.push_back(token);
97+
input++;
98+
}
6999
else if(strncmp(input, "=", 1) == 0){
70100
Token token = { TK_RESERVED, input, 1 };
71101
tokens.push_back(token);

vm.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,26 @@ DWORD VM::run(vector<Operation>& code)
6262
push(reg[op->operand] / reg[op->operand2]);
6363
break;
6464
}
65+
case OP_EQ:
66+
{
67+
push(reg[op->operand] == reg[op->operand2]);
68+
break;
69+
}
70+
case OP_NEQ:
71+
{
72+
push(reg[op->operand] != reg[op->operand2]);
73+
break;
74+
}
75+
case OP_LESS:
76+
{
77+
push(reg[op->operand] < reg[op->operand2]);
78+
break;
79+
}
80+
case OP_EQLESS:
81+
{
82+
push(reg[op->operand] <= reg[op->operand2]);
83+
break;
84+
}
6585
case OP_STORE:
6686
{
6787
bp[reg[op->operand]] = reg[op->operand2];

0 commit comments

Comments
 (0)