feat: minimal parsing of statements
This commit is contained in:
parent
e48e36bea8
commit
1225049f76
@ -31,8 +31,8 @@ Now in Zig!
|
||||
- [x] Lex single line comments
|
||||
- [x] Lex strings
|
||||
- [x] Lex grouping signs
|
||||
- [ ]
|
||||
|
||||
|
||||
- [x] Parse minimal expression
|
||||
- [x] Parse minimal variable binding
|
||||
- [x] Parse minimal statement
|
||||
|
||||
|
||||
|
@ -94,6 +94,7 @@ pub fn build(b: *std.Build) void {
|
||||
"src/02_syntax/root.zig",
|
||||
"src/02_syntax/variable.zig",
|
||||
"src/02_syntax/expression.zig",
|
||||
"src/02_syntax/statement.zig",
|
||||
};
|
||||
for (files) |file| {
|
||||
const file_unit_test = b.addTest(.{
|
||||
|
56
src/02_syntax/statement.zig
Normal file
56
src/02_syntax/statement.zig
Normal file
@ -0,0 +1,56 @@
|
||||
const std = @import("std");
|
||||
const lexic = @import("lexic");
|
||||
const expression = @import("expression.zig");
|
||||
const types = @import("./types.zig");
|
||||
const utils = @import("./utils.zig");
|
||||
const variable = @import("./variable.zig");
|
||||
|
||||
const TokenStream = types.TokenStream;
|
||||
const ParseError = types.ParseError;
|
||||
|
||||
pub const Statement = union(enum) {
|
||||
VariableBinding: *variable.VariableBinding,
|
||||
|
||||
fn init(target: *Statement, tokens: *const TokenStream, pos: usize, allocator: std.mem.Allocator) ParseError!void {
|
||||
// try to parse a variable definition
|
||||
|
||||
var vardef: variable.VariableBinding = undefined;
|
||||
var parse_failed = false;
|
||||
vardef.init(tokens, pos, allocator) catch |err| switch (err) {
|
||||
error.Unmatched => {
|
||||
parse_failed = true;
|
||||
},
|
||||
else => {
|
||||
return err;
|
||||
},
|
||||
};
|
||||
if (!parse_failed) {
|
||||
// return the parsed variable definition
|
||||
target.* = .{
|
||||
.VariableBinding = &vardef,
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
// fail
|
||||
return ParseError.Unmatched;
|
||||
}
|
||||
|
||||
fn deinit(self: @This()) void {
|
||||
switch (self) {
|
||||
.VariableBinding => |v| v.deinit(),
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
test "should parse a variable declaration statement" {
|
||||
const input = "var my_variable = 322";
|
||||
const tokens = try lexic.tokenize(input, std.testing.allocator);
|
||||
defer tokens.deinit();
|
||||
|
||||
var statement: Statement = undefined;
|
||||
try statement.init(&tokens, 0, std.testing.allocator);
|
||||
defer statement.deinit();
|
||||
|
||||
// try std.testing.expectEqual(true, statement.is_mutable);
|
||||
}
|
@ -7,7 +7,7 @@ const utils = @import("./utils.zig");
|
||||
const TokenStream = types.TokenStream;
|
||||
const ParseError = types.ParseError;
|
||||
|
||||
const VariableBinding = struct {
|
||||
pub const VariableBinding = struct {
|
||||
is_mutable: bool,
|
||||
datatype: ?*lexic.Token,
|
||||
identifier: *lexic.Token,
|
||||
@ -15,7 +15,7 @@ const VariableBinding = struct {
|
||||
alloc: std.mem.Allocator,
|
||||
|
||||
/// Parses a variable binding
|
||||
fn init(target: *VariableBinding, tokens: *const TokenStream, pos: usize, allocator: std.mem.Allocator) ParseError!void {
|
||||
pub fn init(target: *VariableBinding, tokens: *const TokenStream, pos: usize, allocator: std.mem.Allocator) ParseError!void {
|
||||
std.debug.assert(pos < tokens.items.len);
|
||||
|
||||
// try to parse a var keyword
|
||||
@ -42,9 +42,7 @@ const VariableBinding = struct {
|
||||
|
||||
// parse expression
|
||||
if (pos + 3 >= tokens.items.len) return ParseError.Error;
|
||||
var exp = allocator.create(expression.Expression) catch {
|
||||
return ParseError.Error;
|
||||
};
|
||||
var exp = try allocator.create(expression.Expression);
|
||||
errdefer allocator.destroy(exp);
|
||||
exp.init(tokens, pos + 3) catch {
|
||||
return ParseError.Error;
|
||||
@ -60,7 +58,7 @@ const VariableBinding = struct {
|
||||
};
|
||||
}
|
||||
|
||||
fn deinit(self: *VariableBinding) void {
|
||||
pub fn deinit(self: *VariableBinding) void {
|
||||
self.alloc.destroy(self.expression);
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user