Add Function Literal Syntax to Ona Script #39
| @ -6,6 +6,8 @@ let pr = lambda (str): | |||||||
| 	@print(str) | 	@print(str) | ||||||
| end | end | ||||||
| 
 | 
 | ||||||
|  | pr("eeee") | ||||||
|  | 
 | ||||||
| while i < 5: | while i < 5: | ||||||
| 	pr("hello, world") | 	pr("hello, world") | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -18,6 +18,7 @@ pub const RuntimeEnv = struct { | |||||||
| 	const Chunk = struct { | 	const Chunk = struct { | ||||||
| 		env: *RuntimeEnv, | 		env: *RuntimeEnv, | ||||||
| 		name: []coral.io.Byte, | 		name: []coral.io.Byte, | ||||||
|  | 		arity: u8, | ||||||
| 		opcodes: OpcodeList, | 		opcodes: OpcodeList, | ||||||
| 		constants: ConstList, | 		constants: ConstList, | ||||||
| 
 | 
 | ||||||
| @ -141,11 +142,15 @@ pub const RuntimeEnv = struct { | |||||||
| 					}, | 					}, | ||||||
| 
 | 
 | ||||||
| 					.lambda_literal => |literal| { | 					.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; | 							return error.OutOfMemory; | ||||||
| 						} | 						} | ||||||
| 
 | 
 | ||||||
| 						var lambda_chunk = try Chunk.make(chunk.env, "<lambda>"); | 						var lambda_chunk = try Chunk.make( | ||||||
|  | 							chunk.env, | ||||||
|  | 							"<lambda>", | ||||||
|  | 							@intCast(literal.argument_identifiers.values.len), | ||||||
|  | 						); | ||||||
| 
 | 
 | ||||||
| 						errdefer lambda_chunk.free(); | 						errdefer lambda_chunk.free(); | ||||||
| 
 | 
 | ||||||
| @ -982,11 +987,12 @@ pub const RuntimeEnv = struct { | |||||||
| 			self.env.allocator.deallocate(self.name); | 			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 .{ | 			return .{ | ||||||
| 				.name = try coral.io.allocate_copy(env.allocator, name), | 				.name = try coral.io.allocate_copy(env.allocator, name), | ||||||
| 				.opcodes = OpcodeList.make(env.allocator), | 				.opcodes = OpcodeList.make(env.allocator), | ||||||
| 				.constants = ConstList.make(env.allocator), | 				.constants = ConstList.make(env.allocator), | ||||||
|  | 				.arity = arity, | ||||||
| 				.env = env, | 				.env = env, | ||||||
| 			}; | 			}; | ||||||
| 		} | 		} | ||||||
| @ -996,7 +1002,13 @@ pub const RuntimeEnv = struct { | |||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		fn typeinfo_call(method: Typeinfo.Method) RuntimeError!?*RuntimeRef { | 		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 { | 		fn typeinfo_destruct(method: Typeinfo.Method) void { | ||||||
| @ -1122,7 +1134,6 @@ pub const RuntimeEnv = struct { | |||||||
| 				method.env.discard(replaced.value); | 				method.env.discard(replaced.value); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 |  | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 	pub fn acquire(self: *RuntimeEnv, value: *const RuntimeRef) RuntimeError!*RuntimeRef { | 	pub fn acquire(self: *RuntimeEnv, value: *const RuntimeRef) RuntimeError!*RuntimeRef { | ||||||
| @ -1147,16 +1158,6 @@ pub const RuntimeEnv = struct { | |||||||
| 		return null; | 		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 { | 	pub fn call(self: *RuntimeEnv, callable: *RuntimeRef, args: []const *RuntimeRef) RuntimeError!?*RuntimeRef { | ||||||
| 		try self.locals.push_all(args); | 		try self.locals.push_all(args); | ||||||
| 
 | 
 | ||||||
| @ -1222,7 +1223,7 @@ pub const RuntimeEnv = struct { | |||||||
| 		defer self.allocator.deallocate(file_data); | 		defer self.allocator.deallocate(file_data); | ||||||
| 
 | 
 | ||||||
| 		const file_name = file_path.to_string() orelse "<script>"; | 		const file_name = file_path.to_string() orelse "<script>"; | ||||||
| 		var chunk = try Chunk.make(self, file_name); | 		var chunk = try Chunk.make(self, file_name, 0); | ||||||
| 
 | 
 | ||||||
| 		defer chunk.free(); | 		defer chunk.free(); | ||||||
| 
 | 
 | ||||||
| @ -1539,6 +1540,12 @@ pub const RuntimeEnv = struct { | |||||||
| 			else => env.raise(error.TypeMismatch, "expected symbol object") | 			else => env.raise(error.TypeMismatch, "expected symbol object") | ||||||
| 		}; | 		}; | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	pub fn view_args(self: *RuntimeEnv) RuntimeError![]const ?*const RuntimeRef { | ||||||
|  | 		const frame = self.frames.peek() orelse return self.raise(error.IllegalState, "stack underflow"); | ||||||
|  | 
 | ||||||
|  | 		return self.locals.values[(frame.locals_top - frame.arg_count) ..]; | ||||||
|  | 	} | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| pub const RuntimeError = coral.io.AllocationError || error { | pub const RuntimeError = coral.io.AllocationError || error { | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user