Skip to content

Commit 4e934d5

Browse files
committed
Add Inc/Dec operator, Compound Assginment Operator
Increment, // ++ Decrement, // -- PlusAssign, // += MinusAssign, // -= AsteriskAssign, // *= SlashAssign, // /=
1 parent 42842c5 commit 4e934d5

File tree

5 files changed

+134
-43
lines changed

5 files changed

+134
-43
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
- name: fmt check
2020
run: cargo fmt -- --check
2121
- name: lint
22-
run: cargo clippy -- -D warnings
22+
run: cargo clippy
2323
- name: build
2424
run: cargo build --verbose
2525
- name: run tests

src/lexer/lexer.rs

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,53 @@ impl Lexer {
8787
pub fn next_token(&mut self) -> Token {
8888
self.skip_trivia();
8989
let tok = match self.ch {
90-
Some('+') => Token::Plus,
91-
Some('-') => Token::Minus,
92-
Some('*') => Token::Asterisk,
93-
Some('/') => Token::Slash,
90+
Some('+') => {
91+
// ++
92+
if self.peek_char() == Some('+') {
93+
self.read_char();
94+
Token::Increment
95+
// +=
96+
} else if self.peek_char() == Some('=') {
97+
self.read_char();
98+
Token::PlusAssign
99+
// +
100+
} else {
101+
Token::Plus
102+
}
103+
}
104+
105+
Some('-') => {
106+
// --
107+
if self.peek_char() == Some('-') {
108+
self.read_char();
109+
Token::Decrement
110+
// -=
111+
} else if self.peek_char() == Some('=') {
112+
self.read_char();
113+
Token::MinusAssign
114+
// -
115+
} else {
116+
Token::Minus
117+
}
118+
}
119+
120+
Some('*') => {
121+
if self.peek_char() == Some('=') {
122+
self.read_char();
123+
Token::AsteriskAssign
124+
} else {
125+
Token::Asterisk
126+
}
127+
}
128+
129+
Some('/') => {
130+
if self.peek_char() == Some('=') {
131+
self.read_char();
132+
Token::SlashAssign
133+
} else {
134+
Token::Slash
135+
}
136+
}
94137
Some('%') => Token::Percent,
95138

96139
Some('=') => {

src/lexer/token.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,14 @@ pub enum Token {
6565
// Types
6666
Int,
6767
Char,
68-
// Increment, // ++
69-
// Decrement, // --
70-
// PlusAssign, // +=
71-
// MinusAssign, // -=
68+
69+
70+
Increment, // ++
71+
Decrement, // --
72+
PlusAssign, // +=
73+
MinusAssign, // -=
74+
AsteriskAssign, // *=
75+
SlashAssign, // /=
7276
}
7377

7478
/// Lookup identifier keyword

tests/fixtures/sample.c

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ int add(int a, int b) {
44

55
int factorial(int n) {
66
int result = 1;
7-
// for (int i = 1; i <= n; ++i) {
8-
// result *= i;
7+
for (int i = 1; i <= n; ++i) {
8+
result *= i;
99
}
1010
return result;
1111
}
@@ -28,16 +28,17 @@ int main() {
2828
char ch3 = '\0';
2929
char buf[5] = {'h','e','l','l','o'}; // 고정 크기 배열
3030
int arr2[3];
31-
// for (int i = 0; i < 3; i++) {
31+
for (int i = 0; i < 3; i++) {
3232
arr2[i] = i * 2;
3333
}
3434

3535
// 포인터 산술 및 복합 할당, 증감 연산
36-
// *p += 10;
37-
// x -= 5;
38-
// x++;
39-
// ++x;
40-
// --x;
36+
*p += 10;
37+
x -= 5;
38+
x++;
39+
++x;
40+
--x;
41+
x--;
4142

4243
// 논리 연산자, 비교 연산자
4344
if (x > 10 && x < 100) {
@@ -55,13 +56,13 @@ int main() {
5556
int count = 0;
5657
while (count < 5) {
5758
if (count == 2) {
58-
// count++;
59+
count++;
5960
continue;
6061
}
6162
if (count == 4) {
6263
break;
6364
}
64-
// count += 1;
65+
count += 1;
6566
}
6667

6768
return 0;

tests/lexer_c_fixture_test.rs

Lines changed: 67 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,28 @@ fn test_sample_c_tokens() {
4646
assert_eq!(next_token(), Token::IntLiteral(1));
4747
assert_eq!(next_token(), Token::Semicolon);
4848

49-
// todo
5049
// for (int i = 1; i <= n; ++i) {
50+
assert_eq!(next_token(), Token::For);
51+
assert_eq!(next_token(), Token::LParen);
52+
assert_eq!(next_token(), Token::Int);
53+
assert_eq!(next_token(), Token::Ident("i".into()));
54+
assert_eq!(next_token(), Token::Assign);
55+
assert_eq!(next_token(), Token::IntLiteral(1));
56+
assert_eq!(next_token(), Token::Semicolon);
57+
assert_eq!(next_token(), Token::Ident("i".into()));
58+
assert_eq!(next_token(), Token::Le);
59+
assert_eq!(next_token(), Token::Ident("n".into()));
60+
assert_eq!(next_token(), Token::Semicolon);
61+
assert_eq!(next_token(), Token::Increment);
62+
assert_eq!(next_token(), Token::Ident("i".into()));
63+
assert_eq!(next_token(), Token::RParen);
64+
assert_eq!(next_token(), Token::LBrace);
65+
5166
// result *= i;
67+
assert_eq!(next_token(), Token::Ident("result".into()));
68+
assert_eq!(next_token(), Token::AsteriskAssign);
69+
assert_eq!(next_token(), Token::Ident("i".into()));
70+
assert_eq!(next_token(), Token::Semicolon);
5271

5372
// }
5473
assert_eq!(next_token(), Token::RBrace);
@@ -184,23 +203,22 @@ fn test_sample_c_tokens() {
184203
assert_eq!(next_token(), Token::RBracket);
185204
assert_eq!(next_token(), Token::Semicolon);
186205

187-
// todo
188206
// for (int i = 0; i < 3; i++) {
189-
// assert_eq!(next_token(), Token::For);
190-
// assert_eq!(next_token(), Token::LParen);
191-
// assert_eq!(next_token(), Token::Int);
192-
// assert_eq!(next_token(), Token::Ident("i".into()));
193-
// assert_eq!(next_token(), Token::Assign);
194-
// assert_eq!(next_token(), Token::IntLiteral(0));
195-
// assert_eq!(next_token(), Token::Semicolon);
196-
// assert_eq!(next_token(), Token::Ident("i".into()));
197-
// assert_eq!(next_token(), Token::Lt);
198-
// assert_eq!(next_token(), Token::IntLiteral(3));
199-
// assert_eq!(next_token(), Token::Semicolon);
200-
// assert_eq!(next_token(), Token::Ident("i".into()));
201-
// assert_eq!(next_token(), Token::PlusPlus);
202-
// assert_eq!(next_token(), Token::RParen);
203-
// assert_eq!(next_token(), Token::LBrace);
207+
assert_eq!(next_token(), Token::For);
208+
assert_eq!(next_token(), Token::LParen);
209+
assert_eq!(next_token(), Token::Int);
210+
assert_eq!(next_token(), Token::Ident("i".into()));
211+
assert_eq!(next_token(), Token::Assign);
212+
assert_eq!(next_token(), Token::IntLiteral(0));
213+
assert_eq!(next_token(), Token::Semicolon);
214+
assert_eq!(next_token(), Token::Ident("i".into()));
215+
assert_eq!(next_token(), Token::Lt);
216+
assert_eq!(next_token(), Token::IntLiteral(3));
217+
assert_eq!(next_token(), Token::Semicolon);
218+
assert_eq!(next_token(), Token::Ident("i".into()));
219+
assert_eq!(next_token(), Token::Increment);
220+
assert_eq!(next_token(), Token::RParen);
221+
assert_eq!(next_token(), Token::LBrace);
204222

205223
// arr2[i] = i * 2;
206224
assert_eq!(next_token(), Token::Ident("arr2".into()));
@@ -216,12 +234,35 @@ fn test_sample_c_tokens() {
216234
// }
217235
assert_eq!(next_token(), Token::RBrace);
218236

219-
// todo
220237
// *p += 10;
238+
assert_eq!(next_token(), Token::Asterisk);
239+
assert_eq!(next_token(), Token::Ident("p".into()));
240+
assert_eq!(next_token(), Token::PlusAssign);
241+
assert_eq!(next_token(), Token::IntLiteral(10));
242+
assert_eq!(next_token(), Token::Semicolon);
243+
221244
// x -= 5;
245+
assert_eq!(next_token(), Token::Ident("x".into()));
246+
assert_eq!(next_token(), Token::MinusAssign);
247+
assert_eq!(next_token(), Token::IntLiteral(5));
248+
assert_eq!(next_token(), Token::Semicolon);
249+
222250
// x++;
251+
assert_eq!(next_token(), Token::Ident("x".into()));
252+
assert_eq!(next_token(), Token::Increment);
253+
assert_eq!(next_token(), Token::Semicolon);
223254
// ++x;
255+
assert_eq!(next_token(), Token::Increment);
256+
assert_eq!(next_token(), Token::Ident("x".into()));
257+
assert_eq!(next_token(), Token::Semicolon);
224258
// --x;
259+
assert_eq!(next_token(), Token::Decrement);
260+
assert_eq!(next_token(), Token::Ident("x".into()));
261+
assert_eq!(next_token(), Token::Semicolon);
262+
// x--
263+
assert_eq!(next_token(), Token::Ident("x".into()));
264+
assert_eq!(next_token(), Token::Decrement);
265+
assert_eq!(next_token(), Token::Semicolon);
225266

226267
// if (x > 10 && x < 100) {
227268
assert_eq!(next_token(), Token::If);
@@ -318,11 +359,10 @@ fn test_sample_c_tokens() {
318359
assert_eq!(next_token(), Token::RParen);
319360
assert_eq!(next_token(), Token::LBrace);
320361

321-
// todo
322-
// count++;
323-
// assert_eq!(next_token(), Token::Ident("count".into()));
324-
// assert_eq!(next_token(), Token::PlusPlus);
325-
// assert_eq!(next_token(), Token::Semicolon);
362+
// count++;
363+
assert_eq!(next_token(), Token::Ident("count".into()));
364+
assert_eq!(next_token(), Token::Increment);
365+
assert_eq!(next_token(), Token::Semicolon);
326366

327367
// continue;
328368
assert_eq!(next_token(), Token::Continue);
@@ -345,8 +385,11 @@ fn test_sample_c_tokens() {
345385

346386
assert_eq!(next_token(), Token::RBrace);
347387

348-
// todo
349388
// count += 1;
389+
assert_eq!(next_token(), Token::Ident("count".into()));
390+
assert_eq!(next_token(), Token::PlusAssign);
391+
assert_eq!(next_token(), Token::IntLiteral(1));
392+
assert_eq!(next_token(), Token::Semicolon);
350393

351394
// }
352395
assert_eq!(next_token(), Token::RBrace);

0 commit comments

Comments
 (0)