aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2026-08-18 13:31:47 +0200
committerEugen Wissner <belka@caraus.de>2026-08-18 13:31:47 +0200
commit4f77ad5d019618893c59a0f8d5bfa6b98e50a3be (patch)
treed9e01460ecf94a491be476fbca76b6608276d967
parent4b7c87a9b53f5317e9f7982bd779d53a66960bdc (diff)
downloadelna-4f77ad5d019618893c59a0f8d5bfa6b98e50a3be.tar.gz
Make Int and Word aliases to fixed-size types
-rw-r--r--boot/ast.cc4
-rw-r--r--boot/evaluator.cc10
-rw-r--r--boot/lexer.ll2
-rw-r--r--boot/name_analysis.cc6
-rw-r--r--boot/parser.yy2
-rw-r--r--boot/symbol.cc22
-rw-r--r--boot/type_check.cc6
-rw-r--r--gcc/gcc/elna-builtins.cc6
-rw-r--r--gcc/gcc/elna-generic.cc4
-rw-r--r--gcc/gcc/elna-tree.cc15
-rw-r--r--include/elna/boot/ast.h8
-rw-r--r--include/elna/boot/dependency.h6
-rw-r--r--include/elna/boot/name_analysis.h2
-rw-r--r--include/elna/boot/result.h2
-rw-r--r--include/elna/boot/symbol.h5
-rw-r--r--include/elna/gcc/elna-generic.h2
-rw-r--r--source/command_line_interface.elna8
-rw-r--r--source/common.elna12
-rw-r--r--source/cstdio.elna12
-rw-r--r--source/cstdlib.elna2
-rw-r--r--source/cstring.elna12
-rw-r--r--source/lexer.elna42
-rw-r--r--source/main.elna44
-rw-r--r--testsuite/runnable/constant_string_initializer.elna2
-rw-r--r--testsuite/runnable/record_extension.elna2
-rw-r--r--testsuite/runnable/slice_cast.elna4
-rw-r--r--testsuite/runnable/unicode_escape_character.elna4
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.