diff options
| -rw-r--r-- | boot/ast.cc | 4 | ||||
| -rw-r--r-- | boot/evaluator.cc | 10 | ||||
| -rw-r--r-- | boot/lexer.ll | 2 | ||||
| -rw-r--r-- | boot/name_analysis.cc | 6 | ||||
| -rw-r--r-- | boot/parser.yy | 2 | ||||
| -rw-r--r-- | boot/symbol.cc | 22 | ||||
| -rw-r--r-- | boot/type_check.cc | 6 | ||||
| -rw-r--r-- | gcc/gcc/elna-builtins.cc | 6 | ||||
| -rw-r--r-- | gcc/gcc/elna-generic.cc | 4 | ||||
| -rw-r--r-- | gcc/gcc/elna-tree.cc | 15 | ||||
| -rw-r--r-- | include/elna/boot/ast.h | 8 | ||||
| -rw-r--r-- | include/elna/boot/dependency.h | 6 | ||||
| -rw-r--r-- | include/elna/boot/name_analysis.h | 2 | ||||
| -rw-r--r-- | include/elna/boot/result.h | 2 | ||||
| -rw-r--r-- | include/elna/boot/symbol.h | 5 | ||||
| -rw-r--r-- | include/elna/gcc/elna-generic.h | 2 | ||||
| -rw-r--r-- | source/command_line_interface.elna | 8 | ||||
| -rw-r--r-- | source/common.elna | 12 | ||||
| -rw-r--r-- | source/cstdio.elna | 12 | ||||
| -rw-r--r-- | source/cstdlib.elna | 2 | ||||
| -rw-r--r-- | source/cstring.elna | 12 | ||||
| -rw-r--r-- | source/lexer.elna | 42 | ||||
| -rw-r--r-- | source/main.elna | 44 | ||||
| -rw-r--r-- | testsuite/runnable/constant_string_initializer.elna | 2 | ||||
| -rw-r--r-- | testsuite/runnable/record_extension.elna | 2 | ||||
| -rw-r--r-- | testsuite/runnable/slice_cast.elna | 4 | ||||
| -rw-r--r-- | testsuite/runnable/unicode_escape_character.elna | 4 |
27 files changed, 137 insertions, 109 deletions
diff --git a/boot/ast.cc b/boot/ast.cc index fb1e276..9b21f56 100644 --- a/boot/ast.cc +++ b/boot/ast.cc @@ -196,7 +196,7 @@ namespace elna::boot __builtin_unreachable(); } - void empty_visitor::visit(literal<unsigned char> *) + void empty_visitor::visit(literal<std::uint32_t> *) { __builtin_unreachable(); } @@ -517,7 +517,7 @@ namespace elna::boot { } - void walking_visitor::visit(literal<unsigned char> *) + void walking_visitor::visit(literal<std::uint32_t> *) { } diff --git a/boot/evaluator.cc b/boot/evaluator.cc index b37d1fa..d43ef11 100644 --- a/boot/evaluator.cc +++ b/boot/evaluator.cc @@ -245,7 +245,7 @@ namespace elna::boot { return constant_value{ boolean_subject->value }; } - else if (auto *character_subject = subject.is_a<unsigned char>()) + else if (auto *character_subject = subject.is_a<std::uint32_t>()) { return constant_value{ character_subject->value }; } @@ -686,7 +686,7 @@ namespace elna::boot } else if constexpr (std::is_same_v<T, double> || std::is_same_v<T, bool> - || std::is_same_v<T, unsigned char>) + || std::is_same_v<T, std::uint32_t>) { return integer_literal::from(static_cast<std::ptrdiff_t>(source_value)); } @@ -716,7 +716,7 @@ namespace elna::boot } else if constexpr (std::is_same_v<T, double> || std::is_same_v<T, bool> - || std::is_same_v<T, unsigned char>) + || std::is_same_v<T, std::uint32_t>) { return integer_literal::from(static_cast<std::size_t>(source_value)); } @@ -809,7 +809,7 @@ namespace elna::boot } if (is_primitive_type(resolved, "Char")) { - return constant_value{ static_cast<unsigned char>(0) }; + return constant_value{ static_cast<std::uint32_t>(0) }; } if (is_primitive_type(resolved, "Bool")) { @@ -851,7 +851,7 @@ namespace elna::boot } if (is_primitive_type(resolved, "Char")) { - return constant_value{ std::numeric_limits<unsigned char>::max() }; + return constant_value{ std::numeric_limits<std::uint32_t>::max() }; } if (is_primitive_type(resolved, "Bool")) { diff --git a/boot/lexer.ll b/boot/lexer.ll index c6d3b17..888c17d 100644 --- a/boot/lexer.ll +++ b/boot/lexer.ll @@ -359,7 +359,7 @@ to { } return yy::parser::make_WORD8(std::make_pair(result.value(), integer_sign::_unsigned), this->location); } -`([^'\\\n]|\\.|\\\n)+` { +`([^`\\\n]|\\.|\\\n)+` { std::optional<std::uint32_t> result = parse_character_literal(yytext); if (!result.has_value()) { diff --git a/boot/name_analysis.cc b/boot/name_analysis.cc index 0889ef9..4b69f9c 100644 --- a/boot/name_analysis.cc +++ b/boot/name_analysis.cc @@ -662,7 +662,7 @@ namespace elna::boot auto variable_type = lookup_primitive_type("Int"); this->bag.enter("count", std::make_shared<variable_info>(variable_type, false)); - variable_type = lookup_primitive_type("Char"); + variable_type = lookup_primitive_type("Word8"); variable_type = type(std::make_shared<pointer_type>(variable_type)); variable_type = type(std::make_shared<pointer_type>(variable_type)); this->bag.enter("parameters", std::make_shared<variable_info>(variable_type, false)); @@ -924,7 +924,7 @@ namespace elna::boot this->current_type = type(); } - void name_analysis_visitor::visit(literal<unsigned char> *literal) + void name_analysis_visitor::visit(literal<std::uint32_t> *literal) { literal->type_decoration = lookup_primitive_type("Char"); this->current_type = type(); @@ -939,7 +939,7 @@ namespace elna::boot void name_analysis_visitor::visit(literal<std::string> *literal) { literal->type_decoration = type(std::make_shared<slice_type>( - type(std::make_shared<constant_type>(lookup_primitive_type("Char"))))); + type(std::make_shared<constant_type>(lookup_primitive_type("Word8"))))); this->current_type = type(); } diff --git a/boot/parser.yy b/boot/parser.yy index 1b3005e..411922d 100644 --- a/boot/parser.yy +++ b/boot/parser.yy @@ -308,7 +308,7 @@ literal: } | CHARACTER { - $$ = new boot::literal<unsigned char>(boot::make_position(@$), $1, boot::integer_sign::_unsigned); + $$ = new boot::literal<std::uint32_t>(boot::make_position(@$), $1, boot::integer_sign::_unsigned); } | "nil" { diff --git a/boot/symbol.cc b/boot/symbol.cc index 9854acc..05eea31 100644 --- a/boot/symbol.cc +++ b/boot/symbol.cc @@ -284,7 +284,8 @@ namespace elna::boot static void builtin_integers(const std::shared_ptr<symbol_table>& symbols, const std::array<type_properties, target_integer_count>& properties, - const std::string& integer_name) + const std::string& integer_name, + std::vector<std::shared_ptr<alias_type>>& alias_owners) { for (std::size_t i = 1; i < properties.size(); ++i) { @@ -293,6 +294,16 @@ namespace elna::boot const type variant_type = type(std::make_shared<primitive_type>(type_name, properties[i])); symbols->enter(type_name, std::make_shared<type_info>(variant_type)); + + // The unsuffixed integer type is an alias of the fixed-size type + // matching the machine word. + if (bit_size == properties.front().size * CHAR_BIT) + { + auto alias = std::make_shared<alias_type>(integer_name, variant_type); + + alias_owners.push_back(alias); + symbols->enter(integer_name, std::make_shared<type_info>(type(alias))); + } } if (!symbols->contains(integer_name)) { @@ -302,12 +313,13 @@ namespace elna::boot } } - std::shared_ptr<symbol_table> builtin_symbol_table(const target_info& target) + std::shared_ptr<symbol_table> builtin_symbol_table(const target_info& target, + std::vector<std::shared_ptr<alias_type>>& alias_owners) { auto result = std::make_shared<symbol_table>(); - builtin_integers(result, target.int_properties, "Int"); - builtin_integers(result, target.word_properties, "Word"); + builtin_integers(result, target.int_properties, "Int", alias_owners); + builtin_integers(result, target.word_properties, "Word", alias_owners); result->enter("Char", std::make_shared<type_info>(type(std::make_shared<primitive_type>("Char", target.char_properties)))); @@ -494,7 +506,7 @@ namespace elna::boot { if (auto base = resolve_aliases(slice->base).get<constant_type>()) { - return is_primitive_type(resolve_aliases(base->unqualified), "Char"); + return is_primitive_type(resolve_aliases(base->unqualified), "Word8"); } } return false; diff --git a/boot/type_check.cc b/boot/type_check.cc index e58a50e..d830763 100644 --- a/boot/type_check.cc +++ b/boot/type_check.cc @@ -569,7 +569,8 @@ namespace elna::boot .right = case_label->type_decoration, .operation = binary_operator::equals }; - add_error<type_mismatch_error>(case_label->position(), condition_type, binary_error); + add_error<type_mismatch_error>(case_label->position(), + statement->condition().type_decoration, binary_error); } } } @@ -843,7 +844,8 @@ namespace elna::boot } else if (operation == unary_operator::minus) { - if (!is_primitive_type(resolved, "Int") + auto signed_primitive = resolved.get<primitive_type>(); + if ((signed_primitive == nullptr || !signed_primitive->identifier.starts_with("Int")) && !is_primitive_type(resolved, "Float")) { add_error<type_mismatch_error>(expression->position(), diff --git a/gcc/gcc/elna-builtins.cc b/gcc/gcc/elna-builtins.cc index 4f3db65..95ffb2f 100644 --- a/gcc/gcc/elna-builtins.cc +++ b/gcc/gcc/elna-builtins.cc @@ -66,7 +66,11 @@ namespace elna::gcc { elna_int_type_node = ptrdiff_type_node; elna_word_type_node = size_type_node; - elna_char_type_node = unsigned_char_type_node; + + constexpr int char_bit_size = 32; + elna_char_type_node = make_unsigned_type(char_bit_size); + TYPE_STRING_FLAG(elna_char_type_node) = 1; + elna_pointer_type_node = ptr_type_node; elna_float_type_node = double_type_node; diff --git a/gcc/gcc/elna-generic.cc b/gcc/gcc/elna-generic.cc index 5230196..323ec09 100644 --- a/gcc/gcc/elna-generic.cc +++ b/gcc/gcc/elna-generic.cc @@ -262,7 +262,7 @@ namespace elna::gcc { tree declaration_type = build_function_type_list(elna_int_type_node, elna_int_type_node, - build_pointer_type(build_pointer_type(elna_char_type_node)), + build_pointer_type(build_pointer_type(unsigned_intQI_type_node)), NULL_TREE); tree fndecl = build_fn_decl("main", declaration_type); @@ -510,7 +510,7 @@ namespace elna::gcc this->current_expression = constant_to_tree(boot::constant_value{ boolean->value }, this->symbols); } - void generic_visitor::visit(boot::literal<unsigned char> *character) + void generic_visitor::visit(boot::literal<std::uint32_t> *character) { this->current_expression = constant_to_tree(boot::constant_value{ character->value }, this->symbols); } diff --git a/gcc/gcc/elna-tree.cc b/gcc/gcc/elna-tree.cc index 255cf60..5284e42 100644 --- a/gcc/gcc/elna-tree.cc +++ b/gcc/gcc/elna-tree.cc @@ -288,9 +288,9 @@ namespace elna::gcc { return std::get<bool>(constant_value) ? boolean_true_node : boolean_false_node; } - else if (std::holds_alternative<unsigned char>(constant_value)) + else if (std::holds_alternative<std::uint32_t>(constant_value)) { - return build_int_cstu(elna_char_type_node, std::get<unsigned char>(constant_value)); + return build_int_cstu(elna_char_type_node, std::get<std::uint32_t>(constant_value)); } else if (std::holds_alternative<std::nullptr_t>(constant_value)) { @@ -300,7 +300,11 @@ namespace elna::gcc { const auto& string_value = std::get<std::string>(constant_value); tree index_constant = build_int_cstu(elna_word_type_node, string_value.size()); - tree char_array_type = build_array_type(elna_char_type_node, build_index_type(index_constant)); + + tree ptr_field = TYPE_FIELDS(type); + tree ptr_type = TREE_TYPE(ptr_field); + tree element_type = TYPE_MAIN_VARIANT(TREE_TYPE(ptr_type)); + tree char_array_type = build_array_type(element_type, build_index_type(index_constant)); tree string_literal = build_string(string_value.size(), string_value.c_str()); TREE_TYPE(string_literal) = char_array_type; @@ -308,10 +312,7 @@ namespace elna::gcc TREE_READONLY(string_literal) = 1; TREE_STATIC(string_literal) = 1; - tree ptr_field = TYPE_FIELDS(type); - - tree ptr_type = TREE_TYPE(ptr_field); - string_literal = build4(ARRAY_REF, elna_char_type_node, + string_literal = build4(ARRAY_REF, element_type, string_literal, integer_zero_node, NULL_TREE, NULL_TREE); string_literal = build1(ADDR_EXPR, ptr_type, string_literal); diff --git a/include/elna/boot/ast.h b/include/elna/boot/ast.h index 2645026..a05233c 100644 --- a/include/elna/boot/ast.h +++ b/include/elna/boot/ast.h @@ -91,7 +91,7 @@ namespace elna::boot }; template<> - struct literal_type_id<unsigned char> + struct literal_type_id<std::uint32_t> { static constexpr int value = 4; }; @@ -189,7 +189,7 @@ namespace elna::boot virtual void visit(literal<integer_literal> *) = 0; virtual void visit(literal<double> *) = 0; virtual void visit(literal<bool> *) = 0; - virtual void visit(literal<unsigned char> *) = 0; + virtual void visit(literal<std::uint32_t> *) = 0; virtual void visit(literal<std::nullptr_t> *) = 0; virtual void visit(literal<std::string> *) = 0; }; @@ -238,7 +238,7 @@ namespace elna::boot [[noreturn]] void visit(literal<integer_literal> *) override; [[noreturn]] void visit(literal<double> *) override; [[noreturn]] void visit(literal<bool> *) override; - [[noreturn]] void visit(literal<unsigned char> *) override; + [[noreturn]] void visit(literal<std::uint32_t> *) override; [[noreturn]] void visit(literal<std::nullptr_t> *) override; [[noreturn]] void visit(literal<std::string> *) override; }; @@ -285,7 +285,7 @@ namespace elna::boot void visit(literal<integer_literal> *) override; void visit(literal<double> *) override; void visit(literal<bool> *) override; - void visit(literal<unsigned char> *) override; + void visit(literal<std::uint32_t> *) override; void visit(literal<std::nullptr_t> *) override; void visit(literal<std::string> *) override; }; diff --git a/include/elna/boot/dependency.h b/include/elna/boot/dependency.h index 75bbed3..d534585 100644 --- a/include/elna/boot/dependency.h +++ b/include/elna/boot/dependency.h @@ -47,6 +47,10 @@ namespace elna::boot { std::unordered_map<std::filesystem::path, symbol_bag> cache; + // The builtin table stores global aliases (such as Int, Word) as weak + // pointers, so the state keeps their owners alive. + std::vector<std::shared_ptr<alias_type>> alias_owners; + public: const std::shared_ptr<symbol_table> globals; T custom; @@ -55,7 +59,7 @@ namespace elna::boot using const_iterator = std::unordered_map<std::filesystem::path, symbol_bag>::const_iterator; explicit dependency_state(T custom, const target_info& target) - : globals(builtin_symbol_table(target)), custom(custom) + : globals(builtin_symbol_table(target, this->alias_owners)), custom(custom) { } diff --git a/include/elna/boot/name_analysis.h b/include/elna/boot/name_analysis.h index 736874a..91b669c 100644 --- a/include/elna/boot/name_analysis.h +++ b/include/elna/boot/name_analysis.h @@ -175,7 +175,7 @@ namespace elna::boot void visit(literal<integer_literal> *literal) override; void visit(literal<double> *literal) override; void visit(literal<bool> *literal) override; - void visit(literal<unsigned char> *literal) override; + void visit(literal<std::uint32_t> *literal) override; void visit(literal<std::nullptr_t> *literal) override; void visit(literal<std::string> *literal) override; }; diff --git a/include/elna/boot/result.h b/include/elna/boot/result.h index 23505d0..ccc95ca 100644 --- a/include/elna/boot/result.h +++ b/include/elna/boot/result.h @@ -764,7 +764,7 @@ namespace elna::boot integer_literal, double, bool, - unsigned char, + std::uint32_t, std::nullptr_t, std::string, constant_aggregate<ordered_map>, diff --git a/include/elna/boot/symbol.h b/include/elna/boot/symbol.h index f048016..5817b38 100644 --- a/include/elna/boot/symbol.h +++ b/include/elna/boot/symbol.h @@ -402,7 +402,8 @@ namespace elna::boot std::shared_ptr<variable_info> is_variable() override; }; - std::shared_ptr<symbol_table> builtin_symbol_table(const target_info& target); + std::shared_ptr<symbol_table> builtin_symbol_table(const target_info& target, + std::vector<std::shared_ptr<alias_type>>& alias_owners); /** * Symbol bag contains: @@ -589,7 +590,7 @@ namespace elna::boot bool is_scalar_type(const type& checked); /** - * Checks whether the given type is a string (slice of const Char). + * Checks whether the given type is a string (slice of const bytes). * * \param checked The type t o check. * \return Whether the type is a string type. diff --git a/include/elna/gcc/elna-generic.h b/include/elna/gcc/elna-generic.h index 097a660..2d65a26 100644 --- a/include/elna/gcc/elna-generic.h +++ b/include/elna/gcc/elna-generic.h @@ -76,7 +76,7 @@ namespace elna::gcc void visit(boot::literal<boot::integer_literal> *literal) override; void visit(boot::literal<double> *literal) override; void visit(boot::literal<bool> *boolean) override; - void visit(boot::literal<unsigned char> *character) override; + void visit(boot::literal<std::uint32_t> *character) override; void visit(boot::literal<std::nullptr_t> *) override; void visit(boot::literal<std::string> *string) override; void visit(boot::traits_expression *trait) override; diff --git a/source/command_line_interface.elna b/source/command_line_interface.elna index 6aaf440..62965db 100644 --- a/source/command_line_interface.elna +++ b/source/command_line_interface.elna @@ -9,15 +9,15 @@ import cstdlib, cstring, common type CommandLine* = record - input: ^Char; - output: ^Char; + input: ^Word8; + output: ^Word8; lex: Bool; parse: Bool end -proc parse_command_line*(argc: Int; argv: ^^Char): ^CommandLine +proc parse_command_line*(argc: Int; argv: ^^Word8): ^CommandLine var - parameter: ^Char + parameter: ^Word8 i: Int result: ^CommandLine parsed: Bool diff --git a/source/common.elna b/source/common.elna index 1bdfa1f..c5b67f8 100644 --- a/source/common.elna +++ b/source/common.elna @@ -17,13 +17,13 @@ type proc write*(fd: Int; buf: Pointer; Word: Int): Int extern -proc write_s*(value: []const Char) +proc write_s*(value: []const Word8) begin (* fwrite(cast(value.ptr: Pointer), value.length, 1u, stdout) *) write(1, cast(value.ptr: Pointer), cast(value.length: Int)) return -proc write_z*(value: ^Char) +proc write_z*(value: ^Word8) begin write(1, cast(value: Pointer), cast(strlen(value): Int)) return @@ -37,7 +37,7 @@ begin end return -proc write_c*(value: Char) +proc write_c*(value: Word8) begin putchar(cast(value: Int)); fflush(nil) @@ -47,7 +47,7 @@ proc write_i*(value: Int) var digit: Int n: Word - buffer: [10]Char + buffer: [10]Word8 begin n := 10u; @@ -58,7 +58,7 @@ begin digit := value % 10; value := value / 10; - buffer[n] := cast(cast('0': Int) + digit: Char); + buffer[n] := cast(cast('0': Int) + digit: Word8); n := n - 1u end; while n < 10u do @@ -78,7 +78,7 @@ begin return nil (* Returns true or false depending whether two strings are equal. *) -proc string_compare*(lhs_pointer: ^Char; lhs_length: Word; rhs_pointer: []const Char): Bool +proc string_compare*(lhs_pointer: ^Word8; lhs_length: Word; rhs_pointer: []const Word8): Bool var result: Bool begin diff --git a/source/cstdio.elna b/source/cstdio.elna index f44a972..cd218fe 100644 --- a/source/cstdio.elna +++ b/source/cstdio.elna @@ -10,7 +10,7 @@ var stdout*: ^FILE := extern stderr*: ^FILE := extern -proc fopen*(pathname, mode: ^const Char): ^FILE +proc fopen*(pathname, mode: ^const Word8): ^FILE extern proc fclose*(stream: ^FILE): Int @@ -37,22 +37,22 @@ extern proc fputc*(c: Int; stream: ^FILE): Word extern -proc perror*(s: ^const Char) +proc perror*(s: ^const Word8) extern -proc puts*(s: ^const Char): Int +proc puts*(s: ^const Word8): Int extern proc putchar*(c: Int): Int extern -proc sprintf*(str: Pointer; format: ^const Char; number: Word): Int +proc sprintf*(str: Pointer; format: ^const Word8; number: Word): Int extern -proc fprintf*(stream: Pointer; format: ^const Char; number: Word): Int +proc fprintf*(stream: Pointer; format: ^const Word8; number: Word): Int extern -proc fdopen*(fildes: Int; mode: ^const Char): Pointer +proc fdopen*(fildes: Int; mode: ^const Word8): Pointer extern end. diff --git a/source/cstdlib.elna b/source/cstdlib.elna index 32669c1..0f78c8e 100644 --- a/source/cstdlib.elna +++ b/source/cstdlib.elna @@ -14,7 +14,7 @@ extern proc realloc*(ptr: Pointer; size: Word): Pointer extern -proc atoi*(str: ^Char): Int +proc atoi*(str: ^Word8): Int extern proc exit*(code: Int): ! diff --git a/source/cstring.elna b/source/cstring.elna index 0b4bd90..9290a5c 100644 --- a/source/cstring.elna +++ b/source/cstring.elna @@ -2,7 +2,7 @@ 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): ^Word8 extern proc memcpy*(dst: Pointer; src: const Pointer; n: Word) @@ -11,19 +11,19 @@ extern proc memcmp*(s1, s2: const Pointer; n: Word): Int extern -proc strcmp*(s1: ^const Char; s2: ^const Char): Int +proc strcmp*(s1: ^const Word8; s2: ^const Word8): Int extern -proc strncmp*(s1: ^const Char; s2: ^const Char; n: Word): Int +proc strncmp*(s1: ^const Word8; s2: ^const Word8; n: Word): Int extern -proc strncpy*(dst: ^Char; src: ^const Char; dsize: Word): ^Char +proc strncpy*(dst: ^Word8; src: ^const Word8; dsize: Word): ^Word8 extern -proc strcpy*(dst: ^Char; src: ^const Char): ^Char +proc strcpy*(dst: ^Word8; src: ^const Word8): ^Word8 extern -proc strlen*(ptr: ^const Char): Word +proc strlen*(ptr: ^const Word8): Word extern end. diff --git a/source/lexer.elna b/source/lexer.elna index fa79917..83e89df 100644 --- a/source/lexer.elna +++ b/source/lexer.elna @@ -28,17 +28,17 @@ type ) ElnaLexerToken* = record kind: ElnaLexerKind; - start: []const Char; (* DEPRECATED *) + start: []const Word8; (* DEPRECATED *) position: ElnaPosition end ElnaLexerBooleanToken* = record(ElnaLexerToken) value: Bool end ElnaLexerCharacterToken* = record(ElnaLexerToken) - value: Char + value: Word8 end ElnaLexerStringToken* = record(ElnaLexerToken) - value: []const Char + value: []const Word8 end ElnaLexerIntegerToken* = record(ElnaLexerToken) value: Int @@ -55,19 +55,19 @@ type ElnaLexerCursor = record state: ElnaLexerState; - start: ^Char; - finish: ^Char; + start: ^Word8; + finish: ^Word8; token: ^ElnaLexerToken; position: ElnaPosition end BufferPosition* = record - iterator: ^Char; + iterator: ^Word8; location: ElnaLocation end Lexer* = record input: ^FILE; - buffer: ^Char; + buffer: ^Word8; size: Word; length: Word; start: BufferPosition; @@ -513,7 +513,7 @@ begin cursor^.position.end_location.column := cursor^.position.end_location.column + 1u return -proc elna_lexer_classify_space(start_position: ^Char; location: ^ElnaLocation) +proc elna_lexer_classify_space(start_position: ^Word8; location: ^ElnaLocation) begin if start_position^ = '\n' then location^.line := location^.line + 1u; @@ -532,7 +532,7 @@ begin result^.position := position^ return result -proc elna_lexer_classify_keyword(position_start, position_end: ^Char; position: ^ElnaPosition): ^ElnaLexerToken +proc elna_lexer_classify_keyword(position_start, position_end: ^Word8; position: ^ElnaPosition): ^ElnaLexerToken var result: ^ElnaLexerToken result_length: Word @@ -587,9 +587,9 @@ begin end return result -proc elna_lexer_classify_delimited(start_position, end_position: ^Char; position: ^ElnaPosition): ^ElnaLexerToken +proc elna_lexer_classify_delimited(start_position, end_position: ^Word8; position: ^ElnaPosition): ^ElnaLexerToken var - delimiter: Char + delimiter: Word8 result: ^ElnaLexerToken begin delimiter := start_position^; @@ -604,7 +604,7 @@ begin result^.start := start_position[1 to cast(end_position - start_position: Word)] return result -proc elna_lexer_classify_integer(start_position, end_position: ^Char; position: ^ElnaPosition): ^ElnaLexerToken +proc elna_lexer_classify_integer(start_position, end_position: ^Word8; position: ^ElnaPosition): ^ElnaLexerToken var result: ^ElnaLexerToken begin @@ -612,9 +612,9 @@ begin result^.start := start_position[1 to cast(end_position - start_position: Word)] return result -proc elna_lexer_classify_finalize(start_position: ^Char; position: ^ElnaPosition): ^ElnaLexerToken +proc elna_lexer_classify_finalize(start_position: ^Word8; position: ^ElnaPosition): ^ElnaLexerToken var - character: Char + character: Word8 result: ^ElnaLexerToken begin character := start_position^; @@ -634,9 +634,9 @@ begin end return result -proc elna_lexer_classify_single(start_position: ^Char; position: ^ElnaPosition): ^ElnaLexerToken +proc elna_lexer_classify_single(start_position: ^Word8; position: ^ElnaPosition): ^ElnaLexerToken var - character: Char + character: Word8 result: ^ElnaLexerToken begin result := malloc(#size(ElnaLexerToken)); @@ -675,10 +675,10 @@ begin end return result -proc elna_lexer_classify_composite(start_position, one_before_last: ^Char; position: ^ElnaPosition): ^ElnaLexerToken +proc elna_lexer_classify_composite(start_position, one_before_last: ^Word8; position: ^ElnaPosition): ^ElnaLexerToken var - first_character: Char - last_character: Char + first_character: Word8 + last_character: Word8 result: ^ElnaLexerToken begin first_character := start_position^; @@ -739,7 +739,7 @@ return token proc elna_lexer_execute_transition(cursor: ^ElnaLexerCursor): ^ElnaLexerToken var next_transition: ^ElnaLexerTransition - current_character: Char + current_character: Word8 begin current_character := cursor^.finish^; next_transition := elna_lexer_get_transition(cursor^.state, @@ -750,7 +750,7 @@ return elna_lexer_execute_action(cursor, next_transition^.action) (** * One time lexer initialization. *) -proc elna_lexer_initialize(cursor: ^ElnaLexerCursor; code_pointer: ^Char) +proc elna_lexer_initialize(cursor: ^ElnaLexerCursor; code_pointer: ^Word8) begin elna_lexer_classifications(); elna_lexer_transitions(); diff --git a/source/main.elna b/source/main.elna index 369d013..d539d0d 100644 --- a/source/main.elna +++ b/source/main.elna @@ -6,7 +6,7 @@ import cstdio, cstdlib, cstring, cctype, common, command_line_interface, lexer type SourceFile* = record - buffer: [1024]Char; + buffer: [1024]Word8; handle: ^FILE; size: Word; index: Word @@ -22,7 +22,7 @@ type input: Pointer; empty: proc(stream: Pointer): Bool; advance: proc(stream: Pointer); - head: proc(stream: Pointer): Char + head: proc(stream: Pointer): Word8 end Tokenizer* = record length: Word; @@ -42,9 +42,9 @@ var proc reallocarray(ptr: Pointer; n: Word; size: Word): Pointer return realloc(ptr, n * size) -proc string_dup(origin: []const Char): []const Char +proc string_dup(origin: []const Word8): []const Word8 var - copy: ^Char + copy: ^Word8 begin copy := malloc(origin.length); strncpy(copy, origin.ptr, origin.length) @@ -59,13 +59,13 @@ begin result.size := 0u return result -proc string_buffer_push(buffer: ^StringBuffer; char: Char) +proc string_buffer_push(buffer: ^StringBuffer; char: Word8) begin if buffer^.size >= buffer^.capacity then buffer^.capacity := buffer^.capacity + 1024u; buffer^.data := realloc(buffer^.data, buffer^.capacity) end; - cast(buffer^.data + buffer^.size: ^Char)^ := cast(char: Char); + cast(buffer^.data + buffer^.size: ^Word8)^ := cast(char: Word8); buffer^.size := buffer^.size + 1u return @@ -74,11 +74,11 @@ begin buffer^.size := buffer^.size - count return -proc string_buffer_clear(buffer: ^StringBuffer): []const Char +proc string_buffer_clear(buffer: ^StringBuffer): []const Word8 var - result: []const Char + result: []const Word8 begin - result := cast(buffer^.data: ^Char)[1 to buffer^.size]; + result := cast(buffer^.data: ^Word8)[1 to buffer^.size]; buffer^.size := 0u return result @@ -86,7 +86,7 @@ return result Source code stream procedures. *) -proc read_source(filename: ^Char): ^SourceFile +proc read_source(filename: ^Word8): ^SourceFile var result: ^SourceFile file_handle: ^FILE @@ -113,7 +113,7 @@ begin end return source_file^.size = 0u -proc source_file_head(source_input: Pointer): Char +proc source_file_head(source_input: Pointer): Word8 var source_file: ^SourceFile begin @@ -132,7 +132,7 @@ return proc source_code_empty(source_code: ^SourceCode): Bool return source_code^.empty(source_code^.input) -proc source_code_head(source_code: SourceCode): Char +proc source_code_head(source_code: SourceCode): Word8 return source_code.head(source_code.input) proc source_code_advance(source_code: ^SourceCode) @@ -147,14 +147,14 @@ begin source_code^.position.column := 0u return -proc source_code_expect(source_code: ^SourceCode; expected: Char): Bool +proc source_code_expect(source_code: ^SourceCode; expected: Word8): Bool return ~source_code_empty(source_code) & source_code_head(source_code^) = expected (* Token procedures. *) -proc lexer_escape(escape: Char; result: ^Char): Bool +proc lexer_escape(escape: Word8; result: ^Word8): Bool var successful: Bool begin @@ -194,7 +194,7 @@ return successful (* Skip spaces. *) proc lexer_spaces(source_code: ^SourceCode) var - current: Char + current: Word8 begin while ~source_code_empty(source_code) & isspace(cast(source_code_head(source_code^): Int)) <> 0 do current := source_code_head(source_code^); @@ -207,7 +207,7 @@ begin return (* Checker whether the character is allowed in an identificator. *) -proc lexer_is_ident(char: Char): Bool +proc lexer_is_ident(char: Word8): Bool return isalnum(cast(char: Int)) <> 0 or char = '_' proc lexer_identifier(source_code: ^SourceCode; token_content: ^StringBuffer) @@ -241,7 +241,7 @@ begin end return trailing = 2u -proc lexer_character(source_code: ^SourceCode; token_content: ^Char): Bool +proc lexer_character(source_code: ^SourceCode; token_content: ^Word8): Bool var successful: Bool begin @@ -264,10 +264,10 @@ return successful proc lexer_string(source_code: ^SourceCode; token_content: ^StringBuffer): Bool var - token_end, constructed_string: ^Char + token_end, constructed_string: ^Word8 token_length: Word is_valid: Bool := true - next_char: Char + next_char: Word8 begin while is_valid & ~source_code_empty(source_code) & source_code_head(source_code^) <> '"' do is_valid := lexer_character(source_code, @next_char); @@ -296,7 +296,7 @@ begin return (* Categorize an identifier. *) -proc lexer_categorize(token_content: []const Char): ^ElnaLexerToken +proc lexer_categorize(token_content: []const Word8): ^ElnaLexerToken var current_token: ^ElnaLexerToken begin @@ -395,7 +395,7 @@ return proc lexer_next(source_code: SourceCode; token_buffer: ^StringBuffer): ^ElnaLexerToken var current_token: ^ElnaLexerToken := nil - first_char: Char + first_char: Word8 begin first_char := source_code_head(source_code); @@ -777,7 +777,7 @@ begin end return return_code -proc process(argc: Int; argv: ^^Char): Int +proc process(argc: Int; argv: ^^Word8): Int var tokens: ^ElnaLexerToken tokens_size: Word diff --git a/testsuite/runnable/constant_string_initializer.elna b/testsuite/runnable/constant_string_initializer.elna index e2ffb25..52ca429 100644 --- a/testsuite/runnable/constant_string_initializer.elna +++ b/testsuite/runnable/constant_string_initializer.elna @@ -1,5 +1,5 @@ var - s: []const Char := "String value" + s: []const Word8 := "String value" begin assert(s = "String value") diff --git a/testsuite/runnable/record_extension.elna b/testsuite/runnable/record_extension.elna index 47ac908..7d8dc61 100644 --- a/testsuite/runnable/record_extension.elna +++ b/testsuite/runnable/record_extension.elna @@ -3,7 +3,7 @@ type kind: Word end ElnaLexerStringToken = record(ElnaLexerToken) - value: []const Char + value: []const Word8 end var diff --git a/testsuite/runnable/slice_cast.elna b/testsuite/runnable/slice_cast.elna index 5ab2c93..7c43959 100644 --- a/testsuite/runnable/slice_cast.elna +++ b/testsuite/runnable/slice_cast.elna @@ -1,6 +1,6 @@ var - ints: [4]Int := [4]Int{ 1, 2, 3, 4 } + ints: [4]Int32 := [4]Int32{ 1i32, 2i32, 3i32, 4i32 } begin - assert(cast(ints[1u to 4u]: []Char).length = #size(Int) * ints.length) + assert(cast(ints[1u to 4u]: []Int8).length = #size(Int32) * ints.length) end. diff --git a/testsuite/runnable/unicode_escape_character.elna b/testsuite/runnable/unicode_escape_character.elna new file mode 100644 index 0000000..d49910c --- /dev/null +++ b/testsuite/runnable/unicode_escape_character.elna @@ -0,0 +1,4 @@ +begin + assert(`\{U+E9}` = `é`); + assert(`\{U+1F600}` = `😀`) +end. |
