Skip to content

Refactor/ast expr#28

Merged
broccolingual merged 5 commits into
mainfrom
refactor/ast-expr
Jan 11, 2026
Merged

Refactor/ast expr#28
broccolingual merged 5 commits into
mainfrom
refactor/ast-expr

Conversation

@broccolingual
Copy link
Copy Markdown
Owner

No description provided.

@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello @broccolingual, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request refactors the Abstract Syntax Tree (AST) expression parsing logic by introducing generic helper functions for binary, unary, and logical operators. This significantly cleans up and modularizes the expression parsing code. Additionally, it extends the compiler's capabilities by adding support for the comma operator, unary plus and minus, and the greater than/equal relational operators, along with corresponding type checking and x86 code generation.

Highlights

  • Generalized Expression Parsing: Introduced helper functions (parse_binary_op, parse_unary_op, parse_logical_op) to abstract and reuse common parsing patterns for binary, unary, and logical operators, significantly reducing code duplication in src/ast/expr.rs.
  • Comma Operator Support: Added full support for the comma operator (,) in expressions, including its AST representation (NodeKind::Comma), parsing logic, and x86 code generation, where the left-hand side is evaluated for side effects and its result discarded, and the right-hand side's value is used.
  • Unary Plus and Minus Operators: Implemented unary + and - operators, including their AST representation (UnaryOp::Plus, UnaryOp::Minus), parsing, type checking (ensuring integer types), and x86 code generation.
  • Greater Than/Equal Relational Operators: Extended the parser and code generator to support > (greater than) and >= (greater than or equal) relational operators.
  • New Test Cases: Added comprehensive inline test cases for the newly implemented comma operator to ensure correct behavior and side effects.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

素晴らしいリファクタリングですね! parse_binary_op などのヘルパー関数を導入することで、各式パーサーのコードの重複が大幅に削減され、見通しが良く、メンテナンスしやすくなっていると思います。カンマ演算子や単項の +/- 演算子の実装も追加され、機能的にも改善されています。全体として、コードの品質を大きく向上させる良い変更だと感じました。

Comment thread src/ast/expr.rs
Comment on lines +24 to +44
loop {
let mut matched = false;
for (op_str, constructor) in operators {
if let Some(span) = self.consume_punct(op_str) {
let lhs = node.ok_or_else(|| CompileError::InvalidExpr {
msg: format!("'{}'演算子の左辺値がありません", op_str),
span,
})?;
let rhs = next_parser(self)?.ok_or_else(|| CompileError::InvalidExpr {
msg: format!("'{}'演算子の右辺値がありません", op_str),
span,
})?;
node = Some(Box::new(constructor(lhs, rhs, span)?));
matched = true;
break;
}
}
if !matched {
return Ok(node);
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

matched フラグを使ったループは、よりRustらしいイディオムで書き換えることで、さらに可読性を高めることができます。peek_punct で演算子を先に確認し、iter().find() を使うことで、ネストを減らし、ループの意図をより明確にできます。

        loop {
            if let Some((op_str, constructor)) = operators.iter().find(|(s, _)| self.peek_punct(s)) {
                let span = self.consume_punct(op_str).unwrap(); // peek_punctで確認済みのため安全
                let lhs = node.ok_or_else(|| CompileError::InvalidExpr {
                    msg: format!("'{}'演算子の左辺値がありません", op_str),
                    span,
                })?;
                let rhs = next_parser(self)?.ok_or_else(|| CompileError::InvalidExpr {
                    msg: format!("'{}'演算子の右辺値がありません", op_str),
                    span,
                })?;
                node = Some(Box::new(constructor(lhs, rhs, span)?));
            } else {
                return Ok(node);
            }
        }

@broccolingual
Copy link
Copy Markdown
Owner Author

/gemini review

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

このプルリクエストは、式の解析ロジックを大幅にリファクタリングするもので、素晴らしい改善です。parse_binary_opparse_unary_opparse_logical_opといったヘルパー関数を導入することで、コードの重複が大幅に削減され、各演算子の優先順位と結合規則の処理が非常に明確になりました。

また、カンマ演算子や単項の+/-演算子のサポートが追加され、関連するテストも整備されている点を高く評価します。

1点、単項演算子の型チェックに関して、浮動小数点型が考慮されていない問題を見つけましたので、修正提案をコメントしました。

全体として、コードの品質と保守性を大きく向上させる優れたリファクタリングです。

Comment thread src/node.rs
Comment on lines +239 to +249
if expr_ty.is_integer() {
TypeRef::register(TypeKind::Int, TypeAttr::default(), None) // 整数拡張
} else {
return Err(CompileError::InvalidExpr {
msg: format!(
"単項演算子 '{:?}' は整数型にのみ適用可能です: {:?}",
op, expr_ty
),
span,
});
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

C言語の仕様では、単項の+および-演算子は整数型だけでなく、浮動小数点型にも適用できます。現在の実装では整数型のみを許可しているため、floatdouble型の変数に対してこれらの演算子を使うとコンパイルエラーになってしまいます。

算術型(整数と浮動小数点)を許可するように修正し、エラーメッセージも修正することを提案します。

Suggested change
if expr_ty.is_integer() {
TypeRef::register(TypeKind::Int, TypeAttr::default(), None) // 整数拡張
} else {
return Err(CompileError::InvalidExpr {
msg: format!(
"単項演算子 '{:?}' は整数型にのみ適用可能です: {:?}",
op, expr_ty
),
span,
});
}
if expr_ty.is_integer() {
TypeRef::register(TypeKind::Int, TypeAttr::default(), None) // 整数拡張
} else if expr_ty.is_floating_point() {
expr_ty // 浮動小数点型はそのまま
} else {
return Err(CompileError::InvalidExpr {
msg: format!(
"単項演算子 '{:?}' は算術型にのみ適用可能です: {:?}",
op, expr_ty
),
span,
});
}

Comment thread src/ast/expr.rs
loop {
if let Some((op_str, constructor)) = operators.iter().find(|(s, _)| self.peek_punct(s))
{
let span = self.consume_punct(op_str).unwrap(); // peek_punctで確認済みのため安全
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

peek_punctで存在を確認しているため、ここのunwrap()がパニックすることはないはずですが、より安全で意図が明確になるようにexpect()を使うことをお勧めします。expect()を使うと、万が一ロジックの変更などでパニックした場合に、デバッグに役立つメッセージを残すことができます。

Suggested change
let span = self.consume_punct(op_str).unwrap(); // peek_punctで確認済みのため安全
let span = self.consume_punct(op_str).expect("peek_punctで確認済みのため安全なはず"); // peek_punctで確認済みのため安全

@broccolingual broccolingual reopened this Jan 11, 2026
@broccolingual broccolingual merged commit 03d56c7 into main Jan 11, 2026
2 checks passed
@broccolingual broccolingual deleted the refactor/ast-expr branch January 11, 2026 15:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant