Read the input filename from the command line
This commit is contained in:
		
							
								
								
									
										27
									
								
								boot/ast.cc
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								boot/ast.cc
									
									
									
									
									
								
							| @@ -92,9 +92,13 @@ namespace boot | ||||
|  | ||||
|     void empty_visitor::visit(block *block) | ||||
|     { | ||||
|         for (const auto definition : block->value_definitions) | ||||
|         for (const auto constant : block->constants) | ||||
|         { | ||||
|             definition->accept(this); | ||||
|             constant->accept(this); | ||||
|         } | ||||
|         for (const auto variable : block->variables) | ||||
|         { | ||||
|             variable->accept(this); | ||||
|         } | ||||
|         for (const auto body_statement : block->body) | ||||
|         { | ||||
| @@ -474,9 +478,8 @@ namespace boot | ||||
|         delete m_body; | ||||
|     } | ||||
|  | ||||
|     block::block(const struct position position, std::vector<definition *>&& value_definitions, | ||||
|             std::vector<statement *>&& body) | ||||
|         : node(position), value_definitions(std::move(value_definitions)), body(std::move(body)) | ||||
|     block::block(const struct position position) | ||||
|         : node(position) | ||||
|     { | ||||
|     } | ||||
|  | ||||
| @@ -487,9 +490,13 @@ namespace boot | ||||
|  | ||||
|     block::~block() | ||||
|     { | ||||
|         for (auto definition : this->value_definitions) | ||||
|         for (auto variable : this->variables) | ||||
|         { | ||||
|             delete definition; | ||||
|             delete variable; | ||||
|         } | ||||
|         for (auto constant : this->constants) | ||||
|         { | ||||
|             delete constant; | ||||
|         } | ||||
|         for (auto body_statement : this->body) | ||||
|         { | ||||
| @@ -497,10 +504,8 @@ namespace boot | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     program::program(const struct position position, | ||||
|             std::vector<definition *>&& type_definitions, | ||||
|             std::vector<definition *>&& value_definitions, std::vector<statement *>&& body) | ||||
|         : block(position, std::move(value_definitions), std::move(body)), | ||||
|     program::program(const struct position position, std::vector<definition *>&& type_definitions) | ||||
|         : block(position), | ||||
|         type_definitions(std::move(type_definitions)) | ||||
|     { | ||||
|     } | ||||
|   | ||||
| @@ -111,49 +111,34 @@ | ||||
| %type <elna::boot::cast_expression *> cast_expression; | ||||
| %% | ||||
| program: | ||||
|     type_part constant_part procedure_part variable_part BEGIN_BLOCK optional_statements END_BLOCK DOT | ||||
|     type_part constant_part variable_part procedure_part BEGIN_BLOCK optional_statements END_BLOCK DOT | ||||
|         { | ||||
|             std::vector<elna::boot::definition *> definitions($1.size() + $3.size()); | ||||
|             std::vector<elna::boot::definition *> definitions($1.size() + $4.size()); | ||||
|             std::vector<elna::boot::definition *>::iterator definition = definitions.begin(); | ||||
|             std::vector<elna::boot::definition *> value_definitions($2.size() + $4.size()); | ||||
|             std::vector<elna::boot::definition *>::iterator value_definition = value_definitions.begin(); | ||||
|  | ||||
|             for (auto type : $1) | ||||
|             { | ||||
|                 *definition++ = type; | ||||
|             } | ||||
|             for (auto constant : $2) | ||||
|             { | ||||
|                 *value_definition++ = constant; | ||||
|             } | ||||
|             for (auto procedure : $3) | ||||
|             for (auto procedure : $4) | ||||
|             { | ||||
|                 *definition++ = procedure; | ||||
|             } | ||||
|             for (auto variable : $4) | ||||
|             { | ||||
|                 *value_definition++ = variable; | ||||
|             } | ||||
|             auto tree = new elna::boot::program(elna::boot::make_position(@5), | ||||
|                  std::move(definitions), std::move(value_definitions), std::move($6)); | ||||
|             auto tree = new elna::boot::program(elna::boot::make_position(@5), std::move(definitions)); | ||||
|  | ||||
|             std::swap(tree->constants, $2); | ||||
|             std::swap(tree->variables, $3); | ||||
|             std::swap(tree->body, $6); | ||||
|  | ||||
|             driver.tree.reset(tree); | ||||
|         } | ||||
| block: constant_part variable_part BEGIN_BLOCK optional_statements END_BLOCK | ||||
|         { | ||||
|             std::vector<elna::boot::definition *> definitions($1.size() + $2.size()); | ||||
|             std::vector<elna::boot::definition *>::iterator definition = definitions.begin(); | ||||
|             $$ = new elna::boot::block(elna::boot::make_position(@3)); | ||||
|  | ||||
|             for (auto constant : $1) | ||||
|             { | ||||
|                 *definition++ = constant; | ||||
|             } | ||||
|             for (auto variable : $2) | ||||
|             { | ||||
|                 *definition++ = variable; | ||||
|             } | ||||
|             $$ = new elna::boot::block(elna::boot::make_position(@3), | ||||
|                  std::move(definitions), std::move($4)); | ||||
|             std::swap($$->constants, $1); | ||||
|             std::swap($$->variables, $2); | ||||
|             std::swap($$->body, $4); | ||||
|         } | ||||
| procedure_definition: | ||||
|     PROCEDURE IDENTIFIER formal_parameter_list SEMICOLON block SEMICOLON | ||||
|   | ||||
| @@ -36,10 +36,6 @@ namespace gcc | ||||
|         { | ||||
|             return "Char"; | ||||
|         } | ||||
|         else if (is_string_type(type)) | ||||
|         { | ||||
|             return "String"; | ||||
|         } | ||||
|         else if (is_pointer_type(type)) | ||||
|         { | ||||
|             return "pointer"; | ||||
|   | ||||
| @@ -86,16 +86,44 @@ namespace gcc | ||||
|             || type == this->symbol_map->lookup("Word")->payload; | ||||
|     } | ||||
|  | ||||
|     bool generic_visitor::is_numeric_type(tree type) | ||||
|     { | ||||
|         return is_integral_type(type) | ||||
|             || type == this->symbol_map->lookup("Float")->payload; | ||||
|     } | ||||
|  | ||||
|     void generic_visitor::visit(boot::program *program) | ||||
|     { | ||||
|         for (const auto definition : program->value_definitions) | ||||
|         for (const auto& type_definition : program->type_definitions) | ||||
|         { | ||||
|             definition->accept(this); | ||||
|             type_definition->accept(this); | ||||
|         } | ||||
|         for (const auto& constant : program->type_definitions) | ||||
|         for (const auto constant : program->constants) | ||||
|         { | ||||
|             constant->accept(this); | ||||
|         } | ||||
|         for (const auto declaration : program->variables) | ||||
|         { | ||||
|             tree declaration_type = build_type(declaration->type()); | ||||
|             gcc_assert(declaration_type != NULL_TREE); | ||||
|  | ||||
|             auto declaration_location = get_location(&declaration->position()); | ||||
|             tree declaration_tree = build_decl(declaration_location, VAR_DECL, | ||||
|                     get_identifier(declaration->identifier().c_str()), declaration_type); | ||||
|             auto result = this->symbol_map->enter(declaration->identifier(), boot::make_info(declaration_tree)); | ||||
|  | ||||
|             if (result) | ||||
|             { | ||||
|                 TREE_STATIC(declaration_tree) = 1; | ||||
|                 varpool_node::get_create(declaration_tree); | ||||
|                 varpool_node::finalize_decl(declaration_tree); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 error_at(declaration_location, "variable '%s' already declared in this scope", | ||||
|                         declaration->identifier().c_str()); | ||||
|             } | ||||
|         } | ||||
|         std::array<tree, 2> parameter_types{ | ||||
|             integer_type_node, | ||||
|             build_pointer_type(build_pointer_type(char_type_node)) | ||||
| @@ -278,49 +306,57 @@ namespace gcc | ||||
|         this->current_expression = build_string_literal(string->string().size() + 1, string->string().c_str()); | ||||
|     } | ||||
|  | ||||
|     void generic_visitor::build_binary_operation(bool condition, boot::binary_expression *expression, | ||||
|             tree_code operator_code, tree left, tree right, tree target_type) | ||||
|     tree generic_visitor::build_arithmetic_operation(boot::binary_expression *expression, | ||||
|             tree_code operator_code, tree left, tree right) | ||||
|     { | ||||
|         auto expression_location = get_location(&expression->position()); | ||||
|         auto left_type = TREE_TYPE(left); | ||||
|         auto right_type = TREE_TYPE(right); | ||||
|         return build_binary_operation(is_numeric_type(TREE_TYPE(left)), | ||||
|                 expression, operator_code, left, right, TREE_TYPE(left)); | ||||
|     } | ||||
|  | ||||
|         if (condition) | ||||
|         { | ||||
|             this->current_expression = build2_loc(expression_location, | ||||
|                     operator_code, target_type, left, right); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             error_at(expression_location, | ||||
|                     "invalid operands of type %s and %s for operator %s", | ||||
|                     print_type(left_type), print_type(right_type), | ||||
|                     elna::boot::print_binary_operator(expression->operation())); | ||||
|             this->current_expression = error_mark_node; | ||||
|         } | ||||
|     tree generic_visitor::build_comparison_operation(boot::binary_expression *expression, | ||||
|             tree_code operator_code, tree left, tree right) | ||||
|     { | ||||
|         return build_binary_operation(is_numeric_type(TREE_TYPE(left)) || is_pointer_type(TREE_TYPE(left)), | ||||
|                 expression, operator_code, left, right, this->symbol_map->lookup("Bool")->payload); | ||||
|     } | ||||
|  | ||||
|     tree generic_visitor::build_logic_operation(boot::binary_expression *expression, | ||||
|             tree_code operator_code, tree left, tree right) | ||||
|     { | ||||
|         auto symbol = this->symbol_map->lookup("Bool"); | ||||
|  | ||||
|         return build_binary_operation(TREE_TYPE(left) == symbol->payload, | ||||
|                 expression, operator_code, left, right, symbol->payload); | ||||
|     } | ||||
|  | ||||
|     tree generic_visitor::build_equality_operation(boot::binary_expression *expression, | ||||
|             tree_code operator_code, tree left, tree right) | ||||
|     { | ||||
|         return build_binary_operation(true, expression, | ||||
|                 operator_code, left, right, this->symbol_map->lookup("Bool")->payload); | ||||
|     } | ||||
|  | ||||
|     void generic_visitor::visit(boot::binary_expression *expression) | ||||
|     { | ||||
|         expression->lhs().accept(this); | ||||
|         auto left = this->current_expression; | ||||
|         auto left_type = TREE_TYPE(left); | ||||
|         tree left = this->current_expression; | ||||
|         tree left_type = TREE_TYPE(left); | ||||
|  | ||||
|         expression->rhs().accept(this); | ||||
|         auto right = this->current_expression; | ||||
|         auto right_type = TREE_TYPE(right); | ||||
|         tree right = this->current_expression; | ||||
|         tree right_type = TREE_TYPE(right); | ||||
|  | ||||
|         auto expression_location = get_location(&expression->position()); | ||||
|         tree_code operator_code = ERROR_MARK; | ||||
|         tree target_type = error_mark_node; | ||||
|         location_t expression_location = get_location(&expression->position()); | ||||
|  | ||||
|         if (is_pointer_type(left_type) && is_integral_type(right_type) | ||||
|                 && expression->operation() == boot::binary_operator::sum) | ||||
|         if (is_pointer_type(left_type) && is_integral_type(right_type)) | ||||
|         { | ||||
|             tree convert_expression = build1_loc(expression_location, CONVERT_EXPR, | ||||
|                     sizetype, right); | ||||
|             this->current_expression = build2_loc(expression_location, | ||||
|                     POINTER_PLUS_EXPR, left_type, left, convert_expression); | ||||
|             this->current_expression = do_pointer_arithmetic(expression->operation(), left, right); | ||||
|             if (this->current_expression == error_mark_node) | ||||
|             { | ||||
|                 error_at(expression_location, | ||||
|                         "invalid operation %s on a pointer and an integral type", | ||||
|                         boot::print_binary_operator(expression->operation())); | ||||
|             } | ||||
|             return; | ||||
|         } | ||||
|         if (left_type != right_type) | ||||
| @@ -335,87 +371,45 @@ namespace gcc | ||||
|         switch (expression->operation()) | ||||
|         { | ||||
|             case boot::binary_operator::sum: | ||||
|                 operator_code = PLUS_EXPR; | ||||
|                 target_type = left_type; | ||||
|                 this->current_expression = build_arithmetic_operation(expression, PLUS_EXPR, left, right); | ||||
|                 break; | ||||
|             case boot::binary_operator::subtraction: | ||||
|                 operator_code = MINUS_EXPR; | ||||
|                 target_type = left_type; | ||||
|                 this->current_expression = build_arithmetic_operation(expression, MINUS_EXPR, left, right); | ||||
|                 break; | ||||
|             case boot::binary_operator::division: | ||||
|                 operator_code = TRUNC_DIV_EXPR; | ||||
|                 target_type = left_type; | ||||
|                 this->current_expression = build_arithmetic_operation(expression, TRUNC_DIV_EXPR, left, right); | ||||
|                 break; | ||||
|             case boot::binary_operator::remainder: | ||||
|                 operator_code = TRUNC_MOD_EXPR; | ||||
|                 target_type = left_type; | ||||
|                 this->current_expression = build_arithmetic_operation(expression, TRUNC_MOD_EXPR, left, right); | ||||
|                 break; | ||||
|             case boot::binary_operator::multiplication: | ||||
|                 operator_code = MULT_EXPR; | ||||
|                 target_type = left_type; | ||||
|                 this->current_expression = build_arithmetic_operation(expression, MULT_EXPR, left, right); | ||||
|                 break; | ||||
|             case boot::binary_operator::less: | ||||
|                 operator_code = LT_EXPR; | ||||
|                 target_type = boolean_type_node; | ||||
|                 this->current_expression = build_comparison_operation(expression, LT_EXPR, left, right); | ||||
|                 break; | ||||
|             case boot::binary_operator::greater: | ||||
|                 operator_code = GT_EXPR; | ||||
|                 target_type = boolean_type_node; | ||||
|                 this->current_expression = build_comparison_operation(expression, GT_EXPR, left, right); | ||||
|                 break; | ||||
|             case boot::binary_operator::less_equal: | ||||
|                 operator_code = LE_EXPR; | ||||
|                 target_type = boolean_type_node; | ||||
|                 this->current_expression = build_comparison_operation(expression, LE_EXPR, left, right); | ||||
|                 break; | ||||
|             case boot::binary_operator::greater_equal: | ||||
|                 operator_code = GE_EXPR; | ||||
|                 target_type = boolean_type_node; | ||||
|                 this->current_expression = build_comparison_operation(expression, GE_EXPR, left, right); | ||||
|                 break; | ||||
|             default: | ||||
|                 break; | ||||
|         } | ||||
|         if (operator_code != ERROR_MARK) // An arithmetic operation. | ||||
|         { | ||||
|             build_binary_operation(is_integral_type(left_type) || left_type == double_type_node, | ||||
|                     expression, operator_code, left, right, target_type); | ||||
|             return; | ||||
|         } | ||||
|         switch (expression->operation()) | ||||
|         { | ||||
|             case boot::binary_operator::conjunction: | ||||
|                 operator_code = TRUTH_ANDIF_EXPR; | ||||
|                 target_type = boolean_type_node; | ||||
|                 this->current_expression = build_logic_operation(expression, TRUTH_ANDIF_EXPR, left, right); | ||||
|                 break; | ||||
|             case boot::binary_operator::disjunction: | ||||
|                 operator_code = TRUTH_ORIF_EXPR; | ||||
|                 target_type = boolean_type_node; | ||||
|                 this->current_expression = build_logic_operation(expression, TRUTH_ORIF_EXPR, left, right); | ||||
|                 break; | ||||
|             default: | ||||
|                 break; | ||||
|         } | ||||
|         if (operator_code != ERROR_MARK) // A logical operation. | ||||
|         { | ||||
|             build_binary_operation(left_type == boolean_type_node, | ||||
|                     expression, operator_code, left, right, target_type); | ||||
|             return; | ||||
|         } | ||||
|         switch (expression->operation()) | ||||
|         { | ||||
|             case boot::binary_operator::equals: | ||||
|                 operator_code = EQ_EXPR; | ||||
|                 target_type = boolean_type_node; | ||||
|                 this->current_expression = build_equality_operation(expression, EQ_EXPR, left, right); | ||||
|                 break; | ||||
|             case boot::binary_operator::not_equals: | ||||
|                 operator_code = NE_EXPR; | ||||
|                 target_type = boolean_type_node; | ||||
|                 break; | ||||
|             default: | ||||
|                 this->current_expression = build_equality_operation(expression, NE_EXPR, left, right); | ||||
|                 break; | ||||
|         } | ||||
|         gcc_assert(operator_code != ERROR_MARK); | ||||
|         gcc_assert(target_type != error_mark_node); | ||||
|  | ||||
|         this->current_expression = build2_loc(expression_location, | ||||
|                 operator_code, target_type, left, right); | ||||
|     } | ||||
|  | ||||
|     void generic_visitor::visit(boot::unary_expression *expression) | ||||
|   | ||||
| @@ -1,6 +1,9 @@ | ||||
| #include "elna/gcc/elna-tree.h" | ||||
| #include "elna/gcc/elna-diagnostic.h" | ||||
|  | ||||
| #include "stor-layout.h" | ||||
| #include "fold-const.h" | ||||
| #include "diagnostic-core.h" | ||||
|  | ||||
| tree elna_global_trees[ELNA_TI_MAX]; | ||||
|  | ||||
| @@ -20,12 +23,6 @@ namespace gcc | ||||
|         return TREE_CODE(type) == POINTER_TYPE; | ||||
|     } | ||||
|  | ||||
|     bool is_string_type(tree type) | ||||
|     { | ||||
|         return is_pointer_type(type) | ||||
|             && TYPE_MAIN_VARIANT(TREE_TYPE(type)) == char_type_node; | ||||
|     } | ||||
|  | ||||
|     tree tree_chain_base::head() | ||||
|     { | ||||
|         return first; | ||||
| @@ -81,5 +78,43 @@ namespace gcc | ||||
|  | ||||
|         return initial_table; | ||||
|     } | ||||
|  | ||||
|     tree do_pointer_arithmetic(boot::binary_operator binary_operator, tree left, tree right) | ||||
|     { | ||||
|         tree result = error_mark_node; | ||||
|         tree convert_expression = fold_convert(sizetype, right); | ||||
|  | ||||
|         if (binary_operator == boot::binary_operator::sum) | ||||
|         { | ||||
|             result = fold_build2(POINTER_PLUS_EXPR, TREE_TYPE(left), left, convert_expression); | ||||
|         } | ||||
|         else if (binary_operator == boot::binary_operator::subtraction) | ||||
|         { | ||||
|             convert_expression = fold_build1(NEGATE_EXPR, sizetype, convert_expression); | ||||
|             result = fold_build2(POINTER_PLUS_EXPR, TREE_TYPE(left), left, convert_expression); | ||||
|         } | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     tree build_binary_operation(bool condition, boot::binary_expression *expression, | ||||
|             tree_code operator_code, tree left, tree right, tree target_type) | ||||
|     { | ||||
|         location_t expression_location = get_location(&expression->position()); | ||||
|         tree left_type = TREE_TYPE(left); | ||||
|         tree right_type = TREE_TYPE(right); | ||||
|  | ||||
|         if (condition) | ||||
|         { | ||||
|             return build2_loc(expression_location, operator_code, target_type, left, right); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             error_at(expression_location, | ||||
|                     "invalid operands of type %s and %s for operator %s", | ||||
|                     print_type(left_type), print_type(right_type), | ||||
|                     elna::boot::print_binary_operator(expression->operation())); | ||||
|             return error_mark_node; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -637,11 +637,11 @@ namespace boot | ||||
|     class block : public node | ||||
|     { | ||||
|     public: | ||||
|         std::vector<definition *> value_definitions; | ||||
|         std::vector<variable_declaration *> variables; | ||||
|         std::vector<constant_definition *> constants; | ||||
|         std::vector<statement *> body; | ||||
|  | ||||
|         block(const struct position position, std::vector<definition *>&& value_definitions, | ||||
|                 std::vector<statement *>&& body); | ||||
|         block(const struct position position); | ||||
|         virtual void accept(parser_visitor *visitor) override; | ||||
|  | ||||
|         virtual ~block() override; | ||||
| @@ -652,8 +652,7 @@ namespace boot | ||||
|     public: | ||||
|         std::vector<definition *> type_definitions; | ||||
|  | ||||
|         program(const struct position position, std::vector<definition *>&& type_definitions, | ||||
|                 std::vector<definition *>&& value_definitions, std::vector<statement *>&& body); | ||||
|         program(const struct position position, std::vector<definition *>&& type_definitions); | ||||
|         virtual void accept(parser_visitor *visitor) override; | ||||
|  | ||||
|         virtual ~program() override; | ||||
|   | ||||
| @@ -31,12 +31,19 @@ namespace gcc | ||||
|         void enter_scope(); | ||||
|         tree_symbol_mapping leave_scope(); | ||||
|  | ||||
|         void build_binary_operation(bool condition, boot::binary_expression *expression, | ||||
|             tree_code operator_code, tree left, tree right, tree target_type); | ||||
|  | ||||
|         void make_if_branch(boot::conditional_statements& branch, tree goto_endif); | ||||
|  | ||||
|         bool is_integral_type(tree type); | ||||
|         bool is_numeric_type(tree type); | ||||
|  | ||||
|         tree build_arithmetic_operation(boot::binary_expression *expression, | ||||
|                 tree_code operator_code, tree left, tree right); | ||||
|         tree build_comparison_operation(boot::binary_expression *expression, | ||||
|                 tree_code operator_code, tree left, tree right); | ||||
|         tree build_logic_operation(boot::binary_expression *expression, | ||||
|                 tree_code operator_code, tree left, tree right); | ||||
|         tree build_equality_operation(boot::binary_expression *expression, | ||||
|                 tree_code operator_code, tree left, tree right); | ||||
|  | ||||
|     public: | ||||
|         generic_visitor(std::shared_ptr<boot::symbol_table<tree>> symbol_table); | ||||
|   | ||||
| @@ -4,8 +4,8 @@ | ||||
| #include "system.h" | ||||
| #include "coretypes.h" | ||||
| #include "tree.h" | ||||
| #include "tree.h" | ||||
|  | ||||
| #include "elna/boot/ast.h" | ||||
| #include "elna/boot/symbol.h" | ||||
|  | ||||
| enum elna_tree_index | ||||
| @@ -24,7 +24,6 @@ namespace gcc | ||||
| { | ||||
|     void init_ttree(); | ||||
|     bool is_pointer_type(tree type); | ||||
|     bool is_string_type(tree type); | ||||
|  | ||||
|     class tree_chain_base | ||||
|     { | ||||
| @@ -58,5 +57,11 @@ namespace gcc | ||||
|     }; | ||||
|  | ||||
|     std::shared_ptr<boot::symbol_table<tree>> builtin_symbol_table(); | ||||
|  | ||||
|     tree do_pointer_arithmetic(boot::binary_operator binary_operator, tree left, tree right); | ||||
|     tree build_binary_operation(bool condition, boot::binary_expression *expression, | ||||
|             tree_code operator_code, tree left, tree right, tree target_type); | ||||
|     tree build_arithmetic_operation(boot::binary_expression *expression, | ||||
|             tree_code operator_code, tree left, tree right); | ||||
| } | ||||
| } | ||||
|   | ||||
							
								
								
									
										75
									
								
								source.elna
									
									
									
									
									
								
							
							
						
						
									
										75
									
								
								source.elna
									
									
									
									
									
								
							| @@ -20,6 +20,9 @@ type | ||||
|   end, | ||||
|   FILE = record | ||||
|     dummy: Int | ||||
|   end, | ||||
|   CommandLine = record | ||||
|     input: pointer to Char | ||||
|   end; | ||||
|  | ||||
| const | ||||
| @@ -141,19 +144,6 @@ end; | ||||
|   End of standard procedures. | ||||
| *) | ||||
|  | ||||
| proc test_primitive(); | ||||
| begin | ||||
|   write_s("\nTest primitives:\n"); | ||||
|   write_u(25u); | ||||
|   write_c('\n'); | ||||
|  | ||||
|   write_i(8); | ||||
|   write_c('\n'); | ||||
|  | ||||
|   write_b(true); | ||||
|   write_c('\n') | ||||
| end; | ||||
|  | ||||
| proc read_source(filename: String): pointer to Char; | ||||
| var | ||||
|   input_file: pointer to FILE, | ||||
| @@ -272,7 +262,7 @@ var | ||||
|   is_valid: Bool; | ||||
| begin | ||||
|   token_end := input; | ||||
|   previous := cast(cast(input as Word) - 1u as pointer to Char); | ||||
|   previous := input - 1; | ||||
|  | ||||
|   while token_end^ <> '\0' and not (previous^ <> '\\' and token_end^ = '"') do | ||||
|     previous := token_end; | ||||
| @@ -286,7 +276,7 @@ begin | ||||
|  | ||||
|   is_valid := true; | ||||
|   constructed_string := current_token^.value.string_value; | ||||
|   while cast(input as Word) < cast(token_end as Word) and is_valid do | ||||
|   while input < token_end and is_valid do | ||||
|  | ||||
|     if input^ = '\\' then | ||||
|       input := input + 1; | ||||
| @@ -677,32 +667,51 @@ begin | ||||
|   return tokens | ||||
| end; | ||||
|  | ||||
| proc command_line(argc: Int, argv: pointer to pointer to Char); | ||||
| proc parse_command_line(argc: Int, argv: pointer to pointer to Char): pointer to CommandLine; | ||||
| var | ||||
|   parameter: pointer to pointer to Char, | ||||
|   i: Int; | ||||
|   i: Int, | ||||
|   result: pointer to CommandLine; | ||||
| begin | ||||
|   write_s("Argument count: "); | ||||
|   write_i(argc - 1); | ||||
|   write_s("\nArguments:"); | ||||
|   if argc < 2 then | ||||
|     write_s("Fatal error: no input files.\n"); | ||||
| 	return nil | ||||
|   end; | ||||
|   if argc > 2 then | ||||
|     write_s("Fatal error: Unknown command line options:"); | ||||
|  | ||||
|   i := 1; | ||||
|   while i < argc do | ||||
|     parameter := argv + i * cast(sizeof(pointer to Char) as Int); | ||||
|     i := 2; | ||||
|     while i < argc do | ||||
|       parameter := argv + i * cast(sizeof(pointer to Char) as Int); | ||||
|   | ||||
|       write_c(' '); | ||||
|       write_s(parameter^); | ||||
|       i := i + 1 | ||||
|     end; | ||||
| 	write_s(".\n"); | ||||
| 	return nil | ||||
|   end; | ||||
|  | ||||
| 	write_c(' '); | ||||
|     write_s(parameter^); | ||||
|     i := i + 1 | ||||
|   end | ||||
|   parameter := argv + cast(sizeof(pointer to Char) as Int); | ||||
|   result := cast(malloc(sizeof(CommandLine)) as pointer to CommandLine); | ||||
|   result^.input := parameter^; | ||||
|  | ||||
|   return result | ||||
| end; | ||||
|  | ||||
| proc compile(); | ||||
| proc process(argc: Int, argv: pointer to pointer to Char): Int; | ||||
| var | ||||
|   input: pointer to Char, | ||||
|   tokens: pointer to Token, | ||||
|   tokens_size: Word; | ||||
|   tokens_size: Word, | ||||
|   command_line: pointer to CommandLine; | ||||
| begin | ||||
|   input := read_source("example.elna"); | ||||
|   command_line := parse_command_line(argc, argv); | ||||
|  | ||||
|   if cast(command_line as Word) = 0u then | ||||
|     return 2 | ||||
|   end; | ||||
|   input := read_source(command_line^.input); | ||||
|   tokens := tokenize(input, @tokens_size); | ||||
|  | ||||
|   free(input); | ||||
| @@ -711,9 +720,5 @@ begin | ||||
| end; | ||||
|  | ||||
| begin | ||||
|   command_line(count, parameters); | ||||
|   compile(); | ||||
|   test_primitive(); | ||||
|  | ||||
|   exit(0) | ||||
|   exit(process(count, parameters)) | ||||
| end. | ||||
|   | ||||
		Reference in New Issue
	
	Block a user