Skip to content

Commit

Permalink
feat: Basic GOFF, XOBJECT and SYSOPT_XOBJECT support
Browse files Browse the repository at this point in the history
  • Loading branch information
jirimosinger authored Apr 27, 2022
1 parent 5d13a69 commit 3e6daed
Show file tree
Hide file tree
Showing 11 changed files with 86 additions and 14 deletions.
1 change: 1 addition & 0 deletions clients/vscode-hlasmplugin/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
- Expand the list of associated file extensions
- DB2 preprocessor now supports the VERSION option
- Instruction set versioning support
- Basic GOFF, XOBJECT and SYSOPT_XOBJECT support

#### Fixed
- Fixed an issue preventing correct N' attribute evaluation of empty subscript arrays
Expand Down
8 changes: 8 additions & 0 deletions clients/vscode-hlasmplugin/proc_grps_schema
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@
"type": "object",
"description": "List of assembler options",
"properties": {
"GOFF": {
"type": "boolean",
"description": "Produces Generalized Object File format dataset."
},
"OPTABLE": {
"type": "string",
"description": "Specifies the instruction set to use.",
Expand Down Expand Up @@ -90,6 +94,10 @@
"SYSTEM_ID": {
"type": "string",
"description": "Provides the value for the SYSTEM_ID system variable. Defaults to 'z/OS 02.04.00' when omitted."
},
"XOBJECT": {
"type": "boolean",
"description": "Synonym for the GOFF option."
}
}
},
Expand Down
3 changes: 3 additions & 0 deletions parser_library/src/compiler_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ struct asm_option
static constexpr unsigned int sysopt_rent_default = 0;
unsigned int sysopt_rent = sysopt_rent_default;

static constexpr bool sysopt_xobject_default = false;
bool sysopt_xobject = sysopt_xobject_default;

long long statement_count_limit = 10'000'000;
};
} // namespace hlasm_plugin::parser_library
Expand Down
24 changes: 24 additions & 0 deletions parser_library/src/config/proc_grps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ void from_json(const nlohmann::json& j, library& p)
void to_json(nlohmann::json& j, const assembler_options& p)
{
j = nlohmann::json::object();
if (p.goff)
{
j["GOFF"] = p.goff; // GOFF and XOBJECTS are synonyms
}
if (p.optable.size())
j["OPTABLE"] = p.optable;
if (p.profile.size())
Expand All @@ -53,11 +57,31 @@ void to_json(nlohmann::json& j, const assembler_options& p)
if (p.system_id.size())
j["SYSTEM_ID"] = p.system_id;
}

namespace {
bool get_goff_from_json(const nlohmann::json& j)
{
bool goff = false;
bool xobject = false;

if (auto it = j.find("GOFF"); it != j.end())
it->get_to(goff);

if (auto it = j.find("XOBJECT"); it != j.end())
{
it->get_to(xobject);
}

return goff || xobject; // GOFF and XOBJECTS are synonyms
}
} // namespace

void from_json(const nlohmann::json& j, assembler_options& p)
{
if (!j.is_object())
throw nlohmann::json::other_error::create(501, "asm_options must be an object.");

p.goff = get_goff_from_json(j);
if (auto it = j.find("OPTABLE"); it != j.end())
it->get_to(p.optable);
if (auto it = j.find("PROFILE"); it != j.end())
Expand Down
1 change: 1 addition & 0 deletions parser_library/src/config/proc_grps.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ struct assembler_options
std::string profile;
std::string optable;
std::string system_id;
bool goff = false;

bool valid() const noexcept;
};
Expand Down
6 changes: 6 additions & 0 deletions parser_library/src/context/hlasm_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,11 @@ void hlasm_context::add_global_system_vars(code_scope& scope)
ids(), "SYSOPT_RENT", std::to_string(asm_options_.sysopt_rent), true));
}

{
globals_.insert(create_system_variable<system_variable>(
ids(), "SYSOPT_XOBJECT", std::to_string(asm_options_.sysopt_xobject), true));
}

{
globals_.insert(create_system_variable<system_variable>(ids(), "SYSPARM", asm_options_.sysparm, true));
}
Expand All @@ -349,6 +354,7 @@ void hlasm_context::add_global_system_vars(code_scope& scope)
add_global_system_var_to_scope(ids(), "SYSDATE", scope);
add_global_system_var_to_scope(ids(), "SYSTIME", scope);
add_global_system_var_to_scope(ids(), "SYSOPT_RENT", scope);
add_global_system_var_to_scope(ids(), "SYSOPT_XOBJECT", scope);
add_global_system_var_to_scope(ids(), "SYSPARM", scope);
add_global_system_var_to_scope(ids(), "SYSSTMT", scope);
add_global_system_var_to_scope(ids(), "SYSTEM_ID", scope);
Expand Down
13 changes: 6 additions & 7 deletions parser_library/src/workspaces/processor_group.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,12 @@ instruction_set_version processor_group::find_instruction_set(
asm_option processor_group::translate_assembler_options(
const config::assembler_options& asm_options, std::string_view pg_file_name) const
{
return asm_option {
asm_options.sysparm,
asm_options.profile,
asm_options.optable.empty() ? asm_option::instr_set_default
: find_instruction_set(asm_options.optable, pg_file_name),
asm_options.system_id.empty() ? asm_option::system_id_default : asm_options.system_id,
};
return asm_option { .sysparm = asm_options.sysparm,
.profile = asm_options.profile,
.instr_set = asm_options.optable.empty() ? asm_option::instr_set_default
: find_instruction_set(asm_options.optable, pg_file_name),
.system_id = asm_options.system_id.empty() ? asm_option::system_id_default : asm_options.system_id,
.sysopt_xobject = asm_options.goff };
}

void processor_group::collect_diags() const
Expand Down
15 changes: 11 additions & 4 deletions parser_library/test/config/proc_grps_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,11 @@ TEST(proc_grps, assembler_options_read)
std::make_pair(R"({"SYSPARM":"TESTPARM"})"_json, assembler_options { "TESTPARM", "" }),
std::make_pair(R"({"OPTABLE":"ZS9"})"_json, assembler_options { "", "", "ZS9" }),
std::make_pair(R"({"SYSTEM_ID":"VSE"})"_json, assembler_options { "", "", "", "VSE" }),
std::make_pair(R"({"PROFILE":"MAC","SYSPARM":"TESTPARM","OPTABLE":"ZS9","SYSTEM_ID":"VSE"})"_json,
assembler_options { "TESTPARM", "MAC", "ZS9", "VSE" }),
std::make_pair(R"({"GOFF":true})"_json, assembler_options { "", "", "", "", true }),
std::make_pair(R"({"XOBJECT":true})"_json, assembler_options { "", "", "", "", true }),
std::make_pair(
R"({"GOFF":true,"PROFILE":"MAC","SYSPARM":"TESTPARM","OPTABLE":"ZS9","SYSTEM_ID":"VSE","XOBJECT":false})"_json,
assembler_options { "TESTPARM", "MAC", "ZS9", "VSE", true }),
};

for (const auto& [input, expected] : cases)
Expand All @@ -66,6 +69,7 @@ TEST(proc_grps, assembler_options_read)
EXPECT_EQ(ao.sysparm, expected.sysparm);
EXPECT_EQ(ao.optable, expected.optable);
EXPECT_EQ(ao.system_id, expected.system_id);
EXPECT_EQ(ao.goff, expected.goff);
}
}

Expand All @@ -77,8 +81,9 @@ TEST(proc_grps, assembler_options_write)
std::make_pair(R"({"SYSPARM":"TESTPARM"})"_json, assembler_options { "TESTPARM", "" }),
std::make_pair(R"({"OPTABLE":"ZS9"})"_json, assembler_options { "", "", "ZS9" }),
std::make_pair(R"({"SYSTEM_ID":"VSE"})"_json, assembler_options { "", "", "", "VSE" }),
std::make_pair(R"({"PROFILE":"MAC","SYSPARM":"TESTPARM","OPTABLE":"ZS9","SYSTEM_ID":"VSE"})"_json,
assembler_options { "TESTPARM", "MAC", "ZS9", "VSE" }),
std::make_pair(R"({"GOFF":true})"_json, assembler_options { "", "", "", "", true }),
std::make_pair(R"({"GOFF":true,"PROFILE":"MAC","SYSPARM":"TESTPARM","OPTABLE":"ZS9","SYSTEM_ID":"VSE"})"_json,
assembler_options { "TESTPARM", "MAC", "ZS9", "VSE", true }),
};

for (const auto& [expected, input] : cases)
Expand Down Expand Up @@ -219,6 +224,8 @@ TEST(proc_grps, assembler_options_validate)
std::make_pair(assembler_options { "", "", "" }, true),
std::make_pair(assembler_options { "", "", "UNI" }, true),
std::make_pair(assembler_options { "", "", "A" }, false),
std::make_pair(assembler_options { "", "", "", "", false }, true),
std::make_pair(assembler_options { "", "", "", "", true }, true),
};

for (const auto& [input, expected] : cases)
Expand Down
19 changes: 19 additions & 0 deletions parser_library/test/context/system_variable_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -256,4 +256,23 @@ TEST(system_variable, sysstyp_empty)
EXPECT_EQ(a.diags().size(), (size_t)0);

EXPECT_EQ(get_var_value<C_t>(a.hlasm_ctx(), "VAR"), "");
}

TEST(system_variable, sysopt_xobject)
{
std::string input = R"(
&VAR SETB (&SYSOPT_XOBJECT)
END
)";

auto cases = { std::make_pair(true, true), std::make_pair(false, false) };
for (auto [xobject, expected] : cases)
{
analyzer a(input, analyzer_options(asm_option { .sysopt_xobject = xobject }));
a.analyze();
a.collect_diags();
EXPECT_TRUE(a.diags().empty());

EXPECT_EQ(get_var_value<B_t>(a.hlasm_ctx(), "VAR"), expected);
}
}
3 changes: 2 additions & 1 deletion parser_library/test/debugging/debugger_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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(), 7U);
EXPECT_EQ(globs.size(), 8U);
auto locs = d.variables(sc.item(1).variable_reference);
EXPECT_EQ(locs.size(), 0U);

Expand Down Expand Up @@ -178,6 +178,7 @@ struct frame_vars
this->globals["&SYSDATC"];
this->globals["&SYSTIME"];
this->globals["&SYSOPT_RENT"];
this->globals["&SYSOPT_XOBJECT"];
this->globals["&SYSPARM"];
this->globals["&SYSSTMT"];
this->globals["&SYSTEM_ID"];
Expand Down
7 changes: 5 additions & 2 deletions parser_library/test/workspace/processor_group_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,16 @@ auto pp_options(decltype(config::preprocessor_options::options) o)

TEST(processor_group, assembler_options)
{
EXPECT_EQ(asm_options({ .optable = "XA" }).instr_set, instruction_set_version::XA);
EXPECT_EQ(asm_options({}).instr_set, asm_option::instr_set_default);
EXPECT_EQ(asm_options({ .profile = "PROFILE" }).profile, "PROFILE");
EXPECT_EQ(asm_options({ .sysparm = "SYSPARM" }).sysparm, "SYSPARM");
EXPECT_EQ(asm_options({ .system_id = "SYSID" }).system_id, "SYSID");
EXPECT_EQ(asm_options({}).system_id, asm_option::system_id_default);
EXPECT_EQ(asm_options({}).sysopt_rent, asm_option::sysopt_rent_default);
EXPECT_EQ(asm_options({ .goff = true }).sysopt_xobject, true);
EXPECT_EQ(asm_options({ .goff = false }).sysopt_xobject, false);
EXPECT_EQ(asm_options({}).sysopt_xobject, asm_option::sysopt_xobject_default);
}

TEST(processor_group, preprocessor_options)
Expand Down Expand Up @@ -63,7 +68,6 @@ TEST_F(processor_group_test, asm_options_optable_valid)
{
std::string grp_name = "Group";
config::assembler_options asm_opts;
asm_opts.optable = "UNI";

const auto cases = {
std::make_pair("ZOP", instruction_set_version::ZOP),
Expand Down Expand Up @@ -112,7 +116,6 @@ TEST_F(processor_group_test, asm_options_optable_invalid)
{
std::string grp_name = "Group";
config::assembler_options asm_opts;
asm_opts.optable = "UNI";

const auto cases = {
std::make_pair("klgadh", instruction_set_version::UNI),
Expand Down

0 comments on commit 3e6daed

Please sign in to comment.