-
Notifications
You must be signed in to change notification settings - Fork 16
SY-3484: Implement Support for Compound Assignment Operators in Arc #1802
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
emilbon99
wants to merge
2
commits into
sy-3242-implement-string-literal-parsing-in-arc
Choose a base branch
from
sy-3484-implement-support-for-compounding-assignment-operators
base: sy-3242-implement-string-literal-parsing-in-arc
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
…ps://github.com/synnaxlabs/synnax into sy-3484-implement-support-for-compounding-assignment-operators
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
13 files reviewed, 1 comment
Comment on lines
+507
to
+560
| DescribeTable("Compound assignment operators", func(source string, instructions ...any) { | ||
| Expect(compileBlock(source)).To(MatchOpcodes(instructions...)) | ||
| }, | ||
| Entry("i64 plus equals", | ||
| `x i64 := 10 | ||
| x += 5`, | ||
| OpI64Const, int64(10), | ||
| OpLocalSet, 0, | ||
| OpLocalGet, 0, | ||
| OpI64Const, int64(5), | ||
| OpI64Add, | ||
| OpLocalSet, 0, | ||
| ), | ||
| Entry("f64 minus equals", | ||
| `x f64 := 10.0 | ||
| x -= 2.5`, | ||
| OpF64Const, float64(10.0), | ||
| OpLocalSet, 0, | ||
| OpLocalGet, 0, | ||
| OpF64Const, 2.5, | ||
| OpF64Sub, | ||
| OpLocalSet, 0, | ||
| ), | ||
| Entry("i32 multiply equals", | ||
| `x i32 := 3 | ||
| x *= 4`, | ||
| OpI32Const, int32(3), | ||
| OpLocalSet, 0, | ||
| OpLocalGet, 0, | ||
| OpI32Const, int32(4), | ||
| OpI32Mul, | ||
| OpLocalSet, 0, | ||
| ), | ||
| Entry("f32 divide equals", | ||
| `x f32 := 10.0 | ||
| x /= 2.0`, | ||
| OpF32Const, float32(10.0), | ||
| OpLocalSet, 0, | ||
| OpLocalGet, 0, | ||
| OpF32Const, float32(2.0), | ||
| OpF32Div, | ||
| OpLocalSet, 0, | ||
| ), | ||
| Entry("i64 modulo equals", | ||
| `x i64 := 17 | ||
| x %= 5`, | ||
| OpI64Const, int64(17), | ||
| OpLocalSet, 0, | ||
| OpLocalGet, 0, | ||
| OpI64Const, int64(5), | ||
| OpI64RemS, | ||
| OpLocalSet, 0, | ||
| ), | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style: Missing test for string concatenation with +=.
Add test case:
Suggested change
| DescribeTable("Compound assignment operators", func(source string, instructions ...any) { | |
| Expect(compileBlock(source)).To(MatchOpcodes(instructions...)) | |
| }, | |
| Entry("i64 plus equals", | |
| `x i64 := 10 | |
| x += 5`, | |
| OpI64Const, int64(10), | |
| OpLocalSet, 0, | |
| OpLocalGet, 0, | |
| OpI64Const, int64(5), | |
| OpI64Add, | |
| OpLocalSet, 0, | |
| ), | |
| Entry("f64 minus equals", | |
| `x f64 := 10.0 | |
| x -= 2.5`, | |
| OpF64Const, float64(10.0), | |
| OpLocalSet, 0, | |
| OpLocalGet, 0, | |
| OpF64Const, 2.5, | |
| OpF64Sub, | |
| OpLocalSet, 0, | |
| ), | |
| Entry("i32 multiply equals", | |
| `x i32 := 3 | |
| x *= 4`, | |
| OpI32Const, int32(3), | |
| OpLocalSet, 0, | |
| OpLocalGet, 0, | |
| OpI32Const, int32(4), | |
| OpI32Mul, | |
| OpLocalSet, 0, | |
| ), | |
| Entry("f32 divide equals", | |
| `x f32 := 10.0 | |
| x /= 2.0`, | |
| OpF32Const, float32(10.0), | |
| OpLocalSet, 0, | |
| OpLocalGet, 0, | |
| OpF32Const, float32(2.0), | |
| OpF32Div, | |
| OpLocalSet, 0, | |
| ), | |
| Entry("i64 modulo equals", | |
| `x i64 := 17 | |
| x %= 5`, | |
| OpI64Const, int64(17), | |
| OpLocalSet, 0, | |
| OpLocalGet, 0, | |
| OpI64Const, int64(5), | |
| OpI64RemS, | |
| OpLocalSet, 0, | |
| ), | |
| ) | |
| DescribeTable("Compound assignment operators", func(source string, instructions ...any) { | |
| Expect(compileBlock(source)).To(MatchOpcodes(instructions...)) | |
| }, | |
| Entry("i64 plus equals", | |
| `x i64 := 10 | |
| x += 5`, | |
| OpI64Const, int64(10), | |
| OpLocalSet, 0, | |
| OpLocalGet, 0, | |
| OpI64Const, int64(5), | |
| OpI64Add, | |
| OpLocalSet, 0, | |
| ), | |
| Entry("f64 minus equals", | |
| `x f64 := 10.0 | |
| x -= 2.5`, | |
| OpF64Const, float64(10.0), | |
| OpLocalSet, 0, | |
| OpLocalGet, 0, | |
| OpF64Const, 2.5, | |
| OpF64Sub, | |
| OpLocalSet, 0, | |
| ), | |
| Entry("i32 multiply equals", | |
| `x i32 := 3 | |
| x *= 4`, | |
| OpI32Const, int32(3), | |
| OpLocalSet, 0, | |
| OpLocalGet, 0, | |
| OpI32Const, int32(4), | |
| OpI32Mul, | |
| OpLocalSet, 0, | |
| ), | |
| Entry("f32 divide equals", | |
| `x f32 := 10.0 | |
| x /= 2.0`, | |
| OpF32Const, float32(10.0), | |
| OpLocalSet, 0, | |
| OpLocalGet, 0, | |
| OpF32Const, float32(2.0), | |
| OpF32Div, | |
| OpLocalSet, 0, | |
| ), | |
| Entry("i64 modulo equals", | |
| `x i64 := 17 | |
| x %= 5`, | |
| OpI64Const, int64(17), | |
| OpLocalSet, 0, | |
| OpLocalGet, 0, | |
| OpI64Const, int64(5), | |
| OpI64RemS, | |
| OpLocalSet, 0, | |
| ), | |
| Entry("string plus equals", | |
| `s str := "hello" | |
| s += " world"`, | |
| OpStringConst, "hello", | |
| OpLocalSet, 0, | |
| OpLocalGet, 0, | |
| OpStringConst, " world", | |
| OpCall, /* StringConcat import index */, | |
| OpLocalSet, 0, | |
| ), | |
| ) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Issue Pull Request
Linear Issue
SY-3484
Description
Basic Readiness
Greptile Summary
This PR implements compound assignment operators (
+=,-=,*=,/=,%=) for the Arc language compiler. The implementation spans grammar definitions, semantic analysis, and WASM code generation.Key changes:
ArcLexer.g4and corresponding grammar rules inArcParser.g4analyzeCompoundAssignment()with comprehensive type checking that validates numeric types for all operators except+=which also supports stringscompileCompoundAssignment()to generate correct WASM bytecode, handling local/input/stateful variables and string concatenation via runtime importi32,i64,f32,f64)Design decisions:
array[i] += 5) is explicitly blocked with a clear error message, leaving room for future implementation+=for concatenation; other operators are rejectedThe implementation is clean, well-structured, and follows existing patterns in the codebase.
Confidence Score: 4/5
str += str) validation, which is an explicitly supported feature that should be tested.+=Important Files Changed
compoundOpproduction with 5 operator tokens). Clean implementation, properly integrated intoassignmentrule.PLUS_ASSIGN,MINUS_ASSIGN,STAR_ASSIGN,SLASH_ASSIGN,PERCENT_ASSIGN). Positioned correctly before arithmetic operators.analyzeCompoundAssignmentwith proper type checking. Blocks indexed assignment, channels, validates numeric types, allows string+=. Type compatibility checking is thorough.compileCompoundAssignmentto emit WASM opcodes. Correctly handles local/input/stateful variables, string concatenation via import call, type casting, and binary operations.i64,f64,i32,f32with+=,-=,*=,/=,%=). Missing string+=test case.Sequence Diagram
sequenceDiagram participant Parser as ANTLR Parser participant Lexer as ANTLR Lexer participant Analyzer as Statement Analyzer participant Compiler as Statement Compiler participant WASM as WASM Writer Note over Lexer: Tokenize x += 5 Lexer->>Parser: IDENTIFIER, PLUS_ASSIGN, INTEGER_LITERAL Parser->>Parser: Build assignment AST with CompoundOp context Note over Analyzer: Type checking phase Parser->>Analyzer: analyzeAssignment(assignment context) Analyzer->>Analyzer: Resolve variable scope and type Analyzer->>Analyzer: Check CompoundOp exists Analyzer->>Analyzer: analyzeCompoundAssignment() alt Indexed assignment Analyzer->>Analyzer: Error: not yet supported end alt Channel type Analyzer->>Analyzer: Error: not supported on channels end alt String type Analyzer->>Analyzer: Check only += operator else Numeric type Analyzer->>Analyzer: Validate IsNumeric() end Analyzer->>Analyzer: Analyze expression type Analyzer->>Analyzer: Check type compatibility Analyzer-->>Parser: Type checking complete Note over Compiler: Code generation phase Parser->>Compiler: compileAssignment(assignment context) Compiler->>Compiler: Resolve variable scope Compiler->>Compiler: Check CompoundOp exists Compiler->>Compiler: compileCompoundAssignment() Compiler->>WASM: WriteLocalGet(scope.ID) Note over WASM: Load current value Compiler->>Compiler: Compile expression Compiler->>WASM: Emit expression opcodes alt Type mismatch Compiler->>WASM: EmitCast(exprType, varType) end alt String concatenation Compiler->>WASM: WriteCall(StringConcat import) else Numeric operation Compiler->>WASM: WriteBinaryOpInferred(op, varType) end alt Local/Input variable Compiler->>WASM: WriteLocalSet(scope.ID) else Stateful variable Compiler->>WASM: WriteLocalSet(scope.ID) Compiler->>WASM: Write state store operations Compiler->>WASM: WriteCall(StateStore import) end WASM-->>Compiler: WASM bytecode generated