diff --git a/ts2panda/BUILD.gn b/ts2panda/BUILD.gn index 212e144a548b4ae7a797b8351eb932668596d26a..d01ca6cd5e43c298752303e3d4635687d548a1a5 100755 --- a/ts2panda/BUILD.gn +++ b/ts2panda/BUILD.gn @@ -314,3 +314,52 @@ group("ark_ts2abc_build") { ] } } + +ohos_copy("ts2abc_tests") { + sources = [ "${ts2abc_root}/tests" ] + deps = [ ":npm_run_build" ] + + outputs = [ target_out_dir + "/tests" ] + module_install_name = "" +} + +group("ts2abc_unittests") { + deps = [ + "tests:arguments_tests(${buildtool_linux})", + "tests:binary_tests(${buildtool_linux})", + "tests:call_tests(${buildtool_linux})", + "tests:cmpBinary_tests(${buildtool_linux})", + "tests:conditions_tests(${buildtool_linux})", + "tests:debugger_tests(${buildtool_linux})", + "tests:delete_tests(${buildtool_linux})", + "tests:doWhile_tests(${buildtool_linux})", + "tests:elementAccess_tests(${buildtool_linux})", + "tests:forOf_tests(${buildtool_linux})", + "tests:for_tests(${buildtool_linux})", + "tests:forin_tests(${buildtool_linux})", + "tests:functionDeclaration_tests(${buildtool_linux})", + "tests:functionExpression_tests(${buildtool_linux})", + "tests:hello_tests(${buildtool_linux})", + "tests:literal_tests(${buildtool_linux})", + "tests:logicBinary_tests(${buildtool_linux})", + "tests:new_tests(${buildtool_linux})", + "tests:numericLiteral_tests(${buildtool_linux})", + "tests:operationEqual_tests(${buildtool_linux})", + "tests:parenthesized_tests(${buildtool_linux})", + "tests:postfixOperations_tests(${buildtool_linux})", + "tests:prefixOperations_tests(${buildtool_linux})", + "tests:propertyAccess_tests(${buildtool_linux})", + "tests:regular_tests(${buildtool_linux})", + "tests:return_tests(${buildtool_linux})", + "tests:strictmode_tests(${buildtool_linux})", + "tests:stringLiteral_tests(${buildtool_linux})", + "tests:switch_tests(${buildtool_linux})", + "tests:template_tests(${buildtool_linux})", + "tests:thisKeyWord_tests(${buildtool_linux})", + "tests:tryCatch_tests(${buildtool_linux})", + "tests:typeOf_tests(${buildtool_linux})", + "tests:variableDeclaration_tests(${buildtool_linux})", + "tests:void_tests(${buildtool_linux})", + "tests:while_tests(${buildtool_linux})", + ] +} diff --git a/ts2panda/scripts/generate_plugin.py b/ts2panda/scripts/generate_plugin.py deleted file mode 100755 index 306e9696d26223c0d8a8410728e56b1b30b586d7..0000000000000000000000000000000000000000 --- a/ts2panda/scripts/generate_plugin.py +++ /dev/null @@ -1,170 +0,0 @@ -#!/usr/bin/env python3 -#coding: utf-8 - -""" -Copyright (c) 2021 Huawei Device Co., Ltd. -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -Description: Generate interface to get java plugin's js code and binary -""" - -import os -import subprocess -import argparse - -JAVA_FILE_SUFFIX = "JsCode" -JS_BIN_EXT = ".abc" -ARRAY_MAX = 8192 # size of 8K - - -def parse_args(): - parser = argparse.ArgumentParser() - parser.add_argument("--node", - help="path to nodejs exetuable") - parser.add_argument("--frontend-tool-path", - help="path to frontend conversion tool") - parser.add_argument("--node-modules", - help='path to node-modules exetuable') - parser.add_argument("--plugin-path", - help="plugin js file path") - parser.add_argument("--plugin-name", - help="name of js file, ex: BatteryPlugin.js") - parser.add_argument("--generated-file", - help="name of generated file") - parser.add_argument("--package-name", - help="name of generated file's package") - - arguments = parser.parse_args() - return arguments - - -def split_array_by_n(array, max_len): - for i in range(0, len(array), max_len): - yield array[i: i + max_len] - - -def gen_bin_info(input_arguments): - file_name = input_arguments.plugin_name - file_path = input_arguments.plugin_path - js_file = os.path.join(file_path, file_name) - file_name_pre = os.path.splitext(file_name)[0] - - generate_js_bytecode = os.path.join( - os.path.dirname(__file__), "generate_js_bytecode.py") - - (out_dir, _) = os.path.split(input_arguments.generated_file) - dst_file = os.path.join(out_dir, f'{file_name_pre}{JS_BIN_EXT}') - - args = [ - '--src-js', - js_file, - '--dst-file', - dst_file, - '--node', - input_arguments.node, - '--frontend-tool-path', - input_arguments.frontend_tool_path, - '--node-modules', - input_arguments.node_modules, - ] - - proc = subprocess.Popen(['python3', generate_js_bytecode] + args) - return_code = proc.wait() - return return_code - - -def gen_java_method(input_arguments): - file_name = input_arguments.plugin_name - file_path = input_arguments.plugin_path - out_file = input_arguments.generated_file - - file_name_pre = os.path.splitext(file_name)[0] - js_src_file = os.path.join(file_path, file_name) - (out_dir, _) = os.path.split(input_arguments.generated_file) - js_bin_file = os.path.join(out_dir, file_name_pre + JS_BIN_EXT) - - with open(out_file, "w") as output: - output.write("/*%s * Generated from Java and JavaScript plugins by ts2abc.%s */%s%s" - % (os.linesep, os.linesep, os.linesep, os.linesep)) - - output.write("package %s;%s" - % (input_arguments.package_name, os.linesep)) - output.write("%s" % os.linesep) - output.write("public class %s%s {%s" - % (file_name_pre, JAVA_FILE_SUFFIX, os.linesep)) - - # write method: getJsCode - with open(js_src_file, "r") as input_src: - output.write(" public static String getJsCode() {%s" - % os.linesep) - output.write(" return%s" % os.linesep) - lines = input_src.readlines() - for line in lines[:-1]: - line = line.strip(os.linesep) - line = line.replace("\"", "\\\"") - output.write(" \"%s\\n\" +%s" % (line, os.linesep)) - - last_line = lines[-1].replace("\"", "\\\"").strip(os.linesep) - output.write(" \"%s\";%s" % (last_line, os.linesep)) - output.write(" }%s" % os.linesep) - - output.write("%s" % os.linesep) - - # write method: getJsBytecode - with open(js_bin_file, "rb") as input_bin: - # seperate bytecode list - buf = bytearray(os.path.getsize(js_bin_file)) - input_bin.readinto(buf) - hex_str = [hex(i) for i in buf] - byte_str = ["(byte)" + i for i in hex_str] - seperate_array = split_array_by_n(byte_str, ARRAY_MAX) - - # generate seperate methods for js bytecode with ARRAY_MAX - method_idx = 0 - method_len_list = [] - for array in seperate_array: - output.write(" private static byte[] getJsByteCode_%s() {%s" - % (method_idx, os.linesep)) - output.write(" return new byte[] {") - output.write(", ".join(array)) - output.write("};%s" % os.linesep) - output.write(" }%s" % os.linesep) - method_idx = method_idx + 1 - method_len_list.append(len(array)) - - # generate a method collect all seperated arrays - cur_pos = 0 - output.write(" public static byte[] getJsByteCode() {%s" - % os.linesep) - output.write(" byte[] allByteCode = new byte[%s];%s" - % (len(byte_str), os.linesep)) - for idx, method_len in enumerate(method_len_list): - output.write(" System.arraycopy(getJsByteCode_%s(), " - "0, allByteCode, %s, %s);%s" - % (idx, cur_pos, method_len, os.linesep)) - cur_pos = cur_pos + method_len - output.write(" return allByteCode;%s" % os.linesep) - output.write(" }%s" % os.linesep) - - output.write("}") - - -def operate_file(input_arguments): - retcode = gen_bin_info(input_arguments) - if retcode != 0: - return - - gen_java_method(input_arguments) - - -if __name__ == "__main__": - operate_file(parse_args()) diff --git a/ts2panda/scripts/run_tests.py b/ts2panda/scripts/run_tests.py new file mode 100755 index 0000000000000000000000000000000000000000..616f14f1e0b1ab932ecfe3b5258021087e6a5861 --- /dev/null +++ b/ts2panda/scripts/run_tests.py @@ -0,0 +1,163 @@ +#!/usr/bin/env python3 +# coding: utf-8 + +""" +Copyright (c) 2021 Huawei Device Co., Ltd. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +""" + +import os +import sys +import subprocess +import argparse +import time + +CUR_FILE_DIR = os.path.dirname(__file__) +TS2PANDA_DIR = os.path.abspath(os.path.join(CUR_FILE_DIR, "..")) +CODE_ROOT = os.path.abspath(os.path.join(TS2PANDA_DIR, "../../..")) +DEFAULT_TARGET_DIR = os.path.join( + CODE_ROOT, "out/ohos-arm-release/clang_x64/obj/ark/ts2abc/ts2panda") +DEFAULT_NODE_MODULE = os.path.join( + CODE_ROOT, "prebuilts/build-tools/common/ts2abc/node_modules") + + +def parse_args(): + parser = argparse.ArgumentParser() + + parser.add_argument('--src-dir', + default=TS2PANDA_DIR, + help='Source directory') + parser.add_argument('--dist-dir', + default=DEFAULT_TARGET_DIR, + help='Destination directory') + parser.add_argument("--node-modules", + default=DEFAULT_NODE_MODULE, + help='path to node-modules exetuable') + parser.add_argument('--platform', + default="linux", + help='platform, as: linux, mac, win') + parser.add_argument('--gn-build', + action='store_true', + help='Whether it is GN compilation') + parser.add_argument('--js-file', + metavar='FILE', + help='The name of the test use case file to execute') + + return parser.parse_args() + + +def run_command(cmd, execution_path=os.getcwd()): + print(" ".join(cmd)) + proc = subprocess.Popen(cmd, cwd=execution_path) + ret = proc.wait() + return ret + + +class Ts2abcTests(): + def __init__(self, args): + self.args = args + self.src_dir = TS2PANDA_DIR + self.dist_dir = DEFAULT_TARGET_DIR + self.node_modules = DEFAULT_NODE_MODULE + self.platform = "linux" + + def proce_parameters(self): + if self.args.src_dir: + self.src_dir = self.args.src_dir + + if self.args.dist_dir: + self.dist_dir = self.args.dist_dir + + if self.args.node_modules: + self.node_modules = self.args.node_modules + + if self.args.platform: + self.platform = self.args.platform + + def copy_node_modules(self): + src_dir = self.src_dir + dist_dir = self.dist_dir + run_command(['cp', '-f', os.path.join(src_dir, "package.json"), + os.path.join(dist_dir, "package.json")]) + run_command(['cp', '-f', os.path.join(src_dir, "package-lock.json"), + os.path.join(dist_dir, "package-lock.json")]) + + if self.node_modules: + run_command(['cp', '-rf', self.node_modules, dist_dir]) + else: + run_command(['npm', 'install'], dist_dir) + + def copy_tests(self): + if self.args.gn_build: + return + if os.path.exists(f'{self.dist_dir}/tests'): + run_command(['rm', '-rf', f'{self.dist_dir}/tests']) + run_command(['cp', '-rf', f'{self.src_dir}/tests', self.dist_dir]) + + def run_build(self): + plat_form = self.platform + tsc = "node_modules/typescript/bin/tsc" + if plat_form == "linux": + cmd = [tsc, '-b', 'src', 'tests'] + ret = run_command(cmd, self.dist_dir) + elif plat_form == "win": + cmd = [tsc, '-b', 'src/tsconfig.win.json', + 'tests/tsconfig.win.json'] + ret = run_command(cmd, self.dist_dir) + elif plat_form == 'mac': + cmd = [tsc, '-b', 'src/tsconfig.mac.json', + 'tests/tsconfig.mac.json'] + ret = run_command(cmd, self.dist_dir) + if ret : + raise RuntimeError("Run [" + " ".join(cmd) + "] failed !") + + def run_tests(self): + os.chdir(self.dist_dir) + start_time = time.time() + plat_form = self.platform + mocha = "node_modules/mocha/bin/mocha" + + if self.args.js_file: + tests_args = self.args.js_file + else: + tests_args = "**/*.test.js" + + if plat_form == "linux": + cmd = [mocha, f'build/tests/{tests_args}'] + ret = run_command(cmd, self.dist_dir) + elif plat_form == "win": + cmd = [mocha, f'build-win/tests/{tests_args}'] + ret = run_command(cmd, self.dist_dir) + elif plat_form == 'mac': + cmd = [mocha, f'build-mac/tests/{tests_args}'] + ret = run_command(cmd, self.dist_dir) + if ret: + raise RuntimeError("Run [" + " ".join(cmd) + "] failed !") + else: + print("Run [" + " ".join(cmd) + "] success!") + print("used: %.5f seconds" % (time.time() - start_time)) + + +def main(): + args = parse_args() + + test = Ts2abcTests(args) + test.copy_node_modules() + test.copy_tests() + test.run_build() + test.run_tests() + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/ts2panda/tests/BUILD.gn b/ts2panda/tests/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..0414b6f11227ed5dcedaff78a67c7f5c6c278548 --- /dev/null +++ b/ts2panda/tests/BUILD.gn @@ -0,0 +1,163 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//ark/ts2abc/ts2panda/ts2abc_config.gni") +import("//build/config/clang/clang.gni") +import("//build/ohos.gni") + +# expression tests +ts2abc_unittest("binary_tests") { + js_file = "expression/binary.test.js" +} + +ts2abc_unittest("call_tests") { + js_file = "expression/call.test.js" +} + +ts2abc_unittest("conditions_tests") { + js_file = "expression/conditions.test.js" +} + +ts2abc_unittest("cmpBinary_tests") { + js_file = "expression/cmpBinary.test.js" +} + +ts2abc_unittest("delete_tests") { + js_file = "expression/delete.test.js" +} + +ts2abc_unittest("elementAccess_tests") { + js_file = "expression/elementAccess.test.js" +} + +ts2abc_unittest("functionExpression_tests") { + js_file = "expression/functionExpression.test.js" +} + +ts2abc_unittest("literal_tests") { + js_file = "expression/literal.test.js" +} + +ts2abc_unittest("logicBinary_tests") { + js_file = "expression/logicBinary.test.js" +} + +ts2abc_unittest("new_tests") { + js_file = "expression/new.test.js" +} + +ts2abc_unittest("numericLiteral_tests") { + js_file = "expression/numericLiteral.test.js" +} + +ts2abc_unittest("operationEqual_tests") { + js_file = "expression/operationEqual.test.js" +} + +ts2abc_unittest("parenthesized_tests") { + js_file = "expression/parenthesized.test.js" +} + +ts2abc_unittest("arguments_tests") { + js_file = "expression/arguments.test.js" +} + +ts2abc_unittest("propertyAccess_tests") { + js_file = "expression/propertyAccess.test.js" +} + +ts2abc_unittest("postfixOperations_tests") { + js_file = "expression/postfixOperations.test.js" +} + +ts2abc_unittest("stringLiteral_tests") { + js_file = "expression/stringLiteral.test.js" +} + +ts2abc_unittest("template_tests") { + js_file = "expression/templateExpression.test.js" +} + +ts2abc_unittest("thisKeyWord_tests") { + js_file = "expression/thisKeyWord.test.js" +} + +ts2abc_unittest("typeOf_tests") { + js_file = "expression/typeOf.test.js" +} + +ts2abc_unittest("void_tests") { + js_file = "expression/void.test.js" +} + +ts2abc_unittest("prefixOperations_tests") { + js_file = "expression/prefixOperations.test.js" +} + +ts2abc_unittest("regular_tests") { + js_file = "expression/regular.test.js" +} + +# ststement tests +ts2abc_unittest("debugger_tests") { + js_file = "statements/debugger.test.js" +} + +ts2abc_unittest("functionDeclaration_tests") { + js_file = "statements/functionDeclaration.test.js" +} + +ts2abc_unittest("doWhile_tests") { + js_file = "statements/doWhile.test.js" +} + +ts2abc_unittest("for_tests") { + js_file = "statements/for.test.js" +} + +ts2abc_unittest("forin_tests") { + js_file = "statements/forIn.test.js" +} + +ts2abc_unittest("forOf_tests") { + js_file = "statements/forOf.test.js" +} + +ts2abc_unittest("return_tests") { + js_file = "statements/return.test.js" +} + +ts2abc_unittest("switch_tests") { + js_file = "statements/switch.test.js" +} + +ts2abc_unittest("tryCatch_tests") { + js_file = "statements/tryCatch.test.js" +} + +ts2abc_unittest("variableDeclaration_tests") { + js_file = "statements/variableDeclaration.test.js" +} + +ts2abc_unittest("while_tests") { + js_file = "statements/while.test.js" +} + +# other tests +ts2abc_unittest("strictmode_tests") { + js_file = "strictmode/strictmode.test.js" +} + +ts2abc_unittest("hello_tests") { + js_file = "example_hello/hello.test.js" +} diff --git a/ts2panda/tests/builtIns.test.ts b/ts2panda/tests/builtIns.test.ts index ced5796134ec03244538dcf941ff095aac0de0b3..2484fba12f72d056f9d7f8f8cfd60b2428e128f4 100644 --- a/ts2panda/tests/builtIns.test.ts +++ b/ts2panda/tests/builtIns.test.ts @@ -18,21 +18,21 @@ import { } from 'chai'; import 'mocha'; import { + EcmaReturnundefined, LdaDyn, - ReturnUndefined, VReg } from "../src/irnodes"; import { checkInstructions, compileMainSnippet } from "./utils/base"; -describe("BuiltInsTest", function() { - it("Global Value Properties", function() { +describe("BuiltInsTest", function () { + it("Global Value Properties", function () { let insns = compileMainSnippet(`NaN; Infinity; globalThis;`); let expected = [ new LdaDyn(new VReg()), new LdaDyn(new VReg()), new LdaDyn(new VReg()), - new ReturnUndefined() + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; }); diff --git a/ts2panda/tests/expression/arguments.test.ts b/ts2panda/tests/expression/arguments.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..660e1b72b0f7c13b0d94e13c6d977f9c9d849239 --- /dev/null +++ b/ts2panda/tests/expression/arguments.test.ts @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + expect +} from 'chai'; +import 'mocha'; +import { + EcmaGetunmappedargs, + EcmaLdobjbyindex, + EcmaReturnundefined, + Imm, + LdaDyn, + ResultType, + StaDyn, + VReg +} from "../../src/irnodes"; +import { checkInstructions, SnippetCompiler } from "../utils/base"; + +describe("arguments Keyword", function () { + it('arguments: Array-like object accessible inside functions', function () { + let snippetCompiler = new SnippetCompiler(); + snippetCompiler.compile(`function foo(a,b) {arguments[0];}`); + let argumentsReg = new VReg(); + let temp1 = new VReg(); + let expected = [ + new EcmaGetunmappedargs(), + new StaDyn(argumentsReg), + new LdaDyn(argumentsReg), + new StaDyn(temp1), + new EcmaLdobjbyindex(temp1, new Imm(ResultType.Int, 0)), + new EcmaReturnundefined() + ]; + let functionPg = snippetCompiler.getPandaGenByName("foo"); + let insns = functionPg!.getInsns(); + + expect(checkInstructions(insns, expected)).to.be.true; + }); + + it('arguments as parameter shadows keyword', function () { + let snippetCompiler = new SnippetCompiler(); + snippetCompiler.compile(`function foo(arguments) {arguments[0];}`); + let parameterArguments = new VReg(); + let temp1 = new VReg(); + let expected = [ + new EcmaGetunmappedargs(), + new StaDyn(new VReg()), + new LdaDyn(parameterArguments), + new StaDyn(temp1), + new EcmaLdobjbyindex(temp1, new Imm(ResultType.Int, 0)), + new EcmaReturnundefined() + ]; + let functionPg = snippetCompiler.getPandaGenByName("foo"); + let insns = functionPg!.getInsns(); + + expect(checkInstructions(insns, expected)).to.be.true; + }); +}); diff --git a/ts2panda/tests/binary.test.ts b/ts2panda/tests/expression/binary.test.ts similarity index 31% rename from ts2panda/tests/binary.test.ts rename to ts2panda/tests/expression/binary.test.ts index 3f996596b15ade75a32263aefc44416d74d024f6..f80ba94f38de91a66973ce481b84a9d183e7914a 100644 --- a/ts2panda/tests/binary.test.ts +++ b/ts2panda/tests/expression/binary.test.ts @@ -18,79 +18,68 @@ import { } from 'chai'; import 'mocha'; import { - Add2Dyn, - And2Dyn, - Ashr2Dyn, - CreateEmptyObject, - Div2Dyn, - EqDyn, - ExpDyn, - GreaterDyn, - GreaterEqDyn, + EcmaAdd2dyn, + EcmaAnd2dyn, + EcmaAshr2dyn, + EcmaCreateemptyobject, + EcmaDiv2dyn, + EcmaExpdyn, + EcmaMod2dyn, + EcmaMul2dyn, + EcmaOr2dyn, + EcmaReturnundefined, + EcmaShl2dyn, + EcmaShr2dyn, + EcmaStglobalvar, + EcmaStlettoglobalrecord, + EcmaStobjbyname, + EcmaStrictnoteqdyn, + EcmaSub2dyn, + EcmaTryldglobalbyname, + EcmaTrystglobalbyname, + EcmaXor2dyn, Imm, - IncDyn, - InstanceOfDyn, - IsInDyn, Jeqz, Jmp, Label, LdaDyn, LdaiDyn, LdaStr, - LessDyn, - LessEqDyn, - Mod2Dyn, MovDyn, - Mul2Dyn, - NotEqDyn, - Or2Dyn, ResultType, - ReturnUndefined, - Shl2Dyn, - Shr2Dyn, StaDyn, - StGlobalVar, - StObjByName, - StrictEqDyn, - StrictNotEqDyn, - Sub2Dyn, - Toboolean, - Tonumber, - TryLdGlobalByName, - TryStGlobalByName, - VReg, - Xor2Dyn -} from "../src/irnodes"; -import { checkInstructions, compileMainSnippet } from "./utils/base"; - -describe("BinaryOperationsTest", function() { - it("2 + 3", function() { + VReg +} from "../../src/irnodes"; +import { checkInstructions, compileMainSnippet } from "../utils/base"; + +describe("BinaryOperationsTest", function () { + it("2 + 3", function () { let insns = compileMainSnippet("2 + 3"); let lhs = new VReg(); let expected = [ new LdaiDyn(new Imm(ResultType.Int, 2)), new StaDyn(lhs), new LdaiDyn(new Imm(ResultType.Int, 3)), - new Add2Dyn(lhs), - new ReturnUndefined() + new EcmaAdd2dyn(lhs), + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; }); - it("5 - 1", function() { + it("5 - 1", function () { let insns = compileMainSnippet("5 - 1"); let lhs = new VReg(); let expected = [ new LdaiDyn(new Imm(ResultType.Int, 5)), new StaDyn(lhs), new LdaiDyn(new Imm(ResultType.Int, 1)), - new Sub2Dyn(lhs), - new ReturnUndefined() + new EcmaSub2dyn(lhs), + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; }); - it("null ?? 1", function() { + it("null ?? 1", function () { let insns = compileMainSnippet("null ?? 1"); let leftNullishLabel = new Label(); @@ -98,17 +87,17 @@ describe("BinaryOperationsTest", function() { let expected = [ new LdaDyn(new VReg()), new StaDyn(new VReg()), - new StrictNotEqDyn(new VReg()), + new EcmaStrictnoteqdyn(new VReg()), new Jeqz(leftNullishLabel), new LdaDyn(new VReg()), - new StrictNotEqDyn(new VReg()), + new EcmaStrictnoteqdyn(new VReg()), new Jeqz(leftNullishLabel), new LdaDyn(new VReg()), new Jmp(endLabel), leftNullishLabel, new LdaiDyn(new Imm(ResultType.Int, 1)), endLabel, - new ReturnUndefined() + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; @@ -118,7 +107,7 @@ describe("BinaryOperationsTest", function() { expect(jumps.length).to.equal(3); }); - it("undefined ?? 1", function() { + it("undefined ?? 1", function () { let insns = compileMainSnippet("undefined ?? 1"); let leftNullishLabel = new Label(); @@ -126,10 +115,10 @@ describe("BinaryOperationsTest", function() { let expected = [ new LdaDyn(new VReg()), new StaDyn(new VReg()), - new StrictNotEqDyn(new VReg()), + new EcmaStrictnoteqdyn(new VReg()), new Jeqz(leftNullishLabel), new LdaDyn(new VReg()), - new StrictNotEqDyn(new VReg()), + new EcmaStrictnoteqdyn(new VReg()), new Jeqz(leftNullishLabel), new LdaDyn(new VReg()), @@ -138,7 +127,7 @@ describe("BinaryOperationsTest", function() { leftNullishLabel, new LdaiDyn(new Imm(ResultType.Int, 1)), endLabel, - new ReturnUndefined() + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; @@ -147,7 +136,7 @@ describe("BinaryOperationsTest", function() { expect(jumps.length).to.equal(3); }); - it("2 ?? 1", function() { + it("2 ?? 1", function () { let insns = compileMainSnippet("2 ?? 1"); let lhs = new VReg(); @@ -156,10 +145,10 @@ describe("BinaryOperationsTest", function() { let expected = [ new LdaiDyn(new Imm(ResultType.Int, 2)), new StaDyn(new VReg()), - new StrictNotEqDyn(new VReg()), + new EcmaStrictnoteqdyn(new VReg()), new Jeqz(leftNullishLabel), new LdaDyn(new VReg()), - new StrictNotEqDyn(new VReg()), + new EcmaStrictnoteqdyn(new VReg()), new Jeqz(leftNullishLabel), new LdaDyn(lhs), @@ -168,7 +157,7 @@ describe("BinaryOperationsTest", function() { leftNullishLabel, new LdaiDyn(new Imm(ResultType.Int, 1)), endLabel, - new ReturnUndefined() + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; @@ -177,150 +166,149 @@ describe("BinaryOperationsTest", function() { expect(jumps.length).to.equal(3); }); - it("3 * 4", function() { + it("3 * 4", function () { let insns = compileMainSnippet("3 * 4"); let lhs = new VReg(); let expected = [ new LdaiDyn(new Imm(ResultType.Int, 3)), new StaDyn(lhs), new LdaiDyn(new Imm(ResultType.Int, 4)), - new Mul2Dyn(lhs), - new ReturnUndefined() + new EcmaMul2dyn(lhs), + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; }); - it("2 ** 3", function() { + it("2 ** 3", function () { let insns = compileMainSnippet("2 ** 3"); let lhs = new VReg(); let expected = [ new LdaiDyn(new Imm(ResultType.Int, 2)), new StaDyn(lhs), new LdaiDyn(new Imm(ResultType.Int, 3)), - new ExpDyn(lhs), - new ReturnUndefined(), + new EcmaExpdyn(lhs), + new EcmaReturnundefined(), ]; expect(checkInstructions(insns, expected)).to.be.true; }); - it("7 / 1", function() { + it("7 / 1", function () { let insns = compileMainSnippet("7 / 1"); let lhs = new VReg(); let expected = [ new LdaiDyn(new Imm(ResultType.Int, 7)), new StaDyn(lhs), new LdaiDyn(new Imm(ResultType.Int, 1)), - new Div2Dyn(lhs), - new ReturnUndefined() + new EcmaDiv2dyn(lhs), + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; }); - it("8 % 2", function() { + it("8 % 2", function () { let insns = compileMainSnippet("8 % 2"); let lhs = new VReg(); let expected = [ new LdaiDyn(new Imm(ResultType.Int, 8)), new StaDyn(lhs), new LdaiDyn(new Imm(ResultType.Int, 2)), - new Mod2Dyn(lhs), - new ReturnUndefined() + new EcmaMod2dyn(lhs), + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; }); - it("2 << 3", function() { + it("2 << 3", function () { let insns = compileMainSnippet("2 << 3"); let lhs = new VReg(); let expected = [ new LdaiDyn(new Imm(ResultType.Int, 2)), new StaDyn(lhs), new LdaiDyn(new Imm(ResultType.Int, 3)), - new Shl2Dyn(lhs), - new ReturnUndefined() + new EcmaShl2dyn(lhs), + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; }); - it("4 >> 1", function() { + it("4 >> 1", function () { let insns = compileMainSnippet("4 >> 1"); let lhs = new VReg(); let expected = [ new LdaiDyn(new Imm(ResultType.Int, 4)), new StaDyn(lhs), new LdaiDyn(new Imm(ResultType.Int, 1)), - new Shr2Dyn(lhs), - new ReturnUndefined() + new EcmaShr2dyn(lhs), + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; }); - it("12 >>> 2", function() { + it("12 >>> 2", function () { let insns = compileMainSnippet("12 >>> 2"); let lhs = new VReg(); let expected = [ new LdaiDyn(new Imm(ResultType.Int, 12)), new StaDyn(lhs), new LdaiDyn(new Imm(ResultType.Int, 2)), - new Ashr2Dyn(lhs), - new ReturnUndefined() + new EcmaAshr2dyn(lhs), + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; }); - it("3 & 4", function() { + it("3 & 4", function () { let insns = compileMainSnippet("3 & 4"); let lhs = new VReg(); let expected = [ new LdaiDyn(new Imm(ResultType.Int, 3)), new StaDyn(lhs), new LdaiDyn(new Imm(ResultType.Int, 4)), - new And2Dyn(lhs), - new ReturnUndefined() + new EcmaAnd2dyn(lhs), + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; }); - it("2 | 5", function() { + it("2 | 5", function () { let insns = compileMainSnippet("2 | 5"); let lhs = new VReg(); let expected = [ new LdaiDyn(new Imm(ResultType.Int, 2)), new StaDyn(lhs), new LdaiDyn(new Imm(ResultType.Int, 5)), - new Or2Dyn(lhs), - new ReturnUndefined() + new EcmaOr2dyn(lhs), + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; }); - it("7 ^ 3", function() { + it("7 ^ 3", function () { let insns = compileMainSnippet("7 ^ 3"); let lhs = new VReg(); let expected = [ new LdaiDyn(new Imm(ResultType.Int, 7)), new StaDyn(lhs), new LdaiDyn(new Imm(ResultType.Int, 3)), - new Xor2Dyn(lhs), - new ReturnUndefined() + new EcmaXor2dyn(lhs), + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; }); - it("let i; i = 2", function() { + it("let i; i = 2", function () { let insns = compileMainSnippet("let i; i = 2;"); - let i = new VReg(); let expected = [ new LdaDyn(new VReg()), - new StaDyn(i), + new EcmaStlettoglobalrecord('i'), new LdaiDyn(new Imm(ResultType.Int, 2)), - new StaDyn(i), - new ReturnUndefined() + new EcmaTrystglobalbyname('i'), + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; }); - it("a = 1 under strict mode", function() { + it("a = 1 under strict mode", function () { let insns = compileMainSnippet(` "use strict"; a = 1; @@ -328,552 +316,44 @@ describe("BinaryOperationsTest", function() { let expected = [ new LdaStr("use strict"), new LdaiDyn(new Imm(ResultType.Int, 1)), - new TryStGlobalByName("a"), - new ReturnUndefined() + new EcmaTrystglobalbyname("a"), + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; }) - it("Assignment to ParenthesizedExpression case1", function() { + it("Assignment to ParenthesizedExpression case1", function () { let insns = compileMainSnippet("((x)) = 1;"); let expected = [ new LdaiDyn(new Imm(ResultType.Int, 1)), - new StGlobalVar("x"), - new ReturnUndefined() + new EcmaStglobalvar("x"), + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; }); - it("Assignment to ParenthesizedExpression case2", function() { + it("Assignment to ParenthesizedExpression case2", function () { let insns = compileMainSnippet(`let a = {}; ((a.b)) = 1;`); let objReg = new VReg(); let tempObj = new VReg(); let expected = [ - new CreateEmptyObject(), + new EcmaCreateemptyobject(), new StaDyn(new VReg()), - new StaDyn(objReg), // insns for `((a.b)) = 1` - new LdaDyn(objReg), + new EcmaStlettoglobalrecord('a'), + new EcmaTryldglobalbyname('a'), new StaDyn(tempObj), new MovDyn(objReg, tempObj), new LdaiDyn(new Imm(ResultType.Int, 1)), - new StObjByName("b", objReg), - new ReturnUndefined() - ] - expect(checkInstructions(insns, expected)).to.be.true; - }); -}); - -describe("OperationEqualTest", function() { - it("plusEqual", function() { - let insns = compileMainSnippet("let a = 2;\n" + - "a += 3;"); - let a = new VReg(); - let lhs = new VReg(); - - let expected = [ - new LdaiDyn(new Imm(ResultType.Int, 2)), - new StaDyn(a), - new LdaDyn(a), - new StaDyn(lhs), - new LdaiDyn(new Imm(ResultType.Int, 3)), - new Add2Dyn(lhs), - new StaDyn(a), - new ReturnUndefined() - ]; - expect(checkInstructions(insns, expected)).to.be.true; - }); - - it("minusEqual", function() { - let insns = compileMainSnippet("let a = 5;\n" + - "a -= 7;"); - let a = new VReg(); - let lhs = new VReg(); - - let expected = [ - new LdaiDyn(new Imm(ResultType.Int, 5)), - new StaDyn(a), - new LdaDyn(a), - new StaDyn(lhs), - new LdaiDyn(new Imm(ResultType.Int, 7)), - new Sub2Dyn(lhs), - new StaDyn(a), - new ReturnUndefined() - ]; - expect(checkInstructions(insns, expected)).to.be.true; - }); - - it("asteriskEqual", function() { - let insns = compileMainSnippet("let a = 2;\n" + - "a *= 4;"); - let a = new VReg(); - let lhs = new VReg(); - - let expected = [ - new LdaiDyn(new Imm(ResultType.Int, 2)), - new StaDyn(a), - new LdaDyn(a), - new StaDyn(lhs), - new LdaiDyn(new Imm(ResultType.Int, 4)), - new Mul2Dyn(lhs), - new StaDyn(a), - new ReturnUndefined() - ]; - expect(checkInstructions(insns, expected)).to.be.true; - }); - - it("AsteriskAsteriskEqualsToken", function() { - let insns = compileMainSnippet("let a = 2;\n" + - "a **= 3;"); - let a = new VReg(); - let lhs = new VReg(); - - let expected = [ - new LdaiDyn(new Imm(ResultType.Int, 2)), - new StaDyn(a), - new LdaDyn(a), - new StaDyn(lhs), - new LdaiDyn(new Imm(ResultType.Int, 3)), - new ExpDyn(lhs), - new StaDyn(a), - new ReturnUndefined() - ] - expect(checkInstructions(insns, expected)).to.be.true; - }); - - it("slashEqual", function() { - let insns = compileMainSnippet("let a = 5;\n" + - "a /= 3;"); - let a = new VReg(); - let lhs = new VReg(); - - let expected = [ - new LdaiDyn(new Imm(ResultType.Int, 5)), - new StaDyn(a), - new LdaDyn(a), - new StaDyn(lhs), - new LdaiDyn(new Imm(ResultType.Int, 3)), - new Div2Dyn(lhs), - new StaDyn(a), - new ReturnUndefined() - ]; - expect(checkInstructions(insns, expected)).to.be.true; - }); - - it("percentEqual", function() { - let insns = compileMainSnippet("let a = 15;\n" + - "a %= 7;"); - let a = new VReg(); - let lhs = new VReg(); - - let expected = [ - new LdaiDyn(new Imm(ResultType.Int, 15)), - new StaDyn(a), - new LdaDyn(a), - new StaDyn(lhs), - new LdaiDyn(new Imm(ResultType.Int, 7)), - new Mod2Dyn(lhs), - new StaDyn(a), - new ReturnUndefined() - ]; - expect(checkInstructions(insns, expected)).to.be.true; - }); - - it("lessThanLessThanEqual", function() { - let insns = compileMainSnippet("let a = 8;\n" + - "a <<= 3;"); - let a = new VReg(); - let lhs = new VReg(); - - let expected = [ - new LdaiDyn(new Imm(ResultType.Int, 8)), - new StaDyn(a), - new LdaDyn(a), - new StaDyn(lhs), - new LdaiDyn(new Imm(ResultType.Int, 3)), - new Shl2Dyn(lhs), - new StaDyn(a), - new ReturnUndefined() - ]; - expect(checkInstructions(insns, expected)).to.be.true; - }); - - it("greaterThanGreaterThanEqual", function() { - let insns = compileMainSnippet("let a = 4;\n" + - "a >>= 1;"); - let a = new VReg(); - let lhs = new VReg(); - - let expected = [ - new LdaiDyn(new Imm(ResultType.Int, 4)), - new StaDyn(a), - new LdaDyn(a), - new StaDyn(lhs), - new LdaiDyn(new Imm(ResultType.Int, 1)), - new Shr2Dyn(lhs), - new StaDyn(a), - new ReturnUndefined() - ]; - expect(checkInstructions(insns, expected)).to.be.true; - }); - - it("greaterThanGreaterThanGreaterThanEqual", function() { - let insns = compileMainSnippet("let a = 8;\n" + - "a >>>= 2;"); - let a = new VReg(); - let lhs = new VReg(); - - let expected = [ - new LdaiDyn(new Imm(ResultType.Int, 8)), - new StaDyn(a), - new LdaDyn(a), - new StaDyn(lhs), - new LdaiDyn(new Imm(ResultType.Int, 2)), - new Ashr2Dyn(lhs), - new StaDyn(a), - new ReturnUndefined() - ]; - expect(checkInstructions(insns, expected)).to.be.true; - }); -}); - -describe("LogicBinaryOperators", function() { - it("ampersandAmpersand", function() { - let insns = compileMainSnippet("8 && false;"); - let lhs = new VReg(); - let preLabel = new Label(); - let postLabel = new Label(); - - let expected = [ - new LdaiDyn(new Imm(ResultType.Int, 8)), - new StaDyn(lhs), - new Toboolean(), - new EqDyn(new VReg()), - new Jeqz(preLabel), - new LdaDyn(new VReg()), - new Jmp(postLabel), - preLabel, - new LdaDyn(lhs), - postLabel, - new ReturnUndefined() - ] - - expect(checkInstructions(insns, expected)).to.be.true; - }); - - it("barBar", function() { - let insns = compileMainSnippet("8 || false;"); - let lhs = new VReg(); - let rhs = new VReg(); - let preLabel = new Label(); - let postLabel = new Label(); - let expected = [ - new LdaiDyn(new Imm(ResultType.Int, 8)), - new StaDyn(lhs), - new Toboolean(), - new EqDyn(rhs), - new Jeqz(preLabel), - new LdaDyn(new VReg()), - new Jmp(postLabel), - preLabel, - new LdaDyn(lhs), - postLabel, - new ReturnUndefined() + new EcmaStobjbyname("b", objReg), + new EcmaReturnundefined() ] - - expect(checkInstructions(insns, expected)).to.be.true; - }); -}); - -describe("CmpBinaryOperators", function() { - it("LessThan", function() { - let insns = compileMainSnippet("2 < 3;"); - let lhs = new VReg(); - let falseLabel = new Label(); - let endLabel = new Label(); - - let expected = [ - new LdaiDyn(new Imm(ResultType.Int, 2)), - new StaDyn(lhs), - new LdaiDyn(new Imm(ResultType.Int, 3)), - new LessDyn(lhs), - new Jeqz(falseLabel), - new LdaDyn(new VReg()), - new Jmp(endLabel), - falseLabel, - new LdaDyn(new VReg()), - endLabel, - new ReturnUndefined() - ]; - expect(checkInstructions(insns, expected)).to.be.true; - }); - - it("GreaterThan", function() { - let insns = compileMainSnippet("3 > 1;"); - let lhs = new VReg(); - let falseLabel = new Label(); - let endLabel = new Label(); - - let expected = [ - new LdaiDyn(new Imm(ResultType.Int, 3)), - new StaDyn(lhs), - new LdaiDyn(new Imm(ResultType.Int, 1)), - new GreaterDyn(lhs), - new Jeqz(falseLabel), - new LdaDyn(new VReg()), - new Jmp(endLabel), - falseLabel, - new LdaDyn(new VReg()), - endLabel, - new ReturnUndefined() - ]; - expect(checkInstructions(insns, expected)).to.be.true; - }); - - it("LessThanEquals", function() { - let insns = compileMainSnippet("3 <= 4;"); - let lhs = new VReg(); - let falseLabel = new Label(); - let endLabel = new Label(); - - let expected = [ - new LdaiDyn(new Imm(ResultType.Int, 3)), - new StaDyn(lhs), - new LdaiDyn(new Imm(ResultType.Int, 4)), - new LessEqDyn(lhs), - new Jeqz(falseLabel), - new LdaDyn(new VReg()), - new Jmp(endLabel), - falseLabel, - new LdaDyn(new VReg()), - endLabel, - new ReturnUndefined() - ]; - expect(checkInstructions(insns, expected)).to.be.true; - }); - - it("GreaterThanEquals", function() { - let insns = compileMainSnippet("3 >= 2;"); - let lhs = new VReg(); - let falseLabel = new Label(); - let endLabel = new Label(); - - let expected = [ - new LdaiDyn(new Imm(ResultType.Int, 3)), - new StaDyn(lhs), - new LdaiDyn(new Imm(ResultType.Int, 2)), - new GreaterEqDyn(lhs), - new Jeqz(falseLabel), - new LdaDyn(new VReg()), - new Jmp(endLabel), - falseLabel, - new LdaDyn(new VReg()), - endLabel, - new ReturnUndefined() - ]; - expect(checkInstructions(insns, expected)).to.be.true; - }); - - it("EqualsEquals", function() { - let insns = compileMainSnippet("3 == 3;"); - let lhs = new VReg(); - let falseLabel = new Label(); - let endLabel = new Label(); - - let expected = [ - new LdaiDyn(new Imm(ResultType.Int, 3)), - new StaDyn(lhs), - new LdaiDyn(new Imm(ResultType.Int, 3)), - new EqDyn(lhs), - new Jeqz(falseLabel), - new LdaDyn(new VReg()), - new Jmp(endLabel), - falseLabel, - new LdaDyn(new VReg()), - endLabel, - new ReturnUndefined() - ]; - expect(checkInstructions(insns, expected)).to.be.true; - }); - - it("ExclamationEquals", function() { - let insns = compileMainSnippet("3 != 2;"); - let lhs = new VReg(); - let falseLabel = new Label(); - let endLabel = new Label(); - - let expected = [ - new LdaiDyn(new Imm(ResultType.Int, 3)), - new StaDyn(lhs), - new LdaiDyn(new Imm(ResultType.Int, 2)), - new NotEqDyn(lhs), - new Jeqz(falseLabel), - new LdaDyn(new VReg()), - new Jmp(endLabel), - falseLabel, - new LdaDyn(new VReg()), - endLabel, - new ReturnUndefined() - ]; - expect(checkInstructions(insns, expected)).to.be.true; - }); - - it("EqualsEqualsEquals", function() { - let insns = compileMainSnippet("3 === 3;"); - let lhs = new VReg(); - let falseLabel = new Label(); - let endLabel = new Label(); - - let expected = [ - new LdaiDyn(new Imm(ResultType.Int, 3)), - new StaDyn(lhs), - new LdaiDyn(new Imm(ResultType.Int, 3)), - new StrictEqDyn(lhs), - new Jeqz(falseLabel), - new LdaDyn(new VReg()), - new Jmp(endLabel), - falseLabel, - new LdaDyn(new VReg()), - endLabel, - new ReturnUndefined() - ]; - expect(checkInstructions(insns, expected)).to.be.true; - }); - - it("ExclamationEqualsEquals", function() { - let insns = compileMainSnippet("3 !== 3;"); - let lhs = new VReg(); - let falseLabel = new Label(); - let endLabel = new Label(); - - let expected = [ - new LdaiDyn(new Imm(ResultType.Int, 3)), - new StaDyn(lhs), - new LdaiDyn(new Imm(ResultType.Int, 3)), - new StrictNotEqDyn(lhs), - new Jeqz(falseLabel), - new LdaDyn(new VReg()), - new Jmp(endLabel), - falseLabel, - new LdaDyn(new VReg()), - endLabel, - new ReturnUndefined() - ]; - expect(checkInstructions(insns, expected)).to.be.true; - }); - - it("ampersandEqual", function() { - let insns = compileMainSnippet("let a = 5;\n" + - "a &= 3;"); - let a = new VReg(); - let lhs = new VReg(); - - let expected = [ - new LdaiDyn(new Imm(ResultType.Int, 5)), - new StaDyn(a), - new LdaDyn(a), - new StaDyn(lhs), - new LdaiDyn(new Imm(ResultType.Int, 3)), - new And2Dyn(lhs), - new StaDyn(a), - new ReturnUndefined() - ]; - expect(checkInstructions(insns, expected)).to.be.true; - }); - - it("barEqual", function() { - let insns = compileMainSnippet("let a = 5;\n" + - "a |= 3;"); - let a = new VReg(); - let lhs = new VReg(); - - let expected = [ - new LdaiDyn(new Imm(ResultType.Int, 5)), - new StaDyn(a), - new LdaDyn(a), - new StaDyn(lhs), - new LdaiDyn(new Imm(ResultType.Int, 3)), - new Or2Dyn(lhs), - new StaDyn(a), - new ReturnUndefined() - ]; - expect(checkInstructions(insns, expected)).to.be.true; - }); - - it("caretEqual", function() { - let insns = compileMainSnippet("let a = 5;\n" + - "a ^= 3;"); - let a = new VReg(); - let lhs = new VReg(); - - let expected = [ - new LdaiDyn(new Imm(ResultType.Int, 5)), - new StaDyn(a), - new LdaDyn(a), - new StaDyn(lhs), - new LdaiDyn(new Imm(ResultType.Int, 3)), - new Xor2Dyn(lhs), - new StaDyn(a), - new ReturnUndefined() - ]; - expect(checkInstructions(insns, expected)).to.be.true; - }); - - it("CommaToken", function() { - let insns = compileMainSnippet(`let x = 1; - x = (x++, x);`); - let variable = new VReg(); - let rhs = new VReg(); - let lhs = new VReg(); - - let expected = [ - new LdaiDyn(new Imm(ResultType.Int, 1)), - new StaDyn(variable), - new LdaDyn(variable), - new StaDyn(lhs), - new IncDyn(lhs), - new StaDyn(variable), - new Tonumber(variable), - new StaDyn(rhs), - new LdaDyn(variable), - new StaDyn(variable), - new ReturnUndefined() - ]; - expect(checkInstructions(insns, expected)).to.be.true; - }); - - it("InKeyword", function() { - let insns = compileMainSnippet(`'o' in C;`); - let rhs = new VReg(); - - let expected = [ - new LdaStr('o'), - new StaDyn(rhs), - new TryLdGlobalByName("C"), - new IsInDyn(rhs), - new ReturnUndefined() - ]; expect(checkInstructions(insns, expected)).to.be.true; }); - - it("InstanceOfKeyword", function() { - let insns = compileMainSnippet(`o instanceof C;`); - let rhs = new VReg(); - - let expected = [ - new TryLdGlobalByName("o"), - new StaDyn(rhs), - new TryLdGlobalByName("C"), - new InstanceOfDyn(rhs), - new ReturnUndefined() - ]; - expect(checkInstructions(insns, expected)).to.be.true; - }); - }); diff --git a/ts2panda/tests/expression/call.test.ts b/ts2panda/tests/expression/call.test.ts index 95a2fbb7d55e7e89f05dc24ca15ec981bb1b390e..c19a8a45ac9abc0ae11891857304c14977294318 100755 --- a/ts2panda/tests/expression/call.test.ts +++ b/ts2panda/tests/expression/call.test.ts @@ -18,65 +18,65 @@ import { } from 'chai'; import 'mocha'; import { - Call0Dyn, - Call1Dyn, - CalliThisRangeDyn, - CallSpread, - CreateArrayWithBuffer, - CreateEmptyArray, + EcmaCallarg0dyn, + EcmaCallarg1dyn, + EcmaCallithisrangedyn, + EcmaCallspreaddyn, + EcmaCreatearraywithbuffer, + EcmaCreateemptyarray, + EcmaLdobjbyname, + EcmaLdobjbyvalue, + EcmaReturnundefined, + EcmaStarrayspread, + EcmaStconsttoglobalrecord, + EcmaStlettoglobalrecord, + EcmaTryldglobalbyname, Imm, LdaDyn, LdaiDyn, - LdObjByName, - LdObjByValue, ResultType, - ReturnUndefined, StaDyn, - StArraySpread, - TryLdGlobalByName, VReg } from "../../src/irnodes"; import { checkInstructions, compileMainSnippet } from "../utils/base"; -describe("CallTest", function() { - it("no arg call of a global standalone function", function() { +describe("CallTest", function () { + it("no arg call of a global standalone function", function () { let insns = compileMainSnippet(` foo(); `); let arg0 = new VReg(); let expected = [ - new TryLdGlobalByName("foo"), + new EcmaTryldglobalbyname("foo"), new StaDyn(arg0), - new Call0Dyn(arg0), + new EcmaCallarg0dyn(arg0), - new ReturnUndefined() + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; }); - it("one arg call of a global standalone function", function() { + it("one arg call of a global standalone function", function () { let insns = compileMainSnippet(` let i = 5; foo(i); `); - let i = new VReg(); let arg0 = new VReg(); let arg2 = new VReg(); let expected = [ new LdaiDyn(new Imm(ResultType.Int, 5)), - new StaDyn(i), - new TryLdGlobalByName("foo"), + new EcmaStlettoglobalrecord('i'), + new EcmaTryldglobalbyname("foo"), new StaDyn(arg0), - new LdaDyn(i), + new EcmaTryldglobalbyname('i'), new StaDyn(arg2), - new Call1Dyn(arg0, arg2), - - new ReturnUndefined() + new EcmaCallarg1dyn(arg0, arg2), + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; }); - it("call method", function() { + it("call method", function () { let insns = compileMainSnippet(` Foo.method(); `); @@ -84,18 +84,18 @@ describe("CallTest", function() { let arg0 = new VReg(); let arg1 = new VReg(); let expected = [ - new TryLdGlobalByName("Foo"), + new EcmaTryldglobalbyname("Foo"), new StaDyn(arg0), - new LdObjByName("method", arg0), + new EcmaLdobjbyname("method", arg0), new StaDyn(arg1), - new CalliThisRangeDyn(new Imm(ResultType.Int, 1), [arg1, obj]), + new EcmaCallithisrangedyn(new Imm(ResultType.Int, 1), [arg1, obj]), - new ReturnUndefined() + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; }); - it("spread element call of a global standalone function", function() { + it("spread element call of a global standalone function", function () { let insns = compileMainSnippet(` const args = [1, 2]; myFunction(...args); @@ -104,34 +104,32 @@ describe("CallTest", function() { let globalEnv = new VReg(); let lengthReg = new VReg(); let arrayInstance = new VReg(); - let objReg = new VReg(); let expected = [ - new CreateArrayWithBuffer(new Imm(ResultType.Int, 0)), + new EcmaCreatearraywithbuffer(new Imm(ResultType.Int, 0)), new StaDyn(arrayInstance), new LdaDyn(arrayInstance), - new StaDyn(objReg), + new EcmaStconsttoglobalrecord('args'), - new TryLdGlobalByName("myFunction"), + new EcmaTryldglobalbyname("myFunction"), new StaDyn(arg0), - new CreateEmptyArray(), + new EcmaCreateemptyarray(), new StaDyn(arrayInstance), new LdaiDyn(new Imm(ResultType.Int, 0)), new StaDyn(lengthReg), - new LdaDyn(objReg), - new StArraySpread(arrayInstance, lengthReg), + new EcmaTryldglobalbyname('args'), + new EcmaStarrayspread(arrayInstance, lengthReg), new StaDyn(lengthReg), new LdaDyn(arrayInstance), - new CallSpread(arg0, globalEnv, arrayInstance), - - new ReturnUndefined() + new EcmaCallspreaddyn(arg0, globalEnv, arrayInstance), + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; }); - it("call by element access", function() { + it("call by element access", function () { let insns = compileMainSnippet(` Foo[method](); `); @@ -140,15 +138,15 @@ describe("CallTest", function() { let arg0 = new VReg(); let arg1 = new VReg(); let expected = [ - new TryLdGlobalByName("Foo"), + new EcmaTryldglobalbyname("Foo"), new StaDyn(arg0), - new TryLdGlobalByName("method"), + new EcmaTryldglobalbyname("method"), new StaDyn(prop), - new LdObjByValue(arg0, prop), + new EcmaLdobjbyvalue(arg0, prop), new StaDyn(arg1), - new CalliThisRangeDyn(new Imm(ResultType.Int, 1), [arg1, obj]), + new EcmaCallithisrangedyn(new Imm(ResultType.Int, 1), [arg1, obj]), - new ReturnUndefined() + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; }); diff --git a/ts2panda/tests/expression/cmpBinary.test.ts b/ts2panda/tests/expression/cmpBinary.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..2534c932ac403bf59170da7d0c5023c5542f3aca --- /dev/null +++ b/ts2panda/tests/expression/cmpBinary.test.ts @@ -0,0 +1,335 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + expect +} from 'chai'; +import 'mocha'; +import { + EcmaAnd2dyn, + EcmaEqdyn, + EcmaGreaterdyn, + EcmaGreatereqdyn, + EcmaIncdyn, + EcmaInstanceofdyn, + EcmaIsindyn, + EcmaLessdyn, + EcmaLesseqdyn, + EcmaNoteqdyn, + EcmaOr2dyn, + EcmaReturnundefined, + EcmaStlettoglobalrecord, + EcmaStricteqdyn, + EcmaStrictnoteqdyn, + EcmaTonumber, + EcmaTryldglobalbyname, + EcmaTrystglobalbyname, + EcmaXor2dyn, + Imm, + Jeqz, + Jmp, + Label, + LdaDyn, + LdaiDyn, + LdaStr, + ResultType, + StaDyn, + VReg +} from "../../src/irnodes"; +import { checkInstructions, compileMainSnippet } from "../utils/base"; + +describe("CmpBinaryOperators", function () { + it("LessThan", function () { + let insns = compileMainSnippet("2 < 3;"); + let lhs = new VReg(); + let falseLabel = new Label(); + let endLabel = new Label(); + + let expected = [ + new LdaiDyn(new Imm(ResultType.Int, 2)), + new StaDyn(lhs), + new LdaiDyn(new Imm(ResultType.Int, 3)), + new EcmaLessdyn(lhs), + new Jeqz(falseLabel), + new LdaDyn(new VReg()), + new Jmp(endLabel), + falseLabel, + new LdaDyn(new VReg()), + endLabel, + new EcmaReturnundefined() + ]; + expect(checkInstructions(insns, expected)).to.be.true; + }); + + it("GreaterThan", function () { + let insns = compileMainSnippet("3 > 1;"); + let lhs = new VReg(); + let falseLabel = new Label(); + let endLabel = new Label(); + + let expected = [ + new LdaiDyn(new Imm(ResultType.Int, 3)), + new StaDyn(lhs), + new LdaiDyn(new Imm(ResultType.Int, 1)), + new EcmaGreaterdyn(lhs), + new Jeqz(falseLabel), + new LdaDyn(new VReg()), + new Jmp(endLabel), + falseLabel, + new LdaDyn(new VReg()), + endLabel, + new EcmaReturnundefined() + ]; + expect(checkInstructions(insns, expected)).to.be.true; + }); + + it("LessThanEquals", function () { + let insns = compileMainSnippet("3 <= 4;"); + let lhs = new VReg(); + let falseLabel = new Label(); + let endLabel = new Label(); + + let expected = [ + new LdaiDyn(new Imm(ResultType.Int, 3)), + new StaDyn(lhs), + new LdaiDyn(new Imm(ResultType.Int, 4)), + new EcmaLesseqdyn(lhs), + new Jeqz(falseLabel), + new LdaDyn(new VReg()), + new Jmp(endLabel), + falseLabel, + new LdaDyn(new VReg()), + endLabel, + new EcmaReturnundefined() + ]; + expect(checkInstructions(insns, expected)).to.be.true; + }); + + it("GreaterThanEquals", function () { + let insns = compileMainSnippet("3 >= 2;"); + let lhs = new VReg(); + let falseLabel = new Label(); + let endLabel = new Label(); + + let expected = [ + new LdaiDyn(new Imm(ResultType.Int, 3)), + new StaDyn(lhs), + new LdaiDyn(new Imm(ResultType.Int, 2)), + new EcmaGreatereqdyn(lhs), + new Jeqz(falseLabel), + new LdaDyn(new VReg()), + new Jmp(endLabel), + falseLabel, + new LdaDyn(new VReg()), + endLabel, + new EcmaReturnundefined() + ]; + expect(checkInstructions(insns, expected)).to.be.true; + }); + + it("EqualsEquals", function () { + let insns = compileMainSnippet("3 == 3;"); + let lhs = new VReg(); + let falseLabel = new Label(); + let endLabel = new Label(); + + let expected = [ + new LdaiDyn(new Imm(ResultType.Int, 3)), + new StaDyn(lhs), + new LdaiDyn(new Imm(ResultType.Int, 3)), + new EcmaEqdyn(lhs), + new Jeqz(falseLabel), + new LdaDyn(new VReg()), + new Jmp(endLabel), + falseLabel, + new LdaDyn(new VReg()), + endLabel, + new EcmaReturnundefined() + ]; + expect(checkInstructions(insns, expected)).to.be.true; + }); + + it("ExclamationEquals", function () { + let insns = compileMainSnippet("3 != 2;"); + let lhs = new VReg(); + let falseLabel = new Label(); + let endLabel = new Label(); + + let expected = [ + new LdaiDyn(new Imm(ResultType.Int, 3)), + new StaDyn(lhs), + new LdaiDyn(new Imm(ResultType.Int, 2)), + new EcmaNoteqdyn(lhs), + new Jeqz(falseLabel), + new LdaDyn(new VReg()), + new Jmp(endLabel), + falseLabel, + new LdaDyn(new VReg()), + endLabel, + new EcmaReturnundefined() + ]; + expect(checkInstructions(insns, expected)).to.be.true; + }); + + it("EqualsEqualsEquals", function () { + let insns = compileMainSnippet("3 === 3;"); + let lhs = new VReg(); + let falseLabel = new Label(); + let endLabel = new Label(); + + let expected = [ + new LdaiDyn(new Imm(ResultType.Int, 3)), + new StaDyn(lhs), + new LdaiDyn(new Imm(ResultType.Int, 3)), + new EcmaStricteqdyn(lhs), + new Jeqz(falseLabel), + new LdaDyn(new VReg()), + new Jmp(endLabel), + falseLabel, + new LdaDyn(new VReg()), + endLabel, + new EcmaReturnundefined() + ]; + expect(checkInstructions(insns, expected)).to.be.true; + }); + + it("ExclamationEqualsEquals", function () { + let insns = compileMainSnippet("3 !== 3;"); + let lhs = new VReg(); + let falseLabel = new Label(); + let endLabel = new Label(); + + let expected = [ + new LdaiDyn(new Imm(ResultType.Int, 3)), + new StaDyn(lhs), + new LdaiDyn(new Imm(ResultType.Int, 3)), + new EcmaStrictnoteqdyn(lhs), + new Jeqz(falseLabel), + new LdaDyn(new VReg()), + new Jmp(endLabel), + falseLabel, + new LdaDyn(new VReg()), + endLabel, + new EcmaReturnundefined() + ]; + expect(checkInstructions(insns, expected)).to.be.true; + }); + + it("ampersandEqual", function () { + let insns = compileMainSnippet("let a = 5;\n" + + "a &= 3;"); + let lhs = new VReg(); + + let expected = [ + new LdaiDyn(new Imm(ResultType.Int, 5)), + new EcmaStlettoglobalrecord('a'), + new EcmaTryldglobalbyname('a'), + new StaDyn(lhs), + new LdaiDyn(new Imm(ResultType.Int, 3)), + new EcmaAnd2dyn(lhs), + new EcmaTrystglobalbyname('a'), + new EcmaReturnundefined() + ]; + expect(checkInstructions(insns, expected)).to.be.true; + }); + + it("barEqual", function () { + let insns = compileMainSnippet("let a = 5;\n" + + "a |= 3;"); + let lhs = new VReg(); + + let expected = [ + new LdaiDyn(new Imm(ResultType.Int, 5)), + new EcmaStlettoglobalrecord('a'), + new EcmaTryldglobalbyname('a'), + new StaDyn(lhs), + new LdaiDyn(new Imm(ResultType.Int, 3)), + new EcmaOr2dyn(lhs), + new EcmaTrystglobalbyname('a'), + new EcmaReturnundefined() + ]; + expect(checkInstructions(insns, expected)).to.be.true; + }); + + it("caretEqual", function () { + let insns = compileMainSnippet("let a = 5;\n" + + "a ^= 3;"); + let lhs = new VReg(); + + let expected = [ + new LdaiDyn(new Imm(ResultType.Int, 5)), + new EcmaStlettoglobalrecord('a'), + new EcmaTryldglobalbyname('a'), + new StaDyn(lhs), + new LdaiDyn(new Imm(ResultType.Int, 3)), + new EcmaXor2dyn(lhs), + new EcmaTrystglobalbyname('a'), + new EcmaReturnundefined() + ]; + expect(checkInstructions(insns, expected)).to.be.true; + }); + + it("CommaToken", function () { + let insns = compileMainSnippet(`let x = 1; + x = (x++, x);`); + let variable = new VReg(); + let rhs = new VReg(); + let lhs = new VReg(); + + let expected = [ + new LdaiDyn(new Imm(ResultType.Int, 1)), + new EcmaStlettoglobalrecord('x'), + new EcmaTryldglobalbyname('x'), + new StaDyn(lhs), + new EcmaIncdyn(lhs), + new EcmaTrystglobalbyname('x'), + new EcmaTonumber(variable), + new StaDyn(rhs), + new EcmaTryldglobalbyname('x'), + new EcmaTrystglobalbyname('x'), + new EcmaReturnundefined() + ]; + expect(checkInstructions(insns, expected)).to.be.true; + }); + + it("InKeyword", function () { + let insns = compileMainSnippet(`'o' in C;`); + let rhs = new VReg(); + + let expected = [ + new LdaStr('o'), + new StaDyn(rhs), + new EcmaTryldglobalbyname("C"), + new EcmaIsindyn(rhs), + new EcmaReturnundefined() + ]; + expect(checkInstructions(insns, expected)).to.be.true; + }); + + it("InstanceOfKeyword", function () { + let insns = compileMainSnippet(`o instanceof C;`); + let rhs = new VReg(); + + let expected = [ + new EcmaTryldglobalbyname("o"), + new StaDyn(rhs), + new EcmaTryldglobalbyname("C"), + new EcmaInstanceofdyn(rhs), + new EcmaReturnundefined() + ]; + expect(checkInstructions(insns, expected)).to.be.true; + }); + +}); diff --git a/ts2panda/tests/conditions.test.ts b/ts2panda/tests/expression/conditions.test.ts similarity index 76% rename from ts2panda/tests/conditions.test.ts rename to ts2panda/tests/expression/conditions.test.ts index ae7b88840e62002d2b01653c51014fcfbc7065ab..8e15bd616b506d0b882c3f40469c50bb7a7033c8 100644 --- a/ts2panda/tests/conditions.test.ts +++ b/ts2panda/tests/expression/conditions.test.ts @@ -18,8 +18,13 @@ import { } from 'chai'; import 'mocha'; import { - And2Dyn, - EqDyn, + EcmaAnd2dyn, + EcmaEqdyn, + EcmaIsfalse, + EcmaIstrue, + EcmaReturnundefined, + EcmaStlettoglobalrecord, + EcmaTryldglobalbyname, Imm, Jeqz, Jlez, @@ -27,18 +32,14 @@ import { Label, LdaDyn, LdaiDyn, - NotEqDyn, ResultType, - ReturnDyn, StaDyn, - VReg, - Toboolean, - ReturnUndefined, -} from "../src/irnodes"; -import { checkInstructions, compileMainSnippet } from "./utils/base"; - -describe("IfConditionTest", function() { - it('ifConditionEmpty', function() { + VReg +} from "../../src/irnodes"; +import { checkInstructions, compileMainSnippet } from "../utils/base"; + +describe("IfConditionTest", function () { + it('ifConditionEmpty', function () { let insns = compileMainSnippet("let s = 1;\n" + "if (s > 2) {}"); let jumps = insns.filter(item => item instanceof Jeqz); @@ -50,7 +51,7 @@ describe("IfConditionTest", function() { expect(targetLabel).to.equal(insns[insns.length - 2]); }); - it('ifConditionWithThenStatement', function() { + it('ifConditionWithThenStatement', function () { let insns = compileMainSnippet("let a = 2;\n" + "if (a > 4) {\n" + " a = 3;\n" + @@ -64,7 +65,7 @@ describe("IfConditionTest", function() { expect(targetLabel).to.equal(insns[insns.length - 2]); }); - it('ifConditionWithThenStatementAndElseStatement', function() { + it('ifConditionWithThenStatementAndElseStatement', function () { let insns = compileMainSnippet("let a = 5;\n" + "if (a > 3) {\n" + " a = 2;\n" + @@ -87,25 +88,21 @@ describe("IfConditionTest", function() { expect(endIfLabel).to.equal(insns[insns.length - 2]); }); - it("if (a & b)", function() { + it("if (a & b)", function () { let insns = compileMainSnippet(` let a = 1; let b = 2; if (a & b) { } `); - let a = new VReg(); - let b = new VReg(); let lhs = new VReg(); - let trueReg = new VReg(); let endIfLabel = new Label(); let expected = [ - new LdaDyn(a), + new EcmaTryldglobalbyname('a'), new StaDyn(lhs), - new LdaDyn(b), - new And2Dyn(lhs), - new Toboolean(), - new EqDyn(trueReg), + new EcmaTryldglobalbyname('b'), + new EcmaAnd2dyn(lhs), + new EcmaIstrue(), new Jeqz(endIfLabel), endIfLabel, ]; @@ -113,22 +110,21 @@ describe("IfConditionTest", function() { expect(checkInstructions(insns, expected)).to.be.true }); - it("if (a = b)", function() { + it("if (a == b)", function () { let insns = compileMainSnippet(` let a = 1; let b = 2; - if (a = b) { + if (a == b) { } `); let a = new VReg(); - let b = new VReg(); let trueReg = new VReg(); let endIfLabel = new Label(); let expected = [ - new LdaDyn(b), + new EcmaTryldglobalbyname('a'), new StaDyn(a), - new Toboolean(), - new EqDyn(trueReg), + new EcmaTryldglobalbyname('b'), + new EcmaEqdyn(trueReg), new Jeqz(endIfLabel), endIfLabel, ]; @@ -136,25 +132,22 @@ describe("IfConditionTest", function() { expect(checkInstructions(insns, expected)).to.be.true; }); - it("let a = true ? 5 : 0;", function() { + it("let a = true ? 5 : 0;", function () { let insns = compileMainSnippet(`let a = true ? 5 : 0;`); insns = insns.slice(0, insns.length - 1); - let trueReg = new VReg(); - let tempReg = new VReg(); let expectedElseLabel = new Label(); let expectedEndLabel = new Label(); let expected = [ new LdaDyn(new VReg()), - new Toboolean(), - new EqDyn(trueReg), + new EcmaIstrue(), new Jeqz(expectedElseLabel), new LdaiDyn(new Imm(ResultType.Int, 5)), new Jmp(expectedEndLabel), expectedElseLabel, new LdaiDyn(new Imm(ResultType.Int, 0)), expectedEndLabel, - new StaDyn(tempReg) + new EcmaStlettoglobalrecord('a'), ]; expect(checkInstructions(insns, expected)).to.be.true; @@ -165,42 +158,36 @@ describe("IfConditionTest", function() { expect(labels.length).to.equal(2); }); - it("if (true && 5) {}", function() { + it("if (true && 5) {}", function () { let insns = compileMainSnippet("if (true && 5) {}"); - let trueReg = new VReg(); let ifFalseLabel = new Label(); let expected = [ new LdaDyn(new VReg()), - new Toboolean(), - new EqDyn(trueReg), + new EcmaIstrue(), new Jeqz(ifFalseLabel), new LdaiDyn(new Imm(ResultType.Int, 5)), - new Toboolean(), - new EqDyn(trueReg), + new EcmaIstrue(), new Jeqz(ifFalseLabel), ifFalseLabel, - new ReturnUndefined() + new EcmaReturnundefined() ] expect(checkInstructions(insns, expected)).to.be.true; }); - it("if (false || 5) {}", function() { + it("if (false || 5) {}", function () { let insns = compileMainSnippet("if (false || 5) {}"); - let falseReg = new VReg(); let ifFalseLabel = new Label(); let endLabel = new Label(); let expected = [ new LdaDyn(new VReg()), - new Toboolean(), - new EqDyn(falseReg), + new EcmaIsfalse(), new Jeqz(endLabel), new LdaiDyn(new Imm(ResultType.Int, 5)), - new Toboolean(), - new NotEqDyn(falseReg), + new EcmaIstrue(), new Jeqz(ifFalseLabel), endLabel, ifFalseLabel, - new ReturnUndefined() + new EcmaReturnundefined() ] expect(checkInstructions(insns, expected)).to.be.true; }); diff --git a/ts2panda/tests/expression/delete.test.ts b/ts2panda/tests/expression/delete.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..8c7f3a1ace370a42f0163b37159686fa137a7e63 --- /dev/null +++ b/ts2panda/tests/expression/delete.test.ts @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + expect +} from 'chai'; +import 'mocha'; +import { + EcmaDelobjprop, + EcmaReturnundefined, + EcmaStlettoglobalrecord, + EcmaTryldglobalbyname, + Imm, + LdaDyn, + LdaiDyn, + LdaStr, + ResultType, + StaDyn, + VReg +} from "../../src/irnodes"; +import { checkInstructions, compileMainSnippet, SnippetCompiler } from "../utils/base"; + +describe("deleteExpressionTest", function () { + it("deleteElementFromArray", function () { + let insns = compileMainSnippet("let arr = [1, 2]; delete arr[1];"); + + let objReg = new VReg(); + let propReg = new VReg(); + + let expected = [ + // let arr = [1, 2]; + // ... + // delete arr[1]; + new EcmaStlettoglobalrecord('arr'), + new EcmaTryldglobalbyname('arr'), + new StaDyn(objReg), + new LdaiDyn(new Imm(ResultType.Int, 1)), + new StaDyn(propReg), + new EcmaDelobjprop(objReg, propReg), + new EcmaReturnundefined() + ]; + + insns = insns.slice(insns.length - 7, insns.length); + expect(checkInstructions(insns, expected)).to.be.true; + }); + + it("deletePropFromObj", function () { + // this Snippet code isn't supported by TS + let insns = compileMainSnippet(`let obj = { + a: 1, + b: 2}; + delete obj.b;`); + let objReg = new VReg(); + let propReg = new VReg(); + + let expected = [ + // delete obj.b; + new EcmaStlettoglobalrecord('obj'), + new EcmaTryldglobalbyname('obj'), + new StaDyn(objReg), + new LdaStr("b"), + new StaDyn(propReg), + new EcmaDelobjprop(objReg, propReg), + new EcmaReturnundefined() + ]; + + insns = insns.slice(insns.length - 7, insns.length); + expect(checkInstructions(insns, expected)).to.be.true; + }); + + // delete function call won't use delObjProp + it("deleteFunctionCall", function () { + let snippetCompiler = new SnippetCompiler(); + snippetCompiler.compile(`var foo = function() { + bIsFooCalled = true; + }; + let a = delete foo();`); + + let insns = snippetCompiler.getGlobalInsns(); + let expected = [ + // function call insns + new LdaDyn(new VReg()), + new EcmaStlettoglobalrecord('a'), + new EcmaReturnundefined() + ]; + + insns = insns.slice(insns.length - 3, insns.length); + expect(checkInstructions(insns, expected)).to.be.true; + }); + + // delete keywords won't use delObjProp + it("deleteKeywords", function () { + let insns = compileMainSnippet(`let a = delete false;`); + + let expected = [ + new LdaDyn(new VReg()), + new LdaDyn(new VReg()), + new EcmaStlettoglobalrecord('a'), + new EcmaReturnundefined() + ]; + + expect(checkInstructions(insns, expected)).to.be.true; + }); + + it("deleteUnresolvable", function () { + let insns = compileMainSnippet(`delete a;`); + let globalReg = new VReg(); + let a = new VReg(); + + let expected = [ + new LdaStr("a"), + new StaDyn(a), + new EcmaDelobjprop(globalReg, a), + new EcmaReturnundefined() + ]; + + expect(checkInstructions(insns, expected)).to.be.true; + }); + + it("double delete", function () { + let insns = compileMainSnippet(`delete delete a;`); + let globalReg = new VReg(); + let a = new VReg(); + + let expected = [ + new LdaStr("a"), + new StaDyn(a), + new EcmaDelobjprop(globalReg, a), + new LdaDyn(new VReg()), + new EcmaReturnundefined() + ]; + + expect(checkInstructions(insns, expected)).to.be.true; + }); +}); \ No newline at end of file diff --git a/ts2panda/tests/elementAccess.test.ts b/ts2panda/tests/expression/elementAccess.test.ts similarity index 65% rename from ts2panda/tests/elementAccess.test.ts rename to ts2panda/tests/expression/elementAccess.test.ts index 8f8b26ebe3c3dc5ddc585f610d487501c84381c1..3a466cfd114b46102ab56287f14aa22558ff1358 100644 --- a/ts2panda/tests/elementAccess.test.ts +++ b/ts2panda/tests/expression/elementAccess.test.ts @@ -18,56 +18,59 @@ import { } from 'chai'; import 'mocha'; import { - Add2Dyn, + EcmaAdd2dyn, + EcmaLdobjbyname, + EcmaLdobjbyvalue, + EcmaStlettoglobalrecord, + EcmaStobjbyname, + EcmaTryldglobalbyname, Imm, - LdaDyn, LdaiDyn, - LdObjByName, - LdObjByValue, MovDyn, ResultType, StaDyn, - StObjByName, VReg -} from "../src/irnodes"; -import { checkInstructions, compileMainSnippet } from "./utils/base"; +} from "../../src/irnodes"; +import { checkInstructions, compileMainSnippet } from "../utils/base"; -describe("ElementAccess", function() { - it('get obj["property"]', function() { +describe("ElementAccess", function () { + it('get obj["property"]', function () { let insns = compileMainSnippet(`let obj; obj["property"];`); let objReg = new VReg(); let expected = [ - new LdaDyn(objReg), + new EcmaStlettoglobalrecord('obj'), + new EcmaTryldglobalbyname('obj'), new StaDyn(objReg), - new LdObjByName("property", objReg) + new EcmaLdobjbyname("property", objReg), ]; - insns = insns.slice(2, insns.length - 1); // cut off let obj and return.dyn + insns = insns.slice(1, insns.length - 1); // cut off let obj and return.dyn expect(checkInstructions(insns, expected)).to.be.true; }); - it('set obj["property"]', function() { + it('set obj["property"]', function () { let insns = compileMainSnippet(`let obj; obj["property"] = 5;`); let objReg = new VReg(); let tempObj = new VReg(); let expected = [ - new LdaDyn(objReg), + new EcmaStlettoglobalrecord('obj'), + new EcmaTryldglobalbyname('obj'), new StaDyn(tempObj), new MovDyn(objReg, tempObj), new LdaiDyn(new Imm(ResultType.Int, 5)), - new StObjByName("property", objReg), + new EcmaStobjbyname("property", objReg), ]; - insns = insns.slice(2, insns.length - 1); // cut off let obj and return.dyn + insns = insns.slice(1, insns.length - 1); // cut off let obj and return.dyn expect(checkInstructions(insns, expected)).to.be.true; }); - it('get obj[1 + 2]', function() { + it('get obj[1 + 2]', function () { let insns = compileMainSnippet(`let obj; obj[1 + 2];`); let prop1Reg = new VReg(); @@ -75,17 +78,17 @@ describe("ElementAccess", function() { let val = new VReg(); let expected = [ - new LdaDyn(objReg), + new EcmaStlettoglobalrecord('obj'), + new EcmaTryldglobalbyname('obj'), new StaDyn(objReg), new LdaiDyn(new Imm(ResultType.Int, 1)), new StaDyn(prop1Reg), new LdaiDyn(new Imm(ResultType.Int, 2)), - new Add2Dyn(prop1Reg), + new EcmaAdd2dyn(prop1Reg), new StaDyn(val), - new LdObjByValue(objReg, val) + new EcmaLdobjbyvalue(objReg, val) ]; - - insns = insns.slice(2, insns.length - 1); // cut off let obj and return.dyn + insns = insns.slice(1, insns.length - 1); // cut off let obj and return.dyn expect(checkInstructions(insns, expected)).to.be.true; }); }); diff --git a/ts2panda/tests/expression/functionExpression.test.ts b/ts2panda/tests/expression/functionExpression.test.ts index 1d349b0d258b47f70e5fea1dccad02942eccd810..f7cdaa4e5a76581dcea683aac75c72b2a482399b 100755 --- a/ts2panda/tests/expression/functionExpression.test.ts +++ b/ts2panda/tests/expression/functionExpression.test.ts @@ -14,42 +14,41 @@ */ import { expect } from 'chai'; -import { DiagnosticCode } from '../../src/diagnostic'; +import { DiagnosticCode, DiagnosticError } from '../../src/diagnostic'; import { - Add2Dyn, - AsyncFunctionAwaitUncaughtDyn, - AsyncFunctionEnterDyn, - AsyncFunctionRejectDyn, - AsyncFunctionResolveDyn, - Call0Dyn, - CreateGeneratorObjDyn, - CreateIterResultObjectDyn, - DefineAsyncFuncDyn, - DefinefuncDyn, - DefineGeneratorfuncDyn, - DefineNCFuncDyn, - EqDyn, - GetResumeModeDyn, + EcmaAdd2dyn, + EcmaAsyncfunctionawaituncaught, + EcmaAsyncfunctionenter, + EcmaAsyncfunctionreject, + EcmaAsyncfunctionresolve, + EcmaCallarg0dyn, + EcmaCreategeneratorobj, + EcmaCreateiterresultobj, + EcmaDefinefuncdyn, + EcmaDefinegeneratorfunc, + EcmaDefinencfuncdyn, + EcmaEqdyn, + EcmaGetresumemode, + EcmaLdlexenvdyn, + EcmaResumegenerator, + EcmaReturnundefined, + EcmaSuspendgenerator, + EcmaThrowdyn, Imm, Jeqz, Label, LdaDyn, LdaiDyn, - LdLexEnv, ResultType, - ResumeGeneratorDyn, ReturnDyn, - ReturnUndefined, StaDyn, - SuspendGeneratorDyn, - ThrowDyn, VReg } from "../../src/irnodes"; import { CacheExpander } from '../../src/pass/cacheExpander'; import { checkInstructions, compileAllSnippet } from "../utils/base"; -describe("compileFunctionExpression", function() { - it("FunctionExpression with name", function() { +describe("compileFunctionExpression", function () { + it("FunctionExpression with name", function () { let source: string = ` var a = function test() { test(); @@ -59,17 +58,17 @@ describe("compileFunctionExpression", function() { let pandaGens = compileAllSnippet(source, passes); let expected_func = [ - new LdLexEnv(), + new EcmaLdlexenvdyn(), new StaDyn(new VReg()), new LdaDyn(new VReg()), new StaDyn(new VReg()), - new Call0Dyn(new VReg()), - new ReturnUndefined() + new EcmaCallarg0dyn(new VReg()), + new EcmaReturnundefined() ]; let checkCount = 0; pandaGens.forEach((pg) => { - if (pg.internalName == "func_test_1") { + if (pg.internalName == "test") { expect(checkInstructions(pg.getInsns(), expected_func), "check func insns").to.be.true; checkCount++; } @@ -78,7 +77,7 @@ describe("compileFunctionExpression", function() { expect(checkCount).to.equals(1); }); - it("FunctionExpression without name", function() { + it("FunctionExpression without name", function () { let source: string = ` var a = function () { }`; @@ -87,15 +86,15 @@ describe("compileFunctionExpression", function() { let checkCount = 0; pandaGens.forEach((pg) => { - if (pg.internalName == "func_a_1") { + if (pg.internalName == "a") { checkCount++; } if (pg.internalName == "func_main_0") { pg.getInsns().forEach((insns) => { - if (insns instanceof DefinefuncDyn) { - expect(insns.operands[0]).to.equal('func_a_1'); + if (insns instanceof EcmaDefinefuncdyn) { + expect(insns.operands[0]).to.equal('a'); checkCount++; } }); @@ -105,7 +104,7 @@ describe("compileFunctionExpression", function() { expect(checkCount).to.equals(2); }); - it("FunctionExpression without name in binary expression", function() { + it("FunctionExpression without name in binary expression", function () { let source: string = ` var a; a = function () { @@ -115,15 +114,15 @@ describe("compileFunctionExpression", function() { let checkCount = 0; pandaGens.forEach((pg) => { - if (pg.internalName == "func_a_1") { + if (pg.internalName == "a") { checkCount++; } if (pg.internalName == "func_main_0") { pg.getInsns().forEach((insns) => { - if (insns instanceof DefinefuncDyn) { - expect(insns.operands[0]).to.equal('func_a_1'); + if (insns instanceof EcmaDefinefuncdyn) { + expect(insns.operands[0]).to.equal('a'); checkCount++; } }); @@ -134,7 +133,7 @@ describe("compileFunctionExpression", function() { }); - it("ArrowFunction", function() { + it("ArrowFunction", function () { let source: string = ` var a = ()=> { }`; @@ -143,15 +142,15 @@ describe("compileFunctionExpression", function() { let checkCount = 0; pandaGens.forEach((pg) => { - if (pg.internalName == "func_a_1") { + if (pg.internalName == "a") { checkCount++; } if (pg.internalName == "func_main_0") { pg.getInsns().forEach((insns) => { - if (insns instanceof DefineNCFuncDyn) { - expect(insns.operands[0]).to.equal('func_a_1'); + if (insns instanceof EcmaDefinencfuncdyn) { + expect(insns.operands[0]).to.equal('a'); checkCount++; } }); @@ -161,7 +160,7 @@ describe("compileFunctionExpression", function() { expect(checkCount).to.equals(2); }); - it("ArrowFunctionWithExpression", function() { + it("ArrowFunctionWithExpression", function () { let source: string = ` var p = (x, y) => x + y;`; @@ -172,14 +171,14 @@ describe("compileFunctionExpression", function() { new LdaDyn(new VReg()), new StaDyn(new VReg()), new LdaDyn(new VReg()), - new Add2Dyn(new VReg()), + new EcmaAdd2dyn(new VReg()), new StaDyn(new VReg()), new LdaDyn(new VReg()), new ReturnDyn() ]; pandaGens.forEach((pg) => { - if (pg.internalName == "func_p_1") { + if (pg.internalName == "p") { expect(checkInstructions(pg.getInsns(), expected_func), "check arrow func insns").to.be.true; checkCount++; } @@ -187,8 +186,8 @@ describe("compileFunctionExpression", function() { if (pg.internalName == "func_main_0") { pg.getInsns().forEach((insns) => { - if (insns instanceof DefineNCFuncDyn) { - expect(insns.operands[0]).to.equal('func_p_1'); + if (insns instanceof EcmaDefinencfuncdyn) { + expect(insns.operands[0]).to.equal('p'); checkCount++; } }); @@ -198,7 +197,7 @@ describe("compileFunctionExpression", function() { expect(checkCount).to.equals(2); }); - it("ArrowFunctionSyntaxError", function() { + it("ArrowFunctionSyntaxError", function () { let source: string = ` var af = x => {};`; @@ -206,13 +205,14 @@ describe("compileFunctionExpression", function() { try { compileAllSnippet(source); } catch (err) { - expect(err.code).to.equal(DiagnosticCode.Line_terminator_not_permitted_before_arrow); + expect(err instanceof DiagnosticError).to.be.true; + expect((err).code).to.equal(DiagnosticCode.Line_terminator_not_permitted_before_arrow); errorThrown = true; } expect(errorThrown).to.be.true; }); - it("GeneratorFunction", function() { + it("GeneratorFunction", function () { let source: string = ` function* a() { yield 1; @@ -224,70 +224,70 @@ describe("compileFunctionExpression", function() { let notThrowLabel1 = new Label(); let expected_func = [ - new CreateGeneratorObjDyn(new VReg()), + new EcmaCreategeneratorobj(new VReg()), new StaDyn(new VReg()), - new SuspendGeneratorDyn(new VReg(), new VReg()), - new ResumeGeneratorDyn(new VReg()), + new EcmaSuspendgenerator(new VReg(), new VReg()), + new EcmaResumegenerator(new VReg()), new StaDyn(new VReg()), - new GetResumeModeDyn(new VReg()), + new EcmaGetresumemode(new VReg()), new StaDyn(new VReg()), new LdaiDyn(new Imm(ResultType.Int, 0)), - new EqDyn(new VReg()), + new EcmaEqdyn(new VReg()), new Jeqz(notRetLabel0), new LdaDyn(new VReg()), new ReturnDyn(), notRetLabel0, new LdaiDyn(new Imm(ResultType.Int, 1)), - new EqDyn(new VReg()), + new EcmaEqdyn(new VReg()), new Jeqz(notThrowLabel0), new LdaDyn(new VReg()), - new ThrowDyn(), + new EcmaThrowdyn(), notThrowLabel0, new LdaDyn(new VReg()), new LdaiDyn(new Imm(ResultType.Int, 1)), new StaDyn(new VReg()), - new CreateIterResultObjectDyn(new VReg(), new VReg()), + new EcmaCreateiterresultobj(new VReg(), new VReg()), new StaDyn(new VReg()), - new SuspendGeneratorDyn(new VReg(), new VReg()), - new ResumeGeneratorDyn(new VReg()), + new EcmaSuspendgenerator(new VReg(), new VReg()), + new EcmaResumegenerator(new VReg()), new StaDyn(new VReg()), - new GetResumeModeDyn(new VReg()), + new EcmaGetresumemode(new VReg()), new StaDyn(new VReg()), new LdaiDyn(new Imm(ResultType.Int, 0)), - new EqDyn(new VReg()), + new EcmaEqdyn(new VReg()), new Jeqz(notRetLabel1), new LdaDyn(new VReg()), new ReturnDyn(), notRetLabel1, new LdaiDyn(new Imm(ResultType.Int, 1)), - new EqDyn(new VReg()), + new EcmaEqdyn(new VReg()), new Jeqz(notThrowLabel1), new LdaDyn(new VReg()), - new ThrowDyn(), + new EcmaThrowdyn(), notThrowLabel1, new LdaDyn(new VReg()), - new ReturnUndefined() + new EcmaReturnundefined() ]; let pandaGens = compileAllSnippet(source); let checkCount = 0; pandaGens.forEach((pg) => { - if (pg.internalName == "func_a_1") { + if (pg.internalName == "a") { expect(checkInstructions(pg.getInsns(), expected_func), "check generator func insns").to.be.true; checkCount++; } if (pg.internalName == "func_main_0") { pg.getInsns().forEach((insns) => { - if (insns instanceof DefineGeneratorfuncDyn) { - expect(insns.operands[0]).to.equal('func_a_1'); + if (insns instanceof EcmaDefinegeneratorfunc) { + expect(insns.operands[0]).to.equal('a'); checkCount++; } }); @@ -297,7 +297,7 @@ describe("compileFunctionExpression", function() { expect(checkCount).to.equals(2); }); - it("AsyncFunction", function() { + it("AsyncFunction", function () { let source: string = ` async function a() { await 1; @@ -308,30 +308,30 @@ describe("compileFunctionExpression", function() { let nextLabel = new Label(); let expected_func = [ - new AsyncFunctionEnterDyn(), + new EcmaAsyncfunctionenter(), new StaDyn(new VReg()), beginLabel, new LdaiDyn(new Imm(ResultType.Int, 1)), new StaDyn(new VReg()), - new AsyncFunctionAwaitUncaughtDyn(new VReg(), new VReg()), + new EcmaAsyncfunctionawaituncaught(new VReg(), new VReg()), new StaDyn(new VReg()), - new SuspendGeneratorDyn(new VReg(), new VReg()), - new ResumeGeneratorDyn(new VReg()), + new EcmaSuspendgenerator(new VReg(), new VReg()), + new EcmaResumegenerator(new VReg()), new StaDyn(new VReg()), - new GetResumeModeDyn(new VReg()), + new EcmaGetresumemode(new VReg()), new StaDyn(new VReg()), new LdaiDyn(new Imm(ResultType.Int, 1)), - new EqDyn(new VReg()), + new EcmaEqdyn(new VReg()), new Jeqz(nextLabel), new LdaDyn(new VReg()), - new ThrowDyn(), + new EcmaThrowdyn(), nextLabel, new LdaDyn(new VReg()), - new AsyncFunctionResolveDyn(new VReg(), new VReg(), new VReg()), + new EcmaAsyncfunctionresolve(new VReg(), new VReg(), new VReg()), new ReturnDyn(), endLabel, new StaDyn(new VReg()), - new AsyncFunctionRejectDyn(new VReg(), new VReg(), new VReg()), + new EcmaAsyncfunctionreject(new VReg(), new VReg(), new VReg()), new ReturnDyn(), ]; @@ -339,31 +339,32 @@ describe("compileFunctionExpression", function() { let checkCount = 0; pandaGens.forEach((pg) => { - if (pg.internalName == "func_a_1") { + if (pg.internalName == "a") { expect(checkInstructions(pg.getInsns(), expected_func), "check async func insns").to.be.true; checkCount++; } if (pg.internalName == "func_main_0") { pg.getInsns().forEach((insns) => { - if (insns instanceof DefineAsyncFuncDyn) { - expect(insns.operands[0]).to.equal('func_a_1'); + if (insns instanceof EcmaDefinencfuncdyn) { + expect(insns.operands[0]).to.equal('a'); checkCount++; } }); } }); - expect(checkCount).to.equals(2); + expect(checkCount).to.equals(1); }); - it("FunctionWithRestParameterSyntaxError", function() { + it("FunctionWithRestParameterSyntaxError", function () { let source: string = `function func(...a,)`; let errorThrown = false; try { compileAllSnippet(source); } catch (err) { - expect(err.code).to.equal(DiagnosticCode.A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma); + expect(err instanceof DiagnosticError).to.be.true; + expect((err).code).to.equal(DiagnosticCode.A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma); errorThrown = true; } expect(errorThrown).to.be.true; diff --git a/ts2panda/tests/literal.test.ts b/ts2panda/tests/expression/literal.test.ts similarity index 48% rename from ts2panda/tests/literal.test.ts rename to ts2panda/tests/expression/literal.test.ts index 2f91e12fe66de11abb796a1a5b4043e8dc9fa5fd..7b4936bfb963ab8d8168a7662843abd750c74bc9 100644 --- a/ts2panda/tests/literal.test.ts +++ b/ts2panda/tests/expression/literal.test.ts @@ -17,347 +17,271 @@ import { expect } from 'chai'; import 'mocha'; -import { DiagnosticCode } from '../src/diagnostic'; +import { DiagnosticCode, DiagnosticError } from '../../src/diagnostic'; import { - Add2Dyn, - CreateArrayWithBuffer, - CreateEmptyArray, - CreateEmptyObject, - CreateObjectWithBuffer, + EcmaAdd2dyn, + EcmaCreatearraywithbuffer, + EcmaCreateemptyarray, + EcmaCreateemptyobject, + EcmaCreateobjectwithbuffer, + EcmaIncdyn, + EcmaReturnundefined, + EcmaStarrayspread, + EcmaStlettoglobalrecord, + EcmaStownbyindex, + EcmaStownbyname, + EcmaStownbyvalue, + EcmaTryldglobalbyname, Imm, - IncDyn, LdaDyn, LdaiDyn, LdaStr, - MovDyn, - NewObjDynRange, ResultType, - ReturnUndefined, StaDyn, - StArraySpread, - StOwnByIndex, - StOwnByName, - StOwnByValue, - TryLdGlobalByName, VReg -} from "../src/irnodes"; -import { checkInstructions, compileMainSnippet } from "./utils/base"; +} from "../../src/irnodes"; +import { checkInstructions, compileMainSnippet } from "../utils/base"; -describe("LiteralTest", function() { - it("5", function() { +describe("LiteralTest", function () { + it("5", function () { let insns = compileMainSnippet("5"); let expected = [ new LdaiDyn(new Imm(ResultType.Int, 5)), - new ReturnUndefined() + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; }); - it("\"stringLiteral\"", function() { + it("\"stringLiteral\"", function () { let insns = compileMainSnippet("\"stringLiteral\""); let expected = [ new LdaStr("stringLiteral"), - new ReturnUndefined() + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; }); - it("true", function() { + it("true", function () { let insns = compileMainSnippet("true"); let expected = [ new LdaDyn(new VReg()), - new ReturnUndefined() + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; }); - it("false", function() { + it("false", function () { let insns = compileMainSnippet("false"); let expected = [ new LdaDyn(new VReg()), - new ReturnUndefined() + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; }); - it("null", function() { + it("null", function () { let insns = compileMainSnippet("null"); let expected = [ new LdaDyn(new VReg()), - new ReturnUndefined() + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; }); - it("let arr = [1]", function() { + it("let arr = [1]", function () { let insns = compileMainSnippet("let arr = [1]"); let arrayInstance = new VReg(); - let arrayReg = new VReg(); let expected = [ - new CreateArrayWithBuffer(new Imm(ResultType.Int, 0)), + new EcmaCreatearraywithbuffer(new Imm(ResultType.Int, 0)), new StaDyn(arrayInstance), new LdaDyn(arrayInstance), - new StaDyn(arrayReg), - new ReturnUndefined() + new EcmaStlettoglobalrecord('arr'), + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; }); - it("let arr = []", function() { + it("let arr = []", function () { let insns = compileMainSnippet("let arr = []"); let arrayInstance = new VReg(); - let arrayReg = new VReg(); let expected = [ - new CreateEmptyArray(), + new EcmaCreateemptyarray(), new StaDyn(arrayInstance), - new StaDyn(arrayReg), - new ReturnUndefined() + new EcmaStlettoglobalrecord('arr'), + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; }); - it("let arr = [1, 2]", function() { + it("let arr = [1, 2]", function () { let insns = compileMainSnippet("let arr = [1, 2]"); let arrayInstance = new VReg(); let expected = [ - new CreateArrayWithBuffer(new Imm(ResultType.Int, 0)), + new EcmaCreatearraywithbuffer(new Imm(ResultType.Int, 0)), new StaDyn(arrayInstance), new LdaDyn(arrayInstance), + new EcmaStlettoglobalrecord('arr'), + new EcmaReturnundefined() ]; - insns = insns.slice(0, insns.length - 2); + insns = insns.slice(0, insns.length); expect(checkInstructions(insns, expected)).to.be.true; }); - it("let arr = [, 1]", function() { + it("let arr = [, 1]", function () { let insns = compileMainSnippet("let arr = [, 1]"); - let elemIdxReg = new VReg(); let arrayInstance = new VReg(); - let targetReg = new VReg(); let expected = [ - new CreateEmptyArray(), + new EcmaCreateemptyarray(), new StaDyn(arrayInstance), new LdaiDyn(new Imm(ResultType.Int, 1)), - new StaDyn(targetReg), - new LdaiDyn(new Imm(ResultType.Int, 1)), - new StaDyn(elemIdxReg), - new LdaDyn(targetReg), - new StOwnByIndex(arrayInstance, elemIdxReg), - new LdaDyn(arrayInstance) + new EcmaStownbyindex(arrayInstance, new Imm(ResultType.Int, 1)), + new LdaDyn(arrayInstance), + new EcmaStlettoglobalrecord('arr'), + new EcmaReturnundefined() ]; - insns = insns.slice(0, insns.length - 2); + insns = insns.slice(0, insns.length); expect(checkInstructions(insns, expected)).to.be.true; }); - it("let arr = [1, , 3]", function() { + it("let arr = [1, , 3]", function () { let insns = compileMainSnippet("let arr = [1,, 3]"); - let elemIdxReg = new VReg(); let arrayInstance = new VReg(); - let targetReg = new VReg(); let expected = [ - new CreateArrayWithBuffer(new Imm(ResultType.Int, 0)), + new EcmaCreatearraywithbuffer(new Imm(ResultType.Int, 0)), new StaDyn(arrayInstance), new LdaiDyn(new Imm(ResultType.Int, 3)), - new StaDyn(targetReg), - new LdaiDyn(new Imm(ResultType.Int, 2)), - new StaDyn(elemIdxReg), - new LdaDyn(targetReg), - new StOwnByIndex(arrayInstance, elemIdxReg), - new LdaDyn(arrayInstance) + new EcmaStownbyindex(arrayInstance, new Imm(ResultType.Int, 2)), + new LdaDyn(arrayInstance), + new EcmaStlettoglobalrecord('arr'), + new EcmaReturnundefined() ]; - insns = insns.slice(0, insns.length - 2); + insns = insns.slice(0, insns.length); expect(checkInstructions(insns, expected)).to.be.true; }); - it("let arr = [1, ...arr1, 3]", function() { + it("let arr = [1, ...arr1, 3]", function () { let insns = compileMainSnippet(`let arr1 = [1, 2]; let arr = [1, ...arr1, 3]`); - let arr = new VReg(); let elemIdxReg = new VReg(); let arrayInstance = new VReg(); let expected = [ - new CreateArrayWithBuffer(new Imm(ResultType.Int, 0)), + new EcmaCreatearraywithbuffer(new Imm(ResultType.Int, 0)), new StaDyn(arrayInstance), new LdaDyn(arrayInstance), - new StaDyn(arr), + new EcmaStlettoglobalrecord('arr1'), - new CreateArrayWithBuffer(new Imm(ResultType.Int, 1)), + new EcmaCreatearraywithbuffer(new Imm(ResultType.Int, 1)), new StaDyn(arrayInstance), new LdaiDyn(new Imm(ResultType.Int, 1)), new StaDyn(elemIdxReg), - new LdaDyn(arr), - new StArraySpread(arrayInstance, elemIdxReg), + new EcmaTryldglobalbyname('arr1'), + new EcmaStarrayspread(arrayInstance, elemIdxReg), new StaDyn(elemIdxReg), new LdaiDyn(new Imm(ResultType.Int, 3)), - new StOwnByValue(arrayInstance, elemIdxReg), - new IncDyn(elemIdxReg), + new EcmaStownbyvalue(arrayInstance, elemIdxReg), + new EcmaIncdyn(elemIdxReg), new StaDyn(elemIdxReg), new LdaDyn(arrayInstance), + new EcmaStlettoglobalrecord('arr'), ]; - insns = insns.slice(0, insns.length - 2); + insns = insns.slice(0, insns.length - 1); expect(checkInstructions(insns, expected)).to.be.true; }); - it("let obj = {}", function() { + it("let obj = {}", function () { let insns = compileMainSnippet("let obj = {}"); let objInstance = new VReg(); - let obj = new VReg(); let expected = [ - new CreateEmptyObject(), + new EcmaCreateemptyobject(), new StaDyn(objInstance), - new StaDyn(obj), - new ReturnUndefined() + new EcmaStlettoglobalrecord('obj'), + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; }); - it("let obj = {a: 1}", function() { + it("let obj = {a: 1}", function () { let insns = compileMainSnippet("let obj = {a: 1}"); let objInstance = new VReg(); - let obj = new VReg(); - let expected = [ - new CreateObjectWithBuffer(new Imm(ResultType.Int, 0)), + new EcmaCreateobjectwithbuffer(new Imm(ResultType.Int, 0)), new StaDyn(objInstance), new LdaDyn(objInstance), - new StaDyn(obj), - new ReturnUndefined() + new EcmaStlettoglobalrecord('obj'), + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; }); - it("let obj = {0: 1 + 2}", function() { + it("let obj = {0: 1 + 2}", function () { let insns = compileMainSnippet("let obj = {0: 1 + 2}"); let objInstance = new VReg(); let lhs = new VReg(); - let elemIndex = new VReg(); - let obj = new VReg(); - let targetReg = new VReg(); let expected = [ - new CreateObjectWithBuffer(new Imm(ResultType.Int, 0)), + new EcmaCreateobjectwithbuffer(new Imm(ResultType.Int, 0)), new StaDyn(objInstance), new LdaiDyn(new Imm(ResultType.Int, 1)), new StaDyn(lhs), new LdaiDyn(new Imm(ResultType.Int, 2)), - new Add2Dyn(lhs), - new StaDyn(targetReg), - new LdaiDyn(new Imm(ResultType.Int, 0)), - new StaDyn(elemIndex), - new LdaDyn(targetReg), - new StOwnByIndex(objInstance, elemIndex), + new EcmaAdd2dyn(lhs), + new EcmaStownbyindex(objInstance, new Imm(ResultType.Int, 0)), new LdaDyn(objInstance), - new StaDyn(obj), - new ReturnUndefined() + new EcmaStlettoglobalrecord('obj'), + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; }); - it("let obj = {\"str\": 1}", function() { + it("let obj = {\"str\": 1}", function () { let insns = compileMainSnippet("let obj = {\"str\": 1}"); let objInstance = new VReg(); - let obj = new VReg(); let expected = [ - new CreateObjectWithBuffer(new Imm(ResultType.Int, 0)), + new EcmaCreateobjectwithbuffer(new Imm(ResultType.Int, 0)), new StaDyn(objInstance), new LdaDyn(objInstance), - new StaDyn(obj), - new ReturnUndefined() + new EcmaStlettoglobalrecord('obj'), + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; }); - it("let a; let obj = {a}", function() { + it("let a; let obj = {a}", function () { let insns = compileMainSnippet("let a; let obj = {a}"); let objInstance = new VReg(); - let obj = new VReg(); - let a = new VReg(); let expected = [ - new CreateObjectWithBuffer(new Imm(ResultType.Int, 0)), + new EcmaCreateobjectwithbuffer(new Imm(ResultType.Int, 0)), new StaDyn(objInstance), - new LdaDyn(a), - new StOwnByName("a", objInstance), + new EcmaTryldglobalbyname('a'), + new EcmaStownbyname("a", objInstance), new LdaDyn(objInstance), - new StaDyn(obj) + new EcmaStlettoglobalrecord('obj') ]; insns = insns.slice(2, insns.length - 1); expect(checkInstructions(insns, expected)).to.be.true; }); - it("duplicate __proto__", function() { + it("duplicate __proto__", function () { let errorThrown = false; try { compileMainSnippet("({__proto__: null,other: null,'__proto__': null});"); } catch (err) { - expect(err.code).to.equal(DiagnosticCode.Duplicate_identifier_0); + expect(err instanceof DiagnosticError).to.be.true; + expect((err).code).to.equal(DiagnosticCode.Duplicate_identifier_0); errorThrown = true; } expect(errorThrown).to.be.true; }); }); -describe("Regular Expression", function() { - it("let a = /abc/;", function() { - let insns = compileMainSnippet("let a = /abc/;"); - insns = insns.slice(0, insns.length - 1); - let ctorReg = new VReg(); - let regexpReg = new VReg(); - let regexpInstance = new VReg(); - let targetReg = new VReg(); - - let expected = [ - new TryLdGlobalByName("RegExp"), - new StaDyn(ctorReg), - new MovDyn(targetReg, ctorReg), - new LdaStr("abc"), - new StaDyn(regexpReg), - new NewObjDynRange(new Imm(ResultType.Int, 3), [ctorReg, targetReg, regexpReg]), - new StaDyn(regexpInstance), - ]; - expect(checkInstructions(insns, expected)).to.be.true; - }); - - it("let a = /abc/i;", function() { - let insns = compileMainSnippet("let a = /abc/i;"); - insns = insns.slice(0, insns.length - 1); - let ctorReg = new VReg(); - let patternReg = new VReg(); - let flagsReg = new VReg(); - let regexpInstance = new VReg(); - let targetReg = new VReg(); - - let expected = [ - new TryLdGlobalByName("RegExp"), - new StaDyn(ctorReg), - new MovDyn(targetReg, ctorReg), - new LdaStr("abc"), - new StaDyn(patternReg), - new LdaStr("i"), - new StaDyn(flagsReg), - new NewObjDynRange(new Imm(ResultType.Int, 4), [ctorReg, targetReg, patternReg, flagsReg]), - new StaDyn(regexpInstance), - ]; - expect(checkInstructions(insns, expected)).to.be.true; - }); - - it("let a = /abc;", function() { - let errorThrown = false; - try { - let insns = compileMainSnippet("let a = /abc;"); - } catch (err) { - expect(err.message).to.equal("Invalid regular expression: /abc;: Unterminated regular expression"); - errorThrown = true; - } - expect(errorThrown).to.be.true; - }); -}); diff --git a/ts2panda/tests/expression/logicBinary.test.ts b/ts2panda/tests/expression/logicBinary.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..54e54b96aebd3cbe3c0255090a54cede3a821be9 --- /dev/null +++ b/ts2panda/tests/expression/logicBinary.test.ts @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + expect +} from 'chai'; +import 'mocha'; +import { + EcmaIsfalse, + EcmaIstrue, + EcmaReturnundefined, + Imm, + Jeqz, + Jmp, + Label, + LdaDyn, + LdaiDyn, ResultType, + StaDyn, + VReg +} from "../../src/irnodes"; +import { checkInstructions, compileMainSnippet } from "../utils/base"; + + +describe("LogicBinaryOperators", function () { + it("ampersandAmpersand", function () { + let insns = compileMainSnippet("8 && false;"); + let lhs = new VReg(); + let preLabel = new Label(); + let postLabel = new Label(); + + let expected = [ + new LdaiDyn(new Imm(ResultType.Int, 8)), + new StaDyn(lhs), + new EcmaIstrue(), + new Jeqz(preLabel), + new LdaDyn(new VReg()), + new Jmp(postLabel), + preLabel, + new LdaDyn(lhs), + postLabel, + new EcmaReturnundefined() + ] + + expect(checkInstructions(insns, expected)).to.be.true; + }); + + it("barBar", function () { + let insns = compileMainSnippet("8 || false;"); + let lhs = new VReg(); + let preLabel = new Label(); + let postLabel = new Label(); + let expected = [ + new LdaiDyn(new Imm(ResultType.Int, 8)), + new StaDyn(lhs), + new EcmaIsfalse(), + new Jeqz(preLabel), + new LdaDyn(new VReg()), + new Jmp(postLabel), + preLabel, + new LdaDyn(lhs), + postLabel, + new EcmaReturnundefined() + ] + + expect(checkInstructions(insns, expected)).to.be.true; + }); +}); diff --git a/ts2panda/tests/expression/new.test.ts b/ts2panda/tests/expression/new.test.ts index f81909c89a93e13ef0e4a1b1591d11415ccabbe1..e2440dae8f625fdbedddb44c677902ffbd374fe7 100755 --- a/ts2panda/tests/expression/new.test.ts +++ b/ts2panda/tests/expression/new.test.ts @@ -18,83 +18,83 @@ import { } from 'chai'; import 'mocha'; import { - CreateEmptyArray, + EcmaCreateemptyarray, + EcmaLdobjbyname, + EcmaNewobjdynrange, + EcmaNewobjspreaddyn, + EcmaReturnundefined, + EcmaStarrayspread, + EcmaTryldglobalbyname, Imm, LdaDyn, LdaiDyn, - LdObjByName, MovDyn, - NewObjDynRange, - NewobjSpread, ResultType, - ReturnUndefined, StaDyn, - StArraySpread, - TryLdGlobalByName, VReg } from "../../src/irnodes"; import { checkInstructions, compileMainSnippet } from "../utils/base"; -describe("NewTest", function() { - it("new Object", function() { +describe("NewTest", function () { + it("new Object", function () { let insns = compileMainSnippet("new Object"); let arg0 = new VReg(); let targetReg = new VReg(); let expected = [ - new TryLdGlobalByName("Object"), + new EcmaTryldglobalbyname("Object"), new StaDyn(arg0), new MovDyn(targetReg, arg0), - new NewObjDynRange(new Imm(ResultType.Int, 2), [arg0, targetReg]), + new EcmaNewobjdynrange(new Imm(ResultType.Int, 2), [arg0, targetReg]), - new ReturnUndefined() + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; }); - it("new Object()", function() { + it("new Object()", function () { let insns = compileMainSnippet("new Object()"); let arg0 = new VReg(); let targetReg = new VReg(); let expected = [ - new TryLdGlobalByName("Object"), + new EcmaTryldglobalbyname("Object"), new StaDyn(arg0), new MovDyn(targetReg, arg0), - new NewObjDynRange(new Imm(ResultType.Int, 2), [arg0, targetReg]), + new EcmaNewobjdynrange(new Imm(ResultType.Int, 2), [arg0, targetReg]), - new ReturnUndefined() + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; }); - it("new Object(2)", function() { + it("new Object(2)", function () { let insns = compileMainSnippet("new Object(2)"); let arg0 = new VReg(); let arg1 = new VReg(); let targetReg = new VReg(); let expected = [ - new TryLdGlobalByName("Object"), + new EcmaTryldglobalbyname("Object"), new StaDyn(arg0), new MovDyn(targetReg, arg0), new LdaiDyn(new Imm(ResultType.Int, 2)), new StaDyn(arg1), - new NewObjDynRange(new Imm(ResultType.Int, 3), [arg0, targetReg, arg1]), + new EcmaNewobjdynrange(new Imm(ResultType.Int, 3), [arg0, targetReg, arg1]), - new ReturnUndefined() + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; }); - it("new obj.ctor()", function() { + it("new obj.ctor()", function () { let insns = compileMainSnippet("let obj; new obj.ctor()"); let obj = new VReg(); let arg0 = new VReg(); @@ -102,14 +102,14 @@ describe("NewTest", function() { let targetReg = new VReg(); let expected = [ - new LdaDyn(obj), + new EcmaTryldglobalbyname('obj'), new StaDyn(temp), - new LdObjByName("ctor", obj), + new EcmaLdobjbyname("ctor", obj), new StaDyn(arg0), new MovDyn(targetReg, arg0), - new NewObjDynRange(new Imm(ResultType.Int, 2), [arg0, targetReg]), + new EcmaNewobjdynrange(new Imm(ResultType.Int, 2), [arg0, targetReg]), ]; insns = insns.slice(2, insns.length - 1); @@ -117,7 +117,7 @@ describe("NewTest", function() { expect(checkInstructions(insns, expected)).to.be.true; }); - it("new Object(...args)", function() { + it("new Object(...args)", function () { let insns = compileMainSnippet(`new Object(...args);`); let arg0 = new VReg(); let elemIdxReg = new VReg(); @@ -125,23 +125,23 @@ describe("NewTest", function() { let arrayInstance = new VReg(); let expected = [ - new TryLdGlobalByName("Object"), + new EcmaTryldglobalbyname("Object"), new StaDyn(arg0), new MovDyn(targetReg, arg0), - new CreateEmptyArray(), + new EcmaCreateemptyarray(), new StaDyn(arrayInstance), new LdaiDyn(new Imm(ResultType.Int, 0)), new StaDyn(elemIdxReg), - new TryLdGlobalByName("args"), - new StArraySpread(arrayInstance, elemIdxReg), + new EcmaTryldglobalbyname("args"), + new EcmaStarrayspread(arrayInstance, elemIdxReg), new StaDyn(elemIdxReg), new LdaDyn(arrayInstance), - new NewobjSpread(arg0, targetReg), + new EcmaNewobjspreaddyn(arg0, targetReg), - new ReturnUndefined() + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; diff --git a/ts2panda/tests/expression/numericLiteral.test.ts b/ts2panda/tests/expression/numericLiteral.test.ts index cd6383d014bdf628007c7c99969f34063168e271..e8c3e842e31d3eab754ea7794cd90401bf32df9f 100755 --- a/ts2panda/tests/expression/numericLiteral.test.ts +++ b/ts2panda/tests/expression/numericLiteral.test.ts @@ -27,8 +27,8 @@ import { import { PandaGen } from "../../src/pandagen"; import { checkInstructions } from "../utils/base"; -describe("compileNumericLiteral", function() { - it("NaN", function() { +describe("compileNumericLiteral", function () { + it("NaN", function () { let pandaGen = new PandaGen("ignored", 0, undefined); let node: ts.NumericLiteral = ts.createNumericLiteral("NaN"); compileNumericLiteral(pandaGen, node); @@ -37,7 +37,7 @@ describe("compileNumericLiteral", function() { expect(checkInstructions(insns, expected)).to.be.true; }); - it("Infinity", function() { + it("Infinity", function () { let pandaGen = new PandaGen("ignored", 0, undefined); let node: ts.NumericLiteral = ts.createNumericLiteral("10e10000"); compileNumericLiteral(pandaGen, node); @@ -45,7 +45,7 @@ describe("compileNumericLiteral", function() { let expected = [new LdaDyn(new VReg())]; expect(checkInstructions(insns, expected)).to.be.true; }); - it("int", function() { + it("int", function () { let pandaGen = new PandaGen("ignored", 0, undefined); let node: ts.NumericLiteral = ts.createNumericLiteral("1"); compileNumericLiteral(pandaGen, node); @@ -53,7 +53,7 @@ describe("compileNumericLiteral", function() { let expected = [new LdaiDyn(new Imm(ResultType.Int, 1))]; expect(checkInstructions(insns, expected)).to.be.true; }); - it("Integer overflow", function() { + it("Integer overflow", function () { let pandaGen = new PandaGen("ignored", 0, undefined); let node: ts.NumericLiteral = ts.createNumericLiteral("2147483648"); compileNumericLiteral(pandaGen, node); @@ -61,7 +61,7 @@ describe("compileNumericLiteral", function() { let expected = [new FldaiDyn(new Imm(ResultType.Float, 2147483648))]; expect(checkInstructions(insns, expected)).to.be.true; }); - it("double", function() { + it("double", function () { let pandaGen = new PandaGen("ignored", 0, undefined); let node: ts.NumericLiteral = ts.createNumericLiteral("1.1"); compileNumericLiteral(pandaGen, node); diff --git a/ts2panda/tests/expression/operationEqual.test.ts b/ts2panda/tests/expression/operationEqual.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..64dfb2fadf762dc5640a6532a3e4e4cdc9f92c92 --- /dev/null +++ b/ts2panda/tests/expression/operationEqual.test.ts @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + expect +} from 'chai'; +import 'mocha'; +import { + EcmaAdd2dyn, + EcmaAshr2dyn, + EcmaDiv2dyn, + EcmaExpdyn, + EcmaMod2dyn, + EcmaMul2dyn, + EcmaReturnundefined, + EcmaShl2dyn, + EcmaShr2dyn, + EcmaStlettoglobalrecord, + EcmaSub2dyn, + EcmaTryldglobalbyname, + EcmaTrystglobalbyname, + Imm, + LdaiDyn, + ResultType, + StaDyn, + VReg +} from "../../src/irnodes"; +import { checkInstructions, compileMainSnippet } from "../utils/base"; + +describe("OperationEqualTest", function () { + it("plusEqual", function () { + let insns = compileMainSnippet("let a = 2;\n" + + "a += 3;"); + let lhs = new VReg(); + + let expected = [ + new LdaiDyn(new Imm(ResultType.Int, 2)), + new EcmaStlettoglobalrecord('a'), + new EcmaTryldglobalbyname('a'), + new StaDyn(lhs), + new LdaiDyn(new Imm(ResultType.Int, 3)), + new EcmaAdd2dyn(lhs), + new EcmaTrystglobalbyname('a'), + new EcmaReturnundefined() + ]; + expect(checkInstructions(insns, expected)).to.be.true; + }); + + it("minusEqual", function () { + let insns = compileMainSnippet("let a = 5;\n" + + "a -= 7;"); + let lhs = new VReg(); + + let expected = [ + new LdaiDyn(new Imm(ResultType.Int, 5)), + new EcmaStlettoglobalrecord('a'), + new EcmaTryldglobalbyname('a'), + new StaDyn(lhs), + new LdaiDyn(new Imm(ResultType.Int, 7)), + new EcmaSub2dyn(lhs), + new EcmaTrystglobalbyname('a'), + new EcmaReturnundefined() + ]; + expect(checkInstructions(insns, expected)).to.be.true; + }); + + it("asteriskEqual", function () { + let insns = compileMainSnippet("let a = 2;\n" + + "a *= 4;"); + let lhs = new VReg(); + + let expected = [ + new LdaiDyn(new Imm(ResultType.Int, 2)), + new EcmaStlettoglobalrecord('a'), + new EcmaTryldglobalbyname('a'), + new StaDyn(lhs), + new LdaiDyn(new Imm(ResultType.Int, 4)), + new EcmaMul2dyn(lhs), + new EcmaTrystglobalbyname('a'), + new EcmaReturnundefined() + ]; + expect(checkInstructions(insns, expected)).to.be.true; + }); + + it("AsteriskAsteriskEqualsToken", function () { + let insns = compileMainSnippet("let a = 2;\n" + + "a **= 3;"); + let lhs = new VReg(); + + let expected = [ + new LdaiDyn(new Imm(ResultType.Int, 2)), + new EcmaStlettoglobalrecord('a'), + new EcmaTryldglobalbyname('a'), + new StaDyn(lhs), + new LdaiDyn(new Imm(ResultType.Int, 3)), + new EcmaExpdyn(lhs), + new EcmaTrystglobalbyname('a'), + new EcmaReturnundefined() + ] + expect(checkInstructions(insns, expected)).to.be.true; + }); + + it("slashEqual", function () { + let insns = compileMainSnippet("let a = 5;\n" + + "a /= 3;"); + let lhs = new VReg(); + + let expected = [ + new LdaiDyn(new Imm(ResultType.Int, 5)), + new EcmaStlettoglobalrecord('a'), + new EcmaTryldglobalbyname('a'), + new StaDyn(lhs), + new LdaiDyn(new Imm(ResultType.Int, 3)), + new EcmaDiv2dyn(lhs), + new EcmaTrystglobalbyname('a'), + new EcmaReturnundefined() + ]; + expect(checkInstructions(insns, expected)).to.be.true; + }); + + it("percentEqual", function () { + let insns = compileMainSnippet("let a = 15;\n" + + "a %= 7;"); + let lhs = new VReg(); + + let expected = [ + new LdaiDyn(new Imm(ResultType.Int, 15)), + new EcmaStlettoglobalrecord('a'), + new EcmaTryldglobalbyname('a'), + new StaDyn(lhs), + new LdaiDyn(new Imm(ResultType.Int, 7)), + new EcmaMod2dyn(lhs), + new EcmaTrystglobalbyname('a'), + new EcmaReturnundefined() + ]; + expect(checkInstructions(insns, expected)).to.be.true; + }); + + it("lessThanLessThanEqual", function () { + let insns = compileMainSnippet("let a = 8;\n" + + "a <<= 3;"); + let lhs = new VReg(); + + let expected = [ + new LdaiDyn(new Imm(ResultType.Int, 8)), + new EcmaStlettoglobalrecord('a'), + new EcmaTryldglobalbyname('a'), + new StaDyn(lhs), + new LdaiDyn(new Imm(ResultType.Int, 3)), + new EcmaShl2dyn(lhs), + new EcmaTrystglobalbyname('a'), + new EcmaReturnundefined() + ]; + expect(checkInstructions(insns, expected)).to.be.true; + }); + + it("greaterThanGreaterThanEqual", function () { + let insns = compileMainSnippet("let a = 4;\n" + + "a >>= 1;"); + let lhs = new VReg(); + + let expected = [ + new LdaiDyn(new Imm(ResultType.Int, 4)), + new EcmaStlettoglobalrecord('a'), + new EcmaTryldglobalbyname('a'), + new StaDyn(lhs), + new LdaiDyn(new Imm(ResultType.Int, 1)), + new EcmaShr2dyn(lhs), + new EcmaTrystglobalbyname('a'), + new EcmaReturnundefined() + ]; + expect(checkInstructions(insns, expected)).to.be.true; + }); + + it("greaterThanGreaterThanGreaterThanEqual", function () { + let insns = compileMainSnippet("let a = 8;\n" + + "a >>>= 2;"); + let lhs = new VReg(); + + let expected = [ + new LdaiDyn(new Imm(ResultType.Int, 8)), + new EcmaStlettoglobalrecord('a'), + new EcmaTryldglobalbyname('a'), + new StaDyn(lhs), + new LdaiDyn(new Imm(ResultType.Int, 2)), + new EcmaAshr2dyn(lhs), + new EcmaTrystglobalbyname('a'), + new EcmaReturnundefined() + ]; + expect(checkInstructions(insns, expected)).to.be.true; + }); +}); diff --git a/ts2panda/tests/expression/parenthesized.test.ts b/ts2panda/tests/expression/parenthesized.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..370d10e7513d809b564a4454704fa500aa7ea80d --- /dev/null +++ b/ts2panda/tests/expression/parenthesized.test.ts @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + expect +} from 'chai'; +import 'mocha'; +import { + EcmaReturnundefined, + EcmaStlettoglobalrecord, + EcmaTryldglobalbyname, + LdaDyn, + VReg +} from "../../src/irnodes"; +import { checkInstructions, compileMainSnippet } from "../utils/base"; + +describe("ParenthesizedExpressionTest", function () { + it("(a)", function () { + let insns = compileMainSnippet("let a; (a);"); + let a = new VReg(); + let expected = [ + new LdaDyn(new VReg()), + new EcmaStlettoglobalrecord('a'), + new EcmaTryldglobalbyname('a'), + new EcmaReturnundefined() + ]; + expect(checkInstructions(insns, expected)).to.be.true; + }); + + it("(((a)))", function () { + let insns = compileMainSnippet("let a; (((a)))"); + let a = new VReg(); + let expected = [ + new LdaDyn(new VReg()), + new EcmaStlettoglobalrecord('a'), + new EcmaTryldglobalbyname('a'), + new EcmaReturnundefined() + ]; + expect(checkInstructions(insns, expected)).to.be.true; + }); +}); \ No newline at end of file diff --git a/ts2panda/tests/expression/postfixOperations.test.ts b/ts2panda/tests/expression/postfixOperations.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..df76e7bc4713a6aef7618ad2756d750e5500ebea --- /dev/null +++ b/ts2panda/tests/expression/postfixOperations.test.ts @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + expect +} from 'chai'; +import 'mocha'; +import { + EcmaDecdyn, + EcmaIncdyn, + EcmaReturnundefined, + EcmaStlettoglobalrecord, + EcmaTonumber, + EcmaTryldglobalbyname, + EcmaTrystglobalbyname, + Imm, + LdaiDyn, + ResultType, + StaDyn, + VReg +} from "../../src/irnodes"; +import { checkInstructions, compileMainSnippet } from "../utils/base"; + +describe("PostfixOperationsTest", function () { + it("let i = 0; i++", function () { + let insns = compileMainSnippet("let i = 5; i++"); + let i = new VReg(); + let temp = new VReg(); + let expected = [ + new LdaiDyn(new Imm(ResultType.Int, 5)), + new EcmaStlettoglobalrecord('i'), + new EcmaTryldglobalbyname('i'), + new StaDyn(temp), + new EcmaIncdyn(temp), + new EcmaTrystglobalbyname('i'), + new EcmaTonumber(i), + new EcmaReturnundefined() + ]; + expect(checkInstructions(insns, expected)).to.be.true; + }); + + it("let i = 0; i--", function () { + let insns = compileMainSnippet("let i = 5; i--"); + let i = new VReg(); + let temp = new VReg(); + let expected = [ + new LdaiDyn(new Imm(ResultType.Int, 5)), + new EcmaStlettoglobalrecord('i'), + new EcmaTryldglobalbyname('i'), + new StaDyn(temp), + new EcmaDecdyn(temp), + new EcmaTrystglobalbyname('i'), + new EcmaTonumber(i), + new EcmaReturnundefined() + ]; + expect(checkInstructions(insns, expected)).to.be.true; + }); +}); + + diff --git a/ts2panda/tests/expression/prefixOperations.test.ts b/ts2panda/tests/expression/prefixOperations.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..67f70a550c02fbf6b8dca64f5626341238864fc9 --- /dev/null +++ b/ts2panda/tests/expression/prefixOperations.test.ts @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + expect +} from 'chai'; +import 'mocha'; +import { + EcmaDecdyn, + EcmaIncdyn, + EcmaIstrue, + EcmaNegdyn, + EcmaNotdyn, + EcmaReturnundefined, + EcmaStlettoglobalrecord, + EcmaTonumber, + EcmaTryldglobalbyname, + EcmaTrystglobalbyname, + Imm, + Jeqz, + Jmp, + Label, + LdaDyn, + LdaiDyn, ResultType, StaDyn, VReg +} from "../../src/irnodes"; +import { checkInstructions, compileMainSnippet } from "../utils/base"; + +describe("PrefixOperationsTest", function () { + it('let i = 5; ++i', function () { + let insns = compileMainSnippet("let i = 5; let j = ++i"); + + let temp = new VReg(); + + let expected = [ + new LdaiDyn(new Imm(ResultType.Int, 5)), + new EcmaStlettoglobalrecord('i'), + new EcmaTryldglobalbyname('i'), + new StaDyn(temp), + new EcmaIncdyn(temp), + new EcmaTrystglobalbyname('i'), + new EcmaStlettoglobalrecord('j'), + new EcmaReturnundefined() + ]; + + expect(checkInstructions(insns, expected)).to.be.true; + }); + + it('let i = 5; --i', function () { + let insns = compileMainSnippet("let i = 5; let j = --i"); + + let temp = new VReg(); + + let expected = [ + new LdaiDyn(new Imm(ResultType.Int, 5)), + new EcmaStlettoglobalrecord('i'), + new EcmaTryldglobalbyname('i'), + new StaDyn(temp), + new EcmaDecdyn(temp), + new EcmaTrystglobalbyname('i'), + new EcmaStlettoglobalrecord('j'), + new EcmaReturnundefined() + ]; + + expect(checkInstructions(insns, expected)).to.be.true; + }); + + it('let i = 5; let j = +i', function () { + let insns = compileMainSnippet("let i = 5; let j = +i"); + + let temp = new VReg(); + + let expected = [ + new LdaiDyn(new Imm(ResultType.Int, 5)), + new EcmaStlettoglobalrecord('i'), + new EcmaTryldglobalbyname('i'), + new StaDyn(temp), + new EcmaTonumber(temp), + new EcmaStlettoglobalrecord('j'), + new EcmaReturnundefined() + ]; + + expect(checkInstructions(insns, expected)).to.be.true; + }); + + it('let i = 5; let j = -i', function () { + let insns = compileMainSnippet("let i = 5; let j = -i"); + + let temp = new VReg(); + + let expected = [ + new LdaiDyn(new Imm(ResultType.Int, 5)), + new EcmaStlettoglobalrecord('i'), + new EcmaTryldglobalbyname('i'), + new StaDyn(temp), + new EcmaNegdyn(temp), + new EcmaStlettoglobalrecord('j'), + new EcmaReturnundefined() + ]; + + expect(checkInstructions(insns, expected)).to.be.true; + }); + + it('let i = 5; let j = !i', function () { + let insns = compileMainSnippet("let i = 5; let j = !i"); + + let preLabel = new Label(); + let postLabel = new Label(); + let expected = [ + new LdaiDyn(new Imm(ResultType.Int, 5)), + new EcmaStlettoglobalrecord('i'), + new EcmaTryldglobalbyname('i'), + new StaDyn(new VReg()), + new EcmaIstrue(), + new Jeqz(preLabel), + new LdaDyn(new VReg()), + new Jmp(postLabel), + preLabel, + new LdaDyn(new VReg()), + postLabel, + new EcmaStlettoglobalrecord('j'), + new EcmaReturnundefined() + ]; + expect(checkInstructions(insns, expected)).to.be.true; + }); + + it('let i = 5; let j = ~i', function () { + let insns = compileMainSnippet("let i = 5; let j = ~i"); + + let temp_i = new VReg(); + + let expected = [ + new LdaiDyn(new Imm(ResultType.Int, 5)), + new EcmaStlettoglobalrecord('i'), + new EcmaTryldglobalbyname('i'), + new StaDyn(temp_i), + new EcmaNotdyn(temp_i), + new EcmaStlettoglobalrecord('j'), + new EcmaReturnundefined() + ]; + + expect(checkInstructions(insns, expected)).to.be.true; + }); +}); \ No newline at end of file diff --git a/ts2panda/tests/propertyAccess.test.ts b/ts2panda/tests/expression/propertyAccess.test.ts similarity index 74% rename from ts2panda/tests/propertyAccess.test.ts rename to ts2panda/tests/expression/propertyAccess.test.ts index 541081e8ec93cc0d20e15eb691fef3da017bd848..f63f03003ca04eb641482c26644178d9c239fd3c 100644 --- a/ts2panda/tests/propertyAccess.test.ts +++ b/ts2panda/tests/expression/propertyAccess.test.ts @@ -18,58 +18,59 @@ import { } from 'chai'; import 'mocha'; import { - CreateObjectWithBuffer, - DefineMethod, - DefineGetterSetterByValue, + EcmaCreateobjectwithbuffer, + EcmaDefinegettersetterbyvalue, + EcmaDefinemethod, + EcmaLdobjbyname, + EcmaStobjbyname, + EcmaTryldglobalbyname, Imm, LdaDyn, LdaiDyn, LdaStr, - LdObjByName, MovDyn, ResultType, StaDyn, - StObjByName, VReg -} from "../src/irnodes"; -import { checkInstructions, compileAllSnippet, compileMainSnippet } from "./utils/base"; +} from "../../src/irnodes"; +import { checkInstructions, compileAllSnippet, compileMainSnippet } from "../utils/base"; -describe("PropertyAccess", function() { - it('get obj.property', function() { +describe("PropertyAccess", function () { + it('get obj.property', function () { let insns = compileMainSnippet(`let obj; obj.property;`); let objReg = new VReg(); let expected = [ - new LdaDyn(objReg), + new EcmaTryldglobalbyname('obj'), new StaDyn(objReg), - new LdObjByName("property", objReg) + new EcmaLdobjbyname("property", objReg) ]; insns = insns.slice(2, insns.length - 1); // cut off let obj and return.dyn expect(checkInstructions(insns, expected)).to.be.true; }); - it('set obj.property', function() { + it('set obj.property', function () { let insns = compileMainSnippet(`let obj; obj.property = 0;`); let objReg = new VReg(); let tempObj = new VReg(); let expected = [ - new LdaDyn(objReg), + new EcmaTryldglobalbyname('obj'), new StaDyn(tempObj), new MovDyn(objReg, tempObj), new LdaiDyn(new Imm(ResultType.Int, 0)), - new StObjByName("property", objReg), + new EcmaStobjbyname("property", objReg), ]; insns = insns.slice(2, insns.length - 1); // cut off let obj and return.dyn expect(checkInstructions(insns, expected)).to.be.true; }); - it('SetAccessor', function() { + it('SetAccessor', function () { let compilerunit = compileAllSnippet(` let obj = { set myMethod (arg) { @@ -82,15 +83,15 @@ describe("PropertyAccess", function() { let propReg = new VReg(); let expected = [ - new CreateObjectWithBuffer(new Imm(ResultType.Int, 0)), + new EcmaCreateobjectwithbuffer(new Imm(ResultType.Int, 0)), new StaDyn(objInstance), new LdaDyn(new VReg()), - new DefineMethod("func_myMethod_1", new VReg()), + new EcmaDefinemethod("myMethod", new Imm(ResultType.Int, 1), new VReg()), new StaDyn(funcReg), new LdaStr("myMethod"), new StaDyn(propReg), new LdaDyn(new VReg()), - new DefineGetterSetterByValue(objInstance, propReg, new VReg(), funcReg), + new EcmaDefinegettersetterbyvalue(objInstance, propReg, new VReg(), funcReg), ]; compilerunit.forEach(element => { @@ -101,14 +102,14 @@ describe("PropertyAccess", function() { expect(checkInstructions(insns, expected)).to.be.true; } - if (element.internalName == "func_myMethod_1") { + if (element.internalName == "myMethod") { let parameterLength = element.getParameterLength(); expect(parameterLength == 1).to.be.true; } }); }); - it('GetAccessor', function() { + it('GetAccessor', function () { let compilerunit = compileAllSnippet(` let obj = { get a() { return 'a'; }; @@ -119,15 +120,15 @@ describe("PropertyAccess", function() { let propReg = new VReg(); let expected = [ - new CreateObjectWithBuffer(new Imm(ResultType.Int, 0)), + new EcmaCreateobjectwithbuffer(new Imm(ResultType.Int, 0)), new StaDyn(objInstance), new LdaDyn(new VReg()), - new DefineMethod("func_a_1", new VReg()), + new EcmaDefinemethod("a", new Imm(ResultType.Int, 0), new VReg()), new StaDyn(funcReg), new LdaStr("a"), new StaDyn(propReg), new LdaDyn(new VReg()), - new DefineGetterSetterByValue(objInstance, propReg, funcReg, new VReg()), + new EcmaDefinegettersetterbyvalue(objInstance, propReg, funcReg, new VReg()), ]; compilerunit.forEach(element => { @@ -140,7 +141,7 @@ describe("PropertyAccess", function() { }); }); - it('GetAccessor&SetAccessor', function() { + it('GetAccessor&SetAccessor', function () { let compilerunit = compileAllSnippet(`let obj = { get a() { return 'a'; }, set a(x) {} @@ -152,18 +153,18 @@ describe("PropertyAccess", function() { let propReg = new VReg(); let expected = [ - new CreateObjectWithBuffer(new Imm(ResultType.Int, 0)), + new EcmaCreateobjectwithbuffer(new Imm(ResultType.Int, 0)), new StaDyn(objInstance), new LdaDyn(new VReg()), - new DefineMethod("func_a_1", new VReg()), + new EcmaDefinemethod("#1#a", new Imm(ResultType.Int, 0), new VReg()), new StaDyn(getterReg), new LdaDyn(new VReg()), - new DefineMethod("func_a_2", new VReg()), + new EcmaDefinemethod("#2#a", new Imm(ResultType.Int, 1), new VReg()), new StaDyn(setterReg), new LdaStr("a"), new StaDyn(propReg), new LdaDyn(new VReg()), - new DefineGetterSetterByValue(objInstance, propReg, getterReg, setterReg), + new EcmaDefinegettersetterbyvalue(objInstance, propReg, getterReg, setterReg), ]; compilerunit.forEach(element => { diff --git a/ts2panda/tests/expression/regular.test.js b/ts2panda/tests/expression/regular.test.js new file mode 100644 index 0000000000000000000000000000000000000000..22a0dc7e28c91d217d5c36ab1f2d24d4d60677bc --- /dev/null +++ b/ts2panda/tests/expression/regular.test.js @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + expect +} from 'chai'; +import 'mocha'; +import { + EcmaCreateregexpwithliteral, + EcmaStlettoglobalrecord, + Imm, + ResultType +} from "../../src/irnodes"; +import { checkInstructions, compileMainSnippet } from "../utils/base"; + +describe("Regular Expression", function () { + it("let a = /abc/;", function () { + let insns = compileMainSnippet("let a = /abc/;"); + insns = insns.slice(0, insns.length - 1); + + let expected = [ + new EcmaCreateregexpwithliteral("abc", new Imm(ResultType.Int, 0)), + new EcmaStlettoglobalrecord('a') + ]; + expect(checkInstructions(insns, expected)).to.be.true; + }); + + it("let a = /abc/i;", function () { + let insns = compileMainSnippet("let a = /abc/i;"); + insns = insns.slice(0, insns.length - 1); + + let expected = [ + new EcmaCreateregexpwithliteral("abc", new Imm(ResultType.Int, 2)), + new EcmaStlettoglobalrecord('a') + ]; + expect(checkInstructions(insns, expected)).to.be.true; + }); +}); \ No newline at end of file diff --git a/ts2panda/tests/expression/stringLiteral.test.ts b/ts2panda/tests/expression/stringLiteral.test.ts index b926af8e466a645db1e3d046ebcd62525762cac4..cf56ba16dcb6661a287f3ab30e20858de80455e1 100755 --- a/ts2panda/tests/expression/stringLiteral.test.ts +++ b/ts2panda/tests/expression/stringLiteral.test.ts @@ -22,8 +22,8 @@ import { import { PandaGen } from "../../src/pandagen"; import { checkInstructions } from "../utils/base"; -describe("compileStringLiteral", function() { - it("i am a string", function() { +describe("compileStringLiteral", function () { + it("i am a string", function () { let pandaGen = new PandaGen("ignored", 0, undefined); let node: ts.StringLiteral = ts.createStringLiteral("i am a string"); compileStringLiteral(pandaGen, node); diff --git a/ts2panda/tests/expression/TemplateExpression.test.ts b/ts2panda/tests/expression/templateExpression.test.ts similarity index 70% rename from ts2panda/tests/expression/TemplateExpression.test.ts rename to ts2panda/tests/expression/templateExpression.test.ts index eb892c835f5b21e0b087f2c2092a32c299a79bdd..5654375b5f4b6f3b550ac4878bc8f21d5dc7fadb 100755 --- a/ts2panda/tests/expression/TemplateExpression.test.ts +++ b/ts2panda/tests/expression/templateExpression.test.ts @@ -18,22 +18,22 @@ import { } from 'chai'; import 'mocha'; import { - Add2Dyn, - CalliThisRangeDyn, - GetTemplateObject, + EcmaAdd2dyn, + EcmaCallithisrangedyn, + EcmaCreateemptyarray, + EcmaGettemplateobject, + EcmaLdobjbyname, + EcmaReturnundefined, + EcmaStobjbyvalue, + EcmaTryldglobalbyname, Imm, IRNode, LdaDyn, LdaiDyn, LdaStr, - LdObjByName, MovDyn, ResultType, - ReturnUndefined, StaDyn, - StObjByValue, - TryLdGlobalByName, - CreateEmptyArray, VReg } from "../../src/irnodes"; import { checkInstructions, compileMainSnippet } from "../utils/base"; @@ -45,7 +45,7 @@ function MicroCreateAddInsns(leftVal: number, rightVal: number): IRNode[] { insns.push(new LdaiDyn(new Imm(ResultType.Int, leftVal))); insns.push(new StaDyn(lhs)); insns.push(new LdaiDyn(new Imm(ResultType.Int, rightVal))); - insns.push(new Add2Dyn(lhs)); + insns.push(new EcmaAdd2dyn(lhs)); return insns; } @@ -55,9 +55,9 @@ function MicroCreateObjAndPropInsns(): IRNode[] { let obj = new VReg(); let val = new VReg(); - insns.push(new TryLdGlobalByName("String")); + insns.push(new EcmaTryldglobalbyname("String")); insns.push(new StaDyn(obj)); - insns.push(new LdObjByName("raw", obj)); + insns.push(new EcmaLdobjbyname("raw", obj)); insns.push(new StaDyn(val)); return insns; @@ -68,33 +68,33 @@ function MicroGetTemplateObject(rawArr: VReg, cookedArr: VReg): IRNode[] { let objReg = new VReg(); let indexReg = new VReg(); - insns.push(new CreateEmptyArray()); + insns.push(new EcmaCreateemptyarray()); insns.push(new StaDyn(objReg)); insns.push(new LdaiDyn(new Imm(ResultType.Int, 0))); insns.push(new StaDyn(indexReg)); insns.push(new LdaDyn(rawArr)); - insns.push(new StObjByValue(objReg,indexReg)); + insns.push(new EcmaStobjbyvalue(objReg, indexReg)); insns.push(new LdaiDyn(new Imm(ResultType.Int, 1))); insns.push(new StaDyn(indexReg)); insns.push(new LdaDyn(cookedArr)); - insns.push(new StObjByValue(objReg,indexReg)); - insns.push(new GetTemplateObject(objReg)); + insns.push(new EcmaStobjbyvalue(objReg, indexReg)); + insns.push(new EcmaGettemplateobject(objReg)); return insns; } -describe("templateExpressionTest", function() { - it("`string text line 1`", function() { +describe("templateExpressionTest", function () { + it("`string text line 1`", function () { let insns = compileMainSnippet("`string text line 1`;"); let expected = [ new LdaStr("string text line 1"), - new ReturnUndefined() + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; }); - it("`Fifteen is ${5 + 10}`", function() { + it("`Fifteen is ${5 + 10}`", function () { let insns = compileMainSnippet("`Fifteen is ${5 + 10}`"); let headVal = new VReg(); @@ -102,13 +102,13 @@ describe("templateExpressionTest", function() { new LdaStr("Fifteen is "), new StaDyn(headVal), ...MicroCreateAddInsns(5, 10), - new Add2Dyn(headVal), - new ReturnUndefined() + new EcmaAdd2dyn(headVal), + new EcmaReturnundefined() ] expect(checkInstructions(insns, expected)).to.be.true; }); - it("String.raw`string text line 1`", function() { + it("String.raw`string text line 1`", function () { let insns = compileMainSnippet("String.raw`string text line 1`;"); let obj = new VReg(); let prop = new VReg(); @@ -122,34 +122,34 @@ describe("templateExpressionTest", function() { let expected = [ ...MicroCreateObjAndPropInsns(), - new CreateEmptyArray(), + new EcmaCreateemptyarray(), new StaDyn(rawArr), - new CreateEmptyArray(), + new EcmaCreateemptyarray(), new StaDyn(cookedArr), new LdaiDyn(new Imm(ResultType.Int, 0)), new StaDyn(elemIdxReg), new LdaStr("string text line 1"), - new StObjByValue(rawArr, elemIdxReg), + new EcmaStobjbyvalue(rawArr, elemIdxReg), new LdaStr("string text line 1"), - new StObjByValue(cookedArr, elemIdxReg), - new MovDyn(rawArr1,rawArr), - new MovDyn(cookedArr1,cookedArr), + new EcmaStobjbyvalue(cookedArr, elemIdxReg), + new MovDyn(rawArr1, rawArr), + new MovDyn(cookedArr1, cookedArr), ...MicroGetTemplateObject(rawArr1, cookedArr), new StaDyn(templateObj), // structure call - new CalliThisRangeDyn(new Imm(ResultType.Int, 2), [prop, obj, templateObj]), + new EcmaCallithisrangedyn(new Imm(ResultType.Int, 2), [prop, obj, templateObj]), - new ReturnUndefined() + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; }); - it("String.raw`string text line 1\\nstring text line 2`", function() { + it("String.raw`string text line 1\\nstring text line 2`", function () { let insns = compileMainSnippet("String.raw`string text line 1\\nstring text line 2`;"); let obj = new VReg(); let prop = new VReg(); @@ -163,34 +163,34 @@ describe("templateExpressionTest", function() { let expected = [ ...MicroCreateObjAndPropInsns(), - new CreateEmptyArray(), + new EcmaCreateemptyarray(), new StaDyn(rawArr), - new CreateEmptyArray(), + new EcmaCreateemptyarray(), new StaDyn(cookedArr), new LdaiDyn(new Imm(ResultType.Int, 0)), new StaDyn(elemIdxReg), new LdaStr("string text line 1\\nstring text line 2"), - new StObjByValue(rawArr, elemIdxReg), + new EcmaStobjbyvalue(rawArr, elemIdxReg), new LdaStr("string text line 1\nstring text line 2"), - new StObjByValue(cookedArr, elemIdxReg), - new MovDyn(rawArr1,rawArr), - new MovDyn(cookedArr1,cookedArr), + new EcmaStobjbyvalue(cookedArr, elemIdxReg), + new MovDyn(rawArr1, rawArr), + new MovDyn(cookedArr1, cookedArr), ...MicroGetTemplateObject(rawArr1, cookedArr1), new StaDyn(templateObj), // structure call - new CalliThisRangeDyn(new Imm(ResultType.Int, 2), [prop, obj, templateObj]), + new EcmaCallithisrangedyn(new Imm(ResultType.Int, 2), [prop, obj, templateObj]), - new ReturnUndefined() + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; }); - it("String.raw`Fifteen is ${5 + 10} !!`", function() { + it("String.raw`Fifteen is ${5 + 10} !!`", function () { let insns = compileMainSnippet("String.raw`Fifteen is ${5 + 10} !!`"); let obj = new VReg(); let prop = new VReg(); @@ -205,25 +205,25 @@ describe("templateExpressionTest", function() { let expected = [ ...MicroCreateObjAndPropInsns(), - new CreateEmptyArray(), + new EcmaCreateemptyarray(), new StaDyn(rawArr), - new CreateEmptyArray(), + new EcmaCreateemptyarray(), new StaDyn(cookedArr), new LdaiDyn(new Imm(ResultType.Int, 0)), new StaDyn(elemIdxReg), new LdaStr("Fifteen is "), - new StObjByValue(rawArr, elemIdxReg), + new EcmaStobjbyvalue(rawArr, elemIdxReg), new LdaStr("Fifteen is "), - new StObjByValue(cookedArr, elemIdxReg), + new EcmaStobjbyvalue(cookedArr, elemIdxReg), new LdaiDyn(new Imm(ResultType.Int, 1)), new StaDyn(elemIdxReg), new LdaStr(" !!"), - new StObjByValue(rawArr, elemIdxReg), + new EcmaStobjbyvalue(rawArr, elemIdxReg), new LdaStr(" !!"), - new StObjByValue(cookedArr, elemIdxReg), - new MovDyn(rawArr1,rawArr), - new MovDyn(cookedArr1,cookedArr), + new EcmaStobjbyvalue(cookedArr, elemIdxReg), + new MovDyn(rawArr1, rawArr), + new MovDyn(cookedArr1, cookedArr), ...MicroGetTemplateObject(rawArr1, cookedArr1), new StaDyn(templateObj), @@ -232,13 +232,13 @@ describe("templateExpressionTest", function() { new StaDyn(addRet), // structure call - new CalliThisRangeDyn(new Imm(ResultType.Int, 3), [prop, obj, rawArr, templateObj]), - new ReturnUndefined() + new EcmaCallithisrangedyn(new Imm(ResultType.Int, 3), [prop, obj, rawArr, templateObj]), + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; }); - it("String.raw`Fifteen is ${5 + 10} !!\\n Is not ${15 + 10} !!!`", function() { + it("String.raw`Fifteen is ${5 + 10} !!\\n Is not ${15 + 10} !!!`", function () { let insns = compileMainSnippet("String.raw`Fifteen is ${5 + 10} !!\\n Is not ${15 + 10} !!!\\n`"); let obj = new VReg(); let val = new VReg(); @@ -255,32 +255,32 @@ describe("templateExpressionTest", function() { let expected = [ ...MicroCreateObjAndPropInsns(), - new CreateEmptyArray(), + new EcmaCreateemptyarray(), new StaDyn(rawArr), - new CreateEmptyArray(), + new EcmaCreateemptyarray(), new StaDyn(cookedArr), new LdaiDyn(new Imm(ResultType.Int, 0)), new StaDyn(elemIdxReg), new LdaStr("Fifteen is "), - new StObjByValue(rawArr, elemIdxReg), + new EcmaStobjbyvalue(rawArr, elemIdxReg), new LdaStr("Fifteen is "), - new StObjByValue(cookedArr, elemIdxReg), + new EcmaStobjbyvalue(cookedArr, elemIdxReg), new LdaiDyn(new Imm(ResultType.Int, 1)), new StaDyn(elemIdxReg), new LdaStr(" !!\\n Is not "), - new StObjByValue(rawArr, elemIdxReg), + new EcmaStobjbyvalue(rawArr, elemIdxReg), new LdaStr(" !!\n Is not "), - new StObjByValue(cookedArr, elemIdxReg), + new EcmaStobjbyvalue(cookedArr, elemIdxReg), new LdaiDyn(new Imm(ResultType.Int, 2)), new StaDyn(elemIdxReg), new LdaStr(" !!!\\n"), - new StObjByValue(rawArr, elemIdxReg), + new EcmaStobjbyvalue(rawArr, elemIdxReg), new LdaStr(" !!!\n"), - new StObjByValue(cookedArr, elemIdxReg), - new MovDyn(rawArr1,rawArr), - new MovDyn(cookedArr1,cookedArr), - + new EcmaStobjbyvalue(cookedArr, elemIdxReg), + new MovDyn(rawArr1, rawArr), + new MovDyn(cookedArr1, cookedArr), + ...MicroGetTemplateObject(rawArr1, cookedArr1), new StaDyn(templateObj), @@ -290,8 +290,8 @@ describe("templateExpressionTest", function() { new StaDyn(addRet2), // structure call - new CalliThisRangeDyn(new Imm(ResultType.Int, 4), [prop, obj, rawArr, cookedArr, templateObj]), - new ReturnUndefined() + new EcmaCallithisrangedyn(new Imm(ResultType.Int, 4), [prop, obj, rawArr, cookedArr, templateObj]), + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; }); diff --git a/ts2panda/tests/otherExpressions.test.ts b/ts2panda/tests/expression/thisKeyWord.test.ts similarity index 41% rename from ts2panda/tests/otherExpressions.test.ts rename to ts2panda/tests/expression/thisKeyWord.test.ts index 95e69ebc3e24815bdc5eeaee6f66140b0cb7009a..186c2d2b94ee0fb304e09678151a00e546a450b1 100644 --- a/ts2panda/tests/otherExpressions.test.ts +++ b/ts2panda/tests/expression/thisKeyWord.test.ts @@ -1,143 +1,65 @@ -/* - * Copyright (c) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { - expect -} from 'chai'; -import 'mocha'; -import { - GetUnmappedArgs, - Imm, - LdaDyn, - LdaiDyn, - LdObjByIndex, - ResultType, - ReturnUndefined, - StaDyn, - VReg -} from "../src/irnodes"; -import { PandaGen } from "../src/pandagen"; -import { LocalVariable } from "../src/variable"; -import { checkInstructions, compileMainSnippet, SnippetCompiler } from "./utils/base"; - -describe("ParenthesizedExpressionTest", function () { - it("(a)", function () { - let insns = compileMainSnippet("let a; (a);"); - let a = new VReg(); - let expected = [ - new LdaDyn(new VReg()), - new StaDyn(a), - new LdaDyn(a), - new ReturnUndefined() - ]; - expect(checkInstructions(insns, expected)).to.be.true; - }); - - it("(((a)))", function () { - let insns = compileMainSnippet("let a; (((a)))"); - let a = new VReg(); - let expected = [ - new LdaDyn(new VReg()), - new StaDyn(a), - new LdaDyn(a), - new ReturnUndefined() - ]; - expect(checkInstructions(insns, expected)).to.be.true; - }); -}); - -describe("ThisKeyword", function () { - let pandaGen: PandaGen; - - beforeEach(function () { - pandaGen = new PandaGen("" /* internalName */, 0 /* number of parameters */); - }); - - it("this in global scope", function () { - let snippetCompiler = new SnippetCompiler(); - snippetCompiler.compile("this"); - let globalScope = snippetCompiler.getGlobalScope(); - let insns = snippetCompiler.getGlobalInsns(); - let expected = [ - new LdaDyn(new VReg()), - new ReturnUndefined() - ]; - expect(checkInstructions(insns, expected)).to.be.true; - let thisVar = globalScope!.findLocal("this"); - expect(thisVar instanceof LocalVariable).to.be.true; - }); - - it("this in function scope", function () { - let snippetCompiler = new SnippetCompiler(); - snippetCompiler.compile("function a() {this}"); - let functionPg = snippetCompiler.getPandaGenByName("func_a_1"); - let functionScope = functionPg!.getScope(); - let insns = compileMainSnippet("this;", pandaGen, functionScope); - let expected = [ - new LdaDyn(new VReg()), - new ReturnUndefined() - ]; - expect(checkInstructions(insns, expected)).to.be.true; - let thisVar = functionScope!.findLocal("this"); - expect(thisVar != undefined).to.be.true; - expect(thisVar instanceof LocalVariable).to.be.true; - }); -}); - -describe("arguments Keyword", function () { - it('arguments: Array-like object accessible inside functions', function () { - let snippetCompiler = new SnippetCompiler(); - snippetCompiler.compile(`function foo(a,b) {arguments[0];}`); - let argumentsReg = new VReg(); - let temp1 = new VReg(); - let indexReg = new VReg(); - let expected = [ - new GetUnmappedArgs(), - new StaDyn(argumentsReg), - new LdaDyn(argumentsReg), - new StaDyn(temp1), - new LdaiDyn(new Imm(ResultType.Int, 0)), - new StaDyn(indexReg), - new LdObjByIndex(temp1, indexReg), - new ReturnUndefined() - ]; - let functionPg = snippetCompiler.getPandaGenByName("func_foo_1"); - let insns = functionPg!.getInsns(); - - expect(checkInstructions(insns, expected)).to.be.true; - }); - - it('arguments as parameter shadows keyword', function () { - let snippetCompiler = new SnippetCompiler(); - snippetCompiler.compile(`function foo(arguments) {arguments[0];}`); - let parameterArguments = new VReg(); - let temp1 = new VReg(); - let indexReg = new VReg(); - let expected = [ - new GetUnmappedArgs(), - new StaDyn(new VReg()), - new LdaDyn(parameterArguments), - new StaDyn(temp1), - new LdaiDyn(new Imm(ResultType.Int, 0)), - new StaDyn(indexReg), - new LdObjByIndex(temp1, indexReg), - new ReturnUndefined() - ]; - let functionPg = snippetCompiler.getPandaGenByName("func_foo_1"); - let insns = functionPg!.getInsns(); - - expect(checkInstructions(insns, expected)).to.be.true; - }); -}); +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + expect +} from 'chai'; +import 'mocha'; +import { + EcmaReturnundefined, + LdaDyn, + VReg +} from "../../src/irnodes"; +import { PandaGen } from "../../src/pandagen"; +import { LocalVariable } from "../../src/variable"; +import { checkInstructions, compileMainSnippet, SnippetCompiler } from "../utils/base"; + +describe("ThisKeyword", function () { + let pandaGen: PandaGen; + + beforeEach(function () { + pandaGen = new PandaGen("" /* internalName */, 0 /* number of parameters */); + }); + + it("this in global scope", function () { + let snippetCompiler = new SnippetCompiler(); + snippetCompiler.compile("this"); + let globalScope = snippetCompiler.getGlobalScope(); + let insns = snippetCompiler.getGlobalInsns(); + let expected = [ + new LdaDyn(new VReg()), + new EcmaReturnundefined() + ]; + expect(checkInstructions(insns, expected)).to.be.true; + let thisVar = globalScope!.findLocal("this"); + expect(thisVar instanceof LocalVariable).to.be.true; + }); + + it("this in function scope", function () { + let snippetCompiler = new SnippetCompiler(); + snippetCompiler.compile("function a() {this}"); + let functionPg = snippetCompiler.getPandaGenByName("a"); + let functionScope = functionPg!.getScope(); + let insns = compileMainSnippet("this;", pandaGen, functionScope); + let expected = [ + new LdaDyn(new VReg()), + new EcmaReturnundefined() + ]; + expect(checkInstructions(insns, expected)).to.be.true; + let thisVar = functionScope!.findLocal("this"); + expect(thisVar != undefined).to.be.true; + expect(thisVar instanceof LocalVariable).to.be.true; + }); +}); \ No newline at end of file diff --git a/ts2panda/tests/expression/typeOf.test.ts b/ts2panda/tests/expression/typeOf.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..d504d517216e767050184b872da86058b5cac613 --- /dev/null +++ b/ts2panda/tests/expression/typeOf.test.ts @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + expect +} from 'chai'; +import 'mocha'; +import { + EcmaCallarg1dyn, + EcmaLdobjbyname, + EcmaReturnundefined, + EcmaTryldglobalbyname, + EcmaTypeofdyn, + Imm, + LdaiDyn, + LdaStr, + ResultType, + StaDyn, + VReg +} from "../../src/irnodes"; +import { checkInstructions, compileMainSnippet } from "../utils/base"; + +describe("TypeOfTest", function () { + it("typeof 12", function () { + let insns = compileMainSnippet("typeof 5"); + let expected = [ + new LdaiDyn(new Imm(ResultType.Int, 5)), + new EcmaTypeofdyn(), + new EcmaReturnundefined() + ]; + + expect(checkInstructions(insns, expected)).to.be.true; + }); + + it("typeof Number(\"12\")", function () { + let insns = compileMainSnippet("typeof Number(\"5\")"); + let arg1 = new VReg(); + let arg3 = new VReg(); + let expected = [ + new EcmaTryldglobalbyname("Number"), + new StaDyn(arg1), + + new LdaStr("5"), + new StaDyn(arg3), + new EcmaCallarg1dyn(arg1, arg3), + new EcmaTypeofdyn(), + new EcmaReturnundefined() + ]; + + expect(checkInstructions(insns, expected)).to.be.true; + }); + + it("typeof x", function () { + let insns = compileMainSnippet("typeof x"); + + let expected = [ + new EcmaLdobjbyname("x", new VReg()), + new EcmaTypeofdyn(), + new EcmaReturnundefined() + ]; + + expect(checkInstructions(insns, expected)).to.be.true; + }); + + it("typeof(x)", function () { + let insns = compileMainSnippet("typeof(x)"); + + let expected = [ + new EcmaLdobjbyname("x", new VReg()), + new EcmaTypeofdyn(), + new EcmaReturnundefined() + ]; + + expect(checkInstructions(insns, expected)).to.be.true; + }); +}); diff --git a/ts2panda/tests/expression/void.test.ts b/ts2panda/tests/expression/void.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..330849f16c42c742af3546c64df57037520de317 --- /dev/null +++ b/ts2panda/tests/expression/void.test.ts @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + expect +} from 'chai'; +import 'mocha'; +import { + EcmaReturnundefined, + EcmaStlettoglobalrecord, + EcmaTryldglobalbyname, + LdaDyn, + VReg +} from "../../src/irnodes"; +import { checkInstructions, compileMainSnippet } from "../utils/base"; + +describe("voidExpressionTest", function () { + it("void (a)", function () { + let insns = compileMainSnippet("let a; void (a);"); + + let expected = [ + new LdaDyn(new VReg()), + new EcmaStlettoglobalrecord('a'), + new EcmaTryldglobalbyname('a'), + new LdaDyn(new VReg()), + new EcmaReturnundefined() + ]; + expect(checkInstructions(insns, expected)).to.be.true; + }); +}); \ No newline at end of file diff --git a/ts2panda/tests/hoist.test.ts b/ts2panda/tests/hoist.test.ts index bc5d49f7b2934f8bc099e6d5e84f60b013739c6e..1cb0b35c6eb70e3f037e55cf52a22b064dff9f64 100644 --- a/ts2panda/tests/hoist.test.ts +++ b/ts2panda/tests/hoist.test.ts @@ -18,8 +18,11 @@ import { } from 'chai'; import 'mocha'; import { - DefinefuncDyn, - EqDyn, + EcmaDefinefuncdyn, + EcmaIstrue, + EcmaReturnundefined, + EcmaStglobalvar, + EcmaThrowundefinedifhole, Imm, Jeqz, Label, @@ -27,139 +30,131 @@ import { LdaiDyn, LdaStr, ResultType, - ReturnUndefined, StaDyn, - StGlobalVar, - ThrowUndefinedIfHole, - Toboolean, VReg } from "../src/irnodes"; import { checkInstructions, compileMainSnippet, SnippetCompiler } from "./utils/base"; -describe("HoistTest", function() { +describe("HoistTest", function () { // case 1: hoist var declared variable ((declared in global scope)) in global scope - it('case 1;', function() { + it('case 1;', function () { let insns = compileMainSnippet("var a = 1;"); let expected = [ new LdaDyn(new VReg()), - new StGlobalVar("a"), + new EcmaStglobalvar("a"), new LdaiDyn(new Imm(ResultType.Int, 1)), - new StGlobalVar("a"), - new ReturnUndefined() + new EcmaStglobalvar("a"), + new EcmaReturnundefined() ] expect(checkInstructions(insns, expected)).to.be.true; }); // case 2: hoist var declared variable (declared in local scope) in global scope - it('case 2', function() { + it('case 2', function () { let insns = compileMainSnippet(`if (true) { var a = 2; }`); - let conditionReg = new VReg(); let endLabel = new Label(); let expected = [ new LdaDyn(new VReg()), - new StGlobalVar("a"), + new EcmaStglobalvar("a"), new LdaDyn(new VReg()), - new Toboolean(), - new EqDyn(conditionReg), + new EcmaIstrue(), new Jeqz(endLabel), new LdaiDyn(new Imm(ResultType.Int, 2)), - new StGlobalVar("a"), + new EcmaStglobalvar("a"), endLabel, - new ReturnUndefined() + new EcmaReturnundefined() ] expect(checkInstructions(insns, expected)).to.be.true; }); // case 3: hoist function declaration in global scope - it('case 3', function() { + it('case 3', function () { let snippetCompiler = new SnippetCompiler(); snippetCompiler.compile(`function a() {};`); let insns = snippetCompiler.getGlobalInsns(); let expected = [ - new DefinefuncDyn("func_a_1", new VReg()), - new StGlobalVar("a"), - new ReturnUndefined() + new EcmaDefinefuncdyn("a", new Imm(ResultType.Int, 0), new VReg()), + new EcmaStglobalvar("a"), + new EcmaReturnundefined() ] expect(checkInstructions(insns, expected)).to.be.true; }); // case 4: In case that two function declared directly in global scope with the same name, hoist the later one. - it('case 4', function() { + it('case 4', function () { let snippetCompiler = new SnippetCompiler(); snippetCompiler.compile(`function a() {}; function a() {}`); let insns = snippetCompiler.getGlobalInsns(); let expected = [ - new DefinefuncDyn("func_a_2", new VReg()), - new StGlobalVar("a"), - new ReturnUndefined() + new EcmaDefinefuncdyn("#2#a", new Imm(ResultType.Int, 0), new VReg()), + new EcmaStglobalvar("a"), + new EcmaReturnundefined() ] expect(checkInstructions(insns, expected)).to.be.true; }); // case 5: hoisting of function declaration is of higher priority than var declared variables with a same name in global scope - it('case 5', function() { + it('case 5', function () { let snippetCompiler = new SnippetCompiler(); snippetCompiler.compile(`var a = 1; function a() {}`); let insns = snippetCompiler.getGlobalInsns(); let expected = [ - new DefinefuncDyn("func_a_1", new VReg()), - new StGlobalVar("a"), + new EcmaDefinefuncdyn("a", new Imm(ResultType.Int, 0), new VReg()), + new EcmaStglobalvar("a"), new LdaiDyn(new Imm(ResultType.Int, 1)), - new StGlobalVar("a"), - new ReturnUndefined() + new EcmaStglobalvar("a"), + new EcmaReturnundefined() ] expect(checkInstructions(insns, expected)).to.be.true; }); // case 6: hoist var declared variable in function scope - it('case 6', function() { + it('case 6', function () { let snippetCompiler = new SnippetCompiler(); snippetCompiler.compile(`function a() {var a = 1;}`); - let funcPg = snippetCompiler.getPandaGenByName("func_a_1"); + let funcPg = snippetCompiler.getPandaGenByName("a"); let insns = funcPg!.getInsns(); - let builtInUndefinedVreg = new VReg(); let a = new VReg(); let expected = [ - new LdaDyn(builtInUndefinedVreg), - new StaDyn(a), + new LdaDyn(a), + new StaDyn(new VReg()), new LdaiDyn(new Imm(ResultType.Int, 1)), new StaDyn(a), - new ReturnUndefined() + new EcmaReturnundefined() ] - expect(checkInstructions(insns!, expected)).to.be.true; }); // case 7: hoist function declaration in function scope - it('case 7', function() { + it('case 7', function () { let snippetCompiler = new SnippetCompiler(); snippetCompiler.compile(`function a() {function b() {}};`); - let funcPg = snippetCompiler.getPandaGenByName("func_a_1"); + let funcPg = snippetCompiler.getPandaGenByName("a"); let insns = funcPg!.getInsns(); let a = new VReg(); let expected = [ - new DefinefuncDyn("func_b_2", new VReg()), + new EcmaDefinefuncdyn("b", new Imm(ResultType.Int, 0), new VReg()), new StaDyn(a), - new ReturnUndefined() + new EcmaReturnundefined() ] expect(checkInstructions(insns!, expected)).to.be.true; }); // case 8: temporary dead zone of let in global scope - it('case 8', function() { + it('case 8', function () { let snippetCompiler = new SnippetCompiler(); snippetCompiler.compile(`a = 1; let a;`); @@ -169,34 +164,34 @@ describe("HoistTest", function() { let expected = [ new LdaStr("a"), new StaDyn(idReg), - new ThrowUndefinedIfHole(new VReg(), idReg) + new EcmaThrowundefinedifhole(new VReg(), idReg) ] expect(checkInstructions(insns.slice(3, 5), expected)); }); // case 9: temporary dead zone of let in function scope - it('case 9', function() { + it('case 9', function () { let snippetCompiler = new SnippetCompiler(); snippetCompiler.compile(`function b() { a = 1; let a; }`); - let funcPg = snippetCompiler.getPandaGenByName("func_b_1"); + let funcPg = snippetCompiler.getPandaGenByName("b"); let insns = funcPg!.getInsns(); let idReg = new VReg(); let expected = [ new LdaStr("a"), new StaDyn(idReg), - new ThrowUndefinedIfHole(new VReg(), idReg) + new EcmaThrowundefinedifhole(new VReg(), idReg) ] expect(checkInstructions(insns.slice(3, 5), expected)); }); // case 10: temporary dead zone of let in local scope - it('case 10', function() { + it('case 10', function () { let snippetCompiler = new SnippetCompiler(); snippetCompiler.compile(`{ a = 1; @@ -209,7 +204,7 @@ describe("HoistTest", function() { let expected = [ new LdaStr("a"), new StaDyn(idReg), - new ThrowUndefinedIfHole(new VReg(), idReg) + new EcmaThrowundefinedifhole(new VReg(), idReg) ] expect(checkInstructions(insns.slice(3, 5), expected)); diff --git a/ts2panda/tests/intrinsicExpander.test.ts b/ts2panda/tests/intrinsicExpander.test.ts index 4dfdab7984ae3e8ec7538ed72463e74ee76e2f7b..8016811d793d8d4a8b5fd2fa75cec4b643400470 100644 --- a/ts2panda/tests/intrinsicExpander.test.ts +++ b/ts2panda/tests/intrinsicExpander.test.ts @@ -19,31 +19,31 @@ import { import 'mocha'; import { IntrinsicExpanderInternal } from "../src/intrinsicExpander"; import { - And2Dyn, CallShort, + EcmaAnd2dyn, + EcmaShl2dyn, FormatItem, Intrinsic, IRNodeKind, OperandKind, ResultDst, ResultType, - Shl2Dyn, VReg } from "../src/irnodes"; import { checkInstructions } from "./utils/base"; -describe("InstructionExpanderTest", function() { - it("test expander saves acc", function() { +describe("InstructionExpanderTest", function () { + it("test expander saves acc", function () { let expander = new IntrinsicExpanderInternal(); let lhs = new VReg(); - let insns = expander.expandInstruction(new Shl2Dyn(lhs))[0]; + let insns = expander.expandInstruction(new EcmaShl2dyn(lhs))[0]; let expected = [ - new CallShort("Ecmascript.Intrinsics.shl2Dyn", lhs) + new CallShort("Ecmascript.Intrinsics.ecma.shl2dyn", lhs) ]; expect(checkInstructions(insns, expected)).to.be.true; }); - it("test expander restores acc", function() { + it("test expander restores acc", function () { class FakeDyn extends Intrinsic { constructor(vs: VReg) { super( @@ -79,13 +79,13 @@ describe("InstructionExpanderTest", function() { expect(checkInstructions(insns, expected)).to.be.true; }); - it("test expander for And2Dyn", function() { + it("test expander for EcmaAnd2dyn", function () { let expander = new IntrinsicExpanderInternal(); let v1 = new VReg(); - let insns = expander.expandInstruction(new And2Dyn(v1))[0]; + let insns = expander.expandInstruction(new EcmaAnd2dyn(v1))[0]; let lhs = new VReg(); let expected = [ - new CallShort("Ecmascript.Intrinsics.and2Dyn", lhs) + new CallShort("Ecmascript.Intrinsics.ecma.and2dyn", lhs) ]; expect(checkInstructions(insns, expected)).to.be.true; }) diff --git a/ts2panda/tests/lexenv.test.ts b/ts2panda/tests/lexenv.test.ts index 19c42f89ab73ef153d40710d9de1361347eba14a..634973e7365d51fdc8d9562b28af96ec5a031220 100644 --- a/ts2panda/tests/lexenv.test.ts +++ b/ts2panda/tests/lexenv.test.ts @@ -20,26 +20,28 @@ import { CompilerDriver } from "../src/compilerDriver"; import { - Add2Dyn, - DefinefuncDyn, + EcmaAdd2dyn, + EcmaDefinefuncdyn, + EcmaIncdyn, + EcmaLdlexenvdyn, + EcmaLdlexvardyn, + EcmaNewlexenvdyn, + EcmaReturnundefined, + EcmaStglobalvar, + EcmaStlettoglobalrecord, + EcmaStlexvardyn, + EcmaThrowconstassignment, + EcmaThrowundefinedifhole, + EcmaTonumber, + EcmaTrystglobalbyname, Imm, - IncDyn, IRNode, LdaDyn, LdaiDyn, LdaStr, - LdLexEnv, - LdLexVar, - NewLexEnv, ResultType, ReturnDyn, - ReturnUndefined, StaDyn, - StGlobalVar, - StLexVar, - ThrowConstAssignment, - ThrowUndefinedIfHole, - Tonumber, VReg } from "../src/irnodes"; import { PandaGen } from "../src/pandagen"; @@ -66,9 +68,9 @@ function MicroCreateLexEnv(numVars: number, hasLexEnv: boolean): IRNode[] { let insns = []; if (hasLexEnv) { - insns.push(new NewLexEnv(new Imm(ResultType.Int, numVars))); + insns.push(new EcmaNewlexenvdyn(new Imm(ResultType.Int, numVars))); } else { - insns.push(new LdLexEnv()); + insns.push(new EcmaLdlexenvdyn()); } insns.push(new StaDyn(new VReg())); // create lexenv @@ -79,16 +81,16 @@ function MicroStoreLexVar(level: number, slot: number, kind?: VarDeclarationKind let insns = []; if (kind && name) { - insns.push(new LdLexVar(new Imm(ResultType.Int, level), new Imm(ResultType.Int, slot))); + insns.push(new EcmaLdlexvardyn(new Imm(ResultType.Int, level), new Imm(ResultType.Int, slot))); insns.push(new StaDyn(new VReg())); insns.push(new LdaStr(name)); insns.push(new StaDyn(new VReg())); - insns.push(new ThrowUndefinedIfHole(new VReg(), new VReg())); + insns.push(new EcmaThrowundefinedifhole(new VReg(), new VReg())); if (kind == VarDeclarationKind.CONST) { - insns.push(new ThrowConstAssignment(new VReg())); + insns.push(new EcmaThrowconstassignment(new VReg())); } } - insns.push(new StLexVar(new Imm(ResultType.Int, level), new Imm(ResultType.Int, slot), new VReg())); + insns.push(new EcmaStlexvardyn(new Imm(ResultType.Int, level), new Imm(ResultType.Int, slot), new VReg())); insns.push(new LdaDyn(new VReg())); return insns; @@ -97,21 +99,21 @@ function MicroStoreLexVar(level: number, slot: number, kind?: VarDeclarationKind function MicroLoadLexVar(level: number, slot: number, kind?: VarDeclarationKind, name?: string): IRNode[] { let insns = []; - insns.push(new LdLexVar(new Imm(ResultType.Int, level), new Imm(ResultType.Int, slot))); + insns.push(new EcmaLdlexvardyn(new Imm(ResultType.Int, level), new Imm(ResultType.Int, slot))); if (kind && name) { insns.push(new StaDyn(new VReg())); insns.push(new LdaStr(name)); insns.push(new StaDyn(new VReg())); - insns.push(new ThrowUndefinedIfHole(new VReg(), new VReg())); + insns.push(new EcmaThrowundefinedifhole(new VReg(), new VReg())); insns.push(new LdaDyn(new VReg())); } return insns; } -describe("lexenv-compile-testcase in lexenv.test.ts", function() { +describe("lexenv-compile-testcase in lexenv.test.ts", function () { - it("test CompilerDriver.scanFunctions-with-empty", function() { + it("test CompilerDriver.scanFunctions-with-empty", function () { let source: string = ``; let sourceFile = creatAstFromSnippet(source); let compilerDriver = new CompilerDriver('UnitTest'); @@ -126,7 +128,7 @@ describe("lexenv-compile-testcase in lexenv.test.ts", function() { expect(globalScope.getBindingNode() == sourceFile, "functionblock.node should equal to sourceFile").to.be.true; }); - it("test CompilerDriver.scanFunctions-with-embedded-function", function() { + it("test CompilerDriver.scanFunctions-with-embedded-function", function () { let source: string = ` { function outer() { @@ -185,7 +187,7 @@ describe("lexenv-compile-testcase in lexenv.test.ts", function() { expect(bindingNodeOfSon1.kind, "son1's parent should equal root!").deep.equal(ts.SyntaxKind.FunctionExpression); }); - it("test CompilerDriver.postorderanalysis-with-empty", function() { + it("test CompilerDriver.postorderanalysis-with-empty", function () { let source: string = ` `; let sourceFile = creatAstFromSnippet(source); @@ -200,7 +202,7 @@ describe("lexenv-compile-testcase in lexenv.test.ts", function() { expect(postOrderVariableScopes[0]).to.be.deep.equal(globalScope); }); - it("test CompilerDriver.postorderanalysis-with-embeded-function", function() { + it("test CompilerDriver.postorderanalysis-with-embeded-function", function () { let source: string = ` { function outer() { @@ -252,7 +254,7 @@ describe("lexenv-compile-testcase in lexenv.test.ts", function() { * | 4 | | 5 | * +-------+ +------+ */ - it("test CompilerDriver.postorderanalysis-with-IIFE", function() { + it("test CompilerDriver.postorderanalysis-with-IIFE", function () { let source: string = ` (function (global, factory) { // 1 } (this, (function () { 'use strict'; // 2 @@ -285,7 +287,7 @@ describe("lexenv-compile-testcase in lexenv.test.ts", function() { expect(postOrderVariableScopes[5]).to.be.deep.equal(globalScope); }); - it("test loadAccFromLexEnv with loacal variable", function() { + it("test loadAccFromLexEnv with loacal variable", function () { let globalScope = new GlobalScope(); let pandaGen = new PandaGen("lexVarPassPandaGen", 1, globalScope); let var1 = globalScope.add("var1", VarDeclarationKind.LET); @@ -307,7 +309,7 @@ describe("lexenv-compile-testcase in lexenv.test.ts", function() { expect(checkInstructions(outInsns, expected)).to.be.true; }); - it("test loadAccFromLexEnv with lex env variable", function() { + it("test loadAccFromLexEnv with lex env variable", function () { let globalScope = new GlobalScope(); let pandaGen = new PandaGen("lexVarPassPandaGen", 1, globalScope); let var1 = globalScope.add("var1", VarDeclarationKind.LET); @@ -323,17 +325,17 @@ describe("lexenv-compile-testcase in lexenv.test.ts", function() { let tempReg = new VReg(); let nameReg = new VReg(); let expected = [ - new LdLexVar(new Imm(ResultType.Int, 0), new Imm(ResultType.Int, 0)), + new EcmaLdlexvardyn(new Imm(ResultType.Int, 0), new Imm(ResultType.Int, 0)), new StaDyn(tempReg), new LdaStr("var1"), new StaDyn(nameReg), - new ThrowUndefinedIfHole(new VReg(), nameReg), + new EcmaThrowundefinedifhole(new VReg(), nameReg), new LdaDyn(tempReg) ]; expect(checkInstructions(outInsns, expected)).to.be.true; }); - it("test storeAccFromLexEnv with local variable", function() { + it("test storeAccFromLexEnv with local variable", function () { let globalScope = new GlobalScope(); let pandaGen = new PandaGen("lexVarPassPandaGen", 1, globalScope); let var1 = globalScope.add("var1", VarDeclarationKind.LET); @@ -352,7 +354,7 @@ describe("lexenv-compile-testcase in lexenv.test.ts", function() { expect(checkInstructions(outInsns, expected)).to.be.true; }); - it("test storeAccFromLexEnv with lex env let-variable", function() { + it("test storeAccFromLexEnv with lex env let-variable", function () { let globalScope = new GlobalScope(); let pandaGen = new PandaGen("lexVarPassPandaGen", 1, globalScope); let var1 = globalScope.add("var1", VarDeclarationKind.LET); @@ -369,13 +371,13 @@ describe("lexenv-compile-testcase in lexenv.test.ts", function() { let valueReg = new VReg(); let expected = [ new StaDyn(valueReg), - new StLexVar(new Imm(ResultType.Int, 0), new Imm(ResultType.Int, 0), valueReg), + new EcmaStlexvardyn(new Imm(ResultType.Int, 0), new Imm(ResultType.Int, 0), valueReg), new LdaDyn(new VReg()) ]; expect(checkInstructions(outInsns, expected)).to.be.true; }); - it("test storeAccFromLexEnv with lex env const-variable", function() { + it("test storeAccFromLexEnv with lex env const-variable", function () { let globalScope = new GlobalScope(); let pandaGen = new PandaGen("lexVarPassPandaGen", 1, globalScope); let var1 = globalScope.add("var1", VarDeclarationKind.CONST); @@ -391,13 +393,13 @@ describe("lexenv-compile-testcase in lexenv.test.ts", function() { let valueReg = new VReg(); let expected = [ new StaDyn(valueReg), - new StLexVar(new Imm(ResultType.Int, 0), new Imm(ResultType.Int, 0), valueReg), + new EcmaStlexvardyn(new Imm(ResultType.Int, 0), new Imm(ResultType.Int, 0), valueReg), new LdaDyn(valueReg) ]; expect(checkInstructions(outInsns, expected)).to.be.true; }); - it("test lexenv variable capture in function", function() { + it("test lexenv variable capture in function", function () { let source: string = ` var outer = 1; @@ -409,29 +411,29 @@ describe("lexenv-compile-testcase in lexenv.test.ts", function() { let pandaGens = compileAllSnippet(source); let expected_main = [ new LdaDyn(new VReg()), - new StGlobalVar("outer"), - new DefinefuncDyn("func_func_1", new VReg()), - new StGlobalVar("func"), + new EcmaStglobalvar("outer"), + new EcmaDefinefuncdyn("func", new Imm(ResultType.Int, 0), new VReg()), + new EcmaStglobalvar("func"), new LdaiDyn(new Imm(ResultType.Int, 1)), - new StGlobalVar("outer"), - new ReturnUndefined() + new EcmaStglobalvar("outer"), + new EcmaReturnundefined() ]; let expected_func = [ new LdaiDyn(new Imm(ResultType.Int, 2)), - new StGlobalVar("outer"), - new ReturnUndefined() + new EcmaStglobalvar("outer"), + new EcmaReturnundefined() ]; pandaGens.forEach((pg) => { if (pg.internalName == "func_main_0") { expect(checkInstructions(pg.getInsns(), expected_main)).to.be.true; - } else if (pg.internalName == "func_func_1") { + } else if (pg.internalName == "func") { expect(checkInstructions(pg.getInsns(), expected_func)).to.be.true; } }) }); - it("test lexenv let capture in function", function() { + it("test lexenv let capture in function", function () { let source: string = ` let outer = 1; @@ -440,45 +442,44 @@ describe("lexenv-compile-testcase in lexenv.test.ts", function() { } `; - let insnsCreateLexEnv_main = MicroCreateLexEnv(1, true); - let insnsStoreLexVar_main = MicroStoreLexVar(0, 0); + let insnsCreateLexEnv_main = MicroCreateLexEnv(1, false); let passes = [new CacheExpander()]; let pandaGens = compileAllSnippet(source, passes); let expected_main = [ ...insnsCreateLexEnv_main, - new DefinefuncDyn("func_func_1", new VReg()), - new StGlobalVar("func"), // global.func = func_func_1 + new EcmaDefinefuncdyn("func", new Imm(ResultType.Int, 0), new VReg()), + new EcmaStglobalvar("func"), // global.func = func_func_1 new LdaiDyn(new Imm(ResultType.Int, 1)), // value = 1 - new StaDyn(new VReg()), - ...insnsStoreLexVar_main, - new ReturnUndefined() + // ...insnsStoreLexVar_main, + new EcmaStlettoglobalrecord("outer"), + new EcmaReturnundefined() ]; - let insnsStoreLexVar_func = MicroStoreLexVar(1, 0, VarDeclarationKind.LET, "outer"); - let insnsCreateLexEnv_func = MicroCreateLexEnv(0, true); + let insnsCreateLexEnv_func = MicroCreateLexEnv(0, false); let expected_func = [ ...insnsCreateLexEnv_func, new LdaiDyn(new Imm(ResultType.Int, 2)), - new StaDyn(new VReg()), - ...insnsStoreLexVar_func, - new ReturnUndefined() + // ...insnsStoreLexVar_func, + new EcmaTrystglobalbyname("outer"), + new EcmaReturnundefined() ]; pandaGens.forEach((pg) => { let scope = pg.getScope(); if (pg.internalName == "func_main_0") { expect(checkInstructions(pg.getInsns(), expected_main), "check main insns").to.be.true; - expect(scope.getNumLexEnv(), "main scope has 1 lexvar").to.be.equal(1); - expect(scope.hasLexEnv(), "main scope has lexenv").to.be.true; - } else if (pg.internalName == "func_func_1") { + expect(scope.getNumLexEnv(), "main scope has 0 lexvar").to.be.equal(0); + // expect(scope.hasLexEnv(), "main scope has lexenv").to.be.true; + } else if (pg.internalName == "func") { + expect(checkInstructions(pg.getInsns(), expected_func), "check func insns").to.be.true; expect(scope.getNumLexEnv(), "func scope has 1 lexvar").to.be.equal(0); - expect(scope.hasLexEnv(), "func scope has lexenv").to.be.true; + // expect(scope.hasLexEnv(), "func scope has lexenv").to.be.true; } }); }); - it("test lexenv capture in function", function() { + it("test lexenv capture in function", function () { let source: string = ` var a = 1; function outer(a, b) { @@ -504,7 +505,7 @@ describe("lexenv-compile-testcase in lexenv.test.ts", function() { new LdaDyn(new VReg()), new StaDyn(new VReg()), ...insnsStoreLexVar_outer_2, - new DefinefuncDyn("func_2", new VReg()), + new EcmaDefinefuncdyn("#2#", new Imm(ResultType.Int, 0), new VReg()), // returnStatement new StaDyn(new VReg()), new LdaDyn(new VReg()), @@ -516,14 +517,14 @@ describe("lexenv-compile-testcase in lexenv.test.ts", function() { ...MicroCreateLexEnv(0, true), ...MicroLoadLexVar(1, 0), new StaDyn(new VReg()), - new IncDyn(new VReg()), + new EcmaIncdyn(new VReg()), new StaDyn(new VReg()), ...MicroStoreLexVar(1, 0), - new Tonumber(new VReg()), // this is reduntant load varialbe + new EcmaTonumber(new VReg()), // this is reduntant load varialbe ...MicroLoadLexVar(1, 0), new StaDyn(new VReg), ...MicroLoadLexVar(1, 1), - new Add2Dyn(new VReg()), + new EcmaAdd2dyn(new VReg()), // returnStatement new StaDyn(new VReg()), new LdaDyn(new VReg()), @@ -535,20 +536,20 @@ describe("lexenv-compile-testcase in lexenv.test.ts", function() { snippetCompiler.compile(source, passes); // check compile result! - let outerPg = snippetCompiler.getPandaGenByName("func_outer_1"); + let outerPg = snippetCompiler.getPandaGenByName("outer"); let outerScope = outerPg!.getScope(); let outerA = outerScope!.findLocal("a"); expect(outerA instanceof LocalVariable, "a in outer is local variable").to.be.true; - expect((outerScope).hasLexEnv(), "outer scope need to create lex env").to.be.true; + // expect((outerScope).hasLexEnv(), "outer scope need to create lex env").to.be.true; expect((outerScope).getNumLexEnv(), "number of lexvar at outer scope").to.be.equal(2); - let anonymousPg = snippetCompiler.getPandaGenByName("func_2"); + let anonymousPg = snippetCompiler.getPandaGenByName("#2#"); let anonymousScope = anonymousPg!.getScope(); let anonymousA = anonymousScope!.findLocal("a"); let searchRlt = anonymousScope!.find("a"); expect(searchRlt!.level).to.be.equal(1); expect(searchRlt!.scope, "a is defined in outerscope").to.be.deep.equal(outerScope); expect(anonymousA, "no a in anonymous function").to.be.undefined; - expect((anonymousScope).hasLexEnv(), "anonymous scope had lex env").to.be.true; + // expect((anonymousScope).hasLexEnv(), "anonymous scope had lex env").to.be.true; expect((anonymousScope).getNumLexEnv()).to.be.equal(0); let globalPg = snippetCompiler.getPandaGenByName("func_main_0"); let globalScope = globalPg!.getScope(); diff --git a/ts2panda/tests/pandagen.test.ts b/ts2panda/tests/pandagen.test.ts index f96187ca5891af62b14cbcc85909adb90796fe61..c380eeb24edc4ef22b22f3b0907cdc245c747cd6 100644 --- a/ts2panda/tests/pandagen.test.ts +++ b/ts2panda/tests/pandagen.test.ts @@ -13,11 +13,11 @@ * limitations under the License. */ -import * as ts from "typescript"; import { expect } from 'chai'; import 'mocha'; +import * as ts from "typescript"; import { StaDyn, VReg @@ -25,8 +25,8 @@ import { import { PandaGen } from "../src/pandagen"; import { checkInstructions } from "./utils/base"; -describe("PandaGenTest", function() { - it("StoreAccumulator", function() { +describe("PandaGenTest", function () { + it("StoreAccumulator", function () { let pandaGen = new PandaGen("pandaGen", 0); let vreg = new VReg(); pandaGen.storeAccumulator(ts.createNode(0), vreg); diff --git a/ts2panda/tests/regAllocator.test.ts b/ts2panda/tests/regAllocator.test.ts index 0a35621cf62783eff8806dcee7705ff2bc5a3e35..93e4c6892f92706a3f3e0b402001c50878928801 100644 --- a/ts2panda/tests/regAllocator.test.ts +++ b/ts2panda/tests/regAllocator.test.ts @@ -17,21 +17,20 @@ import { expect } from 'chai'; import 'mocha'; import * as ts from "typescript"; import { - BuiltinAcc, - BuiltinR2i, CallRange, + EcmaCallirangedyn, + EcmaReturnundefined, + EcmaStlettoglobalrecord, + EcmaTryldglobalbyname, Imm, IRNode, - LdaDyn, - MovDyn, + LdaiDyn, ResultType, - ReturnUndefined, StaDyn, VReg } from "../src/irnodes"; import { PandaGen } from "../src/pandagen"; import { CacheExpander } from "../src/pass/cacheExpander"; -import { IntrinsicVariantExpander } from "../src/pass/intrinsicVariantExpander"; import { RegAlloc } from "../src/regAllocator"; import { basicChecker, checkInstructions, compileAllSnippet } from "./utils/base"; @@ -56,8 +55,8 @@ function checkRegisterNumber(left: IRNode, right: IRNode): boolean { } return true; } -describe("RegAllocator", function() { - it("make spill for Src register", function() { +describe("RegAllocator", function () { + it("make spill for Src register", function () { let string: string = ""; for (let i = 0; i < 256; ++i) { string += "let a" + i + " = " + i + ";"; @@ -66,31 +65,24 @@ describe("RegAllocator", function() { let pgs = compileAllSnippet(string, [new CacheExpander(), new RegAlloc()]); let insns = pgs[0].getInsns(); - let v260 = new VReg(); - v260.num = 260; - let v259 = new VReg(); - v259.num = 259; - let v258 = new VReg(); - v258.num = 258; - let v0 = new VReg(); - v0.num = 0; let expected: IRNode[] = [ - new MovDyn(v260, v0), - new StaDyn(v0), - new MovDyn(v258, v0), - new MovDyn(v0, v260), - - new MovDyn(v260, v0), - new MovDyn(v0, v258), - new LdaDyn(v0), - new MovDyn(v0, v260), - new ReturnUndefined() - ]; - expect(checkInstructions(insns.slice(insns.length - 9), expected, checkRegisterNumber)).to.be.true; + new LdaiDyn(new Imm(ResultType.Int, 252)), + new EcmaStlettoglobalrecord('a252'), + new LdaiDyn(new Imm(ResultType.Int, 253)), + new EcmaStlettoglobalrecord('a253'), + new LdaiDyn(new Imm(ResultType.Int, 254)), + new EcmaStlettoglobalrecord('a254'), + new LdaiDyn(new Imm(ResultType.Int, 255)), + new EcmaStlettoglobalrecord('a255'), + new EcmaTryldglobalbyname('a255'), + new EcmaReturnundefined() + ] + + expect(checkInstructions(insns.slice(insns.length - 10), expected, checkRegisterNumber)).to.be.true; }); - it("make spill for SrcDst register", function() { + it("make spill for SrcDst register", function () { /* the only possible instruction whose operand register type could be SrcDstVReg is INCI, * but we do not use it at all by now */ @@ -107,40 +99,39 @@ describe("RegAllocator", function() { string += "let a" + i + " = " + i + ";"; } string += "call(a252, a253, a254, a255);"; - let pgs = compileAllSnippet(string, [new CacheExpander(), new IntrinsicVariantExpander(), new RegAlloc()]); + let pgs = compileAllSnippet(string, [new CacheExpander(), new RegAlloc()]); let insns = pgs[0].getInsns(); let v = []; - for (let i = 0; i < 5; ++i) { - v[i] = new VReg(); - v[i].num = i; - } - for (let i = 259; i <= 269; ++i) { + for (let i = 0; i < 8; ++i) { v[i] = new VReg(); v[i].num = i; } let expected = [ - new MovDyn(v[265], v[0]), - new MovDyn(v[0], v[259]), - new MovDyn(v[266], v[1]), - new MovDyn(v[1], v[260]), - new MovDyn(v[267], v[2]), - new MovDyn(v[2], v[261]), - new MovDyn(v[268], v[3]), - new MovDyn(v[3], v[262]), - new MovDyn(v[269], v[4]), - new MovDyn(v[4], v[263]), - new BuiltinR2i(new Imm(ResultType.Int, 3), new Imm(ResultType.Int, 4), v.slice(0, 5)), - new MovDyn(v[0], v[265]), - new MovDyn(v[1], v[266]), - new MovDyn(v[2], v[267]), - new MovDyn(v[3], v[268]), - new MovDyn(v[4], v[269]), - new BuiltinAcc(new Imm(ResultType.Int, 23)) // ReturnUndefined + new LdaiDyn(new Imm(ResultType.Int, 252)), + new EcmaStlettoglobalrecord('a252'), + new LdaiDyn(new Imm(ResultType.Int, 253)), + new EcmaStlettoglobalrecord('a253'), + new LdaiDyn(new Imm(ResultType.Int, 254)), + new EcmaStlettoglobalrecord('a254'), + new LdaiDyn(new Imm(ResultType.Int, 255)), + new EcmaStlettoglobalrecord('a255'), + new EcmaTryldglobalbyname('call'), + new StaDyn(v[3]), + new EcmaTryldglobalbyname('a252'), + new StaDyn(v[4]), + new EcmaTryldglobalbyname('a253'), + new StaDyn(v[5]), + new EcmaTryldglobalbyname('a254'), + new StaDyn(v[6]), + new EcmaTryldglobalbyname('a255'), + new StaDyn(v[7]), + new EcmaCallirangedyn(new Imm(ResultType.Int, 4), [v[3],v[4],v[5],v[6],v[7]]), + new EcmaReturnundefined(), ]; - expect(checkInstructions(insns.slice(insns.length - 17), expected, checkRegisterNumber)).to.be.true; + expect(checkInstructions(insns.slice(insns.length - 20), expected, checkRegisterNumber)).to.be.true; }); - it("VReg sequence of CalliDynRange is not continuous", function() { + it("VReg sequence of CalliDynRange is not continuous", function () { let pandaGen = new PandaGen('', 0); let para1 = pandaGen.getTemp(); @@ -163,7 +154,7 @@ describe("RegAllocator", function() { expect(true).to.be.false; }); - it("VReg sequence of DynRange is not continuous", function() { + it("VReg sequence of DynRange is not continuous", function () { let pandaGen = new PandaGen('', 0); let para1 = pandaGen.getTemp(); diff --git a/ts2panda/tests/scope.test.ts b/ts2panda/tests/scope.test.ts index 3b2a4dde104160e3ca9c10c39cf29253dbfef853..85ef72aa12f4d374754159f3b406c591619b7950 100644 --- a/ts2panda/tests/scope.test.ts +++ b/ts2panda/tests/scope.test.ts @@ -28,8 +28,8 @@ import { VarDeclarationKind } from "../src/variable"; -describe("ScopeTest", function() { - it("test add 'none' variable to GlobalScope", function() { +describe("ScopeTest", function () { + it("test add 'none' variable to GlobalScope", function () { let scope = new GlobalScope(); let variable = scope.add("x", VarDeclarationKind.NONE); expect(variable instanceof GlobalVariable).to.be.true; @@ -39,7 +39,7 @@ describe("ScopeTest", function() { expect(sp).to.be.equal(scope); }); - it("test add 'var' variable to GlobalScope", function() { + it("test add 'var' variable to GlobalScope", function () { let scope = new GlobalScope(); let variable = scope.add("x", VarDeclarationKind.VAR); expect(variable instanceof GlobalVariable).to.be.true; @@ -49,7 +49,7 @@ describe("ScopeTest", function() { expect(sp).to.be.equal(scope); }); - it("test add 'let' variable to GlobalScope", function() { + it("test add 'let' variable to GlobalScope", function () { let scope = new GlobalScope(); let variable = scope.add("x", VarDeclarationKind.LET); expect(variable instanceof LocalVariable).to.be.true; @@ -59,7 +59,7 @@ describe("ScopeTest", function() { expect(sp).to.be.equal(scope); }); - it("test add 'const' variable to GlobalScope", function() { + it("test add 'const' variable to GlobalScope", function () { let scope = new GlobalScope(); let variable = scope.add("x", VarDeclarationKind.CONST); expect(variable instanceof LocalVariable).to.be.true; @@ -69,14 +69,14 @@ describe("ScopeTest", function() { expect(sp).to.be.equal(scope); }); - it("test add several variables to GlobalScope", function() { + it("test add several variables to GlobalScope", function () { let scope = new GlobalScope(); let x = scope.add("x", VarDeclarationKind.LET); let y = scope.add("y", VarDeclarationKind.NONE); let z = scope.add("z", VarDeclarationKind.LET); }); - it("test add 'none' variable to FunctionScope", function() { + it("test add 'none' variable to FunctionScope", function () { let globalScope = new GlobalScope(); let scope = new FunctionScope(globalScope); let variable = scope.add("x", VarDeclarationKind.NONE); @@ -87,7 +87,7 @@ describe("ScopeTest", function() { expect(sp).to.be.equal(globalScope); }); - it("test add 'var' variable to FunctionScope", function() { + it("test add 'var' variable to FunctionScope", function () { let scope = new FunctionScope(); let variable = scope.add("x", VarDeclarationKind.VAR); expect(variable instanceof LocalVariable).to.be.true; @@ -97,7 +97,7 @@ describe("ScopeTest", function() { expect(sp).to.be.equal(scope); }); - it("test add 'let' variable to FunctionScope", function() { + it("test add 'let' variable to FunctionScope", function () { let scope = new FunctionScope(); let variable = scope.add("x", VarDeclarationKind.LET); expect(variable instanceof LocalVariable).to.be.true; @@ -107,7 +107,7 @@ describe("ScopeTest", function() { expect(sp).to.be.equal(scope); }); - it("test add 'const' variable to FunctionScope", function() { + it("test add 'const' variable to FunctionScope", function () { let scope = new FunctionScope(); let variable = scope.add("x", VarDeclarationKind.LET); expect(variable instanceof LocalVariable).to.be.true; @@ -117,7 +117,7 @@ describe("ScopeTest", function() { expect(sp).to.be.equal(scope); }); - it("test add several variables to FunctionScope", function() { + it("test add several variables to FunctionScope", function () { let globalScope = new GlobalScope(); let scope = new FunctionScope(globalScope); let x = scope.add("x", VarDeclarationKind.LET); @@ -125,7 +125,7 @@ describe("ScopeTest", function() { let z = scope.add("z", VarDeclarationKind.LET); }); - it("test add 'none' variable to LocalScope", function() { + it("test add 'none' variable to LocalScope", function () { let parent = new FunctionScope(); let scope = new LocalScope(parent); let variable = scope.add("x", VarDeclarationKind.NONE); @@ -140,7 +140,7 @@ describe("ScopeTest", function() { expect(spParent).to.be.equal(undefined); }); - it("test add 'var' variable to LocalScope", function() { + it("test add 'var' variable to LocalScope", function () { let parent = new FunctionScope(); let scope = new LocalScope(parent); let variable = scope.add("x", VarDeclarationKind.VAR); @@ -155,7 +155,7 @@ describe("ScopeTest", function() { expect(spParent).to.be.equal(parent); }); - it("test add 'let' variable to LocalScope", function() { + it("test add 'let' variable to LocalScope", function () { let parent = new FunctionScope(); let scope = new LocalScope(parent); let variable = scope.add("x", VarDeclarationKind.LET); @@ -168,7 +168,7 @@ describe("ScopeTest", function() { expect(outVariableParent === undefined).to.be.true; }); - it("test add 'const' variable to LocalScope", function() { + it("test add 'const' variable to LocalScope", function () { let parent = new FunctionScope(); let scope = new LocalScope(parent); let variable = scope.add("x", VarDeclarationKind.LET); @@ -181,7 +181,7 @@ describe("ScopeTest", function() { expect(outVariableParent === undefined).to.be.true; }); - it("test add several variables to LocalScope", function() { + it("test add several variables to LocalScope", function () { let global = new GlobalScope(); let parent = new FunctionScope(global); let scope = new LocalScope(parent); @@ -216,7 +216,7 @@ describe("ScopeTest", function() { * | func4 | * +---------+ */ - it("test multi-scope nesting function", function() { + it("test multi-scope nesting function", function () { let globalScope = new GlobalScope(); let func1Scope = new FunctionScope(globalScope); let aV = func1Scope.add("a", VarDeclarationKind.LET); @@ -246,24 +246,24 @@ describe("ScopeTest", function() { expect(p2FindEntry.scope).to.be.equal(func1Scope); // check global - expect(globalScope.hasLexEnv(), "gloal has lexenv").to.be.false; + // expect(globalScope.hasLexEnv(), "gloal has lexenv").to.be.false; // check func1 - expect(func1Scope.hasLexEnv(), "func1 haslexenv").to.be.true; + // expect(func1Scope.hasLexEnv(), "func1 haslexenv").to.be.true; expect(func1Scope.getNumLexEnv(), "func1 status").to.be.equal(2); // check fun21 - expect(func21Scope.hasLexEnv(), "func21 has lexenv").to.be.true; + // expect(func21Scope.hasLexEnv(), "func21 has lexenv").to.be.true; expect(func21Scope.getNumLexEnv(), "func21 status").to.be.equal(0); // check fun22 - expect(func22Scope.hasLexEnv(), "func22 has lexenv").to.be.true; + // expect(func22Scope.hasLexEnv(), "func22 has lexenv").to.be.true; expect(func22Scope.getNumLexEnv(), "func22 status").to.be.equal(0); // check fun31 - expect(func31Scope.hasLexEnv(), "func31 has lexenv").to.be.false; + // expect(func31Scope.hasLexEnv(), "func31 has lexenv").to.be.false; expect(func31Scope.getNumLexEnv(), "func31 status").to.be.equal(0); // check fun32 - expect(func32Scope.hasLexEnv(), "func32 has lexenv").to.be.true; + // expect(func32Scope.hasLexEnv(), "func32 has lexenv").to.be.true; expect(func32Scope.getNumLexEnv(), "func32 status").to.be.equal(0); // check fun4 - expect(func4Scope.hasLexEnv(), "func4 has lexenv").to.be.false; + // expect(func4Scope.hasLexEnv(), "func4 has lexenv").to.be.false; expect(func4Scope.getNumLexEnv(), "func4 status").to.be.equal(0); }); }) diff --git a/ts2panda/tests/otherStatements.test.ts b/ts2panda/tests/statements/debugger.test.ts similarity index 74% rename from ts2panda/tests/otherStatements.test.ts rename to ts2panda/tests/statements/debugger.test.ts index f121dce9cb8e1380c25118740b539bcbdb6ee03f..9cbe527f94c0f08baa120bd7ecb7da256dfd1155 100644 --- a/ts2panda/tests/otherStatements.test.ts +++ b/ts2panda/tests/statements/debugger.test.ts @@ -18,17 +18,17 @@ import { } from 'chai'; import 'mocha'; import { - Debugger, - ReturnUndefined -} from "../src/irnodes"; -import { checkInstructions, compileMainSnippet } from "./utils/base"; + EcmaDebugger, + EcmaReturnundefined +} from "../../src/irnodes"; +import { checkInstructions, compileMainSnippet } from "../utils/base"; -describe("DebuggerTest", function() { - it("debugger", function() { +describe("DebuggerTest", function () { + it("debugger", function () { let insns = compileMainSnippet("debugger;"); let expected = [ - new Debugger(), - new ReturnUndefined() + new EcmaDebugger(), + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; }); diff --git a/ts2panda/tests/statements/doWhile.test.ts b/ts2panda/tests/statements/doWhile.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..ca308a2d4ab500aa1747f7b725feeb08395abb59 --- /dev/null +++ b/ts2panda/tests/statements/doWhile.test.ts @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + expect +} from 'chai'; +import 'mocha'; +import { + EcmaLessdyn, + EcmaReturnundefined, + EcmaStlettoglobalrecord, + EcmaTryldglobalbyname, + EcmaTrystglobalbyname, + Imm, + Jeqz, + Jmp, + Label, LdaiDyn, + ResultType, + StaDyn, + VReg +} from "../../src/irnodes"; +import { checkInstructions, compileMainSnippet } from "../utils/base"; + + +describe("DoWhileLoopTest", function () { + it('doWhileLoopEmpty', function () { + let insns = compileMainSnippet("do {} while (true)"); + + let jumps = insns.filter(item => item instanceof Jmp); + + expect(jumps.length).to.equal(1); + + let jmpLabel = (jumps[0]).getTarget(); + + expect(jmpLabel).to.equal(insns[0]); + }); + + it('doWhileLoopWithBody', function () { + let insns = compileMainSnippet("let a = 5;" + + "do { a++ } while (a < 11);"); + + let jumps = insns.filter(item => (item instanceof Jmp || item instanceof Jeqz)); + + expect(jumps.length).to.equal(2); + + let jgezLabel = (jumps[0]).getTarget(); + let jmpLabel = (jumps[1]).getTarget(); + + expect(jmpLabel).to.equal(insns[2]); + expect(jgezLabel).to.equal(insns[15]); + + expect(insns[13]).to.equal(jumps[0]); + expect(insns[14]).to.equal(jumps[1]); + }); + + it('doWhileLoopWithContinue', function () { + let insns = compileMainSnippet("let a = 5;" + + "do { a = 1; continue; } while (a < 1);"); + let a = new VReg(); + let lhs = new VReg(); + let labelPre = new Label(); + let labelCond = new Label(); + let labelPost = new Label(); + let expected = [ + new LdaiDyn(new Imm(ResultType.Int, 5)), + new EcmaStlettoglobalrecord('a'), + // body + labelPre, + new LdaiDyn(new Imm(ResultType.Int, 1)), + new EcmaTrystglobalbyname('a'), + new Jmp(labelCond), // continue + // condition + labelCond, + new EcmaTryldglobalbyname('a'), + new StaDyn(lhs), + new LdaiDyn(new Imm(ResultType.Int, 1)), + new EcmaLessdyn(lhs), + new Jeqz(labelPost), + new Jmp(labelPre), + labelPost, + new EcmaReturnundefined() + ] + + // check the instruction kinds are the same as we expect + expect(checkInstructions(insns, expected)).to.be.true; + // check continue jumps to the expected instruction + let jmp = insns[5]; + let targetLabel = (jmp).getTarget(); + expect(targetLabel).to.equal(insns[6]); + }); + + it('doWhileLoopWithBreak', function () { + let insns = compileMainSnippet("let a = 5;" + + "do { a = 1; break; } while (a < 1);"); + let a = new VReg(); + let lhs = new VReg(); + let labelPre = new Label(); + let labelPost = new Label(); + let labelCond = new Label(); + let expected = [ + new LdaiDyn(new Imm(ResultType.Int, 5)), + new EcmaStlettoglobalrecord('a'), + //body + labelPre, + new LdaiDyn(new Imm(ResultType.Int, 1)), + new EcmaTrystglobalbyname('a'), + new Jmp(labelPost), // break + // condition + labelCond, + new EcmaTryldglobalbyname('a'), + new StaDyn(lhs), + new LdaiDyn(new Imm(ResultType.Int, 1)), + new EcmaLessdyn(lhs), + new Jeqz(labelPost), + new Jmp(labelPre), + labelPost, + new EcmaReturnundefined() + ] + + // check the instruction kinds are the same as we expect + expect(checkInstructions(insns, expected)).to.be.true; + // check continue jumps to the expected instruction + let jmp = insns[5]; + let targetLabel = (jmp).getTarget(); + expect(targetLabel).to.equal(insns[13]); + }); +}); \ No newline at end of file diff --git a/ts2panda/tests/loops.test.ts b/ts2panda/tests/statements/for.test.ts similarity index 33% rename from ts2panda/tests/loops.test.ts rename to ts2panda/tests/statements/for.test.ts index 7f5bc717baaa8d82f77191eb107e944b05fa7e92..6b52e9cfd53a7efd329d6433983a9a7427b86b30 100644 --- a/ts2panda/tests/loops.test.ts +++ b/ts2panda/tests/statements/for.test.ts @@ -1,869 +1,325 @@ -/* - * Copyright (c) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { - expect -} from 'chai'; -import 'mocha'; -import { - Add2Dyn, - CalliThisRangeDyn, - CreateEmptyArray, - EqDyn, - GetIterator, - Imm, - IncDyn, - Jeqz, - Jgez, - Jmp, - Label, - LdaDyn, - LdaiDyn, - LdObjByName, - LdTrue, - LessDyn, - ResultType, - ReturnUndefined, - StaDyn, - StrictNotEqDyn, - ThrowDyn, - ThrowIfNotObject, - Toboolean, - Tonumber, - VReg -} from "../src/irnodes"; -import { checkInstructions, compileMainSnippet } from "./utils/base"; -import { DiagnosticCode } from '../src/diagnostic'; - -describe("ForLoopTest", function() { - it('forLoopEmpty', function() { - let insns = compileMainSnippet("for (;;) {}"); - let labelPre = new Label(); - let labelPost = new Label(); - let labelIncr = new Label(); - let expected = [ - labelPre, - labelIncr, - new Jmp(labelPre), - labelPost, - new ReturnUndefined() - ]; - let jumps = insns.filter(item => item instanceof Jmp); - - expect(jumps.length).to.equal(1); - - let jmpLabel = (jumps[0]).getTarget(); - - expect(checkInstructions(insns, expected)).to.be.true; - expect(jmpLabel).to.equal(insns[0]); - }); - - it('forLoopWithInitializer', function() { - let insns = compileMainSnippet("for (let i = 0;;) {}"); - let jumps = insns.filter(item => item instanceof Jmp); - - expect(jumps.length).to.equal(1); - - let jmpLabel = (jumps[0]).getTarget(); - - expect(insns[4]).to.equal(jumps[0]); - expect(jmpLabel).to.equal(insns[2]); - }); - - it('forLoopWithInitializerAndCondition', function() { - let insns = compileMainSnippet("for (let i = 0; i < 5;) {}"); - let jumps = insns.filter(item => (item instanceof Jmp || item instanceof Jeqz)); - - expect(jumps.length).to.equal(2); - - let jgezLabel = (jumps[0]).getTarget(); - let jmpLabel = (jumps[1]).getTarget(); - - expect(jmpLabel).to.equal(insns[2]); - expect(jgezLabel).to.equal(insns[10]); - - expect(insns[7]).to.equal(jumps[0]); - expect(insns[9]).to.equal(jumps[1]); - }); - - it('forLoopWithInitializerAndConditionAndIncrementor', function() { - let insns = compileMainSnippet("for (let i = 0; i < 5; i++) {}"); - let jumps = insns.filter(item => (item instanceof Jmp || item instanceof Jeqz)); - - expect(jumps.length).to.equal(2); - - let jgezLabel = (jumps[0]).getTarget(); - let jmpLabel = (jumps[1]).getTarget(); - - expect(jmpLabel).to.equal(insns[2]); - expect(jgezLabel).to.equal(insns[15]); - - expect(insns[7]).to.equal(jumps[0]); - expect(insns[14]).to.equal(jumps[1]); - }); - - it('forLoopWithContinue', function() { - let insns = compileMainSnippet("for (let i = 0; i < 5; ++i) { continue; }"); - let i = new VReg(); - let lhs = new VReg(); - let operand = new VReg(); - let labelPre = new Label(); - let labelPost = new Label(); - let labelIncr = new Label(); - let expected = [ - // initializer - new LdaiDyn(new Imm(ResultType.Int, 0)), - new StaDyn(i), - labelPre, - // condition - new LdaDyn(i), - new StaDyn(lhs), - new LdaiDyn(new Imm(ResultType.Int, 5)), - new LessDyn(lhs), - new Jeqz(labelPost), - // body - new Jmp(labelIncr), // continue - labelIncr, - // incrementor - new LdaDyn(i), - new StaDyn(operand), - new IncDyn(operand), - new StaDyn(i), - // jump to the loop header - new Jmp(new Label()), - labelPost, - new ReturnUndefined() - ]; - // check the instruction kinds are the same as we expect - expect(checkInstructions(insns, expected)).to.be.true; - // check continue jumps to the expected instruction - let jmp = insns[8]; - let targetLabel = (jmp).getTarget(); - expect(targetLabel).to.equal(insns[9]); - }); - - it('forLoopWithBreak', function() { - let insns = compileMainSnippet("for (let i = 0; i < 5; ++i) {break; }"); - let i = new VReg(); - let lhs = new VReg(); - let operand = new VReg(); - let labelPre = new Label(); - let labelPost = new Label(); - let labelIncr = new Label(); - let expected = [ - // initializer - new LdaiDyn(new Imm(ResultType.Int, 0)), - new StaDyn(i), - labelPre, - // condition - new LdaDyn(i), - new StaDyn(lhs), - new LdaiDyn(new Imm(ResultType.Int, 5)), - new LessDyn(lhs), - new Jeqz(labelPost), - // body - new Jmp(labelPost), // break - // incrementor - labelIncr, - new LdaDyn(i), - new StaDyn(operand), - new IncDyn(operand), - new StaDyn(i), - // jump to the loop header - new Jmp(labelPre), - labelPost, - new ReturnUndefined() - ]; - // check the instruction kinds are the same as we expect - expect(checkInstructions(insns, expected)).to.be.true; - // check continue jumps to the expected instruction - let jmp = insns[8]; - let targetLabel = (jmp).getTarget(); - expect(targetLabel).to.equal(insns[15]); - }); -}); - -describe("ForOfLoopTest", function() { - it("forOfLoopWithEmptyArray", function() { - let insns = compileMainSnippet("for (let a of []) {}"); - let a = new VReg(); - let arrInstance = new VReg(); - let iterReg = new VReg(); - let nextMethodReg = new VReg(); - let resultObj = new VReg(); - let exceptionVreg = new VReg(); - let trueReg = new VReg(); - let done = new VReg(); - let value = new VReg(); - - let loopStartLabel = new Label(); - let loopEndLabel = new Label(); - let tryBeginLabel = new Label(); - let tryEndLabel = new Label(); - let catchBeginLabel = new Label(); - let isDone = new Label(); - - let expected = [ - new CreateEmptyArray(), - new StaDyn(arrInstance), - new GetIterator(), - new StaDyn(iterReg), - new LdObjByName("next", iterReg), - new StaDyn(nextMethodReg), - - new LdaDyn(new VReg()), - new StaDyn(done), - - tryBeginLabel, - new LdaDyn(trueReg), - new StaDyn(done), - loopStartLabel, - new CalliThisRangeDyn(new Imm(ResultType.Int, 1), [nextMethodReg, iterReg]), - new StaDyn(resultObj), - new ThrowIfNotObject(resultObj), - new LdObjByName("done", resultObj), - new Toboolean(), - new StrictNotEqDyn(trueReg), - new Jeqz(loopEndLabel), - new LdObjByName("value", resultObj), - new StaDyn(value), - - new LdaDyn(new VReg()), - new StaDyn(done), - - new LdaDyn(value), - new StaDyn(a), - tryEndLabel, - - new Jmp(loopStartLabel), - - catchBeginLabel, - new StaDyn(exceptionVreg), - new LdaDyn(done), - new StrictNotEqDyn(trueReg), - new Jeqz(isDone), - new LdObjByName("return", iterReg), - new StaDyn(nextMethodReg), - new StrictNotEqDyn(new VReg()), - new Jeqz(isDone), - new CalliThisRangeDyn(new Imm(ResultType.Int, 1), [nextMethodReg, iterReg]), - isDone, - new LdaDyn(exceptionVreg), - new ThrowDyn(), - - loopEndLabel, - new ReturnUndefined() - ]; - expect(checkInstructions(insns, expected)).to.be.true; - - let jumps = insns.filter(item => (item instanceof Jmp || item instanceof Jeqz)); - - expect(jumps.length).to.equal(4); - }); - - it("forOfLoopWithContinue", function() { - let insns = compileMainSnippet("for (let a of []) {continue;}"); - let a = new VReg(); - let arrInstance = new VReg(); - let resultObj = new VReg(); - let trueReg = new VReg(); - let iterReg = new VReg(); - let exceptionVreg = new VReg(); - let nextMethodReg = new VReg(); - let done = new VReg(); - let value = new VReg(); - - let loopStartLabel = new Label(); - let loopEndLabel = new Label(); - let tryBeginLabel = new Label(); - let tryEndLabel = new Label(); - let catchBeginLabel = new Label(); - let isDone = new Label(); - let insertedtryBeginLabel = new Label(); - let insertedtryEndLabel = new Label(); - - let expected = [ - new CreateEmptyArray(), - new StaDyn(arrInstance), - new GetIterator(), - new StaDyn(iterReg), - new LdObjByName("next", iterReg), - new StaDyn(nextMethodReg), - - new LdaDyn(new VReg()), - new StaDyn(done), - - tryBeginLabel, - new LdaDyn(trueReg), - new StaDyn(done), - loopStartLabel, - new CalliThisRangeDyn(new Imm(ResultType.Int, 1), [nextMethodReg, iterReg]), - new StaDyn(resultObj), - new ThrowIfNotObject(resultObj), - new LdObjByName("done", resultObj), - new Toboolean(), - new StrictNotEqDyn(trueReg), - new Jeqz(loopEndLabel), - new LdObjByName("value", resultObj), - new StaDyn(value), - - new LdaDyn(new VReg()), - new StaDyn(done), - - new LdaDyn(value), - new StaDyn(a), - - insertedtryBeginLabel, - insertedtryEndLabel, - new Jmp(loopStartLabel), - - tryEndLabel, - - new Jmp(loopStartLabel), - - catchBeginLabel, - new StaDyn(exceptionVreg), - new LdaDyn(done), - new StrictNotEqDyn(trueReg), - new Jeqz(isDone), - new LdObjByName("return", iterReg), - new StaDyn(nextMethodReg), - new StrictNotEqDyn(new VReg()), - new Jeqz(isDone), - new CalliThisRangeDyn(new Imm(ResultType.Int, 1), [nextMethodReg, iterReg]), - isDone, - new LdaDyn(exceptionVreg), - new ThrowDyn(), - - loopEndLabel, - new ReturnUndefined() - ]; - expect(checkInstructions(insns, expected)).to.be.true; - - let jumps = insns.filter(item => (item instanceof Jmp || item instanceof Jeqz)); - - expect(jumps.length).to.equal(5); - }); - - it("forOfLoopWithBreak", function() { - let insns = compileMainSnippet("for (let a of []) {break;}"); - let a = new VReg(); - let arrInstance = new VReg(); - let resultObj = new VReg(); - let exceptionVreg = new VReg(); - let iterReg = new VReg(); - let trueReg = new VReg(); - let nextMethodReg = new VReg(); - let done = new VReg(); - let value = new VReg(); - let loopStartLabel = new Label(); - let loopEndLabel = new Label(); - let tryBeginLabel = new Label(); - let tryEndLabel = new Label(); - let catchBeginLabel = new Label(); - let isDone = new Label(); - let noReturn = new Label(); - let insertedtryBeginLabel = new Label(); - let insertedtryEndLabel = new Label(); - - let expected = [ - new CreateEmptyArray(), - new StaDyn(arrInstance), - new GetIterator(), - new StaDyn(iterReg), - new LdObjByName("next", iterReg), - new StaDyn(nextMethodReg), - - new LdaDyn(new VReg()), - new StaDyn(done), - - tryBeginLabel, - new LdaDyn(trueReg), - new StaDyn(done), - loopStartLabel, - new CalliThisRangeDyn(new Imm(ResultType.Int, 1), [nextMethodReg, iterReg]), - new StaDyn(resultObj), - new ThrowIfNotObject(resultObj), - new LdObjByName("done", resultObj), - new Toboolean(), - new StrictNotEqDyn(trueReg), - new Jeqz(loopEndLabel), - new LdObjByName("value", resultObj), - new StaDyn(value), - - new LdaDyn(new VReg()), - new StaDyn(done), - - new LdaDyn(value), - new StaDyn(a), - - insertedtryBeginLabel, - new LdObjByName("return", iterReg), - new StaDyn(nextMethodReg), - new StrictNotEqDyn(new VReg()), // undefined - new Jeqz(noReturn), - new CalliThisRangeDyn(new Imm(ResultType.Int, 1), [nextMethodReg, iterReg]), - new StaDyn(new VReg()), - new ThrowIfNotObject(new VReg()), - noReturn, - insertedtryEndLabel, - new Jmp(loopEndLabel), - - tryEndLabel, - - new Jmp(loopStartLabel), - - catchBeginLabel, - new StaDyn(exceptionVreg), - new LdaDyn(done), - new StrictNotEqDyn(trueReg), - new Jeqz(isDone), - new LdObjByName("return", iterReg), - new StaDyn(nextMethodReg), - new StrictNotEqDyn(new VReg()), - new Jeqz(isDone), - new CalliThisRangeDyn(new Imm(ResultType.Int, 1), [nextMethodReg, iterReg]), - isDone, - new LdaDyn(exceptionVreg), - new ThrowDyn(), - - loopEndLabel, - new ReturnUndefined() - ]; - - expect(checkInstructions(insns, expected)).to.be.true; - - let jumps = insns.filter(item => (item instanceof Jmp || item instanceof Jeqz)); - - expect(jumps.length).to.equal(6); - }); - - it("ForIn SyntaxError", function() { - let source: string = `for ([(x, y)] in {}) { }`; - let errorThrown = false; - try { - compileMainSnippet(source); - } catch (err) { - expect(err.code).to.equal(DiagnosticCode.Property_destructuring_pattern_expected); - errorThrown = true; - } - expect(errorThrown).to.be.true; - }); - - it("ForOf SyntaxError", function() { - let source: string = `for ([(x, y)] of []) {}`; - let errorThrown = false; - try { - compileMainSnippet(source); - } catch (err) { - expect(err.code).to.equal(DiagnosticCode.Property_destructuring_pattern_expected); - errorThrown = true; - } - expect(errorThrown).to.be.true; - }); -}); - -describe("WhileLoopTest", function() { - it("while (true) {}", function() { - let insns = compileMainSnippet("while (true) {}"); - let labelPre = new Label(); - let labelPost = new Label(); - let trueReg = new VReg(); - let expected = [ - labelPre, - new LdaDyn(new VReg()), - new Toboolean(), - new EqDyn(trueReg), - new Jeqz(labelPost), - new Jmp(labelPre), - labelPost, - new ReturnUndefined() - ]; - - expect(checkInstructions(insns, expected)).to.be.true; - }); - - it("while (a + b) {}", function() { - let insns = compileMainSnippet("let a, b; while (a + b) {}"); - let loopBegin = new Label(); - let loopEnd = new Label(); - let a = new VReg(); - let b = new VReg(); - let lhs = new VReg(); - let trueReg = new VReg(); - let expected = [ - loopBegin, - // a + b - new LdaDyn(a), - new StaDyn(lhs), - new LdaDyn(b), - new Add2Dyn(lhs), - new Toboolean(), - new EqDyn(trueReg), - new Jeqz(loopEnd), - // body - new Jmp(loopBegin), - loopEnd - ]; - - insns = insns.slice(4, insns.length - 1); // skip let a, b and return.dyn - expect(checkInstructions(insns, expected)).to.be.true; - }); - - it('whileLoopWithBody', function() { - let insns = compileMainSnippet(` - let a; - while (a < 0) { a = 1; } - `); - - let a = new VReg(); - let lhs = new VReg(); - let loopBegin = new Label(); - let loopEnd = new Label(); - let expected = [ - loopBegin, - // condition - // compute lhs - new LdaDyn(a), - new StaDyn(lhs), - // compute rhs - new LdaiDyn(new Imm(ResultType.Int, 0)), - new LessDyn(lhs), - new Jeqz(loopEnd), - - // body - new LdaiDyn(new Imm(ResultType.Int, 1)), - new StaDyn(a), - new Jmp(loopBegin), - - loopEnd, - ]; - - insns = insns.slice(2, insns.length - 1); // skip let a and return.dyn - expect(checkInstructions(insns, expected)).to.be.true; - expect((insns[5]).getTarget() === insns[insns.length - 1]).to.be.true; - expect((insns[insns.length - 2]).getTarget() === insns[0]).to.be.true; - }); - - it('whileLoopWithContinue', function() { - let insns = compileMainSnippet("let a = 5;" + - "while (a < 1) { a = 2; continue; }"); - let a = new VReg(); - let lhs = new VReg(); - let labelPre = new Label(); - let labelPost = new Label(); - let expected = [ - new LdaiDyn(new Imm(ResultType.Int, 5)), - new StaDyn(a), - labelPre, - // condition - new LdaDyn(a), - new StaDyn(lhs), - new LdaiDyn(new Imm(ResultType.Int, 1)), - new LessDyn(lhs), - new Jeqz(labelPost), - //body - new LdaiDyn(new Imm(ResultType.Int, 2)), - new StaDyn(a), - new Jmp(labelPre), // continue - new Jmp(labelPre), - labelPost, - new ReturnUndefined() - ] - // check the instruction kinds are the same as we expect - expect(checkInstructions(insns, expected)).to.be.true; - // check continue jumps to the expected instruction - let jmp = insns[11]; - let targetLabel = (jmp).getTarget(); - expect(targetLabel).to.equal(insns[2]); - }); - - it('whileLoopWithBreak', function() { - let insns = compileMainSnippet("let a = 5;" + - "while (a < 1) { a = 2; break; }"); - let a = new VReg(); - let lhs = new VReg(); - let labelPre = new Label(); - let labelPost = new Label(); - let expected = [ - new LdaiDyn(new Imm(ResultType.Int, 5)), - new StaDyn(a), - labelPre, - // condition - new LdaDyn(a), - new StaDyn(lhs), - new LdaiDyn(new Imm(ResultType.Int, 1)), - new LessDyn(lhs), - new Jeqz(labelPost), - //body - new LdaiDyn(new Imm(ResultType.Int, 2)), - new StaDyn(a), - new Jmp(labelPost), //break - new Jmp(labelPre), - labelPost, - new ReturnUndefined() - ] - // check the instruction kinds are the same as we expect - expect(checkInstructions(insns, expected)).to.be.true; - // check continue jumps to the expected instruction - let jmp = insns[10]; - let targetLabel = (jmp).getTarget(); - expect(targetLabel).to.equal(insns[12]); - }); -}); - -describe("DoWhileLoopTest", function() { - it('doWhileLoopEmpty', function() { - let insns = compileMainSnippet("do {} while (true)"); - - let jumps = insns.filter(item => item instanceof Jmp); - - expect(jumps.length).to.equal(1); - - let jmpLabel = (jumps[0]).getTarget(); - - expect(jmpLabel).to.equal(insns[0]); - }); - - it('doWhileLoopWithBody', function() { - let insns = compileMainSnippet("let a = 5;" + - "do { a++ } while (a < 11);"); - - let jumps = insns.filter(item => (item instanceof Jmp || item instanceof Jeqz)); - - expect(jumps.length).to.equal(2); - - let jgezLabel = (jumps[0]).getTarget(); - let jmpLabel = (jumps[1]).getTarget(); - - expect(jmpLabel).to.equal(insns[2]); - expect(jgezLabel).to.equal(insns[15]); - - expect(insns[13]).to.equal(jumps[0]); - expect(insns[14]).to.equal(jumps[1]); - }); - - it('doWhileLoopWithContinue', function() { - let insns = compileMainSnippet("let a = 5;" + - "do { a = 1; continue; } while (a < 1);"); - let a = new VReg(); - let lhs = new VReg(); - let labelPre = new Label(); - let labelCond = new Label(); - let labelPost = new Label(); - let expected = [ - new LdaiDyn(new Imm(ResultType.Int, 5)), - new StaDyn(a), - // body - labelPre, - new LdaiDyn(new Imm(ResultType.Int, 1)), - new StaDyn(a), - new Jmp(labelCond), // continue - // condition - labelCond, - new LdaDyn(a), - new StaDyn(lhs), - new LdaiDyn(new Imm(ResultType.Int, 1)), - new LessDyn(lhs), - new Jeqz(labelPost), - new Jmp(labelPre), - labelPost, - new ReturnUndefined() - ] - // check the instruction kinds are the same as we expect - expect(checkInstructions(insns, expected)).to.be.true; - // check continue jumps to the expected instruction - let jmp = insns[5]; - let targetLabel = (jmp).getTarget(); - expect(targetLabel).to.equal(insns[6]); - }); - - it('doWhileLoopWithBreak', function() { - let insns = compileMainSnippet("let a = 5;" + - "do { a = 1; break; } while (a < 1);"); - let a = new VReg(); - let lhs = new VReg(); - let labelPre = new Label(); - let labelPost = new Label(); - let labelCond = new Label(); - let expected = [ - new LdaiDyn(new Imm(ResultType.Int, 5)), - new StaDyn(a), - //body - labelPre, - new LdaiDyn(new Imm(ResultType.Int, 1)), - new StaDyn(a), - new Jmp(labelPost), // break - // condition - labelCond, - new LdaDyn(a), - new StaDyn(lhs), - new LdaiDyn(new Imm(ResultType.Int, 1)), - new LessDyn(lhs), - new Jeqz(labelPost), - new Jmp(labelPre), - labelPost, - new ReturnUndefined() - ] - // check the instruction kinds are the same as we expect - expect(checkInstructions(insns, expected)).to.be.true; - // check continue jumps to the expected instruction - let jmp = insns[5]; - let targetLabel = (jmp).getTarget(); - expect(targetLabel).to.equal(insns[13]); - }); -}); - -describe("LoopWithLabelTests", function() { - it('forLoopWithBreakWithLabel', function() { - let insns = compileMainSnippet(`loop1: - for (let i = 0; i < 5; ++i) { - for (let j = 0; j < 6; j++) { - break loop1; - } - }`); - let i = new VReg(); - let j = new VReg(); - let lhs = new VReg(); - let labelPre = new Label(); - let labelPost = new Label(); - let labelIncr = new Label(); - let labelPre1 = new Label(); - let labelPost1 = new Label(); - let labelIncr1 = new Label(); - let expected = [ - // initializer - new LdaiDyn(new Imm(ResultType.Int, 0.0)), - new StaDyn(i), - labelPre, - // condition - new LdaDyn(i), - new StaDyn(lhs), - new LdaiDyn(new Imm(ResultType.Int, 5.0)), - new LessDyn(lhs), - new Jeqz(labelPost), - - // second for - new LdaiDyn(new Imm(ResultType.Int, 0.0)), - new StaDyn(j), - labelPre1, - // condition - new LdaDyn(j), - new StaDyn(lhs), - new LdaiDyn(new Imm(ResultType.Int, 6.0)), - new LessDyn(lhs), - new Jeqz(labelPost1), - new Jmp(labelPost), - labelIncr1, - // incrementor - new LdaDyn(j), - new StaDyn(j), - new IncDyn(j), - new StaDyn(j), - new Tonumber(j), - // jump to the loop header - new Jmp(labelPre1), - labelPost1, - labelIncr, - // incrementor - new LdaDyn(i), - new StaDyn(i), - new IncDyn(i), - new StaDyn(i), - // jump to the loop header - new Jmp(labelPre), - labelPost, - new ReturnUndefined() - ]; - - // check the instruction kinds are the same as we expect - expect(checkInstructions(insns, expected)).to.be.true; - // check break jumps to the expected instruction - let jmp = insns[16]; - let targetLabel = (jmp).getTarget(); - expect(targetLabel).to.equal(insns[31]); - }); - - it('forLoopWithContinueWithLabel', function() { - let insns = compileMainSnippet(`loop1: - loop2: - loop3: - for (let i = 0; i < 5; ++i) { - for (let j = 0; j < 6; j++) { - continue loop2; - } - }`); - let i = new VReg(); - let j = new VReg(); - let lhs = new VReg(); - let labelPre = new Label(); - let labelPost = new Label(); - let labelIncr = new Label(); - let labelPre1 = new Label(); - let labelPost1 = new Label(); - let labelIncr1 = new Label(); - let expected = [ - // initializer - new LdaiDyn(new Imm(ResultType.Int, 0.0)), - new StaDyn(i), - labelPre, - // condition - new LdaDyn(i), - new StaDyn(lhs), - new LdaiDyn(new Imm(ResultType.Int, 5.0)), - new LessDyn(lhs), - new Jeqz(labelPost), - - // second for - new LdaiDyn(new Imm(ResultType.Int, 0.0)), - new StaDyn(j), - labelPre1, - // condition - new LdaDyn(j), - new StaDyn(lhs), - new LdaiDyn(new Imm(ResultType.Int, 6.0)), - new LessDyn(lhs), - new Jeqz(labelPost1), - new Jmp(labelIncr), - labelIncr1, - // incrementor - new LdaDyn(j), - new StaDyn(j), - new IncDyn(j), - new StaDyn(j), - new Tonumber(j), - // jump to the loop header - new Jmp(labelPre1), - labelPost1, - labelIncr, - // incrementor - new LdaDyn(i), - new StaDyn(i), - new IncDyn(i), - new StaDyn(i), - // jump to the loop header - new Jmp(labelPre), - labelPost, - new ReturnUndefined() - ]; - - // check the instruction kinds are the same as we expect - expect(checkInstructions(insns, expected)).to.be.true; - // check break jumps to the expected instruction - let jmp = insns[16]; - let targetLabel = (jmp).getTarget(); - expect(targetLabel).to.equal(insns[25]); - }); -}); +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + expect +} from 'chai'; +import 'mocha'; +import { + EcmaIncdyn, + EcmaLessdyn, + EcmaReturnundefined, + EcmaTonumber, + Imm, + Jeqz, + Jmp, + Label, + LdaDyn, + LdaiDyn, + ResultType, + StaDyn, + VReg +} from "../../src/irnodes"; +import { checkInstructions, compileMainSnippet } from "../utils/base"; + +describe("ForLoopTest", function () { + it('forLoopEmpty', function () { + let insns = compileMainSnippet("for (;;) {}"); + let labelPre = new Label(); + let labelPost = new Label(); + let labelIncr = new Label(); + let expected = [ + labelPre, + labelIncr, + new Jmp(labelPre), + labelPost, + new EcmaReturnundefined() + ]; + let jumps = insns.filter(item => item instanceof Jmp); + + expect(jumps.length).to.equal(1); + + let jmpLabel = (jumps[0]).getTarget(); + + expect(checkInstructions(insns, expected)).to.be.true; + expect(jmpLabel).to.equal(insns[0]); + }); + + it('forLoopWithInitializer', function () { + let insns = compileMainSnippet("for (let i = 0;;) {}"); + let jumps = insns.filter(item => item instanceof Jmp); + + expect(jumps.length).to.equal(1); + + let jmpLabel = (jumps[0]).getTarget(); + + expect(insns[4]).to.equal(jumps[0]); + expect(jmpLabel).to.equal(insns[2]); + }); + + it('forLoopWithInitializerAndCondition', function () { + let insns = compileMainSnippet("for (let i = 0; i < 5;) {}"); + let jumps = insns.filter(item => (item instanceof Jmp || item instanceof Jeqz)); + + expect(jumps.length).to.equal(2); + + let jgezLabel = (jumps[0]).getTarget(); + let jmpLabel = (jumps[1]).getTarget(); + + expect(jmpLabel).to.equal(insns[2]); + expect(jgezLabel).to.equal(insns[10]); + + expect(insns[7]).to.equal(jumps[0]); + expect(insns[9]).to.equal(jumps[1]); + }); + + it('forLoopWithInitializerAndConditionAndIncrementor', function () { + let insns = compileMainSnippet("for (let i = 0; i < 5; i++) {}"); + let jumps = insns.filter(item => (item instanceof Jmp || item instanceof Jeqz)); + + expect(jumps.length).to.equal(2); + + let jgezLabel = (jumps[0]).getTarget(); + let jmpLabel = (jumps[1]).getTarget(); + + expect(jmpLabel).to.equal(insns[2]); + expect(jgezLabel).to.equal(insns[15]); + + expect(insns[7]).to.equal(jumps[0]); + expect(insns[14]).to.equal(jumps[1]); + }); + + it('forLoopWithContinue', function () { + let insns = compileMainSnippet("for (let i = 0; i < 5; ++i) { continue; }"); + let i = new VReg(); + let lhs = new VReg(); + let operand = new VReg(); + let labelPre = new Label(); + let labelPost = new Label(); + let labelIncr = new Label(); + let expected = [ + // initializer + new LdaiDyn(new Imm(ResultType.Int, 0)), + new StaDyn(i), + labelPre, + // condition + new LdaDyn(i), + new StaDyn(lhs), + new LdaiDyn(new Imm(ResultType.Int, 5)), + new EcmaLessdyn(lhs), + new Jeqz(labelPost), + // body + new Jmp(labelIncr), // continue + labelIncr, + // incrementor + new LdaDyn(i), + new StaDyn(operand), + new EcmaIncdyn(operand), + new StaDyn(i), + // jump to the loop header + new Jmp(new Label()), + labelPost, + new EcmaReturnundefined() + ]; + // check the instruction kinds are the same as we expect + expect(checkInstructions(insns, expected)).to.be.true; + // check continue jumps to the expected instruction + let jmp = insns[8]; + let targetLabel = (jmp).getTarget(); + expect(targetLabel).to.equal(insns[9]); + }); + + it('forLoopWithBreak', function () { + let insns = compileMainSnippet("for (let i = 0; i < 5; ++i) {break; }"); + let i = new VReg(); + let lhs = new VReg(); + let operand = new VReg(); + let labelPre = new Label(); + let labelPost = new Label(); + let labelIncr = new Label(); + let expected = [ + // initializer + new LdaiDyn(new Imm(ResultType.Int, 0)), + new StaDyn(i), + labelPre, + // condition + new LdaDyn(i), + new StaDyn(lhs), + new LdaiDyn(new Imm(ResultType.Int, 5)), + new EcmaLessdyn(lhs), + new Jeqz(labelPost), + // body + new Jmp(labelPost), // break + // incrementor + labelIncr, + new LdaDyn(i), + new StaDyn(operand), + new EcmaIncdyn(operand), + new StaDyn(i), + // jump to the loop header + new Jmp(labelPre), + labelPost, + new EcmaReturnundefined() + ]; + // check the instruction kinds are the same as we expect + expect(checkInstructions(insns, expected)).to.be.true; + // check continue jumps to the expected instruction + let jmp = insns[8]; + let targetLabel = (jmp).getTarget(); + expect(targetLabel).to.equal(insns[15]); + }); +}); + +describe("LoopWithLabelTests", function () { + it('forLoopWithBreakWithLabel', function () { + let insns = compileMainSnippet(`loop1: + for (let i = 0; i < 5; ++i) { + for (let j = 0; j < 6; j++) { + break loop1; + } + }`); + let i = new VReg(); + let j = new VReg(); + let lhs = new VReg(); + let labelPre = new Label(); + let labelPost = new Label(); + let labelIncr = new Label(); + let labelPre1 = new Label(); + let labelPost1 = new Label(); + let labelIncr1 = new Label(); + let expected = [ + // initializer + new LdaiDyn(new Imm(ResultType.Int, 0.0)), + new StaDyn(i), + labelPre, + // condition + new LdaDyn(i), + new StaDyn(lhs), + new LdaiDyn(new Imm(ResultType.Int, 5.0)), + new EcmaLessdyn(lhs), + new Jeqz(labelPost), + + // second for + new LdaiDyn(new Imm(ResultType.Int, 0.0)), + new StaDyn(j), + labelPre1, + // condition + new LdaDyn(j), + new StaDyn(lhs), + new LdaiDyn(new Imm(ResultType.Int, 6.0)), + new EcmaLessdyn(lhs), + new Jeqz(labelPost1), + new Jmp(labelPost), + labelIncr1, + // incrementor + new LdaDyn(j), + new StaDyn(j), + new EcmaIncdyn(j), + new StaDyn(j), + new EcmaTonumber(j), + // jump to the loop header + new Jmp(labelPre1), + labelPost1, + labelIncr, + // incrementor + new LdaDyn(i), + new StaDyn(i), + new EcmaIncdyn(i), + new StaDyn(i), + // jump to the loop header + new Jmp(labelPre), + labelPost, + new EcmaReturnundefined() + ]; + + // check the instruction kinds are the same as we expect + expect(checkInstructions(insns, expected)).to.be.true; + // check break jumps to the expected instruction + let jmp = insns[16]; + let targetLabel = (jmp).getTarget(); + expect(targetLabel).to.equal(insns[31]); + }); + + it('forLoopWithContinueWithLabel', function () { + let insns = compileMainSnippet(`loop1: + loop2: + loop3: + for (let i = 0; i < 5; ++i) { + for (let j = 0; j < 6; j++) { + continue loop2; + } + }`); + let i = new VReg(); + let j = new VReg(); + let lhs = new VReg(); + let labelPre = new Label(); + let labelPost = new Label(); + let labelIncr = new Label(); + let labelPre1 = new Label(); + let labelPost1 = new Label(); + let labelIncr1 = new Label(); + let expected = [ + // initializer + new LdaiDyn(new Imm(ResultType.Int, 0.0)), + new StaDyn(i), + labelPre, + // condition + new LdaDyn(i), + new StaDyn(lhs), + new LdaiDyn(new Imm(ResultType.Int, 5.0)), + new EcmaLessdyn(lhs), + new Jeqz(labelPost), + + // second for + new LdaiDyn(new Imm(ResultType.Int, 0.0)), + new StaDyn(j), + labelPre1, + // condition + new LdaDyn(j), + new StaDyn(lhs), + new LdaiDyn(new Imm(ResultType.Int, 6.0)), + new EcmaLessdyn(lhs), + new Jeqz(labelPost1), + new Jmp(labelIncr), + labelIncr1, + // incrementor + new LdaDyn(j), + new StaDyn(j), + new EcmaIncdyn(j), + new StaDyn(j), + new EcmaTonumber(j), + // jump to the loop header + new Jmp(labelPre1), + labelPost1, + labelIncr, + // incrementor + new LdaDyn(i), + new StaDyn(i), + new EcmaIncdyn(i), + new StaDyn(i), + // jump to the loop header + new Jmp(labelPre), + labelPost, + new EcmaReturnundefined() + ]; + + // check the instruction kinds are the same as we expect + expect(checkInstructions(insns, expected)).to.be.true; + // check break jumps to the expected instruction + let jmp = insns[16]; + let targetLabel = (jmp).getTarget(); + expect(targetLabel).to.equal(insns[25]); + }); +}); diff --git a/ts2panda/tests/statements/forIn.test.ts b/ts2panda/tests/statements/forIn.test.ts index 93348bfc36fd2584a7c414501b454c3059855b85..374f6c7b400e99914b0a990da06c6c39d3c939f6 100755 --- a/ts2panda/tests/statements/forIn.test.ts +++ b/ts2panda/tests/statements/forIn.test.ts @@ -17,24 +17,26 @@ import { expect } from 'chai'; import 'mocha'; -import { couldStartTrivia } from 'typescript'; +import { DiagnosticCode, DiagnosticError } from '../../src/diagnostic'; import { - CreateEmptyObject, - GetNextPropName, - GetPropertiesIterator, + EcmaCreateemptyobject, + EcmaGetnextpropname, + EcmaGetpropiterator, + EcmaReturnundefined, + EcmaStrictnoteqdyn, + EcmaTryldglobalbyname, + EcmaTrystglobalbyname, Jeqz, Jmp, Label, LdaDyn, - ReturnUndefined, StaDyn, - StrictNotEqDyn, VReg } from "../../src/irnodes"; import { checkInstructions, compileMainSnippet } from "../utils/base"; -describe("forInLoopTest", function() { - it("forInLoopwithEmptyObject", function() { +describe("forInLoopTest", function () { + it("forInLoopwithEmptyObject", function () { let insns = compileMainSnippet("for (let prop in {}) {}"); let prop = new VReg(); let temp = new VReg(); @@ -45,22 +47,22 @@ describe("forInLoopTest", function() { let loopStartLabel = new Label(); let loopEndLabel = new Label(); let expected = [ - new CreateEmptyObject(), + new EcmaCreateemptyobject(), new StaDyn(objInstance), - new GetPropertiesIterator(), + new EcmaGetpropiterator(), new StaDyn(iterReg), loopStartLabel, - new GetNextPropName(iterReg), + new EcmaGetnextpropname(iterReg), new StaDyn(rhs), - new StrictNotEqDyn(temp), + new EcmaStrictnoteqdyn(temp), new Jeqz(loopEndLabel), new LdaDyn(rhs), new StaDyn(prop), new Jmp(loopStartLabel), loopEndLabel, - new ReturnUndefined() + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; @@ -69,7 +71,7 @@ describe("forInLoopTest", function() { expect(jumps.length).to.equal(2); }); - it("forInLoopWithExpressionAsLoopVariable", function() { + it("forInLoopWithExpressionAsLoopVariable", function () { let insns = compileMainSnippet(` let prop; let obj; @@ -77,31 +79,29 @@ describe("forInLoopTest", function() { } `); let temp = new VReg(); - let prop = new VReg(); - let obj = new VReg(); let iterReg = new VReg(); let rhs = new VReg(); let loopStartLabel = new Label(); let loopEndLabel = new Label(); let expected = [ - new LdaDyn(obj), - new GetPropertiesIterator(), + new EcmaTryldglobalbyname('obj'), + new EcmaGetpropiterator(), new StaDyn(iterReg), loopStartLabel, - new GetNextPropName(iterReg), + new EcmaGetnextpropname(iterReg), new StaDyn(rhs), - new StrictNotEqDyn(temp), + new EcmaStrictnoteqdyn(temp), new Jeqz(loopEndLabel), new LdaDyn(rhs), - new StaDyn(prop), + new EcmaTrystglobalbyname('prop'), new Jmp(loopStartLabel), loopEndLabel, ]; - insns = insns.slice(4, insns.length - 1); + insns = insns.slice(4, insns.length - 1); expect(checkInstructions(insns, expected)).to.be.true; let jmp = insns.find(item => (item instanceof Jmp)); @@ -110,7 +110,7 @@ describe("forInLoopTest", function() { expect(jeqz.getTarget()).to.equal(insns[insns.length - 1]); }); - it("forInLoopwithObjectwithContinue", function() { + it("forInLoopwithObjectwithContinue", function () { let insns = compileMainSnippet("for (let prop in {}) {continue; }"); let prop = new VReg(); let temp = new VReg(); @@ -121,15 +121,15 @@ describe("forInLoopTest", function() { let loopStartLabel = new Label(); let loopEndLabel = new Label(); let expected = [ - new CreateEmptyObject(), + new EcmaCreateemptyobject(), new StaDyn(objInstance), - new GetPropertiesIterator(), + new EcmaGetpropiterator(), new StaDyn(iterReg), loopStartLabel, - new GetNextPropName(iterReg), + new EcmaGetnextpropname(iterReg), new StaDyn(rhs), - new StrictNotEqDyn(temp), + new EcmaStrictnoteqdyn(temp), new Jeqz(loopEndLabel), new LdaDyn(rhs), new StaDyn(prop), @@ -137,7 +137,7 @@ describe("forInLoopTest", function() { new Jmp(loopStartLabel), loopEndLabel, - new ReturnUndefined() + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; @@ -146,7 +146,7 @@ describe("forInLoopTest", function() { expect(jumps.length).to.equal(3); }); - it("forInLoopwithObjectwithBreak", function() { + it("forInLoopwithObjectwithBreak", function () { let insns = compileMainSnippet("for (let prop in {}) {break; }"); let prop = new VReg(); let temp = new VReg(); @@ -157,15 +157,15 @@ describe("forInLoopTest", function() { let loopStartLabel = new Label(); let loopEndLabel = new Label(); let expected = [ - new CreateEmptyObject(), + new EcmaCreateemptyobject(), new StaDyn(objInstance), - new GetPropertiesIterator(), + new EcmaGetpropiterator(), new StaDyn(iterReg), loopStartLabel, - new GetNextPropName(iterReg), + new EcmaGetnextpropname(iterReg), new StaDyn(rhs), - new StrictNotEqDyn(temp), + new EcmaStrictnoteqdyn(temp), new Jeqz(loopEndLabel), new LdaDyn(rhs), new StaDyn(prop), @@ -173,7 +173,7 @@ describe("forInLoopTest", function() { new Jmp(loopStartLabel), loopEndLabel, - new ReturnUndefined() + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; @@ -181,4 +181,17 @@ describe("forInLoopTest", function() { expect(jumps.length).to.equal(3); }); + + it("ForIn SyntaxError", function () { + let source: string = `for ([(x, y)] in {}) { }`; + let errorThrown = false; + try { + compileMainSnippet(source); + } catch (err) { + expect(err instanceof DiagnosticError).to.be.true; + expect((err).code).to.equal(DiagnosticCode.Property_destructuring_pattern_expected); + errorThrown = true; + } + expect(errorThrown).to.be.true; + }); }); diff --git a/ts2panda/tests/statements/forOf.test.ts b/ts2panda/tests/statements/forOf.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..bf2963edfe391d4f5de107272aa84d17aac06955 --- /dev/null +++ b/ts2panda/tests/statements/forOf.test.ts @@ -0,0 +1,305 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + expect +} from 'chai'; +import 'mocha'; +import { DiagnosticCode, DiagnosticError } from '../../src/diagnostic'; +import { + EcmaCallithisrangedyn, + EcmaCreateemptyarray, + EcmaGetiterator, + EcmaIsfalse, + EcmaLdobjbyname, + EcmaReturnundefined, + EcmaStrictnoteqdyn, + EcmaThrowdyn, + EcmaThrowifnotobject, + Imm, + Jeqz, + Jmp, + Label, + LdaDyn, ResultType, + StaDyn, + VReg +} from "../../src/irnodes"; +import { checkInstructions, compileMainSnippet } from "../utils/base"; + +describe("ForOfLoopTest", function () { + it("forOfLoopWithEmptyArray", function () { + let insns = compileMainSnippet("for (let a of []) {}"); + let a = new VReg(); + let arrInstance = new VReg(); + let iterReg = new VReg(); + let nextMethodReg = new VReg(); + let resultObj = new VReg(); + let exceptionVreg = new VReg(); + let trueReg = new VReg(); + let done = new VReg(); + let value = new VReg(); + + let loopStartLabel = new Label(); + let loopEndLabel = new Label(); + let tryBeginLabel = new Label(); + let tryEndLabel = new Label(); + let catchBeginLabel = new Label(); + let isDone = new Label(); + + let expected = [ + new EcmaCreateemptyarray(), + new StaDyn(arrInstance), + new EcmaGetiterator(), + new StaDyn(iterReg), + new EcmaLdobjbyname("next", iterReg), + new StaDyn(nextMethodReg), + + new LdaDyn(new VReg()), + new StaDyn(done), + + tryBeginLabel, + new LdaDyn(trueReg), + new StaDyn(done), + loopStartLabel, + new EcmaCallithisrangedyn(new Imm(ResultType.Int, 1), [nextMethodReg, iterReg]), + new StaDyn(resultObj), + new EcmaThrowifnotobject(resultObj), + new EcmaLdobjbyname("done", resultObj), + new EcmaIsfalse(), + new Jeqz(loopEndLabel), + new EcmaLdobjbyname("value", resultObj), + new StaDyn(value), + + new LdaDyn(new VReg()), + new StaDyn(done), + + new LdaDyn(value), + new StaDyn(a), + tryEndLabel, + + new Jmp(loopStartLabel), + + catchBeginLabel, + new StaDyn(exceptionVreg), + new LdaDyn(done), + new EcmaStrictnoteqdyn(trueReg), + new Jeqz(isDone), + new EcmaLdobjbyname("return", iterReg), + new StaDyn(nextMethodReg), + new EcmaStrictnoteqdyn(new VReg()), + new Jeqz(isDone), + new EcmaCallithisrangedyn(new Imm(ResultType.Int, 1), [nextMethodReg, iterReg]), + isDone, + new LdaDyn(exceptionVreg), + new EcmaThrowdyn(), + + loopEndLabel, + new EcmaReturnundefined() + ]; + expect(checkInstructions(insns, expected)).to.be.true; + + let jumps = insns.filter(item => (item instanceof Jmp || item instanceof Jeqz)); + + expect(jumps.length).to.equal(4); + }); + + it("forOfLoopWithContinue", function () { + let insns = compileMainSnippet("for (let a of []) {continue;}"); + let a = new VReg(); + let arrInstance = new VReg(); + let resultObj = new VReg(); + let trueReg = new VReg(); + let iterReg = new VReg(); + let exceptionVreg = new VReg(); + let nextMethodReg = new VReg(); + let done = new VReg(); + let value = new VReg(); + + let loopStartLabel = new Label(); + let loopEndLabel = new Label(); + let tryBeginLabel = new Label(); + let tryEndLabel = new Label(); + let catchBeginLabel = new Label(); + let isDone = new Label(); + let insertedtryBeginLabel = new Label(); + let insertedtryEndLabel = new Label(); + + let expected = [ + new EcmaCreateemptyarray(), + new StaDyn(arrInstance), + new EcmaGetiterator(), + new StaDyn(iterReg), + new EcmaLdobjbyname("next", iterReg), + new StaDyn(nextMethodReg), + + new LdaDyn(new VReg()), + new StaDyn(done), + + tryBeginLabel, + new LdaDyn(trueReg), + new StaDyn(done), + loopStartLabel, + new EcmaCallithisrangedyn(new Imm(ResultType.Int, 1), [nextMethodReg, iterReg]), + new StaDyn(resultObj), + new EcmaThrowifnotobject(resultObj), + new EcmaLdobjbyname("done", resultObj), + new EcmaIsfalse(), + new Jeqz(loopEndLabel), + new EcmaLdobjbyname("value", resultObj), + new StaDyn(value), + + new LdaDyn(new VReg()), + new StaDyn(done), + + new LdaDyn(value), + new StaDyn(a), + + insertedtryBeginLabel, + insertedtryEndLabel, + new Jmp(loopStartLabel), + + tryEndLabel, + + new Jmp(loopStartLabel), + + catchBeginLabel, + new StaDyn(exceptionVreg), + new LdaDyn(done), + new EcmaStrictnoteqdyn(trueReg), + new Jeqz(isDone), + new EcmaLdobjbyname("return", iterReg), + new StaDyn(nextMethodReg), + new EcmaStrictnoteqdyn(new VReg()), + new Jeqz(isDone), + new EcmaCallithisrangedyn(new Imm(ResultType.Int, 1), [nextMethodReg, iterReg]), + isDone, + new LdaDyn(exceptionVreg), + new EcmaThrowdyn(), + + loopEndLabel, + new EcmaReturnundefined() + ]; + expect(checkInstructions(insns, expected)).to.be.true; + + let jumps = insns.filter(item => (item instanceof Jmp || item instanceof Jeqz)); + + expect(jumps.length).to.equal(5); + }); + + it("forOfLoopWithBreak", function () { + let insns = compileMainSnippet("for (let a of []) {break;}"); + let a = new VReg(); + let arrInstance = new VReg(); + let resultObj = new VReg(); + let exceptionVreg = new VReg(); + let iterReg = new VReg(); + let trueReg = new VReg(); + let nextMethodReg = new VReg(); + let done = new VReg(); + let value = new VReg(); + let loopStartLabel = new Label(); + let loopEndLabel = new Label(); + let tryBeginLabel = new Label(); + let tryEndLabel = new Label(); + let catchBeginLabel = new Label(); + let isDone = new Label(); + let noReturn = new Label(); + let insertedtryBeginLabel = new Label(); + let insertedtryEndLabel = new Label(); + + let expected = [ + new EcmaCreateemptyarray(), + new StaDyn(arrInstance), + new EcmaGetiterator(), + new StaDyn(iterReg), + new EcmaLdobjbyname("next", iterReg), + new StaDyn(nextMethodReg), + + new LdaDyn(new VReg()), + new StaDyn(done), + + tryBeginLabel, + new LdaDyn(trueReg), + new StaDyn(done), + loopStartLabel, + new EcmaCallithisrangedyn(new Imm(ResultType.Int, 1), [nextMethodReg, iterReg]), + new StaDyn(resultObj), + new EcmaThrowifnotobject(resultObj), + new EcmaLdobjbyname("done", resultObj), + new EcmaIsfalse(), + new Jeqz(loopEndLabel), + new EcmaLdobjbyname("value", resultObj), + new StaDyn(value), + + new LdaDyn(new VReg()), + new StaDyn(done), + + new LdaDyn(value), + new StaDyn(a), + + insertedtryBeginLabel, + new EcmaLdobjbyname("return", iterReg), + new StaDyn(nextMethodReg), + new EcmaStrictnoteqdyn(new VReg()), // undefined + new Jeqz(noReturn), + new EcmaCallithisrangedyn(new Imm(ResultType.Int, 1), [nextMethodReg, iterReg]), + new StaDyn(new VReg()), + new EcmaThrowifnotobject(new VReg()), + noReturn, + insertedtryEndLabel, + new Jmp(loopEndLabel), + + tryEndLabel, + + new Jmp(loopStartLabel), + + catchBeginLabel, + new StaDyn(exceptionVreg), + new LdaDyn(done), + new EcmaStrictnoteqdyn(trueReg), + new Jeqz(isDone), + new EcmaLdobjbyname("return", iterReg), + new StaDyn(nextMethodReg), + new EcmaStrictnoteqdyn(new VReg()), + new Jeqz(isDone), + new EcmaCallithisrangedyn(new Imm(ResultType.Int, 1), [nextMethodReg, iterReg]), + isDone, + new LdaDyn(exceptionVreg), + new EcmaThrowdyn(), + + loopEndLabel, + new EcmaReturnundefined() + ]; + + expect(checkInstructions(insns, expected)).to.be.true; + + let jumps = insns.filter(item => (item instanceof Jmp || item instanceof Jeqz)); + + expect(jumps.length).to.equal(6); + }); + + it("ForOf SyntaxError", function () { + let source: string = `for ([(x, y)] of []) {}`; + let errorThrown = false; + try { + compileMainSnippet(source); + } catch (err) { + expect(err instanceof DiagnosticError).to.be.true; + expect((err).code).to.equal(DiagnosticCode.Property_destructuring_pattern_expected); + errorThrown = true; + } + expect(errorThrown).to.be.true; + }); +}); diff --git a/ts2panda/tests/statements/functionDeclaration.test.ts b/ts2panda/tests/statements/functionDeclaration.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..a62f826d80b0d40d2bcd1dff7772cb402702141e --- /dev/null +++ b/ts2panda/tests/statements/functionDeclaration.test.ts @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + expect +} from 'chai'; +import 'mocha'; +import { + EcmaCopyrestargs, + EcmaDefinefuncdyn, + EcmaReturnundefined, + EcmaStglobalvar, + EcmaStlettoglobalrecord, + EcmaStricteqdyn, + Imm, + Jeqz, + Label, + LdaDyn, + LdaiDyn, + ResultType, + StaDyn, + VReg +} from "../../src/irnodes"; +import { + GlobalVariable, + LocalVariable +} from "../../src/variable"; +import { checkInstructions, compileAllSnippet, SnippetCompiler } from "../utils/base"; + +describe("FunctionDeclarationTest", function () { + it('function definition in the global scope', function () { + let snippetCompiler = new SnippetCompiler(); + snippetCompiler.compile("function foo() {}"); + let funcName = "foo"; + let expected = [ + new EcmaDefinefuncdyn(funcName, new Imm(ResultType.Int, 0), new VReg()), + new EcmaStglobalvar(funcName), + new EcmaReturnundefined() + ]; + let insns = snippetCompiler.getGlobalInsns(); + let globalScope = snippetCompiler.getGlobalScope(); + expect(checkInstructions(insns, expected)).to.be.true; + let foo = globalScope!.findLocal(funcName); + expect(foo != undefined).to.be.true; + expect(foo instanceof GlobalVariable).to.be.true; + }); + + it('function redefinition in the global scope', function () { + let snippetCompiler = new SnippetCompiler(); + snippetCompiler.compile(` + function foo() {} + function foo() {} + `); + let expected = [ + new EcmaDefinefuncdyn("#2#foo", new Imm(ResultType.Int, 0), new VReg()), + new EcmaStglobalvar("foo"), + new EcmaReturnundefined() + ]; + let insns = snippetCompiler.getGlobalInsns(); + let globalScope = snippetCompiler.getGlobalScope(); + expect(checkInstructions(insns, expected)).to.be.true; + let foo = globalScope!.findLocal("foo"); + expect(foo != undefined).to.be.true; + expect(foo instanceof GlobalVariable).to.be.true; + }); + + it('function definition inside a function', function () { + let snippetCompiler = new SnippetCompiler(); + snippetCompiler.compile(`function out() {function foo() {}}`); + let funcReg = new VReg(); + let expected = [ + new EcmaDefinefuncdyn("foo", new Imm(ResultType.Int, 0), new VReg()), + new StaDyn(funcReg), + + new EcmaReturnundefined() + ]; + let functionPg = snippetCompiler.getPandaGenByName("out"); + let insns = functionPg!.getInsns(); + let functionScope = functionPg!.getScope(); + + expect(checkInstructions(insns!, expected)).to.be.true; + let foo = functionScope!.findLocal("foo"); + expect(foo != undefined).to.be.true; + expect(foo instanceof LocalVariable).to.be.true; + let parameterLength = functionPg!.getParameterLength(); + expect(parameterLength == 0).to.be.true; + }); + + it("function expression", function () { + let snippetCompiler = new SnippetCompiler(); + snippetCompiler.compile("let foo = function() {}"); + let insns = snippetCompiler.getGlobalInsns(); + let expected = [ + new EcmaDefinefuncdyn("foo", new Imm(ResultType.Int, 0), new VReg()), + new EcmaStlettoglobalrecord("foo"), + new EcmaReturnundefined() + ]; + expect(checkInstructions(insns, expected)).to.be.true; + }); + + it("Parameters with initializer", function () { + let compilerunit = compileAllSnippet("function test(a, b = 1) {}"); + let undefinedVReg = new VReg(); + let value = new VReg(); + let endLabel = new Label(); + + let expected_main = [ + new EcmaDefinefuncdyn("test", new Imm(ResultType.Int, 1), new VReg()), + new EcmaStglobalvar("test"), + new EcmaReturnundefined() + ]; + let expected_func = [ + // func_test_0 + new LdaDyn(new VReg()), + new EcmaStricteqdyn(undefinedVReg), + new Jeqz(endLabel), + new LdaiDyn(new Imm(ResultType.Int, 1)), + new StaDyn(value), + endLabel, + new EcmaReturnundefined(), + ]; + + compilerunit.forEach(element => { + if (element.internalName == "func_main_0") { + let insns = element.getInsns(); + expect(checkInstructions(insns, expected_main)).to.be.true; + } else if (element.internalName == "test") { + let insns = element.getInsns(); + expect(checkInstructions(insns, expected_func)).to.be.true; + let parameterLength = element.getParameterLength(); + expect(parameterLength == 1).to.be.true; + } + }); + }); + + it("Rest Parameters", function () { + let snippetCompiler = new SnippetCompiler(); + snippetCompiler.compile(`function test(a, ...b) {}`); + + let idx = new Imm(ResultType.Int, 1); + let lastParam = new VReg(); + let expected_func = [ + // func_test_0 + new EcmaCopyrestargs(idx), + new StaDyn(lastParam), + new EcmaReturnundefined(), + ]; + + let functionPg = snippetCompiler.getPandaGenByName("test"); + let insns = functionPg!.getInsns(); + + expect(checkInstructions(insns, expected_func)).to.be.true; + }); +}); diff --git a/ts2panda/tests/returnStatement.test.ts b/ts2panda/tests/statements/return.test.ts similarity index 68% rename from ts2panda/tests/returnStatement.test.ts rename to ts2panda/tests/statements/return.test.ts index 9c4b77a7a3e0869990767f1e2a217eb81e9f727b..7528c8dffc7f7563c8cb206d207ba2482925b63a 100644 --- a/ts2panda/tests/returnStatement.test.ts +++ b/ts2panda/tests/statements/return.test.ts @@ -17,12 +17,12 @@ import { expect } from 'chai'; import 'mocha'; -import { ReturnUndefined } from "../src/irnodes"; -import { compileMainSnippet } from "./utils/base"; +import { EcmaReturnundefined } from "../../src/irnodes"; +import { compileMainSnippet } from "../utils/base"; -describe("ReturnStatementTest", function() { - it('exitGlobalScope', function() { - let insns = compileMainSnippet("var a;"); - expect(insns[insns.length - 1] instanceof ReturnUndefined).to.be.true; - }); +describe("ReturnStatementTest", function () { + it('exitGlobalScope', function () { + let insns = compileMainSnippet("var a;"); + expect(insns[insns.length - 1] instanceof EcmaReturnundefined).to.be.true; + }); }); diff --git a/ts2panda/tests/statements/switch.test.ts b/ts2panda/tests/statements/switch.test.ts index 2a04ef11be2fb9077577f19e787cc341f5c209f0..91cb0a12552ddbeb8bc9f6d36a41d59179eb884e 100755 --- a/ts2panda/tests/statements/switch.test.ts +++ b/ts2panda/tests/statements/switch.test.ts @@ -18,24 +18,23 @@ import { } from 'chai'; import 'mocha'; import { + EcmaReturnundefined, + EcmaStlettoglobalrecord, + EcmaStrictnoteqdyn, + EcmaTryldglobalbyname, Imm, Jeqz, Jmp, Jnez, - Label, - LdaDyn, - LdaiDyn, + Label, LdaiDyn, ResultType, - ReturnDyn, - ReturnUndefined, StaDyn, - StrictNotEqDyn, VReg } from "../../src/irnodes"; import { checkInstructions, compileMainSnippet } from "../utils/base"; -describe("switchTest", function() { - it("single case", function() { +describe("switchTest", function () { + it("single case", function () { let insns = compileMainSnippet("let a = 0; switch (a) {case 0 : ;}"); let a = new VReg(); let rhs = new VReg(); @@ -43,32 +42,31 @@ describe("switchTest", function() { let switchEndLabel = new Label(); let expected = [ new LdaiDyn(new Imm(ResultType.Int, 0)), - new StaDyn(a), + new EcmaStlettoglobalrecord('a'), // switch body - new LdaDyn(a), + new EcmaTryldglobalbyname('a'), new StaDyn(rhs), new LdaiDyn(new Imm(ResultType.Int, 0)), - new StrictNotEqDyn(rhs), + new EcmaStrictnoteqdyn(rhs), new Jeqz(caseLabel), new Jmp(switchEndLabel), // switch cases caseLabel, switchEndLabel, - new ReturnUndefined() + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; expect((insns[6]).getTarget() === insns[8]).to.be.true; expect((insns[7]).getTarget() === insns[9]).to.be.true; }); - it("multiple cases without break", function() { + it("multiple cases without break", function () { let insns = compileMainSnippet(`let a = 0; switch (a) { case 0 : ; case 1 : ; default : ; }`); - let a = new VReg(); let rhs = new VReg(); let caseLabel_0 = new Label(); let caseLabel_1 = new Label(); @@ -76,15 +74,15 @@ describe("switchTest", function() { let switchEndLabel = new Label(); let expected = [ new LdaiDyn(new Imm(ResultType.Int, 0)), - new StaDyn(a), + new EcmaStlettoglobalrecord('a'), // switch body - new LdaDyn(a), + new EcmaTryldglobalbyname('a'), new StaDyn(rhs), new LdaiDyn(new Imm(ResultType.Int, 0)), - new StrictNotEqDyn(rhs), + new EcmaStrictnoteqdyn(rhs), new Jeqz(caseLabel_0), new LdaiDyn(new Imm(ResultType.Int, 1)), - new StrictNotEqDyn(rhs), + new EcmaStrictnoteqdyn(rhs), new Jeqz(caseLabel_1), new Jmp(defaultLabel), // cases @@ -93,19 +91,18 @@ describe("switchTest", function() { // default case defaultLabel, switchEndLabel, - new ReturnUndefined() + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; }); - it("multiple cases with default", function() { + it("multiple cases with default", function () { let insns = compileMainSnippet(`let a = 0; switch (a) { case 0 : break; case 1 : break; default : ; }`); - let a = new VReg(); let rhs = new VReg(); let caseLabel_0 = new Label(); let caseLabel_1 = new Label(); @@ -113,15 +110,15 @@ describe("switchTest", function() { let switchEndLabel = new Label(); let expected = [ new LdaiDyn(new Imm(ResultType.Int, 0)), - new StaDyn(a), + new EcmaStlettoglobalrecord('a'), // switch body - new LdaDyn(a), + new EcmaTryldglobalbyname('a'), new StaDyn(rhs), new LdaiDyn(new Imm(ResultType.Int, 0)), - new StrictNotEqDyn(rhs), + new EcmaStrictnoteqdyn(rhs), new Jeqz(caseLabel_0), new LdaiDyn(new Imm(ResultType.Int, 1)), - new StrictNotEqDyn(rhs), + new EcmaStrictnoteqdyn(rhs), new Jeqz(caseLabel_1), new Jmp(defaultLabel), // switch cases @@ -131,33 +128,32 @@ describe("switchTest", function() { new Jmp(switchEndLabel), defaultLabel, switchEndLabel, - new ReturnUndefined() + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; }); - it("multiple cases without default", function() { + it("multiple cases without default", function () { let insns = compileMainSnippet(`let a = 0; switch (a) { case 0 : break; case 1 : break; }`); - let a = new VReg(); let rhs = new VReg(); let caseLabel_0 = new Label(); let caseLabel_1 = new Label(); let switchEndLabel = new Label(); let expected = [ new LdaiDyn(new Imm(ResultType.Int, 0)), - new StaDyn(a), + new EcmaStlettoglobalrecord('a'), // switch body - new LdaDyn(a), + new EcmaTryldglobalbyname('a'), new StaDyn(rhs), new LdaiDyn(new Imm(ResultType.Int, 0)), - new StrictNotEqDyn(rhs), + new EcmaStrictnoteqdyn(rhs), new Jeqz(caseLabel_0), new LdaiDyn(new Imm(ResultType.Int, 1)), - new StrictNotEqDyn(rhs), + new EcmaStrictnoteqdyn(rhs), new Jeqz(caseLabel_1), new Jmp(switchEndLabel), // switch cases @@ -166,19 +162,18 @@ describe("switchTest", function() { caseLabel_1, new Jmp(switchEndLabel), switchEndLabel, - new ReturnUndefined() + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; }); - it("multiple cases with default surrounded by cases", function() { + it("multiple cases with default surrounded by cases", function () { let insns = compileMainSnippet(`let a = 0; switch (a) { case 0 : break; default : ; case 1 : ; }`); - let a = new VReg(); let rhs = new VReg(); let caseLabel_0 = new Label(); let caseLabel_1 = new Label(); @@ -186,15 +181,15 @@ describe("switchTest", function() { let switchEndLabel = new Label(); let expected = [ new LdaiDyn(new Imm(ResultType.Int, 0)), - new StaDyn(a), + new EcmaStlettoglobalrecord('a'), // switch body - new LdaDyn(a), + new EcmaTryldglobalbyname('a'), new StaDyn(rhs), new LdaiDyn(new Imm(ResultType.Int, 0)), - new StrictNotEqDyn(rhs), + new EcmaStrictnoteqdyn(rhs), new Jeqz(caseLabel_0), new LdaiDyn(new Imm(ResultType.Int, 1)), - new StrictNotEqDyn(rhs), + new EcmaStrictnoteqdyn(rhs), new Jeqz(caseLabel_1), new Jmp(defaultLabel), // switch cases @@ -204,7 +199,7 @@ describe("switchTest", function() { defaultLabel, caseLabel_1, switchEndLabel, - new ReturnUndefined() + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; }); diff --git a/ts2panda/tests/tryCatch.test.ts b/ts2panda/tests/statements/tryCatch.test.ts similarity index 78% rename from ts2panda/tests/tryCatch.test.ts rename to ts2panda/tests/statements/tryCatch.test.ts index b280676bba1d3d7e8c84abc1a9a30706b34b2d08..7114b171ca7a779986ec16873710ca41846004b8 100644 --- a/ts2panda/tests/tryCatch.test.ts +++ b/ts2panda/tests/statements/tryCatch.test.ts @@ -18,27 +18,27 @@ import { } from 'chai'; import 'mocha'; import { + EcmaReturnundefined, + EcmaStlettoglobalrecord, + EcmaThrowdyn, + EcmaTrystglobalbyname, Imm, Jmp, Label, LdaDyn, LdaiDyn, ResultType, - ReturnDyn, - ReturnUndefined, StaDyn, - ThrowDyn, VReg -} from "../src/irnodes"; -import { checkInstructions, compileMainSnippet } from "./utils/base"; +} from "../../src/irnodes"; +import { checkInstructions, compileMainSnippet } from "../utils/base"; -describe("TryCatch", function() { - it('tryCatch', function() { +describe("TryCatch", function () { + it('tryCatch', function () { let insns = compileMainSnippet(`let a = 0; try {a = 1;} catch {a = 2;}`); - let a = new VReg(); let tryBeginLabel = new Label(); let tryEndLabel = new Label(); let catchBeginLabel = new Label(); @@ -46,28 +46,27 @@ describe("TryCatch", function() { let expected = [ new LdaiDyn(new Imm(ResultType.Int, 0)), - new StaDyn(a), + new EcmaStlettoglobalrecord('a'), tryBeginLabel, new LdaiDyn(new Imm(ResultType.Int, 1)), - new StaDyn(a), + new EcmaTrystglobalbyname('a'), tryEndLabel, new Jmp(catchEndLabel), catchBeginLabel, new LdaiDyn(new Imm(ResultType.Int, 2)), - new StaDyn(a), + new EcmaTrystglobalbyname('a'), catchEndLabel, - new ReturnUndefined() + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; }); - it('tryCatchWithIdentifier', function() { + it('tryCatchWithIdentifier', function () { let insns = compileMainSnippet(`let a = 0; try {a = 1;} catch(err) {a = 2;}`); - let a = new VReg(); let tryBeginLabel = new Label(); let tryEndLabel = new Label(); let catchBeginLabel = new Label(); @@ -76,29 +75,28 @@ describe("TryCatch", function() { let expected = [ new LdaiDyn(new Imm(ResultType.Int, 0)), - new StaDyn(a), + new EcmaStlettoglobalrecord('a'), tryBeginLabel, new LdaiDyn(new Imm(ResultType.Int, 1)), - new StaDyn(a), + new EcmaTrystglobalbyname('a'), tryEndLabel, new Jmp(catchEndLabel), catchBeginLabel, new StaDyn(err), new LdaiDyn(new Imm(ResultType.Int, 2)), - new StaDyn(a), + new EcmaTrystglobalbyname('a'), catchEndLabel, - new ReturnUndefined() + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; }); - it('tryFinally', function() { + it('tryFinally', function () { let insns = compileMainSnippet(`let a = 0; try {a = 1;} finally {a = 3;}`); - let a = new VReg(); let tryBeginLabel = new Label(); let tryEndLabel = new Label(); let catchBeginLabel = new Label(); @@ -107,34 +105,33 @@ describe("TryCatch", function() { let expected = [ new LdaiDyn(new Imm(ResultType.Int, 0)), - new StaDyn(a), + new EcmaStlettoglobalrecord('a'), tryBeginLabel, new LdaiDyn(new Imm(ResultType.Int, 1)), - new StaDyn(a), + new EcmaTrystglobalbyname('a'), tryEndLabel, new LdaiDyn(new Imm(ResultType.Int, 3)), - new StaDyn(a), + new EcmaTrystglobalbyname('a'), new Jmp(catchEndLabel), catchBeginLabel, new StaDyn(exceptionVreg), new LdaiDyn(new Imm(ResultType.Int, 3)), - new StaDyn(a), + new EcmaTrystglobalbyname('a'), new LdaDyn(exceptionVreg), - new ThrowDyn(), + new EcmaThrowdyn(), catchEndLabel, - new ReturnUndefined() + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; }); - it('tryCatchFinally', function() { + it('tryCatchFinally', function () { let insns = compileMainSnippet(`let a = 0; try {a = 1;} catch {a = 2;} finally {a = 3;}`); - let a = new VReg(); let exceptionVreg = new VReg(); let tryBeginLabel = new Label(); let tryEndLabel = new Label(); @@ -147,29 +144,29 @@ describe("TryCatch", function() { let expected = [ new LdaiDyn(new Imm(ResultType.Int, 0)), - new StaDyn(a), + new EcmaStlettoglobalrecord('a'), tryBeginLabel, nestedTryBeginLabel, new LdaiDyn(new Imm(ResultType.Int, 1)), - new StaDyn(a), + new EcmaTrystglobalbyname('a'), nestedTryEndLabel, new Jmp(tryEndLabel), nestedCatchBeginLabel, new LdaiDyn(new Imm(ResultType.Int, 2)), - new StaDyn(a), + new EcmaTrystglobalbyname('a'), nestedCatchEndLabel, tryEndLabel, new LdaiDyn(new Imm(ResultType.Int, 3)), - new StaDyn(a), + new EcmaTrystglobalbyname('a'), new Jmp(catchEndLabel), catchBeginLabel, new StaDyn(exceptionVreg), new LdaiDyn(new Imm(ResultType.Int, 3)), - new StaDyn(a), + new EcmaTrystglobalbyname('a'), new LdaDyn(exceptionVreg), - new ThrowDyn(), + new EcmaThrowdyn(), catchEndLabel, - new ReturnUndefined() + new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; diff --git a/ts2panda/tests/declaration.test.ts b/ts2panda/tests/statements/variableDeclaration.test.ts similarity index 51% rename from ts2panda/tests/declaration.test.ts rename to ts2panda/tests/statements/variableDeclaration.test.ts index 49f61826328634a409cd4c321aef40befb5ec1db..51f1082baf5d164c6d3aa6c89c2c0e367ba30fc3 100644 --- a/ts2panda/tests/declaration.test.ts +++ b/ts2panda/tests/statements/variableDeclaration.test.ts @@ -1,378 +1,248 @@ -/* - * Copyright (c) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { - expect -} from 'chai'; -import 'mocha'; -import { - CopyRestArgs, - DefinefuncDyn, - Imm, - Jeqz, - Label, - LdaDyn, - LdaiDyn, - ResultType, - ReturnUndefined, - StaDyn, - StGlobalVar, - StrictEqDyn, - VReg -} from "../src/irnodes"; -import { - FunctionScope, - GlobalScope -} from "../src/scope"; -import { - GlobalVariable, - LocalVariable -} from "../src/variable"; -import { checkInstructions, compileAllSnippet, SnippetCompiler } from "./utils/base"; -import { DiagnosticCode } from '../src/diagnostic'; - -describe("DeclarationTest", function() { - - it('var i in the global scope', function() { - let snippetCompiler = new SnippetCompiler(); - - snippetCompiler.compile("var i;"); - let globalScope = snippetCompiler.getGlobalScope(); - let insns = snippetCompiler.getGlobalInsns(); - - let expected = [ - new LdaDyn(new VReg()), - new StGlobalVar("i"), - new ReturnUndefined() - ]; - expect(checkInstructions(insns, expected)).to.be.true; - let v = globalScope.findLocal("i"); - expect(v instanceof GlobalVariable).to.be.true; - }); - - it('let i in the global scope', function() { - let snippetCompiler = new SnippetCompiler(); - snippetCompiler.compile("let i;"); - let globalScope = snippetCompiler.getGlobalScope(); - let insns = snippetCompiler.getGlobalInsns(); - let expected = [ - new LdaDyn(new VReg()), - new StaDyn(new VReg()), - new ReturnUndefined() - ]; - expect(checkInstructions(insns, expected)).to.be.true; - let v = globalScope.findLocal("i"); - expect(v instanceof LocalVariable).to.be.true; - }); - - it('const i in the global scope', function() { - let snippetCompiler = new SnippetCompiler(); - snippetCompiler.compile("const i = 5;"); - let globalScope = snippetCompiler.getGlobalScope(); - let insns = snippetCompiler.getGlobalInsns(); - let expected = [ - new LdaiDyn(new Imm(ResultType.Int, 5)), - new StaDyn(new VReg()), - new ReturnUndefined() - ]; - expect(checkInstructions(insns, expected)).to.be.true; - let v = globalScope.findLocal("i"); - expect(v instanceof LocalVariable).to.be.true; - }); - - it('var i = 5 in the global scope', function() { - let snippetCompiler = new SnippetCompiler(); - snippetCompiler.compile("var i = 5;"); - let globalScope = snippetCompiler.getGlobalScope(); - let insns = snippetCompiler.getGlobalInsns(); - let expected = [ - new LdaDyn(new VReg()), - new StGlobalVar("i"), - new LdaiDyn(new Imm(ResultType.Int, 5)), - new StGlobalVar("i"), - new ReturnUndefined() - ]; - expect(checkInstructions(insns, expected)).to.be.true; - let v = globalScope.findLocal("i"); - expect(v instanceof GlobalVariable).to.be.true; - }); - - it('let i = 5 in the global scope', function() { - let snippetCompiler = new SnippetCompiler(); - snippetCompiler.compile("let i = 5;"); - let globalScope = snippetCompiler.getGlobalScope(); - let insns = snippetCompiler.getGlobalInsns(); - let i = new VReg(); - let expected = [ - new LdaiDyn(new Imm(ResultType.Int, 5)), - new StaDyn(i), - new ReturnUndefined() - ]; - expect(checkInstructions(insns, expected)).to.be.true; - let v = globalScope.findLocal("i"); - expect(v instanceof LocalVariable).to.be.true; - }); - - it('var i, j in the global scope', function() { - let snippetCompiler = new SnippetCompiler(); - snippetCompiler.compile("var i, j;"); - let globalScope = snippetCompiler.getGlobalScope(); - let i = globalScope.findLocal("i"); - expect(i instanceof GlobalVariable).to.be.true; - let j = globalScope.findLocal("j"); - expect(j instanceof GlobalVariable).to.be.true; - }); - - it('let i, j in the global scope', function() { - let snippetCompiler = new SnippetCompiler(); - snippetCompiler.compile("let i, j;"); - let globalScope = snippetCompiler.getGlobalScope(); - let i = globalScope.findLocal("i"); - expect(i instanceof LocalVariable).to.be.true; - let j = globalScope.findLocal("j"); - expect(j instanceof LocalVariable).to.be.true; - }); - - it('const i, j in the global scope', function() { - let snippetCompiler = new SnippetCompiler(); - snippetCompiler.compile("const i=5, j=5;"); - let globalScope = snippetCompiler.getGlobalScope(); - let i = globalScope.findLocal("i"); - expect(i instanceof LocalVariable).to.be.true; - let j = globalScope.findLocal("j"); - expect(j instanceof LocalVariable).to.be.true; - }); - - it('var i in a function scope', function() { - let snippetCompiler = new SnippetCompiler(); - snippetCompiler.compile("function a() {var i;}"); - let funcPg = snippetCompiler.getPandaGenByName("func_a_1"); - let functionScope = funcPg!.getScope(); - let insns = funcPg!.getInsns(); - let builtInUndefinedReg = new VReg(); - let v = new VReg(); - let expected = [ - new LdaDyn(builtInUndefinedReg), - new StaDyn(v), - new ReturnUndefined() - ]; - expect(checkInstructions(insns, expected)).to.be.true; - let i = functionScope.findLocal("i"); - expect(i).to.not.be.equal(undefined); - expect(i instanceof LocalVariable).to.be.true; - }); - - it('let i in a function scope', function() { - let snippetCompiler = new SnippetCompiler(); - snippetCompiler.compile("function a() {let i;}"); - let funcPg = snippetCompiler.getPandaGenByName("func_a_1"); - let functionScope = funcPg!.getScope(); - let insns = funcPg!.getInsns(); - let expected = [ - new LdaDyn(new VReg()), - new StaDyn(new VReg()), - new ReturnUndefined() - ]; - expect(checkInstructions(insns, expected)).to.be.true; - let i = functionScope.findLocal("i"); - expect(i).to.be.equal(undefined); - }); - - it('const i in a function scope', function() { - let snippetCompiler = new SnippetCompiler(); - snippetCompiler.compile("function a() {const i = 5;}"); - let funcPg = snippetCompiler.getPandaGenByName("func_a_1"); - let functionScope = funcPg!.getScope(); - let insns = funcPg!.getInsns(); - let expected = [ - new LdaiDyn(new Imm(ResultType.Int, 5)), - new StaDyn(new VReg()), - new ReturnUndefined() - ]; - expect(checkInstructions(insns, expected)).to.be.true; - let i = functionScope.findLocal("i"); - expect(i).to.be.equal(undefined); - }); - - it('let i in a local scope', function() { - let snippetCompiler = new SnippetCompiler(); - snippetCompiler.compile("{let i;}"); - let funcPg = snippetCompiler.getPandaGenByName("func_main_0"); - let localScope = funcPg!.getScope(); - let insns = funcPg!.getInsns(); - - let expected = [ - new LdaDyn(new VReg()), - new StaDyn(new VReg()), - new ReturnUndefined() - ]; - expect(checkInstructions(insns, expected)).to.be.true; - let i = localScope!.findLocal("i"); - expect(i).to.be.equal(undefined); - }); - - it('let declaration syntax error', function() { - let errorThrown = false; - let snippetCompiler = new SnippetCompiler(); - try { - snippetCompiler.compile("label: let i = 5;"); - } catch (err) { - expect(err.code).to.equal(DiagnosticCode.Lexical_declaration_let_not_allowed_in_statement_position); - errorThrown = true; - } - expect(errorThrown).to.be.true; - }); - - it('const i in a local scope', function() { - let snippetCompiler = new SnippetCompiler(); - snippetCompiler.compile("{const i = 5;}"); - let insns = snippetCompiler.getGlobalInsns(); - let scope = snippetCompiler.getGlobalScope(); - let expected = [ - new LdaiDyn(new Imm(ResultType.Int, 5)), - new StaDyn(new VReg()), - new ReturnUndefined() - ]; - expect(checkInstructions(insns, expected)).to.be.true; - let i = scope!.findLocal("i"); - expect(i == undefined).to.be.true; // not in global - }); - - it('function definition in the global scope', function() { - let snippetCompiler = new SnippetCompiler(); - snippetCompiler.compile("function foo() {}"); - let funcName = "foo"; - let internalName = "func_foo_1"; - let expected = [ - new DefinefuncDyn(internalName, new VReg()), - new StGlobalVar(funcName), - new ReturnUndefined() - ]; - let insns = snippetCompiler.getGlobalInsns(); - let globalScope = snippetCompiler.getGlobalScope(); - expect(checkInstructions(insns, expected)).to.be.true; - let foo = globalScope!.findLocal("foo"); - expect(foo != undefined).to.be.true; - expect(foo instanceof GlobalVariable).to.be.true; - }); - - it('function redefinition in the global scope', function() { - let snippetCompiler = new SnippetCompiler(); - snippetCompiler.compile(` - function foo() {} - function foo() {} - `); - let expected = [ - new DefinefuncDyn("func_foo_2", new VReg()), - new StGlobalVar("foo"), - new ReturnUndefined() - ]; - let insns = snippetCompiler.getGlobalInsns(); - let globalScope = snippetCompiler.getGlobalScope(); - expect(checkInstructions(insns, expected)).to.be.true; - let foo = globalScope!.findLocal("foo"); - expect(foo != undefined).to.be.true; - expect(foo instanceof GlobalVariable).to.be.true; - }); - - it('function definition inside a function', function() { - let snippetCompiler = new SnippetCompiler(); - snippetCompiler.compile(`function out() {function foo() {}}`); - let funcReg = new VReg(); - let expected = [ - new DefinefuncDyn("func_foo_2", new VReg()), - new StaDyn(funcReg), - - new ReturnUndefined() - ]; - let functionPg = snippetCompiler.getPandaGenByName("func_out_1"); - let insns = functionPg!.getInsns(); - let functionScope = functionPg!.getScope(); - - expect(checkInstructions(insns!, expected)).to.be.true; - let foo = functionScope!.findLocal("foo"); - expect(foo != undefined).to.be.true; - expect(foo instanceof LocalVariable).to.be.true; - let parameterLength = functionPg!.getParameterLength(); - expect(parameterLength == 0).to.be.true; - }); - - it("function expression", function() { - let snippetCompiler = new SnippetCompiler(); - snippetCompiler.compile("let foo = function() {}"); - let insns = snippetCompiler.getGlobalInsns(); - let func = new VReg(); - let expected = [ - new DefinefuncDyn("func_foo_1", new VReg()), - new StaDyn(func), - new ReturnUndefined() - ]; - expect(checkInstructions(insns, expected)).to.be.true; - }); - - it("Parameters with initializer", function() { - let compilerunit = compileAllSnippet("function test(a, b = 1) {}"); - let undefinedVReg = new VReg(); - let value = new VReg(); - let endLabel = new Label(); - - let expected_main = [ - new DefinefuncDyn("func_test_1", new VReg()), - new StGlobalVar("test"), - new ReturnUndefined() - ]; - let expected_func = [ - // func_test_0 - new LdaDyn(new VReg()), - new StrictEqDyn(undefinedVReg), - new Jeqz(endLabel), - new LdaiDyn(new Imm(ResultType.Int, 1)), - new StaDyn(value), - endLabel, - new ReturnUndefined(), - ]; - - compilerunit.forEach(element => { - if (element.internalName == "func_main_0") { - let insns = element.getInsns(); - expect(checkInstructions(insns, expected_main)).to.be.true; - } else if (element.internalName == "func_test_1") { - let insns = element.getInsns(); - expect(checkInstructions(insns, expected_func)).to.be.true; - let parameterLength = element.getParameterLength(); - expect(parameterLength == 1).to.be.true; - } - }); - }); - - it("Rest Parameters", function() { - let snippetCompiler = new SnippetCompiler(); - snippetCompiler.compile(`function test(a, ...b) {}`); - - let idx = new Imm(ResultType.Int, 1); - let lastParam = new VReg(); - let expected_func = [ - // func_test_0 - new CopyRestArgs(idx), - new StaDyn(lastParam), - new ReturnUndefined(), - ]; - - let functionPg = snippetCompiler.getPandaGenByName("func_test_1"); - let insns = functionPg!.getInsns(); - - expect(checkInstructions(insns, expected_func)).to.be.true; - }); -}); +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + expect +} from 'chai'; +import 'mocha'; +import { DiagnosticCode, DiagnosticError } from '../../src/diagnostic'; +import { + EcmaReturnundefined, + EcmaStconsttoglobalrecord, + EcmaStglobalvar, + EcmaStlettoglobalrecord, + Imm, + LdaDyn, + LdaiDyn, + ResultType, + StaDyn, + VReg +} from "../../src/irnodes"; +import { + FunctionScope, + GlobalScope +} from "../../src/scope"; +import { + GlobalVariable, + LocalVariable +} from "../../src/variable"; +import { checkInstructions, SnippetCompiler } from "../utils/base"; + +describe("VariableDeclarationTest", function () { + + it('var i in the global scope', function () { + let snippetCompiler = new SnippetCompiler(); + + snippetCompiler.compile("var i;"); + let globalScope = snippetCompiler.getGlobalScope(); + let insns = snippetCompiler.getGlobalInsns(); + + let expected = [ + new LdaDyn(new VReg()), + new EcmaStglobalvar("i"), + new EcmaReturnundefined() + ]; + expect(checkInstructions(insns, expected)).to.be.true; + let v = globalScope.findLocal("i"); + expect(v instanceof GlobalVariable).to.be.true; + }); + + it('let i in the global scope', function () { + let snippetCompiler = new SnippetCompiler(); + snippetCompiler.compile("let i;"); + let globalScope = snippetCompiler.getGlobalScope(); + let insns = snippetCompiler.getGlobalInsns(); + let expected = [ + new LdaDyn(new VReg()), + new EcmaStlettoglobalrecord('i'), + new EcmaReturnundefined() + ]; + expect(checkInstructions(insns, expected)).to.be.true; + let v = globalScope.findLocal("i"); + expect(v instanceof LocalVariable).to.be.true; + }); + + it('const i in the global scope', function () { + let snippetCompiler = new SnippetCompiler(); + snippetCompiler.compile("const i = 5;"); + let globalScope = snippetCompiler.getGlobalScope(); + let insns = snippetCompiler.getGlobalInsns(); + let expected = [ + new LdaiDyn(new Imm(ResultType.Int, 5)), + new EcmaStconsttoglobalrecord('i'), + new EcmaReturnundefined() + ]; + expect(checkInstructions(insns, expected)).to.be.true; + let v = globalScope.findLocal("i"); + expect(v instanceof LocalVariable).to.be.true; + }); + + it('var i = 5 in the global scope', function () { + let snippetCompiler = new SnippetCompiler(); + snippetCompiler.compile("var i = 5;"); + let globalScope = snippetCompiler.getGlobalScope(); + let insns = snippetCompiler.getGlobalInsns(); + let expected = [ + new LdaDyn(new VReg()), + new EcmaStglobalvar("i"), + new LdaiDyn(new Imm(ResultType.Int, 5)), + new EcmaStglobalvar("i"), + new EcmaReturnundefined() + ]; + expect(checkInstructions(insns, expected)).to.be.true; + let v = globalScope.findLocal("i"); + expect(v instanceof GlobalVariable).to.be.true; + }); + + it('let i = 5 in the global scope', function () { + let snippetCompiler = new SnippetCompiler(); + snippetCompiler.compile("let i = 5;"); + let globalScope = snippetCompiler.getGlobalScope(); + let insns = snippetCompiler.getGlobalInsns(); + let expected = [ + new LdaiDyn(new Imm(ResultType.Int, 5)), + new EcmaStlettoglobalrecord('i'), + new EcmaReturnundefined() + ]; + expect(checkInstructions(insns, expected)).to.be.true; + let v = globalScope.findLocal("i"); + expect(v instanceof LocalVariable).to.be.true; + }); + + it('var i, j in the global scope', function () { + let snippetCompiler = new SnippetCompiler(); + snippetCompiler.compile("var i, j;"); + let globalScope = snippetCompiler.getGlobalScope(); + let i = globalScope.findLocal("i"); + expect(i instanceof GlobalVariable).to.be.true; + let j = globalScope.findLocal("j"); + expect(j instanceof GlobalVariable).to.be.true; + }); + + it('let i, j in the global scope', function () { + let snippetCompiler = new SnippetCompiler(); + snippetCompiler.compile("let i, j;"); + let globalScope = snippetCompiler.getGlobalScope(); + let i = globalScope.findLocal("i"); + expect(i instanceof LocalVariable).to.be.true; + let j = globalScope.findLocal("j"); + expect(j instanceof LocalVariable).to.be.true; + }); + + it('const i, j in the global scope', function () { + let snippetCompiler = new SnippetCompiler(); + snippetCompiler.compile("const i=5, j=5;"); + let globalScope = snippetCompiler.getGlobalScope(); + let i = globalScope.findLocal("i"); + expect(i instanceof LocalVariable).to.be.true; + let j = globalScope.findLocal("j"); + expect(j instanceof LocalVariable).to.be.true; + }); + + it('var i in a function scope', function () { + let snippetCompiler = new SnippetCompiler(); + snippetCompiler.compile("function a() {var i;}"); + let funcPg = snippetCompiler.getPandaGenByName("a"); + let functionScope = funcPg!.getScope(); + let insns = funcPg!.getInsns(); + let expected = [ + new LdaDyn(new VReg()), + new StaDyn(new VReg()), + new EcmaReturnundefined() + ]; + + expect(checkInstructions(insns, expected)).to.be.true; + let i = functionScope.findLocal("i"); + expect(i).to.not.be.equal(undefined); + expect(i instanceof LocalVariable).to.be.true; + }); + + it('let i in a function scope', function () { + let snippetCompiler = new SnippetCompiler(); + snippetCompiler.compile("function a() {let i;}"); + let funcPg = snippetCompiler.getPandaGenByName("a"); + let functionScope = funcPg!.getScope(); + let insns = funcPg!.getInsns(); + let expected = [ + new LdaDyn(new VReg()), + new StaDyn(new VReg()), + new EcmaReturnundefined() + ]; + expect(checkInstructions(insns, expected)).to.be.true; + let i = functionScope.findLocal("i"); + expect(i).to.be.equal(undefined); + }); + + it('const i in a function scope', function () { + let snippetCompiler = new SnippetCompiler(); + snippetCompiler.compile("function a() {const i = 5;}"); + let funcPg = snippetCompiler.getPandaGenByName("a"); + let functionScope = funcPg!.getScope(); + let insns = funcPg!.getInsns(); + let expected = [ + new LdaiDyn(new Imm(ResultType.Int, 5)), + new StaDyn(new VReg()), + new EcmaReturnundefined() + ]; + expect(checkInstructions(insns, expected)).to.be.true; + let i = functionScope.findLocal("i"); + expect(i).to.be.equal(undefined); + }); + + it('let i in a local scope', function () { + let snippetCompiler = new SnippetCompiler(); + snippetCompiler.compile("{let i;}"); + let funcPg = snippetCompiler.getPandaGenByName("func_main_0"); + let localScope = funcPg!.getScope(); + let insns = funcPg!.getInsns(); + + let expected = [ + new LdaDyn(new VReg()), + new StaDyn(new VReg()), + new EcmaReturnundefined() + ]; + expect(checkInstructions(insns, expected)).to.be.true; + let i = localScope!.findLocal("i"); + expect(i).to.be.equal(undefined); + }); + + it('let declaration syntax error', function () { + let errorThrown = false; + let snippetCompiler = new SnippetCompiler(); + try { + snippetCompiler.compile("label: let i = 5;"); + } catch (err) { + expect(err instanceof DiagnosticError).to.be.true; + expect((err).code).to.equal(DiagnosticCode.Lexical_declaration_let_not_allowed_in_statement_position); + errorThrown = true; + } + expect(errorThrown).to.be.true; + }); + + it('const i in a local scope', function () { + let snippetCompiler = new SnippetCompiler(); + snippetCompiler.compile("{const i = 5;}"); + let insns = snippetCompiler.getGlobalInsns(); + let scope = snippetCompiler.getGlobalScope(); + let expected = [ + new LdaiDyn(new Imm(ResultType.Int, 5)), + new StaDyn(new VReg()), + new EcmaReturnundefined() + ]; + expect(checkInstructions(insns, expected)).to.be.true; + let i = scope!.findLocal("i"); + expect(i == undefined).to.be.true; // not in global + }); +}); diff --git a/ts2panda/tests/statements/while.test.ts b/ts2panda/tests/statements/while.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..6e40c78dc991a3e256015c192268641805cc84d0 --- /dev/null +++ b/ts2panda/tests/statements/while.test.ts @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + expect +} from 'chai'; +import 'mocha'; +import { + EcmaAdd2dyn, + EcmaIstrue, + EcmaLessdyn, + EcmaReturnundefined, + EcmaStlettoglobalrecord, + EcmaTryldglobalbyname, + EcmaTrystglobalbyname, + Imm, + Jeqz, + Jgez, + Jmp, + Label, + LdaDyn, + LdaiDyn, + ResultType, + StaDyn, + VReg +} from "../../src/irnodes"; +import { checkInstructions, compileMainSnippet } from "../utils/base"; + +describe("WhileLoopTest", function () { + it("while (true) {}", function () { + let insns = compileMainSnippet("while (true) {}"); + let labelPre = new Label(); + let labelPost = new Label(); + let expected = [ + labelPre, + new LdaDyn(new VReg()), + new EcmaIstrue(), + new Jeqz(labelPost), + new Jmp(labelPre), + labelPost, + new EcmaReturnundefined() + ]; + + expect(checkInstructions(insns, expected)).to.be.true; + }); + + it("while (a + b) {}", function () { + let insns = compileMainSnippet("let a, b; while (a + b) {}"); + let loopBegin = new Label(); + let loopEnd = new Label(); + let lhs = new VReg(); + let expected = [ + loopBegin, + // a + b + new EcmaTryldglobalbyname('a'), + new StaDyn(lhs), + new EcmaTryldglobalbyname('b'), + new EcmaAdd2dyn(lhs), + new EcmaIstrue(), + new Jeqz(loopEnd), + // body + new Jmp(loopBegin), + loopEnd + ]; + + insns = insns.slice(4, insns.length - 1); // skip let a, b and return.dyn + expect(checkInstructions(insns, expected)).to.be.true; + }); + + it('whileLoopWithBody', function () { + let insns = compileMainSnippet(` + let a; + while (a < 0) { a = 1; } + `); + + let lhs = new VReg(); + let loopBegin = new Label(); + let loopEnd = new Label(); + let expected = [ + loopBegin, + // condition + // compute lhs + new EcmaTryldglobalbyname('a'), + new StaDyn(lhs), + // compute rhs + new LdaiDyn(new Imm(ResultType.Int, 0)), + new EcmaLessdyn(lhs), + new Jeqz(loopEnd), + + // body + new LdaiDyn(new Imm(ResultType.Int, 1)), + new EcmaTrystglobalbyname('a'), + new Jmp(loopBegin), + + loopEnd, + ]; + + insns = insns.slice(2, insns.length - 1); // skip let a and return.dyn + expect(checkInstructions(insns, expected)).to.be.true; + expect((insns[5]).getTarget() === insns[insns.length - 1]).to.be.true; + expect((insns[insns.length - 2]).getTarget() === insns[0]).to.be.true; + }); + + it('whileLoopWithContinue', function () { + let insns = compileMainSnippet("let a = 5;" + + "while (a < 1) { a = 2; continue; }"); + let lhs = new VReg(); + let labelPre = new Label(); + let labelPost = new Label(); + let expected = [ + new LdaiDyn(new Imm(ResultType.Int, 5)), + new EcmaStlettoglobalrecord('a'), + labelPre, + // condition + new EcmaTryldglobalbyname('a'), + new StaDyn(lhs), + new LdaiDyn(new Imm(ResultType.Int, 1)), + new EcmaLessdyn(lhs), + new Jeqz(labelPost), + //body + new LdaiDyn(new Imm(ResultType.Int, 2)), + new EcmaTrystglobalbyname('a'), + new Jmp(labelPre), // continue + new Jmp(labelPre), + labelPost, + new EcmaReturnundefined() + ] + // check the instruction kinds are the same as we expect + expect(checkInstructions(insns, expected)).to.be.true; + // check continue jumps to the expected instruction + let jmp = insns[11]; + let targetLabel = (jmp).getTarget(); + expect(targetLabel).to.equal(insns[2]); + }); + + it('whileLoopWithBreak', function () { + let insns = compileMainSnippet("let a = 5;" + + "while (a < 1) { a = 2; break; }"); + let lhs = new VReg(); + let labelPre = new Label(); + let labelPost = new Label(); + let expected = [ + new LdaiDyn(new Imm(ResultType.Int, 5)), + new EcmaStlettoglobalrecord('a'), + labelPre, + // condition + new EcmaTryldglobalbyname('a'), + new StaDyn(lhs), + new LdaiDyn(new Imm(ResultType.Int, 1)), + new EcmaLessdyn(lhs), + new Jeqz(labelPost), + //body + new LdaiDyn(new Imm(ResultType.Int, 2)), + new EcmaTrystglobalbyname('a'), + new Jmp(labelPost), //break + new Jmp(labelPre), + labelPost, + new EcmaReturnundefined() + ] + // check the instruction kinds are the same as we expect + expect(checkInstructions(insns, expected)).to.be.true; + // check continue jumps to the expected instruction + let jmp = insns[10]; + let targetLabel = (jmp).getTarget(); + expect(targetLabel).to.equal(insns[12]); + }); +}); diff --git a/ts2panda/tests/strictmode/strictmode.test.ts b/ts2panda/tests/strictmode/strictmode.test.ts index f10c1a2c54e4de393e79afe1a310a882fce116b8..f7f6282f4485aa2685d7261d885c95b49b1e1222 100755 --- a/ts2panda/tests/strictmode/strictmode.test.ts +++ b/ts2panda/tests/strictmode/strictmode.test.ts @@ -14,12 +14,12 @@ */ import { expect } from 'chai'; -import * as ts from "typescript"; import { readFileSync } from "fs"; +import * as ts from "typescript"; import { isStrictMode, setGlobalStrict } from '../../src/strictMode'; -import jshelpers = require('../../src/jshelpers'); -import { getCompileOptions } from '../utils/base'; import { isFunctionLikeDeclaration } from '../../src/syntaxCheckHelper'; +import { getCompileOptions } from '../utils/base'; +import jshelpers = require('../../src/jshelpers'); function createSourceFile(filename: string): ts.SourceFile { let sourceFile = ts.createSourceFile( @@ -41,15 +41,15 @@ function recordNodes(node: ts.Node, flag: boolean): boolean { return false; } -describe("strict_mode", function() { - it('global strict mode', function() { +describe("strict_mode", function () { + it('global strict mode', function () { let node = createSourceFile("tests/strictmode/global.js"); setGlobalStrict(jshelpers.isEffectiveStrictModeSourceFile(node, getCompileOptions())); expect(isStrictMode(node)).to.be.true; recordNodes(node, true); }); - it('function strict mode', function() { + it('function strict mode', function () { let node = createSourceFile("tests/strictmode/function.js"); setGlobalStrict(jshelpers.isEffectiveStrictModeSourceFile(node, getCompileOptions())); expect(isStrictMode(node)).to.be.false; @@ -68,7 +68,7 @@ describe("strict_mode", function() { }); }); - it('function nest1 strict mode', function() { + it('function nest1 strict mode', function () { let node = createSourceFile("tests/strictmode/function_nest1.js"); setGlobalStrict(jshelpers.isEffectiveStrictModeSourceFile(node, getCompileOptions())); expect(isStrictMode(node)).to.be.false; @@ -81,7 +81,7 @@ describe("strict_mode", function() { }); }); - it('function nest2 strict mode', function() { + it('function nest2 strict mode', function () { let node = createSourceFile("tests/strictmode/function_nest2.js"); setGlobalStrict(jshelpers.isEffectiveStrictModeSourceFile(node, getCompileOptions())); expect(isStrictMode(node)).to.be.false; diff --git a/ts2panda/tests/tsconfig.mac.json b/ts2panda/tests/tsconfig.mac.json new file mode 100644 index 0000000000000000000000000000000000000000..23c1b381797729234af10d8f805a957d3a6e3d98 --- /dev/null +++ b/ts2panda/tests/tsconfig.mac.json @@ -0,0 +1,12 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "outDir": "../build-mac", + "incremental": true, + "tsBuildInfoFile": "../build-mac/tests/tsconfig.tsbuildinfo", + }, + "references": [ + { "path": "../src" } + ] + } + \ No newline at end of file diff --git a/ts2panda/tests/tsconfig.win.json b/ts2panda/tests/tsconfig.win.json new file mode 100644 index 0000000000000000000000000000000000000000..edaef63e1b79281c261411e28c3387fee80ac22f --- /dev/null +++ b/ts2panda/tests/tsconfig.win.json @@ -0,0 +1,12 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "outDir": "../build-win", + "incremental": true, + "tsBuildInfoFile": "../build-win/tests/tsconfig.tsbuildinfo", + }, + "references": [ + { "path": "../src" } + ] + } + \ No newline at end of file diff --git a/ts2panda/tests/unary.test.ts b/ts2panda/tests/unary.test.ts deleted file mode 100644 index 3be3b735be29ed85d2648905a1041961af71504f..0000000000000000000000000000000000000000 --- a/ts2panda/tests/unary.test.ts +++ /dev/null @@ -1,399 +0,0 @@ -/* - * Copyright (c) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { - expect -} from 'chai'; -import 'mocha'; -import { - Call1Dyn, - DecDyn, - DelObjProp, - EqDyn, - Imm, - IncDyn, - Jeqz, - Jmp, - Label, - LdaDyn, - LdaiDyn, - LdaStr, - LdObjByName, - NegDyn, - NotDyn, - ResultType, - ReturnUndefined, - StaDyn, - Toboolean, - Tonumber, - TryLdGlobalByName, - TypeOfDyn, - VReg -} from "../src/irnodes"; -import { checkInstructions, compileMainSnippet, SnippetCompiler } from "./utils/base"; - -describe("UnaryOperationsTest", function() { - describe("PrefixOperationsTest", function() { - it('let i = 5; ++i', function() { - let insns = compileMainSnippet("let i = 5; let j = ++i"); - - let i = new VReg(); - let j = new VReg(); - let temp = new VReg(); - - let expected = [ - new LdaiDyn(new Imm(ResultType.Int, 5)), - new StaDyn(i), - new LdaDyn(i), - new StaDyn(temp), - new IncDyn(temp), - new StaDyn(i), - new StaDyn(j), - new ReturnUndefined() - ]; - - expect(checkInstructions(insns, expected)).to.be.true; - }); - - it('let i = 5; --i', function() { - let insns = compileMainSnippet("let i = 5; let j = --i"); - - let i = new VReg(); - let j = new VReg(); - let temp = new VReg(); - - let expected = [ - new LdaiDyn(new Imm(ResultType.Int, 5)), - new StaDyn(i), - new LdaDyn(i), - new StaDyn(temp), - new DecDyn(temp), - new StaDyn(i), - new StaDyn(j), - new ReturnUndefined() - ]; - - expect(checkInstructions(insns, expected)).to.be.true; - }); - - it('let i = 5; let j = +i', function() { - let insns = compileMainSnippet("let i = 5; let j = +i"); - - let i = new VReg(); - let j = new VReg(); - let temp = new VReg(); - - let expected = [ - new LdaiDyn(new Imm(ResultType.Int, 5)), - new StaDyn(i), - new LdaDyn(i), - new StaDyn(temp), - new Tonumber(temp), - new StaDyn(j), - new ReturnUndefined() - ]; - - expect(checkInstructions(insns, expected)).to.be.true; - }); - - it('let i = 5; let j = -i', function() { - let insns = compileMainSnippet("let i = 5; let j = -i"); - - let i = new VReg(); - let j = new VReg(); - let temp = new VReg(); - - let expected = [ - new LdaiDyn(new Imm(ResultType.Int, 5)), - new StaDyn(i), - new LdaDyn(i), - new StaDyn(temp), - new NegDyn(temp), - new StaDyn(j), - new ReturnUndefined() - ]; - - expect(checkInstructions(insns, expected)).to.be.true; - }); - - it('let i = 5; let j = !i', function() { - let insns = compileMainSnippet("let i = 5; let j = !i"); - - let i = new VReg(); - let j = new VReg(); - let trueReg = new VReg(); - let preLabel = new Label(); - let postLabel = new Label(); - let expected = [ - new LdaiDyn(new Imm(ResultType.Int, 5)), - new StaDyn(i), - new LdaDyn(i), - new StaDyn(new VReg()), - new Toboolean(), - new EqDyn(trueReg), - new Jeqz(preLabel), - new LdaDyn(new VReg()), - new Jmp(postLabel), - preLabel, - new LdaDyn(new VReg()), - postLabel, - new StaDyn(j), - new ReturnUndefined() - ]; - expect(checkInstructions(insns, expected)).to.be.true; - }); - - it('let i = 5; let j = ~i', function() { - let insns = compileMainSnippet("let i = 5; let j = ~i"); - - let i = new VReg(); - let j = new VReg(); - let temp_i = new VReg(); - - let expected = [ - new LdaiDyn(new Imm(ResultType.Int, 5)), - new StaDyn(i), - new LdaDyn(i), - new StaDyn(temp_i), - new NotDyn(temp_i), - new StaDyn(j), - new ReturnUndefined() - ]; - - expect(checkInstructions(insns, expected)).to.be.true; - }); - }); - - describe("PostfixOperationsTest", function() { - it("let i = 0; i++", function() { - let insns = compileMainSnippet("let i = 5; i++"); - let i = new VReg(); - let temp = new VReg(); - let expected = [ - new LdaiDyn(new Imm(ResultType.Int, 5)), - new StaDyn(i), - new LdaDyn(i), - new StaDyn(temp), - new IncDyn(temp), - new StaDyn(i), - new Tonumber(i), - new ReturnUndefined() - ]; - expect(checkInstructions(insns, expected)).to.be.true; - }); - - it("let i = 0; i--", function() { - let insns = compileMainSnippet("let i = 5; i--"); - let i = new VReg(); - let temp = new VReg(); - let expected = [ - new LdaiDyn(new Imm(ResultType.Int, 5)), - new StaDyn(i), - new LdaDyn(i), - new StaDyn(temp), - new DecDyn(temp), - new StaDyn(i), - new Tonumber(i), - new ReturnUndefined() - ]; - expect(checkInstructions(insns, expected)).to.be.true; - }); - }); - - describe("TypeOfTest", function() { - it("typeof 12", function() { - let insns = compileMainSnippet("typeof 5"); - let expected = [ - new LdaiDyn(new Imm(ResultType.Int, 5)), - new TypeOfDyn(), - new ReturnUndefined() - ]; - - expect(checkInstructions(insns, expected)).to.be.true; - }); - - it("typeof Number(\"12\")", function() { - let insns = compileMainSnippet("typeof Number(\"5\")"); - let arg1 = new VReg(); - let arg3 = new VReg(); - let expected = [ - new TryLdGlobalByName("Number"), - new StaDyn(arg1), - - new LdaStr("5"), - new StaDyn(arg3), - new Call1Dyn(arg1, arg3), - new TypeOfDyn(), - new ReturnUndefined() - ]; - - expect(checkInstructions(insns, expected)).to.be.true; - }); - - it("typeof x", function() { - let insns = compileMainSnippet("typeof x"); - - let expected = [ - new LdObjByName("x", new VReg()), - new TypeOfDyn(), - new ReturnUndefined() - ]; - - expect(checkInstructions(insns, expected)).to.be.true; - }); - - it("typeof(x)", function() { - let insns = compileMainSnippet("typeof(x)"); - - let expected = [ - new LdObjByName("x", new VReg()), - new TypeOfDyn(), - new ReturnUndefined() - ]; - - expect(checkInstructions(insns, expected)).to.be.true; - }); - }); - - describe("voidExpressionTest", function() { - it("void (a)", function() { - let insns = compileMainSnippet("let a; void (a);"); - let a = new VReg(); - let expected = [ - new LdaDyn(new VReg()), - new StaDyn(a), - new LdaDyn(a), - new LdaDyn(new VReg()), - new ReturnUndefined() - ]; - expect(checkInstructions(insns, expected)).to.be.true; - }); - }); - - describe("deleteExpressionTest", function() { - it("deleteElementFromArray", function() { - let insns = compileMainSnippet("let arr = [1, 2]; delete arr[1];"); - let arrayReg = new VReg(); - let objReg = new VReg(); - let propReg = new VReg(); - - let expected = [ - // let arr = [1, 2]; - // ... - // delete arr[1]; - new LdaDyn(arrayReg), - new StaDyn(objReg), - new LdaiDyn(new Imm(ResultType.Int, 1)), - new StaDyn(propReg), - new DelObjProp(objReg, propReg), - new ReturnUndefined() - ]; - - insns = insns.slice(insns.length - 6, insns.length); - expect(checkInstructions(insns, expected)).to.be.true; - }); - - it("deletePropFromObj", function() { - // this Snippet code isn't supported by TS - let insns = compileMainSnippet(`let obj = { - a: 1, - b: 2}; - delete obj.b;`); - let localObj = new VReg(); - let objReg = new VReg(); - let propReg = new VReg(); - - let expected = [ - // delete obj.b; - new LdaDyn(localObj), - new StaDyn(objReg), - new LdaStr("b"), - new StaDyn(propReg), - new DelObjProp(objReg, propReg), - new ReturnUndefined() - ]; - - insns = insns.slice(insns.length - 6, insns.length); - expect(checkInstructions(insns, expected)).to.be.true; - }); - - // delete function call won't use delObjProp - it("deleteFunctionCall", function() { - let snippetCompiler = new SnippetCompiler(); - snippetCompiler.compile(`var foo = function() { - bIsFooCalled = true; - }; - let a = delete foo();`); - - let insns = snippetCompiler.getGlobalInsns(); - let a = new VReg(); - let expected = [ - // function call insns - new LdaDyn(new VReg()), - new StaDyn(a), - new ReturnUndefined() - ]; - - insns = insns.slice(insns.length - 3, insns.length); - expect(checkInstructions(insns, expected)).to.be.true; - }); - - // delete keywords won't use delObjProp - it("deleteKeywords", function() { - let insns = compileMainSnippet(`let a = delete false;`); - let a = new VReg(); - - let expected = [ - new LdaDyn(new VReg()), - new LdaDyn(new VReg()), - new StaDyn(a), - new ReturnUndefined() - ]; - - expect(checkInstructions(insns, expected)).to.be.true; - }); - - it("deleteUnresolvable", function() { - let insns = compileMainSnippet(`delete a;`); - let globalReg = new VReg(); - let a = new VReg(); - - let expected = [ - new LdaStr("a"), - new StaDyn(a), - new DelObjProp(globalReg, a), - new ReturnUndefined() - ]; - - expect(checkInstructions(insns, expected)).to.be.true; - }); - - it("double delete", function() { - let insns = compileMainSnippet(`delete delete a;`); - let globalReg = new VReg(); - let a = new VReg(); - - let expected = [ - new LdaStr("a"), - new StaDyn(a), - new DelObjProp(globalReg, a), - new LdaDyn(new VReg()), - new ReturnUndefined() - ]; - - expect(checkInstructions(insns, expected)).to.be.true; - }); - }); -}); diff --git a/ts2panda/tests/utils/asthelper.ts b/ts2panda/tests/utils/asthelper.ts index de869a4650c04676d99d8d9b5c4ae9d2ffb19998..51d5dbb431c6c0fead44f04ac716a3816664c1ad 100644 --- a/ts2panda/tests/utils/asthelper.ts +++ b/ts2panda/tests/utils/asthelper.ts @@ -23,7 +23,7 @@ export function creatAstFromSnippet(snippet: string): ts.SourceFile { /** It would be tricky here to use relative path, so please use an absolute path instead. * For how to use this function, please refer to example_asthelper.ts - */ + */ export function creatAstFromFile(fileName: string): ts.SourceFile { let sourceFile = ts.createSourceFile(fileName, readFileSync(fileName).toString(), ts.ScriptTarget.ES2015, true); return sourceFile; diff --git a/ts2panda/tests/utils/base.ts b/ts2panda/tests/utils/base.ts index b4185ef75dfe70be3afdc8ba94ca133ac6570a9d..78718fbd04153cf6e76d43501172fa3fd9ebee47 100644 --- a/ts2panda/tests/utils/base.ts +++ b/ts2panda/tests/utils/base.ts @@ -28,8 +28,8 @@ import { Pass } from "../../src/pass"; import { Scope } from "../../src/scope"; -import { creatAstFromSnippet } from "./asthelper"; import { setGlobalStrict } from "../../src/strictMode"; +import { creatAstFromSnippet } from "./asthelper"; const compileOptions = { outDir: "../tmp/build", @@ -107,7 +107,6 @@ export function basicChecker(left: IRNode, right: IRNode): boolean { for (let i = 0; i < operandCount; ++i) { const lop = left.operands[i]; const rop = right.operands[i]; - if (!basicOperandsEqual(lop, rop)) { console.log("left.operands:"); console.log(left.operands[i]); diff --git a/ts2panda/ts2abc_config.gni b/ts2panda/ts2abc_config.gni index a86ae8032eb04bbe23de2eeda0b41bf5a8f4c4cb..3455351b7205cb6657710bfb510ec732cc386e8d 100755 --- a/ts2panda/ts2abc_config.gni +++ b/ts2panda/ts2abc_config.gni @@ -151,3 +151,46 @@ template("ts2abc_gen_abc") { outputs = invoker.out_puts } } + +# ts2abc performs the ut test +# +# Mandatory arguments: +# js_file: The name of the test use case file to execute , ex expression/TemplateExpression.test.js +template("ts2abc_unittest") { + assert(defined(invoker.js_file), "js_file is required!") + + action("$target_name") { + script = "${ts2abc_root}/scripts/run_tests.py" + deps = [ "${ts2abc_root}:ts2abc_tests" ] + + args = [ + "--src-dir", + rebase_path("${ts2abc_root}"), + "--dist-dir", + rebase_path(target_out_dir + "/.."), + "--node-modules", + rebase_path("${node_modules}"), + "--js-file", + invoker.js_file, + "--gn-build", + ] + + if (host_toolchain == buildtool_linux) { + args += [ + "--platform", + "linux", + ] + } else if (host_toolchain == buildtool_mac) { + args += [ + "--platform", + "mac", + ] + } else { + args += [ + "--platform", + "win", + ] + } + outputs = [ "$target_out_dir/${target_name}/" ] + } +}