refactor: pass all tests on lexic analyzer
This commit is contained in:
parent
8425f621eb
commit
35a022cdf9
@ -31,8 +31,7 @@ pub fn lex(
|
||||
// check for CR, and throw error
|
||||
if (input[current_pos] == '\r') {
|
||||
var err = try ctx.create_and_append_error("Usage of CRLF", current_pos, current_pos + 1);
|
||||
var label = ctx.create_error_label("There is a line feed (CR) here", current_pos, current_pos + 1);
|
||||
try err.add_label(&label);
|
||||
try err.add_label(ctx.create_error_label("There is a line feed (CR) here", current_pos, current_pos + 1));
|
||||
err.set_help("All THP code must use LF newline delimiters.");
|
||||
|
||||
return LexError.CRLF;
|
||||
|
@ -66,8 +66,7 @@ fn prefixed(
|
||||
if (end_position >= cap or !validator(input[end_position])) {
|
||||
// populate error information
|
||||
var new_error = try ctx.create_and_append_error("Incomplete number", start, end_position);
|
||||
var new_label = ctx.create_error_label("Expected a valid digit after the '" ++ [_]u8{prefix} ++ "'", start, end_position);
|
||||
try new_error.add_label(&new_label);
|
||||
try new_error.add_label(ctx.create_error_label("Expected a valid digit after the '" ++ [_]u8{prefix} ++ "'", start, end_position));
|
||||
|
||||
switch (prefix) {
|
||||
'x' => new_error.set_help("Hex numbers should have at least one 0-9a-fA-F after the x"),
|
||||
@ -128,8 +127,7 @@ fn integer(
|
||||
// - a single zero. valid
|
||||
if (first_char == '0' and last_pos > start + 1) {
|
||||
var err = try ctx.create_and_append_error("Leading zero", start, start + 1);
|
||||
var label = ctx.create_error_label("This decimal number has a leading zero.", start, last_pos);
|
||||
try err.add_label(&label);
|
||||
try err.add_label(ctx.create_error_label("This decimal number has a leading zero.", start, last_pos));
|
||||
err.set_help("If you want an octal number use '0o', otherwise remove the leading zero");
|
||||
|
||||
return LexError.LeadingZero;
|
||||
@ -157,8 +155,7 @@ fn integer(
|
||||
// leading zero on an integer, throw an error
|
||||
if (first_char == '0') {
|
||||
var err = try ctx.create_and_append_error("Leading zero", start, start + 1);
|
||||
var label = ctx.create_error_label("This decimal number has a leading zero.", start, last_pos);
|
||||
try err.add_label(&label);
|
||||
try err.add_label(ctx.create_error_label("This decimal number has a leading zero.", start, last_pos));
|
||||
err.set_help("If you want an octal number use '0o', otherwise remove the leading zero");
|
||||
|
||||
return LexError.LeadingZero;
|
||||
@ -189,8 +186,7 @@ fn floating_point(
|
||||
if (current_pos >= cap or !utils.is_decimal_digit(input[current_pos])) {
|
||||
// This is an error
|
||||
var err = try ctx.create_and_append_error("Incomplete floating point number", token_start, current_pos);
|
||||
var label = ctx.create_error_label("This number is incomplete", token_start, current_pos);
|
||||
try err.add_label(&label);
|
||||
try err.add_label(ctx.create_error_label("This number is incomplete", token_start, current_pos));
|
||||
err.set_help("Add a number after the period");
|
||||
|
||||
return LexError.IncompleteFloatingNumber;
|
||||
@ -228,8 +224,7 @@ fn scientific(
|
||||
// expect `+` or `-`
|
||||
if (current_pos >= cap) {
|
||||
var err = try ctx.create_and_append_error("Incomplete scientific point number", token_start, current_pos);
|
||||
var label = ctx.create_error_label("Expected a '+' or '-' after the exponent", token_start, current_pos);
|
||||
try err.add_label(&label);
|
||||
try err.add_label(ctx.create_error_label("Expected a '+' or '-' after the exponent", token_start, current_pos));
|
||||
err.set_help("Add a sign and a digit to complete the scientific number");
|
||||
|
||||
return LexError.IncompleteScientificNumber;
|
||||
@ -237,8 +232,7 @@ fn scientific(
|
||||
const sign_char = input[current_pos];
|
||||
if (sign_char != '+' and sign_char != '-') {
|
||||
var err = try ctx.create_and_append_error("Incomplete scientific point number", current_pos, current_pos + 1);
|
||||
var label = ctx.create_error_label("Expected a '+' or '-' here, found another char", current_pos, current_pos + 1);
|
||||
try err.add_label(&label);
|
||||
try err.add_label(ctx.create_error_label("Expected a '+' or '-' here, found another char", current_pos, current_pos + 1));
|
||||
err.set_help("Add a sign and a digit after the first 'e' to complete the scientific number");
|
||||
|
||||
return LexError.IncompleteScientificNumber;
|
||||
@ -254,8 +248,7 @@ fn scientific(
|
||||
// if there is no difference, no extra digits were lexed.
|
||||
if (digits_start == current_pos) {
|
||||
var err = try ctx.create_and_append_error("Incomplete scientific point number", current_pos - 1, current_pos);
|
||||
var label = ctx.create_error_label("Expected at least one digit after this sign", current_pos - 1, current_pos);
|
||||
try err.add_label(&label);
|
||||
try err.add_label(ctx.create_error_label("Expected at least one digit after this sign", current_pos - 1, current_pos));
|
||||
err.set_help("Add a digit after the sign to complit the scientific number");
|
||||
|
||||
return LexError.IncompleteScientificNumber;
|
||||
|
@ -37,8 +37,7 @@ pub fn lex(
|
||||
// new line, initialize and return error
|
||||
else if (next_char == '\n') {
|
||||
var err = try ctx.create_and_append_error("Incomplete String", current_pos, current_pos + 1);
|
||||
var label = ctx.create_error_label("Found a new line here", current_pos, current_pos + 1);
|
||||
try err.add_label(&label);
|
||||
try err.add_label(ctx.create_error_label("Found a new line here", current_pos, current_pos + 1));
|
||||
err.set_help("Strings must always end on the same line that they start.");
|
||||
|
||||
return LexError.IncompleteString;
|
||||
@ -48,16 +47,14 @@ pub fn lex(
|
||||
// if next char is EOF, return error
|
||||
if (current_pos + 1 == cap) {
|
||||
var err = try ctx.create_and_append_error("Incomplete String", current_pos, current_pos + 1);
|
||||
var label = ctx.create_error_label("Found EOF here", current_pos, current_pos + 1);
|
||||
try err.add_label(&label);
|
||||
try err.add_label(ctx.create_error_label("Found EOF here", current_pos, current_pos + 1));
|
||||
err.set_help("Strings must always end on the same line that they start.");
|
||||
return LexError.IncompleteString;
|
||||
}
|
||||
// if next char is newline, return error
|
||||
else if (input[current_pos + 1] == '\n') {
|
||||
var err = try ctx.create_and_append_error("Incomplete String", current_pos, current_pos + 1);
|
||||
var label = ctx.create_error_label("Found a new line here", current_pos, current_pos + 1);
|
||||
try err.add_label(&label);
|
||||
try err.add_label(ctx.create_error_label("Found a new line here", current_pos, current_pos + 1));
|
||||
err.set_help("Strings must always end on the same line that they start.");
|
||||
return LexError.IncompleteString;
|
||||
}
|
||||
@ -70,10 +67,9 @@ pub fn lex(
|
||||
current_pos += 1;
|
||||
}
|
||||
|
||||
// this could only reach when EOF is hit, return error
|
||||
// this can only happen when EOF is hit, return error
|
||||
var err = try ctx.create_and_append_error("Incomplete String", current_pos, current_pos + 1);
|
||||
var label = ctx.create_error_label("Found EOF here", current_pos, current_pos + 1);
|
||||
try err.add_label(&label);
|
||||
try err.add_label(ctx.create_error_label("Found EOF here", current_pos, current_pos + 1));
|
||||
err.set_help("Strings must always end on the same line that they start.");
|
||||
|
||||
return LexError.IncompleteString;
|
||||
|
@ -13,15 +13,26 @@ pub const CompilerContext = struct {
|
||||
};
|
||||
}
|
||||
|
||||
/// Appends a new error to the compiler context
|
||||
/// and returns a handle to the just created error
|
||||
/// Creates a new compiler error and appends it to the context's error list.
|
||||
///
|
||||
/// This function creates an `ErrorData` instance and adds it to the context's error list.
|
||||
/// IMPORTANT: The returned pointer becomes invalid if the error list needs to reallocate,
|
||||
/// which happens when a new error is appended to the context.
|
||||
///
|
||||
/// Example:
|
||||
/// ```zig
|
||||
/// const err = try ctx.create_and_append_error("Syntax error", 10, 15);
|
||||
/// // Safe to use err here
|
||||
/// try err.add_label(...);
|
||||
/// // After this point, err might become invalid if new errors are added
|
||||
/// ```
|
||||
pub fn create_and_append_error(
|
||||
self: *CompilerContext,
|
||||
reason: []const u8,
|
||||
start_position: usize,
|
||||
end_position: usize,
|
||||
) !*ErrorData {
|
||||
var new_error = ErrorData{
|
||||
const new_error = ErrorData{
|
||||
.reason = reason,
|
||||
.start_position = start_position,
|
||||
.end_position = end_position,
|
||||
@ -29,8 +40,11 @@ pub const CompilerContext = struct {
|
||||
.help = null,
|
||||
};
|
||||
|
||||
// Append the error to the array list
|
||||
try self.errors.append(new_error);
|
||||
return &new_error;
|
||||
// Get a pointer to the newly appended error
|
||||
const ptr = &self.errors.items[self.errors.items.len - 1];
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/// Creates a new ErrorLabel with a static message.
|
||||
@ -70,8 +84,8 @@ pub const ErrorData = struct {
|
||||
/// A list of detailed messages about the error
|
||||
labels: std.ArrayList(ErrorLabel),
|
||||
|
||||
pub fn add_label(self: *ErrorData, label: *ErrorLabel) !void {
|
||||
try self.labels.append(label.*);
|
||||
pub fn add_label(self: *ErrorData, label: ErrorLabel) !void {
|
||||
try self.labels.append(label);
|
||||
}
|
||||
|
||||
/// Sets the help message of this error.
|
||||
|
Loading…
Reference in New Issue
Block a user