Merge pull request 'Add Vector Types to Ona Script' (#34) from kym-vector-types into main
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				continuous-integration/drone/push Build is passing
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	continuous-integration/drone/push Build is passing
				
			Reviewed-on: #34
This commit is contained in:
		
						commit
						d2490bc90d
					
				| @ -1,6 +1,8 @@ | ||||
| 
 | ||||
| # Test comment. | ||||
| 
 | ||||
| pos = @vec3(10, 20, 0.3) | ||||
| 
 | ||||
| options = { | ||||
| 	.title = "Afterglow", | ||||
| 	.width = 1280, | ||||
|  | ||||
| @ -207,6 +207,16 @@ pub fn Tag(comptime Element: type) type { | ||||
| 
 | ||||
| pub const Writer = Generator(?usize, []const Byte); | ||||
| 
 | ||||
| pub fn all_equals(target: []const Byte, match: Byte) bool { | ||||
| 	for (0 .. target.len) |index| { | ||||
| 		if (target[index] != match) { | ||||
| 			return false; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return true; | ||||
| } | ||||
| 
 | ||||
| pub fn allocate_copy(allocator: Allocator, source: []const Byte) AllocationError![]Byte { | ||||
| 	const allocation = try allocator.actions.reallocate(allocator.context, @returnAddress(), null, source.len); | ||||
| 
 | ||||
| @ -265,6 +275,20 @@ pub fn allocate_string(allocator: Allocator, source: []const Byte) AllocationErr | ||||
| 	return @ptrCast(allocation); | ||||
| } | ||||
| 
 | ||||
| pub fn are_equal(target: []const Byte, match: []const Byte) bool { | ||||
| 	if (target.len != match.len) { | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	for (0 .. target.len) |index| { | ||||
| 		if (target[index] != match[index]) { | ||||
| 			return false; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return true; | ||||
| } | ||||
| 
 | ||||
| pub fn bytes_of(value: anytype) []const Byte { | ||||
| 	const pointer_info = @typeInfo(@TypeOf(value)).Pointer; | ||||
| 
 | ||||
| @ -326,20 +350,6 @@ pub fn ends_with(target: []const Byte, match: []const Byte) bool { | ||||
| 	return true; | ||||
| } | ||||
| 
 | ||||
| pub fn equals(target: []const Byte, match: []const Byte) bool { | ||||
| 	if (target.len != match.len) { | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	for (0 .. target.len) |index| { | ||||
| 		if (target[index] != match[index]) { | ||||
| 			return false; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return true; | ||||
| } | ||||
| 
 | ||||
| pub fn find_first(haystack: []const Byte, needle: Byte) ?usize { | ||||
| 	for (0 .. haystack.len) |i| { | ||||
| 		if (haystack[i] == needle) { | ||||
| @ -350,15 +360,23 @@ pub fn find_first(haystack: []const Byte, needle: Byte) ?usize { | ||||
| 	return null; | ||||
| } | ||||
| 
 | ||||
| var null_context = @as(usize, 0); | ||||
| pub fn jenkins_hash(comptime int: std.builtin.Type.Int, bytes: []const Byte) math.Int(int) { | ||||
|     var hash = @as(math.Int(int), 0); | ||||
| 
 | ||||
| pub const null_writer = Writer.bind(usize, &null_context, struct { | ||||
| 	fn write(context: *usize, buffer: []const u8) ?usize { | ||||
| 		debug.assert(context.* == 0); | ||||
|     for (bytes) |byte| { | ||||
|         hash +%= byte; | ||||
|         hash +%= (hash << 10); | ||||
|         hash ^= (hash >> 6); | ||||
|     } | ||||
| 
 | ||||
| 		return buffer.len; | ||||
| 	} | ||||
| }.write); | ||||
|     hash +%= (hash << 3); | ||||
|     hash ^= (hash >> 11); | ||||
|     hash +%= (hash << 15); | ||||
| 
 | ||||
|     return hash; | ||||
| } | ||||
| 
 | ||||
| pub const null_writer = Writer.from(write_null); | ||||
| 
 | ||||
| pub fn slice_sentineled(comptime sen: anytype, ptr: [*:sen]const @TypeOf(sen)) [:sen]const @TypeOf(sen) { | ||||
|     var len = @as(usize, 0); | ||||
| @ -374,6 +392,10 @@ pub fn tag_of(comptime value: anytype) Tag(@TypeOf(value)) { | ||||
| 	return @as(Tag(@TypeOf(value)), value); | ||||
| } | ||||
| 
 | ||||
| pub fn write_null(buffer: []const u8) ?usize { | ||||
| 	return buffer.len; | ||||
| } | ||||
| 
 | ||||
| pub fn zero(target: []Byte) void { | ||||
| 	for (target) |*t| t.* = 0; | ||||
| } | ||||
|  | ||||
| @ -11,7 +11,7 @@ pub fn StringTable(comptime Value: type) type { | ||||
| 		const Self = @This(); | ||||
| 
 | ||||
| 		fn equals(key_a: []const io.Byte, key_b: []const io.Byte) bool { | ||||
| 			return io.equals(key_a, key_b); | ||||
| 			return io.are_equal(key_a, key_b); | ||||
| 		} | ||||
| 
 | ||||
| 		fn hash(key: []const io.Byte) usize { | ||||
|  | ||||
| @ -40,7 +40,7 @@ pub const DecimalFormat = struct { | ||||
| 						}, | ||||
| 
 | ||||
| 						else => { | ||||
| 							if (self.delimiter.len == 0 or !io.equals(self.delimiter, utf8[index ..])) { | ||||
| 							if (self.delimiter.len == 0 or !io.are_equal(self.delimiter, utf8[index ..])) { | ||||
| 								return null; | ||||
| 							} | ||||
| 						}, | ||||
|  | ||||
| @ -24,6 +24,8 @@ pub const RuntimeEnv = struct { | ||||
| 		const Builtin = enum { | ||||
| 			import, | ||||
| 			print, | ||||
| 			vec2, | ||||
| 			vec3, | ||||
| 		}; | ||||
| 
 | ||||
| 		const Constant = union (enum) { | ||||
| @ -167,15 +169,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| { | ||||
| @ -257,7 +277,7 @@ pub const RuntimeEnv = struct { | ||||
| 				var index = @as(u8, self.local_identifiers_count - 1); | ||||
| 
 | ||||
| 				while (true) : (index -= 1) { | ||||
| 					if (coral.io.equals(local_identifier, self.local_identifiers_buffer[index])) { | ||||
| 					if (coral.io.are_equal(local_identifier, self.local_identifiers_buffer[index])) { | ||||
| 						return index; | ||||
| 					} | ||||
| 
 | ||||
| @ -361,6 +381,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); | ||||
| @ -934,7 +956,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); | ||||
| 			} | ||||
| 		} | ||||
| @ -991,7 +1013,7 @@ pub const RuntimeEnv = struct { | ||||
| 
 | ||||
| 		if (object.ref_count == 0) { | ||||
| 			switch (object.payload) { | ||||
| 				.false, .true, .float, .fixed, .symbol, .syscall => {}, | ||||
| 				.false, .true, .float, .fixed, .symbol, .vector2, .vector3, .syscall => {}, | ||||
| 
 | ||||
| 				.string => |string| { | ||||
| 					coral.debug.assert(string.len >= 0); | ||||
| @ -1190,6 +1212,20 @@ pub const RuntimeEnv = struct { | ||||
| 		}); | ||||
| 	} | ||||
| 
 | ||||
| 	pub fn new_vector2(self: *RuntimeEnv, x: f32, y: f32) RuntimeError!*RuntimeRef { | ||||
| 		return RuntimeRef.allocate(self.allocator, .{ | ||||
| 			.ref_count = 1, | ||||
| 			.payload = .{.vector2 = .{x, y}}, | ||||
| 		}); | ||||
| 	} | ||||
| 
 | ||||
| 	pub fn new_vector3(self: *RuntimeEnv, x: f32, y: f32, z: f32) RuntimeError!*RuntimeRef { | ||||
| 		return RuntimeRef.allocate(self.allocator, .{ | ||||
| 			.ref_count = 1, | ||||
| 			.payload = .{.vector3 = .{x, y, z}}, | ||||
| 		}); | ||||
| 	} | ||||
| 
 | ||||
| 	pub fn print(self: *RuntimeEnv, buffer: []const coral.io.Byte) void { | ||||
| 		if (self.options.print) |bound_print| { | ||||
| 			bound_print(buffer); | ||||
| @ -1287,6 +1323,8 @@ pub const RuntimeRef = opaque { | ||||
| 			float: Float, | ||||
| 			fixed: Fixed, | ||||
| 			symbol: [*:0]const coral.io.Byte, | ||||
| 			vector2: [2]f32, | ||||
| 			vector3: [3]f32, | ||||
| 			syscall: *const Syscall, | ||||
| 
 | ||||
| 			string: struct { | ||||
| @ -1357,13 +1395,23 @@ pub const RuntimeRef = opaque { | ||||
| 				else => false, | ||||
| 			}, | ||||
| 
 | ||||
| 			.vector2 => |self_vector| switch (other.object().payload) { | ||||
| 				.vector2 => |other_vector| coral.io.are_equal(coral.io.bytes_of(&self_vector), coral.io.bytes_of(&other_vector)), | ||||
| 				else => false, | ||||
| 			}, | ||||
| 
 | ||||
| 			.vector3 => |self_vector| switch (other.object().payload) { | ||||
| 				.vector3 => |other_vector| coral.io.are_equal(coral.io.bytes_of(&self_vector), coral.io.bytes_of(&other_vector)), | ||||
| 				else => false, | ||||
| 			}, | ||||
| 
 | ||||
| 			.syscall => |self_syscall| switch (other.object().payload) { | ||||
| 				.syscall => |other_syscall| self_syscall == other_syscall, | ||||
| 				else => false, | ||||
| 			}, | ||||
| 
 | ||||
| 			.string => |self_string| switch (other.object().payload) { | ||||
| 				.string => |other_string| coral.io.equals(self_string.unpack(), other_string.unpack()), | ||||
| 				.string => |other_string| coral.io.are_equal(self_string.unpack(), other_string.unpack()), | ||||
| 				else => false, | ||||
| 			}, | ||||
| 
 | ||||
| @ -1384,6 +1432,8 @@ pub const RuntimeRef = opaque { | ||||
| 			.float => |float| @bitCast(float), | ||||
| 			.fixed => |fixed| @intCast(@as(u32, @bitCast(fixed))), | ||||
| 			.symbol => |symbol| @intFromPtr(symbol), | ||||
| 			.vector2 => |vector| @bitCast(vector), | ||||
| 			.vector3 => |vector| coral.io.jenkins_hash(@typeInfo(usize).Int, coral.io.bytes_of(&vector)), | ||||
| 			.syscall => |syscall| @intFromPtr(syscall), | ||||
| 			.string => |string| coral.io.djb2_hash(@typeInfo(usize).Int, string.unpack()), | ||||
| 			.dynamic => |dynamic| @intFromPtr(dynamic.typeinfo()) ^ @intFromPtr(dynamic.userdata().ptr), | ||||
| @ -1404,6 +1454,8 @@ pub const RuntimeRef = opaque { | ||||
| 			.float => |float| float != 0, | ||||
| 			.fixed => |fixed| fixed != 0, | ||||
| 			.symbol => true, | ||||
| 			.vector2 => |vector| coral.io.all_equals(coral.io.bytes_of(&vector), 0), | ||||
| 			.vector3 => |vector| coral.io.all_equals(coral.io.bytes_of(&vector), 0), | ||||
| 			.syscall => true, | ||||
| 			.string => |string| string.len != 0, | ||||
| 			.dynamic => true, | ||||
| @ -1480,3 +1532,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); | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user