http server

This commit is contained in:
agra
2026-02-17 16:57:12 +02:00
parent 66034b4fec
commit 4fd87309d9
17 changed files with 437 additions and 113 deletions

View File

@@ -62,19 +62,6 @@ pub const Parser = struct {
return try self.createNode(start, .{ .import_decl = .{ .path = path, .name = null } });
}
// Top-level #library directive: #library "libname";
if (self.current.tag == .hash_library) {
self.advance();
if (self.current.tag != .string_literal) {
return self.fail("expected string after '#library'");
}
const raw = self.tokenSlice(self.current);
const lib_name = raw[1 .. raw.len - 1];
self.advance();
try self.expect(.semicolon);
return try self.createNode(start, .{ .library_decl = .{ .lib_name = lib_name } });
}
// Top-level #run directive
if (self.current.tag == .hash_run) {
self.advance();
@@ -131,6 +118,19 @@ pub const Parser = struct {
return try self.createNode(start_pos, .{ .import_decl = .{ .path = path, .name = name } });
}
// Named library: name :: #library "libname";
if (self.current.tag == .hash_library) {
self.advance();
if (self.current.tag != .string_literal) {
return self.fail("expected string after '#library'");
}
const raw = self.tokenSlice(self.current);
const lib_name = raw[1 .. raw.len - 1];
self.advance();
try self.expect(.semicolon);
return try self.createNode(start_pos, .{ .library_decl = .{ .lib_name = lib_name, .name = name } });
}
// Compile-time evaluation: name :: #run expr;
if (self.current.tag == .hash_run) {
const run_start = self.current.loc.start;
@@ -192,12 +192,27 @@ pub const Parser = struct {
return try self.createNode(start_pos, .{ .const_decl = .{ .name = name, .type_annotation = value, .value = bi } });
}
// name :: type_expr #foreign; — foreign with type annotation
// name :: type_expr #foreign lib ["c_name"]; — foreign with type annotation
if (self.current.tag == .hash_foreign) {
const fi_start = self.current.loc.start;
self.advance();
// Required: library reference (identifier)
if (self.current.tag != .identifier)
return self.fail("expected library name after '#foreign'");
const lib_ref = self.tokenSlice(self.current);
self.advance();
// Optional: C symbol name (string literal)
var c_name: ?[]const u8 = null;
if (self.current.tag == .string_literal) {
const raw = self.tokenSlice(self.current);
c_name = raw[1 .. raw.len - 1];
self.advance();
}
try self.expect(.semicolon);
const fi = try self.createNode(fi_start, .{ .foreign_expr = {} });
const fi = try self.createNode(fi_start, .{ .foreign_expr = .{
.library_ref = lib_ref,
.c_name = c_name,
} });
return try self.createNode(start_pos, .{ .const_decl = .{ .name = name, .type_annotation = value, .value = fi } });
}
@@ -754,8 +769,23 @@ pub const Parser = struct {
} else if (self.current.tag == .hash_foreign) blk: {
const fi_start = self.current.loc.start;
self.advance();
// Required: library reference (identifier)
if (self.current.tag != .identifier)
return self.fail("expected library name after '#foreign'");
const lib_ref = self.tokenSlice(self.current);
self.advance();
// Optional: C symbol name (string literal)
var c_name: ?[]const u8 = null;
if (self.current.tag == .string_literal) {
const raw = self.tokenSlice(self.current);
c_name = raw[1 .. raw.len - 1];
self.advance();
}
try self.expect(.semicolon);
break :blk try self.createNode(fi_start, .{ .foreign_expr = {} });
break :blk try self.createNode(fi_start, .{ .foreign_expr = .{
.library_ref = lib_ref,
.c_name = c_name,
} });
} else if (self.current.tag == .fat_arrow) blk: {
is_arrow = true;
self.advance();
@@ -1826,7 +1856,7 @@ test "parse namespaced import" {
}
test "parse library declaration" {
const source = "#library \"raylib\";";
const source = "rl :: #library \"raylib\";";
var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
defer arena.deinit();
var parser = Parser.init(arena.allocator(), source);
@@ -1835,6 +1865,7 @@ test "parse library declaration" {
const decl = root.data.root.decls[0];
try std.testing.expect(decl.data == .library_decl);
try std.testing.expectEqualStrings("raylib", decl.data.library_decl.lib_name);
try std.testing.expectEqualStrings("rl", decl.data.library_decl.name);
}
test "parse void function with builtin body" {
@@ -1851,7 +1882,7 @@ test "parse void function with builtin body" {
}
test "parse void function with foreign body" {
const source = "InitWindow :: (width: s32, height: s32, title: *u8) -> void #foreign;";
const source = "InitWindow :: (width: s32, height: s32, title: *u8) -> void #foreign rl;";
var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
defer arena.deinit();
var parser = Parser.init(arena.allocator(), source);
@@ -1861,6 +1892,7 @@ test "parse void function with foreign body" {
try std.testing.expect(decl.data == .fn_decl);
try std.testing.expectEqualStrings("InitWindow", decl.data.fn_decl.name);
try std.testing.expect(decl.data.fn_decl.body.data == .foreign_expr);
try std.testing.expectEqualStrings("rl", decl.data.fn_decl.body.data.foreign_expr.library_ref.?);
try std.testing.expectEqual(@as(usize, 3), decl.data.fn_decl.params.len);
}