Skip to content
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

Add test infrastructure for compiler #14

Merged
merged 12 commits into from
Feb 12, 2024
Prev Previous commit
Next Next commit
Add support for unary operators
  • Loading branch information
1001mei committed Dec 10, 2023
commit 9f5e94b68756f5602a49da613849fa894d4832b6
11 changes: 9 additions & 2 deletions src/ast/types/blocks-and-statements.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,16 @@ export interface Assignment {
}

export type LeftHandSide = ExpressionName;
export type UnaryExpression = PrefixExpression;
export type UnaryExpression = PrefixExpression | PostfixExpression;

export interface PrefixExpression {
kind: "PrefixExpression";
operator: "-" | "+";
operator: "-" | "+" | "++" | "--" | "!" | "~";
expression: Expression;
}

export interface PostfixExpression {
kind: "PostfixExpression";
operator: "++" | "--";
expression: Expression;
}
2 changes: 2 additions & 0 deletions src/compiler/__tests__/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ import { arithmeticExpressionTest } from "./tests/arithmeticExpression.test";
import { ifElseTest } from "./tests/ifElse.test";
import { whileTest } from "./tests/while.test";
import { forTest } from "./tests/for.test";
import { unaryExpressionTest } from "./tests/unaryExpression.test";

describe("compiler tests", () => {
printlnTest();
variableDeclarationTest();
arithmeticExpressionTest();
unaryExpressionTest();
ifElseTest();
whileTest();
forTest();
Expand Down
16 changes: 8 additions & 8 deletions src/compiler/__tests__/main.pegjs
Original file line number Diff line number Diff line change
Expand Up @@ -378,9 +378,9 @@ Dims
}

TypeArguments
= lt TypeArgumentsList gt
= lt TypeArgumentList gt

TypeArgumentsList
TypeArgumentList
= TypeArgument (comma TypeArgument)*

TypeArgument
Expand Down Expand Up @@ -927,9 +927,9 @@ UnaryExpression
= PostfixExpression
/ op:PrefixOp expr:UnaryExpression {
return {
kind: "UnaryPrefixExpression",
op: op,
expr: expr,
kind: "PrefixExpression",
operator: op,
expression: expr,
}
}
/ CastExpression
Expand All @@ -945,9 +945,9 @@ PostfixExpression
= expr:(Primary / @ExpressionName)
op:(increment / decrement)? {
return op ? {
kind: "UnaryPostfixExpression",
op: op,
expr: expr,
kind: "PostfixExpression",
operator: op,
expression: expr,
} : expr;
}

Expand Down
6 changes: 4 additions & 2 deletions src/compiler/__tests__/tests/arithmeticExpression.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,20 @@ const testCases: testCase[] = [
expectedLines: ["15", "2", "14", "-1", "0", "-4"],
},
{
comment: "complex binary expression (int only)",
comment: "int only complex binary expression",
program: `
public class Main {
public static void main(String[] args) {
System.out.println(1 + 2 * 3 - 4);
System.out.println(10 * (7 - 4) / 2);
System.out.println(3 * 4 * 5 - 100 / 2 / 5);
System.out.println((4 | 6) & (10 ^ 24) + 100);
System.out.println(~3 >>> 2 & 5 << 1 + 2);
System.out.println((~3 >>> 2) & (5 << (1 + 2)));
}
}
`,
expectedLines: ["3", "15", "50", "6"],
expectedLines: ["3", "15", "50", "6", "40", "40"],
},
{
comment: "int boundaries",
Expand Down
16 changes: 16 additions & 0 deletions src/compiler/__tests__/tests/for.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,22 @@ const testCases: testCase[] = [
}
`,
expectedLines: ["0", "0", "0", "1", "0", "2", "1", "0", "1", "1", "1", "2", "2", "0", "2", "1", "2", "2",],
},
{
comment: "nested for loops",
program: `
public class Main {
public static void main(String[] args) {
for (int x = -1; x <= 1; x++) {
for (int y = 1; y >= -1; y--) {
System.out.println(x);
System.out.println(y);
}
}
}
}
`,
expectedLines: ["-1", "1", "-1", "0", "-1", "-1", "0", "1", "0", "0", "0", "-1", "1", "1", "1", "0", "1", "-1",],
}
];

Expand Down
158 changes: 156 additions & 2 deletions src/compiler/__tests__/tests/ifElse.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {

const testCases: testCase[] = [
{
comment: "only if",
comment: "if without else",
program: `
public class Main {
public static void main(String[] args) {
Expand Down Expand Up @@ -78,7 +78,161 @@ const testCases: testCase[] = [
}
`,
expectedLines: ["Good", "Nice", "Ok"],
}
},
{
comment: "logical and",
program: `
public class Main {
public static void main(String[] args) {
int x = 10, y = 5, z = 3;
if (x > y && y > z) {
System.out.println("Yes1");
} else {
System.out.println("No");
}

if (x > y && y <= 4) {
System.out.println("No");
} else {
System.out.println("Yes2");
}

if (x < y && y > z) {
System.out.println("No");
} else {
System.out.println("Yes3");
}

if (x < y && y <= 4) {
System.out.println("No");
} else {
System.out.println("Yes4");
}
}
}
`,
expectedLines: ["Yes1", "Yes2", "Yes3", "Yes4"],
},
{
comment: "logical or",
program: `
public class Main {
public static void main(String[] args) {
int x = 7, y = 5, z = 2;
if (x > y || y > z) {
System.out.println("Yes1");
} else {
System.out.println("No");
}

if (x > y || y <= 4) {
System.out.println("Yes2");
} else {
System.out.println("No");
}

if (x < y || y > z) {
System.out.println("Yes3");
} else {
System.out.println("No");
}

if (x < y || y <= 4) {
System.out.println("No");
} else {
System.out.println("Yes4");
}
}
}
`,
expectedLines: ["Yes1", "Yes2", "Yes3", "Yes4"],
},
{
comment: "logical not",
program: `
public class Main {
public static void main(String[] args) {
int x = 7, y = 5, z = 2;

if (!(x < y)) {
System.out.println("Yes1");
} else {
System.out.println("No");
}

if (!(z <= y)) {
System.out.println("No");
} else {
System.out.println("Yes2");
}
}
}
`,
expectedLines: ["Yes1", "Yes2"],
},
{
comment: "complex conditional expression",
program: `
public class Main {
public static void main(String[] args) {
if (4 <= 4 && (!(1 <= 2) || 9 > 5) ) {
System.out.println("Yes");
} else {
System.out.println("No");
}

if (!(8 > 3 || !(7 < 9))) {
System.out.println("No");
} else {
System.out.println("Yes2");
}
}
}
`,
expectedLines: ["Yes", "Yes2"],
},
{
comment: "nested if else",
program: `
public class Main {
public static void main(String[] args) {
int a = 5, b = 10, c = 15;
if (a == 5) {
if (b < c) {
System.out.println("Yes");
} else {
System.out.println("No");
}
if (c < b) {
System.out.println("No");
} else {
System.out.println("Yes");
}
} else {
System.out.println("No");
}

if (b != 10) {
System.out.println("No");
} else if (b <= 10) {
if (b < c) {
System.out.println("Yes");
} else {
System.out.println("No");
}
if (c < b) {
System.out.println("No");
} else {
System.out.println("Yes");
}
} else {
System.out.println("No");
}
}
}
`,
expectedLines: ["Yes", "Yes", "Yes", "Yes"],
},
];

export const ifElseTest = () => describe("if else statements", () => {
Expand Down
90 changes: 90 additions & 0 deletions src/compiler/__tests__/tests/unaryExpression.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import {
runTest,
testCase,
} from "../test-utils";

const testCases: testCase[] = [
{
comment: "postfix increment/decrement",
program: `
public class Main {
public static void main(String[] args) {
int a = 1, b = 2, c = 3, d = 4, e = 5, f = 6;
System.out.println(a+b--);
System.out.println(a);
System.out.println(b);

System.out.println(c-d++);
System.out.println(c);
System.out.println(d);

System.out.println(e+++f);
System.out.println(e);
System.out.println(f);
}
}`,
expectedLines: ["3", "1", "1", "-1", "3", "5", "11", "6", "6"],
},
{
comment: "prefix increment/decrement",
program: `
public class Main {
public static void main(String[] args) {
int a = 1, b = 2, c = 3;
System.out.println(a+(++b));
System.out.println(a);
System.out.println(b);

System.out.println(--c);
System.out.println(c);
System.out.println(++c);
System.out.println(c);
}
}`,
expectedLines: ["4", "1", "3", "2", "2", "3", "3"],
},
{
comment: "unary plus/minus",
program: `
public class Main {
public static void main(String[] args) {
int a = 10;
System.out.println(a);
System.out.println(+a);
System.out.println(-a);
System.out.println(+-a);
System.out.println(-+a);
System.out.println(+-+a);
System.out.println(-+-a);
System.out.println(+--a);
System.out.println(-++a);
}
}`,
expectedLines: ["10", "10", "-10", "-10", "-10", "-10", "10", "9", "-10"],
},
{
comment: "bitwise complement",
program: `
public class Main {
public static void main(String[] args) {
int a = 1, b = 42;
System.out.println(a);
System.out.println(~a);
System.out.println(~~a);
System.out.println(~~~a);

System.out.println(~b);
System.out.println(-b - 1);
}
}`,
expectedLines: ["1", "-2", "1", "-2", "-43", "-43"],
},
];

export const unaryExpressionTest = () => describe("unary expression", () => {
for (let testCase of testCases) {
const { comment: comment, program: program, expectedLines: expectedLines } = testCase;
const expectedResult = expectedLines.join("\n") + "\n";
it(comment, () => runTest(program, expectedResult));
}
});
Loading