diff --git a/src/02_syntax/root.zig b/src/02_syntax/root.zig index 3ae44a4..8fd1e73 100644 --- a/src/02_syntax/root.zig +++ b/src/02_syntax/root.zig @@ -15,7 +15,6 @@ const TokenStream = types.TokenStream; pub const Module = struct { statements: std.ArrayList(statement.Statement), - alloc: std.mem.Allocator, /// Parses a module. /// @@ -27,13 +26,12 @@ pub const Module = struct { target: *@This(), tokens: *const TokenStream, pos: usize, - allocator: std.mem.Allocator, - err_arrl: *std.ArrayList(errors.ErrorData), + ctx: *context.CompilerContext, ) ParseError!void { - var arrl = std.ArrayList(statement.Statement).init(allocator); + var arrl = std.ArrayList(statement.Statement).init(ctx.allocator); errdefer arrl.deinit(); errdefer for (arrl.items) |i| { - i.deinit(); + i.deinit(ctx); }; const input_len = tokens.items.len; @@ -42,15 +40,13 @@ pub const Module = struct { // parse many statements while (current_pos < input_len) { var stmt: statement.Statement = undefined; - var current_error: errors.ErrorData = undefined; // TODO: handle other errors of vardef parsing - const next_pos = stmt.init(tokens, current_pos, ¤t_error, allocator) catch |e| switch (e) { + const next_pos = stmt.init(tokens, current_pos, ctx) catch |e| switch (e) { error.Error => { // add the error to the list of errors, // and exit for now because i havent implemented // error recovery yet - try err_arrl.append(current_error); return error.Error; }, else => return e, @@ -63,20 +59,12 @@ pub const Module = struct { } // 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); + _ = try ctx.create_and_append_error("No statement matched", current_pos, current_pos + 1); return error.Error; } target.* = .{ .statements = arrl, - .alloc = allocator, }; } diff --git a/src/02_syntax/statement.zig b/src/02_syntax/statement.zig index e0e9458..6441949 100644 --- a/src/02_syntax/statement.zig +++ b/src/02_syntax/statement.zig @@ -11,7 +11,6 @@ const TokenStream = types.TokenStream; const ParseError = types.ParseError; pub const Statement = struct { - alloc: std.mem.Allocator, value: union(enum) { variableBinding: *variable.VariableBinding, }, @@ -21,35 +20,36 @@ pub const Statement = struct { target: *Statement, tokens: *const TokenStream, pos: usize, - err: *errors.ErrorData, - allocator: std.mem.Allocator, + ctx: *context.CompilerContext, ) ParseError!?usize { // try to parse a variable definition - var vardef = try allocator.create(variable.VariableBinding); - errdefer allocator.destroy(vardef); + var vardef = try ctx.allocator.create(variable.VariableBinding); + errdefer ctx.allocator.destroy(vardef); - const vardef_result = try vardef.init(tokens, pos, err, allocator); + const vardef_result = try vardef.init(tokens, pos, ctx); if (vardef_result) |vardef_end| { // variable definition parsed // return the parsed variable definition target.* = .{ - .alloc = allocator, .value = .{ .variableBinding = vardef }, }; return vardef_end; } // manually deallocate - allocator.destroy(vardef); + ctx.allocator.destroy(vardef); return null; } - pub fn deinit(self: @This()) void { + pub fn deinit( + self: @This(), + ctx: *context.CompilerContext, + ) void { switch (self.value) { .variableBinding => |v| { - v.deinit(); - self.alloc.destroy(v); + v.deinit(ctx); + ctx.allocator.destroy(v); }, } } diff --git a/src/02_syntax/variable.zig b/src/02_syntax/variable.zig index c00d184..0ec91aa 100644 --- a/src/02_syntax/variable.zig +++ b/src/02_syntax/variable.zig @@ -14,15 +14,13 @@ pub const VariableBinding = struct { datatype: ?*lexic.Token, identifier: *lexic.Token, expression: *expression.Expression, - alloc: std.mem.Allocator, /// Parses a variable binding and returns the position of the next token pub fn init( target: *VariableBinding, tokens: *const TokenStream, pos: usize, - err: *errors.ErrorData, - allocator: std.mem.Allocator, + ctx: *context.CompilerContext, ) ParseError!?usize { std.debug.assert(pos < tokens.items.len); @@ -34,17 +32,16 @@ pub const VariableBinding = struct { // check there is still input if (pos + 1 >= tokens.items.len) { // return error - try err.init( + var err = try ctx.create_and_append_error( "Incomplete variable declaration", var_keyword.start_pos, var_keyword.start_pos + var_keyword.value.len, - allocator, ); - try err.add_label( + try err.add_label(ctx.create_error_label( "This variable declaration is incomplete", var_keyword.start_pos, var_keyword.start_pos + var_keyword.value.len, - ); + )); return ParseError.Error; } @@ -65,26 +62,28 @@ pub const VariableBinding = struct { // parse expression if (pos + 3 >= tokens.items.len) return ParseError.Error; - const exp = try allocator.create(expression.Expression); - errdefer allocator.destroy(exp); + const exp = try ctx.allocator.create(expression.Expression); + errdefer ctx.allocator.destroy(exp); const next_pos = if (exp.init(tokens, pos + 3)) |x| x else { // TODO: populate error information return ParseError.Error; }; - // return + // assign and return target.* = .{ .is_mutable = true, .datatype = null, .identifier = identifier, .expression = exp, - .alloc = allocator, }; return next_pos; } - pub fn deinit(self: @This()) void { - self.alloc.destroy(self.expression); + pub fn deinit( + self: @This(), + ctx: *context.CompilerContext, + ) void { + ctx.allocator.destroy(self.expression); } }; diff --git a/src/main.zig b/src/main.zig index f720500..d6becc3 100644 --- a/src/main.zig +++ b/src/main.zig @@ -116,17 +116,14 @@ fn repl() !void { continue; } - std.debug.print("should be syntax analizing the tokens...\n", .{}); - // // Syntax analysis // var ast: syntax.Module = undefined; - ast.init(&tokens, 0, alloc, &error_array) catch |e| switch (e) { + ast.init(&tokens, 0, &ctx) catch |e| switch (e) { error.Error => { // Print all the errors - for (error_array.items) |ee| { - var err_item = ee; + for (ctx.errors.items) |*err_item| { const err_str = try err_item.get_error_str(line, "repl", alloc); try stdout.print("\n{s}\n", .{err_str}); try bw.flush();