refactor: migrate syntax parser to new compiler context
This commit is contained in:
parent
ac30ea169c
commit
2aa81dd39f
@ -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,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user