Add argument resolving to functions
This commit is contained in:
		
							parent
							
								
									f5ed4bbcad
								
							
						
					
					
						commit
						b9f03b34c1
					
				| @ -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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user