Add Function Literal Syntax to Ona Script #39

Merged
kayomn merged 5 commits from kym-functions into main 2023-09-02 21:15:28 +02:00
2 changed files with 42 additions and 11 deletions
Showing only changes of commit b9f03b34c1 - Show all commits

View File

@ -1,8 +1,9 @@
var i = 0 var i = 0
let pr = lambda (): let pr = lambda (str):
@print("foo") @print("This is a func call")
@print(str)
end end
while i < 5: while i < 5:

View File

@ -43,6 +43,7 @@ pub const RuntimeEnv = struct {
push_false, push_false,
push_const: u16, push_const: u16,
push_local: u8, push_local: u8,
push_arg: u8,
push_table: u32, push_table: u32,
push_builtin: Builtin, push_builtin: Builtin,
local_set: u8, local_set: u8,
@ -71,6 +72,7 @@ pub const RuntimeEnv = struct {
const OpcodeList = coral.list.Stack(Opcode); const OpcodeList = coral.list.Stack(Opcode);
const CompilationUnit = struct { const CompilationUnit = struct {
args: []const []const coral.io.Byte,
locals_buffer: [255]Local = [_]Local{.{}} ** 255, locals_buffer: [255]Local = [_]Local{.{}} ** 255,
locals_count: u8 = 0, locals_count: u8 = 0,
@ -147,7 +149,7 @@ pub const RuntimeEnv = struct {
errdefer lambda_chunk.free(); errdefer lambda_chunk.free();
try lambda_chunk.compile(literal.block_statements.values); try lambda_chunk.compile(literal.block_statements.values, literal.argument_identifiers.values);
try chunk.opcodes.push_one(.{ try chunk.opcodes.push_one(.{
.push_const = try chunk.declare_constant(.{ .push_const = try chunk.declare_constant(.{
@ -232,11 +234,15 @@ pub const RuntimeEnv = struct {
}, },
.local_get => |local_get| { .local_get => |local_get| {
try chunk.opcodes.push_one(.{ if (self.resolve_local(local_get.identifier)) |local| {
.push_local = (self.resolve_local(local_get.identifier) orelse { return chunk.opcodes.push_one(.{.push_local = local.index});
return chunk.env.raise(error.OutOfMemory, "undefined local"); }
}).index,
}); if (self.resolve_arg(local_get.identifier)) |arg| {
return chunk.opcodes.push_one(.{.push_arg = arg});
}
return chunk.env.raise(error.OutOfMemory, "undefined local");
}, },
.local_set => |local_set| { .local_set => |local_set| {
@ -367,6 +373,18 @@ pub const RuntimeEnv = struct {
} }
} }
fn resolve_arg(self: *CompilationUnit, arg_identifier: []const coral.io.Byte) ?u8 {
var index = @as(u8, 0);
while (index < self.args.len) {
if (coral.io.are_equal(self.args[index], arg_identifier)) {
return index;
}
}
return null;
}
fn resolve_local(self: *CompilationUnit, local_identifier: []const coral.io.Byte) ?ResolvedLocal { fn resolve_local(self: *CompilationUnit, local_identifier: []const coral.io.Byte) ?ResolvedLocal {
if (self.locals_count == 0) { if (self.locals_count == 0) {
return null; return null;
@ -391,8 +409,8 @@ pub const RuntimeEnv = struct {
} }
}; };
fn compile(self: *Chunk, statements: []const ast.Statement) RuntimeError!void { fn compile(self: *Chunk, statements: []const ast.Statement, args: []const []const coral.io.Byte) RuntimeError!void {
var unit = CompilationUnit{}; var unit = CompilationUnit{.args = args};
var has_returned = false; var has_returned = false;
for (statements) |statement| { for (statements) |statement| {
@ -468,6 +486,18 @@ pub const RuntimeEnv = struct {
} }
}, },
.push_arg => |push_arg| {
const arg = try self.env.acquire_arg(push_arg);
errdefer {
if (arg) |ref| {
self.env.discard(ref);
}
}
try self.env.locals.push_one(arg);
},
.push_table => |push_table| { .push_table => |push_table| {
const table = try self.env.new_table(); const table = try self.env.new_table();
@ -1203,7 +1233,7 @@ pub const RuntimeEnv = struct {
try chunk.compile(ast_tree.parse(file_data) catch |parse_error| return switch (parse_error) { try chunk.compile(ast_tree.parse(file_data) catch |parse_error| return switch (parse_error) {
error.BadSyntax => self.raise(error.BadSyntax, ast_tree.error_message()), error.BadSyntax => self.raise(error.BadSyntax, ast_tree.error_message()),
error.OutOfMemory => error.OutOfMemory, error.OutOfMemory => error.OutOfMemory,
}); }, &.{});
try self.frames.push_one(.{ try self.frames.push_one(.{
.name = file_name, .name = file_name,