Add Function Literal Syntax to Ona Script #39
|
@ -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:
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue