diff options
author | kdx <kikoodx@paranoici.org> | 2024-03-19 13:42:20 +0100 |
---|---|---|
committer | kdx <kikoodx@paranoici.org> | 2024-03-19 13:42:20 +0100 |
commit | 2f9e4f9dc6472af059b740513ebb3ca04cc0bc44 (patch) | |
tree | 43ba4881b3acd55585c16a2c1903c837170d7273 | |
parent | ffea8259f2cda681c3c14bbb4b09f6d0a39b291f (diff) | |
download | o7z-2f9e4f9dc6472af059b740513ebb3ca04cc0bc44.tar.gz |
dumbest function
-rw-r--r-- | src/Node.zig | 44 | ||||
-rw-r--r-- | src/Parser.zig | 48 | ||||
-rw-r--r-- | src/Token.zig | 13 | ||||
-rw-r--r-- | test.o7 | 19 |
4 files changed, 91 insertions, 33 deletions
diff --git a/src/Node.zig b/src/Node.zig index 358cd46..a5aa0d0 100644 --- a/src/Node.zig +++ b/src/Node.zig @@ -4,28 +4,56 @@ const Token = @import("Token.zig"); const Self = @This(); -next: ?*Self = null, +left: ?*Self = null, +right: ?*Self = null, +tag: Tag, token: Token, -pub fn init(allocator: std.mem.Allocator, lexer: *Lexer) !*Self { +const Tag = enum { + fndef, + number, + add, + sub, +}; + +pub const stub = Self{ .tag = undefined, .token = undefined }; + +pub fn init(allocator: std.mem.Allocator, tag: Tag, token: Token) !*Self { const self = try allocator.create(Self); - self.* = .{ .token = try lexer.pop() }; + self.* = .{ .tag = tag, .token = token }; return self; } pub fn deinit(self: *Self, allocator: std.mem.Allocator) void { - if (self.next != null) - self.next.?.deinit(allocator); + if (self.left != null) + self.left.?.deinit(allocator); + if (self.right != null) + self.right.?.deinit(allocator); allocator.destroy(self); } +pub fn chainLeft(self: *Self, left: *Self) *Self { + self.left = left; + return left; +} + +pub fn chainRight(self: *Self, right: *Self) *Self { + self.right = right; + return right; +} + pub fn format( self: Self, comptime _: []const u8, _: std.fmt.FormatOptions, writer: std.io.AnyWriter, ) !void { - try writer.print("Node{{ .token = {} }}\n", .{self.token}); - if (self.next != null) - try self.next.?.format("", .{}, writer); + try writer.print( + "Node{{ .tag = {}, .token = {} }}\n", + .{ self.tag, self.token }, + ); + if (self.left != null) + try self.left.?.format("", .{}, writer); + if (self.right != null) + try self.right.?.format("", .{}, writer); } diff --git a/src/Parser.zig b/src/Parser.zig index 27a0163..43741e3 100644 --- a/src/Parser.zig +++ b/src/Parser.zig @@ -1,6 +1,7 @@ const std = @import("std"); const Node = @import("Node.zig"); const Lexer = @import("Lexer.zig"); +const Token = @import("Token.zig"); const Self = @This(); @@ -8,6 +9,10 @@ allocator: std.mem.Allocator, root: ?*Node, lexer: *Lexer, +const Error = error{ + UnexpectedToken, +}; + pub fn init( allocator: std.mem.Allocator, lexer: *Lexer, @@ -21,14 +26,43 @@ pub fn init( pub fn deinit(_: Self) void {} +pub fn skip(self: *Self, op: []const u8) !void { + const token = try self.lexer.pop(); + if (!token.is(op)) + return Error.UnexpectedToken; +} + +pub fn expect(self: *Self, tag: Token.Tag) !void { + try (try self.lexer.peek()).expect(tag); +} + +fn expr(self: *Self) !*Node { + try self.expect(.number); + return try Node.init(self.allocator, .number, try self.lexer.pop()); +} + +fn function(self: *Self) !*Node { + try self.skip("fn"); + + try self.expect(.word); + const node = try Node.init(self.allocator, .fndef, try self.lexer.pop()); + errdefer node.deinit(self.allocator); + + try self.skip("("); + node.left = null; + try self.skip(")"); + + node.right = try self.expr(); + try self.skip(";"); + return node; +} + pub fn parse(self: *Self) !?*Node { - var root = Node{ .token = undefined }; - var cur = &root.next; + var root = Node.stub; + var cur = &root; - while (!self.lexer.empty()) { - cur.* = try Node.init(self.allocator, self.lexer); - cur = &cur.*.?.next; - } + while (!self.lexer.empty()) + cur = cur.chainRight(try self.function()); - return root.next; + return root.right; } diff --git a/src/Token.zig b/src/Token.zig index 8256664..1357776 100644 --- a/src/Token.zig +++ b/src/Token.zig @@ -17,6 +17,10 @@ pub const Tag = enum { string, }; +pub const Error = error{ + ExpectedTagNotMatch, +}; + pub fn init(tag: Tag, s: []const u8, x: usize, y: usize) Self { return Self{ .tag = tag, @@ -26,6 +30,15 @@ pub fn init(tag: Tag, s: []const u8, x: usize, y: usize) Self { }; } +pub fn is(self: Self, s: []const u8) bool { + return std.mem.eql(u8, self.s, s); +} + +pub fn expect(self: Self, tag: Tag) !void { + if (self.tag != tag) + return Error.ExpectedTagNotMatch; +} + pub fn format( self: Self, comptime _: []const u8, @@ -1,18 +1 @@ -@import("std.o7"); - -mut x = 25; # commentaire -mut y = x * x + (8 - 2); -let zied = golem("large"); -let doc = @as(Prof, zied); - -pub fn main(argv: [][]u8) i32 { - var lol: i32 = 5 + 2; - std~io~puts $ "Hello, World!"; - let file = std~io~open $ "file.txt", "rb"; - defer file:std~io~close(); - let content = file:std~io~read(); -} - -fn span(s: [*]u8) []u8 { - return @slice(s, std~string~len(s)); -} +fn main() 0; |