From 470bfba45661d19558c0bf43b7819696a925ecb4 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Mon, 6 Jul 2026 10:44:15 +0200 Subject: Fix compiler crashing on syntax errors after error reporting. --- boot/dependency.cc | 19 +++---- boot/driver.cc | 10 +--- boot/lexer.ll | 2 +- boot/parser.yy | 4 +- boot/result.cc | 9 +-- boot/semantic.cc | 53 ++++++++--------- gcc/gcc/elna-diagnostic.cc | 7 +++ gcc/gcc/elna-generic.cc | 2 +- gcc/gcc/elna-tree.cc | 2 +- gcc/gcc/elna1.cc | 66 ++++++++++++---------- include/elna/boot/dependency.h | 46 +++++++++++++-- include/elna/boot/driver.h | 5 +- include/elna/boot/result.h | 7 +-- include/elna/boot/semantic.h | 19 +++---- include/elna/gcc/elna-diagnostic.h | 11 ++-- include/elna/gcc/elna-generic.h | 6 +- source/command_line_interface.elna | 2 +- source/common.elna | 2 +- source/cstdio.elna | 8 +-- source/cstdlib.elna | 4 +- source/cstring.elna | 12 ++-- source/lexer.elna | 24 ++++---- source/main.elna | 34 +++++------ .../compilable/semicolon_parameter_separator.elna | 4 ++ 24 files changed, 193 insertions(+), 165 deletions(-) create mode 100644 testsuite/compilable/semicolon_parameter_separator.elna diff --git a/boot/dependency.cc b/boot/dependency.cc index 6b10611..84fd800 100644 --- a/boot/dependency.cc +++ b/boot/dependency.cc @@ -27,18 +27,13 @@ along with GCC; see the file COPYING3. If not see namespace elna::boot { - dependency::dependency(const char *path) - : error_container(path) + dependency read_source(std::istream& entry_point) { - } - - dependency read_source(std::istream& entry_point, const char *entry_path) - { - driver parse_driver{ entry_path }; + driver parse_driver; lexer tokenizer(entry_point); yy::parser parser(tokenizer, parse_driver); - dependency outcome{ entry_path }; + dependency outcome; if (parser()) { std::swap(outcome.errors(), parse_driver.errors()); @@ -48,7 +43,7 @@ namespace elna::boot { std::swap(outcome.tree, parse_driver.tree); } - declaration_visitor declaration_visitor(entry_path); + declaration_visitor declaration_visitor; outcome.tree->accept(&declaration_visitor); if (!declaration_visitor.errors().empty()) @@ -60,16 +55,16 @@ namespace elna::boot return outcome; } - error_list analyze_semantics(const char *path, std::unique_ptr& tree, symbol_bag bag) + error_list analyze_semantics(std::unique_ptr& tree, symbol_bag bag) { - name_analysis_visitor name_analyser(path, bag); + name_analysis_visitor name_analyser(bag); tree->accept(&name_analyser); if (name_analyser.has_errors()) { return std::move(name_analyser.errors()); } - type_analysis_visitor type_analyzer(path, bag); + type_analysis_visitor type_analyzer(bag); tree->accept(&type_analyzer); if (type_analyzer.has_errors()) diff --git a/boot/driver.cc b/boot/driver.cc index abbf0f1..b2ffe60 100644 --- a/boot/driver.cc +++ b/boot/driver.cc @@ -28,9 +28,8 @@ namespace elna::boot return result; } - syntax_error::syntax_error(const std::string& message, - const char *input_file, const yy::location& location) - : error(input_file, make_position(location)), message(message) + syntax_error::syntax_error(const std::string& message, const yy::location& location) + : error(make_position(location)), message(message) { } @@ -39,11 +38,6 @@ namespace elna::boot return message; } - driver::driver(const char *input_file) - : error_container(input_file) - { - } - char escape_char(char escape) { switch (escape) diff --git a/boot/lexer.ll b/boot/lexer.ll index fac70f0..4f9fed7 100644 --- a/boot/lexer.ll +++ b/boot/lexer.ll @@ -309,6 +309,6 @@ of { std::stringstream ss; ss << "Illegal character 0x" << std::hex << static_cast(yytext[0]); - driver.add_error(ss.str(), driver.input_file, this->location); + driver.add_error(ss.str(), this->location); } %% diff --git a/boot/parser.yy b/boot/parser.yy index 4d4f038..a36b953 100644 --- a/boot/parser.yy +++ b/boot/parser.yy @@ -576,7 +576,7 @@ formal_parameter_list: "(" ")" {} | "(" formal_parameters ")" { std::swap($$, $2); } formal_parameters: - formal_parameter "," formal_parameters + formal_parameter ";" formal_parameters { std::swap($$, $3); $$.emplace($$.cbegin(), std::move($1)); @@ -589,5 +589,5 @@ actual_parameter_list: void yy::parser::error(const location_type& loc, const std::string& message) { - driver.add_error(message, driver.input_file, loc); + driver.add_error(message, loc); } diff --git a/boot/result.cc b/boot/result.cc index dab82f4..2222bd5 100644 --- a/boot/result.cc +++ b/boot/result.cc @@ -19,8 +19,8 @@ along with GCC; see the file COPYING3. If not see namespace elna::boot { - error::error(const char *path, const struct position position) - : position(position), path(path) + error::error(const struct position position) + : position(position) { } @@ -34,11 +34,6 @@ namespace elna::boot return this->position.column; } - error_container::error_container(const char *input_file) - : input_file(input_file) - { - } - std::deque>& error_container::errors() { return m_errors; diff --git a/boot/semantic.cc b/boot/semantic.cc index 300c91d..29ef3c1 100644 --- a/boot/semantic.cc +++ b/boot/semantic.cc @@ -22,8 +22,8 @@ along with GCC; see the file COPYING3. If not see namespace elna::boot { - undeclared_error::undeclared_error(const std::string& identifier, const char *path, const struct position position) - : error(path, position), identifier(identifier) + undeclared_error::undeclared_error(const std::string& identifier, const struct position position) + : error(position), identifier(identifier) { } @@ -32,9 +32,8 @@ namespace elna::boot return "Type '" + identifier + "' not declared"; } - already_declared_error::already_declared_error(const std::string& identifier, - const char *path, const struct position position) - : error(path, position), identifier(identifier) + already_declared_error::already_declared_error(const std::string& identifier, const struct position position) + : error(position), identifier(identifier) { } @@ -43,9 +42,8 @@ namespace elna::boot return "Symbol '" + identifier + "' has been already declared"; } - field_duplication_error::field_duplication_error(const std::string& field_name, - const char *path, const struct position position) - : error(path, position), field_name(field_name) + field_duplication_error::field_duplication_error(const std::string& field_name, const struct position position) + : error(position), field_name(field_name) { } @@ -55,8 +53,8 @@ namespace elna::boot } cyclic_declaration_error::cyclic_declaration_error(const std::vector& cycle, - const char *path, const struct position position) - : error(path, position), cycle(cycle) + const struct position position) + : error(position), cycle(cycle) { } @@ -73,8 +71,8 @@ namespace elna::boot return message; } - return_error::return_error(const std::string& identifier, const char *path, const struct position position) - : error(path, position), identifier(identifier) + return_error::return_error(const std::string& identifier, const struct position position) + : error(position), identifier(identifier) { } @@ -83,8 +81,8 @@ namespace elna::boot return "Procedure '" + identifier + "' is expected to return, but does not have a return statement"; } - variable_initializer_error::variable_initializer_error(const char *path, const struct position position) - : error(path, position) + variable_initializer_error::variable_initializer_error(const struct position position) + : error(position) { } @@ -93,8 +91,8 @@ namespace elna::boot return "Only one variable can be initialized"; } - type_analysis_visitor::type_analysis_visitor(const char *path, symbol_bag bag) - : error_container(path), bag(bag) + type_analysis_visitor::type_analysis_visitor(symbol_bag bag) + : error_container(), bag(bag) { } @@ -113,7 +111,7 @@ namespace elna::boot } if (!this->returns) { - add_error(definition->identifier.name, this->input_file, definition->position()); + add_error(definition->identifier.name, definition->position()); } } } @@ -187,12 +185,12 @@ namespace elna::boot if (!check_unresolved_symbol(unresolved_type, alias_path)) { - add_error(alias_path, this->input_file, definition->position()); + add_error(alias_path, definition->position()); } } - name_analysis_visitor::name_analysis_visitor(const char *path, symbol_bag bag) - : error_container(path), bag(bag) + name_analysis_visitor::name_analysis_visitor(symbol_bag bag) + : error_container(), bag(bag) { } @@ -280,7 +278,7 @@ namespace elna::boot { if (field_names.find(field.first) != field_names.cend()) { - add_error(field.first, this->input_file, field.second->position()); + add_error(field.first, field.second->position()); } else { @@ -332,7 +330,7 @@ namespace elna::boot if (!this->bag.enter(name, variable_symbol)) { - add_error(name, this->input_file, position); + add_error(name, position); } return variable_symbol; } @@ -567,7 +565,7 @@ namespace elna::boot } else { - add_error(type_expression->name, this->input_file, type_expression->position()); + add_error(type_expression->name, type_expression->position()); this->current_type = type(); } } @@ -623,8 +621,8 @@ namespace elna::boot this->current_literal = literal->value; } - declaration_visitor::declaration_visitor(const char *path) - : error_container(path) + declaration_visitor::declaration_visitor() + : error_container() { } @@ -663,8 +661,7 @@ namespace elna::boot if (!this->unresolved.insert({ type_identifier, std::make_shared(type_identifier) }).second) { - add_error(definition->identifier.name, this->input_file, - definition->position()); + add_error(definition->identifier.name, definition->position()); } } @@ -672,7 +669,7 @@ namespace elna::boot { if (declaration->has_initializer() && declaration->identifiers.size() > 1) { - add_error(this->input_file, declaration->position()); + add_error(declaration->position()); } } diff --git a/gcc/gcc/elna-diagnostic.cc b/gcc/gcc/elna-diagnostic.cc index fa32788..509871c 100644 --- a/gcc/gcc/elna-diagnostic.cc +++ b/gcc/gcc/elna-diagnostic.cc @@ -26,6 +26,13 @@ namespace elna::gcc linemap_add(line_table, LC_ENTER, 0, filename, 1); } + linemap_guard::linemap_guard(const std::filesystem::path filename) + { + const char *filename_pointer = ggc_strdup(filename.native().c_str()); + + linemap_add(line_table, LC_ENTER, 0, filename_pointer, 1); + } + linemap_guard::~linemap_guard() { linemap_add(line_table, LC_LEAVE, 0, NULL, 0); diff --git a/gcc/gcc/elna-generic.cc b/gcc/gcc/elna-generic.cc index 2c16a37..eb30b4d 100644 --- a/gcc/gcc/elna-generic.cc +++ b/gcc/gcc/elna-generic.cc @@ -17,8 +17,8 @@ along with GCC; see the file COPYING3. If not see #include -#include "elna/gcc/elna-generic.h" #include "elna/gcc/elna-diagnostic.h" +#include "elna/gcc/elna-generic.h" #include "elna/gcc/elna1.h" #include "elna/gcc/elna-builtins.h" diff --git a/gcc/gcc/elna-tree.cc b/gcc/gcc/elna-tree.cc index de7f6b0..835702a 100644 --- a/gcc/gcc/elna-tree.cc +++ b/gcc/gcc/elna-tree.cc @@ -15,8 +15,8 @@ You should have received a copy of the GNU General Public License along with GCC; see the file COPYING3. If not see . */ -#include "elna/gcc/elna-tree.h" #include "elna/gcc/elna-diagnostic.h" +#include "elna/gcc/elna-tree.h" #include "elna/gcc/elna1.h" #include "function.h" diff --git a/gcc/gcc/elna1.cc b/gcc/gcc/elna1.cc index 0333f70..c87d462 100644 --- a/gcc/gcc/elna1.cc +++ b/gcc/gcc/elna1.cc @@ -15,6 +15,14 @@ You should have received a copy of the GNU General Public License along with GCC; see the file COPYING3. If not see . */ +#include + +#include "elna/gcc/elna-diagnostic.h" +#include "elna/boot/dependency.h" +#include "elna/gcc/elna-tree.h" +#include "elna/gcc/elna-generic.h" +#include "elna/gcc/elna-builtins.h" + #include "config.h" #include "system.h" #include "coretypes.h" @@ -28,13 +36,6 @@ along with GCC; see the file COPYING3. If not see #include "langhooks.h" #include "langhooks-def.h" -#include -#include "elna/boot/dependency.h" -#include "elna/gcc/elna-tree.h" -#include "elna/gcc/elna-generic.h" -#include "elna/gcc/elna-diagnostic.h" -#include "elna/gcc/elna-builtins.h" - tree elna_global_trees[ELNA_TI_MAX]; hash_map *elna_global_decls = nullptr; @@ -73,36 +74,36 @@ static elna::boot::dependency elna_parse_file(dependency_state& state, const cha fatal_error(UNKNOWN_LOCATION, "Cannot open filename %s: %m", filename); } elna::gcc::linemap_guard{ filename }; - elna::boot::dependency outcome = elna::boot::read_source(entry_point, filename); + elna::boot::dependency outcome = elna::boot::read_source(entry_point); - if (outcome.has_errors()) - { - elna::gcc::report_errors(outcome.errors()); - return outcome; - } - elna::boot::symbol_bag outcome_bag = elna::boot::symbol_bag{ std::move(outcome.unresolved), state.globals }; + elna::boot::symbol_bag outcome_bag{ std::move(outcome.unresolved), state.globals }; - for (const auto& sub_tree : outcome.tree->imports) + if (!outcome.has_errors()) { - std::filesystem::path sub_path = "source" / elna::boot::build_path(sub_tree->segments); - std::unordered_map::const_iterator cached_import = - state.cache.find(sub_path); - - if (cached_import == state.cache.end()) + for (elna::boot::import_declaration const* sub_tree : outcome.tree->imports) { - elna_parse_file(state, sub_path.c_str()); - cached_import = state.cache.find(sub_path); + std::filesystem::path sub_path = "source" / elna::boot::build_path(sub_tree->segments); + dependency_state::const_iterator cached_import = state.find(sub_path); + + if (cached_import == state.cend()) + { + auto filename_pointer = ggc_strdup(sub_path.native().c_str()); + + elna_parse_file(state, filename_pointer); + cached_import = state.find(sub_path); + } + if (cached_import != state.cend()) + { + outcome_bag.add_import(cached_import->second); + } } - outcome_bag.add_import(cached_import->second); + outcome.errors() = analyze_semantics(outcome.tree, outcome_bag); } - outcome.errors() = analyze_semantics(filename, outcome.tree, outcome_bag); - if (outcome.has_errors()) { elna::gcc::report_errors(outcome.errors()); - return outcome; } - state.cache.insert({ filename, outcome_bag }); + state.insert(filename, outcome_bag); elna::gcc::rewrite_symbol_table(outcome_bag.leave(), state.custom); return outcome; @@ -116,10 +117,13 @@ static void elna_langhook_parse_file(void) { elna::boot::dependency outcome = elna_parse_file(state, in_fnames[i]); - linemap_add(line_table, LC_ENTER, 0, in_fnames[i], 1); - elna::gcc::generic_visitor generic_visitor{ state.custom, state.cache.find(in_fnames[i])->second }; - outcome.tree->accept(&generic_visitor); - linemap_add(line_table, LC_LEAVE, 0, NULL, 0); + if (!outcome.has_errors()) + { + linemap_add(line_table, LC_ENTER, 0, in_fnames[i], 1); + elna::gcc::generic_visitor generic_visitor{ state.custom, state.find(in_fnames[i])->second }; + outcome.tree->accept(&generic_visitor); + linemap_add(line_table, LC_LEAVE, 0, NULL, 0); + } } } diff --git a/include/elna/boot/dependency.h b/include/elna/boot/dependency.h index 4ec4d44..5f6eba5 100644 --- a/include/elna/boot/dependency.h +++ b/include/elna/boot/dependency.h @@ -33,23 +33,59 @@ namespace elna::boot std::unique_ptr tree; forward_table unresolved; - explicit dependency(const char *path); + dependency() = default; }; - dependency read_source(std::istream& entry_point, const char *entry_path); + dependency read_source(std::istream& entry_point); std::filesystem::path build_path(const std::vector& segments); - error_list analyze_semantics(const char *path, std::unique_ptr& tree, symbol_bag bag); + error_list analyze_semantics(std::unique_ptr& tree, symbol_bag bag); template - struct dependency_state + class dependency_state { + std::unordered_map cache; + + public: const std::shared_ptr globals; T custom; - std::unordered_map cache; + + using iterator = typename std::unordered_map::iterator; + using const_iterator = typename std::unordered_map::const_iterator; explicit dependency_state(T custom) : globals(builtin_symbol_table()), custom(custom) { } + + const_iterator find(const std::filesystem::path& key) + { + return cache.find(key); + } + + void insert(const std::filesystem::path& key, symbol_bag value) + { + cache.insert({ key, value }); + } + + iterator begin() + { + return this->cache.begin(); + } + + iterator end() + { + return this->cache.end(); + } + + const_iterator cbegin() const + { + return this->cache.cbegin(); + } + + const_iterator cend() const + { + return this->cache.cend(); + } + }; } diff --git a/include/elna/boot/driver.h b/include/elna/boot/driver.h index 288aa0c..cd29376 100644 --- a/include/elna/boot/driver.h +++ b/include/elna/boot/driver.h @@ -30,8 +30,7 @@ namespace elna::boot std::string message; public: - syntax_error(const std::string& message, - const char *input_file, const yy::location& location); + syntax_error(const std::string& message, const yy::location& location); virtual std::string what() const override; }; @@ -41,7 +40,7 @@ namespace elna::boot public: std::unique_ptr tree; - driver(const char *input_file); + driver() = default; }; constexpr char escape_invalid_char = '\xff'; diff --git a/include/elna/boot/result.h b/include/elna/boot/result.h index 9fc1849..3a84229 100644 --- a/include/elna/boot/result.h +++ b/include/elna/boot/result.h @@ -43,11 +43,10 @@ namespace elna::boot class error { protected: - error(const char *path, const struct position position); + error(const struct position position); public: const struct position position; - const char *path; virtual ~error() = default; @@ -68,11 +67,9 @@ namespace elna::boot protected: error_list m_errors; - error_container(const char *input_file); + error_container() = default; public: - const char *input_file; - error_list& errors(); template diff --git a/include/elna/boot/semantic.h b/include/elna/boot/semantic.h index 7094ee9..97286f0 100644 --- a/include/elna/boot/semantic.h +++ b/include/elna/boot/semantic.h @@ -33,7 +33,7 @@ namespace elna::boot const std::string identifier; public: - undeclared_error(const std::string& identifier, const char *path, const struct position position); + undeclared_error(const std::string& identifier, const struct position position); std::string what() const override; }; @@ -43,7 +43,7 @@ namespace elna::boot const std::string identifier; public: - already_declared_error(const std::string& identifier, const char *path, const struct position position); + already_declared_error(const std::string& identifier, const struct position position); std::string what() const override; }; @@ -53,7 +53,7 @@ namespace elna::boot const std::string field_name; public: - field_duplication_error(const std::string& field_name, const char *path, const struct position position); + field_duplication_error(const std::string& field_name, const struct position position); std::string what() const override; }; @@ -63,8 +63,7 @@ namespace elna::boot const std::vector cycle; public: - cyclic_declaration_error(const std::vector& cycle, - const char *path, const struct position position); + cyclic_declaration_error(const std::vector& cycle, const struct position position); std::string what() const override; }; @@ -74,7 +73,7 @@ namespace elna::boot const std::string identifier; public: - return_error(const std::string& identifier, const char *path, const struct position position); + return_error(const std::string& identifier, const struct position position); std::string what() const override; }; @@ -82,7 +81,7 @@ namespace elna::boot class variable_initializer_error : public error { public: - variable_initializer_error(const char *path, const struct position position); + variable_initializer_error(const struct position position); std::string what() const override; }; @@ -99,7 +98,7 @@ namespace elna::boot std::vector& path); public: - explicit type_analysis_visitor(const char *path, symbol_bag bag); + explicit type_analysis_visitor(symbol_bag bag); void visit(program *program) override; @@ -132,7 +131,7 @@ namespace elna::boot const bool is_extern, const struct position position); public: - name_analysis_visitor(const char *path, symbol_bag bag); + name_analysis_visitor(symbol_bag bag); void visit(type_expression *) override; void visit(array_type_expression *type_expression) override; @@ -182,7 +181,7 @@ namespace elna::boot public: forward_table unresolved; - explicit declaration_visitor(const char *path); + explicit declaration_visitor(); void visit(program *program) override; void visit(import_declaration *) override; diff --git a/include/elna/gcc/elna-diagnostic.h b/include/elna/gcc/elna-diagnostic.h index 1eef65d..a8d4a69 100644 --- a/include/elna/gcc/elna-diagnostic.h +++ b/include/elna/gcc/elna-diagnostic.h @@ -17,16 +17,15 @@ along with GCC; see the file COPYING3. If not see #pragma once +#include +#include +#include + #include "config.h" #include "system.h" #include "coretypes.h" -#include "input.h" -#include "tree.h" #include "diagnostic.h" -#include -#include - #include "elna/boot/result.h" namespace elna::gcc @@ -34,6 +33,8 @@ namespace elna::gcc struct linemap_guard { explicit linemap_guard(const char *filename); + explicit linemap_guard(const std::filesystem::path filename); + linemap_guard(const linemap_guard&) = delete; linemap_guard(linemap_guard&&) = delete; diff --git a/include/elna/gcc/elna-generic.h b/include/elna/gcc/elna-generic.h index 9e148e6..77fd792 100644 --- a/include/elna/gcc/elna-generic.h +++ b/include/elna/gcc/elna-generic.h @@ -17,6 +17,9 @@ along with GCC; see the file COPYING3. If not see #pragma once +#include +#include + #include "elna/boot/ast.h" #include "elna/boot/symbol.h" #include "elna/boot/semantic.h" @@ -28,9 +31,6 @@ along with GCC; see the file COPYING3. If not see #include "tree.h" #include "tree-iterator.h" -#include -#include - namespace elna::gcc { class generic_visitor final : public boot::empty_visitor diff --git a/source/command_line_interface.elna b/source/command_line_interface.elna index 78e1cf5..eeb2103 100644 --- a/source/command_line_interface.elna +++ b/source/command_line_interface.elna @@ -15,7 +15,7 @@ type parse: Bool end -proc parse_command_line*(argc: Int, argv: ^^Char) -> ^CommandLine +proc parse_command_line*(argc: Int; argv: ^^Char) -> ^CommandLine var parameter: ^Char i: Int diff --git a/source/common.elna b/source/common.elna index 33a79b8..f75751c 100644 --- a/source/common.elna +++ b/source/common.elna @@ -11,7 +11,7 @@ type column: Word end -proc write*(fd: Int, buf: Pointer, Word: Int) -> Int +proc write*(fd: Int; buf: Pointer; Word: Int) -> Int extern proc write_s*(value: String) diff --git a/source/cstdio.elna b/source/cstdio.elna index b86014f..c589200 100644 --- a/source/cstdio.elna +++ b/source/cstdio.elna @@ -10,13 +10,13 @@ var stdout*: ^FILE := extern stderr*: ^FILE := extern -proc fopen*(pathname: ^Char, mode: ^Char) -> ^FILE +proc fopen*(pathname: ^Char; mode: ^Char) -> ^FILE extern proc fclose*(stream: ^FILE) -> Int extern -proc fseek*(stream: ^FILE, off: Int, whence: Int) -> Int +proc fseek*(stream: ^FILE; off: Int; whence: Int) -> Int extern proc rewind*(stream: ^FILE) @@ -28,10 +28,10 @@ extern proc fflush*(stream: ^FILE) -> Int extern -proc fread*(ptr: Pointer, size: Word, nmemb: Word, stream: ^FILE) -> Word +proc fread*(ptr: Pointer; size: Word; nmemb: Word; stream: ^FILE) -> Word extern -proc fwrite*(ptr: Pointer, size: Word, nitems: Word, stream: ^FILE) -> Word +proc fwrite*(ptr: Pointer; size: Word; nitems: Word; stream: ^FILE) -> Word extern proc perror(s: ^Char) diff --git a/source/cstdlib.elna b/source/cstdlib.elna index 3346440..930246d 100644 --- a/source/cstdlib.elna +++ b/source/cstdlib.elna @@ -8,10 +8,10 @@ extern proc free(ptr: Pointer) extern -proc calloc(nmemb: Word, size: Word) -> Pointer +proc calloc(nmemb: Word; size: Word) -> Pointer extern -proc realloc(ptr: Pointer, size: Word) -> Pointer +proc realloc(ptr: Pointer; size: Word) -> Pointer extern proc atoi(str: ^Char) -> Int diff --git a/source/cstring.elna b/source/cstring.elna index ef04e59..e19658f 100644 --- a/source/cstring.elna +++ b/source/cstring.elna @@ -2,22 +2,22 @@ v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. *) -proc memset(ptr: Pointer, c: Int, n: Word) -> ^Char +proc memset(ptr: Pointer; c: Int; n: Word) -> ^Char extern -proc memcpy(dst: Pointer, src: Pointer, n: Word) +proc memcpy(dst: Pointer; src: Pointer; n: Word) extern -proc strcmp(s1: ^Char, s2: ^Char) -> Int +proc strcmp(s1: ^Char; s2: ^Char) -> Int extern -proc strncmp(s1: ^Char, s2: ^Char, n: Word) -> Int +proc strncmp(s1: ^Char; s2: ^Char; n: Word) -> Int extern -proc strncpy(dst: ^Char, src: ^Char, dsize: Word) -> ^Char +proc strncpy(dst: ^Char; src: ^Char; dsize: Word) -> ^Char extern -proc strcpy(dst: ^Char, src: ^Char) -> ^Char +proc strcpy(dst: ^Char; src: ^Char) -> ^Char extern proc strlen(ptr: ^Char) -> Word diff --git a/source/lexer.elna b/source/lexer.elna index e6fc38c..b3250d0 100644 --- a/source/lexer.elna +++ b/source/lexer.elna @@ -298,7 +298,7 @@ begin end end -proc compare_keyword(keyword: String, token_start: BufferPosition, token_end: ^Char) -> Bool +proc compare_keyword(keyword: String; token_start: BufferPosition; token_end: ^Char) -> Bool var result: Bool index: Word @@ -321,7 +321,7 @@ begin end (* Reached the end of file. *) -proc transition_action_eof(lexer: ^Lexer, token: ^LexerToken) +proc transition_action_eof(lexer: ^Lexer; token: ^LexerToken) begin token^.kind := LexerKind.unknown end @@ -332,14 +332,14 @@ begin end (* Add the character to the token currently read and advance to the next character. *) -proc transition_action_accumulate(lexer: ^Lexer, token: ^LexerToken) +proc transition_action_accumulate(lexer: ^Lexer; token: ^LexerToken) begin increment(@lexer^.current) end (* The current character is not a part of the token. Finish the token already * read. Don't advance to the next character. *) -proc transition_action_finalize(lexer: ^Lexer, token: ^LexerToken) +proc transition_action_finalize(lexer: ^Lexer; token: ^LexerToken) begin if lexer^.start.iterator^ = ':' then token^.kind := LexerKind.colon @@ -362,7 +362,7 @@ begin end (* An action for tokens containing multiple characters. *) -proc transition_action_composite(lexer: ^Lexer, token: ^LexerToken) +proc transition_action_composite(lexer: ^Lexer; token: ^LexerToken) begin if lexer^.start.iterator^ = '<' then if lexer^.current.iterator^ = '>' then @@ -385,7 +385,7 @@ begin end (* Skip a space. *) -proc transition_action_skip(lexer: ^Lexer, token: ^LexerToken) +proc transition_action_skip(lexer: ^Lexer; token: ^LexerToken) begin increment(@lexer^.start); @@ -397,7 +397,7 @@ begin end (* Delimited string action. *) -proc transition_action_delimited(lexer: ^Lexer, token: ^LexerToken) +proc transition_action_delimited(lexer: ^Lexer; token: ^LexerToken) var text_length: Word begin @@ -424,7 +424,7 @@ begin end (* Finalize keyword or identifier. *) -proc transition_action_key_id(lexer: ^Lexer, token: ^LexerToken) +proc transition_action_key_id(lexer: ^Lexer; token: ^LexerToken) begin token^.kind := LexerKind.identifier; @@ -518,7 +518,7 @@ end (* Action for tokens containing only one character. The character cannot be * followed by other characters forming a composite token. *) -proc transition_action_single(lexer: ^Lexer, token: ^LexerToken) +proc transition_action_single(lexer: ^Lexer; token: ^LexerToken) begin if lexer^.current.iterator^ = '&' then token^.kind := LexerKind.and @@ -569,7 +569,7 @@ begin end (* Handle an integer literal. *) -proc transition_action_integer(lexer: ^Lexer, token: ^LexerToken) +proc transition_action_integer(lexer: ^Lexer; token: ^LexerToken) var buffer: String integer_length: Word @@ -585,7 +585,7 @@ begin token^.value.integerKind := atoi(@token^.value.identifierKind[2]) end -proc set_default_transition(current_state: TransitionState, default_action: TransitionAction, next_state: TransitionState) -> Int +proc set_default_transition(current_state: TransitionState; default_action: TransitionAction; next_state: TransitionState) -> Int var default_transition: Transition state_index: Int @@ -878,7 +878,7 @@ begin transitions[state_index][cast(TransitionClass.x: Int) + 1].next_state := TransitionState.finish end -proc lexer_make*(lexer: ^Lexer, input: ^FILE) +proc lexer_make*(lexer: ^Lexer; input: ^FILE) begin lexer^.input := input; lexer^.length := 0u; diff --git a/source/main.elna b/source/main.elna index db5e76f..468556d 100644 --- a/source/main.elna +++ b/source/main.elna @@ -41,15 +41,15 @@ type (* Standard procedures. *) -proc reallocarray(ptr: Pointer, n: Word, size: Word) -> Pointer +proc reallocarray(ptr: Pointer; n: Word; size: Word) -> Pointer return realloc(ptr, n * size) end -proc substring(string: String, start: Word, count: Word) -> String +proc substring(string: String; start: Word; count: Word) -> String return String(string.ptr + start, count) end -proc open_substring(string: String, start: Word) -> String +proc open_substring(string: String; start: Word) -> String return substring(string, start, string.length - start) end @@ -74,7 +74,7 @@ begin return result end -proc string_buffer_push(buffer: ^StringBuffer, char: Char) +proc string_buffer_push(buffer: ^StringBuffer; char: Char) begin if buffer^.size >= buffer^.capacity then buffer^.capacity := buffer^.capacity + 1024u; @@ -84,7 +84,7 @@ begin buffer^.size := buffer^.size + 1u end -proc string_buffer_pop(buffer: ^StringBuffer, count: Word) +proc string_buffer_pop(buffer: ^StringBuffer; count: Word) begin buffer^.size := buffer^.size - count end @@ -170,7 +170,7 @@ begin source_code^.position.column := 0u end -proc source_code_expect(source_code: ^SourceCode, expected: Char) -> Bool +proc source_code_expect(source_code: ^SourceCode; expected: Char) -> Bool return ~source_code_empty(source_code) & source_code_head(source_code^) = expected end @@ -178,7 +178,7 @@ end Token procedures. *) -proc lexer_escape(escape: Char, result: ^Char) -> Bool +proc lexer_escape(escape: Char; result: ^Char) -> Bool var successful: Bool begin @@ -236,7 +236,7 @@ proc lexer_is_ident(char: Char) -> Bool return isalnum(cast(char: Int)) <> 0 or char = '_' end -proc lexer_identifier(source_code: ^SourceCode, token_content: ^StringBuffer) +proc lexer_identifier(source_code: ^SourceCode; token_content: ^StringBuffer) var content_length: Word begin @@ -246,7 +246,7 @@ begin end end -proc lexer_comment(source_code: ^SourceCode, token_content: ^StringBuffer) -> Bool +proc lexer_comment(source_code: ^SourceCode; token_content: ^StringBuffer) -> Bool var trailing: Word begin @@ -269,7 +269,7 @@ begin return trailing = 2u end -proc lexer_character(source_code: ^SourceCode, token_content: ^Char) -> Bool +proc lexer_character(source_code: ^SourceCode; token_content: ^Char) -> Bool var successful: Bool begin @@ -291,7 +291,7 @@ begin return successful end -proc lexer_string(source_code: ^SourceCode, token_content: ^StringBuffer) -> Bool +proc lexer_string(source_code: ^SourceCode; token_content: ^StringBuffer) -> Bool var token_end, constructed_string: ^Char token_length: Word @@ -314,7 +314,7 @@ begin return is_valid end -proc lexer_number(source_code: ^SourceCode, token_content: ^Int) +proc lexer_number(source_code: ^SourceCode; token_content: ^Int) begin token_content^ := 0; @@ -394,7 +394,7 @@ begin return current_token end -proc lexer_add_token(lexer: ^Tokenizer, token: Token) +proc lexer_add_token(lexer: ^Tokenizer; token: Token) var new_length: Word begin @@ -405,7 +405,7 @@ begin end (* Read the next token from the input. *) -proc lexer_next(source_code: SourceCode, token_buffer: ^StringBuffer) -> Token +proc lexer_next(source_code: SourceCode; token_buffer: ^StringBuffer) -> Token var current_token: Token first_char: Char @@ -611,7 +611,7 @@ end Parser. *) -proc parse(tokens: ^Token, tokens_size: Word) +proc parse(tokens: ^Token; tokens_size: Word) var current_token: ^Token i: Word := 0u @@ -773,7 +773,7 @@ end Compilation entry. *) -proc compile_in_stages(command_line: ^CommandLine, source_code: SourceCode) -> Int +proc compile_in_stages(command_line: ^CommandLine; source_code: SourceCode) -> Int var return_code: Int := 0 lexer: Tokenizer @@ -788,7 +788,7 @@ begin return return_code end -proc process(argc: Int, argv: ^^Char) -> Int +proc process(argc: Int; argv: ^^Char) -> Int var tokens: ^Token tokens_size: Word diff --git a/testsuite/compilable/semicolon_parameter_separator.elna b/testsuite/compilable/semicolon_parameter_separator.elna new file mode 100644 index 0000000..36c8f29 --- /dev/null +++ b/testsuite/compilable/semicolon_parameter_separator.elna @@ -0,0 +1,4 @@ +proc f(a: Int; b: Word) +end + +end. -- cgit v1.2.3