From ed1e94014c52241f8909c879bd2aca881777be6f Mon Sep 17 00:00:00 2001 From: Slavomir Kucera Date: Mon, 20 Sep 2021 14:41:22 +0200 Subject: [PATCH] feat: Implement SYSTEM_ID system variable --- clients/vscode-hlasmplugin/CHANGELOG.md | 3 + clients/vscode-hlasmplugin/README.md | 2 +- clients/vscode-hlasmplugin/proc_grps_schema | 4 ++ parser_library/src/CMakeLists.txt | 1 + parser_library/src/compiler_options.cpp | 19 +++++++ parser_library/src/compiler_options.h | 4 +- parser_library/src/config/proc_grps.cpp | 4 ++ parser_library/src/config/proc_grps.h | 1 + parser_library/src/context/hlasm_context.cpp | 10 ++++ .../src/workspaces/processor_group.cpp | 11 +++- parser_library/test/config/CMakeLists.txt | 1 + parser_library/test/config/proc_grps_test.cpp | 9 ++- parser_library/test/config/system_id_test.cpp | 55 +++++++++++++++++++ .../test/debugging/debugger_test.cpp | 3 +- 14 files changed, 121 insertions(+), 6 deletions(-) create mode 100644 parser_library/src/compiler_options.cpp create mode 100644 parser_library/test/config/system_id_test.cpp diff --git a/clients/vscode-hlasmplugin/CHANGELOG.md b/clients/vscode-hlasmplugin/CHANGELOG.md index dbbef3d7c..b4180e9cc 100644 --- a/clients/vscode-hlasmplugin/CHANGELOG.md +++ b/clients/vscode-hlasmplugin/CHANGELOG.md @@ -7,6 +7,7 @@ - CNOP instruction implementation (limited) - START, MHELP instructions - Wildcard support in library specification +- Support for SYSTEM_ID system variable. #### Fixed - Preserve mixed-case labels on macro calls @@ -20,6 +21,8 @@ - Lookahead mode does not work correctly when triggered from AINSERTed code - Incorrect relative immediate operand validation - Remove ALIAS operand parsing limitation +- Attribute expressions ending with dot are not parsed correctly +- Improve evaluation and diagnostics of conditional assembler expressions ## [0.14.0](https://github.com/eclipse/che-che4z-lsp-for-hlasm/compare/0.13.0...0.14.0) (2021-08-18) diff --git a/clients/vscode-hlasmplugin/README.md b/clients/vscode-hlasmplugin/README.md index 78f014192..d1d68501c 100644 --- a/clients/vscode-hlasmplugin/README.md +++ b/clients/vscode-hlasmplugin/README.md @@ -88,7 +88,7 @@ Breakpoints can be set before or during the debugging session. ### External Macro Libraries and COPY Members The HLASM Language Support extension looks for locally stored members when a macro or COPY instruction is evaluated. The paths of these members are specified in two configuration files in the `.hlasmplugin` folder of the currently open workspace: -- `proc_grps.json` defines _processor groups_ by assigning a group name to a list of directories. Hence, the group name serves as a unique identifier of a set of HLASM libraries defined by a list of directories (some of which can be optional). Additionaly, the _SYSPARM_ option can be specified in the `asm_options` section. +- `proc_grps.json` defines _processor groups_ by assigning a group name to a list of directories. Hence, the group name serves as a unique identifier of a set of HLASM libraries defined by a list of directories (some of which can be optional). Additionaly, the _SYSPARM_ and _SYSTEM_ID_ options can be specified in the `asm_options` section. - `pgm_conf.json` provides a mapping between _programs_ (open-code files) and processor groups. It specifies which list of directories is used with which source file. If a relative source file path is specified, it is relative to the current workspace. diff --git a/clients/vscode-hlasmplugin/proc_grps_schema b/clients/vscode-hlasmplugin/proc_grps_schema index 17a836c2e..768475632 100644 --- a/clients/vscode-hlasmplugin/proc_grps_schema +++ b/clients/vscode-hlasmplugin/proc_grps_schema @@ -57,6 +57,10 @@ "PROFILE": { "type": "string", "description": "Profile Member to be copied into the source program." + }, + "SYSTEM_ID": { + "type": "string", + "description": "Provides the value for the SYSTEM_ID system variable. Defaults to 'z/OS 02.04.00' when omitted." } } }, diff --git a/parser_library/src/CMakeLists.txt b/parser_library/src/CMakeLists.txt index aaf67fcf7..85d6ae90a 100644 --- a/parser_library/src/CMakeLists.txt +++ b/parser_library/src/CMakeLists.txt @@ -16,6 +16,7 @@ target_sources(parser_library PRIVATE analyzer.cpp analyzer.h analyzing_context.h + compiler_options.cpp compiler_options.h diagnosable.h diagnosable_ctx.cpp diff --git a/parser_library/src/compiler_options.cpp b/parser_library/src/compiler_options.cpp new file mode 100644 index 000000000..6764267be --- /dev/null +++ b/parser_library/src/compiler_options.cpp @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2021 Broadcom. + * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Broadcom, Inc. - initial API and implementation + */ + +#include "compiler_options.h" + +namespace hlasm_plugin::parser_library { +const std::string asm_option::system_id_default = "z/OS 02.04.00"; +} // namespace hlasm_plugin::parser_library diff --git a/parser_library/src/compiler_options.h b/parser_library/src/compiler_options.h index 182184998..1bc65109e 100644 --- a/parser_library/src/compiler_options.h +++ b/parser_library/src/compiler_options.h @@ -21,10 +21,12 @@ namespace hlasm_plugin::parser_library { struct asm_option - { std::string sysparm; std::string profile; + + static const std::string system_id_default; + std::string system_id = system_id_default; }; } // namespace hlasm_plugin::parser_library #endif diff --git a/parser_library/src/config/proc_grps.cpp b/parser_library/src/config/proc_grps.cpp index 4d571c422..d0feb0c2b 100644 --- a/parser_library/src/config/proc_grps.cpp +++ b/parser_library/src/config/proc_grps.cpp @@ -47,6 +47,8 @@ void to_json(nlohmann::json& j, const assembler_options& p) j["PROFILE"] = p.profile; if (p.sysparm.size()) j["SYSPARM"] = p.sysparm; + if (p.system_id.size()) + j["SYSTEM_ID"] = p.system_id; } void from_json(const nlohmann::json& j, assembler_options& p) { @@ -57,6 +59,8 @@ void from_json(const nlohmann::json& j, assembler_options& p) it->get_to(p.profile); if (auto it = j.find("SYSPARM"); it != j.end()) it->get_to(p.sysparm); + if (auto it = j.find("SYSTEM_ID"); it != j.end()) + it->get_to(p.system_id); } void to_json(nlohmann::json& j, const db2_preprocessor&) { j = "DB2"; } diff --git a/parser_library/src/config/proc_grps.h b/parser_library/src/config/proc_grps.h index 8f5bd8287..35d4543ee 100644 --- a/parser_library/src/config/proc_grps.h +++ b/parser_library/src/config/proc_grps.h @@ -37,6 +37,7 @@ struct assembler_options { std::string sysparm; std::string profile; + std::string system_id; bool valid() const noexcept { return sysparm.size() < 256; } }; diff --git a/parser_library/src/context/hlasm_context.cpp b/parser_library/src/context/hlasm_context.cpp index 98777100c..d1651680b 100644 --- a/parser_library/src/context/hlasm_context.cpp +++ b/parser_library/src/context/hlasm_context.cpp @@ -161,6 +161,7 @@ void hlasm_context::add_global_system_vars() auto SYSTIME = ids().add("SYSTIME"); auto SYSPARM = ids().add("SYSPARM"); auto SYSOPT_RENT = ids().add("SYSOPT_RENT"); + auto SYSTEM_ID = ids().add("SYSTEM_ID"); if (!is_in_macro()) { @@ -231,6 +232,13 @@ void hlasm_context::add_global_system_vars() auto val = std::make_shared>(SYSOPT_RENT, true, true); globals_.insert({ SYSOPT_RENT, std::move(val) }); } + { + auto val = std::make_shared>(SYSTEM_ID, true, true); + + val->set_value(asm_options_.system_id); + + globals_.insert({ SYSTEM_ID, std::move(val) }); + } } auto glob = globals_.find(SYSDATC); @@ -243,6 +251,8 @@ void hlasm_context::add_global_system_vars() curr_scope()->variables.insert({ glob->second->id, glob->second }); glob = globals_.find(SYSOPT_RENT); curr_scope()->variables.insert({ glob->second->id, glob->second }); + glob = globals_.find(SYSTEM_ID); + curr_scope()->variables.insert({ glob->second->id, glob->second }); } bool hlasm_context::is_opcode(id_index symbol) const diff --git a/parser_library/src/workspaces/processor_group.cpp b/parser_library/src/workspaces/processor_group.cpp index 61b82eafb..6bc3bd98f 100644 --- a/parser_library/src/workspaces/processor_group.cpp +++ b/parser_library/src/workspaces/processor_group.cpp @@ -24,12 +24,21 @@ struct translate_pp_options preprocessor_options operator()(const std::monostate&) const { return std::monostate {}; } preprocessor_options operator()(const config::db2_preprocessor&) const { return db2_preprocessor_options {}; } }; + +asm_option translate_assembler_options(const config::assembler_options& asm_options) +{ + return asm_option { + asm_options.sysparm, + asm_options.profile, + asm_options.system_id.empty() ? asm_option::system_id_default : asm_options.system_id, + }; +} } // namespace processor_group::processor_group( const std::string& name, const config::assembler_options& asm_options, const config::preprocessor_options& pp) : name_(name) - , asm_optns { asm_options.sysparm, asm_options.profile } + , asm_optns(translate_assembler_options(asm_options)) , prep_opts(std::visit(translate_pp_options {}, pp.options)) {} diff --git a/parser_library/test/config/CMakeLists.txt b/parser_library/test/config/CMakeLists.txt index 74f468bb0..8784c3197 100644 --- a/parser_library/test/config/CMakeLists.txt +++ b/parser_library/test/config/CMakeLists.txt @@ -13,4 +13,5 @@ target_sources(library_test PRIVATE pgm_conf_test.cpp proc_grps_test.cpp + system_id_test.cpp ) diff --git a/parser_library/test/config/proc_grps_test.cpp b/parser_library/test/config/proc_grps_test.cpp index 94020047a..e7a3ba866 100644 --- a/parser_library/test/config/proc_grps_test.cpp +++ b/parser_library/test/config/proc_grps_test.cpp @@ -53,7 +53,9 @@ TEST(proc_grps, assembler_options_read) std::make_pair(R"({})"_json, assembler_options {}), std::make_pair(R"({"PROFILE":"MAC"})"_json, assembler_options { "", "MAC" }), std::make_pair(R"({"SYSPARM":"TESTPARM"})"_json, assembler_options { "TESTPARM", "" }), - std::make_pair(R"({"PROFILE":"MAC","SYSPARM":"TESTPARM"})"_json, assembler_options { "TESTPARM", "MAC" }), + std::make_pair(R"({"SYSTEM_ID":"VSE"})"_json, assembler_options { "", "", "VSE" }), + std::make_pair(R"({"PROFILE":"MAC","SYSPARM":"TESTPARM","SYSTEM_ID":"VSE"})"_json, + assembler_options { "TESTPARM", "MAC", "VSE" }), }; for (const auto& [input, expected] : cases) @@ -61,6 +63,7 @@ TEST(proc_grps, assembler_options_read) const auto ao = input.get(); EXPECT_EQ(ao.profile, expected.profile); EXPECT_EQ(ao.sysparm, expected.sysparm); + EXPECT_EQ(ao.system_id, expected.system_id); } } @@ -70,7 +73,9 @@ TEST(proc_grps, assembler_options_write) std::make_pair(R"({})"_json, assembler_options {}), std::make_pair(R"({"PROFILE":"MAC"})"_json, assembler_options { "", "MAC" }), std::make_pair(R"({"SYSPARM":"TESTPARM"})"_json, assembler_options { "TESTPARM", "" }), - std::make_pair(R"({"PROFILE":"MAC","SYSPARM":"TESTPARM"})"_json, assembler_options { "TESTPARM", "MAC" }), + std::make_pair(R"({"SYSTEM_ID":"VSE"})"_json, assembler_options { "", "", "VSE" }), + std::make_pair(R"({"PROFILE":"MAC","SYSPARM":"TESTPARM","SYSTEM_ID":"VSE"})"_json, + assembler_options { "TESTPARM", "MAC", "VSE" }), }; for (const auto& [expected, input] : cases) diff --git a/parser_library/test/config/system_id_test.cpp b/parser_library/test/config/system_id_test.cpp new file mode 100644 index 000000000..7b49f88d7 --- /dev/null +++ b/parser_library/test/config/system_id_test.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2021 Broadcom. + * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Broadcom, Inc. - initial API and implementation + */ + +#include "gtest/gtest.h" + +#include "../common_testing.h" + +TEST(system_id, basic_properties) +{ + std::string input = + R"( +&A SETC '&SYSTEM_ID' +&B SETC T'&SYSTEM_ID +&C SETA K'&SYSTEM_ID +)"; + analyzer a(input, analyzer_options { asm_option { "", "", "VSE" } }); + a.analyze(); + + a.collect_diags(); + EXPECT_TRUE(a.diags().empty()); + + EXPECT_EQ(get_var_value(a.hlasm_ctx(), "A"), "VSE"); + EXPECT_EQ(get_var_value(a.hlasm_ctx(), "B"), "U"); + EXPECT_EQ(get_var_value(a.hlasm_ctx(), "C"), 3); +} + +TEST(system_id, check_defaults) +{ + std::string input = + R"( +&A SETC '&SYSTEM_ID' +&B SETC T'&SYSTEM_ID +&C SETA K'&SYSTEM_ID +)"; + analyzer a(input); + a.analyze(); + + a.collect_diags(); + EXPECT_TRUE(a.diags().empty()); + + EXPECT_EQ(get_var_value(a.hlasm_ctx(), "A"), "z/OS 02.04.00"); + EXPECT_EQ(get_var_value(a.hlasm_ctx(), "B"), "U"); + EXPECT_EQ(get_var_value(a.hlasm_ctx(), "C"), 13); +} diff --git a/parser_library/test/debugging/debugger_test.cpp b/parser_library/test/debugging/debugger_test.cpp index 2e5f83687..d139780ee 100644 --- a/parser_library/test/debugging/debugger_test.cpp +++ b/parser_library/test/debugging/debugger_test.cpp @@ -59,7 +59,7 @@ TEST(debugger, stopped_on_entry) EXPECT_EQ(std::string_view(sc.item(1).name), "Locals"); EXPECT_EQ(std::string_view(sc.item(2).name), "Ordinary symbols"); auto globs = d.variables(sc.item(0).variable_reference); - EXPECT_EQ(globs.size(), 5U); + EXPECT_EQ(globs.size(), 6U); auto locs = d.variables(sc.item(1).variable_reference); EXPECT_EQ(locs.size(), 0U); @@ -178,6 +178,7 @@ struct frame_vars this->globals["&SYSTIME"]; this->globals["&SYSPARM"]; this->globals["&SYSOPT_RENT"]; + this->globals["&SYSTEM_ID"]; } std::unordered_map globals; std::unordered_map locals;