Allow only one return statement
This commit is contained in:
		
							
								
								
									
										16
									
								
								boot/ast.cc
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								boot/ast.cc
									
									
									
									
									
								
							@@ -795,7 +795,7 @@ namespace elna::boot
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return_statement::return_statement(const struct position position, expression *return_expression)
 | 
			
		||||
        : node(position), return_expression(return_expression)
 | 
			
		||||
        : node(position), m_return_expression(return_expression)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -804,9 +804,14 @@ namespace elna::boot
 | 
			
		||||
        visitor->visit(this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    expression& return_statement::return_expression()
 | 
			
		||||
    {
 | 
			
		||||
        return *m_return_expression;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return_statement::~return_statement()
 | 
			
		||||
    {
 | 
			
		||||
        delete this->return_expression;
 | 
			
		||||
        delete m_return_expression;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    case_statement::case_statement(const struct position position,
 | 
			
		||||
@@ -914,13 +919,6 @@ namespace elna::boot
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    while_statement::while_statement(const struct position position, conditional_statements *body,
 | 
			
		||||
            std::vector<conditional_statements *>&& branches, const std::string& label,
 | 
			
		||||
            std::vector<statement *> *alternative)
 | 
			
		||||
        : node(position), m_body(body), branches(std::move(branches)), label(label), alternative(alternative)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void while_statement::accept(parser_visitor *visitor)
 | 
			
		||||
    {
 | 
			
		||||
        visitor->visit(this);
 | 
			
		||||
 
 | 
			
		||||
@@ -145,10 +145,9 @@ along with GCC; see the file COPYING3.  If not see
 | 
			
		||||
%type <std::vector<elna::boot::expression *>> expressions actual_parameter_list;
 | 
			
		||||
%type <elna::boot::designator_expression *> designator_expression;
 | 
			
		||||
%type <elna::boot::procedure_call*> call_expression;
 | 
			
		||||
%type <elna::boot::while_statement *> while_statement;
 | 
			
		||||
%type <elna::boot::return_statement *> return_statement;
 | 
			
		||||
%type <elna::boot::statement *> statement;
 | 
			
		||||
%type <std::vector<elna::boot::statement *>> statements;
 | 
			
		||||
%type <std::vector<elna::boot::statement *>> required_statements optional_statements statement_part;
 | 
			
		||||
%type <elna::boot::procedure_definition *> procedure_definition;
 | 
			
		||||
%type <std::pair<std::vector<std::string>, elna::boot::procedure_type_expression *>> procedure_heading;
 | 
			
		||||
%type <elna::boot::procedure_type_expression::return_t> return_declaration;
 | 
			
		||||
@@ -158,7 +157,7 @@ along with GCC; see the file COPYING3.  If not see
 | 
			
		||||
%type <std::unique_ptr<elna::boot::block>> block;
 | 
			
		||||
%type <elna::boot::field_declaration> field_declaration formal_parameter;
 | 
			
		||||
%type <std::vector<std::pair<std::string, elna::boot::type_expression *>>>
 | 
			
		||||
    optional_fields required_fields formal_parameters;
 | 
			
		||||
    optional_fields required_fields 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;
 | 
			
		||||
@@ -168,7 +167,7 @@ along with GCC; see the file COPYING3.  If not see
 | 
			
		||||
%type <std::vector<elna::boot::import_declaration *>> import_declarations import_part;
 | 
			
		||||
%%
 | 
			
		||||
program:
 | 
			
		||||
    "program" import_part constant_part type_part variable_part procedure_part "begin" statements "end" "."
 | 
			
		||||
    "program" import_part constant_part type_part variable_part procedure_part "begin" optional_statements "end" "."
 | 
			
		||||
        {
 | 
			
		||||
            auto tree = new boot::program(boot::make_position(@7));
 | 
			
		||||
 | 
			
		||||
@@ -193,9 +192,18 @@ program:
 | 
			
		||||
 | 
			
		||||
            driver.tree.reset(tree);
 | 
			
		||||
        }
 | 
			
		||||
block: constant_part variable_part "begin" statements "end"
 | 
			
		||||
block: constant_part variable_part statement_part "end"
 | 
			
		||||
        {
 | 
			
		||||
            $$ = std::make_unique<boot::block>(std::move($1), std::move($2), std::move($4));
 | 
			
		||||
            $$ = std::make_unique<boot::block>(std::move($1), std::move($2), std::move($3));
 | 
			
		||||
        }
 | 
			
		||||
statement_part:
 | 
			
		||||
    /* no statements */ {}
 | 
			
		||||
    | "begin" required_statements { std::swap($$, $2); }
 | 
			
		||||
    | return_statement { $$.push_back($1); }
 | 
			
		||||
    | "begin" required_statements ";" return_statement
 | 
			
		||||
        {
 | 
			
		||||
            std::swap($$, $2);
 | 
			
		||||
            $$.push_back($4);
 | 
			
		||||
        }
 | 
			
		||||
identifier_definition:
 | 
			
		||||
    IDENTIFIER "*" { $$ = boot::identifier_definition{ $1, true }; }
 | 
			
		||||
@@ -211,11 +219,10 @@ return_declaration:
 | 
			
		||||
    /* proper procedure */ {}
 | 
			
		||||
    | "->" "!" { $$ = boot::procedure_type_expression::return_t(std::monostate{}); }
 | 
			
		||||
    | "->" type_expression { $$ = boot::procedure_type_expression::return_t($2); }
 | 
			
		||||
procedure_heading:
 | 
			
		||||
    "(" formal_parameters ")" return_declaration
 | 
			
		||||
procedure_heading: formal_parameter_list return_declaration
 | 
			
		||||
        {
 | 
			
		||||
            $$.second = new boot::procedure_type_expression(boot::make_position(@1), std::move($4));
 | 
			
		||||
            for (auto& [name, type] : $2)
 | 
			
		||||
            $$.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);
 | 
			
		||||
@@ -250,7 +257,7 @@ call_expression: designator_expression actual_parameter_list
 | 
			
		||||
cast_expression: "cast" "(" expression ":" type_expression ")"
 | 
			
		||||
        { $$ = new boot::cast_expression(boot::make_position(@1), $5, $3); }
 | 
			
		||||
elsif_do_statements:
 | 
			
		||||
    "elsif" expression "do" statements elsif_do_statements
 | 
			
		||||
    "elsif" expression "do" optional_statements elsif_do_statements
 | 
			
		||||
        {
 | 
			
		||||
            boot::conditional_statements *branch = new boot::conditional_statements($2, std::move($4));
 | 
			
		||||
            std::swap($5, $$);
 | 
			
		||||
@@ -258,36 +265,18 @@ elsif_do_statements:
 | 
			
		||||
        }
 | 
			
		||||
    | {}
 | 
			
		||||
else_statements:
 | 
			
		||||
    "else" statements { $$ = new std::vector<boot::statement *>(std::move($2)); }
 | 
			
		||||
    "else" optional_statements { $$ = new std::vector<boot::statement *>(std::move($2)); }
 | 
			
		||||
    | { $$ = nullptr; }
 | 
			
		||||
while_statement:
 | 
			
		||||
    "while" expression "do" statements elsif_do_statements else_statements "end"
 | 
			
		||||
        {
 | 
			
		||||
            boot::conditional_statements *body = new boot::conditional_statements($2, std::move($4));
 | 
			
		||||
            $$ = new boot::while_statement(boot::make_position(@1), body, std::move($5), $6);
 | 
			
		||||
        }
 | 
			
		||||
    | "while" expression "," IDENTIFIER "do" statements elsif_do_statements else_statements "end"
 | 
			
		||||
        {
 | 
			
		||||
            boot::conditional_statements *body = new boot::conditional_statements($2, std::move($6));
 | 
			
		||||
            $$ = new boot::while_statement(boot::make_position(@1), body, std::move($7), $4, $8);
 | 
			
		||||
        }
 | 
			
		||||
elsif_then_statements:
 | 
			
		||||
    "elsif" expression "then" statements elsif_then_statements
 | 
			
		||||
    "elsif" expression "then" optional_statements elsif_then_statements
 | 
			
		||||
        {
 | 
			
		||||
            boot::conditional_statements *branch = new boot::conditional_statements($2, std::move($4));
 | 
			
		||||
            std::swap($5, $$);
 | 
			
		||||
            $$.emplace($$.begin(), branch);
 | 
			
		||||
        }
 | 
			
		||||
    | {}
 | 
			
		||||
return_statement:
 | 
			
		||||
    "return" expression
 | 
			
		||||
        {
 | 
			
		||||
            $$ = new boot::return_statement(boot::make_position(@1), $2);
 | 
			
		||||
        }
 | 
			
		||||
    | "return"
 | 
			
		||||
        {
 | 
			
		||||
            $$ = new boot::return_statement(boot::make_position(@1));
 | 
			
		||||
        }
 | 
			
		||||
return_statement: "return" expression
 | 
			
		||||
        { $$ = new boot::return_statement(boot::make_position(@1), $2); }
 | 
			
		||||
literal:
 | 
			
		||||
    INTEGER { $$ = new boot::literal<std::int32_t>(boot::make_position(@1), $1); }
 | 
			
		||||
    | WORD { $$ = new boot::literal<std::uint32_t>(boot::make_position(@1), $1); }
 | 
			
		||||
@@ -421,18 +410,23 @@ designator_expression:
 | 
			
		||||
statement:
 | 
			
		||||
    designator_expression ":=" expression
 | 
			
		||||
        { $$ = new boot::assign_statement(boot::make_position(@1), $1, $3); }
 | 
			
		||||
    | while_statement { $$ = $1; }
 | 
			
		||||
    | "if" expression "then" statements elsif_then_statements else_statements "end"
 | 
			
		||||
    | "while" expression "do" optional_statements elsif_do_statements else_statements "end"
 | 
			
		||||
        {
 | 
			
		||||
            boot::conditional_statements *body = new boot::conditional_statements($2, std::move($4));
 | 
			
		||||
            $$ = new boot::while_statement(boot::make_position(@1), body, std::move($5), $6);
 | 
			
		||||
        }
 | 
			
		||||
    | "if" expression "then" optional_statements elsif_then_statements else_statements "end"
 | 
			
		||||
        {
 | 
			
		||||
            boot::conditional_statements *then = new boot::conditional_statements($2, std::move($4));
 | 
			
		||||
            $$ = new boot::if_statement(boot::make_position(@1), then, std::move($5), $6);
 | 
			
		||||
        }
 | 
			
		||||
    | return_statement { $$ = $1; }
 | 
			
		||||
    | call_expression { $$ = $1; }
 | 
			
		||||
    | "defer" statements "end" { $$ = new boot::defer_statement(boot::make_position(@1), std::move($2)); }
 | 
			
		||||
    | "defer" optional_statements "end"
 | 
			
		||||
        { $$ = new boot::defer_statement(boot::make_position(@1), std::move($2)); }
 | 
			
		||||
    | "case" expression "of" switch_cases else_statements "end"
 | 
			
		||||
        { $$ = new boot::case_statement(boot::make_position(@1), $2, std::move($4), $5); }
 | 
			
		||||
switch_case: case_labels ":" statements { $$ = { .labels = std::move($1), .statements = std::move($3) }; }
 | 
			
		||||
switch_case: case_labels ":" optional_statements
 | 
			
		||||
        { $$ = { .labels = std::move($1), .statements = std::move($3) }; }
 | 
			
		||||
switch_cases:
 | 
			
		||||
    switch_case "|" switch_cases
 | 
			
		||||
        {
 | 
			
		||||
@@ -447,13 +441,15 @@ case_labels:
 | 
			
		||||
            $$.emplace($$.cbegin(), $1);
 | 
			
		||||
        }
 | 
			
		||||
    | expression { $$.push_back($1); }
 | 
			
		||||
statements:
 | 
			
		||||
    statement ";" statements
 | 
			
		||||
required_statements:
 | 
			
		||||
    required_statements ";" statement
 | 
			
		||||
        {
 | 
			
		||||
            std::swap($$, $3);
 | 
			
		||||
            $$.insert($$.cbegin(), $1);
 | 
			
		||||
            std::swap($$, $1);
 | 
			
		||||
            $$.insert($$.cend(), $3);
 | 
			
		||||
        }
 | 
			
		||||
    | statement { $$.push_back($1); }
 | 
			
		||||
optional_statements:
 | 
			
		||||
    required_statements { std::swap($$, $1); }
 | 
			
		||||
    | /* no statements */ {}
 | 
			
		||||
field_declaration:
 | 
			
		||||
    IDENTIFIER ":" type_expression { $$ = std::make_pair($1, $3); }
 | 
			
		||||
@@ -578,9 +574,11 @@ type_part:
 | 
			
		||||
    | "type" type_definitions { std::swap($$, $2); }
 | 
			
		||||
formal_parameter:
 | 
			
		||||
    IDENTIFIER ":" type_expression { $$ = std::make_pair($1, $3); }
 | 
			
		||||
formal_parameter_list:
 | 
			
		||||
    "(" ")" {}
 | 
			
		||||
    | "(" formal_parameters ")" { std::swap($$, $2); }
 | 
			
		||||
formal_parameters:
 | 
			
		||||
    /* no formal parameters */ {}
 | 
			
		||||
    | formal_parameter "," formal_parameters
 | 
			
		||||
    formal_parameter "," formal_parameters
 | 
			
		||||
        {
 | 
			
		||||
            std::swap($$, $3);
 | 
			
		||||
            $$.emplace($$.cbegin(), std::move($1));
 | 
			
		||||
 
 | 
			
		||||
@@ -252,10 +252,7 @@ namespace elna::boot
 | 
			
		||||
 | 
			
		||||
    void declaration_visitor::visit(return_statement *statement)
 | 
			
		||||
    {
 | 
			
		||||
        if (statement->return_expression != nullptr)
 | 
			
		||||
        {
 | 
			
		||||
            statement->return_expression->accept(this);
 | 
			
		||||
        }
 | 
			
		||||
        statement->return_expression().accept(this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void declaration_visitor::visit(defer_statement *statement)
 | 
			
		||||
 
 | 
			
		||||
@@ -1297,13 +1297,12 @@ namespace elna::gcc
 | 
			
		||||
 | 
			
		||||
    void generic_visitor::visit(boot::while_statement *statement)
 | 
			
		||||
    {
 | 
			
		||||
        std::string loop_identifier = statement->label.value_or("while");
 | 
			
		||||
        location_t prerequisite_location = get_location(&statement->body().prerequisite().position());
 | 
			
		||||
        tree prerequisite_label_decl = build_label_decl(loop_identifier.c_str(), prerequisite_location);
 | 
			
		||||
        tree prerequisite_label_decl = build_label_decl("while_do", prerequisite_location);
 | 
			
		||||
        auto prerequisite_label_expr = build1_loc(prerequisite_location, LABEL_EXPR,
 | 
			
		||||
                void_type_node, prerequisite_label_decl);
 | 
			
		||||
        auto goto_check = build1(GOTO_EXPR, void_type_node, prerequisite_label_decl);
 | 
			
		||||
        tree branch_end_declaration = build_label_decl(loop_identifier.c_str(), UNKNOWN_LOCATION);
 | 
			
		||||
        tree branch_end_declaration = build_label_decl("while_end", UNKNOWN_LOCATION);
 | 
			
		||||
        tree branch_end_expression = build1_loc(UNKNOWN_LOCATION, LABEL_EXPR, void_type_node, branch_end_declaration);
 | 
			
		||||
 | 
			
		||||
        append_statement(prerequisite_label_expr);
 | 
			
		||||
@@ -1340,7 +1339,7 @@ namespace elna::gcc
 | 
			
		||||
 | 
			
		||||
    void generic_visitor::visit(boot::return_statement *statement)
 | 
			
		||||
    {
 | 
			
		||||
        boot::expression *return_expression = statement->return_expression;
 | 
			
		||||
        boot::expression *return_expression = &statement->return_expression();
 | 
			
		||||
        location_t statement_position = get_location(&statement->position());
 | 
			
		||||
        tree set_result{ NULL_TREE };
 | 
			
		||||
        tree return_type = TREE_TYPE(TREE_TYPE(current_function_decl));
 | 
			
		||||
 
 | 
			
		||||
@@ -466,11 +466,13 @@ namespace elna::boot
 | 
			
		||||
    class return_statement : public statement
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
        expression *const return_expression{ nullptr };
 | 
			
		||||
        expression *m_return_expression;
 | 
			
		||||
 | 
			
		||||
        return_statement(const struct position position, expression *return_expression = nullptr);
 | 
			
		||||
        return_statement(const struct position position, expression *return_expression);
 | 
			
		||||
        void accept(parser_visitor *visitor) override;
 | 
			
		||||
 | 
			
		||||
        expression& return_expression();
 | 
			
		||||
 | 
			
		||||
        virtual ~return_statement() override;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
@@ -653,14 +655,10 @@ namespace elna::boot
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
        const std::vector<conditional_statements *> branches;
 | 
			
		||||
        const std::optional<std::string> label;
 | 
			
		||||
        const std::vector<statement *> *alternative;
 | 
			
		||||
 | 
			
		||||
        while_statement(const struct position position, conditional_statements *body,
 | 
			
		||||
                std::vector<conditional_statements *>&& branches, std::vector<statement *> *alternative = nullptr);
 | 
			
		||||
        while_statement(const struct position position, conditional_statements *body,
 | 
			
		||||
                std::vector<conditional_statements *>&& branches, const std::string& label,
 | 
			
		||||
                std::vector<statement *> *alternative = nullptr);
 | 
			
		||||
        void accept(parser_visitor *visitor) override;
 | 
			
		||||
 | 
			
		||||
        conditional_statements& body();
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										36
									
								
								source.elna
									
									
									
									
									
								
							
							
						
						
									
										36
									
								
								source.elna
									
									
									
									
									
								
							@@ -154,7 +154,6 @@ proc exit(code: Int) -> !; extern
 | 
			
		||||
*)
 | 
			
		||||
 | 
			
		||||
proc reallocarray(ptr: ^Byte, n: Word, size: Word) -> ^Byte;
 | 
			
		||||
begin
 | 
			
		||||
  return realloc(ptr, n * size)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
@@ -212,32 +211,26 @@ begin
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
proc is_digit(c: Char) -> Bool;
 | 
			
		||||
begin
 | 
			
		||||
  return cast(c: Int) >= cast('0': Int) & cast(c: Int) <= cast('9': Int)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
proc is_alpha(c: Char) -> Bool;
 | 
			
		||||
begin
 | 
			
		||||
  return cast(c: Int) >= cast('A': Int) & cast(c: Int) <= cast('z': Int)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
proc is_alnum(c: Char) -> Bool;
 | 
			
		||||
begin
 | 
			
		||||
  return is_digit(c) or is_alpha(c)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
proc is_space(c: Char) -> Bool;
 | 
			
		||||
begin
 | 
			
		||||
  return c = ' ' or c = '\n' or c = '\t'
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
proc substring(string: String, start: Word, count: Word) -> String;
 | 
			
		||||
begin
 | 
			
		||||
  return String(string.ptr + start, count)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
proc open_substring(string: String, start: Word) -> String;
 | 
			
		||||
begin
 | 
			
		||||
  return substring(string, start, string.length - start)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
@@ -339,12 +332,10 @@ begin
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
proc source_code_empty(source_code: ^SourceCode) -> Bool;
 | 
			
		||||
begin
 | 
			
		||||
  return source_code^.empty(source_code^.input)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
proc source_code_head(source_code: SourceCode) -> Char;
 | 
			
		||||
begin
 | 
			
		||||
  return source_code.head(source_code.input)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
@@ -361,7 +352,6 @@ begin
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
proc source_code_expect(source_code: ^SourceCode, expected: Char) -> Bool;
 | 
			
		||||
begin
 | 
			
		||||
  return ~source_code_empty(source_code) & source_code_head(source_code^) = expected
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
@@ -375,7 +365,7 @@ var
 | 
			
		||||
begin
 | 
			
		||||
  if escape = 'n' then
 | 
			
		||||
	result^ := '\n';
 | 
			
		||||
	successful := true;
 | 
			
		||||
	successful := true
 | 
			
		||||
  elsif escape = 'a' then
 | 
			
		||||
	result^ := '\a';
 | 
			
		||||
	successful := true
 | 
			
		||||
@@ -419,12 +409,10 @@ proc skip_spaces(source_code: ^SourceCode);
 | 
			
		||||
var
 | 
			
		||||
  current: Char
 | 
			
		||||
begin
 | 
			
		||||
  while ~source_code_empty(source_code) do
 | 
			
		||||
  while ~source_code_empty(source_code) & is_space(source_code_head(source_code^)) do
 | 
			
		||||
    current := source_code_head(source_code^);
 | 
			
		||||
 | 
			
		||||
    if ~is_space(current) then
 | 
			
		||||
      return
 | 
			
		||||
    elsif current = '\n' then
 | 
			
		||||
    if current = '\n' then
 | 
			
		||||
      source_code_break(source_code)
 | 
			
		||||
	end;
 | 
			
		||||
	source_code_advance(source_code)
 | 
			
		||||
@@ -432,7 +420,6 @@ begin
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
proc is_ident(char: Char) -> Bool;
 | 
			
		||||
begin
 | 
			
		||||
  return is_alnum(char) or char = '_'
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
@@ -681,7 +668,7 @@ begin
 | 
			
		||||
	end;
 | 
			
		||||
	write_c(' ');
 | 
			
		||||
 | 
			
		||||
	i := i + 1u;
 | 
			
		||||
	i := i + 1u
 | 
			
		||||
  end;
 | 
			
		||||
  write_c('\n')
 | 
			
		||||
end
 | 
			
		||||
@@ -962,7 +949,7 @@ begin
 | 
			
		||||
  result^.parse := false;
 | 
			
		||||
  result^.input := nil;
 | 
			
		||||
 | 
			
		||||
  while i < argc do
 | 
			
		||||
  while i < argc & result <> nil do
 | 
			
		||||
    parameter := argv + i;
 | 
			
		||||
 | 
			
		||||
    if strcmp(parameter^, "--lex\0".ptr) = 0 then
 | 
			
		||||
@@ -972,23 +959,24 @@ begin
 | 
			
		||||
    elsif parameter^^ <> '-' then
 | 
			
		||||
	  if result^.input <> nil then
 | 
			
		||||
		write_s("Fatal error: Only one source file can be given.\n");
 | 
			
		||||
		return nil
 | 
			
		||||
	  end;
 | 
			
		||||
      result^.input := parameter^
 | 
			
		||||
		result := nil
 | 
			
		||||
	  else
 | 
			
		||||
        result^.input := parameter^
 | 
			
		||||
	  end
 | 
			
		||||
    else
 | 
			
		||||
      write_s("Fatal error: Unknown command line options: ");
 | 
			
		||||
 | 
			
		||||
      write_z(parameter^);
 | 
			
		||||
      write_s(".\n");
 | 
			
		||||
 | 
			
		||||
      return nil
 | 
			
		||||
      result := nil
 | 
			
		||||
    end;
 | 
			
		||||
 | 
			
		||||
    i := i + 1
 | 
			
		||||
  end;
 | 
			
		||||
  if result^.input = nil then
 | 
			
		||||
  if result <> nil & result^.input = nil then
 | 
			
		||||
    write_s("Fatal error: no input files.\n");
 | 
			
		||||
	return nil
 | 
			
		||||
	result := nil
 | 
			
		||||
  end;
 | 
			
		||||
 | 
			
		||||
  return result
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user