diff --git a/debug/app.ona b/debug/app.ona index abf72fa..dddd91f 100644 --- a/debug/app.ona +++ b/debug/app.ona @@ -1,8 +1,9 @@ var i = 0 -let pr = lambda (): - @print("foo") +let pr = lambda (str): + @print("This is a func call") + @print(str) end while i < 5: diff --git a/source/ona/kym.zig b/source/ona/kym.zig index 30b82cc..2a865c8 100644 --- a/source/ona/kym.zig +++ b/source/ona/kym.zig @@ -43,6 +43,7 @@ pub const RuntimeEnv = struct { push_false, push_const: u16, push_local: u8, + push_arg: u8, push_table: u32, push_builtin: Builtin, local_set: u8, @@ -71,6 +72,7 @@ pub const RuntimeEnv = struct { const OpcodeList = coral.list.Stack(Opcode); const CompilationUnit = struct { + args: []const []const coral.io.Byte, locals_buffer: [255]Local = [_]Local{.{}} ** 255, locals_count: u8 = 0, @@ -147,7 +149,7 @@ pub const RuntimeEnv = struct { 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(.{ .push_const = try chunk.declare_constant(.{ @@ -232,11 +234,15 @@ pub const RuntimeEnv = struct { }, .local_get => |local_get| { - try chunk.opcodes.push_one(.{ - .push_local = (self.resolve_local(local_get.identifier) orelse { - return chunk.env.raise(error.OutOfMemory, "undefined local"); - }).index, - }); + if (self.resolve_local(local_get.identifier)) |local| { + return chunk.opcodes.push_one(.{.push_local = 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| { @@ -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 { if (self.locals_count == 0) { return null; @@ -391,8 +409,8 @@ pub const RuntimeEnv = struct { } }; - fn compile(self: *Chunk, statements: []const ast.Statement) RuntimeError!void { - var unit = CompilationUnit{}; + fn compile(self: *Chunk, statements: []const ast.Statement, args: []const []const coral.io.Byte) RuntimeError!void { + var unit = CompilationUnit{.args = args}; var has_returned = false; 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| { 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) { error.BadSyntax => self.raise(error.BadSyntax, ast_tree.error_message()), error.OutOfMemory => error.OutOfMemory, - }); + }, &.{}); try self.frames.push_one(.{ .name = file_name,