summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkdx <kikoodx@paranoici.org>2024-03-19 13:42:20 +0100
committerkdx <kikoodx@paranoici.org>2024-03-19 13:42:20 +0100
commit2f9e4f9dc6472af059b740513ebb3ca04cc0bc44 (patch)
tree43ba4881b3acd55585c16a2c1903c837170d7273
parentffea8259f2cda681c3c14bbb4b09f6d0a39b291f (diff)
downloado7z-2f9e4f9dc6472af059b740513ebb3ca04cc0bc44.tar.gz
dumbest function
-rw-r--r--src/Node.zig44
-rw-r--r--src/Parser.zig48
-rw-r--r--src/Token.zig13
-rw-r--r--test.o719
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,
diff --git a/test.o7 b/test.o7
index cb95ab4..6c06e3c 100644
--- a/test.o7
+++ b/test.o7
@@ -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;