Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
18d8da4
integrate Conductor
kjw142857 Jun 10, 2026
d637754
.
kjw142857 Jun 10, 2026
810656f
jvm changes
kjw142857 Jun 15, 2026
6d73dab
Potential fix for pull request finding 'CodeQL / Workflow does not co…
kjw142857 Jun 15, 2026
ef3a3f2
remove residue exception handling code
kjw142857 Jun 15, 2026
ed2b8f6
implement in-memory class loading
kjw142857 Jun 15, 2026
08b9345
Use conductor@sourceacademy types
kjw142857 Jun 16, 2026
1b1ec53
remove package_lock.json
kjw142857 Jun 16, 2026
1ddea74
change conductor version
kjw142857 Jun 16, 2026
ffedd16
revert yarn.lock file
kjw142857 Jun 16, 2026
e1f8876
revert yarn.lock file
kjw142857 Jun 16, 2026
b1593a3
include try/catch/finally support in code generator
kjw142857 Jun 16, 2026
12926df
fix try statement logic
kjw142857 Jun 24, 2026
b7a4b18
Merge branch 'main' into exception-handling
martin-henz Jun 24, 2026
8f7d8b4
add parser and type checker integration
kjw142857 Jul 1, 2026
79a4e6b
fix finally bug
kjw142857 Jul 1, 2026
2daa965
add tests and fix syntax error
kjw142857 Jul 8, 2026
8e933b6
Patch grammar logic for throws keyword
kjw142857 Jul 16, 2026
181ae61
Revert "Patch grammar logic for throws keyword"
kjw142857 Jul 16, 2026
ee94927
Patch grammar logic for throws keyword
kjw142857 Jul 16, 2026
63f0301
Add fix for execption table finally logic
kjw142857 Jul 21, 2026
df4fede
Add more tests
kjw142857 Jul 21, 2026
e35730a
Add java.lang.Throwable subclasses to compiler/type checker imports
kjw142857 Jul 21, 2026
e8985da
remove some hardcoding for typechecker
kjw142857 Jul 28, 2026
e941932
tighten selector criteria
kjw142857 Aug 10, 2026
89ccf30
add enum support
kjw142857 Aug 10, 2026
4e0b4d5
WIP: Add enum grammar rules and compiler tests
kjw142857 Aug 26, 2026
0625138
Add enum parsing and compiler support (partial)
kjw142857 Aug 26, 2026
954c172
Register enum synthetic methods in symbol table
kjw142857 Aug 26, 2026
b9a196c
Implement exception handling in java-slang (#96)
kjw142857 Aug 26, 2026
f2a823e
Add feature details in README (#88)
kjw142857 Aug 27, 2026
86fc930
Merge branch 'main' into switch-statements
kjw142857 Sep 2, 2026
4cfcdf1
fix exception table merge conflict
kjw142857 Sep 2, 2026
21c3f1f
integrate enum types into switch statements
kjw142857 Sep 2, 2026
d9d7665
add enum ordinals
kjw142857 Sep 2, 2026
9d3e723
correct enum grammar
kjw142857 Sep 2, 2026
af3648d
Merge branch 'main' into switch-statements
kjw142857 Sep 2, 2026
52781ca
remove excessively long logging statement
kjw142857 Sep 2, 2026
0ceb317
remove redundant color test
kjw142857 Sep 2, 2026
1c102bd
Merge branch 'main' into std-imports
kjw142857 Sep 7, 2026
f0f6980
update compiler to add importing of std classes
kjw142857 Sep 7, 2026
c827574
ensure imported classes for compiler are handled by jvm as well
kjw142857 Sep 7, 2026
dde0622
add enum support
kjw142857 Sep 7, 2026
6cd7a78
implement library loading and primitive unboxing
kjw142857 Sep 7, 2026
aa8a837
Merge branch 'std-imports' into switch-statements
kjw142857 Sep 7, 2026
99e7920
Return compiled classes in declaration order, not compilation order
kjw142857 Sep 7, 2026
ae58cef
Make generated enums genuinely extend java.lang.Enum
kjw142857 Sep 7, 2026
d05bc85
change compiler/jvm reference to Java 8
kjw142857 Sep 7, 2026
e17c26d
merge java 8 integration from std-imports
kjw142857 Sep 7, 2026
9c2fc3a
Merge branch 'main' into switch-statements
kjw142857 Sep 7, 2026
317ece6
fix dropping of initialiser and add helper for class collation
kjw142857 Sep 7, 2026
de7cd15
Refactor enum switch label error handling
kjw142857 Sep 9, 2026
55754df
Simplify error check for duplicate classes
kjw142857 Sep 9, 2026
1702d4d
Merge branch 'main' into switch-statements
kjw142857 Sep 9, 2026
8f4b3e8
fix bug with updating of fields
kjw142857 Sep 23, 2026
5f7b9ea
Merge remote-tracking branch 'origin/main' into inner-classes
kjw142857 Sep 23, 2026
9436019
merge from main
kjw142857 Sep 23, 2026
bc0045a
Merge remote-tracking branch 'origin/main' into conductor
kjw142857 Sep 23, 2026
0daa7a2
Add dependencies and conductor bundling
kjw142857 Sep 30, 2026
04f493f
resolve missing components
kjw142857 Oct 6, 2026
81aa6be
Merge branch 'conductor' into inner-classes
kjw142857 Oct 7, 2026
56903d9
Integrate Conductor changes from branch
kjw142857 Oct 7, 2026
c5e47ea
Add two-pass verification for scoping reference checks
kjw142857 Oct 7, 2026
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
2 changes: 1 addition & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": "tsconfig.json",
"project": ["tsconfig.json", "tsconfig.conductor.json"],
"sourceType": "module"
},
"plugins": [
Expand Down
58 changes: 58 additions & 0 deletions .github/workflows/build-deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: Build and deploy runner

on:
push:
branches:
- main

jobs:
build:
name: Build runner
permissions:
contents: read
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v6

- name: Enable corepack
run: corepack enable

- name: Setup node
uses: actions/setup-node@v4
with:
node-version: 22
cache: yarn

- name: Install dependencies
run: yarn install --frozen-lockfile

- name: Typecheck conductor evaluator
run: yarn typecheck:conductor

- name: Test conductor evaluator
run: yarn test:conductor

- name: Build conductor evaluator bundle
run: yarn build:conductor

- name: Upload artifacts
id: deployment
uses: actions/upload-pages-artifact@v3
with:
path: dist-conductor/

deploy:
needs: build
name: Deploy runner
permissions:
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# compiled output
/dist
/dist-conductor
/node_modules
tsconfig.tsbuildinfo

Expand Down
9 changes: 9 additions & 0 deletions jest.conductor.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/** @type {import('jest').Config} */
export default {
testEnvironment: 'node',
testMatch: ['<rootDir>/src/conductor/**/*.test.ts'],
extensionsToTreatAsEsm: ['.ts'],
transform: {
'^.+\\.tsx?$': ['ts-jest', { useESM: true, tsconfig: '<rootDir>/tsconfig.conductor.json' }]
}
}
1 change: 1 addition & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ module.exports = {
testPathIgnorePatterns: [
'<rootDir>/node_modules/',
'<rootDir>/src/compiler/__tests__/tests/',
'<rootDir>/src/conductor/',
'__utils__'
]
}
11 changes: 11 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,22 @@
"scripts": {
"build": "tsc --build --force",
"build:lib-info": "tsc --build --force && node dist/compiler/import/build-lib-info.js",
"build:conductor": "rollup -c rollup.config.conductor.mjs",
"typecheck:conductor": "tsc --noEmit -p tsconfig.conductor.json",
"test": "jest",
"test:watch": "jest --watch",
"test:conductor": "node --experimental-vm-modules node_modules/.bin/jest --config jest.conductor.config.mjs",
"jsdoc": "typedoc --plugin typedoc-plugin-rename-defaults",
"eslint": "ESLINT_USE_FLAT_CONFIG=false eslint --ext \".ts\" src",
"format": "prettier --write src/**/*.ts",
"prepare": "husky"
},
"devDependencies": {
"@rollup/plugin-commonjs": "^29.0.3",
"@rollup/plugin-json": "^6.1.0",
"@rollup/plugin-node-resolve": "^16.0.3",
"@rollup/plugin-terser": "^1.0.0",
"@rollup/plugin-typescript": "^12.3.0",
"@types/jest": "^29.5.4",
"@typescript-eslint/eslint-plugin": "^7.4.0",
"@typescript-eslint/parser": "^7.4.0",
Expand All @@ -32,13 +40,16 @@
"jest": "^29.6.4",
"jest-environment-jsdom": "^29.6.4",
"prettier": "^3.2.5",
"rollup": "^4.63.5",
"ts-jest": "^29.1.1",
"tslib": "^2.8.1",
"typedoc": "^0.25.12",
"typedoc-plugin-markdown": "^3.17.1",
"typedoc-plugin-rename-defaults": "^0.7.0",
"typescript": "^5.2.2"
},
"dependencies": {
"@sourceacademy/conductor": "^0.8.3",
"@types/lodash": "^4.14.198",
"java-parser": "^2.0.5",
"lodash": "^4.17.21",
Expand Down
21 changes: 21 additions & 0 deletions rollup.config.conductor.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import commonjs from '@rollup/plugin-commonjs'
import json from '@rollup/plugin-json'
import { nodeResolve } from '@rollup/plugin-node-resolve'
import terser from '@rollup/plugin-terser'
import typescript from '@rollup/plugin-typescript'

export default {
input: 'src/conductor/initialise.ts',
output: {
file: 'dist-conductor/index.js',
format: 'iife',
sourcemap: true
},
plugins: [
nodeResolve(),
commonjs(),
json(),
typescript({ tsconfig: 'tsconfig.conductor.json', outDir: undefined, declaration: false }),
terser()
]
}
36 changes: 36 additions & 0 deletions src/ast/__tests__/class-extractor.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,3 +124,39 @@ describe("extract multiple NormalClassDeclaration correctly", () => {
expect(ast).toEqual(expectedAst);
});
});

describe("extract nested NormalClassDeclaration correctly", () => {
it("extract a static nested class inside a class body correctly", () => {
const programStr = `
class Outer {
static class Inner {}
}
`;

const expectedAst: AST = {
kind: "CompilationUnit",
importDeclarations: [],
topLevelClassOrInterfaceDeclarations: [
{
kind: "NormalClassDeclaration",
classModifier: [],
typeIdentifier: "Outer",
classBody: [
{
kind: "NormalClassDeclaration",
classModifier: ["static"],
typeIdentifier: "Inner",
classBody: [],
location: expect.anything(),
},
],
location: expect.anything(),
},
],
location: expect.anything(),
};

const ast = parse(programStr);
expect(ast).toEqual(expectedAst);
});
});
7 changes: 7 additions & 0 deletions src/ast/astExtractor/class-extractor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,5 +91,12 @@ export class ClassExtractor extends BaseJavaCstVisitorWithDefaults {
this.body.push(methodNode);
})
}
if (ctx.classDeclaration) {
ctx.classDeclaration.forEach(x => {
const classExtractor = new ClassExtractor();
const classNode = classExtractor.extract(x);
this.body.push(classNode);
})
}
}
}
2 changes: 1 addition & 1 deletion src/ast/types/classes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export type ClassModifier =
| "strictfp"
| "enum";

export type ClassBodyDeclaration = ClassMemberDeclaration | ConstructorDeclaration | EnumDeclaration;
export type ClassBodyDeclaration = ClassMemberDeclaration | ConstructorDeclaration | EnumDeclaration | NormalClassDeclaration;
export type ClassMemberDeclaration = MethodDeclaration | FieldDeclaration;

export interface ConstructorDeclaration extends BaseNode {
Expand Down
6 changes: 4 additions & 2 deletions src/compiler/__tests__/classOrdering.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ describe('compiled class ordering', () => {
}
`
const classes = compileFromSource(program)
expect(classes.map(c => c.className)).toEqual(['Main', 'Day'])
expect(classes.map(c => c.className)).toEqual(['Main', 'Main$Day'])
})

it('keeps top-level declaration order, with member enums appended', () => {
Expand All @@ -24,7 +24,9 @@ describe('compiled class ordering', () => {
`
const classes = compileFromSource(program)
expect(classes[0].className).toBe('Main')
expect(new Set(classes.map(c => c.className))).toEqual(new Set(['Main', 'A', 'B']))
expect(new Set(classes.map(c => c.className))).toEqual(
new Set(['Main', 'Main$A', 'Main$B'])
)
})

it('is unchanged when there is no enum', () => {
Expand Down
2 changes: 2 additions & 0 deletions src/compiler/__tests__/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { importTest } from "./tests/import.test";
import { arrayTest } from "./tests/array.test";
import { classTest } from "./tests/class.test";
import { enumTest } from "./tests/enum.test";
import { nestedClassesTest } from "./tests/nestedClasses.test";
import { typeConversionTest } from "./tests/typeConversion.test";

describe("compiler tests", () => {
Expand All @@ -25,5 +26,6 @@ describe("compiler tests", () => {
arrayTest();
classTest();
enumTest();
nestedClassesTest();
typeConversionTest();
})
13 changes: 13 additions & 0 deletions src/compiler/__tests__/tests/class.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,19 @@ const testCases: testCase[] = [
`,
expectedLines: ["in f"],
},
{
comment: "instance field with an inline initializer",
program: `
public class Main {
public int one = 1;
public static void main(String[] args) {
Main m = new Main();
System.out.println(m.one);
}
}
`,
expectedLines: ["1"],
},
{
comment: "instance field",
program: `
Expand Down
Loading
Loading