diff --git a/src/02_syntax/expression.zig b/src/02_syntax/expression.zig index 03a1be4..255db74 100644 --- a/src/02_syntax/expression.zig +++ b/src/02_syntax/expression.zig @@ -3,7 +3,6 @@ const lexic = @import("lexic"); const errors = @import("errors"); const Token = lexic.Token; const TokenType = lexic.TokenType; -const ParseError = @import("./types.zig").ParseError; pub const Expression = union(enum) { number: *const Token, diff --git a/src/02_syntax/root.zig b/src/02_syntax/root.zig index d5e6292..a79e996 100644 --- a/src/02_syntax/root.zig +++ b/src/02_syntax/root.zig @@ -13,7 +13,7 @@ const ParseError = types.ParseError; const TokenStream = types.TokenStream; pub const Module = struct { - statements: std.ArrayList(*statement.Statement), + statements: std.ArrayList(statement.Statement), alloc: std.mem.Allocator, /// Parses a module. @@ -29,11 +29,10 @@ pub const Module = struct { allocator: std.mem.Allocator, err_arrl: *std.ArrayList(errors.ErrorData), ) ParseError!void { - var arrl = std.ArrayList(*statement.Statement).init(allocator); + var arrl = std.ArrayList(statement.Statement).init(allocator); errdefer arrl.deinit(); errdefer for (arrl.items) |i| { i.deinit(); - allocator.destroy(i); }; const input_len = tokens.items.len; @@ -41,30 +40,27 @@ pub const Module = struct { // parse many statements while (current_pos < input_len) { - var stmt = try allocator.create(statement.Statement); - errdefer allocator.destroy(stmt); + var stmt: statement.Statement = undefined; - const next_pos = stmt.init(tokens, current_pos, allocator) catch |e| { - switch (e) { - error.Unmatched => { - // create the error value - var error_target: errors.ErrorData = undefined; - try error_target.init( - "No statement found", - current_pos, - current_pos + 1, - allocator, - ); - defer error_target.deinit(); - try err_arrl.append(error_target); - return error.Unmatched; - }, - else => return e, - } - }; - current_pos = next_pos; + // TODO: handle other errors of vardef parsing + const next_pos = try stmt.init(tokens, current_pos, allocator); + if (next_pos) |next_pos_actual| { + current_pos = next_pos_actual; - try arrl.append(stmt); + try arrl.append(stmt); + continue; + } + + // nothing matched, but there are tokens. this in an error + var err: errors.ErrorData = undefined; + try err.init( + "No statement matched", + current_pos, + current_pos + 1, + allocator, + ); + try err_arrl.append(err); + return error.Error; } target.* = .{ @@ -76,7 +72,6 @@ pub const Module = struct { pub fn deinit(self: @This()) void { for (self.statements.items) |stmt| { stmt.deinit(); - self.alloc.destroy(stmt); } self.statements.deinit(); } diff --git a/src/02_syntax/statement.zig b/src/02_syntax/statement.zig index 687d5cb..761b17d 100644 --- a/src/02_syntax/statement.zig +++ b/src/02_syntax/statement.zig @@ -21,14 +21,13 @@ pub const Statement = struct { tokens: *const TokenStream, pos: usize, allocator: std.mem.Allocator, - ) ParseError!usize { + ) ParseError!?usize { // try to parse a variable definition - var vardef = allocator.create(variable.VariableBinding) catch { - return ParseError.OutOfMemory; - }; + var vardef = try allocator.create(variable.VariableBinding); errdefer allocator.destroy(vardef); + // TODO: handle other errors of vardef parsing if (try vardef.init(tokens, pos, allocator)) |vardef_end| { // variable definition parsed // return the parsed variable definition @@ -38,10 +37,10 @@ pub const Statement = struct { }; return vardef_end; } - // TODO: handle other errors of vardef parsing - // fail - return ParseError.Unmatched; + // manually deallocate + allocator.destroy(vardef); + return null; } pub fn deinit(self: @This()) void { @@ -81,15 +80,11 @@ test "should fail on other constructs" { defer tokens.deinit(); var statement: Statement = undefined; - _ = statement.init(&tokens, 0, std.testing.allocator) catch |e| switch (e) { - error.Unmatched => { - return; - }, - else => { - try std.testing.expect(false); - return; - }, - }; + const result = try statement.init(&tokens, 0, std.testing.allocator); + if (result == null) { + // good path + return; + } try std.testing.expect(false); } diff --git a/src/02_syntax/types.zig b/src/02_syntax/types.zig index 7673404..7aa317a 100644 --- a/src/02_syntax/types.zig +++ b/src/02_syntax/types.zig @@ -3,9 +3,6 @@ const lexic = @import("lexic"); /// Respresents a failure of parsing. pub const ParseError = error{ - /// The parse operation failed, but it is recoverable. - /// Other parsers should be considered. - Unmatched, /// The parse operation parsed after a point of no return. /// For example, a `var` keyword was found, but then no identifier /// The parsing should stop