From b746261f970f04c226e51b8516f6d448ec9122fb Mon Sep 17 00:00:00 2001 From: mattcce Date: Mon, 16 Jun 2025 23:58:46 +0800 Subject: [PATCH 01/14] native methods --- src/ec-evaluator/__tests__/natives.test.ts | 67 +++ src/ec-evaluator/errors.ts | 10 + src/ec-evaluator/interpreter.ts | 29 +- src/ec-evaluator/natives.ts | 29 ++ src/ec-evaluator/nodeCreator.ts | 38 +- src/ec-evaluator/utils.ts | 9 + yarn.lock | 578 ++++++++++++++------- 7 files changed, 557 insertions(+), 203 deletions(-) create mode 100644 src/ec-evaluator/__tests__/natives.test.ts create mode 100644 src/ec-evaluator/natives.ts diff --git a/src/ec-evaluator/__tests__/natives.test.ts b/src/ec-evaluator/__tests__/natives.test.ts new file mode 100644 index 0000000..f8979c1 --- /dev/null +++ b/src/ec-evaluator/__tests__/natives.test.ts @@ -0,0 +1,67 @@ +import { natives } from '../natives' +import { + // ControlStub, + // StashStub, + createContextStub + // getControlItemStr, + // getStashItemStr +} from './__utils__/utils' +import { parse } from '../../ast/parser' +import { evaluate } from '../interpreter' + +describe('native functions', () => { + it('should invoke external native function', () => { + const mockForeignFn = jest.fn() + + natives['testNative(): void'] = mockForeignFn + + const programStr = ` + class C { + public native void testNative(); + + public static void main(String[] args) { + C c = new C(); + c.testNative(); + } + }` + + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() + + const context = createContextStub() + context.control.push(compilationUnit!) + + evaluate(context) + + expect(mockForeignFn.mock.calls).toHaveLength(1) + }) + + it('should invoke external native function with correct environment', () => { + const foreignFn = jest.fn(({ environment }) => { + const s = environment.getVariable('s').value.literalType.value + expect(s).toBe('"Test"') + }) + + natives['testNative(String s): void'] = foreignFn + + const programStr = ` + class C { + public native void testNative(String s); + + public static void main(String[] args) { + C c = new C(); + c.testNative("Test"); + } + }` + + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() + + const context = createContextStub() + context.control.push(compilationUnit!) + + evaluate(context) + + expect(foreignFn.mock.calls).toHaveLength(1) + }) +}) diff --git a/src/ec-evaluator/errors.ts b/src/ec-evaluator/errors.ts index 495b3a0..e0d5d4a 100644 --- a/src/ec-evaluator/errors.ts +++ b/src/ec-evaluator/errors.ts @@ -160,3 +160,13 @@ export class NoMainMtdError extends RuntimeError { return `public static void main(String[] args) is not defined in any class.` } } + +export class UndefinedNativeMethod extends RuntimeError { + constructor(private descriptor: string) { + super() + } + + public explain() { + return `Native function ${this.descriptor} has no defined implementation.` + } +} diff --git a/src/ec-evaluator/interpreter.ts b/src/ec-evaluator/interpreter.ts index fa8c548..27e6173 100644 --- a/src/ec-evaluator/interpreter.ts +++ b/src/ec-evaluator/interpreter.ts @@ -87,12 +87,15 @@ import { searchMainMtdClass, prependExpConInvIfNeeded, isStatic, + isNative, resOverload, resOverride, resConOverload, isNull, - makeNonLocalVarNonParamSimpleNameQualified + makeNonLocalVarNonParamSimpleNameQualified, + getFullyQualifiedDescriptor } from './utils' +import { natives } from './natives' type CmdEvaluator = ( command: ControlItem, @@ -136,7 +139,7 @@ export const evaluate = ( return stash.peek() } -const cmdEvaluators: { [type: string]: CmdEvaluator } = { +export const cmdEvaluators: { [type: string]: CmdEvaluator } = { CompilationUnit: ( command: CompilationUnit, _environment: Environment, @@ -501,6 +504,28 @@ const cmdEvaluators: { [type: string]: CmdEvaluator } = { environment.defineVariable(params[i].identifier, params[i].unannType, args[i]) } + // Native function escape hatch + if (closure.mtdOrCon.kind === 'MethodDeclaration' && isNative(closure.mtdOrCon)) { + const nativeFn = natives[getFullyQualifiedDescriptor(closure.mtdOrCon)] + + if (!nativeFn) { + throw new errors.UndefinedNativeMethod(nativeFn) + } + + // call foreign fn + nativeFn({ control, stash, environment }) + + // only because resetInstr demands one, never actually used + const superfluousReturnStatement: ReturnStatement = { + kind: 'ReturnStatement', + exp: { kind: 'Void' } + } + + // handle return from native fn + control.push(instr.resetInstr(superfluousReturnStatement)) + return + } + // Push method/constructor body. const body = closure.mtdOrCon.kind === 'MethodDeclaration' diff --git a/src/ec-evaluator/natives.ts b/src/ec-evaluator/natives.ts new file mode 100644 index 0000000..9a188de --- /dev/null +++ b/src/ec-evaluator/natives.ts @@ -0,0 +1,29 @@ +import { Control, Environment, Stash } from './components' + +/* + Native function escape hatch. + + Used for implementing native methods. Allows for purely arbitrary modification to the control, stash, and environment via an external handler function. + + All native functions are expected to respect Java method call preconditions and postconditions, with the exception of returning. When a native function is called, it can expect the following. + + Preconditions: environment has been initialised for the current function call. + + Postconditions: returned result must be pushed onto the top of the stash. + + The current implementation automatically injects a return instruction after the external handler function call ends. +*/ + +export type NativeFunction = ({ + control, + stash, + environment +}: { + control: Control + stash: Stash + environment: Environment +}) => void + +export const natives: { + [descriptor: string]: NativeFunction +} = {} diff --git a/src/ec-evaluator/nodeCreator.ts b/src/ec-evaluator/nodeCreator.ts index 05d9c3c..6c62247 100644 --- a/src/ec-evaluator/nodeCreator.ts +++ b/src/ec-evaluator/nodeCreator.ts @@ -138,5 +138,41 @@ export const objClassDeclNode = (): ClassDeclaration => ({ kind: 'NormalClassDeclaration', classModifier: [], typeIdentifier: OBJECT_CLASS, - classBody: [] + classBody: [ + { + kind: 'FieldDeclaration', + fieldModifier: ['private'], + fieldType: 'int', + variableDeclaratorList: [ + { + kind: 'VariableDeclarator', + variableDeclaratorId: 'hash', + variableInitializer: { + kind: 'Literal', + literalType: { + kind: 'DecimalIntegerLiteral', + value: String(Math.floor(Math.random() * Math.pow(2, 32))) + } + } + } + ] + }, + { + kind: 'MethodDeclaration', + methodModifier: ['public'], + methodHeader: { result: 'int', identifier: 'hashCode', formalParameterList: [] }, + methodBody: { + kind: 'Block', + blockStatements: [ + { + kind: 'ReturnStatement', + exp: { + kind: 'ExpressionName', + name: 'this.hash' + } + } + ] + } + } + ] }) diff --git a/src/ec-evaluator/utils.ts b/src/ec-evaluator/utils.ts index 650a078..4aaa0ad 100644 --- a/src/ec-evaluator/utils.ts +++ b/src/ec-evaluator/utils.ts @@ -183,6 +183,11 @@ export const getDescriptor = (mtdOrCon: MethodDeclaration | ConstructorDeclarati : `${mtdOrCon.constructorDeclarator.identifier}(${mtdOrCon.constructorDeclarator.formalParameterList.map(p => p.unannType).join(',')})` } +// for native methods (uses new proposed format) with parameter names +// because native functions must retrieve variables from the environment by identifier, this descriptor type also includes parameter names for convenience +export const getFullyQualifiedDescriptor = (mtd: MethodDeclaration): string => + `${mtd.methodHeader.identifier}(${mtd.methodHeader.formalParameterList.map(p => `${p.unannType} ${p.identifier}`).join(',')}): ${mtd.methodHeader.result}` + export const isQualified = (name: string) => { return name.includes('.') } @@ -230,6 +235,10 @@ export const isInstance = (fieldOrMtd: FieldDeclaration | MethodDeclaration): bo return !isStatic(fieldOrMtd) } +export const isNative = (mtd: MethodDeclaration): boolean => { + return mtd.methodModifier.includes('native') +} + const convertFieldDeclToExpStmtAssmt = (fd: FieldDeclaration): ExpressionStatement => { const left = `this.${fd.variableDeclaratorList[0].variableDeclaratorId}` // Fields are always initialized to default value if initializer is absent. diff --git a/yarn.lock b/yarn.lock index f67a700..5e3d891 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4,7 +4,7 @@ "@aashutoshrathi/word-wrap@^1.2.3": version "1.2.6" - resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" + resolved "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz" integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== "@ampproject/remapping@^2.2.0": @@ -302,21 +302,146 @@ resolved "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== +"@esbuild/aix-ppc64@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.25.5.tgz#4e0f91776c2b340e75558f60552195f6fad09f18" + integrity sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA== + +"@esbuild/android-arm64@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.25.5.tgz#bc766407f1718923f6b8079c8c61bf86ac3a6a4f" + integrity sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg== + +"@esbuild/android-arm@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.25.5.tgz#4290d6d3407bae3883ad2cded1081a234473ce26" + integrity sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA== + +"@esbuild/android-x64@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.25.5.tgz#40c11d9cbca4f2406548c8a9895d321bc3b35eff" + integrity sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw== + +"@esbuild/darwin-arm64@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.25.5.tgz#49d8bf8b1df95f759ac81eb1d0736018006d7e34" + integrity sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ== + +"@esbuild/darwin-x64@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.25.5.tgz#e27a5d92a14886ef1d492fd50fc61a2d4d87e418" + integrity sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ== + +"@esbuild/freebsd-arm64@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.5.tgz#97cede59d638840ca104e605cdb9f1b118ba0b1c" + integrity sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw== + +"@esbuild/freebsd-x64@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.25.5.tgz#71c77812042a1a8190c3d581e140d15b876b9c6f" + integrity sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw== + +"@esbuild/linux-arm64@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.25.5.tgz#f7b7c8f97eff8ffd2e47f6c67eb5c9765f2181b8" + integrity sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg== + +"@esbuild/linux-arm@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.25.5.tgz#2a0be71b6cd8201fa559aea45598dffabc05d911" + integrity sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw== + +"@esbuild/linux-ia32@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.25.5.tgz#763414463cd9ea6fa1f96555d2762f9f84c61783" + integrity sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA== + +"@esbuild/linux-loong64@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.25.5.tgz#428cf2213ff786a502a52c96cf29d1fcf1eb8506" + integrity sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg== + +"@esbuild/linux-mips64el@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.25.5.tgz#5cbcc7fd841b4cd53358afd33527cd394e325d96" + integrity sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg== + +"@esbuild/linux-ppc64@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.25.5.tgz#0d954ab39ce4f5e50f00c4f8c4fd38f976c13ad9" + integrity sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ== + +"@esbuild/linux-riscv64@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.25.5.tgz#0e7dd30730505abd8088321e8497e94b547bfb1e" + integrity sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA== + +"@esbuild/linux-s390x@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.25.5.tgz#5669af81327a398a336d7e40e320b5bbd6e6e72d" + integrity sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ== + +"@esbuild/linux-x64@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.25.5.tgz#b2357dd153aa49038967ddc1ffd90c68a9d2a0d4" + integrity sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw== + +"@esbuild/netbsd-arm64@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.5.tgz#53b4dfb8fe1cee93777c9e366893bd3daa6ba63d" + integrity sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw== + +"@esbuild/netbsd-x64@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.25.5.tgz#a0206f6314ce7dc8713b7732703d0f58de1d1e79" + integrity sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ== + +"@esbuild/openbsd-arm64@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.5.tgz#2a796c87c44e8de78001d808c77d948a21ec22fd" + integrity sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw== + +"@esbuild/openbsd-x64@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.25.5.tgz#28d0cd8909b7fa3953af998f2b2ed34f576728f0" + integrity sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg== + +"@esbuild/sunos-x64@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.25.5.tgz#a28164f5b997e8247d407e36c90d3fd5ddbe0dc5" + integrity sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA== + +"@esbuild/win32-arm64@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.25.5.tgz#6eadbead38e8bd12f633a5190e45eff80e24007e" + integrity sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw== + +"@esbuild/win32-ia32@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.25.5.tgz#bab6288005482f9ed2adb9ded7e88eba9a62cc0d" + integrity sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ== + +"@esbuild/win32-x64@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.25.5.tgz#7fc114af5f6563f19f73324b5d5ff36ece0803d1" + integrity sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g== + "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": version "4.4.0" - resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" + resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz" integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== dependencies: eslint-visitor-keys "^3.3.0" "@eslint-community/regexpp@^4.5.1", "@eslint-community/regexpp@^4.6.1": version "4.10.0" - resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.10.0.tgz#548f6de556857c8bb73bbee70c35dc82a2e74d63" + resolved "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz" integrity sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA== "@eslint/eslintrc@^2.1.4": version "2.1.4" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.4.tgz#388a269f0f25c1b6adc317b5a2c55714894c70ad" + resolved "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz" integrity sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ== dependencies: ajv "^6.12.4" @@ -331,12 +456,12 @@ "@eslint/js@8.57.0": version "8.57.0" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.57.0.tgz#a5417ae8427873f1dd08b70b3574b453e67b5f7f" + resolved "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz" integrity sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g== "@humanwhocodes/config-array@^0.11.14": version "0.11.14" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.14.tgz#d78e481a039f7566ecc9660b4ea7fe6b1fec442b" + resolved "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz" integrity sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg== dependencies: "@humanwhocodes/object-schema" "^2.0.2" @@ -345,12 +470,12 @@ "@humanwhocodes/module-importer@^1.0.1": version "1.0.1" - resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" + resolved "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz" integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== "@humanwhocodes/object-schema@^2.0.2": version "2.0.2" - resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz#d9fae00a2d5cb40f92cfe64b47ad749fbc38f917" + resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz" integrity sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw== "@istanbuljs/load-nyc-config@^1.0.0": @@ -595,7 +720,7 @@ "@nodelib/fs.scandir@2.1.5": version "2.1.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== dependencies: "@nodelib/fs.stat" "2.0.5" @@ -603,12 +728,12 @@ "@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": version "2.0.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== "@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": version "1.2.8" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + resolved "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz" integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== dependencies: "@nodelib/fs.scandir" "2.1.5" @@ -616,7 +741,7 @@ "@peggyjs/from-mem@1.2.1": version "1.2.1" - resolved "https://registry.yarnpkg.com/@peggyjs/from-mem/-/from-mem-1.2.1.tgz#b83db5b439f1b02159fe47f5c9684bd1ee244edd" + resolved "https://registry.npmjs.org/@peggyjs/from-mem/-/from-mem-1.2.1.tgz" integrity sha512-qh5zG8WKT36142/FqOYtpF0scRR3ZJ3H5XST1bJ/KV2FvyB5MvUB/tB9ZjihRe1iKjJD4PBOZczzwEx7hJtgMw== dependencies: semver "7.6.0" @@ -705,9 +830,9 @@ "@types/istanbul-lib-report" "*" "@types/jest@^29.5.4": - version "29.5.5" - resolved "https://registry.npmjs.org/@types/jest/-/jest-29.5.5.tgz" - integrity sha512-ebylz2hnsWR9mYvmBFbXJXr+33UPc4+ZdxyDXh5w0FlPBTfCVN3wPL+kuOiQt3xvrK419v7XWeAs+AeOksafXg== + version "29.5.14" + resolved "https://registry.npmjs.org/@types/jest/-/jest-29.5.14.tgz" + integrity sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ== dependencies: expect "^29.0.0" pretty-format "^29.0.0" @@ -723,12 +848,12 @@ "@types/json-schema@^7.0.12": version "7.0.15" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" + resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz" integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== "@types/json5@^0.0.29": version "0.0.29" - resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" + resolved "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz" integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== "@types/lodash@^4.14.198": @@ -743,7 +868,7 @@ "@types/semver@^7.5.0": version "7.5.8" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.8.tgz#8268a8c57a3e4abd25c165ecd36237db7948a55e" + resolved "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz" integrity sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ== "@types/stack-utils@^2.0.0": @@ -770,7 +895,7 @@ "@typescript-eslint/eslint-plugin@^7.4.0": version "7.4.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.4.0.tgz#de61c3083842fc6ac889d2fc83c9a96b55ab8328" + resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.4.0.tgz" integrity sha512-yHMQ/oFaM7HZdVrVm/M2WHaNPgyuJH4WelkSVEWSSsir34kxW2kDJCxlXRhhGWEsMN0WAW/vLpKfKVcm8k+MPw== dependencies: "@eslint-community/regexpp" "^4.5.1" @@ -787,7 +912,7 @@ "@typescript-eslint/parser@^7.4.0": version "7.4.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-7.4.0.tgz#540f4321de1e52b886c0fa68628af1459954c1f1" + resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.4.0.tgz" integrity sha512-ZvKHxHLusweEUVwrGRXXUVzFgnWhigo4JurEj0dGF1tbcGh6buL+ejDdjxOQxv6ytcY1uhun1p2sm8iWStlgLQ== dependencies: "@typescript-eslint/scope-manager" "7.4.0" @@ -798,7 +923,7 @@ "@typescript-eslint/scope-manager@7.4.0": version "7.4.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-7.4.0.tgz#acfc69261f10ece7bf7ece1734f1713392c3655f" + resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.4.0.tgz" integrity sha512-68VqENG5HK27ypafqLVs8qO+RkNc7TezCduYrx8YJpXq2QGZ30vmNZGJJJC48+MVn4G2dCV8m5ZTVnzRexTVtw== dependencies: "@typescript-eslint/types" "7.4.0" @@ -806,7 +931,7 @@ "@typescript-eslint/type-utils@7.4.0": version "7.4.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-7.4.0.tgz#cfcaab21bcca441c57da5d3a1153555e39028cbd" + resolved "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.4.0.tgz" integrity sha512-247ETeHgr9WTRMqHbbQdzwzhuyaJ8dPTuyuUEMANqzMRB1rj/9qFIuIXK7l0FX9i9FXbHeBQl/4uz6mYuCE7Aw== dependencies: "@typescript-eslint/typescript-estree" "7.4.0" @@ -816,12 +941,12 @@ "@typescript-eslint/types@7.4.0": version "7.4.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.4.0.tgz#ee9dafa75c99eaee49de6dcc9348b45d354419b6" + resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.4.0.tgz" integrity sha512-mjQopsbffzJskos5B4HmbsadSJQWaRK0UxqQ7GuNA9Ga4bEKeiO6b2DnB6cM6bpc8lemaPseh0H9B/wyg+J7rw== "@typescript-eslint/typescript-estree@7.4.0": version "7.4.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.4.0.tgz#12dbcb4624d952f72c10a9f4431284fca24624f4" + resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.4.0.tgz" integrity sha512-A99j5AYoME/UBQ1ucEbbMEmGkN7SE0BvZFreSnTd1luq7yulcHdyGamZKizU7canpGDWGJ+Q6ZA9SyQobipePg== dependencies: "@typescript-eslint/types" "7.4.0" @@ -835,7 +960,7 @@ "@typescript-eslint/utils@7.4.0": version "7.4.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-7.4.0.tgz#d889a0630cab88bddedaf7c845c64a00576257bd" + resolved "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.4.0.tgz" integrity sha512-NQt9QLM4Tt8qrlBVY9lkMYzfYtNz8/6qwZg8pI3cMGlPnj6mOpRxxAm7BMJN9K0AiY+1BwJ5lVC650YJqYOuNg== dependencies: "@eslint-community/eslint-utils" "^4.4.0" @@ -848,7 +973,7 @@ "@typescript-eslint/visitor-keys@7.4.0": version "7.4.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.4.0.tgz#0c8ff2c1f8a6fe8d7d1a57ebbd4a638e86a60a94" + resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.4.0.tgz" integrity sha512-0zkC7YM0iX5Y41homUUeW1CHtZR01K3ybjM1l6QczoMuay0XKtrb93kv95AxUGwdjGr64nNqnOCwmEl616N8CA== dependencies: "@typescript-eslint/types" "7.4.0" @@ -856,7 +981,7 @@ "@ungap/structured-clone@^1.2.0": version "1.2.0" - resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" + resolved "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz" integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== abab@^2.0.6: @@ -874,7 +999,7 @@ acorn-globals@^7.0.0: acorn-jsx@^5.3.2: version "5.3.2" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== acorn-walk@^8.0.2: @@ -889,7 +1014,7 @@ acorn@^8.1.0, acorn@^8.8.1: acorn@^8.9.0: version "8.11.3" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a" + resolved "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz" integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== agent-base@6: @@ -901,7 +1026,7 @@ agent-base@6: ajv@^6.12.4: version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== dependencies: fast-deep-equal "^3.1.1" @@ -923,7 +1048,7 @@ ansi-regex@^5.0.1: ansi-sequence-parser@^1.1.0: version "1.1.1" - resolved "https://registry.yarnpkg.com/ansi-sequence-parser/-/ansi-sequence-parser-1.1.1.tgz#e0aa1cdcbc8f8bb0b5bca625aac41f5f056973cf" + resolved "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.1.tgz" integrity sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg== ansi-styles@^3.2.1: @@ -962,12 +1087,12 @@ argparse@^1.0.7: argparse@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== array-buffer-byte-length@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz#1e5583ec16763540a27ae52eed99ff899223568f" + resolved "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz" integrity sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg== dependencies: call-bind "^1.0.5" @@ -975,7 +1100,7 @@ array-buffer-byte-length@^1.0.1: array-includes@^3.1.7: version "3.1.8" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.8.tgz#5e370cbe172fdd5dd6530c1d4aadda25281ba97d" + resolved "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz" integrity sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ== dependencies: call-bind "^1.0.7" @@ -987,12 +1112,12 @@ array-includes@^3.1.7: array-union@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + resolved "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== array.prototype.findlastindex@^1.2.3: version "1.2.5" - resolved "https://registry.yarnpkg.com/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz#8c35a755c72908719453f87145ca011e39334d0d" + resolved "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz" integrity sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ== dependencies: call-bind "^1.0.7" @@ -1004,7 +1129,7 @@ array.prototype.findlastindex@^1.2.3: array.prototype.flat@^1.3.2: version "1.3.2" - resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz#1476217df8cff17d72ee8f3ba06738db5b387d18" + resolved "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz" integrity sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA== dependencies: call-bind "^1.0.2" @@ -1014,7 +1139,7 @@ array.prototype.flat@^1.3.2: array.prototype.flatmap@^1.3.2: version "1.3.2" - resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz#c9a7c6831db8e719d6ce639190146c24bbd3e527" + resolved "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz" integrity sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ== dependencies: call-bind "^1.0.2" @@ -1024,7 +1149,7 @@ array.prototype.flatmap@^1.3.2: arraybuffer.prototype.slice@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz#097972f4255e41bc3425e37dc3f6421cf9aefde6" + resolved "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz" integrity sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A== dependencies: array-buffer-byte-length "^1.0.1" @@ -1043,7 +1168,7 @@ asynckit@^0.4.0: available-typed-arrays@^1.0.7: version "1.0.7" - resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz#a5cc375d6a03c2efc87a553f3e0b1522def14846" + resolved "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz" integrity sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ== dependencies: possible-typed-array-names "^1.0.0" @@ -1123,14 +1248,14 @@ brace-expansion@^1.1.7: brace-expansion@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz" integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== dependencies: balanced-match "^1.0.0" braces@^3.0.3: version "3.0.3" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" + resolved "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz" integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== dependencies: fill-range "^7.1.1" @@ -1166,7 +1291,7 @@ buffer-from@^1.0.0: call-bind@^1.0.2, call-bind@^1.0.5, call-bind@^1.0.6, call-bind@^1.0.7: version "1.0.7" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9" + resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz" integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w== dependencies: es-define-property "^1.0.0" @@ -1192,7 +1317,7 @@ camelcase@^6.2.0: camelcase@^8.0.0: version "8.0.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-8.0.0.tgz#c0d36d418753fb6ad9c5e0437579745c1c14a534" + resolved "https://registry.npmjs.org/camelcase/-/camelcase-8.0.0.tgz" integrity sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA== caniuse-lite@^1.0.30001517: @@ -1291,7 +1416,7 @@ combined-stream@^1.0.8: commander@^12.0.0: version "12.0.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-12.0.0.tgz#b929db6df8546080adfd004ab215ed48cf6f2592" + resolved "https://registry.npmjs.org/commander/-/commander-12.0.0.tgz" integrity sha512-MwVNWlYjDTtOjX5PiD7o5pK0UrFU/OYgcJfjjK4RaHZETNtjJqrZa9Y9ds88+A+f+d5lv+561eZ+yCKoS3gbAA== concat-map@0.0.1: @@ -1359,7 +1484,7 @@ data-urls@^3.0.2: data-view-buffer@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/data-view-buffer/-/data-view-buffer-1.0.1.tgz#8ea6326efec17a2e42620696e671d7d5a8bc66b2" + resolved "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz" integrity sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA== dependencies: call-bind "^1.0.6" @@ -1368,7 +1493,7 @@ data-view-buffer@^1.0.1: data-view-byte-length@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz#90721ca95ff280677eb793749fce1011347669e2" + resolved "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz" integrity sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ== dependencies: call-bind "^1.0.7" @@ -1377,7 +1502,7 @@ data-view-byte-length@^1.0.1: data-view-byte-offset@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz#5e0bbfb4828ed2d1b9b400cd8a7d119bca0ff18a" + resolved "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz" integrity sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA== dependencies: call-bind "^1.0.6" @@ -1393,7 +1518,7 @@ debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4: debug@^3.2.7: version "3.2.7" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== dependencies: ms "^2.1.1" @@ -1410,7 +1535,7 @@ dedent@^1.0.0: deep-is@^0.1.3: version "0.1.4" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== deepmerge@^4.2.2: @@ -1420,7 +1545,7 @@ deepmerge@^4.2.2: define-data-property@^1.0.1, define-data-property@^1.1.4: version "1.1.4" - resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e" + resolved "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz" integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== dependencies: es-define-property "^1.0.0" @@ -1429,7 +1554,7 @@ define-data-property@^1.0.1, define-data-property@^1.1.4: define-properties@^1.1.3, define-properties@^1.2.0, define-properties@^1.2.1: version "1.2.1" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" + resolved "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz" integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== dependencies: define-data-property "^1.0.1" @@ -1453,21 +1578,21 @@ diff-sequences@^29.6.3: dir-glob@^3.0.1: version "3.0.1" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz" integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== dependencies: path-type "^4.0.0" doctrine@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" + resolved "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz" integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== dependencies: esutils "^2.0.2" doctrine@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + resolved "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz" integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== dependencies: esutils "^2.0.2" @@ -1508,7 +1633,7 @@ error-ex@^1.3.1: es-abstract@^1.22.1, es-abstract@^1.22.3, es-abstract@^1.23.0, es-abstract@^1.23.2: version "1.23.3" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.23.3.tgz#8f0c5a35cd215312573c5a27c87dfd6c881a0aa0" + resolved "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz" integrity sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A== dependencies: array-buffer-byte-length "^1.0.1" @@ -1560,26 +1685,26 @@ es-abstract@^1.22.1, es-abstract@^1.22.3, es-abstract@^1.23.0, es-abstract@^1.23 es-define-property@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845" + resolved "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz" integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ== dependencies: get-intrinsic "^1.2.4" es-errors@^1.2.1, es-errors@^1.3.0: version "1.3.0" - resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" + resolved "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz" integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== es-object-atoms@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/es-object-atoms/-/es-object-atoms-1.0.0.tgz#ddb55cd47ac2e240701260bc2a8e31ecb643d941" + resolved "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz" integrity sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw== dependencies: es-errors "^1.3.0" es-set-tostringtag@^2.0.3: version "2.0.3" - resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz#8bb60f0a440c2e4281962428438d58545af39777" + resolved "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz" integrity sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ== dependencies: get-intrinsic "^1.2.4" @@ -1588,20 +1713,51 @@ es-set-tostringtag@^2.0.3: es-shim-unscopables@^1.0.0, es-shim-unscopables@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz#1f6942e71ecc7835ed1c8a83006d8771a63a3763" + resolved "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz" integrity sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw== dependencies: hasown "^2.0.0" es-to-primitive@^1.2.1: version "1.2.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + resolved "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz" integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== dependencies: is-callable "^1.1.4" is-date-object "^1.0.1" is-symbol "^1.0.2" +esbuild@~0.25.0: + version "0.25.5" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.25.5.tgz#71075054993fdfae76c66586f9b9c1f8d7edd430" + integrity sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ== + optionalDependencies: + "@esbuild/aix-ppc64" "0.25.5" + "@esbuild/android-arm" "0.25.5" + "@esbuild/android-arm64" "0.25.5" + "@esbuild/android-x64" "0.25.5" + "@esbuild/darwin-arm64" "0.25.5" + "@esbuild/darwin-x64" "0.25.5" + "@esbuild/freebsd-arm64" "0.25.5" + "@esbuild/freebsd-x64" "0.25.5" + "@esbuild/linux-arm" "0.25.5" + "@esbuild/linux-arm64" "0.25.5" + "@esbuild/linux-ia32" "0.25.5" + "@esbuild/linux-loong64" "0.25.5" + "@esbuild/linux-mips64el" "0.25.5" + "@esbuild/linux-ppc64" "0.25.5" + "@esbuild/linux-riscv64" "0.25.5" + "@esbuild/linux-s390x" "0.25.5" + "@esbuild/linux-x64" "0.25.5" + "@esbuild/netbsd-arm64" "0.25.5" + "@esbuild/netbsd-x64" "0.25.5" + "@esbuild/openbsd-arm64" "0.25.5" + "@esbuild/openbsd-x64" "0.25.5" + "@esbuild/sunos-x64" "0.25.5" + "@esbuild/win32-arm64" "0.25.5" + "@esbuild/win32-ia32" "0.25.5" + "@esbuild/win32-x64" "0.25.5" + escalade@^3.1.1: version "3.1.1" resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" @@ -1619,7 +1775,7 @@ escape-string-regexp@^2.0.0: escape-string-regexp@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== escodegen@^2.0.0: @@ -1635,12 +1791,12 @@ escodegen@^2.0.0: eslint-config-prettier@^9.1.0: version "9.1.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz#31af3d94578645966c082fcb71a5846d3c94867f" + resolved "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz" integrity sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw== eslint-import-resolver-node@^0.3.9: version "0.3.9" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz#d4eaac52b8a2e7c3cd1903eb00f7e053356118ac" + resolved "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz" integrity sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g== dependencies: debug "^3.2.7" @@ -1649,14 +1805,14 @@ eslint-import-resolver-node@^0.3.9: eslint-module-utils@^2.8.0: version "2.8.1" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz#52f2404300c3bd33deece9d7372fb337cc1d7c34" + resolved "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz" integrity sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q== dependencies: debug "^3.2.7" eslint-plugin-import@^2.29.1: version "2.29.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz#d45b37b5ef5901d639c15270d74d46d161150643" + resolved "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz" integrity sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw== dependencies: array-includes "^3.1.7" @@ -1679,7 +1835,7 @@ eslint-plugin-import@^2.29.1: eslint-scope@^7.2.2: version "7.2.2" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" + resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz" integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== dependencies: esrecurse "^4.3.0" @@ -1687,12 +1843,12 @@ eslint-scope@^7.2.2: eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: version "3.4.3" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" + resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz" integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== eslint@^8.57.0: version "8.57.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.57.0.tgz#c786a6fd0e0b68941aaf624596fb987089195668" + resolved "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz" integrity sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ== dependencies: "@eslint-community/eslint-utils" "^4.2.0" @@ -1736,7 +1892,7 @@ eslint@^8.57.0: espree@^9.6.0, espree@^9.6.1: version "9.6.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" + resolved "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz" integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== dependencies: acorn "^8.9.0" @@ -1750,14 +1906,14 @@ esprima@^4.0.0, esprima@^4.0.1: esquery@^1.4.2: version "1.5.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" + resolved "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz" integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== dependencies: estraverse "^5.1.0" esrecurse@^4.3.0: version "4.3.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz" integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== dependencies: estraverse "^5.2.0" @@ -1805,12 +1961,12 @@ expect@^29.0.0, expect@^29.7.0: fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== fast-glob@^3.2.9: version "3.3.2" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" + resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz" integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== dependencies: "@nodelib/fs.stat" "^2.0.2" @@ -1826,12 +1982,12 @@ fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0, fast-json-sta fast-levenshtein@^2.0.6: version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz" integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== fastq@^1.6.0: version "1.17.1" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.17.1.tgz#2a523f07a4e7b1e81a42b91b8bf2254107753b47" + resolved "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz" integrity sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w== dependencies: reusify "^1.0.4" @@ -1845,14 +2001,14 @@ fb-watchman@^2.0.0: file-entry-cache@^6.0.1: version "6.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz" integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== dependencies: flat-cache "^3.0.4" fill-range@^7.1.1: version "7.1.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" + resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz" integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== dependencies: to-regex-range "^5.0.1" @@ -1867,7 +2023,7 @@ find-up@^4.0.0, find-up@^4.1.0: find-up@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + resolved "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz" integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== dependencies: locate-path "^6.0.0" @@ -1875,7 +2031,7 @@ find-up@^5.0.0: flat-cache@^3.0.4: version "3.2.0" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.2.0.tgz#2c0c2d5040c99b1632771a9d105725c0115363ee" + resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz" integrity sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw== dependencies: flatted "^3.2.9" @@ -1884,12 +2040,12 @@ flat-cache@^3.0.4: flatted@^3.2.9: version "3.3.1" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.1.tgz#21db470729a6734d4997002f439cb308987f567a" + resolved "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz" integrity sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw== for-each@^0.3.3: version "0.3.3" - resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" + resolved "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz" integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== dependencies: is-callable "^1.1.3" @@ -1908,9 +2064,9 @@ fs.realpath@^1.0.0: resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== -fsevents@^2.3.2: +fsevents@^2.3.2, fsevents@~2.3.3: version "2.3.3" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz" integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== function-bind@^1.1.1: @@ -1920,12 +2076,12 @@ function-bind@^1.1.1: function-bind@^1.1.2: version "1.1.2" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz" integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== function.prototype.name@^1.1.6: version "1.1.6" - resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.6.tgz#cdf315b7d90ee77a4c6ee216c3c3362da07533fd" + resolved "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz" integrity sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg== dependencies: call-bind "^1.0.2" @@ -1935,7 +2091,7 @@ function.prototype.name@^1.1.6: functions-have-names@^1.2.3: version "1.2.3" - resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" + resolved "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz" integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== gensync@^1.0.0-beta.2: @@ -1950,7 +2106,7 @@ get-caller-file@^2.0.5: get-intrinsic@^1.1.3, get-intrinsic@^1.2.1, get-intrinsic@^1.2.3, get-intrinsic@^1.2.4: version "1.2.4" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd" + resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz" integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ== dependencies: es-errors "^1.3.0" @@ -1971,23 +2127,30 @@ get-stream@^6.0.0: get-symbol-description@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.2.tgz#533744d5aa20aca4e079c8e5daf7fd44202821f5" + resolved "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz" integrity sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg== dependencies: call-bind "^1.0.5" es-errors "^1.3.0" get-intrinsic "^1.2.4" +get-tsconfig@^4.7.5: + version "4.10.1" + resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.10.1.tgz#d34c1c01f47d65a606c37aa7a177bc3e56ab4b2e" + integrity sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ== + dependencies: + resolve-pkg-maps "^1.0.0" + glob-parent@^5.1.2: version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== dependencies: is-glob "^4.0.1" glob-parent@^6.0.2: version "6.0.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz" integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== dependencies: is-glob "^4.0.3" @@ -2011,21 +2174,21 @@ globals@^11.1.0: globals@^13.19.0: version "13.24.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.24.0.tgz#8432a19d78ce0c1e833949c36adb345400bb1171" + resolved "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz" integrity sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ== dependencies: type-fest "^0.20.2" globalthis@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.3.tgz#5852882a52b80dc301b0660273e1ed082f0b6ccf" + resolved "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz" integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA== dependencies: define-properties "^1.1.3" globby@^11.1.0: version "11.1.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + resolved "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz" integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== dependencies: array-union "^2.1.0" @@ -2037,7 +2200,7 @@ globby@^11.1.0: gopd@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" + resolved "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz" integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== dependencies: get-intrinsic "^1.1.3" @@ -2049,12 +2212,12 @@ graceful-fs@^4.2.9: graphemer@^1.4.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" + resolved "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz" integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== handlebars@^4.7.7: version "4.7.8" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.8.tgz#41c42c18b1be2365439188c77c6afae71c0cd9e9" + resolved "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz" integrity sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ== dependencies: minimist "^1.2.5" @@ -2066,7 +2229,7 @@ handlebars@^4.7.7: has-bigints@^1.0.1, has-bigints@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" + resolved "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz" integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== has-flag@^3.0.0: @@ -2081,24 +2244,24 @@ has-flag@^4.0.0: has-property-descriptors@^1.0.0, has-property-descriptors@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854" + resolved "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz" integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== dependencies: es-define-property "^1.0.0" has-proto@^1.0.1, has-proto@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.3.tgz#b31ddfe9b0e6e9914536a6ab286426d0214f77fd" + resolved "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz" integrity sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q== has-symbols@^1.0.2, has-symbols@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz" integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== has-tostringtag@^1.0.0, has-tostringtag@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc" + resolved "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz" integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw== dependencies: has-symbols "^1.0.3" @@ -2112,7 +2275,7 @@ has@^1.0.3: hasown@^2.0.0, hasown@^2.0.1, hasown@^2.0.2: version "2.0.2" - resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" + resolved "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz" integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== dependencies: function-bind "^1.1.2" @@ -2153,7 +2316,7 @@ human-signals@^2.1.0: husky@^9.0.11: version "9.0.11" - resolved "https://registry.yarnpkg.com/husky/-/husky-9.0.11.tgz#fc91df4c756050de41b3e478b2158b87c1e79af9" + resolved "https://registry.npmjs.org/husky/-/husky-9.0.11.tgz" integrity sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw== iconv-lite@0.6.3: @@ -2165,12 +2328,12 @@ iconv-lite@0.6.3: ignore@^5.2.0, ignore@^5.2.4: version "5.3.1" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.1.tgz#5073e554cd42c5b33b394375f538b8593e34d4ef" + resolved "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz" integrity sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw== import-fresh@^3.2.1: version "3.3.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz" integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== dependencies: parent-module "^1.0.0" @@ -2204,7 +2367,7 @@ inherits@2: internal-slot@^1.0.7: version "1.0.7" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.7.tgz#c06dcca3ed874249881007b0a5523b172a190802" + resolved "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz" integrity sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g== dependencies: es-errors "^1.3.0" @@ -2213,7 +2376,7 @@ internal-slot@^1.0.7: is-array-buffer@^3.0.4: version "3.0.4" - resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.4.tgz#7a1f92b3d61edd2bc65d24f130530ea93d7fae98" + resolved "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz" integrity sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw== dependencies: call-bind "^1.0.2" @@ -2226,14 +2389,14 @@ is-arrayish@^0.2.1: is-bigint@^1.0.1: version "1.0.4" - resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" + resolved "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz" integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== dependencies: has-bigints "^1.0.1" is-boolean-object@^1.1.0: version "1.1.2" - resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" + resolved "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz" integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== dependencies: call-bind "^1.0.2" @@ -2241,7 +2404,7 @@ is-boolean-object@^1.1.0: is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: version "1.2.7" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" + resolved "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz" integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== is-core-module@^2.13.0: @@ -2253,28 +2416,28 @@ is-core-module@^2.13.0: is-core-module@^2.13.1: version "2.13.1" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384" + resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz" integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw== dependencies: hasown "^2.0.0" is-data-view@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/is-data-view/-/is-data-view-1.0.1.tgz#4b4d3a511b70f3dc26d42c03ca9ca515d847759f" + resolved "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz" integrity sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w== dependencies: is-typed-array "^1.1.13" is-date-object@^1.0.1: version "1.0.5" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" + resolved "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz" integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== dependencies: has-tostringtag "^1.0.0" is-extglob@^2.1.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== is-fullwidth-code-point@^3.0.0: @@ -2289,19 +2452,19 @@ is-generator-fn@^2.0.0: is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3: version "4.0.3" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== dependencies: is-extglob "^2.1.1" is-negative-zero@^2.0.3: version "2.0.3" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.3.tgz#ced903a027aca6381b777a5743069d7376a49747" + resolved "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz" integrity sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw== is-number-object@^1.0.4: version "1.0.7" - resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc" + resolved "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz" integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== dependencies: has-tostringtag "^1.0.0" @@ -2313,7 +2476,7 @@ is-number@^7.0.0: is-path-inside@^3.0.3: version "3.0.3" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + resolved "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz" integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== is-potential-custom-element-name@^1.0.1: @@ -2323,7 +2486,7 @@ is-potential-custom-element-name@^1.0.1: is-regex@^1.1.4: version "1.1.4" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" + resolved "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz" integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== dependencies: call-bind "^1.0.2" @@ -2331,7 +2494,7 @@ is-regex@^1.1.4: is-shared-array-buffer@^1.0.2, is-shared-array-buffer@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz#1237f1cba059cdb62431d378dcc37d9680181688" + resolved "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz" integrity sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg== dependencies: call-bind "^1.0.7" @@ -2343,35 +2506,35 @@ is-stream@^2.0.0: is-string@^1.0.5, is-string@^1.0.7: version "1.0.7" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" + resolved "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz" integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== dependencies: has-tostringtag "^1.0.0" is-symbol@^1.0.2, is-symbol@^1.0.3: version "1.0.4" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" + resolved "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz" integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== dependencies: has-symbols "^1.0.2" is-typed-array@^1.1.13: version "1.1.13" - resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.13.tgz#d6c5ca56df62334959322d7d7dd1cca50debe229" + resolved "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz" integrity sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw== dependencies: which-typed-array "^1.1.14" is-weakref@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" + resolved "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz" integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== dependencies: call-bind "^1.0.2" isarray@^2.0.5: version "2.0.5" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" + resolved "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz" integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== isexe@^2.0.0: @@ -2827,7 +2990,7 @@ js-yaml@^3.13.1: js-yaml@^4.1.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz" integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== dependencies: argparse "^2.0.1" @@ -2871,7 +3034,7 @@ jsesc@^2.5.1: json-buffer@3.0.1: version "3.0.1" - resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" + resolved "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz" integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== json-parse-even-better-errors@^2.3.0: @@ -2881,17 +3044,17 @@ json-parse-even-better-errors@^2.3.0: json-schema-traverse@^0.4.1: version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz" integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== json5@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593" + resolved "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz" integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA== dependencies: minimist "^1.2.0" @@ -2903,12 +3066,12 @@ json5@^2.2.3: jsonc-parser@^3.2.0: version "3.2.1" - resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.1.tgz#031904571ccf929d7670ee8c547545081cb37f1a" + resolved "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.1.tgz" integrity sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA== keyv@^4.5.3: version "4.5.4" - resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" + resolved "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz" integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== dependencies: json-buffer "3.0.1" @@ -2925,7 +3088,7 @@ leven@^3.1.0: levn@^0.4.1: version "0.4.1" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + resolved "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz" integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== dependencies: prelude-ls "^1.2.1" @@ -2945,7 +3108,7 @@ locate-path@^5.0.0: locate-path@^6.0.0: version "6.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + resolved "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz" integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== dependencies: p-locate "^5.0.0" @@ -2957,7 +3120,7 @@ lodash.memoize@4.x: lodash.merge@^4.6.2: version "4.6.2" - resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== lodash@4.17.21, lodash@^4.17.21: @@ -2981,7 +3144,7 @@ lru-cache@^6.0.0: lunr@^2.3.9: version "2.3.9" - resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.9.tgz#18b123142832337dd6e964df1a5a7707b25d35e1" + resolved "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz" integrity sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow== make-dir@^4.0.0: @@ -3005,7 +3168,7 @@ makeerror@1.0.12: marked@^4.3.0: version "4.3.0" - resolved "https://registry.yarnpkg.com/marked/-/marked-4.3.0.tgz#796362821b019f734054582038b116481b456cf3" + resolved "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz" integrity sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A== merge-stream@^2.0.0: @@ -3015,12 +3178,12 @@ merge-stream@^2.0.0: merge2@^1.3.0, merge2@^1.4.1: version "1.4.1" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== micromatch@^4.0.4: version "4.0.8" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202" + resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz" integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== dependencies: braces "^3.0.3" @@ -3045,7 +3208,7 @@ mimic-fn@^2.1.0: minimatch@9.0.3, minimatch@^9.0.3: version "9.0.3" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz" integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== dependencies: brace-expansion "^2.0.1" @@ -3059,7 +3222,7 @@ minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6: version "1.2.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== ms@2.1.2: @@ -3069,7 +3232,7 @@ ms@2.1.2: ms@^2.1.1: version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== natural-compare@^1.4.0: @@ -3079,7 +3242,7 @@ natural-compare@^1.4.0: neo-async@^2.6.2: version "2.6.2" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + resolved "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== node-int64@^0.4.0: @@ -3111,17 +3274,17 @@ nwsapi@^2.2.2: object-inspect@^1.13.1: version "1.13.1" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2" + resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz" integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ== object-keys@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + resolved "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== object.assign@^4.1.5: version "4.1.5" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.5.tgz#3a833f9ab7fdb80fc9e8d2300c803d216d8fdbb0" + resolved "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz" integrity sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ== dependencies: call-bind "^1.0.5" @@ -3131,7 +3294,7 @@ object.assign@^4.1.5: object.fromentries@^2.0.7: version "2.0.8" - resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.8.tgz#f7195d8a9b97bd95cbc1999ea939ecd1a2b00c65" + resolved "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz" integrity sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ== dependencies: call-bind "^1.0.7" @@ -3141,7 +3304,7 @@ object.fromentries@^2.0.7: object.groupby@^1.0.1: version "1.0.3" - resolved "https://registry.yarnpkg.com/object.groupby/-/object.groupby-1.0.3.tgz#9b125c36238129f6f7b61954a1e7176148d5002e" + resolved "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz" integrity sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ== dependencies: call-bind "^1.0.7" @@ -3150,7 +3313,7 @@ object.groupby@^1.0.1: object.values@^1.1.7: version "1.2.0" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.2.0.tgz#65405a9d92cee68ac2d303002e0b8470a4d9ab1b" + resolved "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz" integrity sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ== dependencies: call-bind "^1.0.7" @@ -3173,7 +3336,7 @@ onetime@^5.1.2: optionator@^0.9.3: version "0.9.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" + resolved "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz" integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== dependencies: "@aashutoshrathi/word-wrap" "^1.2.3" @@ -3206,7 +3369,7 @@ p-locate@^4.1.0: p-locate@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + resolved "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz" integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== dependencies: p-limit "^3.0.2" @@ -3218,7 +3381,7 @@ p-try@^2.0.0: parent-module@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + resolved "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz" integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== dependencies: callsites "^3.0.0" @@ -3262,12 +3425,12 @@ path-parse@^1.0.7: path-type@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== peggy@^4.0.2: version "4.0.2" - resolved "https://registry.yarnpkg.com/peggy/-/peggy-4.0.2.tgz#440b79ff8270668294d877addb3a30bb9e28bad5" + resolved "https://registry.npmjs.org/peggy/-/peggy-4.0.2.tgz" integrity sha512-j4cepPgB20V7honmTAI+7U022y/n/wVi7Rbbd2QrMl2nifFECpngvA6Zhrz/JdmZ5LIBoTdkgHcDzzaA6C4ABg== dependencies: "@peggyjs/from-mem" "1.2.1" @@ -3298,17 +3461,17 @@ pkg-dir@^4.2.0: possible-typed-array-names@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz#89bb63c6fada2c3e90adc4a647beeeb39cc7bf8f" + resolved "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz" integrity sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q== prelude-ls@^1.2.1: version "1.2.1" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== prettier@^3.2.5: version "3.2.5" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.2.5.tgz#e52bc3090586e824964a8813b09aba6233b28368" + resolved "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz" integrity sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A== pretty-format@^29.0.0, pretty-format@^29.7.0: @@ -3335,7 +3498,7 @@ psl@^1.1.33: punycode@^2.1.0: version "2.3.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" + resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz" integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== punycode@^2.1.1: @@ -3355,7 +3518,7 @@ querystringify@^2.1.1: queue-microtask@^1.2.2: version "1.2.3" - resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== react-is@^18.0.0: @@ -3370,7 +3533,7 @@ regexp-to-ast@0.4.0: regexp.prototype.flags@^1.5.2: version "1.5.2" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz#138f644a3350f981a858c44f6bb1a61ff59be334" + resolved "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz" integrity sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw== dependencies: call-bind "^1.0.6" @@ -3397,7 +3560,7 @@ resolve-cwd@^3.0.0: resolve-from@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== resolve-from@^5.0.0: @@ -3405,6 +3568,11 @@ resolve-from@^5.0.0: resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz" integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== +resolve-pkg-maps@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz#616b3dc2c57056b5588c31cdf4b3d64db133720f" + integrity sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw== + resolve.exports@^2.0.0: version "2.0.2" resolved "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz" @@ -3421,7 +3589,7 @@ resolve@^1.20.0: resolve@^1.22.4: version "1.22.8" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" + resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz" integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== dependencies: is-core-module "^2.13.0" @@ -3430,26 +3598,26 @@ resolve@^1.22.4: reusify@^1.0.4: version "1.0.4" - resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== rimraf@^3.0.2: version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== dependencies: glob "^7.1.3" run-parallel@^1.1.9: version "1.2.0" - resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz" integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== dependencies: queue-microtask "^1.2.2" safe-array-concat@^1.1.2: version "1.1.2" - resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.1.2.tgz#81d77ee0c4e8b863635227c721278dd524c20edb" + resolved "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz" integrity sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q== dependencies: call-bind "^1.0.7" @@ -3459,7 +3627,7 @@ safe-array-concat@^1.1.2: safe-regex-test@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.3.tgz#a5b4c0f06e0ab50ea2c395c14d8371232924c377" + resolved "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz" integrity sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw== dependencies: call-bind "^1.0.6" @@ -3480,7 +3648,7 @@ saxes@^6.0.0: semver@7.6.0: version "7.6.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.0.tgz#1a46a4db4bffcccd97b743b5005c8325f23d4e2d" + resolved "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz" integrity sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg== dependencies: lru-cache "^6.0.0" @@ -3499,7 +3667,7 @@ semver@^7.5.3, semver@^7.5.4: set-function-length@^1.2.1: version "1.2.2" - resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" + resolved "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz" integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg== dependencies: define-data-property "^1.1.4" @@ -3511,7 +3679,7 @@ set-function-length@^1.2.1: set-function-name@^2.0.1: version "2.0.2" - resolved "https://registry.yarnpkg.com/set-function-name/-/set-function-name-2.0.2.tgz#16a705c5a0dc2f5e638ca96d8a8cd4e1c2b90985" + resolved "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz" integrity sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ== dependencies: define-data-property "^1.1.4" @@ -3533,7 +3701,7 @@ shebang-regex@^3.0.0: shiki@^0.14.7: version "0.14.7" - resolved "https://registry.yarnpkg.com/shiki/-/shiki-0.14.7.tgz#c3c9e1853e9737845f1d2ef81b31bcfb07056d4e" + resolved "https://registry.npmjs.org/shiki/-/shiki-0.14.7.tgz" integrity sha512-dNPAPrxSc87ua2sKJ3H5dQ/6ZaY8RNnaAqK+t0eG7p0Soi2ydiqbGOTaZCqaYvA/uZYfS1LJnemt3Q+mSfcPCg== dependencies: ansi-sequence-parser "^1.1.0" @@ -3543,7 +3711,7 @@ shiki@^0.14.7: side-channel@^1.0.4: version "1.0.6" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2" + resolved "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz" integrity sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA== dependencies: call-bind "^1.0.7" @@ -3568,7 +3736,7 @@ slash@^3.0.0: source-map-generator@0.8.0: version "0.8.0" - resolved "https://registry.yarnpkg.com/source-map-generator/-/source-map-generator-0.8.0.tgz#10d5ca0651e2c9302ea338739cbd4408849c5d00" + resolved "https://registry.npmjs.org/source-map-generator/-/source-map-generator-0.8.0.tgz" integrity sha512-psgxdGMwl5MZM9S3FWee4EgsEaIjahYV5AzGnwUvPhWeITz/j6rKpysQHlQ4USdxvINlb8lKfWGIXwfkrgtqkA== source-map-support@0.5.13: @@ -3615,7 +3783,7 @@ string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: string.prototype.trim@^1.2.9: version "1.2.9" - resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz#b6fa326d72d2c78b6df02f7759c73f8f6274faa4" + resolved "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz" integrity sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw== dependencies: call-bind "^1.0.7" @@ -3625,7 +3793,7 @@ string.prototype.trim@^1.2.9: string.prototype.trimend@^1.0.8: version "1.0.8" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz#3651b8513719e8a9f48de7f2f77640b26652b229" + resolved "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz" integrity sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ== dependencies: call-bind "^1.0.7" @@ -3634,7 +3802,7 @@ string.prototype.trimend@^1.0.8: string.prototype.trimstart@^1.0.8: version "1.0.8" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz#7ee834dda8c7c17eff3118472bb35bfedaa34dde" + resolved "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz" integrity sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg== dependencies: call-bind "^1.0.7" @@ -3650,7 +3818,7 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1: strip-bom@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz" integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== strip-bom@^4.0.0: @@ -3710,7 +3878,7 @@ test-exclude@^6.0.0: text-table@^0.2.0: version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== tmpl@1.0.5: @@ -3749,7 +3917,7 @@ tr46@^3.0.0: ts-api-utils@^1.0.1: version "1.3.0" - resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.3.0.tgz#4b490e27129f1e8e686b45cc4ab63714dc60eea1" + resolved "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz" integrity sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ== ts-jest@^29.1.1: @@ -3768,7 +3936,7 @@ ts-jest@^29.1.1: tsconfig-paths@^3.15.0: version "3.15.0" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz#5299ec605e55b1abb23ec939ef15edaf483070d4" + resolved "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz" integrity sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg== dependencies: "@types/json5" "^0.0.29" @@ -3776,9 +3944,19 @@ tsconfig-paths@^3.15.0: minimist "^1.2.6" strip-bom "^3.0.0" +tsx@^4.19.4: + version "4.19.4" + resolved "https://registry.yarnpkg.com/tsx/-/tsx-4.19.4.tgz#647b4141f4fdd9d773a9b564876773d2846901f4" + integrity sha512-gK5GVzDkJK1SI1zwHf32Mqxf2tSJkNx+eYcNly5+nHvWqXUJYUkWBQtKauoESz3ymezAI++ZwT855x5p5eop+Q== + dependencies: + esbuild "~0.25.0" + get-tsconfig "^4.7.5" + optionalDependencies: + fsevents "~2.3.3" + type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + resolved "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz" integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== dependencies: prelude-ls "^1.2.1" @@ -3790,7 +3968,7 @@ type-detect@4.0.8: type-fest@^0.20.2: version "0.20.2" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz" integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== type-fest@^0.21.3: @@ -3800,7 +3978,7 @@ type-fest@^0.21.3: typed-array-buffer@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz#1867c5d83b20fcb5ccf32649e5e2fc7424474ff3" + resolved "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz" integrity sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ== dependencies: call-bind "^1.0.7" @@ -3809,7 +3987,7 @@ typed-array-buffer@^1.0.2: typed-array-byte-length@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz#d92972d3cff99a3fa2e765a28fcdc0f1d89dec67" + resolved "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz" integrity sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw== dependencies: call-bind "^1.0.7" @@ -3820,7 +3998,7 @@ typed-array-byte-length@^1.0.1: typed-array-byte-offset@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz#f9ec1acb9259f395093e4567eb3c28a580d02063" + resolved "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz" integrity sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA== dependencies: available-typed-arrays "^1.0.7" @@ -3832,7 +4010,7 @@ typed-array-byte-offset@^1.0.2: typed-array-length@^1.0.6: version "1.0.6" - resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.6.tgz#57155207c76e64a3457482dfdc1c9d1d3c4c73a3" + resolved "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz" integrity sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g== dependencies: call-bind "^1.0.7" @@ -3844,21 +4022,21 @@ typed-array-length@^1.0.6: typedoc-plugin-markdown@^3.17.1: version "3.17.1" - resolved "https://registry.yarnpkg.com/typedoc-plugin-markdown/-/typedoc-plugin-markdown-3.17.1.tgz#c33f42363c185adf842f4699166015f7fe0ed02b" + resolved "https://registry.npmjs.org/typedoc-plugin-markdown/-/typedoc-plugin-markdown-3.17.1.tgz" integrity sha512-QzdU3fj0Kzw2XSdoL15ExLASt2WPqD7FbLeaqwT70+XjKyTshBnUlQA5nNREO1C2P8Uen0CDjsBLMsCQ+zd0lw== dependencies: handlebars "^4.7.7" typedoc-plugin-rename-defaults@^0.7.0: version "0.7.0" - resolved "https://registry.yarnpkg.com/typedoc-plugin-rename-defaults/-/typedoc-plugin-rename-defaults-0.7.0.tgz#8cd477b4e914c6021a1a0e1badaa869159bb6945" + resolved "https://registry.npmjs.org/typedoc-plugin-rename-defaults/-/typedoc-plugin-rename-defaults-0.7.0.tgz" integrity sha512-NudSQ1o/XLHNF9c4y7LzIZxfE9ltz09yCDklBPJpP5VMRvuBpYGIbQ0ZgmPz+EIV8vPx9Z/OyKwzp4HT2vDtfg== dependencies: camelcase "^8.0.0" typedoc@^0.25.12: version "0.25.12" - resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.25.12.tgz#f73f0a8d3731d418cc604d4230f95a857799e27a" + resolved "https://registry.npmjs.org/typedoc/-/typedoc-0.25.12.tgz" integrity sha512-F+qhkK2VoTweDXd1c42GS/By2DvI2uDF4/EpG424dTexSHdtCH52C6IcAvMA6jR3DzAWZjHpUOW+E02kyPNUNw== dependencies: lunr "^2.3.9" @@ -3873,12 +4051,12 @@ typescript@^5.2.2: uglify-js@^3.1.4: version "3.17.4" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.4.tgz#61678cf5fa3f5b7eb789bb345df29afb8257c22c" + resolved "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz" integrity sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g== unbox-primitive@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" + resolved "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz" integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== dependencies: call-bind "^1.0.2" @@ -3901,7 +4079,7 @@ update-browserslist-db@^1.0.11: uri-js@^4.2.2: version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz" integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== dependencies: punycode "^2.1.0" @@ -3925,12 +4103,12 @@ v8-to-istanbul@^9.0.1: vscode-oniguruma@^1.7.0: version "1.7.0" - resolved "https://registry.yarnpkg.com/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz#439bfad8fe71abd7798338d1cd3dc53a8beea94b" + resolved "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz" integrity sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA== vscode-textmate@^8.0.0: version "8.0.0" - resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-8.0.0.tgz#2c7a3b1163ef0441097e0b5d6389cd5504b59e5d" + resolved "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-8.0.0.tgz" integrity sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg== w3c-xmlserializer@^4.0.0: @@ -3974,7 +4152,7 @@ whatwg-url@^11.0.0: which-boxed-primitive@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" + resolved "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz" integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== dependencies: is-bigint "^1.0.1" @@ -3985,7 +4163,7 @@ which-boxed-primitive@^1.0.2: which-typed-array@^1.1.14, which-typed-array@^1.1.15: version "1.1.15" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.15.tgz#264859e9b11a649b388bfaaf4f767df1f779b38d" + resolved "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz" integrity sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA== dependencies: available-typed-arrays "^1.0.7" @@ -4003,7 +4181,7 @@ which@^2.0.1: wordwrap@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + resolved "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz" integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== wrap-ansi@^7.0.0: @@ -4030,7 +4208,7 @@ write-file-atomic@^4.0.2: ws@^8.11.0: version "8.17.1" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.17.1.tgz#9293da530bb548febc95371d90f9c878727d919b" + resolved "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz" integrity sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ== xml-name-validator@^4.0.0: From 8decac5b84150236b0ed9688e8c4f8519b3fc825 Mon Sep 17 00:00:00 2001 From: mattcce Date: Tue, 17 Jun 2025 00:52:33 +0800 Subject: [PATCH 02/14] display native function descriptor when unimplemented --- src/ec-evaluator/interpreter.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ec-evaluator/interpreter.ts b/src/ec-evaluator/interpreter.ts index 27e6173..f8cf11d 100644 --- a/src/ec-evaluator/interpreter.ts +++ b/src/ec-evaluator/interpreter.ts @@ -506,10 +506,11 @@ export const cmdEvaluators: { [type: string]: CmdEvaluator } = { // Native function escape hatch if (closure.mtdOrCon.kind === 'MethodDeclaration' && isNative(closure.mtdOrCon)) { - const nativeFn = natives[getFullyQualifiedDescriptor(closure.mtdOrCon)] + const nativeFnDescriptor = getFullyQualifiedDescriptor(closure.mtdOrCon) + const nativeFn = natives[nativeFnDescriptor] if (!nativeFn) { - throw new errors.UndefinedNativeMethod(nativeFn) + throw new errors.UndefinedNativeMethod(nativeFnDescriptor) } // call foreign fn From db6c94b8f9be8e2436a399e2d40308adde10ac56 Mon Sep 17 00:00:00 2001 From: mattcce Date: Tue, 17 Jun 2025 13:15:37 +0800 Subject: [PATCH 03/14] native method handling for type-checker --- src/types/ast/extractor.ts | 8 +++++++- src/types/ast/specificationTypes.ts | 2 +- src/types/checker/index.ts | 14 ++++++++++++++ src/types/errors.ts | 6 ++++++ 4 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/types/ast/extractor.ts b/src/types/ast/extractor.ts index ff7a043..b081dc2 100644 --- a/src/types/ast/extractor.ts +++ b/src/types/ast/extractor.ts @@ -1294,8 +1294,14 @@ class AstExtractor extends BaseJavaCstVisitor { return getIdentifier(ctx.Identifier![0]) } - methodBody(ctx: JavaParser.MethodBodyCtx): AST.MethodBody { + methodBody(ctx: JavaParser.MethodBodyCtx): AST.MethodBody | undefined { if (ctx.block) return this.visit(ctx.block) + + // handle only semicolon i.e. empty block + if (ctx.Semicolon) { + return undefined + } + throw new Error('Not implemented') } diff --git a/src/types/ast/specificationTypes.ts b/src/types/ast/specificationTypes.ts index 70bd060..f3d1f3a 100644 --- a/src/types/ast/specificationTypes.ts +++ b/src/types/ast/specificationTypes.ts @@ -742,7 +742,7 @@ export type MethodDeclaration = { kind: 'MethodDeclaration' methodModifiers: MethodModifier[] methodHeader: MethodHeader - methodBody: MethodBody + methodBody: MethodBody | undefined location: Location } diff --git a/src/types/checker/index.ts b/src/types/checker/index.ts index 005286e..851ab03 100644 --- a/src/types/checker/index.ts +++ b/src/types/checker/index.ts @@ -7,6 +7,7 @@ import { BadOperandTypesError, CannotFindSymbolError, IncompatibleTypesError, + MissingMethodBodyError, NotApplicableToExpressionTypeError, TypeCheckerError, TypeCheckerInternalError, @@ -518,6 +519,19 @@ export const typeCheckBody = (node: Node, frame: Frame = Frame.globalFrame()): R errors.push(...methodErrors) break } + + // skip type checking for bodies of native methods (admit empty body) + if (bodyDeclaration.methodModifiers.map(i => i.identifier).includes('native')) { + console.log(bodyDeclaration) + break + } + + // empty body is error + if (bodyDeclaration.methodBody === undefined) { + errors.push(new MissingMethodBodyError(bodyDeclaration.location)) + break + } + const { errors: checkErrors } = typeCheckBody(bodyDeclaration.methodBody, methodFrame) if (checkErrors.length > 0) errors.push(...checkErrors) break diff --git a/src/types/errors.ts b/src/types/errors.ts index 6428e4c..1e15e6e 100644 --- a/src/types/errors.ts +++ b/src/types/errors.ts @@ -118,6 +118,12 @@ export class MethodCannotBeAppliedError extends TypeCheckerError { } } +export class MissingMethodBodyError extends TypeCheckerError { + constructor(location?: Location) { + super('missing method body', location) + } +} + export class ModifierNotAllowedHereError extends TypeCheckerError { constructor(location?: Location) { super('modifier not allowed here', location) From 0103daf717d8df82f8b02242a5a2aee4ba49d713 Mon Sep 17 00:00:00 2001 From: mattcce Date: Tue, 17 Jun 2025 13:22:32 +0800 Subject: [PATCH 04/14] revert Object class declaration --- src/ec-evaluator/nodeCreator.ts | 38 +-------------------------------- 1 file changed, 1 insertion(+), 37 deletions(-) diff --git a/src/ec-evaluator/nodeCreator.ts b/src/ec-evaluator/nodeCreator.ts index 6c62247..05d9c3c 100644 --- a/src/ec-evaluator/nodeCreator.ts +++ b/src/ec-evaluator/nodeCreator.ts @@ -138,41 +138,5 @@ export const objClassDeclNode = (): ClassDeclaration => ({ kind: 'NormalClassDeclaration', classModifier: [], typeIdentifier: OBJECT_CLASS, - classBody: [ - { - kind: 'FieldDeclaration', - fieldModifier: ['private'], - fieldType: 'int', - variableDeclaratorList: [ - { - kind: 'VariableDeclarator', - variableDeclaratorId: 'hash', - variableInitializer: { - kind: 'Literal', - literalType: { - kind: 'DecimalIntegerLiteral', - value: String(Math.floor(Math.random() * Math.pow(2, 32))) - } - } - } - ] - }, - { - kind: 'MethodDeclaration', - methodModifier: ['public'], - methodHeader: { result: 'int', identifier: 'hashCode', formalParameterList: [] }, - methodBody: { - kind: 'Block', - blockStatements: [ - { - kind: 'ReturnStatement', - exp: { - kind: 'ExpressionName', - name: 'this.hash' - } - } - ] - } - } - ] + classBody: [] }) From 8d126f07f418a54c4e8ceb1bfdbff6d7f9e0f8d6 Mon Sep 17 00:00:00 2001 From: mattcce Date: Tue, 17 Jun 2025 15:09:23 +0800 Subject: [PATCH 05/14] disallow native methods with body --- src/types/checker/index.ts | 7 +++++-- src/types/errors.ts | 6 ++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/types/checker/index.ts b/src/types/checker/index.ts index 851ab03..24bd266 100644 --- a/src/types/checker/index.ts +++ b/src/types/checker/index.ts @@ -8,6 +8,7 @@ import { CannotFindSymbolError, IncompatibleTypesError, MissingMethodBodyError, + NativeMethodHasBodyError, NotApplicableToExpressionTypeError, TypeCheckerError, TypeCheckerInternalError, @@ -520,9 +521,11 @@ export const typeCheckBody = (node: Node, frame: Frame = Frame.globalFrame()): R break } - // skip type checking for bodies of native methods (admit empty body) + // native methods (admit empty body) if (bodyDeclaration.methodModifiers.map(i => i.identifier).includes('native')) { - console.log(bodyDeclaration) + if (bodyDeclaration.methodBody !== undefined) { + errors.push(new NativeMethodHasBodyError(bodyDeclaration.location)) + } break } diff --git a/src/types/errors.ts b/src/types/errors.ts index 1e15e6e..469151c 100644 --- a/src/types/errors.ts +++ b/src/types/errors.ts @@ -130,6 +130,12 @@ export class ModifierNotAllowedHereError extends TypeCheckerError { } } +export class NativeMethodHasBodyError extends TypeCheckerError { + constructor(location?: Location) { + super('native methods cannot have a body', location) + } +} + export class NotApplicableToExpressionTypeError extends TypeCheckerError { constructor(location?: Location) { super('not applicable to expression type', location) From fcfb36e1072c55f54c62ecc5983c28ad34366146 Mon Sep 17 00:00:00 2001 From: mattcce Date: Sat, 21 Jun 2025 11:27:02 +0800 Subject: [PATCH 06/14] method declaration and invoke handling --- src/ec-evaluator/__tests__/__utils__/utils.ts | 62 +++++++-------- src/ec-evaluator/__tests__/natives.test.ts | 36 ++++++++- src/ec-evaluator/interpreter.ts | 75 +++++++++++-------- src/ec-evaluator/natives.ts | 28 ++++++- src/ec-evaluator/structCreator.ts | 17 ++++- src/ec-evaluator/types.ts | 14 +++- src/ec-evaluator/utils.ts | 48 +++++++----- 7 files changed, 188 insertions(+), 92 deletions(-) diff --git a/src/ec-evaluator/__tests__/__utils__/utils.ts b/src/ec-evaluator/__tests__/__utils__/utils.ts index cb6ce5c..27732b3 100644 --- a/src/ec-evaluator/__tests__/__utils__/utils.ts +++ b/src/ec-evaluator/__tests__/__utils__/utils.ts @@ -1,51 +1,51 @@ -import { Environment } from "../../components"; -import { STEP_LIMIT } from "../../constants"; -import { ControlItem, Context, StashItem, StructType } from "../../types"; -import { Stack, isNode } from "../../utils"; +import { Environment } from '../../components' +import { STEP_LIMIT } from '../../constants' +import { ControlItem, Context, StashItem, StructType } from '../../types' +import { Stack, isNode } from '../../utils' export class StackStub extends Stack { - private trace: T[] = []; + private trace: T[] = [] public push(...items: T[]): void { for (const item of items) { - super.push(item); - this.trace.push(item); + super.push(item) + this.trace.push(item) } - }; + } public getTrace(): T[] { - return this.trace; - }; -}; -export class ControlStub extends StackStub {}; -export class StashStub extends StackStub {}; + return this.trace + } +} +export class ControlStub extends StackStub {} +export class StashStub extends StackStub {} // TODO make env traceable -export class EnvironmentStub extends Environment {}; +export class EnvironmentStub extends Environment {} export const createContextStub = (): Context => ({ errors: [], control: new ControlStub(), stash: new StashStub(), environment: new EnvironmentStub(), - totalSteps: STEP_LIMIT, -}); + totalSteps: STEP_LIMIT +}) export const getControlItemStr = (i: ControlItem): string => { - return isNode(i) ? i.kind : i.instrType; -}; + return isNode(i) ? i.kind : i.instrType +} export const getStashItemStr = (i: StashItem): string => { - return i.kind === "Literal" - ? i.literalType.value + return i.kind === 'Literal' + ? i.literalType.value : i.kind === StructType.CLOSURE - ? i.mtdOrCon.kind === "MethodDeclaration" - ? i.mtdOrCon.methodHeader.identifier - : i.mtdOrCon.constructorDeclarator.identifier - : i.kind === StructType.VARIABLE - ? i.name - : i.kind === StructType.CLASS - ? i.frame.name - : i.kind === StructType.TYPE - ? i.type - : i.kind; -}; + ? i.decl.kind === 'MethodDeclaration' || i.decl.kind === 'NativeDeclaration' + ? i.decl.methodHeader.identifier + : i.decl.constructorDeclarator.identifier + : i.kind === StructType.VARIABLE + ? i.name + : i.kind === StructType.CLASS + ? i.frame.name + : i.kind === StructType.TYPE + ? i.type + : i.kind +} diff --git a/src/ec-evaluator/__tests__/natives.test.ts b/src/ec-evaluator/__tests__/natives.test.ts index f8979c1..9ee7d0e 100644 --- a/src/ec-evaluator/__tests__/natives.test.ts +++ b/src/ec-evaluator/__tests__/natives.test.ts @@ -1,4 +1,4 @@ -import { natives } from '../natives' +import { foreigns } from '../natives' import { // ControlStub, // StashStub, @@ -10,10 +10,38 @@ import { parse } from '../../ast/parser' import { evaluate } from '../interpreter' describe('native functions', () => { - it('should invoke external native function', () => { + it('method declaration should dynamically link foreign function', () => { const mockForeignFn = jest.fn() - natives['testNative(): void'] = mockForeignFn + foreigns['C::testNative(): void'] = mockForeignFn + + const programStr = ` + class C { + public native void testNative(); + + public static void main(String[] args) { + C c = new C(); + c.testNative(); + } + } + ` + + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() + + const context = createContextStub() + context.control.push(compilationUnit!) + + evaluate(context) + + const c = context.environment.getClass('C') + c.instanceMethods.find(md => md) + }) + + it('invoke instruction should invoke external native function', () => { + const mockForeignFn = jest.fn() + + foreigns['C::testNative(): void'] = mockForeignFn const programStr = ` class C { @@ -42,7 +70,7 @@ describe('native functions', () => { expect(s).toBe('"Test"') }) - natives['testNative(String s): void'] = foreignFn + foreigns['C::testNative(String s): void'] = foreignFn const programStr = ` class C { diff --git a/src/ec-evaluator/interpreter.ts b/src/ec-evaluator/interpreter.ts index f8cf11d..ceac086 100644 --- a/src/ec-evaluator/interpreter.ts +++ b/src/ec-evaluator/interpreter.ts @@ -65,7 +65,8 @@ import { ResConOverloadInstr, ResOverrideInstr, ResTypeContInstr, - StructType + StructType, + NativeDeclaration } from './types' import { defaultValues, @@ -87,7 +88,7 @@ import { searchMainMtdClass, prependExpConInvIfNeeded, isStatic, - isNative, + isNativeMethodDeclaration, resOverload, resOverride, resConOverload, @@ -95,7 +96,7 @@ import { makeNonLocalVarNonParamSimpleNameQualified, getFullyQualifiedDescriptor } from './utils' -import { natives } from './natives' +import { foreigns } from './natives' type CmdEvaluator = ( command: ControlItem, @@ -253,9 +254,31 @@ export const cmdEvaluators: { [type: string]: CmdEvaluator } = { _control: Control, _stash: Stash ) => { + let mtdClosure + // Native method handling + if (isNativeMethodDeclaration(command)) { + const FQMtdDesc = getFullyQualifiedDescriptor(environment.current.name, command) + const fn = foreigns[FQMtdDesc] + + if (fn === undefined) { + throw new errors.UndefinedNativeMethod(FQMtdDesc) + } + + // bind foreign function + const natDecl: NativeDeclaration = { + kind: 'NativeDeclaration', + methodModifier: command.methodModifier, + methodHeader: command.methodHeader, + foreignFunction: fn + } + + mtdClosure = struct.closureStruct(natDecl, environment.current) + } else { + mtdClosure = struct.closureStruct(command, environment.current) + } + // Use method descriptor as key. const mtdDescriptor: string = getDescriptor(command) - const mtdClosure = struct.closureStruct(command, environment.current) environment.defineMtdOrCon(mtdDescriptor, mtdClosure) }, @@ -471,13 +494,13 @@ export const cmdEvaluators: { [type: string]: CmdEvaluator } = { const closure: Closure = stash.pop()! as Closure const params: FormalParameter[] = - closure.mtdOrCon.kind === 'MethodDeclaration' - ? cloneDeep(closure.mtdOrCon.methodHeader.formalParameterList) - : cloneDeep(closure.mtdOrCon.constructorDeclarator.formalParameterList) + closure.decl.kind === 'MethodDeclaration' || closure.decl.kind === 'NativeDeclaration' + ? cloneDeep(closure.decl.methodHeader.formalParameterList) + : cloneDeep(closure.decl.constructorDeclarator.formalParameterList) // Extend env from global frame. - const mtdOrConDescriptor = getDescriptor(closure.mtdOrCon) - environment.extendEnv(environment.global, mtdOrConDescriptor) + const methodDescriptor = getDescriptor(closure.decl) + environment.extendEnv(environment.global, methodDescriptor) const isInstanceMtdOrCon = args.length == params.length + 1 if (isInstanceMtdOrCon) { @@ -504,17 +527,10 @@ export const cmdEvaluators: { [type: string]: CmdEvaluator } = { environment.defineVariable(params[i].identifier, params[i].unannType, args[i]) } - // Native function escape hatch - if (closure.mtdOrCon.kind === 'MethodDeclaration' && isNative(closure.mtdOrCon)) { - const nativeFnDescriptor = getFullyQualifiedDescriptor(closure.mtdOrCon) - const nativeFn = natives[nativeFnDescriptor] - - if (!nativeFn) { - throw new errors.UndefinedNativeMethod(nativeFnDescriptor) - } - - // call foreign fn - nativeFn({ control, stash, environment }) + // Native functions + if (closure.decl.kind === 'NativeDeclaration') { + // call foreign fn with CSE machine state + closure.decl.foreignFunction({ control, stash, environment }) // only because resetInstr demands one, never actually used const superfluousReturnStatement: ReturnStatement = { @@ -524,15 +540,14 @@ export const cmdEvaluators: { [type: string]: CmdEvaluator } = { // handle return from native fn control.push(instr.resetInstr(superfluousReturnStatement)) - return + } else { + // Push method/constructor body. + const body = + closure.decl.kind === 'MethodDeclaration' + ? closure.decl.methodBody + : closure.decl.constructorBody + control.push(body) } - - // Push method/constructor body. - const body = - closure.mtdOrCon.kind === 'MethodDeclaration' - ? closure.mtdOrCon.methodBody - : closure.mtdOrCon.constructorBody - control.push(body) }, [InstrType.ENV]: ( @@ -811,7 +826,7 @@ export const cmdEvaluators: { [type: string]: CmdEvaluator } = { stash.push(closure) // Post-processing required if overload resolved method is instance method. - if (isInstance(closure.mtdOrCon as MethodDeclaration)) { + if (isInstance(closure.decl as MethodDeclaration)) { // Increment arity of InvInstr on control. let n = 1 while ( @@ -834,7 +849,7 @@ export const cmdEvaluators: { [type: string]: CmdEvaluator } = { const target = stash.pop()! const overloadResolvedClosure = stash.pop()! as Closure - if (isStatic(overloadResolvedClosure.mtdOrCon as MethodDeclaration)) { + if (isStatic(overloadResolvedClosure.decl as MethodDeclaration)) { // No method overriding resolution is required if resolved method is a static method. stash.push(overloadResolvedClosure) return diff --git a/src/ec-evaluator/natives.ts b/src/ec-evaluator/natives.ts index 9a188de..6c9e64f 100644 --- a/src/ec-evaluator/natives.ts +++ b/src/ec-evaluator/natives.ts @@ -1,4 +1,5 @@ import { Control, Environment, Stash } from './components' +import { StashItem } from './types' /* Native function escape hatch. @@ -14,7 +15,7 @@ import { Control, Environment, Stash } from './components' The current implementation automatically injects a return instruction after the external handler function call ends. */ -export type NativeFunction = ({ +export type ForeignFunction = ({ control, stash, environment @@ -24,6 +25,25 @@ export type NativeFunction = ({ environment: Environment }) => void -export const natives: { - [descriptor: string]: NativeFunction -} = {} +export const foreigns: { + [descriptor: string]: ForeignFunction +} = { + 'Object::hashCode(): int': ({ stash }) => { + const hashCode = Math.floor(Math.random() * Math.pow(2, 32)) + const stashItem: StashItem = { + kind: 'Literal', + literalType: { kind: 'DecimalIntegerLiteral', value: String(hashCode) } + } + + console.log(stashItem) + stash.push(stashItem) + }, + + 'Object::display(String s): void': ({ environment }) => { + // @ts-expect-error ts(2339): guaranteed valid by type checker + const s = environment.getVariable('s').value.literalType.value + + // TODO: hook up to frontend + console.log(s) + } +} diff --git a/src/ec-evaluator/structCreator.ts b/src/ec-evaluator/structCreator.ts index 1943ea4..46cbdf9 100644 --- a/src/ec-evaluator/structCreator.ts +++ b/src/ec-evaluator/structCreator.ts @@ -6,7 +6,18 @@ import { UnannType } from '../ast/types/classes' import { EnvNode } from './components' -import { Name, StructType, Type, VarValue, Variable, Symbol, Object, Class, Closure } from './types' +import { + Name, + StructType, + Type, + VarValue, + Variable, + Symbol, + Object, + Class, + Closure, + NativeDeclaration +} from './types' export const varStruct = (type: UnannType, name: Name, value: VarValue): Variable => ({ kind: StructType.VARIABLE, @@ -27,11 +38,11 @@ export const objStruct = (frame: EnvNode, c: Class): Object => ({ }) export const closureStruct = ( - mtdOrCon: MethodDeclaration | ConstructorDeclaration, + decl: MethodDeclaration | ConstructorDeclaration | NativeDeclaration, env: EnvNode ): Closure => ({ kind: StructType.CLOSURE, - mtdOrCon, + decl, env }) diff --git a/src/ec-evaluator/types.ts b/src/ec-evaluator/types.ts index 9ce1b6d..054ee46 100644 --- a/src/ec-evaluator/types.ts +++ b/src/ec-evaluator/types.ts @@ -4,11 +4,14 @@ import { ConstructorDeclaration, FieldDeclaration, MethodDeclaration, + MethodHeader, + MethodModifier, NormalClassDeclaration, UnannType } from '../ast/types/classes' import { Control, EnvNode, Environment, Stash } from './components' import { SourceError } from './errors' +import { ForeignFunction } from './natives' export interface Context { errors: SourceError[] @@ -161,9 +164,16 @@ export interface Object { class: Class } +export interface NativeDeclaration { + kind: 'NativeDeclaration' + methodModifier: Array + methodHeader: MethodHeader + foreignFunction: ForeignFunction +} + export interface Closure { kind: StructType.CLOSURE - mtdOrCon: MethodDeclaration | ConstructorDeclaration + decl: MethodDeclaration | ConstructorDeclaration | NativeDeclaration env: EnvNode } @@ -173,7 +183,7 @@ export interface Class { classDecl: NormalClassDeclaration constructors: ConstructorDeclaration[] instanceFields: FieldDeclaration[] - instanceMethods: MethodDeclaration[] + instanceMethods: (MethodDeclaration | NativeDeclaration)[] staticFields: FieldDeclaration[] staticMethods: MethodDeclaration[] superclass?: Class diff --git a/src/ec-evaluator/utils.ts b/src/ec-evaluator/utils.ts index 4aaa0ad..cc59204 100644 --- a/src/ec-evaluator/utils.ts +++ b/src/ec-evaluator/utils.ts @@ -26,7 +26,16 @@ import { nullLitNode, returnThisStmtNode } from './nodeCreator' -import { ControlItem, Context, Instr, Class, Type, Closure, StashItem } from './types' +import { + ControlItem, + Context, + Instr, + Class, + Type, + Closure, + StashItem, + NativeDeclaration +} from './types' /** * Components. @@ -177,17 +186,14 @@ export const defaultValues = new Map([ /** * Name */ -export const getDescriptor = (mtdOrCon: MethodDeclaration | ConstructorDeclaration): string => { - return mtdOrCon.kind === 'MethodDeclaration' - ? `${mtdOrCon.methodHeader.identifier}(${mtdOrCon.methodHeader.formalParameterList.map(p => p.unannType).join(',')})${mtdOrCon.methodHeader.result}` - : `${mtdOrCon.constructorDeclarator.identifier}(${mtdOrCon.constructorDeclarator.formalParameterList.map(p => p.unannType).join(',')})` +export const getDescriptor = ( + decl: MethodDeclaration | ConstructorDeclaration | NativeDeclaration +): string => { + return decl.kind === 'MethodDeclaration' || decl.kind === 'NativeDeclaration' + ? `${decl.methodHeader.identifier}(${decl.methodHeader.formalParameterList.map(p => p.unannType).join(',')}): ${decl.methodHeader.result}` + : `${decl.constructorDeclarator.identifier}(${decl.constructorDeclarator.formalParameterList.map(p => p.unannType).join(',')})` } -// for native methods (uses new proposed format) with parameter names -// because native functions must retrieve variables from the environment by identifier, this descriptor type also includes parameter names for convenience -export const getFullyQualifiedDescriptor = (mtd: MethodDeclaration): string => - `${mtd.methodHeader.identifier}(${mtd.methodHeader.formalParameterList.map(p => `${p.unannType} ${p.identifier}`).join(',')}): ${mtd.methodHeader.result}` - export const isQualified = (name: string) => { return name.includes('.') } @@ -235,7 +241,7 @@ export const isInstance = (fieldOrMtd: FieldDeclaration | MethodDeclaration): bo return !isStatic(fieldOrMtd) } -export const isNative = (mtd: MethodDeclaration): boolean => { +export const isNativeMethodDeclaration = (mtd: MethodDeclaration): boolean => { return mtd.methodModifier.includes('native') } @@ -430,8 +436,8 @@ export const resOverload = ( for (const [closureName, closure] of c.frame.frame.entries()) { // Methods contains parantheses and must have return type. if (closureName.includes(mtdName + '(') && closureName[closureName.length - 1] !== ')') { - const params = ((closure as Closure).mtdOrCon as MethodDeclaration).methodHeader - .formalParameterList + const params = ((closure as Closure).decl as MethodDeclaration | NativeDeclaration) + .methodHeader.formalParameterList if (argTypes.length != params.length) continue @@ -466,9 +472,10 @@ export const resOverload = ( for (let i = 0; i < argTypes.length; i++) { let mostSpecClosureByParam = appClosures[0] for (const appClosure of appClosures) { - const mostSpecParams = (mostSpecClosureByParam.mtdOrCon as MethodDeclaration).methodHeader + const mostSpecParams = (mostSpecClosureByParam.decl as MethodDeclaration | NativeDeclaration) + .methodHeader.formalParameterList + const params = (appClosure.decl as MethodDeclaration | NativeDeclaration).methodHeader .formalParameterList - const params = (appClosure.mtdOrCon as MethodDeclaration).methodHeader.formalParameterList if (isSubtype(params[i].unannType, mostSpecParams[i].unannType, classStore)) { mostSpecClosureByParam = appClosure } @@ -484,7 +491,7 @@ export const resOverload = ( } export const resOverride = (classToSearchIn: Class, overloadResolvedClosure: Closure): Closure => { - const overloadResolvedMtd = overloadResolvedClosure.mtdOrCon as MethodDeclaration + const overloadResolvedMtd = overloadResolvedClosure.decl as MethodDeclaration | NativeDeclaration const name = overloadResolvedMtd.methodHeader.identifier const overloadResolvedClosureParams = overloadResolvedMtd.methodHeader.formalParameterList @@ -498,7 +505,8 @@ export const resOverride = (classToSearchIn: Class, overloadResolvedClosure: Clo let overrideResolvedClosure = overloadResolvedClosure for (const closure of closures) { - const params = (closure.mtdOrCon as MethodDeclaration).methodHeader.formalParameterList + const params = (closure.decl as MethodDeclaration | NativeDeclaration).methodHeader + .formalParameterList if (overloadResolvedClosureParams.length != params.length) continue @@ -532,7 +540,7 @@ export const resConOverload = ( let resolved: Closure | undefined for (const closure of closures) { - const params = (closure.mtdOrCon as ConstructorDeclaration).constructorDeclarator + const params = (closure.decl as ConstructorDeclaration).constructorDeclarator .formalParameterList if (argTypes.length != params.length) continue @@ -559,3 +567,7 @@ export const resConOverload = ( export const isNull = (stashItem: StashItem) => { return stashItem.kind === 'Literal' && stashItem.literalType.kind === 'NullLiteral' } + +// because native functions must retrieve variables from the environment by identifier, this descriptor type also includes parameter names for convenience +export const getFullyQualifiedDescriptor = (className: string, decl: MethodDeclaration) => + `${className}::${decl.methodHeader.identifier}(${decl.methodHeader.formalParameterList.map(p => `${p.unannType} ${p.identifier}`).join(',')}): ${decl.methodHeader.result}` From f6f4ea0ad1bf8207d9ff40ac3227d5b5de0c9d00 Mon Sep 17 00:00:00 2001 From: mattcce Date: Wed, 30 Jul 2025 20:05:31 +0800 Subject: [PATCH 07/14] accept multiple programs into typechecker --- src/types/checker/index.ts | 4 ++-- src/types/checker/prechecks.ts | 7 +++++++ src/types/index.ts | 33 +++++++++++++++++++++++---------- 3 files changed, 32 insertions(+), 12 deletions(-) diff --git a/src/types/checker/index.ts b/src/types/checker/index.ts index 24bd266..fc846f6 100644 --- a/src/types/checker/index.ts +++ b/src/types/checker/index.ts @@ -54,8 +54,8 @@ export const newResult = ( export const OK_RESULT: Result = newResult(null) -export const check = (node: Node, frame: Frame = Frame.globalFrame()): Result => { - const typeCheckingFrame = frame.newChildFrame() +export const check = (node: Node, frame: Frame = Frame.globalFrame().newChildFrame()): Result => { + const typeCheckingFrame = frame const addClassesResult = addClasses(node, typeCheckingFrame) if (addClassesResult.hasErrors) return addClassesResult const addClassParentsResult = addClassParents(node, typeCheckingFrame) diff --git a/src/types/checker/prechecks.ts b/src/types/checker/prechecks.ts index fe7df44..90544a2 100644 --- a/src/types/checker/prechecks.ts +++ b/src/types/checker/prechecks.ts @@ -91,6 +91,9 @@ export const addClassParents = (node: Node, frame: Frame): Result => { const classType = frame.getType(node.typeIdentifier.identifier, node.typeIdentifier.location) if (classType instanceof Error) return newResult(null, [classType]) if (!(classType instanceof ClassType)) throw new Error('class type should be a ClassImpl') + if (node.typeIdentifier.identifier === 'Object') { + return newResult(null) + } if (node.classExtends) { const extendsType = frame.getType( node.classExtends.classType.typeIdentifier.identifier, @@ -108,7 +111,11 @@ export const addClassParents = (node: Node, frame: Frame): Result => { type = type.getParentClass() } classType.setParentClass(extendsType) + } else { + const objectType = frame.getType('Object', { startOffset: -1, startLine: -1 }) + classType.setParentClass(objectType as ObjectClass) } + return newResult(classType) } default: diff --git a/src/types/index.ts b/src/types/index.ts index c99b146..420f438 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -1,6 +1,7 @@ import { check } from './checker' import { parse } from './ast' import { TypeCheckerError } from './errors' +import { Frame } from './checker/environment' type TypeCheckResult = { hasTypeErrors: boolean; errorMsgs: string[] } @@ -11,16 +12,28 @@ const convertErrorsToReadableMsgs = (program: string, errors: Error[]): string[] }) } -export const typeCheck = (program: string): TypeCheckResult => { - const ast = parse(program) - if (ast instanceof TypeCheckerError) - return { - hasTypeErrors: true, - errorMsgs: convertErrorsToReadableMsgs(program, [ast]) - } - const result = check(ast) +export const typeCheck = (...programs: string[]): TypeCheckResult => { + const frame: Frame = Frame.globalFrame().newChildFrame() + + // fail fast; returns early + for (const p of programs) { + const ast = parse(p) + if (ast instanceof TypeCheckerError) + return { + hasTypeErrors: true, + errorMsgs: convertErrorsToReadableMsgs(p, [ast]) + } + const result = check(ast, frame) + if (result.errors.length > 0) + return { + hasTypeErrors: true, + errorMsgs: convertErrorsToReadableMsgs(p, result.errors) + } + } + + // no errors return { - hasTypeErrors: result.errors.length > 0, - errorMsgs: convertErrorsToReadableMsgs(program, result.errors) + hasTypeErrors: false, + errorMsgs: [] } } From 933227e97d89c1039fcb1f7d4532a5753c8d7fc4 Mon Sep 17 00:00:00 2001 From: mattcce Date: Thu, 11 Sep 2025 17:25:25 +0800 Subject: [PATCH 08/14] precompile classes with type checking --- src/ec-evaluator/index.ts | 61 +++++++++++++++- src/ec-evaluator/interpreter.ts | 122 ++++++++++++++++++++++---------- src/ec-evaluator/lib.ts | 50 +++++++++++++ src/ec-evaluator/natives.ts | 11 +-- src/ec-evaluator/types.ts | 12 ++++ 5 files changed, 211 insertions(+), 45 deletions(-) create mode 100644 src/ec-evaluator/lib.ts diff --git a/src/ec-evaluator/index.ts b/src/ec-evaluator/index.ts index 9fbf01b..15ea118 100644 --- a/src/ec-evaluator/index.ts +++ b/src/ec-evaluator/index.ts @@ -1,15 +1,61 @@ import { parse } from '../ast/parser' +import { typeCheck } from '../types' import { Control, Environment, Stash } from './components' import { STEP_LIMIT } from './constants' import { RuntimeError } from './errors' import { evaluate } from './interpreter' -import { Context, Error, Finished, Result } from './types' +import { libraryClasses } from './lib' +import { Context, Error, Finished, IOCallbacks, Result } from './types' +import { handleSequence } from './utils' export * from './components' export * from './errors' export * from './types' export { isInstr, isNode } from './utils' +export const runECEvaluatorInjected = ( + code: string, + targetStep: number = STEP_LIMIT, + ioCallbacks: IOCallbacks +): Promise => { + const context = createContext(ioCallbacks) + + // type checking + const typeCheckResult = typeCheck(libraryClasses, code) + if (typeCheckResult.hasTypeErrors) { + const typeErrMsg = typeCheckResult.errorMsgs.join('\n') + context.interfaces.stderr('TypeCheck', typeErrMsg) + return Promise.resolve({ status: 'error' } as Error) + } + + // load library + const libraryCompilationUnit = parse(libraryClasses) + context.control.push( + ...handleSequence(libraryCompilationUnit.topLevelClassOrInterfaceDeclarations) + ) + evaluate(context, targetStep) + + try { + // parse() may throw SyntaxError. + const compilationUnit = parse(code) + + context.control.push(compilationUnit) + // evaluate() may throw RuntimeError + const value = evaluate(context, targetStep) + + return new Promise((resolve, _) => { + resolve({ status: 'finished', context, value } as Finished) + }) + } catch (e) { + // Possible interpreting language error thrown, so conversion to RuntimeError may be required. + const error = e.type ? e : new RuntimeError(e.message) + context.errors.push(error) + return new Promise((resolve, _) => { + resolve({ status: 'error', context } as Error) + }) + } +} + export const runECEvaluator = (code: string, targetStep: number = STEP_LIMIT): Promise => { const context = createContext() try { @@ -33,12 +79,21 @@ export const runECEvaluator = (code: string, targetStep: number = STEP_LIMIT): P } } -export const createContext = (): Context => ({ +export const createContext = (ioCallbacks?: IOCallbacks): Context => ({ errors: [], control: new Control(), stash: new Stash(), environment: new Environment(), - totalSteps: STEP_LIMIT + interfaces: initialiseInterfaces(ioCallbacks), + + totalSteps: 0 }) + +const initialiseInterfaces = (ioCallbacks?: IOCallbacks) => { + return { + stdout: ioCallbacks?.stdout ?? console.log, + stderr: ioCallbacks?.stderr ?? console.log + } +} diff --git a/src/ec-evaluator/interpreter.ts b/src/ec-evaluator/interpreter.ts index ceac086..b5531b5 100644 --- a/src/ec-evaluator/interpreter.ts +++ b/src/ec-evaluator/interpreter.ts @@ -66,7 +66,8 @@ import { ResOverrideInstr, ResTypeContInstr, StructType, - NativeDeclaration + NativeDeclaration, + Interfaces } from './types' import { defaultValues, @@ -102,7 +103,8 @@ type CmdEvaluator = ( command: ControlItem, environment: Environment, control: Control, - stash: Stash + stash: Stash, + interfaces: Interfaces ) => void /** @@ -116,6 +118,7 @@ export const evaluate = ( const environment = context.environment const control = context.control const stash = context.stash + const interfaces = context.interfaces context.totalSteps = 0 @@ -128,9 +131,9 @@ export const evaluate = ( control.pop() if (isNode(command)) { - cmdEvaluators[command.kind](command, environment, control, stash) + cmdEvaluators[command.kind](command, environment, control, stash, interfaces) } else { - cmdEvaluators[command.instrType](command, environment, control, stash) + cmdEvaluators[command.instrType](command, environment, control, stash, interfaces) } command = control.peek() @@ -145,7 +148,8 @@ export const cmdEvaluators: { [type: string]: CmdEvaluator } = { command: CompilationUnit, _environment: Environment, control: Control, - _stash: Stash + _stash: Stash, + _interfaces: Interfaces ) => { // Get first class that defines the main method according to program order. const className = searchMainMtdClass(command.topLevelClassOrInterfaceDeclarations) @@ -155,14 +159,14 @@ export const cmdEvaluators: { [type: string]: CmdEvaluator } = { control.push(node.mainMtdInvExpStmtNode(className)) control.push(...handleSequence(command.topLevelClassOrInterfaceDeclarations)) - control.push(node.objClassDeclNode()) }, NormalClassDeclaration: ( command: NormalClassDeclaration, environment: Environment, control: Control, - _stash: Stash + _stash: Stash, + _interfaces: Interfaces ) => { const className = command.typeIdentifier @@ -228,7 +232,13 @@ export const cmdEvaluators: { [type: string]: CmdEvaluator } = { control.push(...handleSequence(staticFields)) }, - Block: (command: Block, environment: Environment, control: Control, _stash: Stash) => { + Block: ( + command: Block, + environment: Environment, + control: Control, + _stash: Stash, + _interfaces: Interfaces + ) => { // Save current environment before extending. control.push(instr.envInstr(environment.current, command)) control.push(...handleSequence(command.blockStatements)) @@ -240,7 +250,8 @@ export const cmdEvaluators: { [type: string]: CmdEvaluator } = { command: ConstructorDeclaration, environment: Environment, _control: Control, - _stash: Stash + _stash: Stash, + _interfaces: Interfaces ) => { // Use constructor descriptor as key. const conDescriptor: string = getDescriptor(command) @@ -252,7 +263,8 @@ export const cmdEvaluators: { [type: string]: CmdEvaluator } = { command: MethodDeclaration, environment: Environment, _control: Control, - _stash: Stash + _stash: Stash, + _interfaces: Interfaces ) => { let mtdClosure // Native method handling @@ -286,7 +298,8 @@ export const cmdEvaluators: { [type: string]: CmdEvaluator } = { command: FieldDeclaration, environment: Environment, control: Control, - _stash: Stash + _stash: Stash, + _interfaces: Interfaces ) => { // FieldDeclaration to be evaluated are always static fields. // Instance fields are transformed into Assignment ExpressionStatement inserted into constructors. @@ -311,7 +324,8 @@ export const cmdEvaluators: { [type: string]: CmdEvaluator } = { command: LocalVariableDeclarationStatement, environment: Environment, control: Control, - _stash: Stash + _stash: Stash, + _interfaces: Interfaces ) => { const type: LocalVariableType = command.localVariableType const declaration: VariableDeclarator = command.variableDeclaratorList[0] @@ -334,7 +348,8 @@ export const cmdEvaluators: { [type: string]: CmdEvaluator } = { command: ExpressionStatement, _environment: Environment, control: Control, - _stash: Stash + _stash: Stash, + _interfaces: Interfaces ) => { control.push(instr.popInstr(command)) control.push(command.stmtExp) @@ -344,7 +359,8 @@ export const cmdEvaluators: { [type: string]: CmdEvaluator } = { command: ReturnStatement, _environment: Environment, control: Control, - _stash: Stash + _stash: Stash, + _interfaces: Interfaces ) => { control.push(instr.resetInstr(command)) control.push(command.exp) @@ -360,7 +376,8 @@ export const cmdEvaluators: { [type: string]: CmdEvaluator } = { command: MethodInvocation, _environment: Environment, control: Control, - _stash: Stash + _stash: Stash, + _interfaces: Interfaces ) => { const nameParts = command.identifier.split('.') const target = nameParts.splice(0, nameParts.length - 1).join('.') @@ -381,7 +398,8 @@ export const cmdEvaluators: { [type: string]: CmdEvaluator } = { command: ClassInstanceCreationExpression, environment: Environment, control: Control, - _stash: Stash + _stash: Stash, + _interfaces: Interfaces ) => { const c: Class = environment.getClass(command.identifier) @@ -397,7 +415,8 @@ export const cmdEvaluators: { [type: string]: CmdEvaluator } = { command: ExplicitConstructorInvocation, _environment: Environment, control: Control, - _stash: Stash + _stash: Stash, + _interfaces: Interfaces ) => { control.push(instr.popInstr(command)) control.push(instr.invInstr(command.argumentList.length + 1, command)) @@ -408,11 +427,23 @@ export const cmdEvaluators: { [type: string]: CmdEvaluator } = { control.push(instr.resTypeInstr(node.exprNameNode(command.thisOrSuper, command), command)) }, - Literal: (command: Literal, _environment: Environment, _control: Control, stash: Stash) => { + Literal: ( + command: Literal, + _environment: Environment, + _control: Control, + stash: Stash, + _interfaces: Interfaces + ) => { stash.push(command) }, - Void: (command: Void, _environment: Environment, _control: Control, stash: Stash) => { + Void: ( + command: Void, + _environment: Environment, + _control: Control, + stash: Stash, + _interfaces: Interfaces + ) => { stash.push(command) }, @@ -420,7 +451,8 @@ export const cmdEvaluators: { [type: string]: CmdEvaluator } = { command: ExpressionName, _environment: Environment, control: Control, - _stash: Stash + _stash: Stash, + _interfaces: Interfaces ) => { control.push(instr.derefInstr(command)) control.push(instr.evalVarInstr(command.name, command)) @@ -430,7 +462,8 @@ export const cmdEvaluators: { [type: string]: CmdEvaluator } = { command: BinaryExpression, _environment: Environment, control: Control, - _stash: Stash + _stash: Stash, + _interfaces: Interfaces ) => { control.push(instr.binOpInstr(command.operator, command)) control.push(command.right) @@ -441,7 +474,8 @@ export const cmdEvaluators: { [type: string]: CmdEvaluator } = { _command: Instr, _environment: Environment, _control: Control, - stash: Stash + stash: Stash, + _interfaces: Interfaces ) => { stash.pop() }, @@ -450,7 +484,8 @@ export const cmdEvaluators: { [type: string]: CmdEvaluator } = { _command: AssmtInstr, _environment: Environment, _control: Control, - stash: Stash + stash: Stash, + _interfaces: Interfaces ) => { // value is popped before variable becuase value is evaluated later than variable. const value = stash.pop()! as Literal | Object @@ -466,7 +501,8 @@ export const cmdEvaluators: { [type: string]: CmdEvaluator } = { command: BinOpInstr, _environment: Environment, _control: Control, - stash: Stash + stash: Stash, + _interfaces: Interfaces ) => { const right = stash.pop()! as Literal const left = stash.pop()! as Literal @@ -477,7 +513,8 @@ export const cmdEvaluators: { [type: string]: CmdEvaluator } = { command: InvInstr, environment: Environment, control: Control, - stash: Stash + stash: Stash, + interfaces: Interfaces ) => { // Save current environment to be restored after method returns. control.push(instr.envInstr(environment.current, command.srcNode)) @@ -530,7 +567,7 @@ export const cmdEvaluators: { [type: string]: CmdEvaluator } = { // Native functions if (closure.decl.kind === 'NativeDeclaration') { // call foreign fn with CSE machine state - closure.decl.foreignFunction({ control, stash, environment }) + closure.decl.foreignFunction({ control, stash, environment, interfaces }) // only because resetInstr demands one, never actually used const superfluousReturnStatement: ReturnStatement = { @@ -554,7 +591,8 @@ export const cmdEvaluators: { [type: string]: CmdEvaluator } = { command: EnvInstr, environment: Environment, _control: Control, - _stash: Stash + _stash: Stash, + _interfaces: Interfaces ) => { environment.restoreEnv(command.env) }, @@ -563,7 +601,8 @@ export const cmdEvaluators: { [type: string]: CmdEvaluator } = { command: ResetInstr, _environment: Environment, control: Control, - _stash: Stash + _stash: Stash, + _interfaces: Interfaces ) => { // Continue popping ControlItem until Marker is found. const next: ControlItem | undefined = control.pop() @@ -576,7 +615,8 @@ export const cmdEvaluators: { [type: string]: CmdEvaluator } = { command: EvalVarInstr, environment: Environment, control: Control, - stash: Stash + stash: Stash, + _interfaces: Interfaces ) => { if (isQualified(command.symbol)) { const nameParts = command.symbol.split('.') @@ -593,7 +633,8 @@ export const cmdEvaluators: { [type: string]: CmdEvaluator } = { command: ResInstr, environment: Environment, _control: Control, - stash: Stash + stash: Stash, + _interfaces: Interfaces ) => { const varOrClass = stash.pop()! as Variable | Class @@ -662,7 +703,8 @@ export const cmdEvaluators: { [type: string]: CmdEvaluator } = { _command: DerefInstr, _environment: Environment, _control: Control, - stash: Stash + stash: Stash, + _interfaces: Interfaces ) => { const varOrClass = stash.pop()! as Variable | Class const value = @@ -679,7 +721,8 @@ export const cmdEvaluators: { [type: string]: CmdEvaluator } = { command: NewInstr, environment: Environment, _control: Control, - stash: Stash + stash: Stash, + _interfaces: Interfaces ) => { // To be restore after extending curr env to declare instance fields in obj frame. const currEnv = environment.current @@ -729,7 +772,8 @@ export const cmdEvaluators: { [type: string]: CmdEvaluator } = { command: ResTypeInstr, environment: Environment, control: Control, - stash: Stash + stash: Stash, + _interfaces: Interfaces ) => { // TODO need to handle all type of arg expressions const value: Expression | Class = command.value @@ -767,7 +811,8 @@ export const cmdEvaluators: { [type: string]: CmdEvaluator } = { command: ResTypeContInstr, environment: Environment, _control: Control, - stash: Stash + stash: Stash, + _interfaces: Interfaces ) => { const typeToSearchIn = stash.pop()! as Type @@ -807,7 +852,8 @@ export const cmdEvaluators: { [type: string]: CmdEvaluator } = { command: ResOverloadInstr, environment: Environment, control: Control, - stash: Stash + stash: Stash, + _interfaces: Interfaces ) => { // Retrieve arg types in reversed order for method overloading resolution. const argTypes: Type[] = [] @@ -844,7 +890,8 @@ export const cmdEvaluators: { [type: string]: CmdEvaluator } = { _command: ResOverrideInstr, environment: Environment, _control: Control, - stash: Stash + stash: Stash, + _interfaces: Interfaces ) => { const target = stash.pop()! const overloadResolvedClosure = stash.pop()! as Closure @@ -876,7 +923,8 @@ export const cmdEvaluators: { [type: string]: CmdEvaluator } = { command: ResConOverloadInstr, environment: Environment, _control: Control, - stash: Stash + stash: Stash, + _interfaces: Interfaces ) => { // Retrieve arg types in reversed order for constructor resolution. const argTypes: Type[] = [] diff --git a/src/ec-evaluator/lib.ts b/src/ec-evaluator/lib.ts new file mode 100644 index 0000000..d9bf939 --- /dev/null +++ b/src/ec-evaluator/lib.ts @@ -0,0 +1,50 @@ +/* + Java library classes + + Injects library classes for use by programs run in the CSEC machine. +*/ + +// function fnv1a(s: string) { +// const FNV_OFFSET_BASIS = 2166136261 +// const FNV_PRIME = 16777619 + +// let hash = FNV_OFFSET_BASIS + +// for (let i = 0; i < s.length; i++) { +// hash ^= s.charCodeAt(i) +// hash *= FNV_PRIME +// } + +// return hash +// } + +// class LFSR { +// #state: number + +// constructor(init: string) { +// this.#state = fnv1a(init) | 0 // convert to 32-bit integer +// } + +// next() { +// const state = this.#state +// const bit = (state ^ (state >> 1) ^ (state >> 2) ^ (state >> 3)) & 1 +// this.#state = (state >> 1) | (bit << 30) +// return this.#state +// } +// } + +export const libraryClasses = ` +class Object { + public native int hashCode(); + + public static native void display(int s); +}` + +// const disabled = `class PrintStream extends Object { +// public native void println(String s); +// } + +// class System extends Object { +// public static PrintStream out = new PrintStream(); +// } +// ` diff --git a/src/ec-evaluator/natives.ts b/src/ec-evaluator/natives.ts index 6c9e64f..6c08493 100644 --- a/src/ec-evaluator/natives.ts +++ b/src/ec-evaluator/natives.ts @@ -1,5 +1,5 @@ import { Control, Environment, Stash } from './components' -import { StashItem } from './types' +import { Interfaces, StashItem } from './types' /* Native function escape hatch. @@ -18,11 +18,13 @@ import { StashItem } from './types' export type ForeignFunction = ({ control, stash, - environment + environment, + interfaces }: { control: Control stash: Stash environment: Environment + interfaces: Interfaces }) => void export const foreigns: { @@ -39,11 +41,10 @@ export const foreigns: { stash.push(stashItem) }, - 'Object::display(String s): void': ({ environment }) => { + 'Object::display(int s): void': ({ environment, interfaces }) => { // @ts-expect-error ts(2339): guaranteed valid by type checker const s = environment.getVariable('s').value.literalType.value - // TODO: hook up to frontend - console.log(s) + interfaces.stdout(s) } } diff --git a/src/ec-evaluator/types.ts b/src/ec-evaluator/types.ts index 054ee46..5523a2d 100644 --- a/src/ec-evaluator/types.ts +++ b/src/ec-evaluator/types.ts @@ -20,9 +20,21 @@ export interface Context { stash: Stash environment: Environment + interfaces: Interfaces + totalSteps: number } +export interface Interfaces { + stdout: (displayString: string) => void + stderr: (errType: 'TypeCheck' | 'Compile' | 'Runtime', errMsg: string) => void +} + +export interface IOCallbacks { + stdout?: (displayString: string) => void + stderr?: (errType: 'TypeCheck' | 'Compile' | 'Runtime', errMsg: string) => void +} + /** * Instructions */ From 5c38b8690bc86854232874bf89d37e035c5bf550 Mon Sep 17 00:00:00 2001 From: mattcce Date: Fri, 12 Sep 2025 18:54:39 +0800 Subject: [PATCH 09/14] add hashCode native function for CSEC machine --- src/ec-evaluator/index.ts | 19 +++++++----- src/ec-evaluator/lib.ts | 56 +++++++++++++++++----------------- src/ec-evaluator/natives.ts | 8 +++-- src/ec-evaluator/types.ts | 4 +++ src/types/checker/prechecks.ts | 5 ++- 5 files changed, 52 insertions(+), 40 deletions(-) diff --git a/src/ec-evaluator/index.ts b/src/ec-evaluator/index.ts index 15ea118..7abaf4e 100644 --- a/src/ec-evaluator/index.ts +++ b/src/ec-evaluator/index.ts @@ -4,8 +4,8 @@ import { Control, Environment, Stash } from './components' import { STEP_LIMIT } from './constants' import { RuntimeError } from './errors' import { evaluate } from './interpreter' -import { libraryClasses } from './lib' -import { Context, Error, Finished, IOCallbacks, Result } from './types' +import { LFSR, libraryClasses } from './lib' +import { Context, Error, Finished, Interfaces, IOCallbacks, Result } from './types' import { handleSequence } from './utils' export * from './components' @@ -18,7 +18,7 @@ export const runECEvaluatorInjected = ( targetStep: number = STEP_LIMIT, ioCallbacks: IOCallbacks ): Promise => { - const context = createContext(ioCallbacks) + const context = createContext(code, ioCallbacks) // type checking const typeCheckResult = typeCheck(libraryClasses, code) @@ -57,7 +57,7 @@ export const runECEvaluatorInjected = ( } export const runECEvaluator = (code: string, targetStep: number = STEP_LIMIT): Promise => { - const context = createContext() + const context = createContext(code) try { // parse() may throw SyntaxError. const compilationUnit = parse(code) @@ -79,21 +79,24 @@ export const runECEvaluator = (code: string, targetStep: number = STEP_LIMIT): P } } -export const createContext = (ioCallbacks?: IOCallbacks): Context => ({ +export const createContext = (code: string, ioCallbacks?: IOCallbacks): Context => ({ errors: [], control: new Control(), stash: new Stash(), environment: new Environment(), - interfaces: initialiseInterfaces(ioCallbacks), + interfaces: initialiseInterfaces(code, ioCallbacks), totalSteps: 0 }) -const initialiseInterfaces = (ioCallbacks?: IOCallbacks) => { +const initialiseInterfaces = (code: string, ioCallbacks?: IOCallbacks): Interfaces => { return { stdout: ioCallbacks?.stdout ?? console.log, - stderr: ioCallbacks?.stderr ?? console.log + stderr: ioCallbacks?.stderr ?? console.log, + statics: { + lfsr: new LFSR(code) + } } } diff --git a/src/ec-evaluator/lib.ts b/src/ec-evaluator/lib.ts index d9bf939..a712819 100644 --- a/src/ec-evaluator/lib.ts +++ b/src/ec-evaluator/lib.ts @@ -4,34 +4,34 @@ Injects library classes for use by programs run in the CSEC machine. */ -// function fnv1a(s: string) { -// const FNV_OFFSET_BASIS = 2166136261 -// const FNV_PRIME = 16777619 - -// let hash = FNV_OFFSET_BASIS - -// for (let i = 0; i < s.length; i++) { -// hash ^= s.charCodeAt(i) -// hash *= FNV_PRIME -// } - -// return hash -// } - -// class LFSR { -// #state: number - -// constructor(init: string) { -// this.#state = fnv1a(init) | 0 // convert to 32-bit integer -// } - -// next() { -// const state = this.#state -// const bit = (state ^ (state >> 1) ^ (state >> 2) ^ (state >> 3)) & 1 -// this.#state = (state >> 1) | (bit << 30) -// return this.#state -// } -// } +function fnv1a(s: string) { + const FNV_OFFSET_BASIS = 2166136261 + const FNV_PRIME = 16777619 + + let hash = FNV_OFFSET_BASIS + + for (let i = 0; i < s.length; i++) { + hash ^= s.charCodeAt(i) + hash *= FNV_PRIME + } + + return hash +} + +export class LFSR { + #state: number + + constructor(init: string) { + this.#state = fnv1a(init) | 0 // convert to 32-bit integer + } + + next() { + const state = this.#state + const bit = (state ^ (state >> 1) ^ (state >> 2) ^ (state >> 3)) & 1 + this.#state = (state >> 1) | (bit << 30) + return this.#state + } +} export const libraryClasses = ` class Object { diff --git a/src/ec-evaluator/natives.ts b/src/ec-evaluator/natives.ts index 6c08493..1ab74fe 100644 --- a/src/ec-evaluator/natives.ts +++ b/src/ec-evaluator/natives.ts @@ -30,14 +30,16 @@ export type ForeignFunction = ({ export const foreigns: { [descriptor: string]: ForeignFunction } = { - 'Object::hashCode(): int': ({ stash }) => { - const hashCode = Math.floor(Math.random() * Math.pow(2, 32)) + 'Object::hashCode(): int': ({ environment, stash, interfaces }) => { + const instance = environment.getVariable('this').value + + const hashCode = 'hashCode' in instance ? instance.hashCode : interfaces.statics.lfsr.next() + const stashItem: StashItem = { kind: 'Literal', literalType: { kind: 'DecimalIntegerLiteral', value: String(hashCode) } } - console.log(stashItem) stash.push(stashItem) }, diff --git a/src/ec-evaluator/types.ts b/src/ec-evaluator/types.ts index 5523a2d..6774a43 100644 --- a/src/ec-evaluator/types.ts +++ b/src/ec-evaluator/types.ts @@ -11,6 +11,7 @@ import { } from '../ast/types/classes' import { Control, EnvNode, Environment, Stash } from './components' import { SourceError } from './errors' +import { LFSR } from './lib' import { ForeignFunction } from './natives' export interface Context { @@ -28,6 +29,9 @@ export interface Context { export interface Interfaces { stdout: (displayString: string) => void stderr: (errType: 'TypeCheck' | 'Compile' | 'Runtime', errMsg: string) => void + statics: { + lfsr: LFSR + } } export interface IOCallbacks { diff --git a/src/types/checker/prechecks.ts b/src/types/checker/prechecks.ts index 90544a2..7b7778f 100644 --- a/src/types/checker/prechecks.ts +++ b/src/types/checker/prechecks.ts @@ -113,7 +113,10 @@ export const addClassParents = (node: Node, frame: Frame): Result => { classType.setParentClass(extendsType) } else { const objectType = frame.getType('Object', { startOffset: -1, startLine: -1 }) - classType.setParentClass(objectType as ObjectClass) + // if Object is declared explicitly, use that + if (!(objectType instanceof TypeCheckerError)) { + classType.setParentClass(objectType as ObjectClass) + } } return newResult(classType) From 2fca094547297962135dc602d3be6fd0cd899dd9 Mon Sep 17 00:00:00 2001 From: mattcce Date: Sun, 14 Sep 2025 16:57:56 +0800 Subject: [PATCH 10/14] add toString native method for CSEC machine --- src/ast/types/ast.ts | 56 ++++----- src/ast/utils/astToString.ts | 216 ++++++++++++++++++++--------------- src/ec-evaluator/lib.ts | 4 +- src/ec-evaluator/natives.ts | 43 ++++++- src/ec-evaluator/types.ts | 1 + 5 files changed, 199 insertions(+), 121 deletions(-) diff --git a/src/ast/types/ast.ts b/src/ast/types/ast.ts index 80effea..708474f 100644 --- a/src/ast/types/ast.ts +++ b/src/ast/types/ast.ts @@ -1,4 +1,4 @@ -import { CompilationUnit } from "./packages-and-modules"; +import { CompilationUnit } from './packages-and-modules' import { Assignment, Block, @@ -8,44 +8,44 @@ import { Expression, ExpressionStatement, MethodInvocation, - ReturnStatement, -} from "./blocks-and-statements"; + ReturnStatement +} from './blocks-and-statements' import { ConstructorDeclaration, FieldDeclaration, MethodDeclaration, - NormalClassDeclaration, -} from "./classes"; + NormalClassDeclaration +} from './classes' interface NodeMap { - CompilationUnit: CompilationUnit; - MethodDeclaration: MethodDeclaration; - FieldDeclaration: FieldDeclaration; - Block: Block; - BlockStatement: BlockStatement; - Expression: Expression; - Assignment: Assignment; - ExpressionStatement: ExpressionStatement; - MethodInvocation: MethodInvocation; - ReturnStatement: ReturnStatement; - NormalClassDeclaration: NormalClassDeclaration; - ClassInstanceCreationExpression: ClassInstanceCreationExpression; - ConstructorDeclaration: ConstructorDeclaration; - ExplicitConstructorInvocation: ExplicitConstructorInvocation; + CompilationUnit: CompilationUnit + MethodDeclaration: MethodDeclaration + FieldDeclaration: FieldDeclaration + Block: Block + BlockStatement: BlockStatement + Expression: Expression + Assignment: Assignment + ExpressionStatement: ExpressionStatement + MethodInvocation: MethodInvocation + ReturnStatement: ReturnStatement + NormalClassDeclaration: NormalClassDeclaration + ClassInstanceCreationExpression: ClassInstanceCreationExpression + ConstructorDeclaration: ConstructorDeclaration + ExplicitConstructorInvocation: ExplicitConstructorInvocation } -export type Node = NodeMap[keyof NodeMap]; +export type Node = NodeMap[keyof NodeMap] export interface Location { - startOffset: number; - startLine: number; - startColumn?: number; - endOffset?: number; - endLine?: number; - endColumn?: number; + startOffset: number + startLine: number + startColumn?: number + endOffset?: number + endLine?: number + endColumn?: number } export interface BaseNode { - kind: string; - location?: Location; + kind: string + location?: Location } diff --git a/src/ast/utils/astToString.ts b/src/ast/utils/astToString.ts index bf4f38d..aed541b 100644 --- a/src/ast/utils/astToString.ts +++ b/src/ast/utils/astToString.ts @@ -1,4 +1,5 @@ -import { Node } from '../types/ast'; +import { NativeDeclaration } from '../../ec-evaluator' +import { Node } from '../types/ast' import { Assignment, BinaryExpression, @@ -10,122 +11,159 @@ import { Literal, LocalVariableDeclarationStatement, MethodInvocation, - ReturnStatement, -} from '../types/blocks-and-statements'; + ReturnStatement +} from '../types/blocks-and-statements' import { ConstructorDeclaration, FieldDeclaration, MethodDeclaration, - NormalClassDeclaration, -} from '../types/classes'; + NormalClassDeclaration +} from '../types/classes' const newline = (line: string): string => { - return `${line}\n`; + return `${line}\n` } const indentLine = (lvl: number, line: string): string => { - return `${' '.repeat(lvl)}${line}`; + return `${' '.repeat(lvl)}${line}` } -const INDENT_SPACES = 2; +const INDENT_SPACES = 2 -export const astToString = (node: Node, indent: number = 0): string => { +export const astToString = (node: Node | NativeDeclaration, indent: number = 0): string => { switch (node.kind) { - case "NormalClassDeclaration": - const c = node as NormalClassDeclaration; - const cModifier = c.classModifier.length > 0 ? c.classModifier.join(" ") + " " : ""; - const cSuperclass = c.sclass ? " extends " + c.sclass : ""; - return newline(indentLine(indent, `${cModifier}class ${c.typeIdentifier}${cSuperclass} {`)) - + `${c.classBody.map(b => newline(astToString(b, indent + INDENT_SPACES))).join("")}` - + `${indentLine(indent, "}")}`; - - case "Block": - const block = node as Block; - return `${newline(indentLine(indent, "{"))}` - + `${block.blockStatements.map(s => newline(astToString(s, indent + INDENT_SPACES))).join("")}` - + `${indentLine(indent, "}")}`; - - case "ConstructorDeclaration": - const con = node as ConstructorDeclaration; - const conModifier = con.constructorModifier.length > 0 - ? con.constructorModifier.join(" ") + " " - : ""; - const conIdentifier = con.constructorDeclarator.identifier; - const conParams = con.constructorDeclarator.formalParameterList.map(p => `${p.unannType} ${p.identifier}`).join(", "); - return newline(indentLine(indent, `${conModifier}${conIdentifier}(${conParams}) {`)) - + `${con.constructorBody.blockStatements.map(s => newline(astToString(s, indent + INDENT_SPACES))).join("")}` - + `${indentLine(indent, "}")}`; - - case "MethodDeclaration": - const mtd = node as MethodDeclaration; - const mtdModifier = mtd.methodModifier.length > 0 ? mtd.methodModifier.join(" ") + " " : ""; - const mtdRes = mtd.methodHeader.result; - const mtdIdentifier = mtd.methodHeader.identifier; - const mtdParams = mtd.methodHeader.formalParameterList.map(p => `${p.unannType} ${p.identifier}`).join(", "); - return newline(indentLine(indent, `${mtdModifier}${mtdRes} ${mtdIdentifier}(${mtdParams}) {`)) - + `${mtd.methodBody.blockStatements.map(s => newline(astToString(s, indent + INDENT_SPACES))).join("")}` - + `${indentLine(indent, "}")}`; - - case "FieldDeclaration": - const field = node as FieldDeclaration; - const fieldModifier = field.fieldModifier.length > 0 ? field.fieldModifier.join(" ") + " " : ""; - const fieldType = field.fieldType; - const fieldIdentifier = field.variableDeclaratorList[0].variableDeclaratorId; + case 'NormalClassDeclaration': + const c = node as NormalClassDeclaration + const cModifier = c.classModifier.length > 0 ? c.classModifier.join(' ') + ' ' : '' + const cSuperclass = c.sclass ? ' extends ' + c.sclass : '' + return ( + newline(indentLine(indent, `${cModifier}class ${c.typeIdentifier}${cSuperclass} {`)) + + `${c.classBody.map(b => newline(astToString(b, indent + INDENT_SPACES))).join('')}` + + `${indentLine(indent, '}')}` + ) + + case 'Block': + const block = node as Block + return ( + `${newline(indentLine(indent, '{'))}` + + `${block.blockStatements.map(s => newline(astToString(s, indent + INDENT_SPACES))).join('')}` + + `${indentLine(indent, '}')}` + ) + + case 'ConstructorDeclaration': + const con = node as ConstructorDeclaration + const conModifier = + con.constructorModifier.length > 0 ? con.constructorModifier.join(' ') + ' ' : '' + const conIdentifier = con.constructorDeclarator.identifier + const conParams = con.constructorDeclarator.formalParameterList + .map(p => `${p.unannType} ${p.identifier}`) + .join(', ') + return ( + newline(indentLine(indent, `${conModifier}${conIdentifier}(${conParams}) {`)) + + `${con.constructorBody.blockStatements.map(s => newline(astToString(s, indent + INDENT_SPACES))).join('')}` + + `${indentLine(indent, '}')}` + ) + + case 'MethodDeclaration': + const normalMtd = node as MethodDeclaration + const normalMtdModifier = + normalMtd.methodModifier.length > 0 ? normalMtd.methodModifier.join(' ') + ' ' : '' + const normalMtdRes = normalMtd.methodHeader.result + const normalMtdIdentifier = normalMtd.methodHeader.identifier + const normalMtdParams = normalMtd.methodHeader.formalParameterList + .map(p => `${p.unannType} ${p.identifier}`) + .join(', ') + return ( + newline( + indentLine( + indent, + `${normalMtdModifier}${normalMtdRes} ${normalMtdIdentifier}(${normalMtdParams}) {` + ) + ) + + `${normalMtd.methodBody.blockStatements.map(s => newline(astToString(s, indent + INDENT_SPACES))).join('')}` + + `${indentLine(indent, '}')}` + ) + + case 'NativeDeclaration': + const nativeMtd = node as NativeDeclaration + const nativeMtdModifier = + nativeMtd.methodModifier.length > 0 ? nativeMtd.methodModifier.join(' ') + ' ' : '' + const nativeMtdRes = nativeMtd.methodHeader.result + const nativeMtdIdentifier = nativeMtd.methodHeader.identifier + const nativeMtdParams = nativeMtd.methodHeader.formalParameterList + .map(p => `${p.unannType} ${p.identifier}`) + .join(', ') + return newline( + indentLine( + indent, + `${nativeMtdModifier}${nativeMtdRes} ${nativeMtdIdentifier}(${nativeMtdParams});` + ) + ) + + case 'FieldDeclaration': + const field = node as FieldDeclaration + const fieldModifier = + field.fieldModifier.length > 0 ? field.fieldModifier.join(' ') + ' ' : '' + const fieldType = field.fieldType + const fieldIdentifier = field.variableDeclaratorList[0].variableDeclaratorId const fieldInit = field.variableDeclaratorList[0].variableInitializer ? ` = ${astToString(field.variableDeclaratorList[0].variableInitializer! as ExpressionName)}` - : ""; - return indentLine(indent, `${fieldModifier}${fieldType} ${fieldIdentifier}${fieldInit};`); + : '' + return indentLine(indent, `${fieldModifier}${fieldType} ${fieldIdentifier}${fieldInit};`) - case "LocalVariableDeclarationStatement": - const localVar = node as LocalVariableDeclarationStatement; - const localVarType = localVar.localVariableType; - const localVarIdentifier = localVar.variableDeclaratorList[0].variableDeclaratorId; + case 'LocalVariableDeclarationStatement': + const localVar = node as LocalVariableDeclarationStatement + const localVarType = localVar.localVariableType + const localVarIdentifier = localVar.variableDeclaratorList[0].variableDeclaratorId const localVarInit = localVar.variableDeclaratorList[0].variableInitializer ? ` = ${astToString(localVar.variableDeclaratorList[0].variableInitializer! as ExpressionName)}` - : ""; - return indentLine(indent, `${localVarType} ${localVarIdentifier}${localVarInit};`); + : '' + return indentLine(indent, `${localVarType} ${localVarIdentifier}${localVarInit};`) - case "ReturnStatement": - const returnStmt = node as ReturnStatement; - const returnExp = returnStmt.exp.kind === "Void" ? "" : ` ${astToString(returnStmt.exp)}`; - return indentLine(indent, `return${returnExp};`); + case 'ReturnStatement': + const returnStmt = node as ReturnStatement + const returnExp = returnStmt.exp.kind === 'Void' ? '' : ` ${astToString(returnStmt.exp)}` + return indentLine(indent, `return${returnExp};`) - case "ExpressionStatement": - const expStmt = node as ExpressionStatement; - return indentLine(indent, `${astToString(expStmt.stmtExp)};`); + case 'ExpressionStatement': + const expStmt = node as ExpressionStatement + return indentLine(indent, `${astToString(expStmt.stmtExp)};`) - case "Assignment": - const assmt = node as Assignment; - return `${(assmt.left as ExpressionName).name} = ${astToString(assmt.right)}`; + case 'Assignment': + const assmt = node as Assignment + return `${(assmt.left as ExpressionName).name} = ${astToString(assmt.right)}` - case "MethodInvocation": - const mtdInv = node as MethodInvocation; - return `${mtdInv.identifier}(${mtdInv.argumentList.map(a => astToString(a)).join(", ")})` + case 'MethodInvocation': + const mtdInv = node as MethodInvocation + return `${mtdInv.identifier}(${mtdInv.argumentList.map(a => astToString(a)).join(', ')})` - case "ClassInstanceCreationExpression": - const classInstanceCreationExp = node as ClassInstanceCreationExpression; - return `new ${classInstanceCreationExp.identifier}(${classInstanceCreationExp.argumentList.map(a => astToString(a))})`; + case 'ClassInstanceCreationExpression': + const classInstanceCreationExp = node as ClassInstanceCreationExpression + return `new ${classInstanceCreationExp.identifier}(${classInstanceCreationExp.argumentList.map(a => astToString(a))})` - case "ExplicitConstructorInvocation": - const expConInv = node as ExplicitConstructorInvocation; - return indentLine(indent, `${expConInv.thisOrSuper}(${expConInv.argumentList.map(a => astToString(a))});`); + case 'ExplicitConstructorInvocation': + const expConInv = node as ExplicitConstructorInvocation + return indentLine( + indent, + `${expConInv.thisOrSuper}(${expConInv.argumentList.map(a => astToString(a))});` + ) - case "BinaryExpression": - const bin = node as BinaryExpression; - return `${astToString(bin.left)} ${bin.operator} ${astToString(bin.right)}`; + case 'BinaryExpression': + const bin = node as BinaryExpression + return `${astToString(bin.left)} ${bin.operator} ${astToString(bin.right)}` - case "ExpressionName": - const exp = node as ExpressionName; - return exp.name; + case 'ExpressionName': + const exp = node as ExpressionName + return exp.name - case "Literal": - const literal = node as Literal; - return `${literal.literalType.value}`; + case 'Literal': + const literal = node as Literal + return `${literal.literalType.value}` - case "Void": - return "void"; + case 'Void': + return 'void' default: - return node.kind; + return node.kind } -} \ No newline at end of file +} diff --git a/src/ec-evaluator/lib.ts b/src/ec-evaluator/lib.ts index a712819..61c45ca 100644 --- a/src/ec-evaluator/lib.ts +++ b/src/ec-evaluator/lib.ts @@ -35,9 +35,11 @@ export class LFSR { export const libraryClasses = ` class Object { + public static native void display(int s); + public native int hashCode(); - public static native void display(int s); + public native String toString(); }` // const disabled = `class PrintStream extends Object { diff --git a/src/ec-evaluator/natives.ts b/src/ec-evaluator/natives.ts index 1ab74fe..0c9f8f2 100644 --- a/src/ec-evaluator/natives.ts +++ b/src/ec-evaluator/natives.ts @@ -1,5 +1,6 @@ import { Control, Environment, Stash } from './components' -import { Interfaces, StashItem } from './types' +import { RuntimeError } from './errors' +import { Interfaces, StashItem, StructType, VarValue } from './types' /* Native function escape hatch. @@ -30,10 +31,10 @@ export type ForeignFunction = ({ export const foreigns: { [descriptor: string]: ForeignFunction } = { - 'Object::hashCode(): int': ({ environment, stash, interfaces }) => { + 'Object::hashCode(): int': ({ stash, environment, interfaces }) => { const instance = environment.getVariable('this').value - const hashCode = 'hashCode' in instance ? instance.hashCode : interfaces.statics.lfsr.next() + const hashCode = getHashCode(instance, interfaces) const stashItem: StashItem = { kind: 'Literal', @@ -48,5 +49,41 @@ export const foreigns: { const s = environment.getVariable('s').value.literalType.value interfaces.stdout(s) + }, + + 'Object::toString(): String': ({ stash, environment, interfaces }) => { + const instance = environment.getVariable('this').value + + if (instance.kind !== StructType.OBJECT) { + throw new RuntimeError('Call to toString on non-Object') + } + + const className = instance.class.classDecl.typeIdentifier + const hashCodeToHex = getHashCode(instance, interfaces).toString(16) + + const stashItem: StashItem = { + kind: 'Literal', + literalType: { + kind: 'StringLiteral', + value: `${className}@${hashCodeToHex}` + } + } + + stash.push(stashItem) + return } } + +// Utility functions used by native methods +const getHashCode = (obj: VarValue, interfaces: Interfaces): number => { + if (obj.kind !== StructType.OBJECT) { + // TODO: throw error here + throw new RuntimeError('Attempt to retrieve hashCode from non-Object') + } + + if (obj.hashCode === undefined) { + obj.hashCode = interfaces.statics.lfsr.next() + } + + return obj.hashCode +} diff --git a/src/ec-evaluator/types.ts b/src/ec-evaluator/types.ts index 6774a43..b479b75 100644 --- a/src/ec-evaluator/types.ts +++ b/src/ec-evaluator/types.ts @@ -178,6 +178,7 @@ export interface Object { kind: StructType.OBJECT frame: EnvNode class: Class + hashCode?: number } export interface NativeDeclaration { From bd07203af3ee18bfd78031e069595cb435bc8194 Mon Sep 17 00:00:00 2001 From: mattcce Date: Fri, 17 Oct 2025 14:43:22 +0800 Subject: [PATCH 11/14] integrate new CSEC evaluator --- src/ec-evaluator/index.ts | 41 ++++++++++++++------------------------- src/ec-evaluator/types.ts | 2 +- 2 files changed, 16 insertions(+), 27 deletions(-) diff --git a/src/ec-evaluator/index.ts b/src/ec-evaluator/index.ts index 7abaf4e..380cfd9 100644 --- a/src/ec-evaluator/index.ts +++ b/src/ec-evaluator/index.ts @@ -5,7 +5,7 @@ import { STEP_LIMIT } from './constants' import { RuntimeError } from './errors' import { evaluate } from './interpreter' import { LFSR, libraryClasses } from './lib' -import { Context, Error, Finished, Interfaces, IOCallbacks, Result } from './types' +import { Class, Context, Error, Finished, Interfaces, IOCallbacks, Result } from './types' import { handleSequence } from './utils' export * from './components' @@ -13,7 +13,7 @@ export * from './errors' export * from './types' export { isInstr, isNode } from './utils' -export const runECEvaluatorInjected = ( +export const runECEvaluator = ( code: string, targetStep: number = STEP_LIMIT, ioCallbacks: IOCallbacks @@ -56,29 +56,6 @@ export const runECEvaluatorInjected = ( } } -export const runECEvaluator = (code: string, targetStep: number = STEP_LIMIT): Promise => { - const context = createContext(code) - try { - // parse() may throw SyntaxError. - const compilationUnit = parse(code) - - context.control.push(compilationUnit) - // evaluate() may throw RuntimeError - const value = evaluate(context, targetStep) - - return new Promise((resolve, _) => { - resolve({ status: 'finished', context, value } as Finished) - }) - } catch (e) { - // Possible interpreting language error thrown, so conversion to RuntimeError may be required. - const error = e.type ? e : new RuntimeError(e.message) - context.errors.push(error) - return new Promise((resolve, _) => { - resolve({ status: 'error', context } as Error) - }) - } -} - export const createContext = (code: string, ioCallbacks?: IOCallbacks): Context => ({ errors: [], @@ -94,9 +71,21 @@ export const createContext = (code: string, ioCallbacks?: IOCallbacks): Context const initialiseInterfaces = (code: string, ioCallbacks?: IOCallbacks): Interfaces => { return { stdout: ioCallbacks?.stdout ?? console.log, - stderr: ioCallbacks?.stderr ?? console.log, + stderr: ioCallbacks?.stderr ?? console.error, statics: { lfsr: new LFSR(code) } } } + +export const makeObjectClass = (): Class => { + const context = createContext('') + const objectClassDefinition = 'class Object {}' + const libraryCompilationUnit = parse(objectClassDefinition) + context.control.push( + ...handleSequence(libraryCompilationUnit.topLevelClassOrInterfaceDeclarations) + ) + evaluate(context, STEP_LIMIT) + + return context.environment.getClass('Object') +} diff --git a/src/ec-evaluator/types.ts b/src/ec-evaluator/types.ts index b479b75..d39ed56 100644 --- a/src/ec-evaluator/types.ts +++ b/src/ec-evaluator/types.ts @@ -202,7 +202,7 @@ export interface Class { instanceFields: FieldDeclaration[] instanceMethods: (MethodDeclaration | NativeDeclaration)[] staticFields: FieldDeclaration[] - staticMethods: MethodDeclaration[] + staticMethods: (MethodDeclaration | NativeDeclaration)[] superclass?: Class } From 2631fd655334f49a71dc64279652653f9fb2a757 Mon Sep 17 00:00:00 2001 From: mattcce Date: Fri, 17 Oct 2025 14:43:47 +0800 Subject: [PATCH 12/14] update CSEC tests Removed the expectation of an empty `Object` class from all tests, since that behaviour is now deprecated. A blank `Object` class will be synthesized instead by utility function. --- src/ec-evaluator/__tests__/__utils__/utils.ts | 19 +- src/ec-evaluator/__tests__/arithmetic.test.ts | 646 ++--- src/ec-evaluator/__tests__/class-decl.test.ts | 800 +++--- .../__tests__/class-instance-creation.test.ts | 1542 +++++------ .../__tests__/constructor-overloading.test.ts | 1474 +++++----- .../inheritance-instance-field.test.ts | 1798 ++++++------ .../inheritance-static-field.test.ts | 1366 ++++----- .../__tests__/local-var-assignment.test.ts | 596 ++-- src/ec-evaluator/__tests__/main-mtd.test.ts | 542 ++-- .../__tests__/mtd-overloading.test.ts | 2061 +++++++------- .../__tests__/mtd-overriding.test.ts | 1874 ++++++------- .../__tests__/null-pointer-exception.test.ts | 106 +- .../__tests__/qualified-mtd-inv.test.ts | 2430 ++++++++--------- .../__tests__/qualified-names-this.test.ts | 992 +++---- .../__tests__/simple-mtd-inv.test.ts | 798 +++--- .../__tests__/this-keyword.test.ts | 1284 ++++----- 16 files changed, 9171 insertions(+), 9157 deletions(-) diff --git a/src/ec-evaluator/__tests__/__utils__/utils.ts b/src/ec-evaluator/__tests__/__utils__/utils.ts index 27732b3..5c959b6 100644 --- a/src/ec-evaluator/__tests__/__utils__/utils.ts +++ b/src/ec-evaluator/__tests__/__utils__/utils.ts @@ -1,7 +1,9 @@ import { Environment } from '../../components' import { STEP_LIMIT } from '../../constants' +import { LFSR } from '../../lib' import { ControlItem, Context, StashItem, StructType } from '../../types' import { Stack, isNode } from '../../utils' +import { makeObjectClass } from '../../index' export class StackStub extends Stack { private trace: T[] = [] @@ -17,17 +19,30 @@ export class StackStub extends Stack { return this.trace } } + export class ControlStub extends StackStub {} export class StashStub extends StackStub {} // TODO make env traceable -export class EnvironmentStub extends Environment {} +export class EnvironmentStub extends Environment { + constructor() { + super() + this.defineClass('Object', makeObjectClass()) + } +} export const createContextStub = (): Context => ({ errors: [], control: new ControlStub(), stash: new StashStub(), environment: new EnvironmentStub(), - totalSteps: STEP_LIMIT + totalSteps: STEP_LIMIT, + interfaces: { + stdout: console.log, + stderr: console.error, + statics: { + lfsr: new LFSR('') + } + } }) export const getControlItemStr = (i: ControlItem): string => { diff --git a/src/ec-evaluator/__tests__/arithmetic.test.ts b/src/ec-evaluator/__tests__/arithmetic.test.ts index 62f8828..6ee31ca 100644 --- a/src/ec-evaluator/__tests__/arithmetic.test.ts +++ b/src/ec-evaluator/__tests__/arithmetic.test.ts @@ -1,415 +1,415 @@ -import { evaluate } from "../interpreter"; -import { parse } from "../../ast/parser" +import { evaluate } from '../interpreter' +import { parse } from '../../ast/parser' import { ControlStub, StashStub, createContextStub, getControlItemStr, getStashItemStr -} from "./__utils__/utils"; +} from './__utils__/utils' -it("evaluate LocalVariableDeclarationStatement to a basic arithmetic operation correctly", () => { +it('evaluate LocalVariableDeclarationStatement to a basic arithmetic operation correctly', () => { const programStr = ` public class Test { public static void main(String[] args) { int y = 10 % 2; } } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", + 'CompilationUnit', - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // public class Test {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // public class Test {...} - "Env", // from NormalClassDeclaration - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} - "Pop", - "MethodInvocation", // Test.main([""]) + 'Pop', + 'MethodInvocation', // Test.main([""]) - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test - "Deref", - "EvalVariable", // Test + 'Deref', + 'EvalVariable', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; - "LocalVariableDeclarationStatement", // int y = 10 % 2; + 'Env', // from Block + 'ReturnStatement', // return; + 'LocalVariableDeclarationStatement', // int y = 10 % 2; - "ExpressionStatement", // y = 10 % 2; - "LocalVariableDeclarationStatement", // int y; + 'ExpressionStatement', // y = 10 % 2; + 'LocalVariableDeclarationStatement', // int y; - "Pop", - "Assignment", // y = 10 % 2 + 'Pop', + 'Assignment', // y = 10 % 2 - "Assign", // = - "BinaryExpression", // 10 % 2 - "EvalVariable", // y + 'Assign', // = + 'BinaryExpression', // 10 % 2 + 'EvalVariable', // y - "BinaryOperation", // % - "Literal", // 2 - "Literal", // 10 + 'BinaryOperation', // % + 'Literal', // 2 + 'Literal', // 10 - "Reset", // return - "Void", + 'Reset', // return + 'Void', - "Reset", // skip Env from Invocation - ]; + 'Reset' // skip Env from Invocation + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "y", // EvalVariable - "10", // Literal - "2", // Literal - "0", // BinaryOperation % - "0", // Assign - "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); + 'y', // EvalVariable + '10', // Literal + '2', // Literal + '0', // BinaryOperation % + '0', // Assign + '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 + ) // TODO test env -}); +}) -it("evaluate LocalVariableDeclarationStatement to a complex arithmetic operation correctly", () => { +it('evaluate LocalVariableDeclarationStatement to a complex arithmetic operation correctly', () => { const programStr = ` public class Test { public static void main(String[] args) { int z = 1 + (2 * 3) - 4; } } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", + 'CompilationUnit', - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // public class Test {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // public class Test {...} - "Env", // from NormalClassDeclaration - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} - "Pop", - "MethodInvocation", // Test.main([""]) + 'Pop', + 'MethodInvocation', // Test.main([""]) - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test - "Deref", - "EvalVariable", // Test + 'Deref', + 'EvalVariable', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; - "LocalVariableDeclarationStatement", // int z = 1 + (2 * 3) - 4; + 'Env', // from Block + 'ReturnStatement', // return; + 'LocalVariableDeclarationStatement', // int z = 1 + (2 * 3) - 4; - "ExpressionStatement", // z = 1 + (2 * 3) - 4; - "LocalVariableDeclarationStatement", // int z; + 'ExpressionStatement', // z = 1 + (2 * 3) - 4; + 'LocalVariableDeclarationStatement', // int z; - "Pop", - "Assignment", // z = 1 + (2 * 3) - 4 + 'Pop', + 'Assignment', // z = 1 + (2 * 3) - 4 - "Assign", // = - "BinaryExpression", // 1 + (2 * 3) - 4 - "EvalVariable", // z + 'Assign', // = + 'BinaryExpression', // 1 + (2 * 3) - 4 + 'EvalVariable', // z - "BinaryOperation", // + - "Literal", // 1 - "BinaryExpression", // (2 * 3) - 4 + 'BinaryOperation', // + + 'Literal', // 1 + 'BinaryExpression', // (2 * 3) - 4 - "BinaryOperation", // - - "BinaryExpression", // 2 * 3 - "Literal", // 4 + 'BinaryOperation', // - + 'BinaryExpression', // 2 * 3 + 'Literal', // 4 - "BinaryOperation", // * - "Literal", // 2 - "Literal", // 3 + 'BinaryOperation', // * + 'Literal', // 2 + 'Literal', // 3 - "Reset", // return - "Void", + 'Reset', // return + 'Void', - "Reset", // skip Env from Invocation - ]; + 'Reset' // skip Env from Invocation + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "z", // EvalVariable - "1", // Literal - "2", // Literal - "3", // Literal - "6", // BinaryOperation * - "7", // BinaryOperation + - "4", // Literal - "3", // BinaryOperation - - "3", // Assign - "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); + 'z', // EvalVariable + '1', // Literal + '2', // Literal + '3', // Literal + '6', // BinaryOperation * + '7', // BinaryOperation + + '4', // Literal + '3', // BinaryOperation - + '3', // Assign + '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 + ) // TODO test env -}); +}) -it("evaluate FieldDeclaration to a basic arithmetic expression without brackets to enforce precedence correctly", () => { +it('evaluate FieldDeclaration to a basic arithmetic expression without brackets to enforce precedence correctly', () => { const programStr = ` public class Test { static int x = 1 + 2 * 3; public static void main(String[] args) {} } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // public class Test {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} - - "Env", // from NormalClassDeclaration - "MethodDeclaration", // public static void main(String[] args) {} - "ConstructorDeclaration", // Test() {...} - "FieldDeclaration", // static int x = 1 + 2 * 3; - - "Pop", - "Assign", // = - "BinaryExpression", // 1 + 2 * 3 - "EvalVariable", // x - - "BinaryOperation", // + - "BinaryExpression", // 2 * 3 - "Literal", // 1 - - "BinaryOperation", // * - "Literal", // 3 - "Literal", // 2 - - "Pop", - "MethodInvocation", // Test.main([""]) - - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test - - "Deref", - "EvalVariable", // Test - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return; - - "Reset", // return - "Void", - - "Reset", // skip Env from Invocation - ]; + 'CompilationUnit', + + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // public class Test {...} + + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // public static void main(String[] args) {} + 'ConstructorDeclaration', // Test() {...} + 'FieldDeclaration', // static int x = 1 + 2 * 3; + + 'Pop', + 'Assign', // = + 'BinaryExpression', // 1 + 2 * 3 + 'EvalVariable', // x + + 'BinaryOperation', // + + 'BinaryExpression', // 2 * 3 + 'Literal', // 1 + + 'BinaryOperation', // * + 'Literal', // 3 + 'Literal', // 2 + + 'Pop', + 'MethodInvocation', // Test.main([""]) + + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test + + 'Deref', + 'EvalVariable', // Test + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return; + + 'Reset', // return + 'Void', + + 'Reset' // skip Env from Invocation + ] const expectedStashTrace = [ - "x", // EvalVariable - "1", // Literal - "2", // Literal - "3", // Literal - "6", // BinaryOperation * - "7", // BinaryOperation + - "7", // Assign - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'x', // EvalVariable + '1', // Literal + '2', // Literal + '3', // Literal + '6', // BinaryOperation * + '7', // BinaryOperation + + '7', // Assign + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "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); + '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 + ) // TODO test env -}); +}) -it("evaluate FieldDeclaration to a complex arithmetic expression without brackets to enforce precedence correctly", () => { +it('evaluate FieldDeclaration to a complex arithmetic expression without brackets to enforce precedence correctly', () => { const programStr = ` public class Test { static int x = 2 / 1 - 3 * (5 % 4) + 6; public static void main(String[] args) {} } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // public class Test {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} - - "Env", // from NormalClassDeclaration - "MethodDeclaration", // public static void main(String[] args) {} - "ConstructorDeclaration", // Test() {...} - "FieldDeclaration", // static int x = 2 / 1 - 3 * (5 % 4) + 6; - - "Pop", - "Assign", // = - "BinaryExpression", // 2 / 1 - 3 * (5 % 4) + 6 - "EvalVariable", // x - - "BinaryOperation", // + - "Literal", // 6 - "BinaryExpression", // 2 / 1 - 3 * (5 % 4) - - "BinaryOperation", // - - "BinaryExpression", // 3 * (5 % 4) - "BinaryExpression", // 2 / 1 - - "BinaryOperation", // / - "Literal", // 1 - "Literal", // 2 - - "BinaryOperation", // * - "BinaryExpression", // 5 % 4 - "Literal", // 3 - - "BinaryOperation", // % - "Literal", // 4 - "Literal", // 5 - - "Pop", - "MethodInvocation", // Test.main([""]) - - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test - - "Deref", - "EvalVariable", // Test - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return; - - "Reset", // return - "Void", - - "Reset", // skip Env from Invocation - ]; + 'CompilationUnit', + + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // public class Test {...} + + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // public static void main(String[] args) {} + 'ConstructorDeclaration', // Test() {...} + 'FieldDeclaration', // static int x = 2 / 1 - 3 * (5 % 4) + 6; + + 'Pop', + 'Assign', // = + 'BinaryExpression', // 2 / 1 - 3 * (5 % 4) + 6 + 'EvalVariable', // x + + 'BinaryOperation', // + + 'Literal', // 6 + 'BinaryExpression', // 2 / 1 - 3 * (5 % 4) + + 'BinaryOperation', // - + 'BinaryExpression', // 3 * (5 % 4) + 'BinaryExpression', // 2 / 1 + + 'BinaryOperation', // / + 'Literal', // 1 + 'Literal', // 2 + + 'BinaryOperation', // * + 'BinaryExpression', // 5 % 4 + 'Literal', // 3 + + 'BinaryOperation', // % + 'Literal', // 4 + 'Literal', // 5 + + 'Pop', + 'MethodInvocation', // Test.main([""]) + + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test + + 'Deref', + 'EvalVariable', // Test + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return; + + 'Reset', // return + 'Void', + + 'Reset' // skip Env from Invocation + ] const expectedStashTrace = [ - "x", // EvalVariable - "2", // Literal - "1", // Literal - "2", // BinaryOperation / - "3", // Literal - "5", // Literal - "4", // Literal - "1", // BinaryOperation % - "3", // BinaryOperation + - "-1", // BinaryOperation - - "6", // Literal - "5", // BinaryOperation + - "5", // Assign - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'x', // EvalVariable + '2', // Literal + '1', // Literal + '2', // BinaryOperation / + '3', // Literal + '5', // Literal + '4', // Literal + '1', // BinaryOperation % + '3', // BinaryOperation + + '-1', // BinaryOperation - + '6', // Literal + '5', // BinaryOperation + + '5', // Assign + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "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); + '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 + ) // TODO test env -}); +}) diff --git a/src/ec-evaluator/__tests__/class-decl.test.ts b/src/ec-evaluator/__tests__/class-decl.test.ts index 7723f25..6d18544 100644 --- a/src/ec-evaluator/__tests__/class-decl.test.ts +++ b/src/ec-evaluator/__tests__/class-decl.test.ts @@ -1,478 +1,478 @@ -import { parse } from "../../ast/parser"; -import { evaluate } from "../interpreter"; +import { parse } from '../../ast/parser' +import { evaluate } from '../interpreter' import { ControlStub, StashStub, createContextStub, getControlItemStr, getStashItemStr -} from "./__utils__/utils"; +} from './__utils__/utils' -describe("evaluate NormalClassDeclaration correctly", () => { - it("evaluate NormalClassDeclaration correctly", () => { +describe('evaluate NormalClassDeclaration correctly', () => { + it('evaluate NormalClassDeclaration correctly', () => { const programStr = ` class Parent {} class Test extends Parent { public static void main(String[] args) {} } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class Test extends Parent {...} - "NormalClassDeclaration", // class Parent {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Parent() {...} - - "Env", // from NormalClassDeclaration - "MethodDeclaration", // static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} - - "Pop", - "MethodInvocation", // Test.main([""]) - - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test - - "Deref", - "EvalVariable", // Test - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return; - - "Reset", // return - "Void", - - "Reset", // Skip Env from Block - ]; + 'CompilationUnit', + + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class Test extends Parent {...} + 'NormalClassDeclaration', // class Parent {...} + + 'Env', // from NormalClassDeclaration + 'ConstructorDeclaration', // Parent() {...} + + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} + + 'Pop', + 'MethodInvocation', // Test.main([""]) + + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test + + 'Deref', + 'EvalVariable', // Test + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return; + + 'Reset', // return + 'Void', + + 'Reset' // Skip Env from Block + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "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); + '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 + ) // TODO test env - }); -}); + }) +}) -describe("evaluate FieldDeclaration correctly", () => { - it("evaluate static FieldDeclaration without variableInitializer correctly", () => { +describe('evaluate FieldDeclaration correctly', () => { + it('evaluate static FieldDeclaration without variableInitializer correctly', () => { const programStr = ` public class Test { static Test x; public static void main(String[] args) {} } - `; - - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); - - const context = createContextStub(); - context.control.push(compilationUnit!); - - const result = evaluate(context); - + ` + + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() + + const context = createContextStub() + context.control.push(compilationUnit!) + + const result = evaluate(context) + const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // public class Test {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} - - "Env", // from NormalClassDeclaration - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} - "FieldDeclaration", // static Test x = null; - - "Pop", - "Assign", // = - "Literal", // null - "EvalVariable", // x - - "Pop", - "MethodInvocation", // Test.main([""]) - - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test - - "Deref", - "EvalVariable", // Test - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return; - - "Reset", // return - "Void", - - "Reset", // skip Env from Invocation - ]; + 'CompilationUnit', + + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // public class Test {...} + + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} + 'FieldDeclaration', // static Test x = null; + + 'Pop', + 'Assign', // = + 'Literal', // null + 'EvalVariable', // x + + 'Pop', + 'MethodInvocation', // Test.main([""]) + + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test + + 'Deref', + 'EvalVariable', // Test + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return; + + 'Reset', // return + 'Void', + + 'Reset' // skip Env from Invocation + ] const expectedStashTrace = [ - "x", // EvalVariable - "null", // Literal - "null", // Assign - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'x', // EvalVariable + 'null', // Literal + 'null', // Assign + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "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); + '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 + ) // TODO test env - }); - - it("evaluate static FieldDeclaration with variableInitializer correctly", () => { + }) + + it('evaluate static FieldDeclaration with variableInitializer correctly', () => { const programStr = ` public class Test { static int x = 1; public static void main(String[] args) {} } - `; - - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); - - const context = createContextStub(); - context.control.push(compilationUnit!); - - const result = evaluate(context); - + ` + + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() + + const context = createContextStub() + context.control.push(compilationUnit!) + + const result = evaluate(context) + const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // public class Test {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} - - "Env", // from NormalClassDeclaration - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} - "FieldDeclaration", // static int x = 1; - - "Pop", - "Assign", // = - "Literal", // 1 - "EvalVariable", // x - - "Pop", - "MethodInvocation", // Test.main([""]) - - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test - - "Deref", - "EvalVariable", // Test - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return; - - "Reset", // return - "Void", - - "Reset", // skip Env from Invocation - ]; + 'CompilationUnit', + + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // public class Test {...} + + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} + 'FieldDeclaration', // static int x = 1; + + 'Pop', + 'Assign', // = + 'Literal', // 1 + 'EvalVariable', // x + + 'Pop', + 'MethodInvocation', // Test.main([""]) + + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test + + 'Deref', + 'EvalVariable', // Test + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return; + + 'Reset', // return + 'Void', + + 'Reset' // skip Env from Invocation + ] const expectedStashTrace = [ - "x", // EvalVariable - "1", // Literal - "1", // Assign - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'x', // EvalVariable + '1', // Literal + '1', // Assign + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "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); + '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 + ) // TODO test env - }); -}); + }) +}) -describe("evaluate MethodDeclaration correctly", () => { - it("evaluate MethodDeclaration without explicit return correctly", () => { +describe('evaluate MethodDeclaration correctly', () => { + it('evaluate MethodDeclaration without explicit return correctly', () => { const programStr = ` public class Test { public static void main(String[] args) {} } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // public class Test {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} - - "Env", // from NormalClassDeclaration - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} - - "Pop", - "MethodInvocation", // Test.main([""]) - - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test - - "Deref", - "EvalVariable", // Test - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return; - - "Reset", // return - "Void", - - "Reset", // Skip Env from Block - ]; + 'CompilationUnit', + + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // public class Test {...} + + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} + + 'Pop', + 'MethodInvocation', // Test.main([""]) + + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test + + 'Deref', + 'EvalVariable', // Test + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return; + + 'Reset', // return + 'Void', + + 'Reset' // Skip Env from Block + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "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); + '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 + ) // TODO test env - }); + }) - it("evaluate MethodDeclaration with explicit return correctly", () => { + it('evaluate MethodDeclaration with explicit return correctly', () => { const programStr = ` public class Test { public static void main(String[] args) { return; } } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // public class Test {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} - - "Env", // from NormalClassDeclaration - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} - - "Pop", - "MethodInvocation", // Test.main([""]) - - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test - - "Deref", - "EvalVariable", // Test - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return; - - "Reset", // return - "Void", - - "Reset", // Skip Env from Block - ]; + 'CompilationUnit', + + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // public class Test {...} + + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} + + 'Pop', + 'MethodInvocation', // Test.main([""]) + + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test + + 'Deref', + 'EvalVariable', // Test + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return; + + 'Reset', // return + 'Void', + + 'Reset' // Skip Env from Block + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "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); + '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 + ) // TODO test env - }); + }) - it("evaluate multiple MethodDeclaration correctly", () => { + it('evaluate multiple MethodDeclaration correctly', () => { const programStr = ` public class Test { public static void main(String[] args) {} static void test1() {} private int test2(int x) {} } - `; - - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); - - const context = createContextStub(); - context.control.push(compilationUnit!); - - const result = evaluate(context); - + ` + + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() + + const context = createContextStub() + context.control.push(compilationUnit!) + + const result = evaluate(context) + const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // public class Test {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} - - "Env", // from NormalClassDeclaration - "MethodDeclaration", // private int test2(int x) {} - "MethodDeclaration", // static void test1() {} - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} - - "Pop", - "MethodInvocation", // Test.main([""]) - - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test - - "Deref", - "EvalVariable", // Test - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return; - - "Reset", // return - "Void", - - "Reset", // Skip Env from Block - ]; + 'CompilationUnit', + + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // public class Test {...} + + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // private int test2(int x) {} + 'MethodDeclaration', // static void test1() {} + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} + + 'Pop', + 'MethodInvocation', // Test.main([""]) + + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test + + 'Deref', + 'EvalVariable', // Test + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return; + + 'Reset', // return + 'Void', + + 'Reset' // Skip Env from Block + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "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); + '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 + ) // TODO test env - }); -}); + }) +}) diff --git a/src/ec-evaluator/__tests__/class-instance-creation.test.ts b/src/ec-evaluator/__tests__/class-instance-creation.test.ts index e25a4d4..a5e8f56 100644 --- a/src/ec-evaluator/__tests__/class-instance-creation.test.ts +++ b/src/ec-evaluator/__tests__/class-instance-creation.test.ts @@ -1,15 +1,15 @@ -import { parse } from "../../ast/parser"; -import { evaluate } from "../interpreter"; +import { parse } from '../../ast/parser' +import { evaluate } from '../interpreter' import { ControlStub, StashStub, createContextStub, getControlItemStr, getStashItemStr -} from "./__utils__/utils"; +} from './__utils__/utils' -describe("evaluate default constructor", () => { - it("evaluate default constructor without instance field initialization correctly", () => { +describe('evaluate default constructor', () => { + it('evaluate default constructor without instance field initialization correctly', () => { const programStr = ` class Test { int x; @@ -17,158 +17,158 @@ describe("evaluate default constructor", () => { Test test = new Test(); } } - `; - - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); - - const context = createContextStub(); - context.control.push(compilationUnit!); - - const result = evaluate(context); - + ` + + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() + + const context = createContextStub() + context.control.push(compilationUnit!) + + const result = evaluate(context) + const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class Test {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} - - "Env", // from NormalClassDeclaration - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} - - "Pop", - "MethodInvocation", // Test.main([""]) - - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test - - "Deref", - "EvalVariable", // Test - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return; - "LocalVariableDeclarationStatement", // Test test = new Test(); - - "ExpressionStatement", // test = new Test(); - "LocalVariableDeclarationStatement", // Test test; - - "Pop", - "Assignment", // test = new Test() - - "Assign", // = - "ClassInstanceCreationExpression", // new Test() - "EvalVariable", // test - - "Invocation", // () - "New", // new - "ResConOverload", // Test - "ResType", // Test - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return this; - "ExpressionStatement", // this.x = 0; - "ExplicitConstructorInvocation", // super(); - - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Object - "ResType", // super - - "Deref", - "EvalVariable", // super - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return this; - - "Reset", // return - "ExpressionName", // this - - "Deref", - "EvalVariable", // this - - "Reset", // Skip Env from Block - - "Pop", - "Assignment", // this.x = 0 - - "Assign", // = - "Literal", // 0 - "EvalVariable", // this.x - - "Res", // x - "EvalVariable", // this - - "Reset", // return - "ExpressionName", // this - - "Deref", - "EvalVariable", // this - - "Reset", // skip Env from Block - - "Reset", // return - "Void", - - "Reset", // skip Env from Block - ]; + 'CompilationUnit', + + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class Test {...} + + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} + + 'Pop', + 'MethodInvocation', // Test.main([""]) + + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test + + 'Deref', + 'EvalVariable', // Test + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return; + 'LocalVariableDeclarationStatement', // Test test = new Test(); + + 'ExpressionStatement', // test = new Test(); + 'LocalVariableDeclarationStatement', // Test test; + + 'Pop', + 'Assignment', // test = new Test() + + 'Assign', // = + 'ClassInstanceCreationExpression', // new Test() + 'EvalVariable', // test + + 'Invocation', // () + 'New', // new + 'ResConOverload', // Test + 'ResType', // Test + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExpressionStatement', // this.x = 0; + 'ExplicitConstructorInvocation', // super(); + + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Object + 'ResType', // super + + 'Deref', + 'EvalVariable', // super + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return this; + + 'Reset', // return + 'ExpressionName', // this + + 'Deref', + 'EvalVariable', // this + + 'Reset', // Skip Env from Block + + 'Pop', + 'Assignment', // this.x = 0 + + 'Assign', // = + 'Literal', // 0 + 'EvalVariable', // this.x + + 'Res', // x + 'EvalVariable', // this + + 'Reset', // return + 'ExpressionName', // this + + 'Deref', + 'EvalVariable', // this + + 'Reset', // skip Env from Block + + 'Reset', // return + 'Void', + + 'Reset' // skip Env from Block + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable, - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable, + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "test", // EvalVariable - "Test", // ResType - "Test", // ResConOverlaod - "Object", // New - "Object", // ResType - "Object", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "x", // Res - "0", // Literal - "0", // Assign - "this", // EvalVariable - "Object", // Deref - "Object", // Assign - "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); + 'test', // EvalVariable + 'Test', // ResType + 'Test', // ResConOverlaod + 'Object', // New + 'Object', // ResType + 'Object', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'x', // Res + '0', // Literal + '0', // Assign + 'this', // EvalVariable + 'Object', // Deref + 'Object', // Assign + '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 + ) // TODO test env - }); - - it("evaluate default constructor with instance field initialization correctly", () => { + }) + + it('evaluate default constructor with instance field initialization correctly', () => { const programStr = ` class Test { int x = 1; @@ -176,158 +176,158 @@ describe("evaluate default constructor", () => { Test test = new Test(); } } - `; - - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); - - const context = createContextStub(); - context.control.push(compilationUnit!); - - const result = evaluate(context); - + ` + + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() + + const context = createContextStub() + context.control.push(compilationUnit!) + + const result = evaluate(context) + const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class Test {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} - - "Env", // from NormalClassDeclaration - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} - - "Pop", - "MethodInvocation", // Test.main([""]) - - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test - - "Deref", - "EvalVariable", // Test - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return; - "LocalVariableDeclarationStatement", // Test test = new Test(); - - "ExpressionStatement", // test = new Test(); - "LocalVariableDeclarationStatement", // Test test; - - "Pop", - "Assignment", // test = new Test() - - "Assign", // = - "ClassInstanceCreationExpression", // new Test() - "EvalVariable", // test - - "Invocation", // () - "New", // new - "ResConOverload", // Test - "ResType", // Test - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return this; - "ExpressionStatement", // this.x = 1; - "ExplicitConstructorInvocation", // super(); - - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Object - "ResType", // super - - "Deref", - "EvalVariable", // super - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return this; - - "Reset", // return - "ExpressionName", // this - - "Deref", - "EvalVariable", // this - - "Reset", // Skip Env from Block - - "Pop", - "Assignment", // this.x = 1 - - "Assign", // = - "Literal", // 1 - "EvalVariable", // this.x - - "Res", // x - "EvalVariable", // this - - "Reset", // return - "ExpressionName", // this - - "Deref", - "EvalVariable", // this - - "Reset", // skip Env from Block - - "Reset", // return - "Void", - - "Reset", // skip Env from Block - ]; + 'CompilationUnit', + + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class Test {...} + + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} + + 'Pop', + 'MethodInvocation', // Test.main([""]) + + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test + + 'Deref', + 'EvalVariable', // Test + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return; + 'LocalVariableDeclarationStatement', // Test test = new Test(); + + 'ExpressionStatement', // test = new Test(); + 'LocalVariableDeclarationStatement', // Test test; + + 'Pop', + 'Assignment', // test = new Test() + + 'Assign', // = + 'ClassInstanceCreationExpression', // new Test() + 'EvalVariable', // test + + 'Invocation', // () + 'New', // new + 'ResConOverload', // Test + 'ResType', // Test + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExpressionStatement', // this.x = 1; + 'ExplicitConstructorInvocation', // super(); + + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Object + 'ResType', // super + + 'Deref', + 'EvalVariable', // super + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return this; + + 'Reset', // return + 'ExpressionName', // this + + 'Deref', + 'EvalVariable', // this + + 'Reset', // Skip Env from Block + + 'Pop', + 'Assignment', // this.x = 1 + + 'Assign', // = + 'Literal', // 1 + 'EvalVariable', // this.x + + 'Res', // x + 'EvalVariable', // this + + 'Reset', // return + 'ExpressionName', // this + + 'Deref', + 'EvalVariable', // this + + 'Reset', // skip Env from Block + + 'Reset', // return + 'Void', + + 'Reset' // skip Env from Block + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable, - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable, + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "test", // EvalVariable - "Test", // ResType - "Test", // ResConOverlaod - "Object", // New - "Object", // ResType - "Object", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "x", // Res - "1", // Literal - "1", // Assign - "this", // EvalVariable - "Object", // Deref - "Object", // Assign - "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); + 'test', // EvalVariable + 'Test', // ResType + 'Test', // ResConOverlaod + 'Object', // New + 'Object', // ResType + 'Object', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'x', // Res + '1', // Literal + '1', // Assign + 'this', // EvalVariable + 'Object', // Deref + 'Object', // Assign + '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 + ) // TODO test env - }); + }) - it("evaluate overriden default constructor without instance field initialization correctly", () => { + it('evaluate overriden default constructor without instance field initialization correctly', () => { const programStr = ` class Test { int x; @@ -338,173 +338,173 @@ describe("evaluate default constructor", () => { Test test = new Test(); } } - `; - - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); - - const context = createContextStub(); - context.control.push(compilationUnit!); - - const result = evaluate(context); - + ` + + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() + + const context = createContextStub() + context.control.push(compilationUnit!) + + const result = evaluate(context) + const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class Test {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} - - "Env", // from NormalClassDeclaration - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} - - "Pop", - "MethodInvocation", // Test.main([""]) - - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test - - "Deref", - "EvalVariable", // Test - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return; - "LocalVariableDeclarationStatement", // Test test = new Test(); - - "ExpressionStatement", // test = new Test(); - "LocalVariableDeclarationStatement", // Test test; - - "Pop", - "Assignment", // test = new Test() - - "Assign", // = - "ClassInstanceCreationExpression", // new Test() - "EvalVariable", // test - - "Invocation", // () - "New", // new - "ResConOverload", // Test - "ResType", // Test - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return this; - "ExpressionStatement", // this.x = 2; - "ExpressionStatement", // this.x = 0; - "ExplicitConstructorInvocation", // super(); - - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Object - "ResType", // super - - "Deref", - "EvalVariable", // super - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return this; - - "Reset", // return - "ExpressionName", // this - - "Deref", - "EvalVariable", // this - - "Reset", // Skip Env from Block - - "Pop", - "Assignment", // this.x = 0 - - "Assign", // = - "Literal", // 0 - "EvalVariable", // this.x - - "Res", // x - "EvalVariable", // this - - "Pop", - "Assignment", // this.x = 2 - - "Assign", // = - "Literal", // 2 - "EvalVariable", // this.x - - "Res", // x - "EvalVariable", // this - - "Reset", // return - "ExpressionName", // this - - "Deref", - "EvalVariable", // this - - "Reset", // skip Env from Block - - "Reset", // return - "Void", - - "Reset", // skip Env from Block - ]; + 'CompilationUnit', + + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class Test {...} + + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} + + 'Pop', + 'MethodInvocation', // Test.main([""]) + + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test + + 'Deref', + 'EvalVariable', // Test + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return; + 'LocalVariableDeclarationStatement', // Test test = new Test(); + + 'ExpressionStatement', // test = new Test(); + 'LocalVariableDeclarationStatement', // Test test; + + 'Pop', + 'Assignment', // test = new Test() + + 'Assign', // = + 'ClassInstanceCreationExpression', // new Test() + 'EvalVariable', // test + + 'Invocation', // () + 'New', // new + 'ResConOverload', // Test + 'ResType', // Test + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExpressionStatement', // this.x = 2; + 'ExpressionStatement', // this.x = 0; + 'ExplicitConstructorInvocation', // super(); + + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Object + 'ResType', // super + + 'Deref', + 'EvalVariable', // super + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return this; + + 'Reset', // return + 'ExpressionName', // this + + 'Deref', + 'EvalVariable', // this + + 'Reset', // Skip Env from Block + + 'Pop', + 'Assignment', // this.x = 0 + + 'Assign', // = + 'Literal', // 0 + 'EvalVariable', // this.x + + 'Res', // x + 'EvalVariable', // this + + 'Pop', + 'Assignment', // this.x = 2 + + 'Assign', // = + 'Literal', // 2 + 'EvalVariable', // this.x + + 'Res', // x + 'EvalVariable', // this + + 'Reset', // return + 'ExpressionName', // this + + 'Deref', + 'EvalVariable', // this + + 'Reset', // skip Env from Block + + 'Reset', // return + 'Void', + + 'Reset' // skip Env from Block + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable, - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable, + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "test", // EvalVariable - "Test", // ResType - "Test", // ResConOverlaod - "Object", // New - "Object", // ResType - "Object", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "x", // Res - "0", // Literal - "0", // Assign - "this", // EvalVariable - "x", // Res - "2", // Literal - "2", // Assign - "this", // EvalVariable - "Object", // Deref - "Object", // Assign - "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); + 'test', // EvalVariable + 'Test', // ResType + 'Test', // ResConOverlaod + 'Object', // New + 'Object', // ResType + 'Object', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'x', // Res + '0', // Literal + '0', // Assign + 'this', // EvalVariable + 'x', // Res + '2', // Literal + '2', // Assign + 'this', // EvalVariable + 'Object', // Deref + 'Object', // Assign + '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 + ) // TODO test env - }); + }) - it("evaluate overriden default constructor with instance field initialization correctly", () => { + it('evaluate overriden default constructor with instance field initialization correctly', () => { const programStr = ` class Test { int x = 1; @@ -515,173 +515,173 @@ describe("evaluate default constructor", () => { Test test = new Test(); } } - `; - - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); - - const context = createContextStub(); - context.control.push(compilationUnit!); - - const result = evaluate(context); - + ` + + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() + + const context = createContextStub() + context.control.push(compilationUnit!) + + const result = evaluate(context) + const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class Test {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} - - "Env", // from NormalClassDeclaration - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} - - "Pop", - "MethodInvocation", // Test.main([""]) - - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test - - "Deref", - "EvalVariable", // Test - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return; - "LocalVariableDeclarationStatement", // Test test = new Test(); - - "ExpressionStatement", // test = new Test(); - "LocalVariableDeclarationStatement", // Test test; - - "Pop", - "Assignment", // test = new Test() - - "Assign", // = - "ClassInstanceCreationExpression", // new Test() - "EvalVariable", // test - - "Invocation", // () - "New", // new - "ResConOverload", // Test - "ResType", // Test - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return this; - "ExpressionStatement", // this.x = 2; - "ExpressionStatement", // this.x = 1; - "ExplicitConstructorInvocation", // super(); - - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Object - "ResType", // super - - "Deref", - "EvalVariable", // super - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return this; - - "Reset", // return - "ExpressionName", // this - - "Deref", - "EvalVariable", // this - - "Reset", // Skip Env from Block - - "Pop", - "Assignment", // this.x = 1 - - "Assign", // = - "Literal", // 1 - "EvalVariable", // this.x - - "Res", // x - "EvalVariable", // this - - "Pop", - "Assignment", // x = 2 - - "Assign", // = - "Literal", // 2 - "EvalVariable", // this.x - - "Res", // x - "EvalVariable", // this - - "Reset", // return - "ExpressionName", // this - - "Deref", - "EvalVariable", // this - - "Reset", // skip Env from Block - - "Reset", // return - "Void", - - "Reset", // skip Env from Block - ]; + 'CompilationUnit', + + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class Test {...} + + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} + + 'Pop', + 'MethodInvocation', // Test.main([""]) + + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test + + 'Deref', + 'EvalVariable', // Test + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return; + 'LocalVariableDeclarationStatement', // Test test = new Test(); + + 'ExpressionStatement', // test = new Test(); + 'LocalVariableDeclarationStatement', // Test test; + + 'Pop', + 'Assignment', // test = new Test() + + 'Assign', // = + 'ClassInstanceCreationExpression', // new Test() + 'EvalVariable', // test + + 'Invocation', // () + 'New', // new + 'ResConOverload', // Test + 'ResType', // Test + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExpressionStatement', // this.x = 2; + 'ExpressionStatement', // this.x = 1; + 'ExplicitConstructorInvocation', // super(); + + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Object + 'ResType', // super + + 'Deref', + 'EvalVariable', // super + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return this; + + 'Reset', // return + 'ExpressionName', // this + + 'Deref', + 'EvalVariable', // this + + 'Reset', // Skip Env from Block + + 'Pop', + 'Assignment', // this.x = 1 + + 'Assign', // = + 'Literal', // 1 + 'EvalVariable', // this.x + + 'Res', // x + 'EvalVariable', // this + + 'Pop', + 'Assignment', // x = 2 + + 'Assign', // = + 'Literal', // 2 + 'EvalVariable', // this.x + + 'Res', // x + 'EvalVariable', // this + + 'Reset', // return + 'ExpressionName', // this + + 'Deref', + 'EvalVariable', // this + + 'Reset', // skip Env from Block + + 'Reset', // return + 'Void', + + 'Reset' // skip Env from Block + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable, - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable, + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "test", // EvalVariable - "Test", // ResType - "Test", // ResConOverlaod - "Object", // New - "Object", // ResType - "Object", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "x", // Res - "1", // Literal - "1", // Assign - "this", // EvalVariable - "x", // Res - "2", // Literal - "2", // Assign - "this", // EvalVariable - "Object", // Deref - "Object", // Assign - "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); + 'test', // EvalVariable + 'Test', // ResType + 'Test', // ResConOverlaod + 'Object', // New + 'Object', // ResType + 'Object', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'x', // Res + '1', // Literal + '1', // Assign + 'this', // EvalVariable + 'x', // Res + '2', // Literal + '2', // Assign + 'this', // EvalVariable + 'Object', // Deref + 'Object', // Assign + '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 + ) // TODO test env - }); + }) - it("evaluate overriden default constructor with ReturnStatement correctly", () => { + it('evaluate overriden default constructor with ReturnStatement correctly', () => { const programStr = ` class Test { int x; @@ -692,154 +692,154 @@ describe("evaluate default constructor", () => { Test test = new Test(); } } - `; - - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); - - const context = createContextStub(); - context.control.push(compilationUnit!); - - const result = evaluate(context); - + ` + + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() + + const context = createContextStub() + context.control.push(compilationUnit!) + + const result = evaluate(context) + const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class Test {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} - - "Env", // from NormalClassDeclaration - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} - - "Pop", - "MethodInvocation", // Test.main([""]) - - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test - - "Deref", - "EvalVariable", // Test - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return; - "LocalVariableDeclarationStatement", // Test test = new Test(); - - "ExpressionStatement", // test = new Test(); - "LocalVariableDeclarationStatement", // Test test; - - "Pop", - "Assignment", // test = new Test() - - "Assign", // = - "ClassInstanceCreationExpression", // new Test() - "EvalVariable", // test - - "Invocation", // () - "New", // new - "ResConOverload", // Test - "ResType", // Test - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return this; - "ExpressionStatement", // this.x = 0; - "ExplicitConstructorInvocation", // super(); - - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Object - "ResType", // super - - "Deref", - "EvalVariable", // super - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return this; - - "Reset", // return - "ExpressionName", // this - - "Deref", - "EvalVariable", // this - - "Reset", // Skip Env from Block - - "Pop", - "Assignment", // this.x = 0 - - "Assign", // = - "Literal", // 0 - "EvalVariable", // this.x - - "Res", // x - "EvalVariable", // this - - "Reset", // return - "ExpressionName", // this - - "Deref", - "EvalVariable", // this - - "Reset", // skip Env from Block - - "Reset", // return - "Void", - - "Reset", // skip Env from Block - ]; + 'CompilationUnit', + + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class Test {...} + + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} + + 'Pop', + 'MethodInvocation', // Test.main([""]) + + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test + + 'Deref', + 'EvalVariable', // Test + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return; + 'LocalVariableDeclarationStatement', // Test test = new Test(); + + 'ExpressionStatement', // test = new Test(); + 'LocalVariableDeclarationStatement', // Test test; + + 'Pop', + 'Assignment', // test = new Test() + + 'Assign', // = + 'ClassInstanceCreationExpression', // new Test() + 'EvalVariable', // test + + 'Invocation', // () + 'New', // new + 'ResConOverload', // Test + 'ResType', // Test + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExpressionStatement', // this.x = 0; + 'ExplicitConstructorInvocation', // super(); + + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Object + 'ResType', // super + + 'Deref', + 'EvalVariable', // super + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return this; + + 'Reset', // return + 'ExpressionName', // this + + 'Deref', + 'EvalVariable', // this + + 'Reset', // Skip Env from Block + + 'Pop', + 'Assignment', // this.x = 0 + + 'Assign', // = + 'Literal', // 0 + 'EvalVariable', // this.x + + 'Res', // x + 'EvalVariable', // this + + 'Reset', // return + 'ExpressionName', // this + + 'Deref', + 'EvalVariable', // this + + 'Reset', // skip Env from Block + + 'Reset', // return + 'Void', + + 'Reset' // skip Env from Block + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable, - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable, + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "test", // EvalVariable - "Test", // ResType - "Test", // ResConOverlaod - "Object", // New - "Object", // ResType - "Object", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "x", // Res - "0", // Literal - "0", // Assign - "this", // EvalVariable - "Object", // Deref - "Object", // Assign - "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); + 'test', // EvalVariable + 'Test', // ResType + 'Test', // ResConOverlaod + 'Object', // New + 'Object', // ResType + 'Object', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'x', // Res + '0', // Literal + '0', // Assign + 'this', // EvalVariable + 'Object', // Deref + 'Object', // Assign + '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 + ) // TODO test env - }); -}); + }) +}) diff --git a/src/ec-evaluator/__tests__/constructor-overloading.test.ts b/src/ec-evaluator/__tests__/constructor-overloading.test.ts index ec7d2b9..10b27e6 100644 --- a/src/ec-evaluator/__tests__/constructor-overloading.test.ts +++ b/src/ec-evaluator/__tests__/constructor-overloading.test.ts @@ -1,15 +1,15 @@ -import { parse } from "../../ast/parser"; -import { evaluate } from "../interpreter"; +import { parse } from '../../ast/parser' +import { evaluate } from '../interpreter' import { ControlStub, StashStub, createContextStub, getControlItemStr, getStashItemStr -} from "./__utils__/utils"; +} from './__utils__/utils' -describe("evaluate constructor overloading resolution correctly", () => { - it("evaluate superclass constructor invocation correctly", () => { +describe('evaluate constructor overloading resolution correctly', () => { + it('evaluate superclass constructor invocation correctly', () => { const programStr = ` class Parent { int x; @@ -28,218 +28,218 @@ describe("evaluate constructor overloading resolution correctly", () => { Test t = new Test(); } } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class Test extends Parent {...} - "NormalClassDeclaration", // class Parent {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Parent(Parent p) {...} - "ConstructorDeclaration", // Parent(int p) {...} - "ConstructorDeclaration", // Parent() {...} - - "Env", // from NormalClassDeclaration - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} - - "Pop", - "MethodInvocation", // Test.main([""]) - - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test - - "Deref", - "EvalVariable", // Test - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return; - "LocalVariableDeclarationStatement", // Test t = new Test(); - - "ExpressionStatement", // t = new Test(); - "LocalVariableDeclarationStatement", // Test t; - - "Pop", - "Assignment", // t = new Test() - - "Assign", // = - "ClassInstanceCreationExpression", // new Test() - "EvalVariable", // t + 'CompilationUnit', + + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class Test extends Parent {...} + 'NormalClassDeclaration', // class Parent {...} - "Invocation", // () - "New", // new - "ResConOverload", // Test - "ResType", // Test - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return this; - "ExplicitConstructorInvocation", // super(2); - - "Pop", - "Invocation", // () - "Literal", // 2 - "ExpressionName", // super - "ResConOverload", // Parent - "ResType", // 2 - "ResType", // super - - "Deref", - "EvalVariable", // super - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return this; - "ExpressionStatement", // this.x = p; - "ExpressionStatement", // this.x = 0; - "ExplicitConstructorInvocation", // super(); - - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Object - "ResType", // super - - "Deref", - "EvalVariable", // super - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return this; - - "Reset", // return - "ExpressionName", // this + 'Env', // from NormalClassDeclaration + 'ConstructorDeclaration', // Parent(Parent p) {...} + 'ConstructorDeclaration', // Parent(int p) {...} + 'ConstructorDeclaration', // Parent() {...} - "Deref", - "EvalVariable", // this + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} - "Reset", // Skip Env from Block + 'Pop', + 'MethodInvocation', // Test.main([""]) - "Pop", - "Assignment", // this.x = 0 + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test - "Assign", // = - "Literal", // 0 - "EvalVariable", // this.x + 'Deref', + 'EvalVariable', // Test - "Res", // x - "EvalVariable", // this - - "Pop", - "Assignment", // this.x = p + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Assign", // = - "ExpressionName", // p - "EvalVariable", // this.x + 'Env', // from Block + 'ReturnStatement', // return; + 'LocalVariableDeclarationStatement', // Test t = new Test(); - "Res", // x - "EvalVariable", // this - - "Deref", - "EvalVariable", // p + 'ExpressionStatement', // t = new Test(); + 'LocalVariableDeclarationStatement', // Test t; - "Reset", // return - "ExpressionName", // this + 'Pop', + 'Assignment', // t = new Test() - "Deref", - "EvalVariable", // this + 'Assign', // = + 'ClassInstanceCreationExpression', // new Test() + 'EvalVariable', // t - "Reset", // Skip Env from Block + 'Invocation', // () + 'New', // new + 'ResConOverload', // Test + 'ResType', // Test - "Reset", // return - "ExpressionName", // this + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Deref", - "EvalVariable", // this + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExplicitConstructorInvocation', // super(2); - "Reset", // Skip Env from Block + 'Pop', + 'Invocation', // () + 'Literal', // 2 + 'ExpressionName', // super + 'ResConOverload', // Parent + 'ResType', // 2 + 'ResType', // super - "Reset", // return - "Void", + 'Deref', + 'EvalVariable', // super - "Reset", // Skip Env from Block - ]; + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExpressionStatement', // this.x = p; + 'ExpressionStatement', // this.x = 0; + 'ExplicitConstructorInvocation', // super(); + + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Object + 'ResType', // super + + 'Deref', + 'EvalVariable', // super + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return this; + + 'Reset', // return + 'ExpressionName', // this + + 'Deref', + 'EvalVariable', // this + + 'Reset', // Skip Env from Block + + 'Pop', + 'Assignment', // this.x = 0 + + 'Assign', // = + 'Literal', // 0 + 'EvalVariable', // this.x + + 'Res', // x + 'EvalVariable', // this + + 'Pop', + 'Assignment', // this.x = p + + 'Assign', // = + 'ExpressionName', // p + 'EvalVariable', // this.x + + 'Res', // x + 'EvalVariable', // this + + 'Deref', + 'EvalVariable', // p + + 'Reset', // return + 'ExpressionName', // this + + 'Deref', + 'EvalVariable', // this + + 'Reset', // Skip Env from Block + + 'Reset', // return + 'ExpressionName', // this + + 'Deref', + 'EvalVariable', // this + + 'Reset', // Skip Env from Block + + 'Reset', // return + 'Void', + + 'Reset' // Skip Env from Block + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "t", // EvalVariable - "Test", // ResType - "Test", // ResConOverload - "Object", // New - "Parent", // ResType - "int", // ResType - "Parent", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "2", // Literal - "Object", // ResType - "Object", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "x", // Res - "0", // Literal - "0", // Assign - "this", // EvalVariable - "x", // Res - "p", // EvalVariable - "2", // Deref - "2", // Assign - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "Object", // Assign - "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); + 't', // EvalVariable + 'Test', // ResType + 'Test', // ResConOverload + 'Object', // New + 'Parent', // ResType + 'int', // ResType + 'Parent', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + '2', // Literal + 'Object', // ResType + 'Object', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'x', // Res + '0', // Literal + '0', // Assign + 'this', // EvalVariable + 'x', // Res + 'p', // EvalVariable + '2', // Deref + '2', // Assign + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'Object', // Assign + '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 + ) // TODO test env - }); + }) - it("should resolve to Test(int x) instead of default constructor", () => { + it('should resolve to Test(int x) instead of default constructor', () => { const programStr = ` class Test { int x; @@ -250,182 +250,182 @@ describe("evaluate constructor overloading resolution correctly", () => { Test test = new Test(1); } } - `; - - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); - - const context = createContextStub(); - context.control.push(compilationUnit!); - - const result = evaluate(context); - + ` + + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() + + const context = createContextStub() + context.control.push(compilationUnit!) + + const result = evaluate(context) + const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class Test {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} - - "Env", // from NormalClassDeclaration - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} - "ConstructorDeclaration", // Test(int x) {...} - - "Pop", - "MethodInvocation", // Test.main([""]) - - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test - - "Deref", - "EvalVariable", // Test - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return; - "LocalVariableDeclarationStatement", // Test test = new Test(1); - - "ExpressionStatement", // test = new Test(1); - "LocalVariableDeclarationStatement", // Test test; - - "Pop", - "Assignment", // test = new Test(1) - - "Assign", // = - "ClassInstanceCreationExpression", // new Test(1) - "EvalVariable", // test - - "Invocation", // () - "Literal", // 1 - "New", // new - "ResConOverload", // Test - "ResType", // 1 - "ResType", // Test - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return this; - "ExpressionStatement", // this.x = x; - "ExpressionStatement", // this.x = 0; - "ExplicitConstructorInvocation", // super(); - - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Object - "ResType", // super - - "Deref", - "EvalVariable", // super - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return this; - - "Reset", // return - "ExpressionName", // this - - "Deref", - "EvalVariable", // this - - "Reset", // Skip Env from Block - - "Pop", - "Assignment", // this.x = 0 - - "Assign", // = - "Literal", // 0 - "EvalVariable", // this.x - - "Res", // x - "EvalVariable", // this - - "Pop", - "Assignment", // this.x = x; - - "Assign", // = - "ExpressionName", // x - "EvalVariable", // this.x - - "Res", // x - "EvalVariable", // this - - "Deref", - "EvalVariable", // x - - "Reset", // return - "ExpressionName", // this - - "Deref", - "EvalVariable", // this - - "Reset", // skip Env from Block - - "Reset", // return - "Void", - - "Reset", // skip Env from Block - ]; + 'CompilationUnit', + + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class Test {...} + + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} + 'ConstructorDeclaration', // Test(int x) {...} + + 'Pop', + 'MethodInvocation', // Test.main([""]) + + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test + + 'Deref', + 'EvalVariable', // Test + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return; + 'LocalVariableDeclarationStatement', // Test test = new Test(1); + + 'ExpressionStatement', // test = new Test(1); + 'LocalVariableDeclarationStatement', // Test test; + + 'Pop', + 'Assignment', // test = new Test(1) + + 'Assign', // = + 'ClassInstanceCreationExpression', // new Test(1) + 'EvalVariable', // test + + 'Invocation', // () + 'Literal', // 1 + 'New', // new + 'ResConOverload', // Test + 'ResType', // 1 + 'ResType', // Test + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExpressionStatement', // this.x = x; + 'ExpressionStatement', // this.x = 0; + 'ExplicitConstructorInvocation', // super(); + + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Object + 'ResType', // super + + 'Deref', + 'EvalVariable', // super + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return this; + + 'Reset', // return + 'ExpressionName', // this + + 'Deref', + 'EvalVariable', // this + + 'Reset', // Skip Env from Block + + 'Pop', + 'Assignment', // this.x = 0 + + 'Assign', // = + 'Literal', // 0 + 'EvalVariable', // this.x + + 'Res', // x + 'EvalVariable', // this + + 'Pop', + 'Assignment', // this.x = x; + + 'Assign', // = + 'ExpressionName', // x + 'EvalVariable', // this.x + + 'Res', // x + 'EvalVariable', // this + + 'Deref', + 'EvalVariable', // x + + 'Reset', // return + 'ExpressionName', // this + + 'Deref', + 'EvalVariable', // this + + 'Reset', // skip Env from Block + + 'Reset', // return + 'Void', + + 'Reset' // skip Env from Block + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable, - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable, + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "test", // EvalVariable - "Test", // ResType - "int", // ResType - "Test", // ResConOverlaod - "Object", // New - "1", // Literal - "Object", // ResType - "Object", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "x", // Res - "0", // Literal - "0", // Assign - "this", // EvalVariable - "x", // Res - "x", // EvalVariable - "1", // Deref - "1", // Assign - "this", // EvalVariable - "Object", // Deref - "Object", // Assign - "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); + 'test', // EvalVariable + 'Test', // ResType + 'int', // ResType + 'Test', // ResConOverlaod + 'Object', // New + '1', // Literal + 'Object', // ResType + 'Object', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'x', // Res + '0', // Literal + '0', // Assign + 'this', // EvalVariable + 'x', // Res + 'x', // EvalVariable + '1', // Deref + '1', // Assign + 'this', // EvalVariable + 'Object', // Deref + 'Object', // Assign + '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 + ) // TODO test env - }); + }) - it("should resolve to Test(int x) instead of method with similar descriptor", () => { + it('should resolve to Test(int x) instead of method with similar descriptor', () => { const programStr = ` class Test { int x; @@ -439,183 +439,183 @@ describe("evaluate constructor overloading resolution correctly", () => { return new Test(x + 1); } } - `; - - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); - - const context = createContextStub(); - context.control.push(compilationUnit!); - - const result = evaluate(context); - + ` + + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() + + const context = createContextStub() + context.control.push(compilationUnit!) + + const result = evaluate(context) + const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class Test {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} - - "Env", // from NormalClassDeclaration - "MethodDeclaration", // Test Test(int x) {...} - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} - "ConstructorDeclaration", // Test(int x) {...} - - "Pop", - "MethodInvocation", // Test.main([""]) - - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test - - "Deref", - "EvalVariable", // Test - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return; - "LocalVariableDeclarationStatement", // Test test = new Test(1); - - "ExpressionStatement", // test = new Test(1); - "LocalVariableDeclarationStatement", // Test test; - - "Pop", - "Assignment", // test = new Test(1) - - "Assign", // = - "ClassInstanceCreationExpression", // new Test(1) - "EvalVariable", // test - - "Invocation", // () - "Literal", // 1 - "New", // new - "ResConOverload", // Test - "ResType", // 1 - "ResType", // Test - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return this; - "ExpressionStatement", // this.x = x; - "ExpressionStatement", // this.x = 0; - "ExplicitConstructorInvocation", // super(); - - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Object - "ResType", // super - - "Deref", - "EvalVariable", // super - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return this; - - "Reset", // return - "ExpressionName", // this - - "Deref", - "EvalVariable", // this - - "Reset", // Skip Env from Block - - "Pop", - "Assignment", // this.x = 0 - - "Assign", // = - "Literal", // 0 - "EvalVariable", // this.x - - "Res", // x - "EvalVariable", // this - - "Pop", - "Assignment", // this.x = x; - - "Assign", // = - "ExpressionName", // x - "EvalVariable", // this.x - - "Res", // x - "EvalVariable", // this - - "Deref", - "EvalVariable", // x - - "Reset", // return - "ExpressionName", // this - - "Deref", - "EvalVariable", // this - - "Reset", // skip Env from Block - - "Reset", // return - "Void", - - "Reset", // skip Env from Block - ]; + 'CompilationUnit', + + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class Test {...} + + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // Test Test(int x) {...} + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} + 'ConstructorDeclaration', // Test(int x) {...} + + 'Pop', + 'MethodInvocation', // Test.main([""]) + + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test + + 'Deref', + 'EvalVariable', // Test + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return; + 'LocalVariableDeclarationStatement', // Test test = new Test(1); + + 'ExpressionStatement', // test = new Test(1); + 'LocalVariableDeclarationStatement', // Test test; + + 'Pop', + 'Assignment', // test = new Test(1) + + 'Assign', // = + 'ClassInstanceCreationExpression', // new Test(1) + 'EvalVariable', // test + + 'Invocation', // () + 'Literal', // 1 + 'New', // new + 'ResConOverload', // Test + 'ResType', // 1 + 'ResType', // Test + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExpressionStatement', // this.x = x; + 'ExpressionStatement', // this.x = 0; + 'ExplicitConstructorInvocation', // super(); + + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Object + 'ResType', // super + + 'Deref', + 'EvalVariable', // super + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return this; + + 'Reset', // return + 'ExpressionName', // this + + 'Deref', + 'EvalVariable', // this + + 'Reset', // Skip Env from Block + + 'Pop', + 'Assignment', // this.x = 0 + + 'Assign', // = + 'Literal', // 0 + 'EvalVariable', // this.x + + 'Res', // x + 'EvalVariable', // this + + 'Pop', + 'Assignment', // this.x = x; + + 'Assign', // = + 'ExpressionName', // x + 'EvalVariable', // this.x + + 'Res', // x + 'EvalVariable', // this + + 'Deref', + 'EvalVariable', // x + + 'Reset', // return + 'ExpressionName', // this + + 'Deref', + 'EvalVariable', // this + + 'Reset', // skip Env from Block + + 'Reset', // return + 'Void', + + 'Reset' // skip Env from Block + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable, - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable, + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "test", // EvalVariable - "Test", // ResType - "int", // ResType - "Test", // ResConOverlaod - "Object", // New - "1", // Literal - "Object", // ResType - "Object", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "x", // Res - "0", // Literal - "0", // Assign - "this", // EvalVariable - "x", // Res - "x", // EvalVariable - "1", // Deref - "1", // Assign - "this", // EvalVariable - "Object", // Deref - "Object", // Assign - "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); + 'test', // EvalVariable + 'Test', // ResType + 'int', // ResType + 'Test', // ResConOverlaod + 'Object', // New + '1', // Literal + 'Object', // ResType + 'Object', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'x', // Res + '0', // Literal + '0', // Assign + 'this', // EvalVariable + 'x', // Res + 'x', // EvalVariable + '1', // Deref + '1', // Assign + 'this', // EvalVariable + 'Object', // Deref + 'Object', // Assign + '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 + ) // TODO test env - }); + }) - it("evaluate alternate constructor invocation correctly", () => { + it('evaluate alternate constructor invocation correctly', () => { const programStr = ` class Test { int x; @@ -629,209 +629,209 @@ describe("evaluate constructor overloading resolution correctly", () => { Test test = new Test(); } } - `; - - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); - - const context = createContextStub(); - context.control.push(compilationUnit!); - - const result = evaluate(context); - + ` + + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() + + const context = createContextStub() + context.control.push(compilationUnit!) + + const result = evaluate(context) + const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class Test {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} - - "Env", // from NormalClassDeclaration - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} - "ConstructorDeclaration", // Test(int x) {...} - - "Pop", - "MethodInvocation", // Test.main([""]) - - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test - - "Deref", - "EvalVariable", // Test - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return; - "LocalVariableDeclarationStatement", // Test test = new Test(); - - "ExpressionStatement", // test = new Test(); - "LocalVariableDeclarationStatement", // Test test; - - "Pop", - "Assignment", // test = new Test() - - "Assign", // = - "ClassInstanceCreationExpression", // new Test() - "EvalVariable", // test - - "Invocation", // () - "New", // new - "ResConOverload", // Test - "ResType", // Test - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return this; - "ExplicitConstructorInvocation", // this(1); - - "Pop", - "Invocation", // () - "Literal", // 1 - "ExpressionName", // this - "ResConOverload", // Test - "ResType", // 1 - "ResType", // this - - "Deref", - "EvalVariable", // this - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return this; - "ExpressionStatement", // this.x = x; - "ExpressionStatement", // this.x = 0; - "ExplicitConstructorInvocation", // super(); - - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Object - "ResType", // super - - "Deref", - "EvalVariable", // super - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return this; - - "Reset", // return - "ExpressionName", // this - - "Deref", - "EvalVariable", // this - - "Reset", // Skip Env from Block - - "Pop", - "Assignment", // this.x = 0 - - "Assign", // = - "Literal", // 0 - "EvalVariable", // this.x - - "Res", // x - "EvalVariable", // this - - "Pop", - "Assignment", // this.x = x; - - "Assign", // = - "ExpressionName", // x - "EvalVariable", // this.x - - "Res", // x - "EvalVariable", // this - - "Deref", - "EvalVariable", // x - - "Reset", // return - "ExpressionName", // this - - "Deref", - "EvalVariable", // this - - "Reset", // skip Env from Block - - "Reset", // return - "ExpressionName", // this - - "Deref", - "EvalVariable", // this - - "Reset", // skip Env from Block - - "Reset", // return - "Void", - - "Reset", // skip Env from Block - ]; + 'CompilationUnit', + + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class Test {...} + + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} + 'ConstructorDeclaration', // Test(int x) {...} + + 'Pop', + 'MethodInvocation', // Test.main([""]) + + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test + + 'Deref', + 'EvalVariable', // Test + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return; + 'LocalVariableDeclarationStatement', // Test test = new Test(); + + 'ExpressionStatement', // test = new Test(); + 'LocalVariableDeclarationStatement', // Test test; + + 'Pop', + 'Assignment', // test = new Test() + + 'Assign', // = + 'ClassInstanceCreationExpression', // new Test() + 'EvalVariable', // test + + 'Invocation', // () + 'New', // new + 'ResConOverload', // Test + 'ResType', // Test + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExplicitConstructorInvocation', // this(1); + + 'Pop', + 'Invocation', // () + 'Literal', // 1 + 'ExpressionName', // this + 'ResConOverload', // Test + 'ResType', // 1 + 'ResType', // this + + 'Deref', + 'EvalVariable', // this + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExpressionStatement', // this.x = x; + 'ExpressionStatement', // this.x = 0; + 'ExplicitConstructorInvocation', // super(); + + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Object + 'ResType', // super + + 'Deref', + 'EvalVariable', // super + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return this; + + 'Reset', // return + 'ExpressionName', // this + + 'Deref', + 'EvalVariable', // this + + 'Reset', // Skip Env from Block + + 'Pop', + 'Assignment', // this.x = 0 + + 'Assign', // = + 'Literal', // 0 + 'EvalVariable', // this.x + + 'Res', // x + 'EvalVariable', // this + + 'Pop', + 'Assignment', // this.x = x; + + 'Assign', // = + 'ExpressionName', // x + 'EvalVariable', // this.x + + 'Res', // x + 'EvalVariable', // this + + 'Deref', + 'EvalVariable', // x + + 'Reset', // return + 'ExpressionName', // this + + 'Deref', + 'EvalVariable', // this + + 'Reset', // skip Env from Block + + 'Reset', // return + 'ExpressionName', // this + + 'Deref', + 'EvalVariable', // this + + 'Reset', // skip Env from Block + + 'Reset', // return + 'Void', + + 'Reset' // skip Env from Block + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable, - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable, + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "test", // EvalVariable - "Test", // ResType - "Test", // ResConOverlaod - "Object", // New - "Test", // ResType - "int", // ResType - "Test", // ResConOverload - "this", // EvalVariable - "Object", // Deref - "1", // Literal - "Object", // ResType - "Object", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "x", // Res - "0", // Literal - "0", // Assign - "this", // EvalVariable - "x", // Res - "x", // EvalVariable - "1", // Deref - "1", // Assign - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "Object", // Assign - "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); + 'test', // EvalVariable + 'Test', // ResType + 'Test', // ResConOverlaod + 'Object', // New + 'Test', // ResType + 'int', // ResType + 'Test', // ResConOverload + 'this', // EvalVariable + 'Object', // Deref + '1', // Literal + 'Object', // ResType + 'Object', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'x', // Res + '0', // Literal + '0', // Assign + 'this', // EvalVariable + 'x', // Res + 'x', // EvalVariable + '1', // Deref + '1', // Assign + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'Object', // Assign + '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 + ) // TODO test env - }); -}); + }) +}) diff --git a/src/ec-evaluator/__tests__/inheritance-instance-field.test.ts b/src/ec-evaluator/__tests__/inheritance-instance-field.test.ts index a4d9563..bd1ba9d 100644 --- a/src/ec-evaluator/__tests__/inheritance-instance-field.test.ts +++ b/src/ec-evaluator/__tests__/inheritance-instance-field.test.ts @@ -1,16 +1,16 @@ -import { parse } from "../../ast/parser"; -import { UndeclaredVariableError } from "../errors"; -import { evaluate } from "../interpreter"; +import { parse } from '../../ast/parser' +import { UndeclaredVariableError } from '../errors' +import { evaluate } from '../interpreter' import { ControlStub, StashStub, createContextStub, getControlItemStr, getStashItemStr -} from "./__utils__/utils"; +} from './__utils__/utils' -describe("evaluate instance fields with inheritance", () => { - it("evaluate inherited instance field via simple name correctly", () => { +describe('evaluate instance fields with inheritance', () => { + it('evaluate inherited instance field via simple name correctly', () => { const programStr = ` class Parent { int x = 1; @@ -25,249 +25,249 @@ describe("evaluate instance fields with inheritance", () => { int y = x; } } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class Test extends Parent {...} - "NormalClassDeclaration", // class Parent {...} - "NormalClassDeclaration", // class Object {...} + 'CompilationUnit', - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class Test extends Parent {...} + 'NormalClassDeclaration', // class Parent {...} - "Env", // from NormalClassDeclaration - "MethodDeclaration", // void test() {...} - "ConstructorDeclaration", // Parent() {...} + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // void test() {...} + 'ConstructorDeclaration', // Parent() {...} - "Env", // from NormalClassDeclaration - "MethodDeclaration", // void test() {...} - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // void test() {...} + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} - "Pop", - "MethodInvocation", // Test.main([""]) + 'Pop', + 'MethodInvocation', // Test.main([""]) - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test - "Deref", - "EvalVariable", // Test + 'Deref', + 'EvalVariable', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; - "ExpressionStatement", // p.test(); - "LocalVariableDeclarationStatement", // Parent p = new Test(); + 'Env', // from Block + 'ReturnStatement', // return; + 'ExpressionStatement', // p.test(); + 'LocalVariableDeclarationStatement', // Parent p = new Test(); - "ExpressionStatement", // p = new Test(); - "LocalVariableDeclarationStatement", // Parent p; + 'ExpressionStatement', // p = new Test(); + 'LocalVariableDeclarationStatement', // Parent p; - "Pop", - "Assignment", // p = new Test() + 'Pop', + 'Assignment', // p = new Test() - "Assign", // = - "ClassInstanceCreationExpression", // new Test() - "EvalVariable", // p + 'Assign', // = + 'ClassInstanceCreationExpression', // new Test() + 'EvalVariable', // p - "Invocation", // () - "New", // new - "ResConOverload", // Test - "ResType", // Test + 'Invocation', // () + 'New', // new + 'ResConOverload', // Test + 'ResType', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; - "ExplicitConstructorInvocation", // super(); + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExplicitConstructorInvocation', // super(); - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Parent - "ResType", // super + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Parent + 'ResType', // super - "Deref", - "EvalVariable", // super + 'Deref', + 'EvalVariable', // super - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; - "ExpressionStatement", // this.x = 1; - "ExplicitConstructorInvocation", // super(); + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExpressionStatement', // this.x = 1; + 'ExplicitConstructorInvocation', // super(); - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Object - "ResType", // super + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Object + 'ResType', // super - "Deref", - "EvalVariable", // super + 'Deref', + 'EvalVariable', // super - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; + 'Env', // from Block + 'ReturnStatement', // return this; - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "Pop", - "Assignment", // this.x = 1 + 'Pop', + 'Assignment', // this.x = 1 - "Assign", // = - "Literal", // 1 - "EvalVariable", // this.x + 'Assign', // = + 'Literal', // 1 + 'EvalVariable', // this.x - "Res", // x - "EvalVariable", // this + 'Res', // x + 'EvalVariable', // this - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "Pop", - "MethodInvocation", // p.test() + 'Pop', + 'MethodInvocation', // p.test() - "Invocation", // () - "ResOverride", - "ExpressionName", // p - "ResOverload", // test - "ResType", // p + 'Invocation', // () + 'ResOverride', + 'ExpressionName', // p + 'ResOverload', // test + 'ResType', // p - "Deref", - "EvalVariable", // p + 'Deref', + 'EvalVariable', // p - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; - "LocalVariableDeclarationStatement", // int y = this.x; + 'Env', // from Block + 'ReturnStatement', // return; + 'LocalVariableDeclarationStatement', // int y = this.x; - "ExpressionStatement", // y = this.x; - "LocalVariableDeclarationStatement", // int y + 'ExpressionStatement', // y = this.x; + 'LocalVariableDeclarationStatement', // int y - "Pop", - "Assignment", // y = this.x + 'Pop', + 'Assignment', // y = this.x - "Assign", // = - "ExpressionName", // this.x - "EvalVariable", // y + 'Assign', // = + 'ExpressionName', // this.x + 'EvalVariable', // y - "Deref", - "EvalVariable", // this.x + 'Deref', + 'EvalVariable', // this.x - "Res", // x - "EvalVariable", // this + 'Res', // x + 'EvalVariable', // this - "Reset", // return - "Void", + 'Reset', // return + 'Void', - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "Reset", // return - "Void", + 'Reset', // return + 'Void', - "Reset", // Skip Env from Block - ]; + 'Reset' // Skip Env from Block + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "p", // EvalVariable - "Test", // ResType - "Test", // ResConOverload - "Object", // New - "Parent", // ResType - "Parent", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "Object", // ResType - "Object", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "x", // Res - "1", // Literal - "1", // Assign - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "Object", // Assign - "Parent", // ResType - "test", // ResOverload - "p", // EvalVariable - "Object", // Deref - "test", // ResOverride - "Object", - "y", // EvalVariable - "this", // EvalVariable - "x", // Res - "1", // Deref - "1", // Assign - "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); + 'p', // EvalVariable + 'Test', // ResType + 'Test', // ResConOverload + 'Object', // New + 'Parent', // ResType + 'Parent', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'Object', // ResType + 'Object', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'x', // Res + '1', // Literal + '1', // Assign + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'Object', // Assign + 'Parent', // ResType + 'test', // ResOverload + 'p', // EvalVariable + 'Object', // Deref + 'test', // ResOverride + 'Object', + 'y', // EvalVariable + 'this', // EvalVariable + 'x', // Res + '1', // Deref + '1', // Assign + '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 + ) // TODO test env - }); + }) - it("evaluate shadowed instance field via simple name correctly", () => { + it('evaluate shadowed instance field via simple name correctly', () => { const programStr = ` class Parent { int x = 1; @@ -283,265 +283,265 @@ describe("evaluate instance fields with inheritance", () => { int y = x; // 2 } } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class Test extends Parent {...} - "NormalClassDeclaration", // class Parent {...} - "NormalClassDeclaration", // class Object {...} + 'CompilationUnit', - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class Test extends Parent {...} + 'NormalClassDeclaration', // class Parent {...} - "Env", // from NormalClassDeclaration - "MethodDeclaration", // void test() {...} - "ConstructorDeclaration", // Parent() {...} + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // void test() {...} + 'ConstructorDeclaration', // Parent() {...} - "Env", // from NormalClassDeclaration - "MethodDeclaration", // void test() {...} - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // void test() {...} + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} - "Pop", - "MethodInvocation", // Test.main([""]) + 'Pop', + 'MethodInvocation', // Test.main([""]) - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test - "Deref", - "EvalVariable", // Test + 'Deref', + 'EvalVariable', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; - "ExpressionStatement", // p.test(); - "LocalVariableDeclarationStatement", // Parent p = new Test(); + 'Env', // from Block + 'ReturnStatement', // return; + 'ExpressionStatement', // p.test(); + 'LocalVariableDeclarationStatement', // Parent p = new Test(); - "ExpressionStatement", // p = new Test(); - "LocalVariableDeclarationStatement", // Parent p; + 'ExpressionStatement', // p = new Test(); + 'LocalVariableDeclarationStatement', // Parent p; - "Pop", - "Assignment", // p = new Test() + 'Pop', + 'Assignment', // p = new Test() - "Assign", // = - "ClassInstanceCreationExpression", // new Test() - "EvalVariable", // p + 'Assign', // = + 'ClassInstanceCreationExpression', // new Test() + 'EvalVariable', // p - "Invocation", // () - "New", // new - "ResConOverload", // Test - "ResType", // Test + 'Invocation', // () + 'New', // new + 'ResConOverload', // Test + 'ResType', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; - "ExpressionStatement", // this.x = 2; + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExpressionStatement', // this.x = 2; - "ExplicitConstructorInvocation", // super(); + 'ExplicitConstructorInvocation', // super(); - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Parent - "ResType", // super + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Parent + 'ResType', // super - "Deref", - "EvalVariable", // super + 'Deref', + 'EvalVariable', // super - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; - "ExpressionStatement", // this.x = 1; - "ExplicitConstructorInvocation", // super(); + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExpressionStatement', // this.x = 1; + 'ExplicitConstructorInvocation', // super(); - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Object - "ResType", // super + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Object + 'ResType', // super - "Deref", - "EvalVariable", // super + 'Deref', + 'EvalVariable', // super - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; + 'Env', // from Block + 'ReturnStatement', // return this; - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "Pop", - "Assignment", // this.x = 1 + 'Pop', + 'Assignment', // this.x = 1 - "Assign", // = - "Literal", // 1 - "EvalVariable", // this.x + 'Assign', // = + 'Literal', // 1 + 'EvalVariable', // this.x - "Res", // x - "EvalVariable", // this + 'Res', // x + 'EvalVariable', // this - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "Pop", - "Assignment", // this.x = 2 + 'Pop', + 'Assignment', // this.x = 2 - "Assign", // = - "Literal", // 2 - "EvalVariable", // this.x + 'Assign', // = + 'Literal', // 2 + 'EvalVariable', // this.x - "Res", // x - "EvalVariable", // this + 'Res', // x + 'EvalVariable', // this - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "Pop", - "MethodInvocation", // p.test() + 'Pop', + 'MethodInvocation', // p.test() - "Invocation", // () - "ResOverride", - "ExpressionName", // p - "ResOverload", // test - "ResType", // p + 'Invocation', // () + 'ResOverride', + 'ExpressionName', // p + 'ResOverload', // test + 'ResType', // p - "Deref", - "EvalVariable", // p + 'Deref', + 'EvalVariable', // p - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; - "LocalVariableDeclarationStatement", // int y = this.x; + 'Env', // from Block + 'ReturnStatement', // return; + 'LocalVariableDeclarationStatement', // int y = this.x; - "ExpressionStatement", // y = this.x; - "LocalVariableDeclarationStatement", // int y + 'ExpressionStatement', // y = this.x; + 'LocalVariableDeclarationStatement', // int y - "Pop", - "Assignment", // y = this.x + 'Pop', + 'Assignment', // y = this.x - "Assign", // = - "ExpressionName", // this.x - "EvalVariable", // y + 'Assign', // = + 'ExpressionName', // this.x + 'EvalVariable', // y - "Deref", - "EvalVariable", // this.x + 'Deref', + 'EvalVariable', // this.x - "Res", // x - "EvalVariable", // this + 'Res', // x + 'EvalVariable', // this - "Reset", // return - "Void", + 'Reset', // return + 'Void', - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "Reset", // return - "Void", + 'Reset', // return + 'Void', - "Reset", // Skip Env from Block - ]; + 'Reset' // Skip Env from Block + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "p", // EvalVariable - "Test", // ResType - "Test", // ResConOverload - "Object", // New - "Parent", // ResType - "Parent", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "Object", // ResType - "Object", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "x", // Res - "1", // Literal - "1", // Assign - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "x", // Res - "2", // Literal - "2", // Assign - "this", // EvalVariable - "Object", // Deref - "Object", // Assign - "Parent", // ResType - "test", // ResOverload - "p", // EvalVariable - "Object", // Deref - "test", // ResOverride - "Object", - "y", // EvalVariable - "this", // EvalVariable - "x", // Res - "2", // Deref - "2", // Assign - "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); + 'p', // EvalVariable + 'Test', // ResType + 'Test', // ResConOverload + 'Object', // New + 'Parent', // ResType + 'Parent', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'Object', // ResType + 'Object', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'x', // Res + '1', // Literal + '1', // Assign + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'x', // Res + '2', // Literal + '2', // Assign + 'this', // EvalVariable + 'Object', // Deref + 'Object', // Assign + 'Parent', // ResType + 'test', // ResOverload + 'p', // EvalVariable + 'Object', // Deref + 'test', // ResOverride + 'Object', + 'y', // EvalVariable + 'this', // EvalVariable + 'x', // Res + '2', // Deref + '2', // Assign + '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 + ) // TODO test env - }); + }) - it("evaluate inherited instance field via qualified name correctly", () => { + it('evaluate inherited instance field via qualified name correctly', () => { const programStr = ` class Parent { int x = 1; @@ -552,215 +552,215 @@ describe("evaluate instance fields with inheritance", () => { int x = p.x; } } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class Test extends Parent {...} - "NormalClassDeclaration", // class Parent {...} - "NormalClassDeclaration", // class Object {...} + 'CompilationUnit', - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class Test extends Parent {...} + 'NormalClassDeclaration', // class Parent {...} - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Parent() {...} + 'Env', // from NormalClassDeclaration + 'ConstructorDeclaration', // Parent() {...} - "Env", // from NormalClassDeclaration - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} - "Pop", - "MethodInvocation", // Test.main([""]) + 'Pop', + 'MethodInvocation', // Test.main([""]) - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test - "Deref", - "EvalVariable", // Test + 'Deref', + 'EvalVariable', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; - "LocalVariableDeclarationStatement", // int x = p.x; - "LocalVariableDeclarationStatement", // Parent p = new Test(); + 'Env', // from Block + 'ReturnStatement', // return; + 'LocalVariableDeclarationStatement', // int x = p.x; + 'LocalVariableDeclarationStatement', // Parent p = new Test(); - "ExpressionStatement", // p = new Test(); - "LocalVariableDeclarationStatement", // Parent p; + 'ExpressionStatement', // p = new Test(); + 'LocalVariableDeclarationStatement', // Parent p; - "Pop", - "Assignment", // p = new Test() + 'Pop', + 'Assignment', // p = new Test() - "Assign", // = - "ClassInstanceCreationExpression", // new Test() - "EvalVariable", // p + 'Assign', // = + 'ClassInstanceCreationExpression', // new Test() + 'EvalVariable', // p - "Invocation", // () - "New", // new - "ResConOverload", // Test - "ResType", // Test + 'Invocation', // () + 'New', // new + 'ResConOverload', // Test + 'ResType', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; - "ExplicitConstructorInvocation", // super(); + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExplicitConstructorInvocation', // super(); - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Parent - "ResType", // super + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Parent + 'ResType', // super - "Deref", - "EvalVariable", // super + 'Deref', + 'EvalVariable', // super - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; - "ExpressionStatement", // this.x = 1; - "ExplicitConstructorInvocation", // super(); + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExpressionStatement', // this.x = 1; + 'ExplicitConstructorInvocation', // super(); - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Object - "ResType", // super + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Object + 'ResType', // super - "Deref", - "EvalVariable", // super + 'Deref', + 'EvalVariable', // super - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; + 'Env', // from Block + 'ReturnStatement', // return this; - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "Pop", - "Assignment", // this.x = 1 + 'Pop', + 'Assignment', // this.x = 1 - "Assign", // = - "Literal", // 1 - "EvalVariable", // this.x + 'Assign', // = + 'Literal', // 1 + 'EvalVariable', // this.x - "Res", // x - "EvalVariable", // this + 'Res', // x + 'EvalVariable', // this - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "ExpressionStatement", // x = p.x; - "LocalVariableDeclarationStatement", // int x; + 'ExpressionStatement', // x = p.x; + 'LocalVariableDeclarationStatement', // int x; - "Pop", - "Assignment", // x = p.x + 'Pop', + 'Assignment', // x = p.x - "Assign", // = - "ExpressionName", // p.x - "EvalVariable", // x + 'Assign', // = + 'ExpressionName', // p.x + 'EvalVariable', // x - "Deref", - "EvalVariable", // p.x + 'Deref', + 'EvalVariable', // p.x - "Res", // x - "EvalVariable", // p + 'Res', // x + 'EvalVariable', // p - "Reset", // return - "Void", + 'Reset', // return + 'Void', - "Reset", // Skip Env from Block - ]; + 'Reset' // Skip Env from Block + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "p", // EvalVariable - "Test", // ResType - "Test", // ResConOverload - "Object", // New - "Parent", // ResType - "Parent", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "Object", // ResType - "Object", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "x", // Res - "1", // Literal - "1", // Assign - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "Object", // Assign - "x", // EvalVariable - "p", // EvalVariable - "x", // Res - "1", // Deref - "1", // Assign - "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); + 'p', // EvalVariable + 'Test', // ResType + 'Test', // ResConOverload + 'Object', // New + 'Parent', // ResType + 'Parent', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'Object', // ResType + 'Object', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'x', // Res + '1', // Literal + '1', // Assign + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'Object', // Assign + 'x', // EvalVariable + 'p', // EvalVariable + 'x', // Res + '1', // Deref + '1', // Assign + '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 + ) // TODO test env - }); + }) - it("evaluate shadowed instance field via subclass qualified name correctly", () => { + it('evaluate shadowed instance field via subclass qualified name correctly', () => { const programStr = ` class Parent { int x = 1; @@ -772,230 +772,230 @@ describe("evaluate instance fields with inheritance", () => { int x = t.x; // 2 } } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class Test extends Parent {...} - "NormalClassDeclaration", // class Parent {...} - "NormalClassDeclaration", // class Object {...} + 'CompilationUnit', - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class Test extends Parent {...} + 'NormalClassDeclaration', // class Parent {...} - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Parent() {...} + 'Env', // from NormalClassDeclaration + 'ConstructorDeclaration', // Parent() {...} - "Env", // from NormalClassDeclaration - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} - "Pop", - "MethodInvocation", // Test.main([""]) + 'Pop', + 'MethodInvocation', // Test.main([""]) - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test - "Deref", - "EvalVariable", // Test + 'Deref', + 'EvalVariable', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; - "LocalVariableDeclarationStatement", // int x = t.x; - "LocalVariableDeclarationStatement", // Test t = new Test(); + 'Env', // from Block + 'ReturnStatement', // return; + 'LocalVariableDeclarationStatement', // int x = t.x; + 'LocalVariableDeclarationStatement', // Test t = new Test(); - "ExpressionStatement", // t = new Test(); - "LocalVariableDeclarationStatement", // Test t; + 'ExpressionStatement', // t = new Test(); + 'LocalVariableDeclarationStatement', // Test t; - "Pop", - "Assignment", // t = new Test() + 'Pop', + 'Assignment', // t = new Test() - "Assign", // = - "ClassInstanceCreationExpression", // new Test() - "EvalVariable", // t + 'Assign', // = + 'ClassInstanceCreationExpression', // new Test() + 'EvalVariable', // t - "Invocation", // () - "New", // new - "ResConOverload", // Test - "ResType", // Test + 'Invocation', // () + 'New', // new + 'ResConOverload', // Test + 'ResType', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; - "ExpressionStatement", // this.x = 2; - "ExplicitConstructorInvocation", // super(); + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExpressionStatement', // this.x = 2; + 'ExplicitConstructorInvocation', // super(); - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Parent - "ResType", // super + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Parent + 'ResType', // super - "Deref", - "EvalVariable", // super + 'Deref', + 'EvalVariable', // super - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; - "ExpressionStatement", // this.x = 1; - "ExplicitConstructorInvocation", // super(); + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExpressionStatement', // this.x = 1; + 'ExplicitConstructorInvocation', // super(); - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Object - "ResType", // super + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Object + 'ResType', // super - "Deref", - "EvalVariable", // super + 'Deref', + 'EvalVariable', // super - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; + 'Env', // from Block + 'ReturnStatement', // return this; - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "Pop", - "Assignment", // this.x = 1 + 'Pop', + 'Assignment', // this.x = 1 - "Assign", // = - "Literal", // 1 - "EvalVariable", // this.x + 'Assign', // = + 'Literal', // 1 + 'EvalVariable', // this.x - "Res", // x - "EvalVariable", // this + 'Res', // x + 'EvalVariable', // this - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "Pop", - "Assignment", // this.x = 2 + 'Pop', + 'Assignment', // this.x = 2 - "Assign", // = - "Literal", // 2 - "EvalVariable", // this.x + 'Assign', // = + 'Literal', // 2 + 'EvalVariable', // this.x - "Res", // x - "EvalVariable", // this + 'Res', // x + 'EvalVariable', // this - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "ExpressionStatement", // x = t.x; - "LocalVariableDeclarationStatement", // int x; + 'ExpressionStatement', // x = t.x; + 'LocalVariableDeclarationStatement', // int x; - "Pop", - "Assignment", // x = t.x + 'Pop', + 'Assignment', // x = t.x - "Assign", // = - "ExpressionName", // t.x - "EvalVariable", // x + 'Assign', // = + 'ExpressionName', // t.x + 'EvalVariable', // x - "Deref", - "EvalVariable", // t.x + 'Deref', + 'EvalVariable', // t.x - "Res", // x - "EvalVariable", // t + 'Res', // x + 'EvalVariable', // t - "Reset", // return - "Void", + 'Reset', // return + 'Void', - "Reset", // Skip Env from Block - ]; + 'Reset' // Skip Env from Block + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "t", // EvalVariable - "Test", // ResType - "Test", // ResConOverload - "Object", // New - "Parent", // ResType - "Parent", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "Object", // ResType - "Object", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "x", // Res - "1", // Literal - "1", // Assign - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "x", // Res - "2", // Literal - "2", // Assign - "this", // EvalVariable - "Object", // Deref - "Object", // Assign - "x", // EvalVariable - "t", // EvalVariable - "x", // Res - "2", // Deref - "2", // Assign - "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); + 't', // EvalVariable + 'Test', // ResType + 'Test', // ResConOverload + 'Object', // New + 'Parent', // ResType + 'Parent', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'Object', // ResType + 'Object', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'x', // Res + '1', // Literal + '1', // Assign + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'x', // Res + '2', // Literal + '2', // Assign + 'this', // EvalVariable + 'Object', // Deref + 'Object', // Assign + 'x', // EvalVariable + 't', // EvalVariable + 'x', // Res + '2', // Deref + '2', // Assign + '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 + ) // TODO test env - }); + }) - it("evaluate shadowed instance field via superclass qualified name correctly", () => { + it('evaluate shadowed instance field via superclass qualified name correctly', () => { const programStr = ` class Parent { int x = 1; @@ -1007,230 +1007,230 @@ describe("evaluate instance fields with inheritance", () => { int x = p.x; // 1 } } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class Test extends Parent {...} - "NormalClassDeclaration", // class Parent {...} - "NormalClassDeclaration", // class Object {...} + 'CompilationUnit', - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class Test extends Parent {...} + 'NormalClassDeclaration', // class Parent {...} - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Parent() {...} + 'Env', // from NormalClassDeclaration + 'ConstructorDeclaration', // Parent() {...} - "Env", // from NormalClassDeclaration - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} - "Pop", - "MethodInvocation", // Test.main([""]) + 'Pop', + 'MethodInvocation', // Test.main([""]) - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test - "Deref", - "EvalVariable", // Test + 'Deref', + 'EvalVariable', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; - "LocalVariableDeclarationStatement", // int x = p.x; - "LocalVariableDeclarationStatement", // Parent p = new Test(); + 'Env', // from Block + 'ReturnStatement', // return; + 'LocalVariableDeclarationStatement', // int x = p.x; + 'LocalVariableDeclarationStatement', // Parent p = new Test(); - "ExpressionStatement", // p = new Test(); - "LocalVariableDeclarationStatement", // Parent p; + 'ExpressionStatement', // p = new Test(); + 'LocalVariableDeclarationStatement', // Parent p; - "Pop", - "Assignment", // p = new Test() + 'Pop', + 'Assignment', // p = new Test() - "Assign", // = - "ClassInstanceCreationExpression", // new Test() - "EvalVariable", // p + 'Assign', // = + 'ClassInstanceCreationExpression', // new Test() + 'EvalVariable', // p - "Invocation", // () - "New", // new - "ResConOverload", // Test - "ResType", // Test + 'Invocation', // () + 'New', // new + 'ResConOverload', // Test + 'ResType', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; - "ExpressionStatement", // this.x = 2; - "ExplicitConstructorInvocation", // super(); + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExpressionStatement', // this.x = 2; + 'ExplicitConstructorInvocation', // super(); - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Parent - "ResType", // super + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Parent + 'ResType', // super - "Deref", - "EvalVariable", // super + 'Deref', + 'EvalVariable', // super - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; - "ExpressionStatement", // this.x = 1; - "ExplicitConstructorInvocation", // super(); + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExpressionStatement', // this.x = 1; + 'ExplicitConstructorInvocation', // super(); - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Object - "ResType", // super + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Object + 'ResType', // super - "Deref", - "EvalVariable", // super + 'Deref', + 'EvalVariable', // super - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; + 'Env', // from Block + 'ReturnStatement', // return this; - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "Pop", - "Assignment", // this.x = 1 + 'Pop', + 'Assignment', // this.x = 1 - "Assign", // = - "Literal", // 1 - "EvalVariable", // this.x + 'Assign', // = + 'Literal', // 1 + 'EvalVariable', // this.x - "Res", // x - "EvalVariable", // this + 'Res', // x + 'EvalVariable', // this - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "Pop", - "Assignment", // this.x = 2 + 'Pop', + 'Assignment', // this.x = 2 - "Assign", // = - "Literal", // 2 - "EvalVariable", // this.x + 'Assign', // = + 'Literal', // 2 + 'EvalVariable', // this.x - "Res", // x - "EvalVariable", // this + 'Res', // x + 'EvalVariable', // this - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "ExpressionStatement", // x = t.x; - "LocalVariableDeclarationStatement", // int x; + 'ExpressionStatement', // x = t.x; + 'LocalVariableDeclarationStatement', // int x; - "Pop", - "Assignment", // x = p.x + 'Pop', + 'Assignment', // x = p.x - "Assign", // = - "ExpressionName", // p.x - "EvalVariable", // x + 'Assign', // = + 'ExpressionName', // p.x + 'EvalVariable', // x - "Deref", - "EvalVariable", // p.x + 'Deref', + 'EvalVariable', // p.x - "Res", // x - "EvalVariable", // p + 'Res', // x + 'EvalVariable', // p - "Reset", // return - "Void", + 'Reset', // return + 'Void', - "Reset", // Skip Env from Block - ]; + 'Reset' // Skip Env from Block + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "p", // EvalVariable - "Test", // ResType - "Test", // ResConOverload - "Object", // New - "Parent", // ResType - "Parent", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "Object", // ResType - "Object", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "x", // Res - "1", // Literal - "1", // Assign - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "x", // Res - "2", // Literal - "2", // Assign - "this", // EvalVariable - "Object", // Deref - "Object", // Assign - "x", // EvalVariable - "p", // EvalVariable - "x", // Res - "1", // Deref - "1", // Assign - "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); + 'p', // EvalVariable + 'Test', // ResType + 'Test', // ResConOverload + 'Object', // New + 'Parent', // ResType + 'Parent', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'Object', // ResType + 'Object', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'x', // Res + '1', // Literal + '1', // Assign + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'x', // Res + '2', // Literal + '2', // Assign + 'this', // EvalVariable + 'Object', // Deref + 'Object', // Assign + 'x', // EvalVariable + 'p', // EvalVariable + 'x', // Res + '1', // Deref + '1', // Assign + '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 + ) // TODO test env - }); + }) - it("should not be able to access subclass instance field via superclass qualified name", () => { + it('should not be able to access subclass instance field via superclass qualified name', () => { const programStr = ` class Parent {} class Test extends Parent { @@ -1240,14 +1240,14 @@ describe("evaluate instance fields with inheritance", () => { int x = p.x; } } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - expect(() => evaluate(context)).toThrowError(UndeclaredVariableError); - }); -}); + expect(() => evaluate(context)).toThrowError(UndeclaredVariableError) + }) +}) diff --git a/src/ec-evaluator/__tests__/inheritance-static-field.test.ts b/src/ec-evaluator/__tests__/inheritance-static-field.test.ts index f5befa9..6b60dd6 100644 --- a/src/ec-evaluator/__tests__/inheritance-static-field.test.ts +++ b/src/ec-evaluator/__tests__/inheritance-static-field.test.ts @@ -1,16 +1,16 @@ -import { parse } from "../../ast/parser"; -import { UndeclaredVariableError } from "../errors"; -import { evaluate } from "../interpreter"; +import { parse } from '../../ast/parser' +import { UndeclaredVariableError } from '../errors' +import { evaluate } from '../interpreter' import { ControlStub, StashStub, createContextStub, getControlItemStr, getStashItemStr -} from "./__utils__/utils"; +} from './__utils__/utils' -describe("evaluate static fields with inheritance", () => { - it("evaluate inherited static field via simple name correctly", () => { +describe('evaluate static fields with inheritance', () => { + it('evaluate inherited static field via simple name correctly', () => { const programStr = ` class Parent { static int x = 1; @@ -20,109 +20,109 @@ describe("evaluate static fields with inheritance", () => { int y = x; } } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class Test extends Parent {...} - "NormalClassDeclaration", // class Parent {...} - "NormalClassDeclaration", // class Object {...} + 'CompilationUnit', - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class Test extends Parent {...} + 'NormalClassDeclaration', // class Parent {...} - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Parent() {...} - "FieldDeclaration", // static int x = 1; + 'Env', // from NormalClassDeclaration + 'ConstructorDeclaration', // Parent() {...} + 'FieldDeclaration', // static int x = 1; - "Pop", - "Assign", // = - "Literal", // 1 - "EvalVariable", // x + 'Pop', + 'Assign', // = + 'Literal', // 1 + 'EvalVariable', // x - "Env", // from NormalClassDeclaration - "MethodDeclaration", // static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} - "Pop", - "MethodInvocation", // Test.main([""]) + 'Pop', + 'MethodInvocation', // Test.main([""]) - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test - "Deref", - "EvalVariable", // Test + 'Deref', + 'EvalVariable', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; - "LocalVariableDeclarationStatement", // int y = Test.x; + 'Env', // from Block + 'ReturnStatement', // return; + 'LocalVariableDeclarationStatement', // int y = Test.x; - "ExpressionStatement", // y = Test.x; - "LocalVariableDeclarationStatement", // int y; + 'ExpressionStatement', // y = Test.x; + 'LocalVariableDeclarationStatement', // int y; - "Pop", - "Assignment", // y = Test.x + 'Pop', + 'Assignment', // y = Test.x - "Assign", // = - "ExpressionName", // Test.x - "EvalVariable", // y + 'Assign', // = + 'ExpressionName', // Test.x + 'EvalVariable', // y - "Deref", - "EvalVariable", // Test.x + 'Deref', + 'EvalVariable', // Test.x - "Res", // x - "EvalVariable", // Test + 'Res', // x + 'EvalVariable', // Test - "Reset", // return - "Void", + 'Reset', // return + 'Void', - "Reset", // Skip Env from Block - ]; + 'Reset' // Skip Env from Block + ] const expectedStashTrace = [ - "x", // EvalVariable - "1", // Literal - "1", // Assign - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'x', // EvalVariable + '1', // Literal + '1', // Assign + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "y", // EvalVariable - "Test", // EvalVariable - "x", // Res - "1", // Deref - "1", // Assign - "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); + 'y', // EvalVariable + 'Test', // EvalVariable + 'x', // Res + '1', // Deref + '1', // Assign + '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 + ) // TODO test env - }); + }) - it("evaluate shadowed static field via simple name correctly", () => { + it('evaluate shadowed static field via simple name correctly', () => { const programStr = ` class Parent { static int x = 1; @@ -133,118 +133,118 @@ describe("evaluate static fields with inheritance", () => { int y = x; // 2 } } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class Test extends Parent {...} - "NormalClassDeclaration", // class Parent {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Parent() {...} - "FieldDeclaration", // static int x = 1; - - "Pop", - "Assign", // = - "Literal", // 1 - "EvalVariable", // x - - "Env", // from NormalClassDeclaration - "MethodDeclaration", // static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} - "FieldDeclaration", // static int x = 2; - - "Pop", - "Assign", // = - "Literal", // 2 - "EvalVariable", // x - - "Pop", - "MethodInvocation", // Test.main([""]) - - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test - - "Deref", - "EvalVariable", // Test - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return; - "LocalVariableDeclarationStatement", // int y = Test.x; - - "ExpressionStatement", // y = Test.x; - "LocalVariableDeclarationStatement", // int y; - - "Pop", - "Assignment", // y = Test.x - - "Assign", // = - "ExpressionName", // Test.x - "EvalVariable", // y - - "Deref", - "EvalVariable", // Test.x - - "Res", // x - "EvalVariable", // Test - - "Reset", // return - "Void", - - "Reset", // Skip Env from Block - ]; + 'CompilationUnit', + + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class Test extends Parent {...} + 'NormalClassDeclaration', // class Parent {...} + + 'Env', // from NormalClassDeclaration + 'ConstructorDeclaration', // Parent() {...} + 'FieldDeclaration', // static int x = 1; + + 'Pop', + 'Assign', // = + 'Literal', // 1 + 'EvalVariable', // x + + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} + 'FieldDeclaration', // static int x = 2; + + 'Pop', + 'Assign', // = + 'Literal', // 2 + 'EvalVariable', // x + + 'Pop', + 'MethodInvocation', // Test.main([""]) + + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test + + 'Deref', + 'EvalVariable', // Test + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return; + 'LocalVariableDeclarationStatement', // int y = Test.x; + + 'ExpressionStatement', // y = Test.x; + 'LocalVariableDeclarationStatement', // int y; + + 'Pop', + 'Assignment', // y = Test.x + + 'Assign', // = + 'ExpressionName', // Test.x + 'EvalVariable', // y + + 'Deref', + 'EvalVariable', // Test.x + + 'Res', // x + 'EvalVariable', // Test + + 'Reset', // return + 'Void', + + 'Reset' // Skip Env from Block + ] const expectedStashTrace = [ - "x", // EvalVariable - "1", // Literal - "1", // Assign - "x", // EvalVariable - "2", // Literal - "2", // Assign - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'x', // EvalVariable + '1', // Literal + '1', // Assign + 'x', // EvalVariable + '2', // Literal + '2', // Assign + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "y", // EvalVariable - "Test", // EvalVariable - "x", // Res - "2", // Deref - "2", // Assign - "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); + 'y', // EvalVariable + 'Test', // EvalVariable + 'x', // Res + '2', // Deref + '2', // Assign + '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 + ) // TODO test env - }); + }) - it("evaluate inherited static field via qualified name correctly", () => { + it('evaluate inherited static field via qualified name correctly', () => { const programStr = ` class Parent { static int x = 1; @@ -255,209 +255,209 @@ describe("evaluate static fields with inheritance", () => { int x = t.x; } } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class Test extends Parent {...} - "NormalClassDeclaration", // class Parent {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} + 'CompilationUnit', + + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class Test extends Parent {...} + 'NormalClassDeclaration', // class Parent {...} - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Parent() {...} - "FieldDeclaration", // static int x = 1; + 'Env', // from NormalClassDeclaration + 'ConstructorDeclaration', // Parent() {...} + 'FieldDeclaration', // static int x = 1; - "Pop", - "Assign", // = - "Literal", // 1 - "EvalVariable", // x + 'Pop', + 'Assign', // = + 'Literal', // 1 + 'EvalVariable', // x - "Env", // from NormalClassDeclaration - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} - "Pop", - "MethodInvocation", // Test.main([""]) + 'Pop', + 'MethodInvocation', // Test.main([""]) - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test - "Deref", - "EvalVariable", // Test + 'Deref', + 'EvalVariable', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; - "LocalVariableDeclarationStatement", // int x = t.x; - "LocalVariableDeclarationStatement", // Parent t = new Test(); + 'Env', // from Block + 'ReturnStatement', // return; + 'LocalVariableDeclarationStatement', // int x = t.x; + 'LocalVariableDeclarationStatement', // Parent t = new Test(); - "ExpressionStatement", // t = new Test(); - "LocalVariableDeclarationStatement", // Parent t; + 'ExpressionStatement', // t = new Test(); + 'LocalVariableDeclarationStatement', // Parent t; - "Pop", - "Assignment", // t = new Test() + 'Pop', + 'Assignment', // t = new Test() - "Assign", // = - "ClassInstanceCreationExpression", // new Test() - "EvalVariable", // t + 'Assign', // = + 'ClassInstanceCreationExpression', // new Test() + 'EvalVariable', // t - "Invocation", // () - "New", // new - "ResConOverload", // Test - "ResType", // Test + 'Invocation', // () + 'New', // new + 'ResConOverload', // Test + 'ResType', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; - "ExplicitConstructorInvocation", // super(); + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExplicitConstructorInvocation', // super(); - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Parent - "ResType", // super + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Parent + 'ResType', // super - "Deref", - "EvalVariable", // super + 'Deref', + 'EvalVariable', // super - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; - "ExplicitConstructorInvocation", // super(); + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExplicitConstructorInvocation', // super(); - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Object - "ResType", // super + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Object + 'ResType', // super - "Deref", - "EvalVariable", // super + 'Deref', + 'EvalVariable', // super - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; + 'Env', // from Block + 'ReturnStatement', // return this; - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "ExpressionStatement", // x = t.x; - "LocalVariableDeclarationStatement", // int x; + 'ExpressionStatement', // x = t.x; + 'LocalVariableDeclarationStatement', // int x; - "Pop", - "Assignment", // x = t.x + 'Pop', + 'Assignment', // x = t.x - "Assign", // = - "ExpressionName", // t.x - "EvalVariable", // x + 'Assign', // = + 'ExpressionName', // t.x + 'EvalVariable', // x - "Deref", - "EvalVariable", // t.x + 'Deref', + 'EvalVariable', // t.x - "Res", // x - "EvalVariable", // t + 'Res', // x + 'EvalVariable', // t - "Reset", // return - "Void", + 'Reset', // return + 'Void', - "Reset", // Skip Env from Block - ]; + 'Reset' // Skip Env from Block + ] const expectedStashTrace = [ - "x", // EvalVariable - "1", // Literal - "1", // Assign - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'x', // EvalVariable + '1', // Literal + '1', // Assign + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "t", // EvalVariable - "Test", // ResType - "Test", // ResConOverload - "Object", // New - "Parent", // ResType - "Parent", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "Object", // ResType - "Object", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "Object", // Assign - "x", // EvalVariable - "t", // EvalVariable - "x", // Res - "1", // Deref - "1", // Assign - "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); + 't', // EvalVariable + 'Test', // ResType + 'Test', // ResConOverload + 'Object', // New + 'Parent', // ResType + 'Parent', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'Object', // ResType + 'Object', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'Object', // Assign + 'x', // EvalVariable + 't', // EvalVariable + 'x', // Res + '1', // Deref + '1', // Assign + '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 + ) // TODO test env - }); + }) - it("evaluate shadowed static field via subclass qualified name correctly", () => { + it('evaluate shadowed static field via subclass qualified name correctly', () => { const programStr = ` class Parent { static int x = 1; @@ -469,218 +469,218 @@ describe("evaluate static fields with inheritance", () => { int x = t.x; // 2 } } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class Test extends Parent {...} - "NormalClassDeclaration", // class Parent {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Parent() {...} - "FieldDeclaration", // static int x = 1; - - "Pop", - "Assign", // = - "Literal", // 1 - "EvalVariable", // x + 'CompilationUnit', + + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class Test extends Parent {...} + 'NormalClassDeclaration', // class Parent {...} + + 'Env', // from NormalClassDeclaration + 'ConstructorDeclaration', // Parent() {...} + 'FieldDeclaration', // static int x = 1; - "Env", // from NormalClassDeclaration - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} - "FieldDeclaration", // static int x = 2; + 'Pop', + 'Assign', // = + 'Literal', // 1 + 'EvalVariable', // x - "Pop", - "Assign", // = - "Literal", // 2 - "EvalVariable", // x + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} + 'FieldDeclaration', // static int x = 2; - "Pop", - "MethodInvocation", // Test.main([""]) + 'Pop', + 'Assign', // = + 'Literal', // 2 + 'EvalVariable', // x - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test + 'Pop', + 'MethodInvocation', // Test.main([""]) - "Deref", - "EvalVariable", // Test + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Deref', + 'EvalVariable', // Test - "Env", // from Block - "ReturnStatement", // return; - "LocalVariableDeclarationStatement", // int x = t.x; - "LocalVariableDeclarationStatement", // Test t = new Test(); + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "ExpressionStatement", // t = new Test(); - "LocalVariableDeclarationStatement", // Test t; + 'Env', // from Block + 'ReturnStatement', // return; + 'LocalVariableDeclarationStatement', // int x = t.x; + 'LocalVariableDeclarationStatement', // Test t = new Test(); - "Pop", - "Assignment", // t = new Test() + 'ExpressionStatement', // t = new Test(); + 'LocalVariableDeclarationStatement', // Test t; - "Assign", // = - "ClassInstanceCreationExpression", // new Test() - "EvalVariable", // t + 'Pop', + 'Assignment', // t = new Test() - "Invocation", // () - "New", // new - "ResConOverload", // Test - "ResType", // Test + 'Assign', // = + 'ClassInstanceCreationExpression', // new Test() + 'EvalVariable', // t - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Invocation', // () + 'New', // new + 'ResConOverload', // Test + 'ResType', // Test - "Env", // from Block - "ReturnStatement", // return this; - "ExplicitConstructorInvocation", // super(); + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Parent - "ResType", // super + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExplicitConstructorInvocation', // super(); - "Deref", - "EvalVariable", // super + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Parent + 'ResType', // super - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Deref', + 'EvalVariable', // super - "Env", // from Block - "ReturnStatement", // return this; - "ExplicitConstructorInvocation", // super(); + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Object - "ResType", // super + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExplicitConstructorInvocation', // super(); - "Deref", - "EvalVariable", // super + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Object + 'ResType', // super - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Deref', + 'EvalVariable', // super - "Env", // from Block - "ReturnStatement", // return this; + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Reset", // return - "ExpressionName", // this + 'Env', // from Block + 'ReturnStatement', // return this; - "Deref", - "EvalVariable", // this + 'Reset', // return + 'ExpressionName', // this - "Reset", // Skip Env from Block + 'Deref', + 'EvalVariable', // this - "Reset", // return - "ExpressionName", // this + 'Reset', // Skip Env from Block - "Deref", - "EvalVariable", // this + 'Reset', // return + 'ExpressionName', // this - "Reset", // Skip Env from Block + 'Deref', + 'EvalVariable', // this - "Reset", // return - "ExpressionName", // this + 'Reset', // Skip Env from Block - "Deref", - "EvalVariable", // this + 'Reset', // return + 'ExpressionName', // this - "Reset", // Skip Env from Block + 'Deref', + 'EvalVariable', // this - "ExpressionStatement", // int x = t.x; - "LocalVariableDeclarationStatement", // int x; + 'Reset', // Skip Env from Block - "Pop", - "Assignment", // x = t.x + 'ExpressionStatement', // int x = t.x; + 'LocalVariableDeclarationStatement', // int x; - "Assign", // = - "ExpressionName", // t.x - "EvalVariable", // x + 'Pop', + 'Assignment', // x = t.x - "Deref", - "EvalVariable", // t.x + 'Assign', // = + 'ExpressionName', // t.x + 'EvalVariable', // x - "Res", // x - "EvalVariable", // t + 'Deref', + 'EvalVariable', // t.x - "Reset", // return - "Void", + 'Res', // x + 'EvalVariable', // t - "Reset", // Skip Env from Block - ]; + 'Reset', // return + 'Void', + + 'Reset' // Skip Env from Block + ] const expectedStashTrace = [ - "x", // EvalVariable - "1", // Literal - "1", // Assign - "x", // EvalVariable - "2", // Literal - "2", // Assign - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'x', // EvalVariable + '1', // Literal + '1', // Assign + 'x', // EvalVariable + '2', // Literal + '2', // Assign + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "t", // EvalVariable - "Test", // ResType - "Test", // ResConOverload - "Object", // New - "Parent", // ResType - "Parent", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "Object", // ResType - "Object", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "Object", // Assign - "x", // EvalVariable - "t", // EvalVariable - "x", // Res - "2", // Deref - "2", // Assign - "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); + 't', // EvalVariable + 'Test', // ResType + 'Test', // ResConOverload + 'Object', // New + 'Parent', // ResType + 'Parent', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'Object', // ResType + 'Object', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'Object', // Assign + 'x', // EvalVariable + 't', // EvalVariable + 'x', // Res + '2', // Deref + '2', // Assign + '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 + ) // TODO test env - }); + }) - it("evaluate shadowed static field via superclass qualified name correctly", () => { + it('evaluate shadowed static field via superclass qualified name correctly', () => { const programStr = ` class Parent { static int x = 1; @@ -692,218 +692,218 @@ describe("evaluate static fields with inheritance", () => { int x = p.x; // 1 } } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class Test extends Parent {...} - "NormalClassDeclaration", // class Parent {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Parent() {...} - "FieldDeclaration", // static int x = 1; - - "Pop", - "Assign", // = - "Literal", // 1 - "EvalVariable", // x + 'CompilationUnit', + + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class Test extends Parent {...} + 'NormalClassDeclaration', // class Parent {...} + + 'Env', // from NormalClassDeclaration + 'ConstructorDeclaration', // Parent() {...} + 'FieldDeclaration', // static int x = 1; + + 'Pop', + 'Assign', // = + 'Literal', // 1 + 'EvalVariable', // x - "Env", // from NormalClassDeclaration - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} - "FieldDeclaration", // static int x = 2; + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} + 'FieldDeclaration', // static int x = 2; - "Pop", - "Assign", // = - "Literal", // 2 - "EvalVariable", // x + 'Pop', + 'Assign', // = + 'Literal', // 2 + 'EvalVariable', // x - "Pop", - "MethodInvocation", // Test.main([""]) + 'Pop', + 'MethodInvocation', // Test.main([""]) - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test - "Deref", - "EvalVariable", // Test + 'Deref', + 'EvalVariable', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; - "LocalVariableDeclarationStatement", // int x = p.x; - "LocalVariableDeclarationStatement", // Parent p = new Test(); + 'Env', // from Block + 'ReturnStatement', // return; + 'LocalVariableDeclarationStatement', // int x = p.x; + 'LocalVariableDeclarationStatement', // Parent p = new Test(); - "ExpressionStatement", // p = new Test(); - "LocalVariableDeclarationStatement", // Parent p; + 'ExpressionStatement', // p = new Test(); + 'LocalVariableDeclarationStatement', // Parent p; - "Pop", - "Assignment", // p = new Test() + 'Pop', + 'Assignment', // p = new Test() - "Assign", // = - "ClassInstanceCreationExpression", // new Test() - "EvalVariable", // p + 'Assign', // = + 'ClassInstanceCreationExpression', // new Test() + 'EvalVariable', // p - "Invocation", // () - "New", // new - "ResConOverload", // Test - "ResType", // Test + 'Invocation', // () + 'New', // new + 'ResConOverload', // Test + 'ResType', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; - "ExplicitConstructorInvocation", // super(); + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExplicitConstructorInvocation', // super(); - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Parent - "ResType", // super + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Parent + 'ResType', // super - "Deref", - "EvalVariable", // super + 'Deref', + 'EvalVariable', // super - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; - "ExplicitConstructorInvocation", // super(); + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExplicitConstructorInvocation', // super(); - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Object - "ResType", // super + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Object + 'ResType', // super - "Deref", - "EvalVariable", // super + 'Deref', + 'EvalVariable', // super - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; + 'Env', // from Block + 'ReturnStatement', // return this; - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "ExpressionStatement", // x = p.x; - "LocalVariableDeclarationStatement", // int x; + 'ExpressionStatement', // x = p.x; + 'LocalVariableDeclarationStatement', // int x; - "Pop", - "Assignment", // x = p.x + 'Pop', + 'Assignment', // x = p.x - "Assign", // = - "ExpressionName", // p.x - "EvalVariable", // x + 'Assign', // = + 'ExpressionName', // p.x + 'EvalVariable', // x - "Deref", - "EvalVariable", // p.x + 'Deref', + 'EvalVariable', // p.x - "Res", // x - "EvalVariable", // p + 'Res', // x + 'EvalVariable', // p - "Reset", // return - "Void", + 'Reset', // return + 'Void', - "Reset", // Skip Env from Block - ]; + 'Reset' // Skip Env from Block + ] const expectedStashTrace = [ - "x", // EvalVariable - "1", // Literal - "1", // Assign - "x", // EvalVariable - "2", // Literal - "2", // Assign - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'x', // EvalVariable + '1', // Literal + '1', // Assign + 'x', // EvalVariable + '2', // Literal + '2', // Assign + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "p", // EvalVariable - "Test", // ResType - "Test", // ResConOverload - "Object", // New - "Parent", // ResType - "Parent", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "Object", // ResType - "Object", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "Object", // Assign - "x", // EvalVariable - "p", // EvalVariable - "x", // Res - "1", // Deref - "1", // Assign - "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); + 'p', // EvalVariable + 'Test', // ResType + 'Test', // ResConOverload + 'Object', // New + 'Parent', // ResType + 'Parent', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'Object', // ResType + 'Object', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'Object', // Assign + 'x', // EvalVariable + 'p', // EvalVariable + 'x', // Res + '1', // Deref + '1', // Assign + '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 + ) // TODO test env - }); + }) - it("should not be able to access subclass static field via superclass qualified name", () => { + it('should not be able to access subclass static field via superclass qualified name', () => { const programStr = ` class Parent {} class Test extends Parent { @@ -913,14 +913,14 @@ describe("evaluate static fields with inheritance", () => { int x = p.x; } } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - expect(() => evaluate(context)).toThrowError(UndeclaredVariableError); - }); -}); + expect(() => evaluate(context)).toThrowError(UndeclaredVariableError) + }) +}) diff --git a/src/ec-evaluator/__tests__/local-var-assignment.test.ts b/src/ec-evaluator/__tests__/local-var-assignment.test.ts index 471d1ea..a2503c9 100644 --- a/src/ec-evaluator/__tests__/local-var-assignment.test.ts +++ b/src/ec-evaluator/__tests__/local-var-assignment.test.ts @@ -1,177 +1,177 @@ -import { parse } from "../../ast/parser"; -import { evaluate } from "../interpreter"; +import { parse } from '../../ast/parser' +import { evaluate } from '../interpreter' import { ControlStub, StashStub, createContextStub, getControlItemStr, getStashItemStr -} from "./__utils__/utils"; +} from './__utils__/utils' -it("evaluate LocalVariableDeclarationStatement without variableInitializer correctly", () => { +it('evaluate LocalVariableDeclarationStatement without variableInitializer correctly', () => { const programStr = ` public class Test { public static void main(String[] args) { int x; } } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // public class Test {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} - - "Env", // from NormalClassDeclaration - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} - - "Pop", - "MethodInvocation", // Test.main([""]) - - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test - - "Deref", - "EvalVariable", // Test - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return; - "LocalVariableDeclarationStatement", // int x; - - "Reset", // return - "Void", - - "Reset", // skip Env from Invocation - ]; + 'CompilationUnit', + + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // public class Test {...} + + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} + + 'Pop', + 'MethodInvocation', // Test.main([""]) + + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test + + 'Deref', + 'EvalVariable', // Test + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return; + 'LocalVariableDeclarationStatement', // int x; + + 'Reset', // return + 'Void', + + 'Reset' // skip Env from Invocation + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "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); + '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 + ) // TODO test env -}); +}) -it("evaluate LocalVariableDeclarationStatement with variableInitializer correctly", () => { +it('evaluate LocalVariableDeclarationStatement with variableInitializer correctly', () => { const programStr = ` public class Test { public static void main(String[] args) { int x = 1; } } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // public class Test {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} - - "Env", // from NormalClassDeclaration - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} - - "Pop", - "MethodInvocation", // Test.main([""]) - - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test - - "Deref", - "EvalVariable", // Test - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return; - "LocalVariableDeclarationStatement", // int x = 1; - - "ExpressionStatement", // x = 1; - "LocalVariableDeclarationStatement", // int x; - - "Pop", - "Assignment", // x = 1 - - "Assign", // = - "Literal", // 1 - "EvalVariable", // x - - "Reset", // return - "Void", - - "Reset", // skip Env from Invocation - ]; + 'CompilationUnit', + + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // public class Test {...} + + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} + + 'Pop', + 'MethodInvocation', // Test.main([""]) + + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test + + 'Deref', + 'EvalVariable', // Test + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return; + 'LocalVariableDeclarationStatement', // int x = 1; + + 'ExpressionStatement', // x = 1; + 'LocalVariableDeclarationStatement', // int x; + + 'Pop', + 'Assignment', // x = 1 + + 'Assign', // = + 'Literal', // 1 + 'EvalVariable', // x + + 'Reset', // return + 'Void', + + 'Reset' // skip Env from Invocation + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "x", // EvalVariable - "1", // Literal - "1", // Assign - "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); + 'x', // EvalVariable + '1', // Literal + '1', // Assign + '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 + ) // TODO test env -}); +}) -it("evaluate Assignment correctly", () => { +it('evaluate Assignment correctly', () => { const programStr = ` public class Test { public static void main(String[] args) { @@ -179,86 +179,86 @@ it("evaluate Assignment correctly", () => { x = 1; } } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // public class Test {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} - - "Env", // from NormalClassDeclaration - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} - - "Pop", - "MethodInvocation", // Test.main([""]) - - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test - - "Deref", - "EvalVariable", // Test - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return; - "ExpressionStatement", // x = 1; - "LocalVariableDeclarationStatement", // int x; - - "Pop", - "Assignment", // x = 1 - - "Assign", // = - "Literal", // 1 - "EvalVariable", // x - - "Reset", // return - "Void", - - "Reset", // skip Env from Invocation - ]; + 'CompilationUnit', + + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // public class Test {...} + + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} + + 'Pop', + 'MethodInvocation', // Test.main([""]) + + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test + + 'Deref', + 'EvalVariable', // Test + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return; + 'ExpressionStatement', // x = 1; + 'LocalVariableDeclarationStatement', // int x; + + 'Pop', + 'Assignment', // x = 1 + + 'Assign', // = + 'Literal', // 1 + 'EvalVariable', // x + + 'Reset', // return + 'Void', + + 'Reset' // skip Env from Invocation + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "x", // EvalVariable - "1", // Literal - "1", // Assign - "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); + 'x', // EvalVariable + '1', // Literal + '1', // Assign + '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 + ) // TODO test env -}); +}) -it("evaluate LocalVariableDeclarationStatement with local variable as variableInitializer correctly", () => { +it('evaluate LocalVariableDeclarationStatement with local variable as variableInitializer correctly', () => { const programStr = ` public class Test { public static void main(String[] args) { @@ -266,101 +266,101 @@ it("evaluate LocalVariableDeclarationStatement with local variable as variableIn int y = x; } } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // public class Test {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} - - "Env", // from NormalClassDeclaration - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} - - "Pop", - "MethodInvocation", // Test.main([""]) - - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test - - "Deref", - "EvalVariable", // Test - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return; - "LocalVariableDeclarationStatement", // int y = x; - "LocalVariableDeclarationStatement", // int x = 1; - - "ExpressionStatement", // x = 1; - "LocalVariableDeclarationStatement", // int x; - - "Pop", - "Assignment", // x = 1 - - "Assign", // = - "Literal", // 1 - "EvalVariable", // x - - "ExpressionStatement", // y = x; - "LocalVariableDeclarationStatement", // int y; - - "Pop", - "Assignment", // y = x - - "Assign", // = - "ExpressionName", // x - "EvalVariable", // y - - "Deref", - "EvalVariable", // x - - "Reset", // return - "Void", - - "Reset", // skip Env from Invocation - ]; + 'CompilationUnit', + + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // public class Test {...} + + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} + + 'Pop', + 'MethodInvocation', // Test.main([""]) + + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test + + 'Deref', + 'EvalVariable', // Test + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return; + 'LocalVariableDeclarationStatement', // int y = x; + 'LocalVariableDeclarationStatement', // int x = 1; + + 'ExpressionStatement', // x = 1; + 'LocalVariableDeclarationStatement', // int x; + + 'Pop', + 'Assignment', // x = 1 + + 'Assign', // = + 'Literal', // 1 + 'EvalVariable', // x + + 'ExpressionStatement', // y = x; + 'LocalVariableDeclarationStatement', // int y; + + 'Pop', + 'Assignment', // y = x + + 'Assign', // = + 'ExpressionName', // x + 'EvalVariable', // y + + 'Deref', + 'EvalVariable', // x + + 'Reset', // return + 'Void', + + 'Reset' // skip Env from Invocation + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "x", // EvalVariable - "1", // Literal - "1", // Assign - "y", // EvalVariable - "x", // EvalVariable - "1", // Deref - "1", // Assign - "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); + 'x', // EvalVariable + '1', // Literal + '1', // Assign + 'y', // EvalVariable + 'x', // EvalVariable + '1', // Deref + '1', // Assign + '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 + ) // TODO test env -}); +}) diff --git a/src/ec-evaluator/__tests__/main-mtd.test.ts b/src/ec-evaluator/__tests__/main-mtd.test.ts index 60d9d38..51c572b 100644 --- a/src/ec-evaluator/__tests__/main-mtd.test.ts +++ b/src/ec-evaluator/__tests__/main-mtd.test.ts @@ -1,47 +1,47 @@ -import { parse } from "../../ast/parser"; -import { NoMainMtdError } from "../errors"; -import { evaluate } from "../interpreter"; +import { parse } from '../../ast/parser' +import { NoMainMtdError } from '../errors' +import { evaluate } from '../interpreter' import { ControlStub, StashStub, createContextStub, getControlItemStr, getStashItemStr -} from "./__utils__/utils"; +} from './__utils__/utils' -describe("evaluate main method correctly", () => { - it("should throw an error when main method is not defined", () => { +describe('evaluate main method correctly', () => { + it('should throw an error when main method is not defined', () => { const programStr = ` class Test {} - `; - - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); - - const context = createContextStub(); - context.control.push(compilationUnit!); - - expect(() => evaluate(context)).toThrowError(NoMainMtdError); - }); - - it("should not throw an error if main method is defined in at least one class", () => { + ` + + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() + + const context = createContextStub() + context.control.push(compilationUnit!) + + expect(() => evaluate(context)).toThrowError(NoMainMtdError) + }) + + it('should not throw an error if main method is defined in at least one class', () => { const programStr = ` class Test {} class AnotherTest { public static void main(String[] args) {} } - `; - - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); - - const context = createContextStub(); - context.control.push(compilationUnit!); - - expect(() => evaluate(context)).not.toThrowError(NoMainMtdError); - }); - - it("should invoke the main method defined in first class according to program order", () => { + ` + + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() + + const context = createContextStub() + context.control.push(compilationUnit!) + + expect(() => evaluate(context)).not.toThrowError(NoMainMtdError) + }) + + it('should invoke the main method defined in first class according to program order', () => { const programStr = ` class Test { public static void main(String[] args) {} @@ -49,79 +49,79 @@ describe("evaluate main method correctly", () => { class AnotherTest { public static void main(String[] args) {} } - `; - - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); - - const context = createContextStub(); - context.control.push(compilationUnit!); - - const result = evaluate(context); - + ` + + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() + + const context = createContextStub() + context.control.push(compilationUnit!) + + const result = evaluate(context) + const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class AnotherTest {...} - "NormalClassDeclaration", // class Test {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} - - "Env", // from NormalClassDeclaration - "MethodDeclaration", // static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} - - "Env", // from NormalClassDeclaration - "MethodDeclaration", // static void main(String[] args) {...} - "ConstructorDeclaration", // AnotherTest() {...} - - "Pop", - "MethodInvocation", // Test.main([""]) - - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test - - "Deref", - "EvalVariable", // Test - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return; - - "Reset", // return - "Void", - - "Reset", // Skip Env from Block - ]; + 'CompilationUnit', + + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class AnotherTest {...} + 'NormalClassDeclaration', // class Test {...} + + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} + + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // static void main(String[] args) {...} + 'ConstructorDeclaration', // AnotherTest() {...} + + 'Pop', + 'MethodInvocation', // Test.main([""]) + + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test + + 'Deref', + 'EvalVariable', // Test + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return; + + 'Reset', // return + 'Void', + + 'Reset' // Skip Env from Block + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "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); + '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 + ) // TODO test env - }); + }) - it("should not hardcode initial method invocation to Test.main()", () => { + it('should not hardcode initial method invocation to Test.main()', () => { const programStr = ` class test { int x; @@ -139,226 +139,226 @@ describe("evaluate main method correctly", () => { this.x = 3; } } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", + 'CompilationUnit', - "ExpressionStatement", // test.main([""]); - "NormalClassDeclaration", // class test {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} + 'ExpressionStatement', // test.main([""]); + 'NormalClassDeclaration', // class test {...} - "Env", - "MethodDeclaration", // void test() {...} - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // test(int x) {...} - "ConstructorDeclaration", // test() {...} + 'Env', + 'MethodDeclaration', // void test() {...} + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // test(int x) {...} + 'ConstructorDeclaration', // test() {...} - "Pop", - "MethodInvocation", // test.main([""]) + 'Pop', + 'MethodInvocation', // test.main([""]) - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // test - "ResOverload", // main - "ResType", // [""] - "ResType", // test + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // test - "Deref", - "EvalVariable", // test + 'Deref', + 'EvalVariable', // test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; - "ExpressionStatement", // test.test(); - "LocalVariableDeclarationStatement", // test test = new test(1); + 'Env', // from Block + 'ReturnStatement', // return; + 'ExpressionStatement', // test.test(); + 'LocalVariableDeclarationStatement', // test test = new test(1); - "ExpressionStatement", // test = new test(1); - "LocalVariableDeclarationStatement", // test test; + 'ExpressionStatement', // test = new test(1); + 'LocalVariableDeclarationStatement', // test test; - "Pop", - "Assignment", // test = new test(1) + 'Pop', + 'Assignment', // test = new test(1) - "Assign", // = - "ClassInstanceCreationExpression", // new test(1) - "EvalVariable", // test + 'Assign', // = + 'ClassInstanceCreationExpression', // new test(1) + 'EvalVariable', // test - "Invocation", // () - "Literal", // 2 - "New", // new - "ResConOverload", // test - "ResType", // 1 - "ResType", // test + 'Invocation', // () + 'Literal', // 2 + 'New', // new + 'ResConOverload', // test + 'ResType', // 1 + 'ResType', // test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; - "ExpressionStatement", // this.x = x; - "ExpressionStatement", // this.x = 0; - "ExplicitConstructorInvocation", // super(); + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExpressionStatement', // this.x = x; + 'ExpressionStatement', // this.x = 0; + 'ExplicitConstructorInvocation', // super(); - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Object - "ResType", // super + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Object + 'ResType', // super - "Deref", - "EvalVariable", // super + 'Deref', + 'EvalVariable', // super - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; + 'Env', // from Block + 'ReturnStatement', // return this; - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "Pop", - "Assignment", // this.x = 0 + 'Pop', + 'Assignment', // this.x = 0 - "Assign", // = - "Literal", // 0 - "EvalVariable", // this.x + 'Assign', // = + 'Literal', // 0 + 'EvalVariable', // this.x - "Res", // x - "EvalVariable", // this + 'Res', // x + 'EvalVariable', // this - "Pop", - "Assignment", // this.x = x; + 'Pop', + 'Assignment', // this.x = x; - "Assign", // = - "ExpressionName", // x - "EvalVariable", // this.x + 'Assign', // = + 'ExpressionName', // x + 'EvalVariable', // this.x - "Res", // x - "EvalVariable", // this + 'Res', // x + 'EvalVariable', // this - "Deref", - "EvalVariable", // x + 'Deref', + 'EvalVariable', // x - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // skip Env from Block + 'Reset', // skip Env from Block - "Pop", - "MethodInvocation", // test.test() + 'Pop', + 'MethodInvocation', // test.test() - "Invocation", // () - "ResOverride", - "ExpressionName", // test - "ResOverload", // test - "ResType", // test + 'Invocation', // () + 'ResOverride', + 'ExpressionName', // test + 'ResOverload', // test + 'ResType', // test - "Deref", - "EvalVariable", // test + 'Deref', + 'EvalVariable', // test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; - "ExpressionStatement", // this.x = 3; + 'Env', // from Block + 'ReturnStatement', // return; + 'ExpressionStatement', // this.x = 3; - "Pop", - "Assignment", // this.x = 3 + 'Pop', + 'Assignment', // this.x = 3 - "Assign", // = - "Literal", // 3 - "EvalVariable", // this.x + 'Assign', // = + 'Literal', // 3 + 'EvalVariable', // this.x - "Res", // x - "EvalVariable", // this + 'Res', // x + 'EvalVariable', // this - "Reset", // return - "Void", + 'Reset', // return + 'Void', - "Reset", // skip Env from Block + 'Reset', // skip Env from Block - "Reset", // return - "Void", + 'Reset', // return + 'Void', - "Reset", // skip Env from Block - ]; + 'Reset' // skip Env from Block + ] const expectedStashTrace = [ - "test", // ResType - "String[]", // ResType - "main", // ResOverload - "test", // EvalVariable - "test", // Deref - "main", // ResOverride + 'test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'test', // EvalVariable + 'test', // Deref + 'main', // ResOverride `[""]`, // Literal - "test", // EvalVariable - "test", // ResType - "int", // ResType - "test", // ResConOverlaod - "Object", // New - "2", // Literal - "Object", // ResType - "Object", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "x", // Res - "0", // Literal - "0", // Assign - "this", // EvalVariable - "x", // Res - "x", // EvalVariable - "2", // Deref - "2", // Assign - "this", // EvalVariable - "Object", // Deref - "Object", // Assign - "test", // ResType - "test", // ResOverload - "test", // EvalVariable - "Object", // Deref - "test", // ResOverride - "Object", - "this", // EvalVariable - "x", // Res - "3", // Literal - "3", // Assign - "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); + 'test', // EvalVariable + 'test', // ResType + 'int', // ResType + 'test', // ResConOverlaod + 'Object', // New + '2', // Literal + 'Object', // ResType + 'Object', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'x', // Res + '0', // Literal + '0', // Assign + 'this', // EvalVariable + 'x', // Res + 'x', // EvalVariable + '2', // Deref + '2', // Assign + 'this', // EvalVariable + 'Object', // Deref + 'Object', // Assign + 'test', // ResType + 'test', // ResOverload + 'test', // EvalVariable + 'Object', // Deref + 'test', // ResOverride + 'Object', + 'this', // EvalVariable + 'x', // Res + '3', // Literal + '3', // Assign + '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 + ) // TODO test env - }); -}); + }) +}) diff --git a/src/ec-evaluator/__tests__/mtd-overloading.test.ts b/src/ec-evaluator/__tests__/mtd-overloading.test.ts index 7345884..201d806 100644 --- a/src/ec-evaluator/__tests__/mtd-overloading.test.ts +++ b/src/ec-evaluator/__tests__/mtd-overloading.test.ts @@ -1,16 +1,16 @@ -import { parse } from "../../ast/parser"; -import { ResOverloadAmbiguousError, ResOverloadError } from "../errors"; -import { evaluate } from "../interpreter"; +import { parse } from '../../ast/parser' +import { ResOverloadAmbiguousError, ResOverloadError } from '../errors' +import { evaluate } from '../interpreter' import { ControlStub, StashStub, createContextStub, getControlItemStr, getStashItemStr -} from "./__utils__/utils"; +} from './__utils__/utils' -describe("evaluate method overloading correctly", () => { - it("should resolve to test(int x) instead of test()", () => { +describe('evaluate method overloading correctly', () => { + it('should resolve to test(int x) instead of test()', () => { const programStr = ` class Test { public static void main(String[] args) { @@ -21,124 +21,124 @@ describe("evaluate method overloading correctly", () => { return x; } } - `; - - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); - - const context = createContextStub(); - context.control.push(compilationUnit!); - - const result = evaluate(context); - + ` + + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() + + const context = createContextStub() + context.control.push(compilationUnit!) + + const result = evaluate(context) + const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class Test {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} - - "Env", - "MethodDeclaration", // static void test() {...} - "MethodDeclaration", // static void test(int x) {...} - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} - - "Pop", - "MethodInvocation", // Test.main([""]) - - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test - - "Deref", - "EvalVariable", // Test - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return; - "LocalVariableDeclarationStatement", // int x = Test.test(1); - - "ExpressionStatement", // x = Test.test(1); - "LocalVariableDeclarationStatement", // int x; - - "Pop", - "Assignment", // x = Test.test(1) - - "Assign", // = - "MethodInvocation", // Test.test(1) - "EvalVariable", // x - - "Invocation", // () - "Literal", // 1 - "ResOverride", - "ExpressionName", // Test - "ResOverload", // test - "ResType", // 1 - "ResType", // Test - - "Deref", - "EvalVariable", // Test - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return x; - - "Reset", // return - "ExpressionName", // x - - "Deref", - "EvalVariable", // x - - "Reset", // skip Env from Block - - "Reset", // return - "Void", - - "Reset", // skip Env from Block - ]; + 'CompilationUnit', + + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class Test {...} + + 'Env', + 'MethodDeclaration', // static void test() {...} + 'MethodDeclaration', // static void test(int x) {...} + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} + + 'Pop', + 'MethodInvocation', // Test.main([""]) + + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test + + 'Deref', + 'EvalVariable', // Test + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return; + 'LocalVariableDeclarationStatement', // int x = Test.test(1); + + 'ExpressionStatement', // x = Test.test(1); + 'LocalVariableDeclarationStatement', // int x; + + 'Pop', + 'Assignment', // x = Test.test(1) + + 'Assign', // = + 'MethodInvocation', // Test.test(1) + 'EvalVariable', // x + + 'Invocation', // () + 'Literal', // 1 + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // test + 'ResType', // 1 + 'ResType', // Test + + 'Deref', + 'EvalVariable', // Test + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return x; + + 'Reset', // return + 'ExpressionName', // x + + 'Deref', + 'EvalVariable', // x + + 'Reset', // skip Env from Block + + 'Reset', // return + 'Void', + + 'Reset' // skip Env from Block + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "x", // EvalVariable - "Test", // ResType - "int", // ResType - "test", // ResOverlaod - "Test", // EvalVariable - "Test", // Deref - "test", // ResOverride - "1", // Literal - "x", // EvalVariable - "1", // Deref - "1", // Assign - "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); + 'x', // EvalVariable + 'Test', // ResType + 'int', // ResType + 'test', // ResOverlaod + 'Test', // EvalVariable + 'Test', // Deref + 'test', // ResOverride + '1', // Literal + 'x', // EvalVariable + '1', // Deref + '1', // Assign + '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 + ) // TODO test env - }); + }) - it("should resolve to void Test() instead of constructor with similar descriptor", () => { + it('should resolve to void Test() instead of constructor with similar descriptor', () => { const programStr = ` class Test { int x; @@ -156,230 +156,229 @@ describe("evaluate method overloading correctly", () => { this.x = 3; } } - `; - - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); - - const context = createContextStub(); - context.control.push(compilationUnit!); - - const result = evaluate(context); - + ` + + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() + + const context = createContextStub() + context.control.push(compilationUnit!) + + const result = evaluate(context) + const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class Test {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} - - "Env", - "MethodDeclaration", // void Test() {...} - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test(int x) {...} - "ConstructorDeclaration", // Test() {...} - - "Pop", - "MethodInvocation", // Test.main([""]) - - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test - - "Deref", - "EvalVariable", // Test - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return; - "ExpressionStatement", // Test.Test(); - "LocalVariableDeclarationStatement", // Test Test = new Test(1); - - "ExpressionStatement", // Test = new Test(1); - "LocalVariableDeclarationStatement", // Test Test; - - "Pop", - "Assignment", // Test = new Test(1) - - "Assign", // = - "ClassInstanceCreationExpression", // new Test(1) - "EvalVariable", // Test - - "Invocation", // () - "Literal", // 2 - "New", // new - "ResConOverload", // Test - "ResType", // 1 - "ResType", // Test - "Env", // from Invocation - "Marker", - "Block", // {...} - - - "Env", // from Block - "ReturnStatement", // return this; - "ExpressionStatement", // this.x = x; - "ExpressionStatement", // this.x = 0; - "ExplicitConstructorInvocation", // super(); - - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Object - "ResType", // super - - "Deref", - "EvalVariable", // super - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return this; - - "Reset", // return - "ExpressionName", // this - - "Deref", - "EvalVariable", // this - - "Reset", // Skip Env from Block - - "Pop", - "Assignment", // this.x = 0 - - "Assign", // = - "Literal", // 0 - "EvalVariable", // this.x - - "Res", // x - "EvalVariable", // this - - "Pop", - "Assignment", // this.x = x; - - "Assign", // = - "ExpressionName", // x - "EvalVariable", // this.x - - "Res", // x - "EvalVariable", // this - - "Deref", - "EvalVariable", // x - - "Reset", // return - "ExpressionName", // this - - "Deref", - "EvalVariable", // this - - "Reset", // skip Env from Block - - "Pop", - "MethodInvocation", // Test.Test() - - "Invocation", // () - "ResOverride", - "ExpressionName", // Test - "ResOverload", // Test - "ResType", // Test - - "Deref", - "EvalVariable", // Test - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return; - "ExpressionStatement", // this.x = 3; - - "Pop", - "Assignment", // this.x = 3 - - "Assign", // = - "Literal", // 3 - "EvalVariable", // this.x - - "Res", // x - "EvalVariable", // this - - "Reset", // return - "Void", - - "Reset", // skip Env from Block - - "Reset", // return - "Void", - - "Reset", // skip Env from Block - ]; + 'CompilationUnit', + + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class Test {...} + + 'Env', + 'MethodDeclaration', // void Test() {...} + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test(int x) {...} + 'ConstructorDeclaration', // Test() {...} + + 'Pop', + 'MethodInvocation', // Test.main([""]) + + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test + + 'Deref', + 'EvalVariable', // Test + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return; + 'ExpressionStatement', // Test.Test(); + 'LocalVariableDeclarationStatement', // Test Test = new Test(1); + + 'ExpressionStatement', // Test = new Test(1); + 'LocalVariableDeclarationStatement', // Test Test; + + 'Pop', + 'Assignment', // Test = new Test(1) + + 'Assign', // = + 'ClassInstanceCreationExpression', // new Test(1) + 'EvalVariable', // Test + + 'Invocation', // () + 'Literal', // 2 + 'New', // new + 'ResConOverload', // Test + 'ResType', // 1 + 'ResType', // Test + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExpressionStatement', // this.x = x; + 'ExpressionStatement', // this.x = 0; + 'ExplicitConstructorInvocation', // super(); + + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Object + 'ResType', // super + + 'Deref', + 'EvalVariable', // super + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return this; + + 'Reset', // return + 'ExpressionName', // this + + 'Deref', + 'EvalVariable', // this + + 'Reset', // Skip Env from Block + + 'Pop', + 'Assignment', // this.x = 0 + + 'Assign', // = + 'Literal', // 0 + 'EvalVariable', // this.x + + 'Res', // x + 'EvalVariable', // this + + 'Pop', + 'Assignment', // this.x = x; + + 'Assign', // = + 'ExpressionName', // x + 'EvalVariable', // this.x + + 'Res', // x + 'EvalVariable', // this + + 'Deref', + 'EvalVariable', // x + + 'Reset', // return + 'ExpressionName', // this + + 'Deref', + 'EvalVariable', // this + + 'Reset', // skip Env from Block + + 'Pop', + 'MethodInvocation', // Test.Test() + + 'Invocation', // () + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // Test + 'ResType', // Test + + 'Deref', + 'EvalVariable', // Test + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return; + 'ExpressionStatement', // this.x = 3; + + 'Pop', + 'Assignment', // this.x = 3 + + 'Assign', // = + 'Literal', // 3 + 'EvalVariable', // this.x + + 'Res', // x + 'EvalVariable', // this + + 'Reset', // return + 'Void', + + 'Reset', // skip Env from Block + + 'Reset', // return + 'Void', + + 'Reset' // skip Env from Block + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "Test", // EvalVariable - "Test", // ResType - "int", // ResType - "Test", // ResConOverlaod - "Object", // New - "2", // Literal - "Object", // ResType - "Object", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "x", // Res - "0", // Literal - "0", // Assign - "this", // EvalVariable - "x", // Res - "x", // EvalVariable - "2", // Deref - "2", // Assign - "this", // EvalVariable - "Object", // Deref - "Object", // Assign - "Test", // ResType - "Test", // ResOverload - "Test", // EvalVariable - "Object", // Deref - "Test", // ResOverride - "Object", - "this", // EvalVariable - "x", // Res - "3", // Literal - "3", // Assign - "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); + 'Test', // EvalVariable + 'Test', // ResType + 'int', // ResType + 'Test', // ResConOverlaod + 'Object', // New + '2', // Literal + 'Object', // ResType + 'Object', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'x', // Res + '0', // Literal + '0', // Assign + 'this', // EvalVariable + 'x', // Res + 'x', // EvalVariable + '2', // Deref + '2', // Assign + 'this', // EvalVariable + 'Object', // Deref + 'Object', // Assign + 'Test', // ResType + 'Test', // ResOverload + 'Test', // EvalVariable + 'Object', // Deref + 'Test', // ResOverride + 'Object', + 'this', // EvalVariable + 'x', // Res + '3', // Literal + '3', // Assign + '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 + ) // TODO test env - }); + }) - it("should invoke overloaded instance method with supertype", () => { + it('should invoke overloaded instance method with supertype', () => { const programStr = ` class Parent { int x; @@ -393,249 +392,249 @@ describe("evaluate method overloading correctly", () => { x = 2; } } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class Test extends Parent {...} - "NormalClassDeclaration", // class Parent {...} - "NormalClassDeclaration", // class Object {...} + 'CompilationUnit', - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class Test extends Parent {...} + 'NormalClassDeclaration', // class Parent {...} - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Parent() {...} + 'Env', // from NormalClassDeclaration + 'ConstructorDeclaration', // Parent() {...} - "Env", // from NormalClassDeclaration - "MethodDeclaration", // void test(Parent p) {...} - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // void test(Parent p) {...} + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} - "Pop", - "MethodInvocation", // Test.main([""]) + 'Pop', + 'MethodInvocation', // Test.main([""]) - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test - "Deref", - "EvalVariable", // Test + 'Deref', + 'EvalVariable', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; - "ExpressionStatement", // t.test(t); - "LocalVariableDeclarationStatement", // Test t = new Test(); + 'Env', // from Block + 'ReturnStatement', // return; + 'ExpressionStatement', // t.test(t); + 'LocalVariableDeclarationStatement', // Test t = new Test(); - "ExpressionStatement", // t = new Test(); - "LocalVariableDeclarationStatement", // Test t; + 'ExpressionStatement', // t = new Test(); + 'LocalVariableDeclarationStatement', // Test t; - "Pop", - "Assignment", // t = new Test() + 'Pop', + 'Assignment', // t = new Test() - "Assign", // = - "ClassInstanceCreationExpression", // new Test() - "EvalVariable", // t + 'Assign', // = + 'ClassInstanceCreationExpression', // new Test() + 'EvalVariable', // t - "Invocation", // () - "New", // new - "ResConOverload", // Test - "ResType", // Test + 'Invocation', // () + 'New', // new + 'ResConOverload', // Test + 'ResType', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; - "ExplicitConstructorInvocation", // super(); + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExplicitConstructorInvocation', // super(); - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Parent - "ResType", // super + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Parent + 'ResType', // super - "Deref", - "EvalVariable", // super + 'Deref', + 'EvalVariable', // super - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; - "ExpressionStatement", // this.x = 0; - "ExplicitConstructorInvocation", // super(); + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExpressionStatement', // this.x = 0; + 'ExplicitConstructorInvocation', // super(); - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Object - "ResType", // super + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Object + 'ResType', // super - "Deref", - "EvalVariable", // super + 'Deref', + 'EvalVariable', // super - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; + 'Env', // from Block + 'ReturnStatement', // return this; - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "Pop", - "Assignment", // this.x = 0 + 'Pop', + 'Assignment', // this.x = 0 - "Assign", // = - "Literal", // 0 - "EvalVariable", // this.x + 'Assign', // = + 'Literal', // 0 + 'EvalVariable', // this.x - "Res", // x - "EvalVariable", // this + 'Res', // x + 'EvalVariable', // this - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "Pop", - "MethodInvocation", // t.test(t) + 'Pop', + 'MethodInvocation', // t.test(t) - "Invocation", // () - "ExpressionName", // t - "ResOverride", - "ExpressionName", // t - "ResOverload", // test - "ResType", // t - "ResType", // t + 'Invocation', // () + 'ExpressionName', // t + 'ResOverride', + 'ExpressionName', // t + 'ResOverload', // test + 'ResType', // t + 'ResType', // t - "Deref", - "EvalVariable", // t + 'Deref', + 'EvalVariable', // t - "Deref", - "EvalVariable", // t + 'Deref', + 'EvalVariable', // t - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; - "ExpressionStatement", // this.x = 2; + 'Env', // from Block + 'ReturnStatement', // return; + 'ExpressionStatement', // this.x = 2; - "Pop", - "Assignment", // this.x = 2 + 'Pop', + 'Assignment', // this.x = 2 - "Assign", // = - "Literal", // 2 - "EvalVariable", // this.x + 'Assign', // = + 'Literal', // 2 + 'EvalVariable', // this.x - "Res", // x - "EvalVariable", // this + 'Res', // x + 'EvalVariable', // this - "Reset", // return - "Void", + 'Reset', // return + 'Void', - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "Reset", // return - "Void", + 'Reset', // return + 'Void', - "Reset", // Skip Env from Block - ]; + 'Reset' // Skip Env from Block + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "t", // EvalVariable - "Test", // ResType - "Test", // ResConOverload - "Object", // New - "Parent", // ResType - "Parent", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "Object", // ResType - "Object", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "x", // Res - "0", // Literal - "0", // Assign - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "Object", // Assign - "Test", // ResType - "Test", // ResType - "test", // ResOverload - "t", // EvalVariable - "Object", // Deref - "test", // ResOverride - "Object", - "t", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "x", // Res - "2", // Literal - "2", // Assign - "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); + 't', // EvalVariable + 'Test', // ResType + 'Test', // ResConOverload + 'Object', // New + 'Parent', // ResType + 'Parent', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'Object', // ResType + 'Object', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'x', // Res + '0', // Literal + '0', // Assign + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'Object', // Assign + 'Test', // ResType + 'Test', // ResType + 'test', // ResOverload + 't', // EvalVariable + 'Object', // Deref + 'test', // ResOverride + 'Object', + 't', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'x', // Res + '2', // Literal + '2', // Assign + '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 + ) // TODO test env - }); + }) - it("should not invoke overloaded instance method with supertype", () => { + it('should not invoke overloaded instance method with supertype', () => { const programStr = ` class Parent { int x; @@ -652,250 +651,250 @@ describe("evaluate method overloading correctly", () => { x = 3; } } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class Test extends Parent {...} - "NormalClassDeclaration", // class Parent {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Parent() {...} - - "Env", // from NormalClassDeclaration - "MethodDeclaration", // void test(Test t) {...} - "MethodDeclaration", // void test(Parent p) {...} - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} - - "Pop", - "MethodInvocation", // Test.main([""]) - - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test + 'CompilationUnit', + + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class Test extends Parent {...} + 'NormalClassDeclaration', // class Parent {...} + + 'Env', // from NormalClassDeclaration + 'ConstructorDeclaration', // Parent() {...} + + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // void test(Test t) {...} + 'MethodDeclaration', // void test(Parent p) {...} + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} + + 'Pop', + 'MethodInvocation', // Test.main([""]) + + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test - "Deref", - "EvalVariable", // Test + 'Deref', + 'EvalVariable', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; - "ExpressionStatement", // t.test(t); - "LocalVariableDeclarationStatement", // Test t = new Test(); + 'Env', // from Block + 'ReturnStatement', // return; + 'ExpressionStatement', // t.test(t); + 'LocalVariableDeclarationStatement', // Test t = new Test(); - "ExpressionStatement", // t = new Test(); - "LocalVariableDeclarationStatement", // Test t; + 'ExpressionStatement', // t = new Test(); + 'LocalVariableDeclarationStatement', // Test t; - "Pop", - "Assignment", // t = new Test() + 'Pop', + 'Assignment', // t = new Test() - "Assign", // = - "ClassInstanceCreationExpression", // new Test() - "EvalVariable", // t + 'Assign', // = + 'ClassInstanceCreationExpression', // new Test() + 'EvalVariable', // t - "Invocation", // () - "New", // new - "ResConOverload", // Test - "ResType", // Test + 'Invocation', // () + 'New', // new + 'ResConOverload', // Test + 'ResType', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; - "ExplicitConstructorInvocation", // super(); + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExplicitConstructorInvocation', // super(); - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Parent - "ResType", // super + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Parent + 'ResType', // super - "Deref", - "EvalVariable", // super + 'Deref', + 'EvalVariable', // super - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; - "ExpressionStatement", // this.x = 0; - "ExplicitConstructorInvocation", // super(); + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExpressionStatement', // this.x = 0; + 'ExplicitConstructorInvocation', // super(); - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Object - "ResType", // super + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Object + 'ResType', // super - "Deref", - "EvalVariable", // super + 'Deref', + 'EvalVariable', // super - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; + 'Env', // from Block + 'ReturnStatement', // return this; - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "Pop", - "Assignment", // this.x = 0 + 'Pop', + 'Assignment', // this.x = 0 - "Assign", // = - "Literal", // 0 - "EvalVariable", // this.x + 'Assign', // = + 'Literal', // 0 + 'EvalVariable', // this.x - "Res", // x - "EvalVariable", // this + 'Res', // x + 'EvalVariable', // this - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "Pop", - "MethodInvocation", // t.test(t) + 'Pop', + 'MethodInvocation', // t.test(t) - "Invocation", // () - "ExpressionName", // t - "ResOverride", - "ExpressionName", // t - "ResOverload", // test - "ResType", // t - "ResType", // t + 'Invocation', // () + 'ExpressionName', // t + 'ResOverride', + 'ExpressionName', // t + 'ResOverload', // test + 'ResType', // t + 'ResType', // t - "Deref", - "EvalVariable", // t + 'Deref', + 'EvalVariable', // t - "Deref", - "EvalVariable", // t + 'Deref', + 'EvalVariable', // t - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; - "ExpressionStatement", // this.x = 3; + 'Env', // from Block + 'ReturnStatement', // return; + 'ExpressionStatement', // this.x = 3; - "Pop", - "Assignment", // this.x = 3 + 'Pop', + 'Assignment', // this.x = 3 - "Assign", // = - "Literal", // 3 - "EvalVariable", // this.x + 'Assign', // = + 'Literal', // 3 + 'EvalVariable', // this.x - "Res", // x - "EvalVariable", // this + 'Res', // x + 'EvalVariable', // this - "Reset", // return - "Void", + 'Reset', // return + 'Void', - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "Reset", // return - "Void", + 'Reset', // return + 'Void', - "Reset", // Skip Env from Block - ]; + 'Reset' // Skip Env from Block + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "t", // EvalVariable - "Test", // ResType - "Test", // ResConOverload - "Object", // New - "Parent", // ResType - "Parent", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "Object", // ResType - "Object", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "x", // Res - "0", // Literal - "0", // Assign - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "Object", // Assign - "Test", // ResType - "Test", // ResType - "test", // ResOverload - "t", // EvalVariable - "Object", // Deref - "test", // ResOverride - "Object", - "t", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "x", // Res - "3", // Literal - "3", // Assign - "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); + 't', // EvalVariable + 'Test', // ResType + 'Test', // ResConOverload + 'Object', // New + 'Parent', // ResType + 'Parent', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'Object', // ResType + 'Object', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'x', // Res + '0', // Literal + '0', // Assign + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'Object', // Assign + 'Test', // ResType + 'Test', // ResType + 'test', // ResOverload + 't', // EvalVariable + 'Object', // Deref + 'test', // ResOverride + 'Object', + 't', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'x', // Res + '3', // Literal + '3', // Assign + '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 + ) // TODO test env - }); + }) - it("should invoke most specific overloaded instance method", () => { + it('should invoke most specific overloaded instance method', () => { const programStr = ` class Parent { int x; @@ -912,258 +911,258 @@ describe("evaluate method overloading correctly", () => { x = 2; } } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class Test extends Parent {...} - "NormalClassDeclaration", // class Parent {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Parent() {...} - - "Env", // from NormalClassDeclaration - "MethodDeclaration", // void test(Test t1, Test t2) {...} - "MethodDeclaration", // void test(Test t, Parent p) {...} - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} - - "Pop", - "MethodInvocation", // Test.main([""]) - - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test + 'CompilationUnit', - "Deref", - "EvalVariable", // Test + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class Test extends Parent {...} + 'NormalClassDeclaration', // class Parent {...} - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from NormalClassDeclaration + 'ConstructorDeclaration', // Parent() {...} - "Env", // from Block - "ReturnStatement", // return; - "ExpressionStatement", // t.test(t, t); - "LocalVariableDeclarationStatement", // Test t = new Test(); + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // void test(Test t1, Test t2) {...} + 'MethodDeclaration', // void test(Test t, Parent p) {...} + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} - "ExpressionStatement", // t = new Test(); - "LocalVariableDeclarationStatement", // Test t; - - "Pop", - "Assignment", // t = new Test() - - "Assign", // = - "ClassInstanceCreationExpression", // new Test() - "EvalVariable", // t + 'Pop', + 'MethodInvocation', // Test.main([""]) - "Invocation", // () - "New", // new - "ResConOverload", // Test - "ResType", // Test + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Deref', + 'EvalVariable', // Test - "Env", // from Block - "ReturnStatement", // return this; - "ExplicitConstructorInvocation", // super(); + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Parent - "ResType", // super + 'Env', // from Block + 'ReturnStatement', // return; + 'ExpressionStatement', // t.test(t, t); + 'LocalVariableDeclarationStatement', // Test t = new Test(); - "Deref", - "EvalVariable", // super + 'ExpressionStatement', // t = new Test(); + 'LocalVariableDeclarationStatement', // Test t; - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Pop', + 'Assignment', // t = new Test() - "Env", // from Block - "ReturnStatement", // return this; - "ExpressionStatement", // this.x = 0; - "ExplicitConstructorInvocation", // super(); + 'Assign', // = + 'ClassInstanceCreationExpression', // new Test() + 'EvalVariable', // t - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Object - "ResType", // super + 'Invocation', // () + 'New', // new + 'ResConOverload', // Test + 'ResType', // Test - "Deref", - "EvalVariable", // super + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExplicitConstructorInvocation', // super(); - "Env", // from Block - "ReturnStatement", // return this; + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Parent + 'ResType', // super - "Reset", // return - "ExpressionName", // this + 'Deref', + 'EvalVariable', // super - "Deref", - "EvalVariable", // this + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Reset", // Skip Env from Block + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExpressionStatement', // this.x = 0; + 'ExplicitConstructorInvocation', // super(); - "Pop", - "Assignment", // this.x = 0 + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Object + 'ResType', // super - "Assign", // = - "Literal", // 0 - "EvalVariable", // this.x + 'Deref', + 'EvalVariable', // super - "Res", // x - "EvalVariable", // this + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Reset", // return - "ExpressionName", // this + 'Env', // from Block + 'ReturnStatement', // return this; - "Deref", - "EvalVariable", // this + 'Reset', // return + 'ExpressionName', // this - "Reset", // Skip Env from Block + 'Deref', + 'EvalVariable', // this - "Reset", // return - "ExpressionName", // this + 'Reset', // Skip Env from Block - "Deref", - "EvalVariable", // this + 'Pop', + 'Assignment', // this.x = 0 - "Reset", // Skip Env from Block + 'Assign', // = + 'Literal', // 0 + 'EvalVariable', // this.x - "Pop", - "MethodInvocation", // t.test(t, t) + 'Res', // x + 'EvalVariable', // this - "Invocation", // () - "ExpressionName", // t - "ExpressionName", // t - "ResOverride", - "ExpressionName", // t - "ResOverload", // test - "ResType", // t - "ResType", // t - "ResType", // t + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // t + 'Deref', + 'EvalVariable', // this - "Deref", - "EvalVariable", // t + 'Reset', // Skip Env from Block - "Deref", - "EvalVariable", // t + 'Reset', // return + 'ExpressionName', // this - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Deref', + 'EvalVariable', // this - "Env", // from Block - "ReturnStatement", // return; - "ExpressionStatement", // this.x = 3; + 'Reset', // Skip Env from Block - "Pop", - "Assignment", // this.x = 3 + 'Pop', + 'MethodInvocation', // t.test(t, t) - "Assign", // = - "Literal", // 3 - "EvalVariable", // this.x + 'Invocation', // () + 'ExpressionName', // t + 'ExpressionName', // t + 'ResOverride', + 'ExpressionName', // t + 'ResOverload', // test + 'ResType', // t + 'ResType', // t + 'ResType', // t - "Res", // x - "EvalVariable", // this + 'Deref', + 'EvalVariable', // t - "Reset", // return - "Void", + 'Deref', + 'EvalVariable', // t - "Reset", // Skip Env from Block + 'Deref', + 'EvalVariable', // t - "Reset", // return - "Void", + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Reset", // Skip Env from Block - ]; + 'Env', // from Block + 'ReturnStatement', // return; + 'ExpressionStatement', // this.x = 3; + + 'Pop', + 'Assignment', // this.x = 3 + + 'Assign', // = + 'Literal', // 3 + 'EvalVariable', // this.x + + 'Res', // x + 'EvalVariable', // this + + 'Reset', // return + 'Void', + + 'Reset', // Skip Env from Block + + 'Reset', // return + 'Void', + + 'Reset' // Skip Env from Block + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "t", // EvalVariable - "Test", // ResType - "Test", // ResConOverload - "Object", // New - "Parent", // ResType - "Parent", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "Object", // ResType - "Object", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "x", // Res - "0", // Literal - "0", // Assign - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "Object", // Assign - "Test", // ResType - "Test", // ResType - "Test", // ResType - "test", // ResOverload - "t", // EvalVariable - "Object", // Deref - "test", // ResOverride - "Object", - "t", // EvalVariable - "Object", // Deref - "t", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "x", // Res - "3", // Literal - "3", // Assign - "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); + 't', // EvalVariable + 'Test', // ResType + 'Test', // ResConOverload + 'Object', // New + 'Parent', // ResType + 'Parent', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'Object', // ResType + 'Object', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'x', // Res + '0', // Literal + '0', // Assign + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'Object', // Assign + 'Test', // ResType + 'Test', // ResType + 'Test', // ResType + 'test', // ResOverload + 't', // EvalVariable + 'Object', // Deref + 'test', // ResOverride + 'Object', + 't', // EvalVariable + 'Object', // Deref + 't', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'x', // Res + '3', // Literal + '3', // Assign + '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 + ) // TODO test env - }); + }) - it("should throw ambiguous method overloading error", () => { + it('should throw ambiguous method overloading error', () => { const programStr = ` class Parent { int x; @@ -1180,18 +1179,18 @@ describe("evaluate method overloading correctly", () => { x = 2; } } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - expect(() => evaluate(context)).toThrowError(ResOverloadAmbiguousError); - }); + expect(() => evaluate(context)).toThrowError(ResOverloadAmbiguousError) + }) - it("should fail method overloading resolution", () => { + it('should fail method overloading resolution', () => { const programStr = ` class Parent {} class Test extends Parent { @@ -1201,18 +1200,18 @@ describe("evaluate method overloading correctly", () => { } void test() {} } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - expect(() => evaluate(context)).toThrowError(ResOverloadError); - }); + expect(() => evaluate(context)).toThrowError(ResOverloadError) + }) - it("should invoke inherited method", () => { + it('should invoke inherited method', () => { const programStr = ` class Parent { static void test() {} @@ -1222,106 +1221,106 @@ describe("evaluate method overloading correctly", () => { test(); } } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class Test extends Parent {...} - "NormalClassDeclaration", // class Parent {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} - - "Env", // from NormalClassDeclaration - "MethodDeclaration", // static void test() {...} - "ConstructorDeclaration", // Parent() {...} - - "Env", // from NormalClassDeclaration - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} - - "Pop", - "MethodInvocation", // Test.main([""]) - - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test - - "Deref", - "EvalVariable", // Test - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return; - "ExpressionStatement", // Test.test(); - - "Pop", - "MethodInvocation", // Test.test() - - "Invocation", // () - "ResOverride", - "ExpressionName", // Test - "ResOverload", // test - "ResType", // Test - - "Deref", - "EvalVariable", // Test - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return; - - "Reset", // return - "Void", - - "Reset", // Skip Env from Block - - "Reset", // return - "Void", - - "Reset", // Skip Env from Block - ]; + 'CompilationUnit', + + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class Test extends Parent {...} + 'NormalClassDeclaration', // class Parent {...} + + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // static void test() {...} + 'ConstructorDeclaration', // Parent() {...} + + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} + + 'Pop', + 'MethodInvocation', // Test.main([""]) + + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test + + 'Deref', + 'EvalVariable', // Test + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return; + 'ExpressionStatement', // Test.test(); + + 'Pop', + 'MethodInvocation', // Test.test() + + 'Invocation', // () + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // test + 'ResType', // Test + + 'Deref', + 'EvalVariable', // Test + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return; + + 'Reset', // return + 'Void', + + 'Reset', // Skip Env from Block + + 'Reset', // return + 'Void', + + 'Reset' // Skip Env from Block + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "Test", // ResType - "test", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "test", // ResOverride - "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); + 'Test', // ResType + 'test', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'test', // ResOverride + '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 + ) // TODO test env - }); -}); + }) +}) diff --git a/src/ec-evaluator/__tests__/mtd-overriding.test.ts b/src/ec-evaluator/__tests__/mtd-overriding.test.ts index 9de9854..6c43eb6 100644 --- a/src/ec-evaluator/__tests__/mtd-overriding.test.ts +++ b/src/ec-evaluator/__tests__/mtd-overriding.test.ts @@ -1,15 +1,15 @@ -import { parse } from "../../ast/parser"; -import { evaluate } from "../interpreter"; +import { parse } from '../../ast/parser' +import { evaluate } from '../interpreter' import { ControlStub, StashStub, createContextStub, getControlItemStr, getStashItemStr -} from "./__utils__/utils"; +} from './__utils__/utils' -describe("evaluate method overriding correctly", () => { - it("should invoke overriden instance method", () => { +describe('evaluate method overriding correctly', () => { + it('should invoke overriden instance method', () => { const programStr = ` class Parent { int x; @@ -26,242 +26,242 @@ describe("evaluate method overriding correctly", () => { x = 2; } } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class Test extends Parent {...} - "NormalClassDeclaration", // class Parent {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} - - "Env", // from NormalClassDeclaration - "MethodDeclaration", // void test() {...} - "ConstructorDeclaration", // Parent() {...} - - "Env", // from NormalClassDeclaration - "MethodDeclaration", // void test() {...} - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} - - "Pop", - "MethodInvocation", // Test.main([""]) - - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test + 'CompilationUnit', - "Deref", - "EvalVariable", // Test + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class Test extends Parent {...} + 'NormalClassDeclaration', // class Parent {...} - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // void test() {...} + 'ConstructorDeclaration', // Parent() {...} - "Env", // from Block - "ReturnStatement", // return; - "ExpressionStatement", // p.test(); - "LocalVariableDeclarationStatement", // Parent p = new Test(); + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // void test() {...} + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} - "ExpressionStatement", // p = new Test(); - "LocalVariableDeclarationStatement", // Parent p; + 'Pop', + 'MethodInvocation', // Test.main([""]) - "Pop", - "Assignment", // p = new Test() + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test - "Assign", // = - "ClassInstanceCreationExpression", // new Test() - "EvalVariable", // p + 'Deref', + 'EvalVariable', // Test - "Invocation", // () - "New", // new - "ResConOverload", // Test - "ResType", // Test + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Block + 'ReturnStatement', // return; + 'ExpressionStatement', // p.test(); + 'LocalVariableDeclarationStatement', // Parent p = new Test(); - "Env", // from Block - "ReturnStatement", // return this; - "ExplicitConstructorInvocation", // super(); + 'ExpressionStatement', // p = new Test(); + 'LocalVariableDeclarationStatement', // Parent p; - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Parent - "ResType", // super + 'Pop', + 'Assignment', // p = new Test() - "Deref", - "EvalVariable", // super + 'Assign', // = + 'ClassInstanceCreationExpression', // new Test() + 'EvalVariable', // p - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Invocation', // () + 'New', // new + 'ResConOverload', // Test + 'ResType', // Test - "Env", // from Block - "ReturnStatement", // return this; - "ExpressionStatement", // this.x = 0; - "ExplicitConstructorInvocation", // super(); + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Object - "ResType", // super + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExplicitConstructorInvocation', // super(); - "Deref", - "EvalVariable", // super + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Parent + 'ResType', // super - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Deref', + 'EvalVariable', // super - "Env", // from Block - "ReturnStatement", // return this; + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Reset", // return - "ExpressionName", // this + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExpressionStatement', // this.x = 0; + 'ExplicitConstructorInvocation', // super(); - "Deref", - "EvalVariable", // this + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Object + 'ResType', // super - "Reset", // Skip Env from Block + 'Deref', + 'EvalVariable', // super - "Pop", - "Assignment", // this.x = 0 + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Assign", // = - "Literal", // 0 - "EvalVariable", // this.x + 'Env', // from Block + 'ReturnStatement', // return this; - "Res", // x - "EvalVariable", // this + 'Reset', // return + 'ExpressionName', // this - "Reset", // return - "ExpressionName", // this + 'Deref', + 'EvalVariable', // this - "Deref", - "EvalVariable", // this + 'Reset', // Skip Env from Block - "Reset", // Skip Env from Block + 'Pop', + 'Assignment', // this.x = 0 - "Reset", // return - "ExpressionName", // this + 'Assign', // = + 'Literal', // 0 + 'EvalVariable', // this.x - "Deref", - "EvalVariable", // this + 'Res', // x + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // return + 'ExpressionName', // this - "Pop", - "MethodInvocation", // p.test() + 'Deref', + 'EvalVariable', // this - "Invocation", // () - "ResOverride", - "ExpressionName", // p - "ResOverload", // test - "ResType", // p + 'Reset', // Skip Env from Block - "Deref", - "EvalVariable", // p + 'Reset', // return + 'ExpressionName', // this - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Deref', + 'EvalVariable', // this - "Env", // from Block - "ReturnStatement", // return; - "ExpressionStatement", // this.x = 2; + 'Reset', // Skip Env from Block - "Pop", - "Assignment", // this.x = 2 + 'Pop', + 'MethodInvocation', // p.test() - "Assign", // = - "Literal", // 2 - "EvalVariable", // this.x + 'Invocation', // () + 'ResOverride', + 'ExpressionName', // p + 'ResOverload', // test + 'ResType', // p - "Res", // x - "EvalVariable", // this + 'Deref', + 'EvalVariable', // p - "Reset", // return - "Void", + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Reset", // Skip Env from Block + 'Env', // from Block + 'ReturnStatement', // return; + 'ExpressionStatement', // this.x = 2; - "Reset", // return - "Void", + 'Pop', + 'Assignment', // this.x = 2 - "Reset", // Skip Env from Block - ]; + 'Assign', // = + 'Literal', // 2 + 'EvalVariable', // this.x + + 'Res', // x + 'EvalVariable', // this + + 'Reset', // return + 'Void', + + 'Reset', // Skip Env from Block + + 'Reset', // return + 'Void', + + 'Reset' // Skip Env from Block + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "p", // EvalVariable - "Test", // ResType - "Test", // ResConOverload - "Object", // New - "Parent", // ResType - "Parent", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "Object", // ResType - "Object", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "x", // Res - "0", // Literal - "0", // Assign - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "Object", // Assign - "Parent", // ResType - "test", // ResOverload - "p", // EvalVariable - "Object", // Deref - "test", // ResOverride - "Object", - "this", // EvalVariable - "x", // Res - "2", // Literal - "2", // Assign - "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); + 'p', // EvalVariable + 'Test', // ResType + 'Test', // ResConOverload + 'Object', // New + 'Parent', // ResType + 'Parent', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'Object', // ResType + 'Object', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'x', // Res + '0', // Literal + '0', // Assign + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'Object', // Assign + 'Parent', // ResType + 'test', // ResOverload + 'p', // EvalVariable + 'Object', // Deref + 'test', // ResOverride + 'Object', + 'this', // EvalVariable + 'x', // Res + '2', // Literal + '2', // Assign + '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 + ) // TODO test env - }); + }) - it("should not invoke overriden static method", () => { + it('should not invoke overriden static method', () => { const programStr = ` class Parent { static int x; @@ -278,235 +278,235 @@ describe("evaluate method overriding correctly", () => { x = 2; } } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class Test extends Parent {...} - "NormalClassDeclaration", // class Parent {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} - - "Env", // from NormalClassDeclaration - "MethodDeclaration", // static void test() {...} - "ConstructorDeclaration", // Parent() {...} - "FieldDeclaration", // static int x = 0; - - "Pop", - "Assign", // = - "Literal", // 0 - "EvalVariable", // x - - "Env", // from NormalClassDeclaration - "MethodDeclaration", // static void test() {...} - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} - - "Pop", - "MethodInvocation", // Test.main([""]) + 'CompilationUnit', + + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class Test extends Parent {...} + 'NormalClassDeclaration', // class Parent {...} + + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // static void test() {...} + 'ConstructorDeclaration', // Parent() {...} + 'FieldDeclaration', // static int x = 0; + + 'Pop', + 'Assign', // = + 'Literal', // 0 + 'EvalVariable', // x + + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // static void test() {...} + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} + + 'Pop', + 'MethodInvocation', // Test.main([""]) + + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test - - "Deref", - "EvalVariable", // Test + 'Deref', + 'EvalVariable', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; - "ExpressionStatement", // p.test(); - "LocalVariableDeclarationStatement", // Parent p = new Test(); + 'Env', // from Block + 'ReturnStatement', // return; + 'ExpressionStatement', // p.test(); + 'LocalVariableDeclarationStatement', // Parent p = new Test(); - "ExpressionStatement", // p = new Test(); - "LocalVariableDeclarationStatement", // Parent p; + 'ExpressionStatement', // p = new Test(); + 'LocalVariableDeclarationStatement', // Parent p; - "Pop", - "Assignment", // p = new Test() + 'Pop', + 'Assignment', // p = new Test() - "Assign", // = - "ClassInstanceCreationExpression", // new Test() - "EvalVariable", // p + 'Assign', // = + 'ClassInstanceCreationExpression', // new Test() + 'EvalVariable', // p - "Invocation", // () - "New", // new - "ResConOverload", // Test - "ResType", // Test + 'Invocation', // () + 'New', // new + 'ResConOverload', // Test + 'ResType', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; - "ExplicitConstructorInvocation", // super(); + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExplicitConstructorInvocation', // super(); - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Parent - "ResType", // super + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Parent + 'ResType', // super - "Deref", - "EvalVariable", // super + 'Deref', + 'EvalVariable', // super - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; - "ExplicitConstructorInvocation", // super(); + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExplicitConstructorInvocation', // super(); - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Object - "ResType", // super + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Object + 'ResType', // super - "Deref", - "EvalVariable", // super + 'Deref', + 'EvalVariable', // super - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; + 'Env', // from Block + 'ReturnStatement', // return this; - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "Pop", - "MethodInvocation", // p.test() + 'Pop', + 'MethodInvocation', // p.test() - "Invocation", // () - "ResOverride", - "ExpressionName", // p - "ResOverload", // test - "ResType", // p + 'Invocation', // () + 'ResOverride', + 'ExpressionName', // p + 'ResOverload', // test + 'ResType', // p - "Deref", - "EvalVariable", // p + 'Deref', + 'EvalVariable', // p - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; - "ExpressionStatement", // this.x = 1; + 'Env', // from Block + 'ReturnStatement', // return; + 'ExpressionStatement', // this.x = 1; - "Pop", - "Assignment", // this.x = 1 + 'Pop', + 'Assignment', // this.x = 1 - "Assign", // = - "Literal", // 1 - "EvalVariable", // this.x + 'Assign', // = + 'Literal', // 1 + 'EvalVariable', // this.x - "Res", // x - "EvalVariable", // this + 'Res', // x + 'EvalVariable', // this - "Reset", // return - "Void", + 'Reset', // return + 'Void', - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "Reset", // return - "Void", + 'Reset', // return + 'Void', - "Reset", // Skip Env from Block - ]; + 'Reset' // Skip Env from Block + ] const expectedStashTrace = [ - "x", // Res - "0", // Literal - "0", // Assign - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'x', // Res + '0', // Literal + '0', // Assign + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "p", // EvalVariable - "Test", // ResType - "Test", // ResConOverload - "Object", // New - "Parent", // ResType - "Parent", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "Object", // ResType - "Object", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "Object", // Assign - "Parent", // ResType - "test", // ResOverload - "p", // EvalVariable - "Object", // Deref - "test", // ResOverride - "Parent", // EvalVariable - "x", // Res - "1", // Literal - "1", // Assign - "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); + 'p', // EvalVariable + 'Test', // ResType + 'Test', // ResConOverload + 'Object', // New + 'Parent', // ResType + 'Parent', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'Object', // ResType + 'Object', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'Object', // Assign + 'Parent', // ResType + 'test', // ResOverload + 'p', // EvalVariable + 'Object', // Deref + 'test', // ResOverride + 'Parent', // EvalVariable + 'x', // Res + '1', // Literal + '1', // Assign + '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 + ) // TODO test env - }); + }) - it("should not invoke overriden instance method with supertype", () => { + it('should not invoke overriden instance method with supertype', () => { const programStr = ` class Parent { int x; @@ -524,365 +524,365 @@ describe("evaluate method overriding correctly", () => { x = 2; } } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class Test extends Parent {...} - "NormalClassDeclaration", // class Parent {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} - - "Env", // from NormalClassDeclaration - "MethodDeclaration", // void test(Parent p) {...} - "ConstructorDeclaration", // Parent() {...} - - "Env", // from NormalClassDeclaration - "MethodDeclaration", // void test(Parent p) {...} - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} - - "Pop", - "MethodInvocation", // Test.main([""]) - - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test + 'CompilationUnit', - "Deref", - "EvalVariable", // Test + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class Test extends Parent {...} + 'NormalClassDeclaration', // class Parent {...} - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // void test(Parent p) {...} + 'ConstructorDeclaration', // Parent() {...} - "Env", // from Block - "ReturnStatement", // return; - "ExpressionStatement", // p.test(t); - "LocalVariableDeclarationStatement", // Test t = new Test(); - "LocalVariableDeclarationStatement", // Parent p = new Test(); + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // void test(Parent p) {...} + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} - "ExpressionStatement", // p = new Test(); - "LocalVariableDeclarationStatement", // Parent p; + 'Pop', + 'MethodInvocation', // Test.main([""]) - "Pop", - "Assignment", // p = new Test() + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test - "Assign", // = - "ClassInstanceCreationExpression", // new Test() - "EvalVariable", // p + 'Deref', + 'EvalVariable', // Test - "Invocation", // () - "New", // new - "ResConOverload", // Test - "ResType", // Test + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Block + 'ReturnStatement', // return; + 'ExpressionStatement', // p.test(t); + 'LocalVariableDeclarationStatement', // Test t = new Test(); + 'LocalVariableDeclarationStatement', // Parent p = new Test(); - "Env", // from Block - "ReturnStatement", // return this; - "ExplicitConstructorInvocation", // super(); + 'ExpressionStatement', // p = new Test(); + 'LocalVariableDeclarationStatement', // Parent p; - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Parent - "ResType", // super + 'Pop', + 'Assignment', // p = new Test() - "Deref", - "EvalVariable", // super + 'Assign', // = + 'ClassInstanceCreationExpression', // new Test() + 'EvalVariable', // p - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Invocation', // () + 'New', // new + 'ResConOverload', // Test + 'ResType', // Test - "Env", // from Block - "ReturnStatement", // return this; - "ExpressionStatement", // this.x = 0; - "ExplicitConstructorInvocation", // super(); + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Object - "ResType", // super + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExplicitConstructorInvocation', // super(); - "Deref", - "EvalVariable", // super + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Parent + 'ResType', // super - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Deref', + 'EvalVariable', // super - "Env", // from Block - "ReturnStatement", // return this; + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Reset", // return - "ExpressionName", // this + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExpressionStatement', // this.x = 0; + 'ExplicitConstructorInvocation', // super(); - "Deref", - "EvalVariable", // this + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Object + 'ResType', // super - "Reset", // Skip Env from Block + 'Deref', + 'EvalVariable', // super - "Pop", - "Assignment", // this.x = 0 + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Assign", // = - "Literal", // 0 - "EvalVariable", // this.x + 'Env', // from Block + 'ReturnStatement', // return this; - "Res", // x - "EvalVariable", // this + 'Reset', // return + 'ExpressionName', // this - "Reset", // return - "ExpressionName", // this + 'Deref', + 'EvalVariable', // this - "Deref", - "EvalVariable", // this + 'Reset', // Skip Env from Block - "Reset", // Skip Env from Block + 'Pop', + 'Assignment', // this.x = 0 - "Reset", // return - "ExpressionName", // this + 'Assign', // = + 'Literal', // 0 + 'EvalVariable', // this.x - "Deref", - "EvalVariable", // this + 'Res', // x + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // return + 'ExpressionName', // this - "ExpressionStatement", // t = new Test(); - "LocalVariableDeclarationStatement", // Test t; + 'Deref', + 'EvalVariable', // this - "Pop", - "Assignment", // t = new Test() + 'Reset', // Skip Env from Block - "Assign", // = - "ClassInstanceCreationExpression", // new Test() - "EvalVariable", // t + 'Reset', // return + 'ExpressionName', // this - "Invocation", // () - "New", // new - "ResConOverload", // Test - "ResType", // Test + 'Deref', + 'EvalVariable', // this - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Reset', // Skip Env from Block - "Env", // from Block - "ReturnStatement", // return this; - "ExplicitConstructorInvocation", // super(); + 'ExpressionStatement', // t = new Test(); + 'LocalVariableDeclarationStatement', // Test t; - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Parent - "ResType", // super + 'Pop', + 'Assignment', // t = new Test() - "Deref", - "EvalVariable", // super + 'Assign', // = + 'ClassInstanceCreationExpression', // new Test() + 'EvalVariable', // t - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Invocation', // () + 'New', // new + 'ResConOverload', // Test + 'ResType', // Test - "Env", // from Block - "ReturnStatement", // return this; - "ExpressionStatement", // this.x = 0; - "ExplicitConstructorInvocation", // super(); + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Object - "ResType", // super + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExplicitConstructorInvocation', // super(); - "Deref", - "EvalVariable", // super + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Parent + 'ResType', // super - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Deref', + 'EvalVariable', // super - "Env", // from Block - "ReturnStatement", // return this; + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Reset", // return - "ExpressionName", // this + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExpressionStatement', // this.x = 0; + 'ExplicitConstructorInvocation', // super(); - "Deref", - "EvalVariable", // this + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Object + 'ResType', // super - "Reset", // Skip Env from Block + 'Deref', + 'EvalVariable', // super - "Pop", - "Assignment", // this.x = 0 + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Assign", // = - "Literal", // 0 - "EvalVariable", // this.x + 'Env', // from Block + 'ReturnStatement', // return this; - "Res", // x - "EvalVariable", // this + 'Reset', // return + 'ExpressionName', // this - "Reset", // return - "ExpressionName", // this + 'Deref', + 'EvalVariable', // this - "Deref", - "EvalVariable", // this + 'Reset', // Skip Env from Block - "Reset", // Skip Env from Block + 'Pop', + 'Assignment', // this.x = 0 - "Reset", // return - "ExpressionName", // this + 'Assign', // = + 'Literal', // 0 + 'EvalVariable', // this.x - "Deref", - "EvalVariable", // this + 'Res', // x + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // return + 'ExpressionName', // this - "Pop", - "MethodInvocation", // p.test(t) + 'Deref', + 'EvalVariable', // this - "Invocation", // () - "ExpressionName", // t - "ResOverride", - "ExpressionName", // p - "ResOverload", // test - "ResType", // t - "ResType", // p + 'Reset', // Skip Env from Block - "Deref", - "EvalVariable", // p + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // t + 'Deref', + 'EvalVariable', // this - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Reset', // Skip Env from Block - "Env", // from Block - "ReturnStatement", // return; - "ExpressionStatement", // this.x = 2; + 'Pop', + 'MethodInvocation', // p.test(t) - "Pop", - "Assignment", // this.x = 2 + 'Invocation', // () + 'ExpressionName', // t + 'ResOverride', + 'ExpressionName', // p + 'ResOverload', // test + 'ResType', // t + 'ResType', // p - "Assign", // = - "Literal", // 2 - "EvalVariable", // this.x + 'Deref', + 'EvalVariable', // p - "Res", // x - "EvalVariable", // this + 'Deref', + 'EvalVariable', // t - "Reset", // return - "Void", + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Reset", // Skip Env from Block + 'Env', // from Block + 'ReturnStatement', // return; + 'ExpressionStatement', // this.x = 2; - "Reset", // return - "Void", + 'Pop', + 'Assignment', // this.x = 2 - "Reset", // Skip Env from Block - ]; + 'Assign', // = + 'Literal', // 2 + 'EvalVariable', // this.x + + 'Res', // x + 'EvalVariable', // this + + 'Reset', // return + 'Void', + + 'Reset', // Skip Env from Block + + 'Reset', // return + 'Void', + + 'Reset' // Skip Env from Block + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "p", // EvalVariable - "Test", // ResType - "Test", // ResConOverload - "Object", // New - "Parent", // ResType - "Parent", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "Object", // ResType - "Object", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "x", // Res - "0", // Literal - "0", // Assign - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "Object", // Assign - "t", // EvalVariable - "Test", // ResType - "Test", // ResConOverload - "Object", // New - "Parent", // ResType - "Parent", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "Object", // ResType - "Object", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "x", // Res - "0", // Literal - "0", // Assign - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "Object", // Assign - "Parent", // ResType - "Test", // ResType - "test", // ResOverload - "p", // EvalVariable - "Object", // Deref - "test", // ResOverride - "Object", - "t", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "x", // Res - "2", // Literal - "2", // Assign - "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); + 'p', // EvalVariable + 'Test', // ResType + 'Test', // ResConOverload + 'Object', // New + 'Parent', // ResType + 'Parent', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'Object', // ResType + 'Object', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'x', // Res + '0', // Literal + '0', // Assign + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'Object', // Assign + 't', // EvalVariable + 'Test', // ResType + 'Test', // ResConOverload + 'Object', // New + 'Parent', // ResType + 'Parent', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'Object', // ResType + 'Object', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'x', // Res + '0', // Literal + '0', // Assign + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'Object', // Assign + 'Parent', // ResType + 'Test', // ResType + 'test', // ResOverload + 'p', // EvalVariable + 'Object', // Deref + 'test', // ResOverride + 'Object', + 't', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'x', // Res + '2', // Literal + '2', // Assign + '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 + ) // TODO test env - }); + }) - it("should not invoke overriden instance method with supertype", () => { + it('should not invoke overriden instance method with supertype', () => { const programStr = ` class Parent { int x; @@ -900,361 +900,361 @@ describe("evaluate method overriding correctly", () => { x = 2; } } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class Test extends Parent {...} - "NormalClassDeclaration", // class Parent {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} - - "Env", // from NormalClassDeclaration - "MethodDeclaration", // void test(Parent p) {...} - "ConstructorDeclaration", // Parent() {...} - - "Env", // from NormalClassDeclaration - "MethodDeclaration", // void test(Test t) {...} - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} - - "Pop", - "MethodInvocation", // Test.main([""]) - - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test + 'CompilationUnit', + + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class Test extends Parent {...} + 'NormalClassDeclaration', // class Parent {...} + + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // void test(Parent p) {...} + 'ConstructorDeclaration', // Parent() {...} + + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // void test(Test t) {...} + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} + + 'Pop', + 'MethodInvocation', // Test.main([""]) + + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test - "Deref", - "EvalVariable", // Test + 'Deref', + 'EvalVariable', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; - "ExpressionStatement", // p.test(t); - "LocalVariableDeclarationStatement", // Test t = new Test(); - "LocalVariableDeclarationStatement", // Parent p = new Test(); + 'Env', // from Block + 'ReturnStatement', // return; + 'ExpressionStatement', // p.test(t); + 'LocalVariableDeclarationStatement', // Test t = new Test(); + 'LocalVariableDeclarationStatement', // Parent p = new Test(); - "ExpressionStatement", // p = new Test(); - "LocalVariableDeclarationStatement", // Parent p; + 'ExpressionStatement', // p = new Test(); + 'LocalVariableDeclarationStatement', // Parent p; - "Pop", - "Assignment", // p = new Test() + 'Pop', + 'Assignment', // p = new Test() - "Assign", // = - "ClassInstanceCreationExpression", // new Test() - "EvalVariable", // p + 'Assign', // = + 'ClassInstanceCreationExpression', // new Test() + 'EvalVariable', // p - "Invocation", // () - "New", // new - "ResConOverload", // Test - "ResType", // Test + 'Invocation', // () + 'New', // new + 'ResConOverload', // Test + 'ResType', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; - "ExplicitConstructorInvocation", // super(); + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExplicitConstructorInvocation', // super(); - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Parent - "ResType", // super + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Parent + 'ResType', // super - "Deref", - "EvalVariable", // super + 'Deref', + 'EvalVariable', // super - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; - "ExpressionStatement", // this.x = 0; - "ExplicitConstructorInvocation", // super(); + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExpressionStatement', // this.x = 0; + 'ExplicitConstructorInvocation', // super(); - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Object - "ResType", // super + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Object + 'ResType', // super - "Deref", - "EvalVariable", // super + 'Deref', + 'EvalVariable', // super - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; + 'Env', // from Block + 'ReturnStatement', // return this; - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "Pop", - "Assignment", // this.x = 0 + 'Pop', + 'Assignment', // this.x = 0 - "Assign", // = - "Literal", // 0 - "EvalVariable", // this.x + 'Assign', // = + 'Literal', // 0 + 'EvalVariable', // this.x - "Res", // x - "EvalVariable", // this + 'Res', // x + 'EvalVariable', // this - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "ExpressionStatement", // t = new Test(); - "LocalVariableDeclarationStatement", // Test t; + 'ExpressionStatement', // t = new Test(); + 'LocalVariableDeclarationStatement', // Test t; - "Pop", - "Assignment", // t = new Test() + 'Pop', + 'Assignment', // t = new Test() - "Assign", // = - "ClassInstanceCreationExpression", // new Test() - "EvalVariable", // t + 'Assign', // = + 'ClassInstanceCreationExpression', // new Test() + 'EvalVariable', // t - "Invocation", // () - "New", // new - "ResConOverload", // Test - "ResType", // Test + 'Invocation', // () + 'New', // new + 'ResConOverload', // Test + 'ResType', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; - "ExplicitConstructorInvocation", // super(); + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExplicitConstructorInvocation', // super(); - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Parent - "ResType", // super + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Parent + 'ResType', // super - "Deref", - "EvalVariable", // super + 'Deref', + 'EvalVariable', // super - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; - "ExpressionStatement", // this.x = 0; - "ExplicitConstructorInvocation", // super(); + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExpressionStatement', // this.x = 0; + 'ExplicitConstructorInvocation', // super(); - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Object - "ResType", // super + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Object + 'ResType', // super - "Deref", - "EvalVariable", // super + 'Deref', + 'EvalVariable', // super - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; + 'Env', // from Block + 'ReturnStatement', // return this; - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "Pop", - "Assignment", // this.x = 0 + 'Pop', + 'Assignment', // this.x = 0 - "Assign", // = - "Literal", // 0 - "EvalVariable", // this.x + 'Assign', // = + 'Literal', // 0 + 'EvalVariable', // this.x - "Res", // x - "EvalVariable", // this + 'Res', // x + 'EvalVariable', // this - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "Pop", - "MethodInvocation", // p.test(t) + 'Pop', + 'MethodInvocation', // p.test(t) - "Invocation", // () - "ExpressionName", // t - "ResOverride", - "ExpressionName", // p - "ResOverload", // test - "ResType", // t - "ResType", // p + 'Invocation', // () + 'ExpressionName', // t + 'ResOverride', + 'ExpressionName', // p + 'ResOverload', // test + 'ResType', // t + 'ResType', // p - "Deref", - "EvalVariable", // p + 'Deref', + 'EvalVariable', // p - "Deref", - "EvalVariable", // t + 'Deref', + 'EvalVariable', // t - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; - "ExpressionStatement", // this.x = 1; + 'Env', // from Block + 'ReturnStatement', // return; + 'ExpressionStatement', // this.x = 1; - "Pop", - "Assignment", // this.x = 1 + 'Pop', + 'Assignment', // this.x = 1 - "Assign", // = - "Literal", // 1 - "EvalVariable", // this.x + 'Assign', // = + 'Literal', // 1 + 'EvalVariable', // this.x - "Res", // x - "EvalVariable", // this + 'Res', // x + 'EvalVariable', // this - "Reset", // return - "Void", + 'Reset', // return + 'Void', - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "Reset", // return - "Void", + 'Reset', // return + 'Void', - "Reset", // Skip Env from Block - ]; + 'Reset' // Skip Env from Block + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "p", // EvalVariable - "Test", // ResType - "Test", // ResConOverload - "Object", // New - "Parent", // ResType - "Parent", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "Object", // ResType - "Object", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "x", // Res - "0", // Literal - "0", // Assign - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "Object", // Assign - "t", // EvalVariable - "Test", // ResType - "Test", // ResConOverload - "Object", // New - "Parent", // ResType - "Parent", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "Object", // ResType - "Object", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "x", // Res - "0", // Literal - "0", // Assign - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "Object", // Assign - "Parent", // ResType - "Test", // ResType - "test", // ResOverload - "p", // EvalVariable - "Object", // Deref - "test", // ResOverride - "Object", - "t", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "x", // Res - "1", // Literal - "1", // Assign - "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); + 'p', // EvalVariable + 'Test', // ResType + 'Test', // ResConOverload + 'Object', // New + 'Parent', // ResType + 'Parent', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'Object', // ResType + 'Object', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'x', // Res + '0', // Literal + '0', // Assign + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'Object', // Assign + 't', // EvalVariable + 'Test', // ResType + 'Test', // ResConOverload + 'Object', // New + 'Parent', // ResType + 'Parent', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'Object', // ResType + 'Object', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'x', // Res + '0', // Literal + '0', // Assign + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'Object', // Assign + 'Parent', // ResType + 'Test', // ResType + 'test', // ResOverload + 'p', // EvalVariable + 'Object', // Deref + 'test', // ResOverride + 'Object', + 't', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'x', // Res + '1', // Literal + '1', // Assign + '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 + ) // TODO test env - }); -}); + }) +}) diff --git a/src/ec-evaluator/__tests__/null-pointer-exception.test.ts b/src/ec-evaluator/__tests__/null-pointer-exception.test.ts index 3925106..6895ca0 100644 --- a/src/ec-evaluator/__tests__/null-pointer-exception.test.ts +++ b/src/ec-evaluator/__tests__/null-pointer-exception.test.ts @@ -1,10 +1,10 @@ -import { parse } from "../../ast/parser"; -import { NullPointerException } from "../errors"; -import { evaluate } from "../interpreter"; -import { createContextStub } from "./__utils__/utils"; +import { parse } from '../../ast/parser' +import { NullPointerException } from '../errors' +import { evaluate } from '../interpreter' +import { createContextStub } from './__utils__/utils' -describe("should throw NullPointerException correctly", () => { - it("should throw NullPointerException when invoking instance method but target is null", () => { +describe('should throw NullPointerException correctly', () => { + it('should throw NullPointerException when invoking instance method but target is null', () => { const programStr = ` class Test { public static void main(String[] args) { @@ -13,18 +13,18 @@ describe("should throw NullPointerException correctly", () => { } void test() {} } - `; - - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); - - const context = createContextStub(); - context.control.push(compilationUnit!); - - expect(() => evaluate(context)).toThrowError(NullPointerException); - }); - - it("should not throw NullPointerException when invoking static method although target is null", () => { + ` + + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() + + const context = createContextStub() + context.control.push(compilationUnit!) + + expect(() => evaluate(context)).toThrowError(NullPointerException) + }) + + it('should not throw NullPointerException when invoking static method although target is null', () => { const programStr = ` class Test { public static void main(String[] args) { @@ -33,18 +33,18 @@ describe("should throw NullPointerException correctly", () => { } static void test() {} } - `; - - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); - - const context = createContextStub(); - context.control.push(compilationUnit!); - - expect(() => evaluate(context)).not.toThrowError(NullPointerException); - }); - - it("should throw NullPointerException when accessing instance field but target is null", () => { + ` + + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() + + const context = createContextStub() + context.control.push(compilationUnit!) + + expect(() => evaluate(context)).not.toThrowError(NullPointerException) + }) + + it('should throw NullPointerException when accessing instance field but target is null', () => { const programStr = ` class Test { int x; @@ -53,18 +53,18 @@ describe("should throw NullPointerException correctly", () => { int x = test.x; } } - `; - - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); - - const context = createContextStub(); - context.control.push(compilationUnit!); - - expect(() => evaluate(context)).toThrowError(NullPointerException); - }); - - it("should not throw NullPointerException when accessing static field although target is null", () => { + ` + + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() + + const context = createContextStub() + context.control.push(compilationUnit!) + + expect(() => evaluate(context)).toThrowError(NullPointerException) + }) + + it('should not throw NullPointerException when accessing static field although target is null', () => { const programStr = ` class Test { static int x; @@ -73,14 +73,14 @@ describe("should throw NullPointerException correctly", () => { int x = test.x; } } - `; - - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); - - const context = createContextStub(); - context.control.push(compilationUnit!); - - expect(() => evaluate(context)).not.toThrowError(NullPointerException); - }); -}); + ` + + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() + + const context = createContextStub() + context.control.push(compilationUnit!) + + expect(() => evaluate(context)).not.toThrowError(NullPointerException) + }) +}) diff --git a/src/ec-evaluator/__tests__/qualified-mtd-inv.test.ts b/src/ec-evaluator/__tests__/qualified-mtd-inv.test.ts index d020462..29f9cc7 100644 --- a/src/ec-evaluator/__tests__/qualified-mtd-inv.test.ts +++ b/src/ec-evaluator/__tests__/qualified-mtd-inv.test.ts @@ -1,15 +1,15 @@ -import { parse } from "../../ast/parser"; -import { evaluate } from "../interpreter"; +import { parse } from '../../ast/parser' +import { evaluate } from '../interpreter' import { ControlStub, StashStub, createContextStub, getControlItemStr, getStashItemStr -} from "./__utils__/utils"; +} from './__utils__/utils' -describe("evaluate simple qualified MethodInvocation correctly", () => { - it("evaluate static MethodInvocation in static MethodInvocation with qualified class name correctly", () => { +describe('evaluate simple qualified MethodInvocation correctly', () => { + it('evaluate static MethodInvocation in static MethodInvocation with qualified class name correctly', () => { const programStr = ` class Test { public static void main(String[] args) { @@ -17,106 +17,106 @@ describe("evaluate simple qualified MethodInvocation correctly", () => { } static void test() {} } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class Test {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} - - "Env", - "MethodDeclaration", // static void test() {...} - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} - - "Pop", - "MethodInvocation", // Test.main([""]) - - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test - - "Deref", - "EvalVariable", // Test - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return; - "ExpressionStatement", // Test.test(); - - "Pop", - "MethodInvocation", // Test.test() - - "Invocation", // () - "ResOverride", - "ExpressionName", // Test - "ResOverload", // test - "ResType", // Test - - "Deref", - "EvalVariable", // Test - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return; - - "Reset", // return - "Void", // - - "Reset", // skip Env from Block - - "Reset", // return - "Void", - - "Reset", // skip Env from Block - ]; + 'CompilationUnit', + + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class Test {...} + + 'Env', + 'MethodDeclaration', // static void test() {...} + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} + + 'Pop', + 'MethodInvocation', // Test.main([""]) + + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test + + 'Deref', + 'EvalVariable', // Test + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return; + 'ExpressionStatement', // Test.test(); + + 'Pop', + 'MethodInvocation', // Test.test() + + 'Invocation', // () + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // test + 'ResType', // Test + + 'Deref', + 'EvalVariable', // Test + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return; + + 'Reset', // return + 'Void', // + + 'Reset', // skip Env from Block + + 'Reset', // return + 'Void', + + 'Reset' // skip Env from Block + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "Test", // ResType - "test", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "test", // ResOverride - "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); + 'Test', // ResType + 'test', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'test', // ResOverride + '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 + ) // TODO test env - }); - - it("evaluate static MethodInvocation in static MethodInvocation with qualified instance name correctly", () => { + }) + + it('evaluate static MethodInvocation in static MethodInvocation with qualified instance name correctly', () => { const programStr = ` class Test { public static void main(String[] args) { @@ -125,175 +125,175 @@ describe("evaluate simple qualified MethodInvocation correctly", () => { } static void test() {} } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", + 'CompilationUnit', - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class Test {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class Test {...} - "Env", - "MethodDeclaration", // static void test() {...} - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} + 'Env', + 'MethodDeclaration', // static void test() {...} + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} - "Pop", - "MethodInvocation", // Test.main([""]) + 'Pop', + 'MethodInvocation', // Test.main([""]) - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test - "Deref", - "EvalVariable", // Test + 'Deref', + 'EvalVariable', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; - "ExpressionStatement", // test.test(); - "LocalVariableDeclarationStatement", // Test test = new Test(); + 'Env', // from Block + 'ReturnStatement', // return; + 'ExpressionStatement', // test.test(); + 'LocalVariableDeclarationStatement', // Test test = new Test(); - "ExpressionStatement", // test = new Test(); - "LocalVariableDeclarationStatement", // Test test; + 'ExpressionStatement', // test = new Test(); + 'LocalVariableDeclarationStatement', // Test test; - "Pop", - "Assignment", // test = new Test() + 'Pop', + 'Assignment', // test = new Test() - "Assign", // = - "ClassInstanceCreationExpression", // new Test() - "EvalVariable", // test + 'Assign', // = + 'ClassInstanceCreationExpression', // new Test() + 'EvalVariable', // test - "Invocation", // () - "New", // new - "ResConOverload", // Test - "ResType", // Test + 'Invocation', // () + 'New', // new + 'ResConOverload', // Test + 'ResType', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; - "ExplicitConstructorInvocation", // super(); + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExplicitConstructorInvocation', // super(); - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Object - "ResType", // super + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Object + 'ResType', // super - "Deref", - "EvalVariable", // super + 'Deref', + 'EvalVariable', // super - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; + 'Env', // from Block + 'ReturnStatement', // return this; - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // skip Env from Block + 'Reset', // skip Env from Block - "Pop", - "MethodInvocation", // test.test() + 'Pop', + 'MethodInvocation', // test.test() - "Invocation", // () - "ResOverride", - "ExpressionName", // test - "ResOverload", // test - "ResType", // Test + 'Invocation', // () + 'ResOverride', + 'ExpressionName', // test + 'ResOverload', // test + 'ResType', // Test - "Deref", - "EvalVariable", // test + 'Deref', + 'EvalVariable', // test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; + 'Env', // from Block + 'ReturnStatement', // return; - "Reset", // return - "Void", // + 'Reset', // return + 'Void', // - "Reset", // skip Env from Block + 'Reset', // skip Env from Block - "Reset", // return - "Void", // + 'Reset', // return + 'Void', // - "Reset", // skip Env from Block - ]; + 'Reset' // skip Env from Block + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "test", // EvalVariable - "Test", // ResType - "Test", // ResConOverload - "Object", // New - "Object", // ResType - "Object", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "Object", // Assign - "Test", // ResType - "test", // ResOverload - "test", // EvalVariable - "Object", // Deref - "test", // ResOverride - "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); + 'test', // EvalVariable + 'Test', // ResType + 'Test', // ResConOverload + 'Object', // New + 'Object', // ResType + 'Object', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'Object', // Assign + 'Test', // ResType + 'test', // ResOverload + 'test', // EvalVariable + 'Object', // Deref + 'test', // ResOverride + '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 + ) // TODO test env - }); + }) - it("evaluate static MethodInvocation in instance MethodInvocation with qualified name correctly", () => { + it('evaluate static MethodInvocation in instance MethodInvocation with qualified name correctly', () => { const programStr = ` class Test { public static void main(String[] args) { @@ -305,212 +305,212 @@ describe("evaluate simple qualified MethodInvocation correctly", () => { Test.test(1); } } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", + 'CompilationUnit', - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class Test {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class Test {...} - "Env", - "MethodDeclaration", // void test() {...} - "MethodDeclaration", // static void test(int x) {...} - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} + 'Env', + 'MethodDeclaration', // void test() {...} + 'MethodDeclaration', // static void test(int x) {...} + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} - "Pop", - "MethodInvocation", // Test.main([""]) + 'Pop', + 'MethodInvocation', // Test.main([""]) - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test - "Deref", - "EvalVariable", // Test + 'Deref', + 'EvalVariable', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; - "ExpressionStatement", // test.test(); - "LocalVariableDeclarationStatement", // Test test = new Test(); + 'Env', // from Block + 'ReturnStatement', // return; + 'ExpressionStatement', // test.test(); + 'LocalVariableDeclarationStatement', // Test test = new Test(); - "ExpressionStatement", // test = new Test(); - "LocalVariableDeclarationStatement", // Test test; + 'ExpressionStatement', // test = new Test(); + 'LocalVariableDeclarationStatement', // Test test; - "Pop", - "Assignment", // test = new Test() + 'Pop', + 'Assignment', // test = new Test() - "Assign", // = - "ClassInstanceCreationExpression", // new Test() - "EvalVariable", // test + 'Assign', // = + 'ClassInstanceCreationExpression', // new Test() + 'EvalVariable', // test - "Invocation", // () - "New", // new - "ResConOverload", // Test - "ResType", // Test + 'Invocation', // () + 'New', // new + 'ResConOverload', // Test + 'ResType', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; - "ExplicitConstructorInvocation", // super(); + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExplicitConstructorInvocation', // super(); - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Object - "ResType", // super + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Object + 'ResType', // super - "Deref", - "EvalVariable", // super + 'Deref', + 'EvalVariable', // super - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; + 'Env', // from Block + 'ReturnStatement', // return this; - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // skip Env from Block + 'Reset', // skip Env from Block - "Pop", - "MethodInvocation", // test.test() + 'Pop', + 'MethodInvocation', // test.test() - "Invocation", // () - "ResOverride", - "ExpressionName", // test - "ResOverload", // test - "ResType", // Test + 'Invocation', // () + 'ResOverride', + 'ExpressionName', // test + 'ResOverload', // test + 'ResType', // Test - "Deref", - "EvalVariable", // test + 'Deref', + 'EvalVariable', // test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; - "ExpressionStatement", // Test.test(1); + 'Env', // from Block + 'ReturnStatement', // return; + 'ExpressionStatement', // Test.test(1); - "Pop", - "MethodInvocation", // Test.test(1) + 'Pop', + 'MethodInvocation', // Test.test(1) - "Invocation", - "Literal", // 1 - "ResOverride", - "ExpressionName", // Test - "ResOverload", // test - "ResType", // 1 - "ResType", // Test + 'Invocation', + 'Literal', // 1 + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // test + 'ResType', // 1 + 'ResType', // Test - "Deref", - "EvalVariable", // Test + 'Deref', + 'EvalVariable', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; + 'Env', // from Block + 'ReturnStatement', // return; - "Reset", // return - "Void", // + 'Reset', // return + 'Void', // - "Reset", // skip Env from Block + 'Reset', // skip Env from Block - "Reset", // return - "Void", // + 'Reset', // return + 'Void', // - "Reset", // skip Env from Block + 'Reset', // skip Env from Block - "Reset", // return - "Void", // + 'Reset', // return + 'Void', // - "Reset", // skip Env from Block - ]; + 'Reset' // skip Env from Block + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "test", // EvalVariable - "Test", // ResType - "Test", // ResConOverload - "Object", // New - "Object", // ResType - "Object", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "Object", // Assign - "Test", // ResType - "test", // ResOverload - "test", // EvalVariable - "Object", // Deref - "test", // ResOverride - "Object", - "Test", // ResType - "int", // ResType - "test", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "test", // ResOverride - "1", // Literal - "Void", - "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); + 'test', // EvalVariable + 'Test', // ResType + 'Test', // ResConOverload + 'Object', // New + 'Object', // ResType + 'Object', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'Object', // Assign + 'Test', // ResType + 'test', // ResOverload + 'test', // EvalVariable + 'Object', // Deref + 'test', // ResOverride + 'Object', + 'Test', // ResType + 'int', // ResType + 'test', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'test', // ResOverride + '1', // Literal + 'Void', + '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 + ) // TODO test env - }); + }) - it("evaluate instance MethodInvocation in static MethodInvocation with qualified instance name correctly", () => { + it('evaluate instance MethodInvocation in static MethodInvocation with qualified instance name correctly', () => { const programStr = ` class Test { public static void main(String[] args) { @@ -521,185 +521,185 @@ describe("evaluate simple qualified MethodInvocation correctly", () => { return 1; } } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", + 'CompilationUnit', - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class Test {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class Test {...} - "Env", - "MethodDeclaration", // int test() {...} - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} + 'Env', + 'MethodDeclaration', // int test() {...} + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} - "Pop", - "MethodInvocation", // Test.main([""]) + 'Pop', + 'MethodInvocation', // Test.main([""]) - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test - "Deref", - "EvalVariable", // Test + 'Deref', + 'EvalVariable', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; - "LocalVariableDeclarationStatement", // int x = test.test(); - "LocalVariableDeclarationStatement", // Test test = new Test(); + 'Env', // from Block + 'ReturnStatement', // return; + 'LocalVariableDeclarationStatement', // int x = test.test(); + 'LocalVariableDeclarationStatement', // Test test = new Test(); - "ExpressionStatement", // test = new Test(); - "LocalVariableDeclarationStatement", // Test test; + 'ExpressionStatement', // test = new Test(); + 'LocalVariableDeclarationStatement', // Test test; - "Pop", - "Assignment", // test = new Test() + 'Pop', + 'Assignment', // test = new Test() - "Assign", // = - "ClassInstanceCreationExpression", // new Test() - "EvalVariable", // test + 'Assign', // = + 'ClassInstanceCreationExpression', // new Test() + 'EvalVariable', // test - "Invocation", // () - "New", // new - "ResConOverload", // Test - "ResType", // Test - - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Invocation', // () + 'New', // new + 'ResConOverload', // Test + 'ResType', // Test - "Env", // from Block - "ReturnStatement", // return this; - "ExplicitConstructorInvocation", // super(); + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Object - "ResType", // super + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExplicitConstructorInvocation', // super(); - "Deref", - "EvalVariable", // super + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Object + 'ResType', // super - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Deref', + 'EvalVariable', // super - "Env", // from Block - "ReturnStatement", // return this; + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Reset", // return - "ExpressionName", // this + 'Env', // from Block + 'ReturnStatement', // return this; - "Deref", - "EvalVariable", // this + 'Reset', // return + 'ExpressionName', // this - "Reset", // Skip Env from Block + 'Deref', + 'EvalVariable', // this - "Reset", // return - "ExpressionName", // this + 'Reset', // Skip Env from Block - "Deref", - "EvalVariable", // this + 'Reset', // return + 'ExpressionName', // this - "Reset", // skip Env from Block + 'Deref', + 'EvalVariable', // this - "ExpressionStatement", // x = test.test(); - "LocalVariableDeclarationStatement", // int x; + 'Reset', // skip Env from Block - "Pop", - "Assignment", // x = test.test() + 'ExpressionStatement', // x = test.test(); + 'LocalVariableDeclarationStatement', // int x; - "Assign", // = - "MethodInvocation", // test.test() - "EvalVariable", // x + 'Pop', + 'Assignment', // x = test.test() - "Invocation", // () - "ResOverride", - "ExpressionName", // test - "ResOverload", // test - "ResType", // Test + 'Assign', // = + 'MethodInvocation', // test.test() + 'EvalVariable', // x - "Deref", - "EvalVariable", // test + 'Invocation', // () + 'ResOverride', + 'ExpressionName', // test + 'ResOverload', // test + 'ResType', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Deref', + 'EvalVariable', // test - "Env", // from Block - "ReturnStatement", // return 1; + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Reset", // return - "Literal", // 1 + 'Env', // from Block + 'ReturnStatement', // return 1; - "Reset", // skip Env from Block + 'Reset', // return + 'Literal', // 1 - "Reset", // return - "Void", // + 'Reset', // skip Env from Block - "Reset", // skip Env from Block - ]; + 'Reset', // return + 'Void', // + + 'Reset' // skip Env from Block + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "test", // EvalVariable - "Test", // ResType - "Test", // ResConOverload - "Object", // New - "Object", // ResType - "Object", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "Object", // Assign - "x", // EvalVariable - "Test", // ResType - "test", // ResOverload - "test", // EvalVariable - "Object", // Deref - "test", // ResOverride - "Object", - "1", // Literal - "1", // Assign - "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); + 'test', // EvalVariable + 'Test', // ResType + 'Test', // ResConOverload + 'Object', // New + 'Object', // ResType + 'Object', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'Object', // Assign + 'x', // EvalVariable + 'Test', // ResType + 'test', // ResOverload + 'test', // EvalVariable + 'Object', // Deref + 'test', // ResOverride + 'Object', + '1', // Literal + '1', // Assign + '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 + ) // TODO test env - }); + }) - it("evaluate instance MethodInvocation in instance MethodInvocation with qualified instance name correctly", () => { + it('evaluate instance MethodInvocation in instance MethodInvocation with qualified instance name correctly', () => { const programStr = ` class Test { public static void main(String[] args) { @@ -714,288 +714,288 @@ describe("evaluate simple qualified MethodInvocation correctly", () => { test.test(1); } } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", + 'CompilationUnit', - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class Test {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class Test {...} - "Env", - "MethodDeclaration", // void test() {...} - "MethodDeclaration", // int test(int x) {...} - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} + 'Env', + 'MethodDeclaration', // void test() {...} + 'MethodDeclaration', // int test(int x) {...} + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} - "Pop", - "MethodInvocation", // Test.main([""]) + 'Pop', + 'MethodInvocation', // Test.main([""]) - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test - "Deref", - "EvalVariable", // Test + 'Deref', + 'EvalVariable', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; - "ExpressionStatement", // test.test(); - "LocalVariableDeclarationStatement", // Test test = new Test(); + 'Env', // from Block + 'ReturnStatement', // return; + 'ExpressionStatement', // test.test(); + 'LocalVariableDeclarationStatement', // Test test = new Test(); - "ExpressionStatement", // test = new Test(); - "LocalVariableDeclarationStatement", // Test test; + 'ExpressionStatement', // test = new Test(); + 'LocalVariableDeclarationStatement', // Test test; - "Pop", - "Assignment", // test = new Test() + 'Pop', + 'Assignment', // test = new Test() - "Assign", // = - "ClassInstanceCreationExpression", // new Test() - "EvalVariable", // test + 'Assign', // = + 'ClassInstanceCreationExpression', // new Test() + 'EvalVariable', // test - "Invocation", // () - "New", // new - "ResConOverload", // Test - "ResType", // Test + 'Invocation', // () + 'New', // new + 'ResConOverload', // Test + 'ResType', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; - "ExplicitConstructorInvocation", // super(); + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExplicitConstructorInvocation', // super(); - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Object - "ResType", // super + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Object + 'ResType', // super - "Deref", - "EvalVariable", // super + 'Deref', + 'EvalVariable', // super - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; + 'Env', // from Block + 'ReturnStatement', // return this; - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // skip Env from Block + 'Reset', // skip Env from Block - "Pop", - "MethodInvocation", // test.test() + 'Pop', + 'MethodInvocation', // test.test() - "Invocation", // () - "ResOverride", - "ExpressionName", // test - "ResOverload", // test - "ResType", // Test + 'Invocation', // () + 'ResOverride', + 'ExpressionName', // test + 'ResOverload', // test + 'ResType', // Test - "Deref", - "EvalVariable", // test + 'Deref', + 'EvalVariable', // test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; - "ExpressionStatement", // test.test(1); - "LocalVariableDeclarationStatement", // Test test = new Test(); + 'Env', // from Block + 'ReturnStatement', // return; + 'ExpressionStatement', // test.test(1); + 'LocalVariableDeclarationStatement', // Test test = new Test(); - "ExpressionStatement", // test = new Test(); - "LocalVariableDeclarationStatement", // Test test; + 'ExpressionStatement', // test = new Test(); + 'LocalVariableDeclarationStatement', // Test test; - "Pop", - "Assignment", // test = new Test() + 'Pop', + 'Assignment', // test = new Test() - "Assign", // = - "ClassInstanceCreationExpression", // new Test() - "EvalVariable", // test + 'Assign', // = + 'ClassInstanceCreationExpression', // new Test() + 'EvalVariable', // test - "Invocation", // () - "New", // new - "ResConOverload", // Test - "ResType", // Test + 'Invocation', // () + 'New', // new + 'ResConOverload', // Test + 'ResType', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; - "ExplicitConstructorInvocation", // super(); + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExplicitConstructorInvocation', // super(); - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Object - "ResType", // super + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Object + 'ResType', // super - "Deref", - "EvalVariable", // super + 'Deref', + 'EvalVariable', // super - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; + 'Env', // from Block + 'ReturnStatement', // return this; - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // skip Env from Block + 'Reset', // skip Env from Block - "Pop", - "MethodInvocation", // test.test(1) + 'Pop', + 'MethodInvocation', // test.test(1) - "Invocation", // () - "Literal", // 1 - "ResOverride", - "ExpressionName", // test - "ResOverload", // test - "ResType", // 1 - "ResType", // test + 'Invocation', // () + 'Literal', // 1 + 'ResOverride', + 'ExpressionName', // test + 'ResOverload', // test + 'ResType', // 1 + 'ResType', // test - "Deref", - "EvalVariable", // test + 'Deref', + 'EvalVariable', // test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return x; + 'Env', // from Block + 'ReturnStatement', // return x; - "Reset", // return - "ExpressionName", // x + 'Reset', // return + 'ExpressionName', // x - "Deref", - "EvalVariable", // x + 'Deref', + 'EvalVariable', // x - "Reset", // skip Env from Block + 'Reset', // skip Env from Block - "Reset", // return - "Void", // + 'Reset', // return + 'Void', // - "Reset", // skip Env from Block + 'Reset', // skip Env from Block - "Reset", // return - "Void", // + 'Reset', // return + 'Void', // - "Reset", // skip Env from Block - ]; + 'Reset' // skip Env from Block + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "test", // EvalVariable - "Test", // ResType - "Test", // ResConOverload - "Object", // New - "Object", // ResType - "Object", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "Object", // Assign - "Test", // ResType - "test", // ResOverload - "test", // EvalVariable - "Object", // Deref - "test", // ResOverride - "Object", - "test", // EvalVariable - "Test", // ResType - "Test", // ResConOverload - "Object", // New - "Object", // ResType - "Object", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "Object", // Assign - "Test", // ResType - "int", // ResType - "test", // ResOverload - "test", // EvalVariable - "Object", // Deref - "test", // ResOverride - "Object", - "1", // Literal - "x", // EvalVariable - "1", // Deref - "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); + 'test', // EvalVariable + 'Test', // ResType + 'Test', // ResConOverload + 'Object', // New + 'Object', // ResType + 'Object', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'Object', // Assign + 'Test', // ResType + 'test', // ResOverload + 'test', // EvalVariable + 'Object', // Deref + 'test', // ResOverride + 'Object', + 'test', // EvalVariable + 'Test', // ResType + 'Test', // ResConOverload + 'Object', // New + 'Object', // ResType + 'Object', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'Object', // Assign + 'Test', // ResType + 'int', // ResType + 'test', // ResOverload + 'test', // EvalVariable + 'Object', // Deref + 'test', // ResOverride + 'Object', + '1', // Literal + 'x', // EvalVariable + '1', // Deref + '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 + ) // TODO test env - }); -}); + }) +}) -describe("evaluate complex qualified MethodInvocation correctly", () => { - it("evaluate qualified MethodInvocation with static field correctly", () => { +describe('evaluate complex qualified MethodInvocation correctly', () => { + it('evaluate qualified MethodInvocation with static field correctly', () => { const programStr = ` class Test { static Test t; @@ -1004,123 +1004,123 @@ describe("evaluate complex qualified MethodInvocation correctly", () => { } static void test() {} } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class Test {...} - "NormalClassDeclaration", // class Object {...} + 'CompilationUnit', - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class Test {...} - "Env", - "MethodDeclaration", // static void test() {...} - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} - "FieldDeclaration", // static Test x = null; + 'Env', + 'MethodDeclaration', // static void test() {...} + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} + 'FieldDeclaration', // static Test x = null; - "Pop", - "Assign", // = - "Literal", // null - "EvalVariable", // Test + 'Pop', + 'Assign', // = + 'Literal', // null + 'EvalVariable', // Test - "Pop", - "MethodInvocation", // Test.main([""]) + 'Pop', + 'MethodInvocation', // Test.main([""]) - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test - "Deref", - "EvalVariable", // Test + 'Deref', + 'EvalVariable', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; - "ExpressionStatement", // Test.t.test(); + 'Env', // from Block + 'ReturnStatement', // return; + 'ExpressionStatement', // Test.t.test(); - "Pop", - "MethodInvocation", // Test.t.test() + 'Pop', + 'MethodInvocation', // Test.t.test() - "Invocation", // () - "ResOverride", - "ExpressionName", // Test.t - "ResOverload", // test - "ResType", // Test.t + 'Invocation', // () + 'ResOverride', + 'ExpressionName', // Test.t + 'ResOverload', // test + 'ResType', // Test.t - "ResTypeCont", // t - "ResType", // Test + 'ResTypeCont', // t + 'ResType', // Test - "Deref", - "EvalVariable", // Test.t + 'Deref', + 'EvalVariable', // Test.t - "Res", // t - "EvalVariable", // Test + 'Res', // t + 'EvalVariable', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; + 'Env', // from Block + 'ReturnStatement', // return; - "Reset", // return - "Void", + 'Reset', // return + 'Void', - "Reset", // skip Env from Block + 'Reset', // skip Env from Block - "Reset", // return - "Void", + 'Reset', // return + 'Void', - "Reset", // skip Env from Block - ]; + 'Reset' // skip Env from Block + ] const expectedStashTrace = [ - "t", // EvalVariable - "null", // Literal - "null", // Assign - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 't', // EvalVariable + 'null', // Literal + 'null', // Assign + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "Test", // ResType - "Test", // ResTypeCont - "test", // ResOverload - "Test", // EvalVariable - "t", // Res - "null", // Deref - "test", // ResOverride - "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); + 'Test', // ResType + 'Test', // ResTypeCont + 'test', // ResOverload + 'Test', // EvalVariable + 't', // Res + 'null', // Deref + 'test', // ResOverride + '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 + ) // TODO test env - }); + }) - it("evaluate qualified MethodInvocation with instance declared field correctly", () => { + it('evaluate qualified MethodInvocation with instance declared field correctly', () => { const programStr = ` class Test { AnotherTest t; @@ -1132,202 +1132,202 @@ describe("evaluate complex qualified MethodInvocation correctly", () => { class AnotherTest { static void test() {} } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class AnotherTest {...} - "NormalClassDeclaration", // class Test {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} - - "Env", // from NormalClassDeclaration - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} - - "Env", // from NormalClassDeclaration - "MethodDeclaration", // static void test() {...} - "ConstructorDeclaration", // AnotherTest() {...} - - "Pop", - "MethodInvocation", // Test.main([""]) - - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test - - "Deref", - "EvalVariable", // Test - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return; - "ExpressionStatement", // t.t.test(); - "LocalVariableDeclarationStatement", // Test t = new Test(); - - "ExpressionStatement", // t = new Test(); - "LocalVariableDeclarationStatement", // Test t; - - "Pop", - "Assignment", // t = new Test() - - "Assign", // = - "ClassInstanceCreationExpression", // new Test() - "EvalVariable", // t - - "Invocation", // () - "New", // new - "ResConOverload", // Test - "ResType", // Test - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return this; - "ExpressionStatement", // this.t = null; - "ExplicitConstructorInvocation", // super(); - - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Object - "ResType", // super - - "Deref", - "EvalVariable", // super - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return this; - - "Reset", // return - "ExpressionName", // this - - "Deref", - "EvalVariable", // this - - "Reset", // Skip Env from Block - - "Pop", - "Assignment", // this.t = null - - "Assign", // = - "Literal", // null - "EvalVariable", // this.t - - "Res", // t - "EvalVariable", // this - - "Reset", // return - "ExpressionName", // this - - "Deref", - "EvalVariable", // this - - "Reset", // skip Env from Block - - "Pop", - "MethodInvocation", // t.t.test() - - "Invocation", // () - "ResOverride", - "ExpressionName", // t.t - "ResOverload", // test - "ResType", // t.t - - "ResTypeCont", // t - "ResType", // t - - "Deref", - "EvalVariable", // t.t - - "Res", // t - "EvalVariable", // t - - "Env", // from Invocation - "Marker", - "Block", // {...} + 'CompilationUnit', + + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class AnotherTest {...} + 'NormalClassDeclaration', // class Test {...} + + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} + + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // static void test() {...} + 'ConstructorDeclaration', // AnotherTest() {...} + + 'Pop', + 'MethodInvocation', // Test.main([""]) + + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test + + 'Deref', + 'EvalVariable', // Test + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return; + 'ExpressionStatement', // t.t.test(); + 'LocalVariableDeclarationStatement', // Test t = new Test(); + + 'ExpressionStatement', // t = new Test(); + 'LocalVariableDeclarationStatement', // Test t; + + 'Pop', + 'Assignment', // t = new Test() + + 'Assign', // = + 'ClassInstanceCreationExpression', // new Test() + 'EvalVariable', // t + + 'Invocation', // () + 'New', // new + 'ResConOverload', // Test + 'ResType', // Test + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExpressionStatement', // this.t = null; + 'ExplicitConstructorInvocation', // super(); + + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Object + 'ResType', // super + + 'Deref', + 'EvalVariable', // super + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return this; + + 'Reset', // return + 'ExpressionName', // this + + 'Deref', + 'EvalVariable', // this + + 'Reset', // Skip Env from Block + + 'Pop', + 'Assignment', // this.t = null + + 'Assign', // = + 'Literal', // null + 'EvalVariable', // this.t + + 'Res', // t + 'EvalVariable', // this - "Env", // from Block - "ReturnStatement", // return; + 'Reset', // return + 'ExpressionName', // this - "Reset", // return - "Void", - - "Reset", // skip Env from Block - - "Reset", // return - "Void", + 'Deref', + 'EvalVariable', // this - "Reset", // skip Env from Block - ]; + 'Reset', // skip Env from Block + + 'Pop', + 'MethodInvocation', // t.t.test() + + 'Invocation', // () + 'ResOverride', + 'ExpressionName', // t.t + 'ResOverload', // test + 'ResType', // t.t + + 'ResTypeCont', // t + 'ResType', // t + + 'Deref', + 'EvalVariable', // t.t + + 'Res', // t + 'EvalVariable', // t + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return; + + 'Reset', // return + 'Void', + + 'Reset', // skip Env from Block + + 'Reset', // return + 'Void', + + 'Reset' // skip Env from Block + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "t", // EvalVariable - "Test", // ResType - "Test", // ResConOverload - "Object", // New - "Object", // ResType - "Object", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "t", // Res - "null", // Literal - "null", // Assign - "this", // EvalVariable - "Object", // Deref - "Object", // Assign - "Test", // ResType - "AnotherTest", // ResTypeCont - "test", // ResOverload - "t", // EvalVariable - "t", // Res - "null", // Deref - "test", // ResOverride - "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); + 't', // EvalVariable + 'Test', // ResType + 'Test', // ResConOverload + 'Object', // New + 'Object', // ResType + 'Object', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 't', // Res + 'null', // Literal + 'null', // Assign + 'this', // EvalVariable + 'Object', // Deref + 'Object', // Assign + 'Test', // ResType + 'AnotherTest', // ResTypeCont + 'test', // ResOverload + 't', // EvalVariable + 't', // Res + 'null', // Deref + 'test', // ResOverride + '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 + ) // TODO test env - }); + }) - it("evaluate qualified MethodInvocation with instance inherited field correctly", () => { + it('evaluate qualified MethodInvocation with instance inherited field correctly', () => { const programStr = ` class Parent { Test t; @@ -1339,229 +1339,229 @@ describe("evaluate complex qualified MethodInvocation correctly", () => { } static void test() {} } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class Test extends Parent {...} - "NormalClassDeclaration", // class Parent {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Parent() {...} - - "Env", // from NormalClassDeclaration - "MethodDeclaration", // static void test() {...} - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} - - "Pop", - "MethodInvocation", // Test.main([""]) - - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test - - "Deref", - "EvalVariable", // Test - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return; - "ExpressionStatement", // t.t.test(); - "LocalVariableDeclarationStatement", // Test t = new Test(); - - "ExpressionStatement", // t = new Test(); - "LocalVariableDeclarationStatement", // Test t; - - "Pop", - "Assignment", // t = new Test() - - "Assign", // = - "ClassInstanceCreationExpression", // new Test() - "EvalVariable", // t - - "Invocation", // () - "New", // new - "ResConOverload", // Test - "ResType", // Test - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return this; - "ExplicitConstructorInvocation", // super(); - - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Parent - "ResType", // super - - "Deref", - "EvalVariable", // super - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return this; - "ExpressionStatement", // this.t = null; - "ExplicitConstructorInvocation", // super(); - - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Object - "ResType", // super - - "Deref", - "EvalVariable", // super - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return this; - - "Reset", // return - "ExpressionName", // this - - "Deref", - "EvalVariable", // this - - "Reset", // Skip Env from Block - - "Pop", - "Assignment", // this.t = null - - "Assign", // = - "Literal", // null - "EvalVariable", // this.t - - "Res", // t - "EvalVariable", // this - - "Reset", // return - "ExpressionName", // this - - "Deref", - "EvalVariable", // this - - "Reset", // skip Env from Block - - "Reset", // return - "ExpressionName", // this + 'CompilationUnit', + + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class Test extends Parent {...} + 'NormalClassDeclaration', // class Parent {...} + + 'Env', // from NormalClassDeclaration + 'ConstructorDeclaration', // Parent() {...} + + 'Env', // from NormalClassDeclaration + 'MethodDeclaration', // static void test() {...} + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} + + 'Pop', + 'MethodInvocation', // Test.main([""]) + + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test + + 'Deref', + 'EvalVariable', // Test + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return; + 'ExpressionStatement', // t.t.test(); + 'LocalVariableDeclarationStatement', // Test t = new Test(); + + 'ExpressionStatement', // t = new Test(); + 'LocalVariableDeclarationStatement', // Test t; + + 'Pop', + 'Assignment', // t = new Test() + + 'Assign', // = + 'ClassInstanceCreationExpression', // new Test() + 'EvalVariable', // t + + 'Invocation', // () + 'New', // new + 'ResConOverload', // Test + 'ResType', // Test + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExplicitConstructorInvocation', // super(); + + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Parent + 'ResType', // super + + 'Deref', + 'EvalVariable', // super + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExpressionStatement', // this.t = null; + 'ExplicitConstructorInvocation', // super(); + + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Object + 'ResType', // super + + 'Deref', + 'EvalVariable', // super + + 'Env', // from Invocation + 'Marker', + 'Block', // {...} + + 'Env', // from Block + 'ReturnStatement', // return this; + + 'Reset', // return + 'ExpressionName', // this + + 'Deref', + 'EvalVariable', // this + + 'Reset', // Skip Env from Block + + 'Pop', + 'Assignment', // this.t = null + + 'Assign', // = + 'Literal', // null + 'EvalVariable', // this.t + + 'Res', // t + 'EvalVariable', // this + + 'Reset', // return + 'ExpressionName', // this + + 'Deref', + 'EvalVariable', // this + + 'Reset', // skip Env from Block + + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "Pop", - "MethodInvocation", // t.t.test() + 'Pop', + 'MethodInvocation', // t.t.test() - "Invocation", // () - "ResOverride", - "ExpressionName", // t.t - "ResOverload", // test - "ResType", // t.t + 'Invocation', // () + 'ResOverride', + 'ExpressionName', // t.t + 'ResOverload', // test + 'ResType', // t.t - "ResTypeCont", // t - "ResType", // t + 'ResTypeCont', // t + 'ResType', // t - "Deref", - "EvalVariable", // t.t + 'Deref', + 'EvalVariable', // t.t - "Res", // t - "EvalVariable", // t + 'Res', // t + 'EvalVariable', // t - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; + 'Env', // from Block + 'ReturnStatement', // return; - "Reset", // return - "Void", + 'Reset', // return + 'Void', - "Reset", // skip Env from Block + 'Reset', // skip Env from Block - "Reset", // return - "Void", + 'Reset', // return + 'Void', - "Reset", // skip Env from Block - ]; + 'Reset' // skip Env from Block + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "t", // EvalVariable - "Test", // ResType - "Test", // ResConOverload - "Object", // New - "Parent", // ResType - "Parent", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "Object", // ResType - "Object", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // ResType - "this", // EvalVariable - "t", // Res - "null", // Literal - "null", // Assign - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "Object", // Assign - "Test", // ResType - "Test", // ResTypeCont - "test", // ResOverload - "t", // EvalVariable - "t", // Res - "null", // Deref - "test", // ResOverride - "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); + 't', // EvalVariable + 'Test', // ResType + 'Test', // ResConOverload + 'Object', // New + 'Parent', // ResType + 'Parent', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'Object', // ResType + 'Object', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // ResType + 'this', // EvalVariable + 't', // Res + 'null', // Literal + 'null', // Assign + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'Object', // Assign + 'Test', // ResType + 'Test', // ResTypeCont + 'test', // ResOverload + 't', // EvalVariable + 't', // Res + 'null', // Deref + 'test', // ResOverride + '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 + ) // TODO test env - }); -}); + }) +}) diff --git a/src/ec-evaluator/__tests__/qualified-names-this.test.ts b/src/ec-evaluator/__tests__/qualified-names-this.test.ts index 302ff12..e518e3e 100644 --- a/src/ec-evaluator/__tests__/qualified-names-this.test.ts +++ b/src/ec-evaluator/__tests__/qualified-names-this.test.ts @@ -1,15 +1,15 @@ -import { parse } from "../../ast/parser"; -import { evaluate } from "../interpreter"; +import { parse } from '../../ast/parser' +import { evaluate } from '../interpreter' import { ControlStub, StashStub, createContextStub, getControlItemStr, getStashItemStr -} from "./__utils__/utils"; +} from './__utils__/utils' -describe("evaluate simple qualified names correctly", () => { - it("evaluate LHS Class correctly", () => { +describe('evaluate simple qualified names correctly', () => { + it('evaluate LHS Class correctly', () => { const programStr = ` class Test { static int x; @@ -17,98 +17,98 @@ describe("evaluate simple qualified names correctly", () => { Test.x = 1; } } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", + 'CompilationUnit', - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class Test {...} - "NormalClassDeclaration", // class Object {...} + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class Test {...} - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} + 'Env', + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} + 'FieldDeclaration', // static int x = 0; - "Env", - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} - "FieldDeclaration", // static int x = 0; + 'Pop', + 'Assign', // = + 'Literal', // 0 + 'EvalVariable', // x - "Pop", - "Assign", // = - "Literal", // 0 - "EvalVariable", // x + 'Pop', + 'MethodInvocation', // Test.main([""]) - "Pop", - "MethodInvocation", // Test.main([""]) + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test + 'Deref', + 'EvalVariable', // Test - "Deref", - "EvalVariable", // Test + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Block + 'ReturnStatement', // return; + 'ExpressionStatement', // Test.x = 1; - "Env", // from Block - "ReturnStatement", // return; - "ExpressionStatement", // Test.x = 1; + 'Pop', + 'Assignment', // Test.x = 1 - "Pop", - "Assignment", // Test.x = 1 + 'Assign', // = + 'Literal', // 1 + 'EvalVariable', // Test.x - "Assign", // = - "Literal", // 1 - "EvalVariable", // Test.x + 'Res', // x + 'EvalVariable', // Test - "Res", // x - "EvalVariable", // Test + 'Reset', // return + 'Void', - "Reset", // return - "Void", - - "Reset", // skip Env from Block - ]; + 'Reset' // skip Env from Block + ] const expectedStashTrace = [ - "x", // EvalVariable - "0", // Literal - "0", // Assign - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'x', // EvalVariable + '0', // Literal + '0', // Assign + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "Test", // EvalVariable - "x", // EvalVariable - "1", // Literal - "1", // Assign - "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); + 'Test', // EvalVariable + 'x', // EvalVariable + '1', // Literal + '1', // Assign + '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 + ) // TODO test env - }); + }) - it("evaluate LHS Object correctly", () => { + it('evaluate LHS Object correctly', () => { const programStr = ` class Test { int x = 1; @@ -117,173 +117,173 @@ describe("evaluate simple qualified names correctly", () => { test.x = 2; } } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class Test {...} - "NormalClassDeclaration", // class Object {...} + 'CompilationUnit', - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class Test {...} - "Env", - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} + 'Env', + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} - "Pop", - "MethodInvocation", // Test.main([""]) + 'Pop', + 'MethodInvocation', // Test.main([""]) - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test - "Deref", - "EvalVariable", // Test + 'Deref', + 'EvalVariable', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; - "ExpressionStatement", // test.x = 2; - "LocalVariableDeclarationStatement", // Test test = new Test(); + 'Env', // from Block + 'ReturnStatement', // return; + 'ExpressionStatement', // test.x = 2; + 'LocalVariableDeclarationStatement', // Test test = new Test(); - "ExpressionStatement", // test = new Test(); - "LocalVariableDeclarationStatement", // Test test; + 'ExpressionStatement', // test = new Test(); + 'LocalVariableDeclarationStatement', // Test test; - "Pop", - "Assignment", // test = new Test() + 'Pop', + 'Assignment', // test = new Test() - "Assign", // = - "ClassInstanceCreationExpression", // new Test() - "EvalVariable", // test + 'Assign', // = + 'ClassInstanceCreationExpression', // new Test() + 'EvalVariable', // test - "Invocation", // () - "New", // new - "ResConOverload", // Test - "ResType", // Test + 'Invocation', // () + 'New', // new + 'ResConOverload', // Test + 'ResType', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; - "ExpressionStatement", // this.x = 1; - "ExplicitConstructorInvocation", // super(); + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExpressionStatement', // this.x = 1; + 'ExplicitConstructorInvocation', // super(); - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Object - "ResType", // super + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Object + 'ResType', // super - "Deref", - "EvalVariable", // super + 'Deref', + 'EvalVariable', // super - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; + 'Env', // from Block + 'ReturnStatement', // return this; - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "Pop", - "Assignment", // this.x = 1 + 'Pop', + 'Assignment', // this.x = 1 - "Assign", // = - "Literal", // 1 - "EvalVariable", // this.x + 'Assign', // = + 'Literal', // 1 + 'EvalVariable', // this.x - "Res", // x - "EvalVariable", // this + 'Res', // x + 'EvalVariable', // this - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // skip Env from Block + 'Reset', // skip Env from Block - "Pop", - "Assignment", // test.x = 2 + 'Pop', + 'Assignment', // test.x = 2 - "Assign", // = - "Literal", // 2 - "EvalVariable", // test.x + 'Assign', // = + 'Literal', // 2 + 'EvalVariable', // test.x - "Res", // x - "EvalVariable", // test + 'Res', // x + 'EvalVariable', // test - "Reset", // return - "Void", + 'Reset', // return + 'Void', - "Reset", // skip Env from Block - ]; + 'Reset' // skip Env from Block + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "test", // EvalVariable - "Test", // ResType - "Test", // ResConOverload - "Object", // New - "Object", // ResType - "Object", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "x", // Res - "1", // Literal - "1", // Assign - "this", // EvalVariable - "Object", // this - "Object", // Assign - "test", // EvalVariable - "x", // EvalVariable - "2", // Literal - "2", // Assign - "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); + 'test', // EvalVariable + 'Test', // ResType + 'Test', // ResConOverload + 'Object', // New + 'Object', // ResType + 'Object', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'x', // Res + '1', // Literal + '1', // Assign + 'this', // EvalVariable + 'Object', // this + 'Object', // Assign + 'test', // EvalVariable + 'x', // EvalVariable + '2', // Literal + '2', // Assign + '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 + ) // TODO test env - }); + }) - it("evaluate RHS Class correctly", () => { + it('evaluate RHS Class correctly', () => { const programStr = ` class Test { static int x; @@ -291,105 +291,105 @@ describe("evaluate simple qualified names correctly", () => { int x = Test.x; } } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class Test {...} - "NormalClassDeclaration", // class Object {...} + 'CompilationUnit', - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class Test {...} - "Env", - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} - "FieldDeclaration", // static int x = 0; + 'Env', + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} + 'FieldDeclaration', // static int x = 0; - "Pop", - "Assign", // = - "Literal", // 0 - "EvalVariable", // x + 'Pop', + 'Assign', // = + 'Literal', // 0 + 'EvalVariable', // x - "Pop", - "MethodInvocation", // Test.main([""]) + 'Pop', + 'MethodInvocation', // Test.main([""]) - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test - "Deref", - "EvalVariable", // Test + 'Deref', + 'EvalVariable', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; - "LocalVariableDeclarationStatement", // int x = Test.x; + 'Env', // from Block + 'ReturnStatement', // return; + 'LocalVariableDeclarationStatement', // int x = Test.x; - "ExpressionStatement", // x = Test.x; - "LocalVariableDeclarationStatement", // int x; + 'ExpressionStatement', // x = Test.x; + 'LocalVariableDeclarationStatement', // int x; - "Pop", - "Assignment", // x = Test.x + 'Pop', + 'Assignment', // x = Test.x - "Assign", // = - "ExpressionName", // Test.x - "EvalVariable", // x + 'Assign', // = + 'ExpressionName', // Test.x + 'EvalVariable', // x - "Deref", - "EvalVariable", // Test.x + 'Deref', + 'EvalVariable', // Test.x - "Res", // x - "EvalVariable", // Test + 'Res', // x + 'EvalVariable', // Test - "Reset", // return - "Void", + 'Reset', // return + 'Void', - "Reset", // skip Env from Block - ]; + 'Reset' // skip Env from Block + ] const expectedStashTrace = [ - "x", // EvalVariable - "0", // Literal - "0", // Assign - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'x', // EvalVariable + '0', // Literal + '0', // Assign + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "x", // EvalVariable - "Test", // EvalVariable - "x", // Res - "0", // Deref - "0", // Assign - "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); + 'x', // EvalVariable + 'Test', // EvalVariable + 'x', // Res + '0', // Deref + '0', // Assign + '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 + ) // TODO test env - }); + }) - it("evaluate RHS Object correctly", () => { + it('evaluate RHS Object correctly', () => { const programStr = ` class Test { int x; @@ -398,182 +398,182 @@ describe("evaluate simple qualified names correctly", () => { int x = test.x; } } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", + 'CompilationUnit', - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class Test {...} - "NormalClassDeclaration", // class Object {...} + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class Test {...} - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} + 'Env', + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} - "Env", - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} + 'Pop', + 'MethodInvocation', // Test.main([""]) - "Pop", - "MethodInvocation", // Test.main([""]) + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test + 'Deref', + 'EvalVariable', // Test - "Deref", - "EvalVariable", // Test + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Block + 'ReturnStatement', // return; + 'LocalVariableDeclarationStatement', // int x = test.x; + 'LocalVariableDeclarationStatement', // Test test = new Test(); - "Env", // from Block - "ReturnStatement", // return; - "LocalVariableDeclarationStatement", // int x = test.x; - "LocalVariableDeclarationStatement", // Test test = new Test(); + 'ExpressionStatement', // test = new Test(); + 'LocalVariableDeclarationStatement', // Test test; - "ExpressionStatement", // test = new Test(); - "LocalVariableDeclarationStatement", // Test test; + 'Pop', + 'Assignment', // test = new Test() - "Pop", - "Assignment", // test = new Test() + 'Assign', // = + 'ClassInstanceCreationExpression', // new Test() + 'EvalVariable', // test - "Assign", // = - "ClassInstanceCreationExpression", // new Test() - "EvalVariable", // test + 'Invocation', // () + 'New', // new + 'ResConOverload', // Test + 'ResType', // Test - "Invocation", // () - "New", // new - "ResConOverload", // Test - "ResType", // Test + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExpressionStatement', // this.x = 0; + 'ExplicitConstructorInvocation', // super(); - "Env", // from Block - "ReturnStatement", // return this; - "ExpressionStatement", // this.x = 0; - "ExplicitConstructorInvocation", // super(); + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Object + 'ResType', // super - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Object - "ResType", // super + 'Deref', + 'EvalVariable', // super - "Deref", - "EvalVariable", // super + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Block + 'ReturnStatement', // return this; - "Env", // from Block - "ReturnStatement", // return this; + 'Reset', // return + 'ExpressionName', // this - "Reset", // return - "ExpressionName", // this + 'Deref', + 'EvalVariable', // this - "Deref", - "EvalVariable", // this + 'Reset', // Skip Env from Block - "Reset", // Skip Env from Block + 'Pop', + 'Assignment', // this.x = 0 - "Pop", - "Assignment", // this.x = 0 + 'Assign', // = + 'Literal', // 0 + 'EvalVariable', // this.x - "Assign", // = - "Literal", // 0 - "EvalVariable", // this.x + 'Res', // x + 'EvalVariable', // this - "Res", // x - "EvalVariable", // this + 'Reset', // return + 'ExpressionName', // this - "Reset", // return - "ExpressionName", // this + 'Deref', + 'EvalVariable', // this - "Deref", - "EvalVariable", // this + 'Reset', // skip Env from Block - "Reset", // skip Env from Block + 'ExpressionStatement', // x = test.x; + 'LocalVariableDeclarationStatement', // int x; - "ExpressionStatement", // x = test.x; - "LocalVariableDeclarationStatement", // int x; + 'Pop', + 'Assignment', // x = test.x - "Pop", - "Assignment", // x = test.x + 'Assign', // = + 'ExpressionName', // test.x + 'EvalVariable', // x - "Assign", // = - "ExpressionName", // test.x - "EvalVariable", // x + 'Deref', + 'EvalVariable', // test.x - "Deref", - "EvalVariable", // test.x + 'Res', // x + 'EvalVariable', // test - "Res", // x - "EvalVariable", // test + 'Reset', // return + 'Void', - "Reset", // return - "Void", - - "Reset", // skip Env from Block - ]; + 'Reset' // skip Env from Block + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "test", // EvalVariable - "Test", // ResType - "Test", // ResConOverload - "Object", // New - "Object", // ResType - "Object", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "x", // Res - "0", // Literal - "0", // Assign - "this", // EvalVariable - "Object", // Deref - "Object", // Assign - "x", // EvalVariable - "test", // EvalVariable - "x", // Res - "0", // Deref - "0", // Assign - "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); + 'test', // EvalVariable + 'Test', // ResType + 'Test', // ResConOverload + 'Object', // New + 'Object', // ResType + 'Object', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'x', // Res + '0', // Literal + '0', // Assign + 'this', // EvalVariable + 'Object', // Deref + 'Object', // Assign + 'x', // EvalVariable + 'test', // EvalVariable + 'x', // Res + '0', // Deref + '0', // Assign + '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 + ) // TODO test env - }); -}); + }) +}) -describe("evaluate complex qualified names correctly", () => { - it("evaluate LHS Class correctly", () => { +describe('evaluate complex qualified names correctly', () => { + it('evaluate LHS Class correctly', () => { const programStr = ` class Test { static int x = 1; @@ -582,114 +582,114 @@ describe("evaluate complex qualified names correctly", () => { int x = Test.t.x; } } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class Test {...} - "NormalClassDeclaration", // class Object {...} + 'CompilationUnit', - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class Test {...} - "Env", - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} - "FieldDeclaration", // static Test x = null; - "FieldDeclaration", // static int x = 1; + 'Env', + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} + 'FieldDeclaration', // static Test x = null; + 'FieldDeclaration', // static int x = 1; - "Pop", - "Assign", // = - "Literal", // 1 - "EvalVariable", // x + 'Pop', + 'Assign', // = + 'Literal', // 1 + 'EvalVariable', // x - "Pop", - "Assign", // = - "Literal", // null - "EvalVariable", // Test + 'Pop', + 'Assign', // = + 'Literal', // null + 'EvalVariable', // Test - "Pop", - "MethodInvocation", // Test.main([""]) + 'Pop', + 'MethodInvocation', // Test.main([""]) - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test - "Deref", - "EvalVariable", // Test + 'Deref', + 'EvalVariable', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; - "LocalVariableDeclarationStatement", // int x = Test.t.x; + 'Env', // from Block + 'ReturnStatement', // return; + 'LocalVariableDeclarationStatement', // int x = Test.t.x; - "ExpressionStatement", // x = Test.t.x; - "LocalVariableDeclarationStatement", // int x; + 'ExpressionStatement', // x = Test.t.x; + 'LocalVariableDeclarationStatement', // int x; - "Pop", - "Assignment", // x = Test.t.x + 'Pop', + 'Assignment', // x = Test.t.x - "Assign", // = - "ExpressionName", // Test.t.x - "EvalVariable", // x + 'Assign', // = + 'ExpressionName', // Test.t.x + 'EvalVariable', // x - "Deref", - "EvalVariable", // Test.t.x + 'Deref', + 'EvalVariable', // Test.t.x - "Res", // x - "EvalVariable", // Test.t + 'Res', // x + 'EvalVariable', // Test.t - "Res", // t - "EvalVariable", // Test + 'Res', // t + 'EvalVariable', // Test - "Reset", // return - "Void", + 'Reset', // return + 'Void', - "Reset", // skip Env from Block - ]; + 'Reset' // skip Env from Block + ] const expectedStashTrace = [ - "x", // EvalVariable - "1", // Literal - "1", // Assign - "t", // EvalVariable - "null", // Literal - "null", // Assign - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'x', // EvalVariable + '1', // Literal + '1', // Assign + 't', // EvalVariable + 'null', // Literal + 'null', // Assign + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "x", // EvalVariable - "Test", // EvalVariable - "t", // Res - "x", // Res - "1", // Literal - "1", // Assign - "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); + 'x', // EvalVariable + 'Test', // EvalVariable + 't', // Res + 'x', // Res + '1', // Literal + '1', // Assign + '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 + ) // TODO test env - }); + }) }) diff --git a/src/ec-evaluator/__tests__/simple-mtd-inv.test.ts b/src/ec-evaluator/__tests__/simple-mtd-inv.test.ts index 9c54370..ceb685b 100644 --- a/src/ec-evaluator/__tests__/simple-mtd-inv.test.ts +++ b/src/ec-evaluator/__tests__/simple-mtd-inv.test.ts @@ -1,15 +1,15 @@ -import { parse } from "../../ast/parser"; -import { evaluate } from "../interpreter"; +import { parse } from '../../ast/parser' +import { evaluate } from '../interpreter' import { ControlStub, StashStub, createContextStub, getControlItemStr, getStashItemStr -} from "./__utils__/utils"; +} from './__utils__/utils' -describe("evaluate static MethodInvocation correctly", () => { - it("evaluate static MethodInvocation in static MethodInvocation with simple name correctly", () => { +describe('evaluate static MethodInvocation correctly', () => { + it('evaluate static MethodInvocation in static MethodInvocation with simple name correctly', () => { const programStr = ` class Test { public static void main(String[] args) { @@ -17,106 +17,106 @@ describe("evaluate static MethodInvocation correctly", () => { } static void test() {} } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", + 'CompilationUnit', - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class Test {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class Test {...} - "Env", - "MethodDeclaration", // static void test() {...} - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} + 'Env', + 'MethodDeclaration', // static void test() {...} + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} - "Pop", - "MethodInvocation", // Test.main([""]) + 'Pop', + 'MethodInvocation', // Test.main([""]) - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test - "Deref", - "EvalVariable", // Test + 'Deref', + 'EvalVariable', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; - "ExpressionStatement", // Test.test(); + 'Env', // from Block + 'ReturnStatement', // return; + 'ExpressionStatement', // Test.test(); - "Pop", - "MethodInvocation", // Test.test() + 'Pop', + 'MethodInvocation', // Test.test() - "Invocation", // () - "ResOverride", - "ExpressionName", // Test - "ResOverload", // test - "ResType", // Test + 'Invocation', // () + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // test + 'ResType', // Test - "Deref", - "EvalVariable", // Test + 'Deref', + 'EvalVariable', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; + 'Env', // from Block + 'ReturnStatement', // return; - "Reset", // return - "Void", // + 'Reset', // return + 'Void', // - "Reset", // skip Env from Block + 'Reset', // skip Env from Block - "Reset", // return - "Void", + 'Reset', // return + 'Void', - "Reset", // skip Env from Block - ]; + 'Reset' // skip Env from Block + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "Test", // ResType - "test", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "test", // ResOverride - "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); + 'Test', // ResType + 'test', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'test', // ResOverride + '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 + ) // TODO test env - }); + }) - it("evaluate static MethodInvocation in instance MethodInvocation with simple name correctly", () => { + it('evaluate static MethodInvocation in instance MethodInvocation with simple name correctly', () => { const programStr = ` class Test { public static void main(String[] args) { @@ -128,214 +128,214 @@ describe("evaluate static MethodInvocation correctly", () => { test(1); } } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", + 'CompilationUnit', - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class Test {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class Test {...} - "Env", - "MethodDeclaration", // void test() {...} - "MethodDeclaration", // static void test(int x) {...} - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} + 'Env', + 'MethodDeclaration', // void test() {...} + 'MethodDeclaration', // static void test(int x) {...} + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} - "Pop", - "MethodInvocation", // Test.main([""]) + 'Pop', + 'MethodInvocation', // Test.main([""]) - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test - "Deref", - "EvalVariable", // Test + 'Deref', + 'EvalVariable', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; - "ExpressionStatement", // test.test(); - "LocalVariableDeclarationStatement", // Test test = new Test(); + 'Env', // from Block + 'ReturnStatement', // return; + 'ExpressionStatement', // test.test(); + 'LocalVariableDeclarationStatement', // Test test = new Test(); - "ExpressionStatement", // test = new Test(); - "LocalVariableDeclarationStatement", // Test test; + 'ExpressionStatement', // test = new Test(); + 'LocalVariableDeclarationStatement', // Test test; - "Pop", - "Assignment", // test = new Test() + 'Pop', + 'Assignment', // test = new Test() - "Assign", // = - "ClassInstanceCreationExpression", // new Test() - "EvalVariable", // test + 'Assign', // = + 'ClassInstanceCreationExpression', // new Test() + 'EvalVariable', // test - "Invocation", // () - "New", // new - "ResConOverload", // Test - "ResType", // Test + 'Invocation', // () + 'New', // new + 'ResConOverload', // Test + 'ResType', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; - "ExplicitConstructorInvocation", // super(); + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExplicitConstructorInvocation', // super(); - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Object - "ResType", // super + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Object + 'ResType', // super - "Deref", - "EvalVariable", // super + 'Deref', + 'EvalVariable', // super - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; + 'Env', // from Block + 'ReturnStatement', // return this; - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // skip Env from Block + 'Reset', // skip Env from Block - "Pop", - "MethodInvocation", // test.test() + 'Pop', + 'MethodInvocation', // test.test() - "Invocation", // () - "ResOverride", - "ExpressionName", // test - "ResOverload", // test - "ResType", // Test + 'Invocation', // () + 'ResOverride', + 'ExpressionName', // test + 'ResOverload', // test + 'ResType', // Test - "Deref", - "EvalVariable", // test + 'Deref', + 'EvalVariable', // test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; - "ExpressionStatement", // this.test(1); + 'Env', // from Block + 'ReturnStatement', // return; + 'ExpressionStatement', // this.test(1); - "Pop", - "MethodInvocation", // this.test(1) + 'Pop', + 'MethodInvocation', // this.test(1) - "Invocation", - "Literal", // 1 - "ResOverride", - "ExpressionName", // this - "ResOverload", // test - "ResType", // 1 - "ResType", // this + 'Invocation', + 'Literal', // 1 + 'ResOverride', + 'ExpressionName', // this + 'ResOverload', // test + 'ResType', // 1 + 'ResType', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; + 'Env', // from Block + 'ReturnStatement', // return; - "Reset", // return - "Void", // + 'Reset', // return + 'Void', // - "Reset", // skip Env from Block + 'Reset', // skip Env from Block - "Reset", // return - "Void", // + 'Reset', // return + 'Void', // - "Reset", // skip Env from Block + 'Reset', // skip Env from Block - "Reset", // return - "Void", // + 'Reset', // return + 'Void', // - "Reset", // skip Env from Block - ]; + 'Reset' // skip Env from Block + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "test", // EvalVariable - "Test", // ResType - "Test", // ResConOverload - "Object", // New - "Object", // ResType - "Object", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "Object", // Assign - "Test", // ResType - "test", // ResOverload - "test", // EvalVariable - "Object", // Deref - "test", // ResOverride - "Object", - "Test", // ResType - "int", // ResType - "test", // ResOverload - "this", // EvalVariable - "Object", // Deref - "test", // ResOverride - "1", // Literal - "Void", - "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); + 'test', // EvalVariable + 'Test', // ResType + 'Test', // ResConOverload + 'Object', // New + 'Object', // ResType + 'Object', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'Object', // Assign + 'Test', // ResType + 'test', // ResOverload + 'test', // EvalVariable + 'Object', // Deref + 'test', // ResOverride + 'Object', + 'Test', // ResType + 'int', // ResType + 'test', // ResOverload + 'this', // EvalVariable + 'Object', // Deref + 'test', // ResOverride + '1', // Literal + 'Void', + '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 + ) // TODO test env - }); -}); + }) +}) -describe("evaluate instance MethodInvocation correctly", () => { - it("evaluate instance MethodInvocation in instance MethodInvocation with simple name correctly", () => { +describe('evaluate instance MethodInvocation correctly', () => { + it('evaluate instance MethodInvocation in instance MethodInvocation with simple name correctly', () => { const programStr = ` class Test { public static void main(String[] args) { @@ -347,209 +347,209 @@ describe("evaluate instance MethodInvocation correctly", () => { test(1); } } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", + 'CompilationUnit', - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class Test {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class Test {...} - "Env", - "MethodDeclaration", // void test() {...} - "MethodDeclaration", // void test(int x) {...} - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} + 'Env', + 'MethodDeclaration', // void test() {...} + 'MethodDeclaration', // void test(int x) {...} + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} - "Pop", - "MethodInvocation", // Test.main([""]) + 'Pop', + 'MethodInvocation', // Test.main([""]) - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test - "Deref", - "EvalVariable", // Test + 'Deref', + 'EvalVariable', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; - "ExpressionStatement", // test.test(); - "LocalVariableDeclarationStatement", // Test test = new Test(); + 'Env', // from Block + 'ReturnStatement', // return; + 'ExpressionStatement', // test.test(); + 'LocalVariableDeclarationStatement', // Test test = new Test(); - "ExpressionStatement", // test = new Test(); - "LocalVariableDeclarationStatement", // Test test; + 'ExpressionStatement', // test = new Test(); + 'LocalVariableDeclarationStatement', // Test test; - "Pop", - "Assignment", // test = new Test() + 'Pop', + 'Assignment', // test = new Test() - "Assign", // = - "ClassInstanceCreationExpression", // new Test() - "EvalVariable", // test + 'Assign', // = + 'ClassInstanceCreationExpression', // new Test() + 'EvalVariable', // test - "Invocation", // () - "New", // new - "ResConOverload", // Test - "ResType", // Test + 'Invocation', // () + 'New', // new + 'ResConOverload', // Test + 'ResType', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; - "ExplicitConstructorInvocation", // super(); + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExplicitConstructorInvocation', // super(); - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Object - "ResType", // super + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Object + 'ResType', // super - "Deref", - "EvalVariable", // super + 'Deref', + 'EvalVariable', // super - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; + 'Env', // from Block + 'ReturnStatement', // return this; - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // skip Env from Block + 'Reset', // skip Env from Block - "Pop", - "MethodInvocation", // test.test() + 'Pop', + 'MethodInvocation', // test.test() - "Invocation", // () - "ResOverride", - "ExpressionName", // test - "ResOverload", // test - "ResType", // Test + 'Invocation', // () + 'ResOverride', + 'ExpressionName', // test + 'ResOverload', // test + 'ResType', // Test - "Deref", - "EvalVariable", // test + 'Deref', + 'EvalVariable', // test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; - "ExpressionStatement", // this.test(1); + 'Env', // from Block + 'ReturnStatement', // return; + 'ExpressionStatement', // this.test(1); - "Pop", - "MethodInvocation", // this.test(1) + 'Pop', + 'MethodInvocation', // this.test(1) - "Invocation", // () - "Literal", // 1 - "ResOverride", - "ExpressionName", // this - "ResOverload", // test - "ResType", // 1 - "ResType", // this + 'Invocation', // () + 'Literal', // 1 + 'ResOverride', + 'ExpressionName', // this + 'ResOverload', // test + 'ResType', // 1 + 'ResType', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; + 'Env', // from Block + 'ReturnStatement', // return; - "Reset", // return - "Void", + 'Reset', // return + 'Void', - "Reset", // skip Env from Block + 'Reset', // skip Env from Block - "Reset", // return - "Void", // + 'Reset', // return + 'Void', // - "Reset", // skip Env from Block + 'Reset', // skip Env from Block - "Reset", // return - "Void", // + 'Reset', // return + 'Void', // - "Reset", // skip Env from Block - ]; + 'Reset' // skip Env from Block + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "test", // EvalVariable - "Test", // ResType - "Test", // ResConOverload - "Object", // New - "Object", // ResType - "Object", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "Object", // Assign - "Test", // ResType - "test", // ResOverload - "test", // EvalVariable - "Object", // Deref - "test", // ResOverride - "Object", - "Test", // ResType - "int", // ResType - "test", // ResOverload - "this", // EvalVariable - "Object", // Deref - "test", // ResOverride - "Object", - "1", // Literal - "Void", - "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); + 'test', // EvalVariable + 'Test', // ResType + 'Test', // ResConOverload + 'Object', // New + 'Object', // ResType + 'Object', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'Object', // Assign + 'Test', // ResType + 'test', // ResOverload + 'test', // EvalVariable + 'Object', // Deref + 'test', // ResOverride + 'Object', + 'Test', // ResType + 'int', // ResType + 'test', // ResOverload + 'this', // EvalVariable + 'Object', // Deref + 'test', // ResOverride + 'Object', + '1', // Literal + 'Void', + '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 + ) // TODO test env - }); -}); + }) +}) diff --git a/src/ec-evaluator/__tests__/this-keyword.test.ts b/src/ec-evaluator/__tests__/this-keyword.test.ts index 8683a0f..2c475a9 100644 --- a/src/ec-evaluator/__tests__/this-keyword.test.ts +++ b/src/ec-evaluator/__tests__/this-keyword.test.ts @@ -1,15 +1,15 @@ -import { parse } from "../../ast/parser"; -import { evaluate } from "../interpreter"; +import { parse } from '../../ast/parser' +import { evaluate } from '../interpreter' import { ControlStub, StashStub, createContextStub, getControlItemStr, getStashItemStr -} from "./__utils__/utils"; +} from './__utils__/utils' -describe("evaluate field access with this keyword correctly", () => { - it("evaluate LHS this correctly", () => { +describe('evaluate field access with this keyword correctly', () => { + it('evaluate LHS this correctly', () => { const programStr = ` class Test { int x = 1; @@ -21,206 +21,206 @@ describe("evaluate field access with this keyword correctly", () => { this.x = 2; } } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", + 'CompilationUnit', - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class Test {...} - "NormalClassDeclaration", // class Object {...} + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class Test {...} - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} + 'Env', + 'MethodDeclaration', // void test() {...} + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} - "Env", - "MethodDeclaration", // void test() {...} - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} + 'Pop', + 'MethodInvocation', // Test.main([""]) - "Pop", - "MethodInvocation", // Test.main([""]) - - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test - "Deref", - "EvalVariable", // Test + 'Deref', + 'EvalVariable', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; - "ExpressionStatement", // test.test(); - "LocalVariableDeclarationStatement", // Test test = new Test(); + 'Env', // from Block + 'ReturnStatement', // return; + 'ExpressionStatement', // test.test(); + 'LocalVariableDeclarationStatement', // Test test = new Test(); - "ExpressionStatement", // test = new Test(); - "LocalVariableDeclarationStatement", // Test test; + 'ExpressionStatement', // test = new Test(); + 'LocalVariableDeclarationStatement', // Test test; - "Pop", - "Assignment", // test = new Test() + 'Pop', + 'Assignment', // test = new Test() - "Assign", // = - "ClassInstanceCreationExpression", // new Test() - "EvalVariable", // test + 'Assign', // = + 'ClassInstanceCreationExpression', // new Test() + 'EvalVariable', // test - "Invocation", // () - "New", // new - "ResConOverload", // Test - "ResType", // Test + 'Invocation', // () + 'New', // new + 'ResConOverload', // Test + 'ResType', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; - "ExpressionStatement", // this.x = 1; - "ExplicitConstructorInvocation", // super(); + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExpressionStatement', // this.x = 1; + 'ExplicitConstructorInvocation', // super(); - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Object - "ResType", // super + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Object + 'ResType', // super - "Deref", - "EvalVariable", // super + 'Deref', + 'EvalVariable', // super - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; + 'Env', // from Block + 'ReturnStatement', // return this; - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "Pop", - "Assignment", // this.x = 1 + 'Pop', + 'Assignment', // this.x = 1 - "Assign", // = - "Literal", // 1 - "EvalVariable", // this.x + 'Assign', // = + 'Literal', // 1 + 'EvalVariable', // this.x - "Res", // x - "EvalVariable", // this + 'Res', // x + 'EvalVariable', // this - "Reset", // return - "ExpressionName", // this - - "Deref", - "EvalVariable", // this + 'Reset', // return + 'ExpressionName', // this - "Reset", // skip Env from Block + 'Deref', + 'EvalVariable', // this - "Pop", - "MethodInvocation", // test.test() + 'Reset', // skip Env from Block - "Invocation", // () - "ResOverride", - "ExpressionName", // test - "ResOverload", // test - "ResType", // test + 'Pop', + 'MethodInvocation', // test.test() - "Deref", - "EvalVariable", // test + 'Invocation', // () + 'ResOverride', + 'ExpressionName', // test + 'ResOverload', // test + 'ResType', // test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Deref', + 'EvalVariable', // test - "Env", // from Block - "ReturnStatement", // return; - "ExpressionStatement", // this.x = 2; + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Pop", - "Assignment", // this.x = 2 + 'Env', // from Block + 'ReturnStatement', // return; + 'ExpressionStatement', // this.x = 2; - "Assign", // = - "Literal", // 2 - "EvalVariable", // this.x + 'Pop', + 'Assignment', // this.x = 2 - "Res", // x - "EvalVariable", // this + 'Assign', // = + 'Literal', // 2 + 'EvalVariable', // this.x - "Reset", // return - "Void", + 'Res', // x + 'EvalVariable', // this - "Reset", // skip Env from Block + 'Reset', // return + 'Void', - "Reset", // return - "Void", + 'Reset', // skip Env from Block - "Reset", // skip Env from Block - ]; + 'Reset', // return + 'Void', + + 'Reset' // skip Env from Block + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "test", // EvalVariable - "Test", // ResType - "Test", // ResConOverload - "Object", // New - "Object", // ResType - "Object", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "x", // Res - "1", // Literal - "1", // Assign - "this", // EvalVariable - "Object", // Deref - "Object", // Assign - "Test", // ResType - "test", // ResOverload - "test", // EvalVariable - "Object", // Deref - "test", // ResOverride - "Object", - "this", // EvalVariable - "x", // Res - "2", // Literal - "2", // Assign - "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); + 'test', // EvalVariable + 'Test', // ResType + 'Test', // ResConOverload + 'Object', // New + 'Object', // ResType + 'Object', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'x', // Res + '1', // Literal + '1', // Assign + 'this', // EvalVariable + 'Object', // Deref + 'Object', // Assign + 'Test', // ResType + 'test', // ResOverload + 'test', // EvalVariable + 'Object', // Deref + 'test', // ResOverride + 'Object', + 'this', // EvalVariable + 'x', // Res + '2', // Literal + '2', // Assign + '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 + ) // TODO test env - }); + }) - it("evaluate RHS this correctly", () => { + it('evaluate RHS this correctly', () => { const programStr = ` class Test { int x = 1; @@ -232,215 +232,215 @@ describe("evaluate field access with this keyword correctly", () => { int x = this.x; } } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", - - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class Test {...} - "NormalClassDeclaration", // class Object {...} + 'CompilationUnit', - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class Test {...} - "Env", - "MethodDeclaration", // void test() {...} - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} + 'Env', + 'MethodDeclaration', // void test() {...} + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} - "Pop", - "MethodInvocation", // Test.main([""]) + 'Pop', + 'MethodInvocation', // Test.main([""]) - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test - "Deref", - "EvalVariable", // Test + 'Deref', + 'EvalVariable', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; - "ExpressionStatement", // test.test(); - "LocalVariableDeclarationStatement", // Test test = new Test(); + 'Env', // from Block + 'ReturnStatement', // return; + 'ExpressionStatement', // test.test(); + 'LocalVariableDeclarationStatement', // Test test = new Test(); - "ExpressionStatement", // test = new Test(); - "LocalVariableDeclarationStatement", // Test test; + 'ExpressionStatement', // test = new Test(); + 'LocalVariableDeclarationStatement', // Test test; - "Pop", - "Assignment", // test = new Test() + 'Pop', + 'Assignment', // test = new Test() - "Assign", // = - "ClassInstanceCreationExpression", // new Test() - "EvalVariable", // test + 'Assign', // = + 'ClassInstanceCreationExpression', // new Test() + 'EvalVariable', // test - "Invocation", // () - "New", // new - "ResConOverload", // Test - "ResType", // Test + 'Invocation', // () + 'New', // new + 'ResConOverload', // Test + 'ResType', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; - "ExpressionStatement", // this.x = 1; - "ExplicitConstructorInvocation", // super(); + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExpressionStatement', // this.x = 1; + 'ExplicitConstructorInvocation', // super(); - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Object - "ResType", // super + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Object + 'ResType', // super - "Deref", - "EvalVariable", // super + 'Deref', + 'EvalVariable', // super - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; + 'Env', // from Block + 'ReturnStatement', // return this; - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "Pop", - "Assignment", // this.x = 1 + 'Pop', + 'Assignment', // this.x = 1 - "Assign", // = - "Literal", // 1 - "EvalVariable", // this.x + 'Assign', // = + 'Literal', // 1 + 'EvalVariable', // this.x - "Res", // x - "EvalVariable", // this + 'Res', // x + 'EvalVariable', // this - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // skip Env from Block + 'Reset', // skip Env from Block - "Pop", - "MethodInvocation", // test.test() + 'Pop', + 'MethodInvocation', // test.test() - "Invocation", // () - "ResOverride", - "ExpressionName", // test - "ResOverload", // test - "ResType", // test + 'Invocation', // () + 'ResOverride', + 'ExpressionName', // test + 'ResOverload', // test + 'ResType', // test - "Deref", - "EvalVariable", // test + 'Deref', + 'EvalVariable', // test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; - "LocalVariableDeclarationStatement", // int x = this.x; + 'Env', // from Block + 'ReturnStatement', // return; + 'LocalVariableDeclarationStatement', // int x = this.x; - "ExpressionStatement", // x = this.x; - "LocalVariableDeclarationStatement", // int x; + 'ExpressionStatement', // x = this.x; + 'LocalVariableDeclarationStatement', // int x; - "Pop", - "Assignment", // x = this.x + 'Pop', + 'Assignment', // x = this.x - "Assign", // = - "ExpressionName", // this.x - "EvalVariable", // x + 'Assign', // = + 'ExpressionName', // this.x + 'EvalVariable', // x - "Deref", - "EvalVariable", // this.x + 'Deref', + 'EvalVariable', // this.x - "Res", // x - "EvalVariable", // this + 'Res', // x + 'EvalVariable', // this - "Reset", // return - "Void", + 'Reset', // return + 'Void', - "Reset", // skip Env from Block + 'Reset', // skip Env from Block - "Reset", // return - "Void", + 'Reset', // return + 'Void', - "Reset", // skip Env from Block - ]; + 'Reset' // skip Env from Block + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "test", // EvalVariable - "Test", // ResConOverload - "Test", // ResType - "Object", // New - "Object", // ResType - "Object", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "x", // Res - "1", // Literal - "1", // Assign - "this", // EvalVariable - "Object", // Deref - "Object", // Assign - "Test", // ResType - "test", // ResOverload - "test", // EvalVariable - "Object", // Deref - "test", // ResOverride - "Object", - "x", // EvalVariable - "this", // EvalVariable - "x", // Res - "1", // Deref - "1", // Assign - "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); + 'test', // EvalVariable + 'Test', // ResConOverload + 'Test', // ResType + 'Object', // New + 'Object', // ResType + 'Object', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'x', // Res + '1', // Literal + '1', // Assign + 'this', // EvalVariable + 'Object', // Deref + 'Object', // Assign + 'Test', // ResType + 'test', // ResOverload + 'test', // EvalVariable + 'Object', // Deref + 'test', // ResOverride + 'Object', + 'x', // EvalVariable + 'this', // EvalVariable + 'x', // Res + '1', // Deref + '1', // Assign + '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 + ) // TODO test env - }); + }) }) -describe("evaluate method invocation with this keyword correctly", () => { - it("evaluate static MethodInvocation in instance MethodInvocation with this keyword correctly", () => { +describe('evaluate method invocation with this keyword correctly', () => { + it('evaluate static MethodInvocation in instance MethodInvocation with this keyword correctly', () => { const programStr = ` class Test { public static void main(String[] args) { @@ -452,212 +452,212 @@ describe("evaluate method invocation with this keyword correctly", () => { this.test(1); } } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", + 'CompilationUnit', - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class Test {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class Test {...} - "Env", - "MethodDeclaration", // void test() {...} - "MethodDeclaration", // static void test(int x) {...} - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} + 'Env', + 'MethodDeclaration', // void test() {...} + 'MethodDeclaration', // static void test(int x) {...} + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} - "Pop", - "MethodInvocation", // Test.main([""]) + 'Pop', + 'MethodInvocation', // Test.main([""]) - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test - "Deref", - "EvalVariable", // Test + 'Deref', + 'EvalVariable', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; - "ExpressionStatement", // test.test(); - "LocalVariableDeclarationStatement", // Test test = new Test(); + 'Env', // from Block + 'ReturnStatement', // return; + 'ExpressionStatement', // test.test(); + 'LocalVariableDeclarationStatement', // Test test = new Test(); - "ExpressionStatement", // test = new Test(); - "LocalVariableDeclarationStatement", // Test test; + 'ExpressionStatement', // test = new Test(); + 'LocalVariableDeclarationStatement', // Test test; - "Pop", - "Assignment", // test = new Test() + 'Pop', + 'Assignment', // test = new Test() - "Assign", // = - "ClassInstanceCreationExpression", // new Test() - "EvalVariable", // test + 'Assign', // = + 'ClassInstanceCreationExpression', // new Test() + 'EvalVariable', // test - "Invocation", // () - "New", // new - "ResConOverload", // Test - "ResType", // Test + 'Invocation', // () + 'New', // new + 'ResConOverload', // Test + 'ResType', // Test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; - "ExplicitConstructorInvocation", // super(); + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExplicitConstructorInvocation', // super(); - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Object - "ResType", // super + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Object + 'ResType', // super - "Deref", - "EvalVariable", // super + 'Deref', + 'EvalVariable', // super - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return this; + 'Env', // from Block + 'ReturnStatement', // return this; - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // Skip Env from Block + 'Reset', // Skip Env from Block - "Reset", // return - "ExpressionName", // this + 'Reset', // return + 'ExpressionName', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Reset", // skip Env from Block + 'Reset', // skip Env from Block - "Pop", - "MethodInvocation", // test.test() + 'Pop', + 'MethodInvocation', // test.test() - "Invocation", // () - "ResOverride", - "ExpressionName", // test - "ResOverload", // test - "ResType", // Test + 'Invocation', // () + 'ResOverride', + 'ExpressionName', // test + 'ResOverload', // test + 'ResType', // Test - "Deref", - "EvalVariable", // test + 'Deref', + 'EvalVariable', // test - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; - "ExpressionStatement", // this.test(1); + 'Env', // from Block + 'ReturnStatement', // return; + 'ExpressionStatement', // this.test(1); - "Pop", - "MethodInvocation", // this.test(1) + 'Pop', + 'MethodInvocation', // this.test(1) - "Invocation", - "Literal", // 1 - "ResOverride", - "ExpressionName", // this - "ResOverload", // test - "ResType", // 1 - "ResType", // this + 'Invocation', + 'Literal', // 1 + 'ResOverride', + 'ExpressionName', // this + 'ResOverload', // test + 'ResType', // 1 + 'ResType', // this - "Deref", - "EvalVariable", // this + 'Deref', + 'EvalVariable', // this - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Env", // from Block - "ReturnStatement", // return; + 'Env', // from Block + 'ReturnStatement', // return; - "Reset", // return - "Void", // + 'Reset', // return + 'Void', // - "Reset", // skip Env from Block + 'Reset', // skip Env from Block - "Reset", // return - "Void", // + 'Reset', // return + 'Void', // - "Reset", // skip Env from Block + 'Reset', // skip Env from Block - "Reset", // return - "Void", // + 'Reset', // return + 'Void', // - "Reset", // skip Env from Block - ]; + 'Reset' // skip Env from Block + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "test", // EvalVariable - "Test", // ResType - "Test", // ResConOverload - "Object", // New - "Object", // ResType - "Object", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "Object", // Assign - "Test", // ResType - "test", // ResOverload - "test", // EvalVariable - "Object", // Deref - "test", // ResOverride - "Object", - "Test", // ResType - "int", // ResType - "test", // ResOverload - "this", // EvalVariable - "Object", // Deref - "test", // ResOverride - "1", // Literal - "Void", - "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); + 'test', // EvalVariable + 'Test', // ResType + 'Test', // ResConOverload + 'Object', // New + 'Object', // ResType + 'Object', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'Object', // Assign + 'Test', // ResType + 'test', // ResOverload + 'test', // EvalVariable + 'Object', // Deref + 'test', // ResOverride + 'Object', + 'Test', // ResType + 'int', // ResType + 'test', // ResOverload + 'this', // EvalVariable + 'Object', // Deref + 'test', // ResOverride + '1', // Literal + 'Void', + '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 + ) // TODO test env - }); + }) - it("evaluate instance MethodInvocation in instance MethodInvocation with this keyword correctly", () => { + it('evaluate instance MethodInvocation in instance MethodInvocation with this keyword correctly', () => { const programStr = ` class Test { public static void main(String[] args) { @@ -671,213 +671,213 @@ describe("evaluate method invocation with this keyword correctly", () => { this.test(1); } } - `; + ` - const compilationUnit = parse(programStr); - expect(compilationUnit).toBeTruthy(); + const compilationUnit = parse(programStr) + expect(compilationUnit).toBeTruthy() - const context = createContextStub(); - context.control.push(compilationUnit!); + const context = createContextStub() + context.control.push(compilationUnit!) - const result = evaluate(context); + const result = evaluate(context) const expectedControlTrace = [ - "CompilationUnit", + 'CompilationUnit', + + 'ExpressionStatement', // Test.main([""]); + 'NormalClassDeclaration', // class Test {...} + + 'Env', + 'MethodDeclaration', // void test() {...} + 'MethodDeclaration', // int test(int x) {...} + 'MethodDeclaration', // public static void main(String[] args) {...} + 'ConstructorDeclaration', // Test() {...} - "ExpressionStatement", // Test.main([""]); - "NormalClassDeclaration", // class Test {...} - "NormalClassDeclaration", // class Object {...} - - "Env", // from NormalClassDeclaration - "ConstructorDeclaration", // Object() {...} + 'Pop', + 'MethodInvocation', // Test.main([""]) - "Env", - "MethodDeclaration", // void test() {...} - "MethodDeclaration", // int test(int x) {...} - "MethodDeclaration", // public static void main(String[] args) {...} - "ConstructorDeclaration", // Test() {...} + 'Invocation', // () + 'Literal', // [""] + 'ResOverride', + 'ExpressionName', // Test + 'ResOverload', // main + 'ResType', // [""] + 'ResType', // Test - "Pop", - "MethodInvocation", // Test.main([""]) + 'Deref', + 'EvalVariable', // Test - "Invocation", // () - "Literal", // [""] - "ResOverride", - "ExpressionName", // Test - "ResOverload", // main - "ResType", // [""] - "ResType", // Test - - "Deref", - "EvalVariable", // Test - - "Env", // from Invocation - "Marker", - "Block", // {...} - - "Env", // from Block - "ReturnStatement", // return; - "ExpressionStatement", // test.test(); - "LocalVariableDeclarationStatement", // Test test = new Test(); + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "ExpressionStatement", // test = new Test(); - "LocalVariableDeclarationStatement", // Test test; + 'Env', // from Block + 'ReturnStatement', // return; + 'ExpressionStatement', // test.test(); + 'LocalVariableDeclarationStatement', // Test test = new Test(); - "Pop", - "Assignment", // test = new Test() + 'ExpressionStatement', // test = new Test(); + 'LocalVariableDeclarationStatement', // Test test; - "Assign", // = - "ClassInstanceCreationExpression", // new Test() - "EvalVariable", // test + 'Pop', + 'Assignment', // test = new Test() - "Invocation", // () - "New", // new - "ResConOverload", // Test - "ResType", // Test - - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Assign', // = + 'ClassInstanceCreationExpression', // new Test() + 'EvalVariable', // test - "Env", // from Block - "ReturnStatement", // return this; - "ExplicitConstructorInvocation", // super(); + 'Invocation', // () + 'New', // new + 'ResConOverload', // Test + 'ResType', // Test - "Pop", - "Invocation", // () - "ExpressionName", // super - "ResConOverload", // Object - "ResType", // super + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Deref", - "EvalVariable", // super + 'Env', // from Block + 'ReturnStatement', // return this; + 'ExplicitConstructorInvocation', // super(); - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Pop', + 'Invocation', // () + 'ExpressionName', // super + 'ResConOverload', // Object + 'ResType', // super - "Env", // from Block - "ReturnStatement", // return this; + 'Deref', + 'EvalVariable', // super - "Reset", // return - "ExpressionName", // this + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Deref", - "EvalVariable", // this + 'Env', // from Block + 'ReturnStatement', // return this; - "Reset", // Skip Env from Block + 'Reset', // return + 'ExpressionName', // this - "Reset", // return - "ExpressionName", // this + 'Deref', + 'EvalVariable', // this - "Deref", - "EvalVariable", // this + 'Reset', // Skip Env from Block - "Reset", // skip Env from Block + 'Reset', // return + 'ExpressionName', // this - "Pop", - "MethodInvocation", // test.test() + 'Deref', + 'EvalVariable', // this - "Invocation", // () - "ResOverride", - "ExpressionName", // test - "ResOverload", // test - "ResType", // Test + 'Reset', // skip Env from Block - "Deref", - "EvalVariable", // test + 'Pop', + 'MethodInvocation', // test.test() - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Invocation', // () + 'ResOverride', + 'ExpressionName', // test + 'ResOverload', // test + 'ResType', // Test - "Env", // from Block - "ReturnStatement", // return; - "ExpressionStatement", // this.test(1); + 'Deref', + 'EvalVariable', // test - "Pop", - "MethodInvocation", // this.test(1) + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Invocation", // () - "Literal", // 1 - "ResOverride", - "ExpressionName", // this - "ResOverload", // test - "ResType", // 1 - "ResType", // this + 'Env', // from Block + 'ReturnStatement', // return; + 'ExpressionStatement', // this.test(1); - "Deref", - "EvalVariable", // this + 'Pop', + 'MethodInvocation', // this.test(1) - "Env", // from Invocation - "Marker", - "Block", // {...} + 'Invocation', // () + 'Literal', // 1 + 'ResOverride', + 'ExpressionName', // this + 'ResOverload', // test + 'ResType', // 1 + 'ResType', // this - "Env", // from Block - "ReturnStatement", // return x; + 'Deref', + 'EvalVariable', // this - "Reset", // return - "ExpressionName", // x + 'Env', // from Invocation + 'Marker', + 'Block', // {...} - "Deref", - "EvalVariable", // x + 'Env', // from Block + 'ReturnStatement', // return x; - "Reset", // skip Env from Block + 'Reset', // return + 'ExpressionName', // x - "Reset", // return - "Void", // + 'Deref', + 'EvalVariable', // x - "Reset", // skip Env from Block + 'Reset', // skip Env from Block - "Reset", // return - "Void", // + 'Reset', // return + 'Void', // - "Reset", // skip Env from Block - ]; + 'Reset', // skip Env from Block + + 'Reset', // return + 'Void', // + + 'Reset' // skip Env from Block + ] const expectedStashTrace = [ - "Test", // ResType - "String[]", // ResType - "main", // ResOverload - "Test", // EvalVariable - "Test", // Deref - "main", // ResOverride + 'Test', // ResType + 'String[]', // ResType + 'main', // ResOverload + 'Test', // EvalVariable + 'Test', // Deref + 'main', // ResOverride `[""]`, // Literal - "test", // EvalVariable - "Test", // ResType - "Test", // ResConOverload - "Object", // New - "Object", // ResType - "Object", // ResConOverload - "super", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "this", // EvalVariable - "Object", // Deref - "Object", // Assign - "Test", // ResType - "test", // ResOverload - "test", // EvalVariable - "Object", // Deref - "test", // ResOverride - "Object", - "Test", // ResType - "int", // ResType - "test", // ResOverload - "this", // EvalVariable - "Object", // Deref - "test", // ResOverride - "Object", - "1", // Literal - "x", // EvalVariable - "1", // Deref - "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); + 'test', // EvalVariable + 'Test', // ResType + 'Test', // ResConOverload + 'Object', // New + 'Object', // ResType + 'Object', // ResConOverload + 'super', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'this', // EvalVariable + 'Object', // Deref + 'Object', // Assign + 'Test', // ResType + 'test', // ResOverload + 'test', // EvalVariable + 'Object', // Deref + 'test', // ResOverride + 'Object', + 'Test', // ResType + 'int', // ResType + 'test', // ResOverload + 'this', // EvalVariable + 'Object', // Deref + 'test', // ResOverride + 'Object', + '1', // Literal + 'x', // EvalVariable + '1', // Deref + '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 + ) // TODO test env - }); -}); + }) +}) From 16c7ee04b513211336a9435be2c8b913344020ce Mon Sep 17 00:00:00 2001 From: mattcce Date: Fri, 17 Oct 2025 15:16:28 +0800 Subject: [PATCH 13/14] fix library class parsing bug Previously, the library classes would be injected but the evaluator would not run the program to completion as it was limited by the input target step. --- src/ec-evaluator/index.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/ec-evaluator/index.ts b/src/ec-evaluator/index.ts index 380cfd9..ac4e285 100644 --- a/src/ec-evaluator/index.ts +++ b/src/ec-evaluator/index.ts @@ -25,7 +25,8 @@ export const runECEvaluator = ( if (typeCheckResult.hasTypeErrors) { const typeErrMsg = typeCheckResult.errorMsgs.join('\n') context.interfaces.stderr('TypeCheck', typeErrMsg) - return Promise.resolve({ status: 'error' } as Error) + console.error(typeErrMsg) + return Promise.resolve({ status: 'error', context } as Error) } // load library @@ -33,7 +34,9 @@ export const runECEvaluator = ( context.control.push( ...handleSequence(libraryCompilationUnit.topLevelClassOrInterfaceDeclarations) ) - evaluate(context, targetStep) + + // step size limit is irrelevant here, just makes injected library classes run to completion + evaluate(context, 100000) try { // parse() may throw SyntaxError. From 4d10a34397047f119ea63f51e66c45da960baa87 Mon Sep 17 00:00:00 2001 From: mattcce Date: Fri, 17 Oct 2025 15:20:15 +0800 Subject: [PATCH 14/14] add System.out::println native method for CSEC machine --- src/ec-evaluator/lib.ts | 13 ++++++++++--- src/ec-evaluator/natives.ts | 2 +- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/ec-evaluator/lib.ts b/src/ec-evaluator/lib.ts index 61c45ca..abb56f0 100644 --- a/src/ec-evaluator/lib.ts +++ b/src/ec-evaluator/lib.ts @@ -35,12 +35,19 @@ export class LFSR { export const libraryClasses = ` class Object { - public static native void display(int s); - public native int hashCode(); public native String toString(); -}` +} + +class PrintStream { + public static native void println(String s); +} + +class System { + public static PrintStream out = new PrintStream(); +} +` // const disabled = `class PrintStream extends Object { // public native void println(String s); diff --git a/src/ec-evaluator/natives.ts b/src/ec-evaluator/natives.ts index 0c9f8f2..aea5537 100644 --- a/src/ec-evaluator/natives.ts +++ b/src/ec-evaluator/natives.ts @@ -44,7 +44,7 @@ export const foreigns: { stash.push(stashItem) }, - 'Object::display(int s): void': ({ environment, interfaces }) => { + 'PrintStream::println(String s): void': ({ environment, interfaces }) => { // @ts-expect-error ts(2339): guaranteed valid by type checker const s = environment.getVariable('s').value.literalType.value