Add Vector Types to Ona Script #34
| @ -1,7 +1,7 @@ | ||||
| 
 | ||||
| # Test comment. | ||||
| 
 | ||||
| pos = [10, 20, 0.3] | ||||
| pos = @vec3(10, 20, 0.3) | ||||
| 
 | ||||
| options = { | ||||
| 	.title = "Afterglow", | ||||
|  | ||||
| @ -24,6 +24,8 @@ pub const RuntimeEnv = struct { | ||||
| 		const Builtin = enum { | ||||
| 			import, | ||||
| 			print, | ||||
| 			vec2, | ||||
| 			vec3, | ||||
| 		}; | ||||
| 
 | ||||
| 		const Constant = union (enum) { | ||||
| @ -110,19 +112,6 @@ pub const RuntimeEnv = struct { | ||||
| 						}); | ||||
| 					}, | ||||
| 
 | ||||
| 					.vector2_literal => |literal| { | ||||
| 						try self.compile_expression(chunk, literal.y_expression.*); | ||||
| 						try self.compile_expression(chunk, literal.x_expression.*); | ||||
| 						try chunk.opcodes.push_one(.push_vector2); | ||||
| 					}, | ||||
| 
 | ||||
| 					.vector3_literal => |literal| { | ||||
| 						try self.compile_expression(chunk, literal.z_expression.*); | ||||
| 						try self.compile_expression(chunk, literal.y_expression.*); | ||||
| 						try self.compile_expression(chunk, literal.x_expression.*); | ||||
| 						try chunk.opcodes.push_one(.push_vector3); | ||||
| 					}, | ||||
| 
 | ||||
| 					.table_literal => |fields| { | ||||
| 						if (fields.values.len > coral.math.max_int(@typeInfo(u32).Int)) { | ||||
| 							return error.OutOfMemory; | ||||
| @ -182,15 +171,33 @@ pub const RuntimeEnv = struct { | ||||
| 					.builtin => |builtin| { | ||||
| 						coral.debug.assert(builtin.len != 0); | ||||
| 
 | ||||
| 						const decoded_builtin = @as(?Builtin, switch (builtin[0]) { | ||||
| 							'i' => if (coral.io.ends_with(builtin, "mport")) .import else null, | ||||
| 							'p' => if (coral.io.ends_with(builtin, "rint")) .print else null, | ||||
| 							else => null, | ||||
| 						}); | ||||
| 						switch (builtin[0]) { | ||||
| 							'i' => { | ||||
| 								if (coral.io.ends_with(builtin, "mport")) { | ||||
| 									return chunk.opcodes.push_one(.{.push_builtin = .import}); | ||||
| 								} | ||||
| 							}, | ||||
| 
 | ||||
| 						try chunk.opcodes.push_one(.{.push_builtin = decoded_builtin orelse { | ||||
| 							return chunk.env.raise(error.BadSyntax, "unknown builtin"); | ||||
| 						}}); | ||||
| 							'p' => { | ||||
| 								if (coral.io.ends_with(builtin, "rint")) { | ||||
| 									return chunk.opcodes.push_one(.{.push_builtin = .print}); | ||||
| 								} | ||||
| 							}, | ||||
| 
 | ||||
| 							'v' => { | ||||
| 								if (coral.io.ends_with(builtin, "ec2")) { | ||||
| 									return chunk.opcodes.push_one(.{.push_builtin = .vec2}); | ||||
| 								} | ||||
| 
 | ||||
| 								if (coral.io.ends_with(builtin, "ec3")) { | ||||
| 									return chunk.opcodes.push_one(.{.push_builtin = .vec3}); | ||||
| 								} | ||||
| 							}, | ||||
| 
 | ||||
| 							else => {}, | ||||
| 						} | ||||
| 
 | ||||
| 						return chunk.env.raise(error.BadSyntax, "unknown builtin"); | ||||
| 					}, | ||||
| 
 | ||||
| 					.local_get => |local_get| { | ||||
| @ -417,6 +424,8 @@ pub const RuntimeEnv = struct { | ||||
| 						const builtin_syscall = try self.env.new_syscall(switch (push_builtin) { | ||||
| 							.import => syscall_import, | ||||
| 							.print => syscall_print, | ||||
| 							.vec2 => syscall_vec2, | ||||
| 							.vec3 => syscall_vec3, | ||||
| 						}); | ||||
| 
 | ||||
| 						errdefer self.env.discard(builtin_syscall); | ||||
| @ -990,7 +999,7 @@ pub const RuntimeEnv = struct { | ||||
| 		const frame = self.frames.peek() orelse return self.raise(error.IllegalState, "stack underflow"); | ||||
| 
 | ||||
| 		if (index < frame.arg_count) { | ||||
| 			if (self.locals.values[frame.locals_top - (1 + index)]) |local| { | ||||
| 			if (self.locals.values[(frame.locals_top - frame.arg_count) + index]) |local| { | ||||
| 				return self.acquire(local); | ||||
| 			} | ||||
| 		} | ||||
| @ -1566,3 +1575,43 @@ fn syscall_print(env: *RuntimeEnv) RuntimeError!?*RuntimeRef { | ||||
| 
 | ||||
| 	return null; | ||||
| } | ||||
| 
 | ||||
| fn syscall_vec2(env: *RuntimeEnv) RuntimeError!?*RuntimeRef { | ||||
| 	const x = decode: { | ||||
| 		const value = try env.expect(try env.acquire_arg(0)); | ||||
| 
 | ||||
| 		defer env.discard(value); | ||||
| 
 | ||||
| 		break: decode @as(f32, @floatCast(try env.unbox_float(value))); | ||||
| 	}; | ||||
| 
 | ||||
| 	if (try env.acquire_arg(1)) |y| { | ||||
| 		defer env.discard(y); | ||||
| 
 | ||||
| 		return env.new_vector2(x, @floatCast(try env.unbox_float(y))); | ||||
| 	} | ||||
| 
 | ||||
| 	return env.new_vector2(x, x); | ||||
| } | ||||
| 
 | ||||
| fn syscall_vec3(env: *RuntimeEnv) RuntimeError!?*RuntimeRef { | ||||
| 	const x = decode: { | ||||
| 		const value = try env.expect(try env.acquire_arg(0)); | ||||
| 
 | ||||
| 		defer env.discard(value); | ||||
| 
 | ||||
| 		break: decode @as(f32, @floatCast(try env.unbox_float(value))); | ||||
| 	}; | ||||
| 
 | ||||
| 	if (try env.acquire_arg(1)) |y| { | ||||
| 		defer env.discard(y); | ||||
| 
 | ||||
| 		const z = try env.expect(try env.acquire_arg(2)); | ||||
| 
 | ||||
| 		defer env.discard(z); | ||||
| 
 | ||||
| 		return env.new_vector3(x, @floatCast(try env.unbox_float(y)), @floatCast(try env.unbox_float(z))); | ||||
| 	} | ||||
| 
 | ||||
| 	return env.new_vector3(x, x, x); | ||||
| } | ||||
|  | ||||
| @ -60,17 +60,6 @@ pub const Expression = union (enum) { | ||||
| 		argument_expressions: List, | ||||
| 	}, | ||||
| 
 | ||||
| 	vector2_literal: struct { | ||||
| 		x_expression: *Expression, | ||||
| 		y_expression: *Expression, | ||||
| 	}, | ||||
| 
 | ||||
| 	vector3_literal: struct { | ||||
| 		x_expression: *Expression, | ||||
| 		y_expression: *Expression, | ||||
| 		z_expression: *Expression, | ||||
| 	}, | ||||
| 
 | ||||
| 	pub const BinaryOperator = enum { | ||||
| 		addition, | ||||
| 		subtraction, | ||||
| @ -368,57 +357,6 @@ fn parse_factor(self: *Self) ParseError!Expression { | ||||
| 				break: parse .{.builtin = builtin}; | ||||
| 			}, | ||||
| 
 | ||||
| 			.symbol_bracket_left => { | ||||
| 				self.tokenizer.skip_newlines(); | ||||
| 
 | ||||
| 				var expressions = [3]?*Expression{null, null, null}; | ||||
| 				var size = @as(u2, 0); | ||||
| 
 | ||||
| 				while (true) { | ||||
| 					if (size == expressions.len) { | ||||
| 						return self.report("vector literals cannot contain more than 3 elements"); | ||||
| 					} | ||||
| 
 | ||||
| 					expressions[size] = try coral.io.allocate_one(allocator, try self.parse_expression()); | ||||
| 					size += 1; | ||||
| 
 | ||||
| 					switch (self.tokenizer.token) { | ||||
| 						.symbol_comma => { | ||||
| 							self.tokenizer.skip_newlines(); | ||||
| 
 | ||||
| 							continue; | ||||
| 						}, | ||||
| 
 | ||||
| 						.symbol_bracket_right => { | ||||
| 							self.tokenizer.skip_newlines(); | ||||
| 
 | ||||
| 							break; | ||||
| 						}, | ||||
| 
 | ||||
| 						else => return self.report("expected `,` or `]` after vector literal element expression"), | ||||
| 					} | ||||
| 				} | ||||
| 
 | ||||
| 				break: parse switch (size) { | ||||
| 					0, 1 => return self.report("vector literals must contain at least 2 elements"), | ||||
| 
 | ||||
| 					2 => .{ | ||||
| 						.vector2_literal = .{ | ||||
| 							.x_expression = expressions[0] orelse unreachable, | ||||
| 							.y_expression = expressions[1] orelse unreachable, | ||||
| 						}, | ||||
| 					}, | ||||
| 
 | ||||
| 					3 => .{ | ||||
| 						.vector3_literal = .{ | ||||
| 							.x_expression = expressions[0] orelse unreachable, | ||||
| 							.y_expression = expressions[1] orelse unreachable, | ||||
| 							.z_expression = expressions[2] orelse unreachable, | ||||
| 						}, | ||||
| 					}, | ||||
| 				}; | ||||
| 			}, | ||||
| 
 | ||||
| 			.symbol_brace_left => { | ||||
| 				var table_literal = Expression.TableLiteral.make(allocator); | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user