Skip to content

Commit

Permalink
fix: Process END instruction (#184)
Browse files Browse the repository at this point in the history
Co-authored-by: slavek-kucera <53339291+slavek-kucera@users.noreply.github.com>
Co-authored-by: Michal Bali <38988507+michalbali256@users.noreply.github.com>
  • Loading branch information
3 people authored Oct 14, 2021
1 parent bcc3792 commit 2d5ad75
Show file tree
Hide file tree
Showing 17 changed files with 528 additions and 44 deletions.
1 change: 1 addition & 0 deletions clients/vscode-hlasmplugin/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
- START, MHELP instructions
- Wildcard support in library specification
- Support for SYSTEM_ID system variable.
- END instruction

#### Fixed
- Preserve mixed-case labels on macro calls
Expand Down
12 changes: 6 additions & 6 deletions parser_library/src/checking/asm_instr_check.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -847,7 +847,7 @@ bool end::check(const std::vector<const asm_operand*>& to_check,
{
if (!is_operand_simple(to_check[0]) && !is_operand_empty(to_check[0])) // first operand must be simple
{
add_diagnostic(diagnostic_op::error_A243_END_expr_format(to_check[0]->operand_range));
add_diagnostic(diagnostic_op::warning_A243_END_expr_format(to_check[0]->operand_range));
return false;
}
}
Expand All @@ -871,15 +871,15 @@ bool end::check(const std::vector<const asm_operand*>& to_check,
}
if (language_operand->operand_identifier != "")
{
add_diagnostic(diagnostic_op::error_A137_END_lang_format(language_operand->operand_range));
add_diagnostic(diagnostic_op::warning_A137_END_lang_format(language_operand->operand_range));
return false;
}
for (const auto& param : language_operand->operand_parameters)
{
// all parameters must be simple
if (!is_operand_simple(param.get()))
{
add_diagnostic(diagnostic_op::error_A248_END_lang_char_sequence(param->operand_range));
add_diagnostic(diagnostic_op::warning_A248_END_lang_char_sequence(param->operand_range));
return false;
}
}
Expand All @@ -888,22 +888,22 @@ bool end::check(const std::vector<const asm_operand*>& to_check,
> END_lang_first_par_size)
{
add_diagnostic(
diagnostic_op::error_A138_END_lang_first(language_operand->operand_parameters[0]->operand_range));
diagnostic_op::warning_A138_END_lang_first(language_operand->operand_parameters[0]->operand_range));
return false;
}
if (get_simple_operand(language_operand->operand_parameters[1].get())->operand_identifier.size()
!= END_lang_second_par_size)
{
add_diagnostic(
diagnostic_op::error_A139_END_lang_second(language_operand->operand_parameters[1]->operand_range));
diagnostic_op::warning_A139_END_lang_second(language_operand->operand_parameters[1]->operand_range));
return false;
}
auto third_op = get_simple_operand(language_operand->operand_parameters[2].get());
if (third_op->operand_identifier.size() != END_lang_third_par_size
|| !has_all_digits(third_op->operand_identifier))
{
add_diagnostic(
diagnostic_op::error_A140_END_lang_third(language_operand->operand_parameters[2]->operand_range));
diagnostic_op::warning_A140_END_lang_third(language_operand->operand_parameters[2]->operand_range));
return false;
}
}
Expand Down
11 changes: 11 additions & 0 deletions parser_library/src/context/hlasm_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,17 @@ std::vector<copy_member_invocation>& hlasm_plugin::parser_library::context::hlas
return source_stack_.front().copy_stack;
}

void hlasm_plugin::parser_library::context::hlasm_context::end_reached()
{
assert(!m_end_reached);
m_end_reached = true;

scope_stack_.erase(scope_stack_.begin() + 1, scope_stack_.end());
source_stack_.erase(source_stack_.begin() + 1, source_stack_.end());
source_stack_.front().copy_stack.clear();
proc_stack_.erase(proc_stack_.begin() + 1, proc_stack_.end());
}

std::vector<id_index> hlasm_context::whole_copy_stack() const
{
std::vector<id_index> ret;
Expand Down
5 changes: 3 additions & 2 deletions parser_library/src/context/hlasm_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ class hlasm_context

// last AINSERT virtual file id
size_t m_ainsert_id = 0;

bool m_end_reached = false;
void add_system_vars_to_scope();
void add_global_system_vars();

Expand Down Expand Up @@ -130,7 +130,8 @@ class hlasm_context
std::vector<copy_member_invocation>& opencode_copy_stack();
// is open code being processed
bool in_opencode() const { return source_stack_.size() == 1; }

bool get_end_reached() const { return m_end_reached; };
void end_reached();
// gets names of whole copy nest
std::vector<id_index> whole_copy_stack() const;

Expand Down
1 change: 1 addition & 0 deletions parser_library/src/context/id_storage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,5 @@ id_storage::well_known_strings::well_known_strings(std::unordered_set<std::strin
, ACTR(&*ptr.emplace("ACTR").first)
, AREAD(&*ptr.emplace("AREAD").first)
, ALIAS(&*ptr.emplace("ALIAS").first)
, END(&*ptr.emplace("END").first)
{}
1 change: 1 addition & 0 deletions parser_library/src/context/id_storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ class id_storage
const std::string* AGO;
const std::string* ACTR;
const std::string* AREAD;
const std::string* END;
const std::string* ALIAS;
well_known_strings(std::unordered_set<std::string>& ptr);

Expand Down
45 changes: 23 additions & 22 deletions parser_library/src/diagnostic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -462,37 +462,37 @@ diagnostic_op diagnostic_op::error_A136_ENTRY_op_format(const range& range)
range);
}

diagnostic_op diagnostic_op::error_A137_END_lang_format(const range& range)
diagnostic_op diagnostic_op::warning_A137_END_lang_format(const range& range)
{
return diagnostic_op(diagnostic_severity::error,
return diagnostic_op(diagnostic_severity::warning,
"A137",
"Error at END instruction: language operand must be in the following format: (char10, char4, char5)",
"Language operand parameter must be in the following format: (char10, char4, char5)",
range);
}

diagnostic_op diagnostic_op::error_A138_END_lang_first(const range& range)
diagnostic_op diagnostic_op::warning_A138_END_lang_first(const range& range)
{
return diagnostic_op(diagnostic_severity::error,
return diagnostic_op(diagnostic_severity::warning,
"A138",
"Error at END instruction: first parameter of language operand (language translator identifier) must be a 1 to "
"First parameter of language operand (language translator identifier) must be a 1 to "
"10 character code",
range);
}

diagnostic_op diagnostic_op::error_A139_END_lang_second(const range& range)
diagnostic_op diagnostic_op::warning_A139_END_lang_second(const range& range)
{
return diagnostic_op(diagnostic_severity::error,
return diagnostic_op(diagnostic_severity::warning,
"A139",
"Error at END instruction: second parameter of language operand (version and release code) must be exactly 4 "
"Second parameter of language operand (version and release code) must be exactly 4 "
"character long",
range);
}

diagnostic_op diagnostic_op::error_A140_END_lang_third(const range& range)
diagnostic_op diagnostic_op::warning_A140_END_lang_third(const range& range)
{
return diagnostic_op(diagnostic_severity::error,
return diagnostic_op(diagnostic_severity::warning,
"A140",
"Error at END instruction: third parameter of language operand must be exactly 5 character long and must "
"Third parameter of language operand must be exactly 5 character long and must "
"specify the compile date in the \"YYDDD\" format",
range);
}
Expand Down Expand Up @@ -1094,11 +1094,11 @@ diagnostic_op diagnostic_op::error_A242_ICTL_op_format_second_third(const range&
range);
}

diagnostic_op diagnostic_op::error_A243_END_expr_format(const range& range)
diagnostic_op diagnostic_op::warning_A243_END_expr_format(const range& range)
{
return diagnostic_op(diagnostic_severity::error,
return diagnostic_op(diagnostic_severity::warning,
"A243",
"Error at END instruction: first operand must either be an expresison or the operand must be omitted",
"First operand must either be an expresison or the operand must be omitted",
range);
}

Expand Down Expand Up @@ -1134,12 +1134,10 @@ diagnostic_op diagnostic_op::error_A247_must_be_rel_abs_expr(const std::string&
range);
}

diagnostic_op diagnostic_op::error_A248_END_lang_char_sequence(const range& range)
diagnostic_op diagnostic_op::warning_A248_END_lang_char_sequence(const range& range)
{
return diagnostic_op(diagnostic_severity::error,
"A248",
"Error at END instruction at language operand: parameter must be a character sequence",
range);
return diagnostic_op(
diagnostic_severity::warning, "A248", "Language operand parameter must be a character sequence", range);
}

diagnostic_op diagnostic_op::warning_A249_sequence_symbol_expected(const range& range)
Expand Down Expand Up @@ -1374,7 +1372,6 @@ diagnostic_op diagnostic_op::error_D005(const range& range)
{
return diagnostic_op(diagnostic_severity::error, "D005", "Unexpected '.' in modifier other than length", range);
}

diagnostic_op diagnostic_op::error_D006(const range& range)
{
return diagnostic_op(
Expand Down Expand Up @@ -1883,7 +1880,11 @@ diagnostic_op diagnostic_op::warning_W014(const range& range)
"Undefined keyword parameter, default to positional including keyword",
range);
}

diagnostic_op diagnostic_op::warning_W015(const range& range)
{
return diagnostic_op(
diagnostic_severity::warning, "W015", "End of source input reached, batch mode is not supported yet", range);
}
diagnostic_op diagnostic_op::error_EQU1(const range& range)
{
return diagnostic_op(diagnostic_severity::error, "EQU1", "Constant redefinition", range);
Expand Down
14 changes: 8 additions & 6 deletions parser_library/src/diagnostic.h
Original file line number Diff line number Diff line change
Expand Up @@ -227,13 +227,13 @@ struct diagnostic_op

static diagnostic_op error_A136_ENTRY_op_format(const range& range);

static diagnostic_op error_A137_END_lang_format(const range& range);
static diagnostic_op warning_A137_END_lang_format(const range& range);

static diagnostic_op error_A138_END_lang_first(const range& range);
static diagnostic_op warning_A138_END_lang_first(const range& range);

static diagnostic_op error_A139_END_lang_second(const range& range);
static diagnostic_op warning_A139_END_lang_second(const range& range);

static diagnostic_op error_A140_END_lang_third(const range& range);
static diagnostic_op warning_A140_END_lang_third(const range& range);

static diagnostic_op error_A141_DROP_op_format(const range& range);

Expand Down Expand Up @@ -374,7 +374,7 @@ struct diagnostic_op

static diagnostic_op error_A242_ICTL_op_format_second_third(const range& range);

static diagnostic_op error_A243_END_expr_format(const range& range);
static diagnostic_op warning_A243_END_expr_format(const range& range);

static diagnostic_op error_A244_PUNCH_char_string(const range& range);

Expand All @@ -384,7 +384,7 @@ struct diagnostic_op

static diagnostic_op error_A247_must_be_rel_abs_expr(const std::string& instr_name, const range& range);

static diagnostic_op error_A248_END_lang_char_sequence(const range& range);
static diagnostic_op warning_A248_END_lang_char_sequence(const range& range);

static diagnostic_op warning_A249_sequence_symbol_expected(const range& range);

Expand Down Expand Up @@ -592,6 +592,8 @@ struct diagnostic_op

static diagnostic_op warning_W014(const range& range);

static diagnostic_op warning_W015(const range& range);

static diagnostic_op error_EQU1(const range& range);

static diagnostic_op error_EQU2(const range& range);
Expand Down
9 changes: 8 additions & 1 deletion parser_library/src/parsing/grammar/lookahead_rules.g4
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,14 @@
parser grammar lookahead_rules;

look_lab_instr returns [std::optional<std::string> op_text, range op_range]
: seq_symbol .*? EOF
: seq_symbol SPACE ORDSYMBOL (SPACE .*?)? EOF
{
collector.set_label_field($seq_symbol.ss,provider.get_range($seq_symbol.ctx));
auto instr_id = parse_identifier($ORDSYMBOL->getText(),provider.get_range($ORDSYMBOL));
collector.set_instruction_field(instr_id,provider.get_range($ORDSYMBOL));
collector.set_operand_remark_field(provider.get_range($seq_symbol.ctx));
}
| seq_symbol .*? EOF
{
collector.set_label_field($seq_symbol.ss,provider.get_range($seq_symbol.ctx));
collector.set_instruction_field(provider.get_range($seq_symbol.ctx));
Expand Down
26 changes: 26 additions & 0 deletions parser_library/src/processing/instruction_sets/asm_processor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -643,6 +643,7 @@ asm_processor::process_table_t asm_processor::create_table(context::hlasm_contex
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)); });
table.emplace(h_ctx.ids().add("END"), [this](rebuilt_statement stmt) { process_END(std::move(stmt)); });

return table;
}
Expand Down Expand Up @@ -817,7 +818,32 @@ 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_END(rebuilt_statement stmt)
{
const auto& label = stmt.label_ref();
check(stmt, hlasm_ctx, checker_, *this);

if (!(label.type == semantics::label_si_type::EMPTY || label.type == semantics::label_si_type::SEQ))
{
add_diagnostic(diagnostic_op::warning_A249_sequence_symbol_expected(stmt.label_ref().field_range));
}
if (!stmt.operands_ref().value.empty() && !(stmt.operands_ref().value[0]->type == semantics::operand_type::EMPTY))
{
if (stmt.operands_ref().value[0]->access_asm() != nullptr
&& stmt.operands_ref().value[0]->access_asm()->kind == semantics::asm_kind::EXPR)
{
auto symbol = stmt.operands_ref().value[0]->access_asm()->access_expr()->expression.get()->evaluate(
hlasm_ctx.ord_ctx);

if (symbol.value_kind() == context::symbol_value_kind::ABS)
{
add_diagnostic(
diagnostic_op::error_E032(std::to_string(symbol.get_abs()), stmt.operands_ref().field_range));
}
}
}
hlasm_ctx.end_reached();
}
void asm_processor::process_ALIAS(rebuilt_statement stmt)
{
if (!check(stmt, hlasm_ctx, checker_, *this))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ class asm_processor : public low_language_processor
void process_START(rebuilt_statement stmt);
void process_ALIAS(rebuilt_statement stmt);

void process_END(rebuilt_statement stmt);

template<checking::data_instr_type instr_type>
void process_data_instruction(rebuilt_statement stmt);

Expand All @@ -82,4 +84,4 @@ class asm_processor : public low_language_processor
};

} // namespace hlasm_plugin::parser_library::processing
#endif
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -47,23 +47,29 @@ void lookahead_processor::process_statement(context::shared_stmt_ptr statement)
{
if (auto resolved = statement->access_resolved())
{
auto opcode = resolved->opcode_ref().value;

if (macro_nest_ == 0)
{
find_seq(*resolved);
find_ord(*resolved);
}
if (resolved->opcode_ref().value == macro_id)
if (opcode == macro_id)
{
process_MACRO();
}
else if (resolved->opcode_ref().value == mend_id)
else if (opcode == mend_id)
{
process_MEND();
}
else if (macro_nest_ == 0 && resolved->opcode_ref().value == copy_id)
else if (macro_nest_ == 0 && opcode == copy_id)
{
process_COPY(*resolved);
}
else if (opcode == hlasm_ctx.ids().well_known.END)
{
finished_flag_ = true;
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,18 @@ void ordinary_processor::process_statement(context::shared_stmt_ptr s)

auto statement = std::static_pointer_cast<const processing::resolved_statement>(std::move(s));

if (hlasm_ctx.get_end_reached())
{
if (statement->label_ref().type != semantics::label_si_type::EMPTY
|| statement->instruction_ref().type != semantics::instruction_si_type::EMPTY
|| !statement->operands_ref().value.empty())
{
add_diagnostic(diagnostic_op::warning_W015(range(statement->statement_position())));
finished_flag_ = true;
}
return;
}

switch (statement->opcode_ref().type)
{
case context::instruction_type::UNDEF:
Expand Down Expand Up @@ -133,6 +145,7 @@ bool ordinary_processor::terminal_condition(const statement_provider_kind prov_k

bool ordinary_processor::finished() { return finished_flag_; }


struct processing_status_visitor
{
context::id_index id;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ class ordinary_processor : public statement_processor
processing_status get_processing_status(const semantics::instruction_si& instruction) const override;
void process_statement(context::shared_stmt_ptr statement) override;
void end_processing() override;

bool terminal_condition(const statement_provider_kind kind) const override;
bool finished() override;

Expand Down
Loading

0 comments on commit 2d5ad75

Please sign in to comment.