From 5c08a1b63ef326210702cf74ce0b2379d009688a Mon Sep 17 00:00:00 2001 From: kayomn Date: Sat, 26 Aug 2023 21:30:36 +0100 Subject: [PATCH] Add lambda argument arity checking to runtime --- debug/app.ona | 2 ++ source/ona/kym.zig | 39 +++++++++++++++++++++++---------------- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/debug/app.ona b/debug/app.ona index dddd91f..855cf63 100644 --- a/debug/app.ona +++ b/debug/app.ona @@ -6,6 +6,8 @@ let pr = lambda (str): @print(str) end +pr("eeee") + while i < 5: pr("hello, world") diff --git a/source/ona/kym.zig b/source/ona/kym.zig index 2a865c8..1a34fc1 100644 --- a/source/ona/kym.zig +++ b/source/ona/kym.zig @@ -18,6 +18,7 @@ pub const RuntimeEnv = struct { const Chunk = struct { env: *RuntimeEnv, name: []coral.io.Byte, + arity: u8, opcodes: OpcodeList, constants: ConstList, @@ -141,11 +142,15 @@ pub const RuntimeEnv = struct { }, .lambda_literal => |literal| { - if (literal.argument_identifiers.values.len > coral.math.max_int(@typeInfo(u32).Int)) { + if (literal.argument_identifiers.values.len > coral.math.max_int(@typeInfo(u8).Int)) { return error.OutOfMemory; } - var lambda_chunk = try Chunk.make(chunk.env, ""); + var lambda_chunk = try Chunk.make( + chunk.env, + "", + @intCast(literal.argument_identifiers.values.len), + ); errdefer lambda_chunk.free(); @@ -982,11 +987,12 @@ pub const RuntimeEnv = struct { self.env.allocator.deallocate(self.name); } - fn make(env: *RuntimeEnv, name: []const coral.io.Byte) coral.io.AllocationError!Chunk { + fn make(env: *RuntimeEnv, name: []const coral.io.Byte, arity: u8) coral.io.AllocationError!Chunk { return .{ .name = try coral.io.allocate_copy(env.allocator, name), .opcodes = OpcodeList.make(env.allocator), .constants = ConstList.make(env.allocator), + .arity = arity, .env = env, }; } @@ -996,7 +1002,13 @@ pub const RuntimeEnv = struct { } fn typeinfo_call(method: Typeinfo.Method) RuntimeError!?*RuntimeRef { - return @as(*Chunk, @ptrCast(@alignCast(method.userdata))).execute(); + const chunk = @as(*Chunk, @ptrCast(@alignCast(method.userdata))); + + if ((method.env.view_args() catch unreachable).len < chunk.arity) { + return method.env.raise(error.BadOperation, "expected more arguments"); + } + + return chunk.execute(); } fn typeinfo_destruct(method: Typeinfo.Method) void { @@ -1122,7 +1134,6 @@ pub const RuntimeEnv = struct { method.env.discard(replaced.value); } } - }; pub fn acquire(self: *RuntimeEnv, value: *const RuntimeRef) RuntimeError!*RuntimeRef { @@ -1147,16 +1158,6 @@ pub const RuntimeEnv = struct { return null; } - pub fn acquire_args(self: *RuntimeEnv) RuntimeError!*RuntimeRef { - const frame = self.frames.peek() orelse return self.raise(error.IllegalState, "stack underflow"); - - _ = frame; - - const args_table = self.new_table(); - - return args_table; - } - pub fn call(self: *RuntimeEnv, callable: *RuntimeRef, args: []const *RuntimeRef) RuntimeError!?*RuntimeRef { try self.locals.push_all(args); @@ -1222,7 +1223,7 @@ pub const RuntimeEnv = struct { defer self.allocator.deallocate(file_data); const file_name = file_path.to_string() orelse "