Skip to content

Commit 37c2cef

Browse files
committed
Fix bug in typechecker for array assignment
1 parent 39fe062 commit 37c2cef

File tree

3 files changed

+26
-10
lines changed

3 files changed

+26
-10
lines changed

src/ast/astExtractor/statement-extractor.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import {
3939
ExpressionStatement,
4040
IfStatement,
4141
MethodInvocation,
42+
Primary,
4243
Statement,
4344
StatementExpression,
4445
VariableDeclarator,
@@ -158,10 +159,26 @@ export class StatementExtractor extends BaseJavaCstVisitorWithDefaults {
158159
return this.visit(ctx.primary);
159160
}
160161

161-
primary(ctx: PrimaryCtx) {
162+
primary(ctx: PrimaryCtx): Primary {
162163
// Assignment LHS, MethodInvocation identifier
163164
let { name, location } = this.visit(ctx.primaryPrefix);
164165
if (ctx.primarySuffix) {
166+
const lastSuffix = ctx.primarySuffix[ctx.primarySuffix.length - 1];
167+
if (lastSuffix.children.arrayAccessSuffix) {
168+
const expressionExtractor = new ExpressionExtractor();
169+
const newPrimaryCtx: PrimaryCtx = { primaryPrefix: ctx.primaryPrefix };
170+
if (ctx.primarySuffix.length - 1 > 0) {
171+
const newSuffixArray = ctx.primarySuffix.filter(
172+
(_, index) => index !== ctx.primarySuffix!.length - 1
173+
);
174+
newPrimaryCtx.primarySuffix = newSuffixArray;
175+
}
176+
return {
177+
...expressionExtractor.visit(lastSuffix.children.arrayAccessSuffix),
178+
primary: this.primary(newPrimaryCtx) as Primary,
179+
};
180+
}
181+
165182
for (const s of ctx.primarySuffix.filter(
166183
(s) => !s.children.methodInvocationSuffix
167184
)) {

src/types/checker/__tests__/arrays.test.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ const testcases: {
6565
numbers[0] = 10; // Correct assignment
6666
`,
6767
result: { type: null, errors: [] },
68-
only: true,
6968
},
7069
{
7170
input: `

src/types/checker/index.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
import {
2-
ExpressionName,
3-
VariableInitializer,
4-
} from "../../ast/types/blocks-and-statements";
1+
import { Array as ArrayType } from "../types/arrays";
52
import { Frame } from "./environment";
3+
import { Integer, String } from "../types/nonPrimitives";
64
import { Method } from "../types/methods";
75
import { Node } from "../../ast/types/ast";
8-
import { Integer, String } from "../types/nonPrimitives";
96
import { Type } from "../types/type";
7+
import { VariableInitializer } from "../../ast/types/blocks-and-statements";
108
import {
119
ArrayRequiredError,
1210
BadOperandTypesError,
@@ -29,7 +27,6 @@ import {
2927
getFloatType,
3028
getNumberType,
3129
} from "../types/primitives";
32-
import { Array as ArrayType } from "../types/arrays";
3330

3431
export type Result = {
3532
currentType: Type | null;
@@ -71,9 +68,12 @@ export const check = (
7168
return newResult(primaryCheck.currentType.getContentType());
7269
}
7370
case "Assignment": {
74-
const left = node.left as ExpressionName;
71+
const leftCheck = check(node.left, frame);
72+
if (leftCheck.errors.length > 0) return newResult(null, leftCheck.errors);
73+
if (!leftCheck.currentType)
74+
throw new Error("Left type in assignment should exist.");
7575
const right = node.right;
76-
const leftType = frame.getVariable(left.name);
76+
const leftType = leftCheck.currentType;
7777
if (leftType instanceof Error) return newResult(null, [leftType]);
7878
const { currentType, errors } = check(right, frame);
7979
if (errors.length > 0) return newResult(null, errors);

0 commit comments

Comments
 (0)