Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion src/ast/utils/astToString.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
ExpressionStatement,
Literal,
LocalVariableDeclarationStatement,
MethodInvocation,
MethodInvocation, PostfixExpression,PrefixExpression,
ReturnStatement,
} from '../types/blocks-and-statements';
import {
Expand Down Expand Up @@ -125,6 +125,13 @@ export const astToString = (node: Node, indent: number = 0): string => {
case "Void":
return "void";

case "PostfixExpression":
const postfix = node as PostfixExpression;
return `${astToString(postfix.expression)}${postfix.operator}`;
case "PrefixExpression":
const prefix = node as PrefixExpression;
return `${prefix.operator}${astToString(prefix.expression)}`;

default:
return node.kind;
}
Expand Down
3 changes: 3 additions & 0 deletions src/ec-evaluator/__tests__/arithmetic.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ it("evaluate LocalVariableDeclarationStatement to a complex arithmetic operation
// TODO test env
});


it("evaluate FieldDeclaration to a basic arithmetic expression without brackets to enforce precedence correctly", () => {
const programStr = `
public class Test {
Expand Down Expand Up @@ -302,6 +303,7 @@ it("evaluate FieldDeclaration to a basic arithmetic expression without brackets
// TODO test env
});


it("evaluate FieldDeclaration to a complex arithmetic expression without brackets to enforce precedence correctly", () => {
const programStr = `
public class Test {
Expand Down Expand Up @@ -408,6 +410,7 @@ it("evaluate FieldDeclaration to a complex arithmetic expression without bracket
"Void", // Void
];


expect(result).toEqual(undefined);
expect((context.control as ControlStub).getTrace().map(i => getControlItemStr(i))).toEqual(expectedControlTrace);
expect((context.stash as StashStub).getTrace().map(i => getStashItemStr(i))).toEqual(expectedStashTrace);
Expand Down
92 changes: 92 additions & 0 deletions src/ec-evaluator/interpreter.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { cloneDeep } from "lodash";


import {
Assignment,
BinaryExpression,
Expand All @@ -16,6 +17,8 @@ import {
ReturnStatement,
VariableDeclarator,
Void,
PrefixExpression,
PostfixExpression,
} from "../ast/types/blocks-and-statements";
import {
ConstructorDeclaration,
Expand Down Expand Up @@ -413,6 +416,48 @@ const cmdEvaluators: { [type: string]: CmdEvaluator } = {
control.push(command.left);
},

PrefixExpression: (
command:PrefixExpression,
environment: Environment,
control: Control,
stash: Stash,
) => {
const operator = command.operator; // Prefix operator (e.g., "++" or "--")
const operand = command.expression; // The variable being operated on (e.g., x)

if (operand.kind !== "ExpressionName") {
throw new errors.RuntimeError(
`Postfix operator ${operator} can only be applied to variables`
);
}
const binExpr = {
kind: "BinaryExpression",
operator: operator === "++" ? "+" : "-",
left: operand,
right: {
kind: "Literal",
literalType: {
kind: "DecimalIntegerLiteral",
value: "1" // This is the increment/decrement value
},
location: command.location
},
location: command.location
} as BinaryExpression

// Push the assignment to update the variable:
control.push({
kind: "Assignment",
left: operand,
operator: "=",
right: binExpr, // Use the result of the binary operation
location: command.location
});

},



[InstrType.POP]: (
_command: Instr,
_environment: Environment,
Expand All @@ -421,6 +466,52 @@ const cmdEvaluators: { [type: string]: CmdEvaluator } = {
) => {
stash.pop();
},

PostfixExpression: (
command: PostfixExpression,
_environment: Environment,
control: Control,
_stash: Stash,
) => {
const operator = command.operator; // Postfix operator (e.g., "++" or "--")
const operand = command.expression; // The variable being operated on (e.g., x)
if (operand.kind !== "ExpressionName") {
throw new errors.RuntimeError(
`Postfix operator ${operator} can only be applied to variables`
);
}

control.push(instr.popInstr(operand));

const binExpr = {
kind: "BinaryExpression",
operator: operator === "++" ? "+" : "-",
left: operand,
right: {
kind: "Literal",
literalType: {
kind: "DecimalIntegerLiteral",
value: "1" // This is the increment/decrement value
},
location: command.location
},
location: command.location
} as BinaryExpression

// Push the assignment to update the variable:
control.push({
kind: "Assignment",
left: operand,
operator: "=",
right: binExpr, // Use the result of the binary operation
location: command.location
});

control.push(operand);

// Apply the postfix operation (after using the value)

},

[InstrType.ASSIGNMENT]: (
_command: AssmtInstr,
Expand Down Expand Up @@ -842,3 +933,4 @@ const cmdEvaluators: { [type: string]: CmdEvaluator } = {
// No post-processing required for constructor.
},
};