authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-07-20 18:11:40+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-07-21 22:29:28+03:00
loge77ca6af7083da6723dfeb83d3788ebf7012c64e
treefdf8b0e08297123cc911e457901c83c43694639a
parentfd2f034e31bb7b2f8c671158a61473222b5cb332
signature Commit is signed but in an unrecognized format.

stage2: add float values


1 files changed, 144 insertions(+), 17 deletions(-)

src-self-hosted/value.zig+144-17
...@@ -80,6 +80,11 @@ pub const Value = extern union {...@@ -80,6 +80,11 @@ pub const Value = extern union {
80 elem_ptr,80 elem_ptr,
81 bytes,81 bytes,
82 repeated, // the value is a value repeated some number of times82 repeated, // the value is a value repeated some number of times
83 float,
84 float_16,
85 float_32,
86 float_64,
87 float_128,
8388
84 pub const last_no_payload_tag = Tag.bool_false;89 pub const last_no_payload_tag = Tag.bool_false;
85 pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1;90 pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1;
...@@ -213,6 +218,10 @@ pub const Value = extern union {...@@ -213,6 +218,10 @@ pub const Value = extern union {
213 };218 };
214 return Value{ .ptr_otherwise = &new_payload.base };219 return Value{ .ptr_otherwise = &new_payload.base };
215 },220 },
221 .float_16 => return self.copyPayloadShallow(allocator, Payload.Float_16),
222 .float_32 => return self.copyPayloadShallow(allocator, Payload.Float_32),
223 .float_64 => return self.copyPayloadShallow(allocator, Payload.Float_64),
224 .float_128, .float => return self.copyPayloadShallow(allocator, Payload.Float_128),
216 }225 }
217 }226 }
218227
...@@ -300,6 +309,10 @@ pub const Value = extern union {...@@ -300,6 +309,10 @@ pub const Value = extern union {
300 try out_stream.writeAll("(repeated) ");309 try out_stream.writeAll("(repeated) ");
301 val = val.cast(Payload.Repeated).?.val;310 val = val.cast(Payload.Repeated).?.val;
302 },311 },
312 .float_16 => return out_stream.print("{}", .{val.cast(Payload.Float_16).?.val}),
313 .float_32 => return out_stream.print("{}", .{val.cast(Payload.Float_32).?.val}),
314 .float_64 => return out_stream.print("{}", .{val.cast(Payload.Float_64).?.val}),
315 .float_128, .float => return out_stream.print("{}", .{val.cast(Payload.Float_128).?.val}),
303 };316 };
304 }317 }
305318
...@@ -380,6 +393,11 @@ pub const Value = extern union {...@@ -380,6 +393,11 @@ pub const Value = extern union {
380 .elem_ptr,393 .elem_ptr,
381 .bytes,394 .bytes,
382 .repeated,395 .repeated,
396 .float,
397 .float_16,
398 .float_32,
399 .float_64,
400 .float_128,
383 => unreachable,401 => unreachable,
384 };402 };
385 }403 }
...@@ -435,6 +453,11 @@ pub const Value = extern union {...@@ -435,6 +453,11 @@ pub const Value = extern union {
435 .bytes,453 .bytes,
436 .undef,454 .undef,
437 .repeated,455 .repeated,
456 .float,
457 .float_16,
458 .float_32,
459 .float_64,
460 .float_128,
438 => unreachable,461 => unreachable,
439462
440 .the_one_possible_value, // An integer with one possible value is always zero.463 .the_one_possible_value, // An integer with one possible value is always zero.
...@@ -502,6 +525,11 @@ pub const Value = extern union {...@@ -502,6 +525,11 @@ pub const Value = extern union {
502 .bytes,525 .bytes,
503 .undef,526 .undef,
504 .repeated,527 .repeated,
528 .float,
529 .float_16,
530 .float_32,
531 .float_64,
532 .float_128,
505 => unreachable,533 => unreachable,
506534
507 .zero,535 .zero,
...@@ -518,6 +546,25 @@ pub const Value = extern union {...@@ -518,6 +546,25 @@ pub const Value = extern union {
518 }546 }
519 }547 }
520548
549 pub fn toBool(self: Value) bool {
550 return switch (self.tag()) {
551 .bool_true => true,
552 .bool_false, .zero => false,
553 else => unreachable,
554 };
555 }
556
557 /// Asserts that the value is a float.
558 pub fn toF128(self: Value) f128 {
559 return switch (self.tag()) {
560 .float_16 => self.cast(Payload.Float_16).?.val,
561 .float_32 => self.cast(Payload.Float_32).?.val,
562 .float_64 => self.cast(Payload.Float_64).?.val,
563 .float_128, .float => self.cast(Payload.Float_128).?.val,
564 else => unreachable,
565 };
566 }
567
521 /// Asserts the value is an integer and not undefined.568 /// Asserts the value is an integer and not undefined.
522 /// Returns the number of bits the value requires to represent stored in twos complement form.569 /// Returns the number of bits the value requires to represent stored in twos complement form.
523 pub fn intBitCountTwosComp(self: Value) usize {570 pub fn intBitCountTwosComp(self: Value) usize {
...@@ -570,6 +617,11 @@ pub const Value = extern union {...@@ -570,6 +617,11 @@ pub const Value = extern union {
570 .bytes,617 .bytes,
571 .undef,618 .undef,
572 .repeated,619 .repeated,
620 .float,
621 .float_16,
622 .float_32,
623 .float_64,
624 .float_128,
573 => unreachable,625 => unreachable,
574626
575 .the_one_possible_value, // an integer with one possible value is always zero627 .the_one_possible_value, // an integer with one possible value is always zero
...@@ -642,6 +694,11 @@ pub const Value = extern union {...@@ -642,6 +694,11 @@ pub const Value = extern union {
642 .elem_ptr,694 .elem_ptr,
643 .bytes,695 .bytes,
644 .repeated,696 .repeated,
697 .float,
698 .float_16,
699 .float_32,
700 .float_64,
701 .float_128,
645 => unreachable,702 => unreachable,
646703
647 .zero,704 .zero,
...@@ -762,11 +819,17 @@ pub const Value = extern union {...@@ -762,11 +819,17 @@ pub const Value = extern union {
762 => unreachable,819 => unreachable,
763820
764 .zero => false,821 .zero => false,
822
823 .float_16 => @rem(self.cast(Payload.Float_16).?.val, 1) != 0,
824 .float_32 => @rem(self.cast(Payload.Float_32).?.val, 1) != 0,
825 .float_64 => @rem(self.cast(Payload.Float_64).?.val, 1) != 0,
826 // .float_128, .float => @rem(self.cast(Payload.Float_128).?.val, 1) != 0,
827 .float_128, .float => @panic("TODO lld: error: undefined symbol: fmodl"),
765 };828 };
766 }829 }
767830
768 pub fn orderAgainstZero(lhs: Value) std.math.Order {831 pub fn orderAgainstZero(lhs: Value) std.math.Order {
769 switch (lhs.tag()) {832 return switch (lhs.tag()) {
770 .ty,833 .ty,
771 .u8_type,834 .u8_type,
772 .i8_type,835 .i8_type,
...@@ -820,15 +883,20 @@ pub const Value = extern union {...@@ -820,15 +883,20 @@ pub const Value = extern union {
820 .zero,883 .zero,
821 .the_one_possible_value, // an integer with one possible value is always zero884 .the_one_possible_value, // an integer with one possible value is always zero
822 .bool_false,885 .bool_false,
823 => return .eq,886 => .eq,
824887
825 .bool_true => return .gt,888 .bool_true => .gt,
826889
827 .int_u64 => return std.math.order(lhs.cast(Payload.Int_u64).?.int, 0),890 .int_u64 => std.math.order(lhs.cast(Payload.Int_u64).?.int, 0),
828 .int_i64 => return std.math.order(lhs.cast(Payload.Int_i64).?.int, 0),891 .int_i64 => std.math.order(lhs.cast(Payload.Int_i64).?.int, 0),
829 .int_big_positive => return lhs.cast(Payload.IntBigPositive).?.asBigInt().orderAgainstScalar(0),892 .int_big_positive => lhs.cast(Payload.IntBigPositive).?.asBigInt().orderAgainstScalar(0),
830 .int_big_negative => return lhs.cast(Payload.IntBigNegative).?.asBigInt().orderAgainstScalar(0),893 .int_big_negative => lhs.cast(Payload.IntBigNegative).?.asBigInt().orderAgainstScalar(0),
831 }894
895 .float_16 => std.math.order(lhs.cast(Payload.Float_16).?.val, 0),
896 .float_32 => std.math.order(lhs.cast(Payload.Float_32).?.val, 0),
897 .float_64 => std.math.order(lhs.cast(Payload.Float_64).?.val, 0),
898 .float_128, .float => std.math.order(lhs.cast(Payload.Float_128).?.val, 0),
899 };
832 }900 }
833901
834 /// Asserts the value is comparable.902 /// Asserts the value is comparable.
...@@ -840,7 +908,24 @@ pub const Value = extern union {...@@ -840,7 +908,24 @@ pub const Value = extern union {
840 if (lhs_is_zero) return rhs.orderAgainstZero().invert();908 if (lhs_is_zero) return rhs.orderAgainstZero().invert();
841 if (rhs_is_zero) return lhs.orderAgainstZero();909 if (rhs_is_zero) return lhs.orderAgainstZero();
842910
843 // TODO floats911 const lhs_float = lhs.isFloat();
912 const rhs_float = rhs.isFloat();
913 if (lhs_float and rhs_float) {
914 if (lhs_tag == rhs_tag) {
915 return switch (lhs.tag()) {
916 .float_16 => return std.math.order(lhs.cast(Payload.Float_16).?.val, rhs.cast(Payload.Float_16).?.val),
917 .float_32 => return std.math.order(lhs.cast(Payload.Float_32).?.val, rhs.cast(Payload.Float_32).?.val),
918 .float_64 => return std.math.order(lhs.cast(Payload.Float_64).?.val, rhs.cast(Payload.Float_64).?.val),
919 .float_128, .float => return std.math.order(lhs.cast(Payload.Float_128).?.val, rhs.cast(Payload.Float_128).?.val),
920 else => unreachable,
921 };
922 }
923 }
924 if (lhs_float or rhs_float) {
925 const lhs_f128 = lhs.toF128();
926 const rhs_f128 = rhs.toF128();
927 return std.math.order(lhs_f128, rhs_f128);
928 }
844929
845 var lhs_bigint_space: BigIntSpace = undefined;930 var lhs_bigint_space: BigIntSpace = undefined;
846 var rhs_bigint_space: BigIntSpace = undefined;931 var rhs_bigint_space: BigIntSpace = undefined;
...@@ -864,14 +949,6 @@ pub const Value = extern union {...@@ -864,14 +949,6 @@ pub const Value = extern union {
864 return compare(a, .eq, b);949 return compare(a, .eq, b);
865 }950 }
866951
867 pub fn toBool(self: Value) bool {
868 return switch (self.tag()) {
869 .bool_true => true,
870 .bool_false, .zero => false,
871 else => unreachable,
872 };
873 }
874
875 /// Asserts the value is a pointer and dereferences it.952 /// Asserts the value is a pointer and dereferences it.
876 /// Returns error.AnalysisFail if the pointer points to a Decl that failed semantic analysis.953 /// Returns error.AnalysisFail if the pointer points to a Decl that failed semantic analysis.
877 pub fn pointerDeref(self: Value, allocator: *Allocator) error{ AnalysisFail, OutOfMemory }!Value {954 pub fn pointerDeref(self: Value, allocator: *Allocator) error{ AnalysisFail, OutOfMemory }!Value {
...@@ -928,6 +1005,11 @@ pub const Value = extern union {...@@ -928,6 +1005,11 @@ pub const Value = extern union {
928 .bytes,1005 .bytes,
929 .undef,1006 .undef,
930 .repeated,1007 .repeated,
1008 .float,
1009 .float_16,
1010 .float_32,
1011 .float_64,
1012 .float_128,
931 => unreachable,1013 => unreachable,
9321014
933 .the_one_possible_value => Value.initTag(.the_one_possible_value),1015 .the_one_possible_value => Value.initTag(.the_one_possible_value),
...@@ -999,6 +1081,11 @@ pub const Value = extern union {...@@ -999,6 +1081,11 @@ pub const Value = extern union {
999 .elem_ptr,1081 .elem_ptr,
1000 .ref_val,1082 .ref_val,
1001 .decl_ref,1083 .decl_ref,
1084 .float,
1085 .float_16,
1086 .float_32,
1087 .float_64,
1088 .float_128,
1002 => unreachable,1089 => unreachable,
10031090
1004 .bytes => {1091 .bytes => {
...@@ -1085,6 +1172,11 @@ pub const Value = extern union {...@@ -1085,6 +1172,11 @@ pub const Value = extern union {
1085 .elem_ptr,1172 .elem_ptr,
1086 .bytes,1173 .bytes,
1087 .repeated,1174 .repeated,
1175 .float,
1176 .float_16,
1177 .float_32,
1178 .float_64,
1179 .float_128,
1088 => false,1180 => false,
10891181
1090 .undef => unreachable,1182 .undef => unreachable,
...@@ -1092,6 +1184,21 @@ pub const Value = extern union {...@@ -1092,6 +1184,21 @@ pub const Value = extern union {
1092 };1184 };
1093 }1185 }
10941186
1187 /// Valid for all types. Asserts the value is not undefined.
1188 pub fn isFloat(self: Value) bool {
1189 return switch (self.tag()) {
1190 .undef => unreachable,
1191
1192 .float,
1193 .float_16,
1194 .float_32,
1195 .float_64,
1196 .float_128,
1197 => true,
1198 else => false,
1199 };
1200 }
1201
1095 /// This type is not copyable since it may contain pointers to its inner data.1202 /// This type is not copyable since it may contain pointers to its inner data.
1096 pub const Payload = struct {1203 pub const Payload = struct {
1097 tag: Tag,1204 tag: Tag,
...@@ -1168,6 +1275,26 @@ pub const Value = extern union {...@@ -1168,6 +1275,26 @@ pub const Value = extern union {
1168 /// is stored externally.1275 /// is stored externally.
1169 val: Value,1276 val: Value,
1170 };1277 };
1278
1279 pub const Float_16 = struct {
1280 base: Payload = .{ .tag = .float_16 },
1281 val: f16,
1282 };
1283
1284 pub const Float_32 = struct {
1285 base: Payload = .{ .tag = .float_32 },
1286 val: f32,
1287 };
1288
1289 pub const Float_64 = struct {
1290 base: Payload = .{ .tag = .float_64 },
1291 val: f64,
1292 };
1293
1294 pub const Float_128 = struct {
1295 base: Payload = .{ .tag = .float_128 },
1296 val: f128,
1297 };
1171 };1298 };
11721299
1173 /// Big enough to fit any non-BigInt value1300 /// Big enough to fit any non-BigInt value