aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2026-07-07 21:39:57 +0200
committerEugen Wissner <belka@caraus.de>2026-07-07 21:39:57 +0200
commit79521d91b2bb85652fd29f5c44279338d55c757f (patch)
treed3b5b73177f63fd5ff684a8aba6f7b9af84dab27
parent470bfba45661d19558c0bf43b7819696a925ecb4 (diff)
downloadelna-79521d91b2bb85652fd29f5c44279338d55c757f.tar.gz
Allow multiple parameters with same type
-rw-r--r--boot/ast.cc10
-rw-r--r--boot/lexer.ll3
-rw-r--r--boot/parser.yy43
-rw-r--r--boot/semantic.cc54
-rw-r--r--include/elna/boot/ast.h7
-rw-r--r--include/elna/boot/semantic.h13
-rw-r--r--source/cctype.elna12
-rw-r--r--source/command_line_interface.elna2
-rw-r--r--source/common.elna2
-rw-r--r--source/cstdio.elna18
-rw-r--r--source/cstdlib.elna10
-rw-r--r--source/cstring.elna12
-rw-r--r--source/lexer.elna10
-rw-r--r--source/main.elna50
-rw-r--r--testsuite/compilable/empty_proc_type_expression.elna2
-rw-r--r--testsuite/runnable/aggregate_argument.elna2
-rw-r--r--testsuite/runnable/aggregate_equality.elna2
-rw-r--r--testsuite/runnable/define_multiple_local_variables.elna16
-rw-r--r--testsuite/runnable/return_aggregate.elna16
-rw-r--r--testsuite/runnable/two_parameters_same_type.elna9
20 files changed, 146 insertions, 147 deletions
diff --git a/boot/ast.cc b/boot/ast.cc
index 91b46a4..b7604e5 100644
--- a/boot/ast.cc
+++ b/boot/ast.cc
@@ -485,8 +485,10 @@ namespace elna::boot
delete m_body;
}
- procedure_type_expression::procedure_type_expression(const struct position position, return_t return_type)
- : node(position), return_type(return_type)
+ procedure_type_expression::procedure_type_expression(const struct position position,
+ std::vector<std::pair<std::vector<std::string>, std::shared_ptr<type_expression>>>&& parameters,
+ return_t return_type)
+ : node(position), return_type(return_type), parameters(std::move(parameters))
{
}
@@ -496,10 +498,6 @@ namespace elna::boot
{
delete return_type.proper_type;
}
- for (const type_expression *parameter : this->parameters)
- {
- delete parameter;
- }
}
void procedure_type_expression::accept(parser_visitor *visitor)
diff --git a/boot/lexer.ll b/boot/lexer.ll
index 4f9fed7..f914d75 100644
--- a/boot/lexer.ll
+++ b/boot/lexer.ll
@@ -275,9 +275,6 @@ of {
\+ {
return yy::parser::make_PLUS(this->location);
}
-\-> {
- return yy::parser::make_ARROW(this->location);
-}
\- {
return yy::parser::make_MINUS(this->location);
}
diff --git a/boot/parser.yy b/boot/parser.yy
index a36b953..3b8e69e 100644
--- a/boot/parser.yy
+++ b/boot/parser.yy
@@ -82,7 +82,7 @@ along with GCC; see the file COPYING3. If not see
%token <bool> BOOLEAN
%token LEFT_PAREN "(" RIGHT_PAREN ")" LEFT_SQUARE "[" RIGHT_SQUARE "]"
%token ASSIGNMENT ":="
- ARROW "->" EXCLAMATION "!"
+ EXCLAMATION "!"
AT "@" HAT "^"
COLON ":" SEMICOLON ";" DOT "." COMMA ","
%token NOT "~"
@@ -143,15 +143,18 @@ along with GCC; see the file COPYING3. If not see
%type <std::vector<elna::boot::statement *>> statements;
%type <std::unique_ptr<std::vector<elna::boot::statement *>>> statement_part;
%type <elna::boot::procedure_declaration *> procedure_declaration;
-%type <std::pair<std::vector<std::string>, elna::boot::procedure_type_expression *>> procedure_heading;
+%type <elna::boot::procedure_type_expression *> procedure_heading;
%type <elna::boot::procedure_type_expression::return_t> return_declaration;
%type <std::vector<elna::boot::procedure_declaration *>> procedure_part;
%type <elna::boot::type_declaration *> type_declaration;
%type <std::vector<elna::boot::type_declaration *>> type_declarations type_part;
%type <std::unique_ptr<elna::boot::block>> block;
-%type <elna::boot::field_declaration> field_declaration formal_parameter;
+%type <elna::boot::field_declaration> field_declaration;
+%type <std::pair<std::vector<std::string>, std::shared_ptr<elna::boot::type_expression>>> formal_parameter;
%type <std::vector<std::pair<std::string, elna::boot::type_expression *>>>
- optional_fields required_fields formal_parameters formal_parameter_list;
+ optional_fields required_fields;
+%type <std::vector<std::pair<std::vector<std::string>, std::shared_ptr<elna::boot::type_expression>>>>
+ formal_parameters formal_parameter_list;
%type <std::vector<elna::boot::conditional_statements *>> elsif_then_statements elsif_do_statements;
%type <std::vector<elna::boot::statement *> *> else_statements;
%type <elna::boot::cast_expression *> cast_expression;
@@ -215,28 +218,21 @@ identifier_definitions:
| identifier_definition { $$.emplace_back(std::move($1)); }
return_declaration:
/* proper procedure */ {}
- | "->" "!" { $$ = boot::procedure_type_expression::return_t(std::monostate{}); }
- | "->" type_expression { $$ = boot::procedure_type_expression::return_t($2); }
+ | ":" "!" { $$ = boot::procedure_type_expression::return_t(std::monostate{}); }
+ | ":" type_expression { $$ = boot::procedure_type_expression::return_t($2); }
procedure_heading: formal_parameter_list return_declaration
{
- $$.second = new boot::procedure_type_expression(boot::make_position(@1), std::move($2));
- for (auto& [name, type] : $1)
- {
- $$.first.emplace_back(std::move(name));
- $$.second->parameters.push_back(type);
- }
+ $$ = new boot::procedure_type_expression(boot::make_position(@1), std::move($1), std::move($2));
}
procedure_declaration:
"proc" identifier_definition procedure_heading block
{
- $$ = new boot::procedure_declaration(boot::make_position(@1), std::move($2), $3.second,
+ $$ = new boot::procedure_declaration(boot::make_position(@1), std::move($2), $3,
std::move(*$4));
- std::swap($3.first, $$->parameter_names);
}
| "proc" identifier_definition procedure_heading "extern"
{
- $$ = new boot::procedure_declaration(boot::make_position(@1), std::move($2), $3.second);
- std::swap($3.first, $$->parameter_names);
+ $$ = new boot::procedure_declaration(boot::make_position(@1), std::move($2), $3);
}
procedure_part:
/* no procedure declarations */ {}
@@ -474,11 +470,9 @@ type_expression:
{
$$ = new boot::union_type_expression(boot::make_position(@1), std::move($2));
}
- | "proc" "(" type_expressions ")" return_declaration
+ | "proc" formal_parameter_list return_declaration
{
- auto result = new boot::procedure_type_expression(boot::make_position(@1), std::move($5));
- std::swap(result->parameters, $3);
- $$ = result;
+ $$ = new boot::procedure_type_expression(boot::make_position(@1), std::move($2), std::move($3));
}
| "(" identifiers ")"
{
@@ -571,7 +565,7 @@ type_part:
/* no type definitions */ {}
| "type" type_declarations { std::swap($$, $2); }
formal_parameter:
- IDENTIFIER ":" type_expression { $$ = std::make_pair($1, $3); }
+ identifiers ":" type_expression { $$ = std::make_pair(std::move($1), std::shared_ptr<boot::type_expression>($3)); }
formal_parameter_list:
"(" ")" {}
| "(" formal_parameters ")" { std::swap($$, $2); }
@@ -579,9 +573,12 @@ formal_parameters:
formal_parameter ";" formal_parameters
{
std::swap($$, $3);
- $$.emplace($$.cbegin(), std::move($1));
+ $$.emplace($$.cbegin(), std::move($1.first), $1.second);
+ }
+ | formal_parameter
+ {
+ $$.emplace_back(std::move($1.first), $1.second);
}
- | formal_parameter { $$.emplace_back(std::move($1)); }
actual_parameter_list:
"(" ")" {}
| "(" expressions ")" { std::swap($$, $2); }
diff --git a/boot/semantic.cc b/boot/semantic.cc
index 29ef3c1..cd50742 100644
--- a/boot/semantic.cc
+++ b/boot/semantic.cc
@@ -81,16 +81,6 @@ namespace elna::boot
return "Procedure '" + identifier + "' is expected to return, but does not have a return statement";
}
- variable_initializer_error::variable_initializer_error(const struct position position)
- : error(position)
- {
- }
-
- std::string variable_initializer_error::what() const
- {
- return "Only one variable can be initialized";
- }
-
type_analysis_visitor::type_analysis_visitor(symbol_bag bag)
: error_container(), bag(bag)
{
@@ -194,7 +184,8 @@ namespace elna::boot
{
}
- procedure_type name_analysis_visitor::build_procedure(procedure_type_expression& type_expression)
+ std::pair<procedure_type, std::vector<std::string>> name_analysis_visitor::build_procedure(
+ procedure_type_expression& type_expression)
{
procedure_type::return_t result_return;
@@ -211,12 +202,17 @@ namespace elna::boot
{
result_return = procedure_type::return_t();
}
- procedure_type result_type = procedure_type(result_return);
-
- for (struct type_expression *parameter : type_expression.parameters)
+ std::pair<procedure_type, std::vector<std::string>> result_type{
+ procedure_type(result_return), std::vector<std::string>()
+ };
+ for (auto& [parameter_names, parameters_type] : type_expression.parameters)
{
- parameter->accept(this);
- result_type.parameters.push_back(this->current_type);
+ parameters_type->accept(this);
+ for (auto& parameter_name : parameter_names)
+ {
+ result_type.first.parameters.push_back(this->current_type);
+ result_type.second.push_back(parameter_name);
+ }
}
return result_type;
}
@@ -311,7 +307,7 @@ namespace elna::boot
void name_analysis_visitor::visit(procedure_type_expression *type_expression)
{
std::shared_ptr<procedure_type> result_type =
- std::make_shared<procedure_type>(std::move(build_procedure(*type_expression)));
+ std::make_shared<procedure_type>(std::move(build_procedure(*type_expression).first));
this->current_type = type(result_type);
}
@@ -359,16 +355,15 @@ namespace elna::boot
void name_analysis_visitor::visit(procedure_declaration *definition)
{
std::shared_ptr<procedure_info> info;
- auto heading = build_procedure(definition->heading());
+ auto [heading, parameter_names] = build_procedure(definition->heading());
if (definition->body.has_value())
{
- info = std::make_shared<procedure_info>(heading, definition->parameter_names, this->bag.enter());
- auto name_iterator = std::cbegin(definition->parameter_names);
+ info = std::make_shared<procedure_info>(heading, std::move(parameter_names), this->bag.enter());
+ auto name_iterator = std::cbegin(info->names);
auto type_iterator = std::cbegin(heading.parameters);
- while (name_iterator != std::cend(definition->parameter_names)
- && type_iterator != std::cend(heading.parameters))
+ while (name_iterator != std::cend(info->names) && type_iterator != std::cend(heading.parameters))
{
this->current_type = *type_iterator;
auto variable_symbol = register_variable(*name_iterator, false, definition->heading().position());
@@ -393,7 +388,7 @@ namespace elna::boot
}
else
{
- info = std::make_shared<procedure_info>(heading, definition->parameter_names);
+ info = std::make_shared<procedure_info>(heading, std::move(parameter_names));
}
info->exported = definition->identifier.exported;
this->bag.enter(definition->identifier.name, info);
@@ -494,7 +489,12 @@ namespace elna::boot
void name_analysis_visitor::visit(procedure_call *call)
{
- call->callable().accept(this);
+ auto name_expression = call->callable().is_named();
+
+ if (name_expression == nullptr || name_expression->name != "assert")
+ {
+ call->callable().accept(this);
+ }
for (expression *const argument: call->arguments)
{
argument->accept(this);
@@ -665,12 +665,8 @@ namespace elna::boot
}
}
- void declaration_visitor::visit(variable_declaration *declaration)
+ void declaration_visitor::visit(variable_declaration *)
{
- if (declaration->has_initializer() && declaration->identifiers.size() > 1)
- {
- add_error<variable_initializer_error>(declaration->position());
- }
}
void declaration_visitor::visit(procedure_declaration *definition)
diff --git a/include/elna/boot/ast.h b/include/elna/boot/ast.h
index 03d3e27..b9414f0 100644
--- a/include/elna/boot/ast.h
+++ b/include/elna/boot/ast.h
@@ -381,9 +381,11 @@ namespace elna::boot
using return_t = return_declaration<type_expression *>;
const return_t return_type;
- std::vector<type_expression *> parameters;
+ const std::vector<std::pair<std::vector<std::string>, std::shared_ptr<type_expression>>> parameters;
- procedure_type_expression(const struct position position, return_t return_type = return_t());
+ procedure_type_expression(const struct position position,
+ std::vector<std::pair<std::vector<std::string>, std::shared_ptr<type_expression>>>&& parameters,
+ return_t return_type = return_t());
~procedure_type_expression();
void accept(parser_visitor *visitor) override;
@@ -423,7 +425,6 @@ namespace elna::boot
public:
std::optional<block> body;
- std::vector<std::string> parameter_names;
procedure_declaration(const struct position position, identifier_definition identifier,
procedure_type_expression *heading, block&& body);
diff --git a/include/elna/boot/semantic.h b/include/elna/boot/semantic.h
index 97286f0..a0a4a73 100644
--- a/include/elna/boot/semantic.h
+++ b/include/elna/boot/semantic.h
@@ -78,14 +78,6 @@ namespace elna::boot
std::string what() const override;
};
- class variable_initializer_error : public error
- {
- public:
- variable_initializer_error(const struct position position);
-
- std::string what() const override;
- };
-
/**
* Checks types.
*/
@@ -125,7 +117,8 @@ namespace elna::boot
symbol_bag bag;
- procedure_type build_procedure(procedure_type_expression& type_expression);
+ std::pair<procedure_type, std::vector<std::string>> build_procedure(
+ procedure_type_expression& type_expression);
std::vector<type_field> build_composite_type(const std::vector<field_declaration>& fields);
std::shared_ptr<variable_info> register_variable(const std::string& name,
const bool is_extern, const struct position position);
@@ -187,7 +180,7 @@ namespace elna::boot
void visit(import_declaration *) override;
void visit(unit *unit) override;
void visit(type_declaration *definition) override;
- void visit(variable_declaration *declaration) override;
+ void visit(variable_declaration *) override;
void visit(procedure_declaration *definition) override;
};
}
diff --git a/source/cctype.elna b/source/cctype.elna
index 13dc50a..1296a10 100644
--- a/source/cctype.elna
+++ b/source/cctype.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 isdigit*(c: Int ) -> Int
+proc isdigit*(c: Int ): Int
extern
-proc isalnum*(c: Int) -> Int
+proc isalnum*(c: Int): Int
extern
-proc isalpha*(c: Int) -> Int
+proc isalpha*(c: Int): Int
extern
-proc isspace*(c: Int) -> Int
+proc isspace*(c: Int): Int
extern
-proc tolower*(c: Int) -> Int
+proc tolower*(c: Int): Int
extern
-proc toupper*(c: Int) -> Int
+proc toupper*(c: Int): Int
extern
end.
diff --git a/source/command_line_interface.elna b/source/command_line_interface.elna
index eeb2103..b9006f1 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 f75751c..7790faf 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 c589200..95283a1 100644
--- a/source/cstdio.elna
+++ b/source/cstdio.elna
@@ -10,37 +10,37 @@ 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
+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)
extern
-proc ftell*(stream: ^FILE) -> Int
+proc ftell*(stream: ^FILE): Int
extern
-proc fflush*(stream: ^FILE) -> Int
+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)
extern
-proc puts(s: ^Char) -> Int
+proc puts(s: ^Char): Int
extern
-proc putchar(c: Int) -> Int
+proc putchar(c: Int): Int
extern
end.
diff --git a/source/cstdlib.elna b/source/cstdlib.elna
index 930246d..696e5dd 100644
--- a/source/cstdlib.elna
+++ b/source/cstdlib.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 malloc(size: Word) -> Pointer
+proc malloc(size: Word): Pointer
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
+proc atoi(str: ^Char): Int
extern
-proc exit(code: Int) -> !
+proc exit(code: Int): !
extern
end.
diff --git a/source/cstring.elna b/source/cstring.elna
index e19658f..ec5cd7b 100644
--- a/source/cstring.elna
+++ b/source/cstring.elna
@@ -2,25 +2,25 @@
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)
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
+proc strlen(ptr: ^Char): Word
extern
end.
diff --git a/source/lexer.elna b/source/lexer.elna
index b3250d0..9008139 100644
--- a/source/lexer.elna
+++ b/source/lexer.elna
@@ -67,7 +67,7 @@ type
start_location: TextLocation;
end_location: TextLocation
end
- TransitionAction = proc(^Lexer, ^LexerToken)
+ TransitionAction = proc(lexer: ^Lexer; token: ^LexerToken)
Transition = record
action: TransitionAction;
next_state: TransitionState
@@ -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
@@ -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
@@ -889,7 +889,7 @@ begin
end
(* Returns the last read token. *)
-proc lexer_current*(lexer: ^Lexer) -> LexerToken
+proc lexer_current*(lexer: ^Lexer): LexerToken
var
current_class: TransitionClass
current_state: TransitionState
@@ -921,7 +921,7 @@ begin
end
(* Read and return the next token. *)
-proc lexer_lex*(lexer: ^Lexer) -> LexerToken
+proc lexer_lex*(lexer: ^Lexer): LexerToken
var
result: LexerToken
begin
diff --git a/source/main.elna b/source/main.elna
index 468556d..aeaba2f 100644
--- a/source/main.elna
+++ b/source/main.elna
@@ -20,9 +20,9 @@ type
position: TextLocation;
input: Pointer;
- empty: proc(Pointer) -> Bool;
- advance: proc(Pointer);
- head: proc(Pointer) -> Char
+ empty: proc(stream: Pointer): Bool;
+ advance: proc(stream: Pointer);
+ head: proc(stream: Pointer): Char
end
Token* = record
kind: LexerKind;
@@ -41,19 +41,19 @@ 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
-proc string_dup(origin: String) -> String
+proc string_dup(origin: String): String
var
copy: ^Char
begin
@@ -63,7 +63,7 @@ begin
return String(copy, origin.length)
end
-proc string_buffer_new() -> StringBuffer
+proc string_buffer_new(): StringBuffer
var
result: StringBuffer
begin
@@ -89,7 +89,7 @@ begin
buffer^.size := buffer^.size - count
end
-proc string_buffer_clear(buffer: ^StringBuffer) -> String
+proc string_buffer_clear(buffer: ^StringBuffer): String
var
result: String
begin
@@ -102,7 +102,7 @@ end
Source code stream procedures.
*)
-proc read_source(filename: ^Char) -> ^SourceFile
+proc read_source(filename: ^Char): ^SourceFile
var
result: ^SourceFile
file_handle: ^FILE
@@ -118,7 +118,7 @@ begin
return result
end
-proc source_file_empty(source_input: Pointer) -> Bool
+proc source_file_empty(source_input: Pointer): Bool
var
source_file: ^SourceFile
begin
@@ -132,7 +132,7 @@ begin
return source_file^.size = 0u
end
-proc source_file_head(source_input: Pointer) -> Char
+proc source_file_head(source_input: Pointer): Char
var
source_file: ^SourceFile
begin
@@ -150,11 +150,11 @@ begin
source_file^.index := source_file^.index + 1u
end
-proc source_code_empty(source_code: ^SourceCode) -> Bool
+proc source_code_empty(source_code: ^SourceCode): Bool
return source_code^.empty(source_code^.input)
end
-proc source_code_head(source_code: SourceCode) -> Char
+proc source_code_head(source_code: SourceCode): Char
return source_code.head(source_code.input)
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
@@ -232,7 +232,7 @@ begin
end
(* Checker whether the character is allowed in an identificator. *)
-proc lexer_is_ident(char: Char) -> Bool
+proc lexer_is_ident(char: Char): Bool
return isalnum(cast(char: Int)) <> 0 or char = '_'
end
@@ -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
@@ -326,7 +326,7 @@ begin
end
(* Categorize an identifier. *)
-proc lexer_categorize(token_content: String) -> Token
+proc lexer_categorize(token_content: String): Token
var
current_token: Token
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
@@ -580,7 +580,7 @@ begin
end
(* Split the source text into tokens. *)
-proc lexer_text(source_code: SourceCode) -> Tokenizer
+proc lexer_text(source_code: SourceCode): Tokenizer
var
current_token: Token
token_buffer: StringBuffer
@@ -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/empty_proc_type_expression.elna b/testsuite/compilable/empty_proc_type_expression.elna
new file mode 100644
index 0000000..ad959f3
--- /dev/null
+++ b/testsuite/compilable/empty_proc_type_expression.elna
@@ -0,0 +1,2 @@
+type P = proc()
+end.
diff --git a/testsuite/runnable/aggregate_argument.elna b/testsuite/runnable/aggregate_argument.elna
index 2492a0b..b92e460 100644
--- a/testsuite/runnable/aggregate_argument.elna
+++ b/testsuite/runnable/aggregate_argument.elna
@@ -4,7 +4,7 @@ type
b: Int
end
-proc f(r: R) -> Int
+proc f(r: R): Int
var
result: Int
begin
diff --git a/testsuite/runnable/aggregate_equality.elna b/testsuite/runnable/aggregate_equality.elna
index 119efbd..9f9e8fc 100644
--- a/testsuite/runnable/aggregate_equality.elna
+++ b/testsuite/runnable/aggregate_equality.elna
@@ -4,7 +4,7 @@ type
b: Int
end
-proc f() -> Int
+proc f(): Int
var
result: Int
begin
diff --git a/testsuite/runnable/define_multiple_local_variables.elna b/testsuite/runnable/define_multiple_local_variables.elna
new file mode 100644
index 0000000..afae692
--- /dev/null
+++ b/testsuite/runnable/define_multiple_local_variables.elna
@@ -0,0 +1,16 @@
+proc f(): Int
+var
+ a, b: Int := 5
+ result: Int
+begin
+ if a = 5 & b = 5 then
+ result := 0
+ else
+ result := 1
+ end;
+ return result
+end
+
+return f()
+
+end.
diff --git a/testsuite/runnable/return_aggregate.elna b/testsuite/runnable/return_aggregate.elna
index 54d833d..fc37565 100644
--- a/testsuite/runnable/return_aggregate.elna
+++ b/testsuite/runnable/return_aggregate.elna
@@ -4,22 +4,12 @@ type
b: Int
end
-proc g() -> R
+proc f(): R
return R(1, 2)
end
-proc f() -> Int
-var
- result: Int
begin
- if g() = R(1, 2) then
- result := 0
- else
- result := 1
- end;
- return result
-end
-
-return f()
+ assert(f() = R(1, 2));
+ return 0
end.
diff --git a/testsuite/runnable/two_parameters_same_type.elna b/testsuite/runnable/two_parameters_same_type.elna
new file mode 100644
index 0000000..34e70eb
--- /dev/null
+++ b/testsuite/runnable/two_parameters_same_type.elna
@@ -0,0 +1,9 @@
+proc f(x, y: Int): Int
+ return x + y
+end
+
+begin
+ assert(f(2, 3) = 5);
+ return 0
+
+end.