Compare commits

..

2 Commits

Author SHA1 Message Date
374a221e94 remove funcs for now
All checks were successful
Run unit tests / zig build test (push) Successful in 33s
2026-01-23 20:16:19 +01:00
a42770f4cc fix test
All checks were successful
Run unit tests / zig build test (push) Successful in 31s
2026-01-23 20:07:24 +01:00
4 changed files with 31 additions and 75 deletions

View File

@@ -1,3 +1 @@
(func main [] {
(print_int (+ 1 (* 2 34)))
})
(print_int (+ 1 (* 2 34)))

View File

@@ -6,17 +6,9 @@ pub const Interpreter = struct {
stdout: *std.Io.Writer,
pub fn interpret(self: @This(), program: parser.Program) !void {
const main = for (program.funcs) |func| {
if (std.mem.eql(u8, func.name, "main")) break func;
} else return error.NoMain;
try self.run_func(main);
try self.stdout.flush();
}
fn run_func(self: @This(), func: parser.Func) !void {
for (func.body) |stmt| {
for (program.stmts) |stmt| {
try self.run_stmt(stmt);
try self.stdout.flush();
}
}

View File

@@ -81,40 +81,7 @@ fn parse_sexprs(gpa: std.mem.Allocator, tokens: []const lexer.Token) ![]const SE
}
pub const Program = struct {
funcs: []const Func,
};
pub const Func = struct {
name: []const u8,
args: []const []const u8,
body: []const Stmt,
fn from(gpa: std.mem.Allocator, sexpr: SExpr) !Func {
if (sexpr != .call or sexpr.call.len != 4) {
return error.InvalidFunc;
}
const call = sexpr.call;
if (call[0] != .identifier or !std.mem.eql(u8, call[0].identifier, "func") or call[1] != .identifier) {
return error.InvalidFunc;
}
if (call[2] != .list or call[3] != .block) {
return error.InvalidFunc;
}
var args = std.ArrayList([]const u8).empty;
for (call[2].list) |arg| {
if (arg != .identifier) return error.InvalidFuncArg;
try args.append(gpa, arg.identifier);
}
var body = std.ArrayList(Stmt).empty;
for (call[3].block) |inner| {
try body.append(gpa, try Stmt.from(gpa, inner));
}
return Func{
.name = call[1].identifier,
.args = try args.toOwnedSlice(gpa),
.body = try body.toOwnedSlice(gpa),
};
}
stmts: []const Stmt,
};
pub const Stmt = union(enum) {
@@ -218,12 +185,12 @@ pub const Expr = union(enum) {
pub fn parse(gpa: std.mem.Allocator, tokens: []const lexer.Token) !Program {
const sexprs = try parse_sexprs(gpa, tokens);
var funcs = std.ArrayList(Func).empty;
var stmts = std.ArrayList(Stmt).empty;
for (sexprs) |sexpr| {
const func = try Func.from(gpa, sexpr);
try funcs.append(gpa, func);
const stmt = try Stmt.from(gpa, sexpr);
try stmts.append(gpa, stmt);
}
return Program{
.funcs = try funcs.toOwnedSlice(gpa),
.stmts = try stmts.toOwnedSlice(gpa),
};
}

View File

@@ -3,50 +3,49 @@ const t = std.testing;
const lib = @import("libneon");
test "large tree" {
test "program" {
var arena = std.heap.ArenaAllocator.init(t.allocator);
defer arena.deinit();
const gpa = arena.allocator();
try t.expectEqualDeep(
&[_]lib.parser.SExpr{
.{ .call = &.{
.{ .identifier = "foo" },
.{ .identifier = "bar" },
.{ .string = "baz" },
.{ .list = &.{
.{ .integer = 1 },
.{ .integer = 2 },
.{ .integer = 3 },
} },
.{ .block = &.{} },
} },
lib.parser.Program{
.stmts = &.{
.{ .expr = .{ .func_call = .{ .name = "foo", .args = &.{
.{ .variable = "bar" },
.{ .string = "baz" },
.{ .func_call = .{ .name = "+", .args = &.{
.{ .integer = 1 },
.{ .integer = 2 },
} } },
} } } },
},
},
try lib.parser.parse_sexprs(gpa, &.{
try lib.parser.parse(gpa, &.{
.lparen,
.{ .identifier = "foo" },
.{ .identifier = "bar" },
.{ .string = "baz" },
.lbracket,
.lparen,
.{ .identifier = "+" },
.{ .integer = 1 },
.{ .integer = 2 },
.{ .integer = 3 },
.rbracket,
.lbrace,
.rbrace,
.rparen,
.rparen,
}),
);
}
test "empty" {
test "empty program" {
var arena = std.heap.ArenaAllocator.init(t.allocator);
defer arena.deinit();
const gpa = arena.allocator();
try t.expectEqualDeep(
&.{},
lib.parser.parse_sexprs(gpa, &.{}),
lib.parser.Program{
.stmts = &.{},
},
lib.parser.parse(gpa, &.{}),
);
}
@@ -57,7 +56,7 @@ test "unmatched delimiters" {
try t.expectError(
error.UnmatchedParen,
lib.parser.parse_sexprs(gpa, &.{
lib.parser.parse(gpa, &.{
.lbracket,
.{ .integer = 34 },
.lparen,
@@ -67,7 +66,7 @@ test "unmatched delimiters" {
try t.expectError(
error.UnmatchedBracket,
lib.parser.parse_sexprs(gpa, &.{
lib.parser.parse(gpa, &.{
.lparen,
.{ .integer = 34 },
.lbracket,