Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
slavek-kucera committed Sep 14, 2021
1 parent f7143c8 commit fa79345
Show file tree
Hide file tree
Showing 12 changed files with 145 additions and 19 deletions.
1 change: 1 addition & 0 deletions clients/vscode-hlasmplugin/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
- Diagnostics lost during JSON serialization
- Files with extension should not be set to hlasm in libs folder
- Lookahead mode does not work correctly when triggered from AINSERTed code
- Remove ALIAS operand parsing limitation

## [0.14.0](https://github.com/eclipse/che-che4z-lsp-for-hlasm/compare/0.13.0...0.14.0) (2021-08-18)

Expand Down
8 changes: 2 additions & 6 deletions parser_library/src/checking/asm_instr_check.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1236,7 +1236,7 @@ bool alias::check(const std::vector<const asm_operand*>& to_check,
{
// TO DO - no support for four characters in EBCDIC (¢, ¬, ±, ¦) - we throw an error although it should
// not be
std::regex regex(R"([\.<¢\(\+\|&!\$\*\);¬\-\/¦,%_>\?`,:#@\=\"~±\[\]\{\}\^\\a-zA-Z0-9]*)");
static const std::regex regex(R"([\.<¢\(\+\|&!\$\*\);¬\-\/¦,%_>\?`,:#@\=\"~±\[\]\{\}\^\\a-zA-Z0-9]*)");
std::string substr = first->operand_identifier.substr(2, first->operand_identifier.size() - 3);
if (!std::regex_match(substr, regex))
{
Expand All @@ -1247,7 +1247,7 @@ bool alias::check(const std::vector<const asm_operand*>& to_check,
}
else if (first->operand_identifier[0] == 'X')
{
if (first->operand_identifier.size() % 2 == 1)
if ((first->operand_identifier.size() - 3) % 2 == 1)
{
add_diagnostic(diagnostic_op::error_A154_ALIAS_X_format_no_of_chars(first->operand_range));
return false;
Expand Down Expand Up @@ -1282,10 +1282,6 @@ bool alias::check(const std::vector<const asm_operand*>& to_check,
}
return true;
}
else
{
return false;
}
}
add_diagnostic(diagnostic_op::error_A151_ALIAS_op_format(first->operand_range));
return false;
Expand Down
5 changes: 5 additions & 0 deletions parser_library/src/diagnostic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,11 @@ diagnostic_op diagnostic_op::error_A162_PROCESS_uknown_option(const std::string&
diagnostic_severity::error, "A162", "Error at *PROCESS instruction: unknown assembler option " + option, range);
}

diagnostic_op diagnostic_op::error_A163_ALIAS_mandatory_label(const range& range)
{
return diagnostic_op(diagnostic_severity::error, "A163", "Label not provided on ALIAS instruction", range);
}

diagnostic_op diagnostic_op::error_A200_SCOPE_param(const std::string& instr_name, const range& range)
{
return diagnostic_op(diagnostic_severity::error,
Expand Down
2 changes: 2 additions & 0 deletions parser_library/src/diagnostic.h
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,8 @@ struct diagnostic_op

static diagnostic_op error_A162_PROCESS_uknown_option(const std::string& option, const range& range);

static diagnostic_op error_A163_ALIAS_mandatory_label(const range& range);

// operand parameters

static diagnostic_op error_A200_SCOPE_param(const std::string& instr_name, const range& range);
Expand Down
10 changes: 8 additions & 2 deletions parser_library/src/parsing/grammar/ca_expr_rules.g4
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,14 @@ term returns [ca_expr_ptr ca_expr]
}
| {is_self_def()}? self_def_term
{
auto r = provider.get_range($self_def_term.ctx);
$ca_expr = std::make_unique<ca_constant>($self_def_term.value, r);
auto& value = $self_def_term.value;
assert(dynamic_cast<const mach_expr_self_def*>(value.get()));
ordinary_assembly_context ctx(hlasm_ctx->ids(), *hlasm_ctx);
auto v = value->evaluate(ctx);
$ca_expr = std::make_unique<expressions::ca_constant>(v.value_kind() == symbol_value_kind::ABS ? v.get_abs() : 0, value->get_range());
$ca_expr->collect_diags_from_child(*value);
}
| num
{
Expand Down
7 changes: 3 additions & 4 deletions parser_library/src/parsing/grammar/hlasmparser.g4
Original file line number Diff line number Diff line change
Expand Up @@ -186,12 +186,11 @@ num_ch
num returns [self_def_t value]
: num_ch {$value = parse_self_def_term("D",$num_ch.ctx->getText(),provider.get_range($num_ch.ctx));};

self_def_term returns [self_def_t value]
self_def_term returns [mach_expr_ptr value]
: ORDSYMBOL string
{
collector.add_hl_symbol(token_info(provider.get_range( $ORDSYMBOL),hl_scopes::self_def_type));
auto opt = $ORDSYMBOL->getText();
$value = parse_self_def_term(opt, $string.value, provider.get_range($ORDSYMBOL,$string.ctx->getStop()));
collector.add_hl_symbol(token_info(provider.get_range($ORDSYMBOL), hl_scopes::self_def_type));
$value = std::make_unique<mach_expr_self_def>($ORDSYMBOL->getText(), $string.value, provider.get_range($ORDSYMBOL, $string.ctx->getStop()));
};


Expand Down
2 changes: 1 addition & 1 deletion parser_library/src/parsing/grammar/machine_expr_rules.g4
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ mach_term returns [mach_expr_ptr m_e]
}
| self_def_term
{
$m_e = std::make_unique<mach_expr_constant>($self_def_term.value, provider.get_range( $self_def_term.ctx));
$m_e = std::move($self_def_term.value);
}
| literal
{
Expand Down
49 changes: 49 additions & 0 deletions parser_library/src/processing/instruction_sets/asm_processor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "expressions/mach_expr_visitor.h"
#include "postponed_statement_impl.h"
#include "processing/context_manager.h"
#include "semantics/operand_visitor.h"

namespace hlasm_plugin::parser_library::processing {

Expand Down Expand Up @@ -642,6 +643,7 @@ asm_processor::process_table_t asm_processor::create_table(context::hlasm_contex
table.emplace(h_ctx.ids().add("CCW1"), [this](rebuilt_statement stmt) { process_CCW(std::move(stmt)); });
table.emplace(h_ctx.ids().add("CNOP"), [this](rebuilt_statement stmt) { process_CNOP(std::move(stmt)); });
table.emplace(h_ctx.ids().add("START"), [this](rebuilt_statement stmt) { process_START(std::move(stmt)); });
table.emplace(h_ctx.ids().add("ALIAS"), [this](rebuilt_statement stmt) { process_ALIAS(std::move(stmt)); });

return table;
}
Expand Down Expand Up @@ -817,4 +819,51 @@ void asm_processor::process_START(rebuilt_statement stmt)
hlasm_ctx.ord_ctx.set_available_location_counter_value(start_section_alignment, offset);
}

void asm_processor::process_ALIAS(rebuilt_statement stmt)
{
if (auto& ops = stmt.operands_ref(); ops.value.size() == 1)
{
using namespace expressions;
using namespace semantics;
class alias_visitor : public mach_expr_visitor, public operand_visitor
{
public:
void visit(const mach_expr_constant&) override {};
void visit(const mach_expr_data_attr&) override {}
void visit(const mach_expr_symbol&) override {}
void visit(const mach_expr_location_counter&) override {}
void visit(const mach_expr_self_def& expr) override { expr.diags().clear(); }
void visit(const mach_expr_default&) override {}

void visit(const empty_operand&) override {}
void visit(const model_operand&) override {}
void visit(const expr_machine_operand&) override {}
void visit(const address_machine_operand&) override {}
void visit(const expr_assembler_operand& op) override { op.expression->apply(*this); }
void visit(const using_instr_assembler_operand&) override {}
void visit(const complex_assembler_operand&) override {}
void visit(const string_assembler_operand&) override {}
void visit(const data_def_operand&) override {}
void visit(const var_ca_operand&) override {}
void visit(const expr_ca_operand&) override {}
void visit(const seq_ca_operand&) override {}
void visit(const branch_ca_operand&) override {}
void visit(const macro_operand_chain&) override {}
void visit(const macro_operand_string&) override {}
} visitor;
// clear self_def_term syntactical diagnostics
ops.value.front()->apply(visitor);
}
if (!check(stmt, hlasm_ctx, checker_, *this))
return;
auto symbol_name = find_label_symbol(stmt);
if (symbol_name->empty())
{
add_diagnostic(diagnostic_op::error_A163_ALIAS_mandatory_label(stmt.stmt_range_ref()));
return;
}

// TODO: check that the symbol_name is an external symbol
}

} // namespace hlasm_plugin::parser_library::processing
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ class asm_processor : public low_language_processor
void process_CCW(rebuilt_statement stmt);
void process_CNOP(rebuilt_statement stmt);
void process_START(rebuilt_statement stmt);
void process_ALIAS(rebuilt_statement stmt);

template<checking::data_instr_type instr_type>
void process_data_instruction(rebuilt_statement stmt);
Expand Down
4 changes: 0 additions & 4 deletions parser_library/test/checking/asm_instr_check_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -876,14 +876,10 @@ TEST_F(instruction_test, ainsert)

TEST_F(instruction_test, alias)
{
// TO DO - not working due to self-defining terms issues

/*
EXPECT_FALSE(checker.check("ALIAS", test_alias_false, range(), collector));
EXPECT_TRUE(checker.check("ALIAS", test_alias_true_one, range(), collector));
EXPECT_TRUE(checker.check("ALIAS", test_alias_true_two, range(), collector));
EXPECT_FALSE(checker.check("ALIAS", test_acontrol_true, range(), collector));
*/
}

TEST_F(instruction_test, amode)
Expand Down
9 changes: 8 additions & 1 deletion parser_library/test/parsing/parser_model_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,14 @@ TEST(parser, invalid_self_def)
range r(position(0, 5), position(0, 12));
auto [op, rem] = parse_model("1,A'10'", r, false, &diag_container);

std::vector<diagnostic_op>& diags = diag_container.diags;
EXPECT_TRUE(diag_container.diags.empty());

ASSERT_EQ(op.value.size(), 2);
auto mach = op.value[1]->access_mach();
ASSERT_TRUE(mach);
mach->collect_diags();

auto& diags = mach->diags();
ASSERT_EQ(diags.size(), 1U);
EXPECT_EQ(diags[0].code, "CE015");

Expand Down
66 changes: 65 additions & 1 deletion parser_library/test/processing/asm_instr_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

#include "gtest/gtest.h"

#include "../common_testing.h"
#include "analyzer.h"
#include "ebcdic_encoding.h"

Expand Down Expand Up @@ -132,4 +133,67 @@ CNOPSYM CNOP ADDR,16
auto symbol = ctx.ord_ctx.get_symbol(ctx.ids().add("CNOPSYM"));
ASSERT_NE(symbol, nullptr);
EXPECT_EQ(symbol->value().get_reloc().offset(), 4);
}
}

TEST(asm_instr_processing, ALIAS_mandatory_label)
{
std::string input = R"(
ALIAS C'SOMESTRING'
ALIAS X'434343434343'
)";

analyzer a(input);
a.analyze();
a.collect_diags();

EXPECT_TRUE(matches_message_codes(a.diags(), { "A163", "A163" }));
}

TEST(asm_instr_processing, ALIAS_external_missing)
{
/* TODO: label must be an external symbol
std::string input = R"(
A ALIAS C'SOMESTRING'
)";
analyzer a(input);
a.analyze();
a.collect_diags();
EXPECT_TRUE(matches_message_codes(a.diags(), { "????" }));
*/
}

TEST(asm_instr_processing, ALIAS_external_present)
{
std::string input = R"(
A DSECT
B START
C CSECT
D DXD F
DC Q(A)
ENTRY E
E DS 0H
DC V(F)
G RSECT
H COM
EXTRN I
WXTRN J
A ALIAS C'STRING'
B ALIAS C'STRING'
C ALIAS C'STRING'
D ALIAS C'STRING'
E ALIAS C'STRING'
F ALIAS C'STRING'
G ALIAS C'STRING'
H ALIAS C'STRING'
I ALIAS C'STRING'
J ALIAS C'STRING'
)";

analyzer a(input);
a.analyze();
a.collect_diags();

EXPECT_TRUE(a.diags().empty());
}

0 comments on commit fa79345

Please sign in to comment.