aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2025-08-14 21:54:53 +0900
committernsfisis <nsfisis@gmail.com>2025-08-15 10:06:21 +0900
commitdbc4b194265bf37d1dc8fb9ba067e3c3240d9d70 (patch)
treeb34b47051be639eba70454194307d5e3886fa14d
parentcefe477fdf8c8a7a081e08add9cafbe1d8a2acf0 (diff)
downloadducc-dbc4b194265bf37d1dc8fb9ba067e3c3240d9d70.tar.gz
ducc-dbc4b194265bf37d1dc8fb9ba067e3c3240d9d70.tar.zst
ducc-dbc4b194265bf37d1dc8fb9ba067e3c3240d9d70.zip
feat: implement comma operator
-rw-r--r--parse.c26
-rw-r--r--tests/090.sh21
2 files changed, 44 insertions, 3 deletions
diff --git a/parse.c b/parse.c
index fb5c751..c9b2886 100644
--- a/parse.c
+++ b/parse.c
@@ -260,6 +260,7 @@ void leave_func(Parser* p) {
leave_scope(p);
}
+AstNode* parse_assignment_expr(Parser* p);
AstNode* parse_expr(Parser* p);
AstNode* parse_stmt(Parser* p);
@@ -334,7 +335,7 @@ AstNode* parse_primary_expr(Parser* p) {
AstNode* parse_arg_list(Parser* p) {
AstNode* list = ast_new_list(6);
while (peek_token(p)->kind != TokenKind_paren_r) {
- AstNode* arg = parse_expr(p);
+ AstNode* arg = parse_assignment_expr(p);
ast_append(list, arg);
if (peek_token(p)->kind == TokenKind_comma) {
next_token(p);
@@ -730,8 +731,27 @@ AstNode* parse_assignment_expr(Parser* p) {
return lhs;
}
+AstNode* parse_comma_expr(Parser* p) {
+ AstNode* lhs = parse_assignment_expr(p);
+ while (1) {
+ TokenKind op = peek_token(p)->kind;
+ if (op == TokenKind_comma) {
+ next_token(p);
+ AstNode* rhs = parse_assignment_expr(p);
+ AstNode* list = ast_new_list(2);
+ ast_append(list, lhs);
+ ast_append(list, rhs);
+ list->ty = rhs->ty;
+ lhs = list;
+ } else {
+ break;
+ }
+ }
+ return lhs;
+}
+
AstNode* parse_expr(Parser* p) {
- return parse_assignment_expr(p);
+ return parse_comma_expr(p);
}
AstNode* parse_return_stmt(Parser* p) {
@@ -789,7 +809,7 @@ AstNode* parse_var_decl(Parser* p) {
AstNode* init = NULL;
if (peek_token(p)->kind == TokenKind_assign) {
next_token(p);
- init = parse_expr(p);
+ init = parse_assignment_expr(p);
}
expect(p, TokenKind_semicolon);
diff --git a/tests/090.sh b/tests/090.sh
new file mode 100644
index 0000000..102b9ab
--- /dev/null
+++ b/tests/090.sh
@@ -0,0 +1,21 @@
+set -e
+
+cat <<'EOF' > expected
+0 0
+1 1
+2 2
+3 3
+4 4
+EOF
+
+bash ../../test_diff.sh <<'EOF'
+int printf();
+
+int main() {
+ int i = 1000;
+ int j = 1000;
+ for (i = 0, j = 0; i < 5; i++, j++) {
+ printf("%d %d\n", i, j);
+ }
+}
+EOF