authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-21 03:02:25-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-21 03:02:25-07:00
log32e2196257b2650e41b683d16bf00ba77ccfbb13
tree1eb681e2443aa31c4d5fea8ab798f12faaf7b3d2
parent5e212db29cf9e2c06aba363736ffb965e631aa2d

number literal rework


11 files changed, 772 insertions(+), 616 deletions(-)

CMakeLists.txt+1
......@@ -25,6 +25,7 @@ include_directories(
2525)
2626
2727set(ZIG_SOURCES
28 "${CMAKE_SOURCE_DIR}/src/bignum.cpp"
2829 "${CMAKE_SOURCE_DIR}/src/tokenizer.cpp"
2930 "${CMAKE_SOURCE_DIR}/src/parser.cpp"
3031 "${CMAKE_SOURCE_DIR}/src/analyze.cpp"
src/all_types.hpp+20-41
......@@ -13,6 +13,7 @@
1313#include "zig_llvm.hpp"
1414#include "hash_map.hpp"
1515#include "errmsg.hpp"
16#include "bignum.hpp"
1617
1718struct AstNode;
1819struct ImportTableEntry;
......@@ -49,15 +50,6 @@ enum CastOp {
4950 CastOpPointerReinterpret,
5051};
5152
52struct Cast {
53 CastOp op;
54 // if op is CastOpArrayToString, this will be a pointer to
55 // the string struct on the stack
56 LLVMValueRef ptr;
57 TypeTableEntry *after_type;
58 AstNode *source_node;
59};
60
6153struct ConstEnumValue {
6254 uint64_t tag;
6355 ConstExprValue *payload;
......@@ -68,9 +60,7 @@ struct ConstExprValue {
6860 bool depends_on_compile_var;
6961
7062 union {
71 uint64_t x_uint;
72 int64_t x_int;
73 double x_float;
63 BigNum x_bignum;
7464 bool x_bool;
7565 FnTableEntry *x_fn;
7666 TypeTableEntry *x_type;
......@@ -79,8 +69,19 @@ struct ConstExprValue {
7969 } data;
8070};
8171
72struct Cast {
73 CastOp op;
74 // if op is CastOpArrayToString, this will be a pointer to
75 // the string struct on the stack
76 LLVMValueRef ptr;
77 TypeTableEntry *after_type;
78 AstNode *source_node;
79 ConstExprValue const_val;
80};
81
8282struct Expr {
8383 TypeTableEntry *type_entry;
84 TypeTableEntry *resolved_type;
8485 // the context in which this expression is evaluated.
8586 // for blocks, this points to the containing scope, not the block's own scope for its children.
8687 BlockContext *block_context;
......@@ -92,10 +93,6 @@ struct Expr {
9293 ConstExprValue const_val;
9394};
9495
95struct NumLitCodeGen {
96 TypeTableEntry *resolved_type;
97};
98
9996struct StructValExprCodeGen {
10097 TypeTableEntry *type_entry;
10198 LLVMValueRef ptr;
......@@ -315,7 +312,6 @@ struct AstNodeFnCallExpr {
315312 // populated by semantic analyzer:
316313 BuiltinFnEntry *builtin_fn;
317314 Expr resolved_expr;
318 NumLitCodeGen resolved_num_lit;
319315 Cast cast;
320316 FnTableEntry *fn_entry;
321317};
......@@ -550,26 +546,15 @@ struct AstNodeCharLiteral {
550546};
551547
552548enum NumLit {
553 NumLitF32,
554 NumLitF64,
555 NumLitF128,
556 NumLitU8,
557 NumLitU16,
558 NumLitU32,
559 NumLitU64,
560 NumLitI8,
561 NumLitI16,
562 NumLitI32,
563 NumLitI64,
564
565 NumLitCount
549 NumLitFloat,
550 NumLitUInt,
566551};
567552
568553struct AstNodeNumberLiteral {
569554 NumLit kind;
570555
571556 // overflow is true if when parsing the number, we discovered it would not
572 // fit without losing data in a uint64_t, int64_t, or double
557 // fit without losing data in a uint64_t or double
573558 bool overflow;
574559
575560 union {
......@@ -578,7 +563,6 @@ struct AstNodeNumberLiteral {
578563 } data;
579564
580565 // populated by semantic analyzer
581 NumLitCodeGen codegen;
582566 Expr resolved_expr;
583567};
584568
......@@ -586,7 +570,6 @@ struct AstNodeErrorLiteral {
586570 Buf symbol;
587571
588572 // populated by semantic analyzer
589 NumLitCodeGen codegen;
590573 Expr resolved_expr;
591574};
592575
......@@ -758,10 +741,6 @@ struct TypeTableEntryStruct {
758741 bool reported_infinite_err;
759742};
760743
761struct TypeTableEntryNumLit {
762 NumLit kind;
763};
764
765744struct TypeTableEntryMaybe {
766745 TypeTableEntry *child_type;
767746};
......@@ -808,7 +787,8 @@ enum TypeTableEntryId {
808787 TypeTableEntryIdPointer,
809788 TypeTableEntryIdArray,
810789 TypeTableEntryIdStruct,
811 TypeTableEntryIdNumberLiteral,
790 TypeTableEntryIdNumLitFloat,
791 TypeTableEntryIdNumLitInt,
812792 TypeTableEntryIdMaybe,
813793 TypeTableEntryIdError,
814794 TypeTableEntryIdEnum,
......@@ -830,7 +810,6 @@ struct TypeTableEntry {
830810 TypeTableEntryInt integral;
831811 TypeTableEntryArray array;
832812 TypeTableEntryStruct structure;
833 TypeTableEntryNumLit num_lit;
834813 TypeTableEntryMaybe maybe;
835814 TypeTableEntryError error;
836815 TypeTableEntryEnum enumeration;
......@@ -951,10 +930,10 @@ struct CodeGen {
951930 TypeTableEntry *entry_unreachable;
952931 TypeTableEntry *entry_type;
953932 TypeTableEntry *entry_invalid;
933 TypeTableEntry *entry_num_lit_int;
934 TypeTableEntry *entry_num_lit_float;
954935 } builtin_types;
955936
956 TypeTableEntry *num_lit_types[NumLitCount];
957
958937 LLVMTargetDataRef target_data_ref;
959938 unsigned pointer_size_bytes;
960939 bool is_static;
src/analyze.cpp+331-333
......@@ -103,7 +103,8 @@ TypeTableEntry *new_type_table_entry(TypeTableEntryId id) {
103103 case TypeTableEntryIdFloat:
104104 case TypeTableEntryIdPointer:
105105 case TypeTableEntryIdArray:
106 case TypeTableEntryIdNumberLiteral:
106 case TypeTableEntryIdNumLitFloat:
107 case TypeTableEntryIdNumLitInt:
107108 case TypeTableEntryIdMaybe:
108109 case TypeTableEntryIdFn:
109110 case TypeTableEntryIdError:
......@@ -121,24 +122,20 @@ TypeTableEntry *new_type_table_entry(TypeTableEntryId id) {
121122 return entry;
122123}
123124
124static NumLit get_number_literal_kind_unsigned(uint64_t x) {
125static int bits_needed_for_unsigned(uint64_t x) {
125126 if (x <= UINT8_MAX) {
126 return NumLitU8;
127 return 8;
127128 } else if (x <= UINT16_MAX) {
128 return NumLitU16;
129 return 16;
129130 } else if (x <= UINT32_MAX) {
130 return NumLitU32;
131 return 32;
131132 } else {
132 return NumLitU64;
133 return 64;
133134 }
134135}
135136
136static TypeTableEntry *get_number_literal_type_unsigned(CodeGen *g, uint64_t x) {
137 return g->num_lit_types[get_number_literal_kind_unsigned(x)];
138}
139
140static TypeTableEntry *get_int_type_unsigned(CodeGen *g, uint64_t x) {
141 return get_int_type(g, false, num_lit_bit_count(get_number_literal_kind_unsigned(x)));
137static TypeTableEntry *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x) {
138 return get_int_type(g, false, bits_needed_for_unsigned(x));
142139}
143140
144141TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool is_const) {
......@@ -660,10 +657,9 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt
660657 if (!enum_type->data.enumeration.is_invalid) {
661658 enum_type->data.enumeration.gen_field_count = gen_field_index;
662659
663 uint64_t tag_size_in_bits = num_lit_bit_count(get_number_literal_kind_unsigned(field_count));
664 enum_type->align_in_bits = tag_size_in_bits;
665 enum_type->size_in_bits = tag_size_in_bits + biggest_union_member_size_in_bits;
666 TypeTableEntry *tag_type_entry = get_int_type_unsigned(g, field_count);
660 TypeTableEntry *tag_type_entry = get_smallest_unsigned_int_type(g, field_count);
661 enum_type->align_in_bits = tag_type_entry->size_in_bits;
662 enum_type->size_in_bits = tag_type_entry->size_in_bits + biggest_union_member_size_in_bits;
667663 enum_type->data.enumeration.tag_type = tag_type_entry;
668664
669665 if (biggest_union_member) {
......@@ -1048,136 +1044,105 @@ static TypeTableEntry *get_return_type(BlockContext *context) {
10481044 return unwrapped_node_type(return_type_node);
10491045}
10501046
1051static bool num_lit_fits_in_other_type(CodeGen *g, TypeTableEntry *literal_type, TypeTableEntry *other_type) {
1052 NumLit num_lit = literal_type->data.num_lit.kind;
1053 uint64_t lit_size_in_bits = num_lit_bit_count(num_lit);
1054
1055 switch (other_type->id) {
1056 case TypeTableEntryIdInvalid:
1057 case TypeTableEntryIdNumberLiteral:
1058 zig_unreachable();
1059 case TypeTableEntryIdVoid:
1060 case TypeTableEntryIdBool:
1061 case TypeTableEntryIdUnreachable:
1062 case TypeTableEntryIdPointer:
1063 case TypeTableEntryIdArray:
1064 case TypeTableEntryIdStruct:
1065 case TypeTableEntryIdEnum:
1066 case TypeTableEntryIdMetaType:
1067 case TypeTableEntryIdFn:
1068 case TypeTableEntryIdError:
1069 return false;
1070 case TypeTableEntryIdInt:
1071 if (is_num_lit_unsigned(num_lit)) {
1072 return lit_size_in_bits <= other_type->size_in_bits;
1073 } else {
1074 return false;
1075 }
1076 case TypeTableEntryIdFloat:
1077 if (is_num_lit_float(num_lit)) {
1078 return lit_size_in_bits <= other_type->size_in_bits;
1079 } else if (other_type->size_in_bits == 32) {
1080 return lit_size_in_bits < 24;
1081 } else if (other_type->size_in_bits == 64) {
1082 return lit_size_in_bits < 53;
1083 } else {
1084 return false;
1085 }
1086 case TypeTableEntryIdMaybe:
1087 return false;
1047static bool num_lit_fits_in_other_type(CodeGen *g, AstNode *literal_node, TypeTableEntry *other_type) {
1048 Expr *expr = get_resolved_expr(literal_node);
1049 ConstExprValue *const_val = &expr->const_val;
1050 assert(const_val->ok);
1051 if (other_type->id == TypeTableEntryIdFloat) {
1052 expr->resolved_type = other_type;
1053 return true;
1054 } else if (other_type->id == TypeTableEntryIdInt &&
1055 const_val->data.x_bignum.kind == BigNumKindInt)
1056 {
1057 if (bignum_fits_in_bits(&const_val->data.x_bignum, other_type->size_in_bits,
1058 other_type->data.integral.is_signed))
1059 {
1060 expr->resolved_type = other_type;
1061 return true;
1062 }
1063 } else if (other_type->id == TypeTableEntryIdNumLitFloat ||
1064 other_type->id == TypeTableEntryIdNumLitInt)
1065 {
1066 return true;
10881067 }
1089 zig_unreachable();
1090}
1091
1092static TypeTableEntry *resolve_rhs_number_literal(CodeGen *g, AstNode *non_literal_node,
1093 TypeTableEntry *non_literal_type, AstNode *literal_node, TypeTableEntry *literal_type)
1094{
1095 NumLitCodeGen *num_lit_codegen = get_resolved_num_lit(literal_node);
10961068
1097 if (non_literal_type && num_lit_fits_in_other_type(g, literal_type, non_literal_type)) {
1098 assert(!num_lit_codegen->resolved_type);
1099 num_lit_codegen->resolved_type = non_literal_type;
1100 return non_literal_type;
1101 } else {
1102 return nullptr;
1103 }
1069 add_node_error(g, literal_node,
1070 buf_sprintf("value %s cannot be represented in type '%s'",
1071 buf_ptr(bignum_to_buf(&const_val->data.x_bignum)),
1072 buf_ptr(&other_type->name)));
1073 return false;
11041074}
11051075
1106static TypeTableEntry * resolve_number_literals(CodeGen *g, AstNode *node1, AstNode *node2,
1107 TypeTableEntry *type1, TypeTableEntry *type2)
1076static TypeTableEntry *determine_peer_type_compatibility(CodeGen *g, AstNode *parent_source_node,
1077 AstNode **child_nodes, TypeTableEntry **child_types, int child_count)
11081078{
1109 if (type1->id == TypeTableEntryIdNumberLiteral &&
1110 type2->id == TypeTableEntryIdNumberLiteral)
1111 {
1112 NumLitCodeGen *codegen_num_lit_1 = get_resolved_num_lit(node1);
1113 NumLitCodeGen *codegen_num_lit_2 = get_resolved_num_lit(node2);
1114
1115 assert(!codegen_num_lit_1->resolved_type);
1116 assert(!codegen_num_lit_2->resolved_type);
1117
1118 if (is_num_lit_float(type1->data.num_lit.kind) &&
1119 is_num_lit_float(type2->data.num_lit.kind))
1079 TypeTableEntry *prev_type = child_types[0];
1080 AstNode *prev_node = child_nodes[0];
1081 if (prev_type->id == TypeTableEntryIdInvalid) {
1082 return prev_type;
1083 }
1084 for (int i = 1; i < child_count; i += 1) {
1085 TypeTableEntry *cur_type = child_types[i];
1086 AstNode *cur_node = child_nodes[i];
1087 if (cur_type->id == TypeTableEntryIdInvalid) {
1088 return cur_type;
1089 } else if (prev_type->id == TypeTableEntryIdUnreachable) {
1090 prev_type = cur_type;
1091 prev_node = cur_node;
1092 } else if (cur_type->id == TypeTableEntryIdUnreachable) {
1093 continue;
1094 } else if (prev_type->id == TypeTableEntryIdInt &&
1095 cur_type->id == TypeTableEntryIdInt &&
1096 prev_type->data.integral.is_signed == cur_type->data.integral.is_signed)
1097 {
1098 if (cur_type->size_in_bits > prev_type->size_in_bits) {
1099 prev_type = cur_type;
1100 prev_node = cur_node;
1101 }
1102 } else if (prev_type->id == TypeTableEntryIdFloat &&
1103 cur_type->id == TypeTableEntryIdFloat)
1104 {
1105 if (cur_type->size_in_bits > prev_type->size_in_bits) {
1106 prev_type = cur_type;
1107 prev_node = cur_node;
1108 }
1109 } else if (prev_type->id == TypeTableEntryIdNumLitFloat &&
1110 cur_type->id == TypeTableEntryIdNumLitFloat)
1111 {
1112 continue;
1113 } else if (prev_type->id == TypeTableEntryIdNumLitInt &&
1114 cur_type->id == TypeTableEntryIdNumLitInt)
11201115 {
1121 codegen_num_lit_1->resolved_type = g->builtin_types.entry_f64;
1122 codegen_num_lit_2->resolved_type = g->builtin_types.entry_f64;
1123 return g->builtin_types.entry_f64;
1124 } else if (is_num_lit_unsigned(type1->data.num_lit.kind) &&
1125 is_num_lit_unsigned(type2->data.num_lit.kind))
1116 continue;
1117 } else if (prev_type->id == TypeTableEntryIdNumLitInt ||
1118 prev_type->id == TypeTableEntryIdNumLitFloat)
1119 {
1120 if (num_lit_fits_in_other_type(g, prev_node, cur_type)) {
1121 prev_type = cur_type;
1122 prev_node = cur_node;
1123 continue;
1124 } else {
1125 return g->builtin_types.entry_invalid;
1126 }
1127 } else if (cur_type->id == TypeTableEntryIdNumLitInt ||
1128 cur_type->id == TypeTableEntryIdNumLitFloat)
11261129 {
1127 codegen_num_lit_1->resolved_type = g->builtin_types.entry_u64;
1128 codegen_num_lit_2->resolved_type = g->builtin_types.entry_u64;
1129 return g->builtin_types.entry_u64;
1130 if (num_lit_fits_in_other_type(g, cur_node, prev_type)) {
1131 continue;
1132 } else {
1133 return g->builtin_types.entry_invalid;
1134 }
1135 } else if (prev_type == cur_type) {
1136 continue;
11301137 } else {
1131 return nullptr;
1132 }
1133 } else if (type1->id == TypeTableEntryIdNumberLiteral) {
1134 return resolve_rhs_number_literal(g, node2, type2, node1, type1);
1135 } else {
1136 assert(type2->id == TypeTableEntryIdNumberLiteral);
1137 return resolve_rhs_number_literal(g, node1, type1, node2, type2);
1138 }
1139}
1138 add_node_error(g, parent_source_node,
1139 buf_sprintf("incompatible types: '%s' and '%s'",
1140 buf_ptr(&prev_type->name), buf_ptr(&cur_type->name)));
11401141
1141static TypeTableEntry *determine_peer_type_compatibility(CodeGen *g, AstNode *node,
1142 TypeTableEntry *type1, TypeTableEntry *type2, AstNode *node1, AstNode *node2)
1143{
1144 if (type1->id == TypeTableEntryIdInvalid ||
1145 type2->id == TypeTableEntryIdInvalid)
1146 {
1147 return type1;
1148 } else if (type1->id == TypeTableEntryIdUnreachable) {
1149 return type2;
1150 } else if (type2->id == TypeTableEntryIdUnreachable) {
1151 return type1;
1152 } else if (type1->id == TypeTableEntryIdInt &&
1153 type2->id == TypeTableEntryIdInt &&
1154 type1->data.integral.is_signed == type2->data.integral.is_signed)
1155 {
1156 return (type1->size_in_bits > type2->size_in_bits) ? type1 : type2;
1157 } else if (type1->id == TypeTableEntryIdFloat &&
1158 type2->id == TypeTableEntryIdFloat)
1159 {
1160 return (type1->size_in_bits > type2->size_in_bits) ? type1 : type2;
1161 } else if (type1->id == TypeTableEntryIdArray &&
1162 type2->id == TypeTableEntryIdArray &&
1163 type1 == type2)
1164 {
1165 return type1;
1166 } else if (type1->id == TypeTableEntryIdNumberLiteral ||
1167 type2->id == TypeTableEntryIdNumberLiteral)
1168 {
1169 TypeTableEntry *resolved_type = resolve_number_literals(g, node1, node2, type1, type2);
1170 if (resolved_type)
1171 return resolved_type;
1172 } else if (type1 == type2) {
1173 return type1;
1142 return g->builtin_types.entry_invalid;
1143 }
11741144 }
1175
1176 add_node_error(g, node,
1177 buf_sprintf("incompatible types: '%s' and '%s'",
1178 buf_ptr(&type1->name), buf_ptr(&type2->name)));
1179
1180 return g->builtin_types.entry_invalid;
1145 return prev_type;
11811146}
11821147
11831148static TypeTableEntry *resolve_type_compatibility(CodeGen *g, BlockContext *context, AstNode *node,
......@@ -1192,16 +1157,6 @@ static TypeTableEntry *resolve_type_compatibility(CodeGen *g, BlockContext *cont
11921157 if (actual_type->id == TypeTableEntryIdUnreachable)
11931158 return actual_type; // sorry toots; gotta run. good luck with that expected type.
11941159
1195 if (actual_type->id == TypeTableEntryIdNumberLiteral &&
1196 num_lit_fits_in_other_type(g, actual_type, expected_type))
1197 {
1198 NumLitCodeGen *num_lit_code_gen = get_resolved_num_lit(node);
1199 assert(!num_lit_code_gen->resolved_type ||
1200 num_lit_code_gen->resolved_type == expected_type);
1201 num_lit_code_gen->resolved_type = expected_type;
1202 return expected_type;
1203 }
1204
12051160 if (expected_type->id == TypeTableEntryIdMaybe &&
12061161 actual_type->id == TypeTableEntryIdMaybe)
12071162 {
......@@ -1283,6 +1238,16 @@ static TypeTableEntry *resolve_type_compatibility(CodeGen *g, BlockContext *cont
12831238 return expected_type;
12841239 }
12851240
1241 if ((actual_type->id == TypeTableEntryIdNumLitFloat ||
1242 actual_type->id == TypeTableEntryIdNumLitInt))
1243 {
1244 if (num_lit_fits_in_other_type(g, node, expected_type)) {
1245 return expected_type;
1246 } else {
1247 return g->builtin_types.entry_invalid;
1248 }
1249 }
1250
12861251 add_node_error(g, first_executing_node(node),
12871252 buf_sprintf("expected type '%s', got '%s'",
12881253 buf_ptr(&expected_type->name),
......@@ -1292,23 +1257,23 @@ static TypeTableEntry *resolve_type_compatibility(CodeGen *g, BlockContext *cont
12921257}
12931258
12941259static TypeTableEntry *resolve_peer_type_compatibility(CodeGen *g, BlockContext *block_context,
1295 AstNode *parent_node,
1296 AstNode *child1, AstNode *child2,
1297 TypeTableEntry *type1, TypeTableEntry *type2)
1260 AstNode *parent_source_node,
1261 AstNode **child_nodes, TypeTableEntry **child_types, int child_count)
12981262{
1299 assert(type1);
1300 assert(type2);
1263 assert(child_count > 0);
13011264
1302 TypeTableEntry *parent_type = determine_peer_type_compatibility(g, parent_node, type1, type2, child1, child2);
1265 TypeTableEntry *expected_type = determine_peer_type_compatibility(g, parent_source_node,
1266 child_nodes, child_types, child_count);
13031267
1304 if (parent_type->id == TypeTableEntryIdInvalid) {
1305 return parent_type;
1268 if (expected_type->id == TypeTableEntryIdInvalid) {
1269 return expected_type;
13061270 }
13071271
1308 resolve_type_compatibility(g, block_context, child1, parent_type, type1);
1309 resolve_type_compatibility(g, block_context, child2, parent_type, type2);
1272 for (int i = 0; i < child_count; i += 1) {
1273 resolve_type_compatibility(g, block_context, child_nodes[i], expected_type, child_types[i]);
1274 }
13101275
1311 return parent_type;
1276 return expected_type;
13121277}
13131278
13141279BlockContext *new_block_context(AstNode *node, BlockContext *parent) {
......@@ -1732,12 +1697,58 @@ static TypeTableEntry *resolve_expr_const_val_as_unsigned_num_lit(CodeGen *g, As
17321697{
17331698 Expr *expr = get_resolved_expr(node);
17341699 expr->const_val.ok = true;
1735 expr->const_val.data.x_uint = x;
1736 TypeTableEntry *num_lit_type = get_number_literal_type_unsigned(g, x);
1737 TypeTableEntry *resolved_type = resolve_rhs_number_literal(g, nullptr, expected_type, node, num_lit_type);
1738 return resolved_type ? resolved_type : num_lit_type;
1700
1701 bignum_init_unsigned(&expr->const_val.data.x_bignum, x);
1702
1703 if (expected_type) {
1704 if (expected_type->id == TypeTableEntryIdMaybe) {
1705 return g->builtin_types.entry_num_lit_int;
1706 } else {
1707 num_lit_fits_in_other_type(g, node, expected_type);
1708 return expected_type;
1709 }
1710 } else {
1711 return g->builtin_types.entry_num_lit_int;
1712 }
1713}
1714
1715static TypeTableEntry *resolve_expr_const_val_as_float_num_lit(CodeGen *g, AstNode *node,
1716 TypeTableEntry *expected_type, double x)
1717{
1718 Expr *expr = get_resolved_expr(node);
1719 expr->const_val.ok = true;
1720
1721 bignum_init_float(&expr->const_val.data.x_bignum, x);
1722
1723 if (expected_type) {
1724 num_lit_fits_in_other_type(g, node, expected_type);
1725 return expected_type;
1726 } else {
1727 return g->builtin_types.entry_num_lit_float;
1728 }
1729}
1730
1731static TypeTableEntry *resolve_expr_const_val_as_bignum_op(CodeGen *g, AstNode *node,
1732 bool (*bignum_fn)(BigNum *, BigNum *, BigNum *), AstNode *op1, AstNode *op2,
1733 TypeTableEntry *resolved_type)
1734{
1735 ConstExprValue *const_val = &get_resolved_expr(node)->const_val;
1736 ConstExprValue *op1_val = &get_resolved_expr(op1)->const_val;
1737 ConstExprValue *op2_val = &get_resolved_expr(op2)->const_val;
1738
1739 const_val->ok = true;
1740
1741 if (bignum_fn(&const_val->data.x_bignum, &op1_val->data.x_bignum, &op2_val->data.x_bignum)) {
1742 add_node_error(g, node,
1743 buf_sprintf("value cannot be represented in any integer type"));
1744 } else {
1745 num_lit_fits_in_other_type(g, node, resolved_type);
1746 }
1747
1748 return resolved_type;
17391749}
17401750
1751
17411752static TypeTableEntry *analyze_symbol_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
17421753 TypeTableEntry *expected_type, AstNode *node)
17431754{
......@@ -1918,60 +1929,6 @@ static bool eval_bool_bin_op_bool(bool a, BinOpType bin_op, bool b) {
19181929 }
19191930}
19201931
1921static bool eval_bool_bin_op_signed(int64_t a, BinOpType bin_op, int64_t b) {
1922 if (bin_op == BinOpTypeCmpEq) {
1923 return a == b;
1924 } else if (bin_op == BinOpTypeCmpNotEq) {
1925 return a != b;
1926 } else if (bin_op == BinOpTypeCmpLessThan) {
1927 return a < b;
1928 } else if (bin_op == BinOpTypeCmpGreaterThan) {
1929 return a > b;
1930 } else if (bin_op == BinOpTypeCmpLessOrEq) {
1931 return a <= b;
1932 } else if (bin_op == BinOpTypeCmpGreaterOrEq) {
1933 return a >= b;
1934 } else {
1935 zig_unreachable();
1936 }
1937}
1938
1939static bool eval_bool_bin_op_unsigned(uint64_t a, BinOpType bin_op, uint64_t b) {
1940 if (bin_op == BinOpTypeCmpEq) {
1941 return a == b;
1942 } else if (bin_op == BinOpTypeCmpNotEq) {
1943 return a != b;
1944 } else if (bin_op == BinOpTypeCmpLessThan) {
1945 return a < b;
1946 } else if (bin_op == BinOpTypeCmpGreaterThan) {
1947 return a > b;
1948 } else if (bin_op == BinOpTypeCmpLessOrEq) {
1949 return a <= b;
1950 } else if (bin_op == BinOpTypeCmpGreaterOrEq) {
1951 return a >= b;
1952 } else {
1953 zig_unreachable();
1954 }
1955}
1956
1957static bool eval_bool_bin_op_float(double a, BinOpType bin_op, double b) {
1958 if (bin_op == BinOpTypeCmpEq) {
1959 return a == b;
1960 } else if (bin_op == BinOpTypeCmpNotEq) {
1961 return a != b;
1962 } else if (bin_op == BinOpTypeCmpLessThan) {
1963 return a < b;
1964 } else if (bin_op == BinOpTypeCmpGreaterThan) {
1965 return a > b;
1966 } else if (bin_op == BinOpTypeCmpLessOrEq) {
1967 return a <= b;
1968 } else if (bin_op == BinOpTypeCmpGreaterOrEq) {
1969 return a >= b;
1970 } else {
1971 zig_unreachable();
1972 }
1973}
1974
19751932static TypeTableEntry *analyze_bool_bin_op_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
19761933 AstNode *node)
19771934{
......@@ -1983,8 +1940,11 @@ static TypeTableEntry *analyze_bool_bin_op_expr(CodeGen *g, ImportTableEntry *im
19831940 TypeTableEntry *op1_type = analyze_expression(g, import, context, nullptr, op1);
19841941 TypeTableEntry *op2_type = analyze_expression(g, import, context, nullptr, op2);
19851942
1943 AstNode *op_nodes[] = {op1, op2};
1944 TypeTableEntry *op_types[] = {op1_type, op2_type};
1945
19861946 TypeTableEntry *resolved_type = resolve_peer_type_compatibility(g, context, node,
1987 op1, op2, op1_type, op2_type);
1947 op_nodes, op_types, 2);
19881948
19891949 if (resolved_type->id == TypeTableEntryIdInvalid) {
19901950 return g->builtin_types.entry_invalid;
......@@ -1997,20 +1957,30 @@ static TypeTableEntry *analyze_bool_bin_op_expr(CodeGen *g, ImportTableEntry *im
19971957 }
19981958
19991959 bool answer;
2000 if (resolved_type->id == TypeTableEntryIdInt) {
2001 if (op1_type->data.integral.is_signed &&
2002 op2_type->data.integral.is_signed)
2003 {
2004 answer = eval_bool_bin_op_signed(op1_val->data.x_int, bin_op_type, op2_val->data.x_int);
2005 } else if (!op1_type->data.integral.is_signed &&
2006 !op2_type->data.integral.is_signed)
2007 {
2008 answer = eval_bool_bin_op_unsigned(op1_val->data.x_uint, bin_op_type, op2_val->data.x_uint);
1960 if (resolved_type->id == TypeTableEntryIdNumLitFloat ||
1961 resolved_type->id == TypeTableEntryIdNumLitInt ||
1962 resolved_type->id == TypeTableEntryIdFloat ||
1963 resolved_type->id == TypeTableEntryIdInt)
1964 {
1965 bool (*bignum_cmp)(BigNum *, BigNum *);
1966 if (bin_op_type == BinOpTypeCmpEq) {
1967 bignum_cmp = bignum_cmp_eq;
1968 } else if (bin_op_type == BinOpTypeCmpNotEq) {
1969 bignum_cmp = bignum_cmp_neq;
1970 } else if (bin_op_type == BinOpTypeCmpLessThan) {
1971 bignum_cmp = bignum_cmp_lt;
1972 } else if (bin_op_type == BinOpTypeCmpGreaterThan) {
1973 bignum_cmp = bignum_cmp_gt;
1974 } else if (bin_op_type == BinOpTypeCmpLessOrEq) {
1975 bignum_cmp = bignum_cmp_lte;
1976 } else if (bin_op_type == BinOpTypeCmpGreaterOrEq) {
1977 bignum_cmp = bignum_cmp_gte;
20091978 } else {
20101979 zig_unreachable();
20111980 }
2012 } else if (resolved_type->id == TypeTableEntryIdFloat) {
2013 answer = eval_bool_bin_op_float(op1_val->data.x_float, bin_op_type, op2_val->data.x_float);
1981
1982 answer = bignum_cmp(&op1_val->data.x_bignum, &op2_val->data.x_bignum);
1983
20141984 } else if (resolved_type->id == TypeTableEntryIdEnum) {
20151985 ConstEnumValue *enum1 = &op1_val->data.x_enum;
20161986 ConstEnumValue *enum2 = &op2_val->data.x_enum;
......@@ -2124,7 +2094,45 @@ static TypeTableEntry *analyze_bin_op_expr(CodeGen *g, ImportTableEntry *import,
21242094 TypeTableEntry *lhs_type = analyze_expression(g, import, context, expected_type, op1);
21252095 TypeTableEntry *rhs_type = analyze_expression(g, import, context, expected_type, op2);
21262096
2127 return resolve_peer_type_compatibility(g, context, node, op1, op2, lhs_type, rhs_type);
2097 AstNode *op_nodes[] = {op1, op2};
2098 TypeTableEntry *op_types[] = {lhs_type, rhs_type};
2099
2100 TypeTableEntry *resolved_type = resolve_peer_type_compatibility(g, context, node,
2101 op_nodes, op_types, 2);
2102
2103 if (resolved_type->id == TypeTableEntryIdInvalid) {
2104 return resolved_type;
2105 }
2106
2107 ConstExprValue *op1_val = &get_resolved_expr(op1)->const_val;
2108 ConstExprValue *op2_val = &get_resolved_expr(op2)->const_val;
2109 if (!op1_val->ok || !op2_val->ok) {
2110 return resolved_type;
2111 }
2112
2113 if (bin_op_type == BinOpTypeAdd) {
2114 return resolve_expr_const_val_as_bignum_op(g, node, bignum_add, op1, op2, resolved_type);
2115 } else if (bin_op_type == BinOpTypeSub) {
2116 return resolve_expr_const_val_as_bignum_op(g, node, bignum_sub, op1, op2, resolved_type);
2117 } else if (bin_op_type == BinOpTypeMult) {
2118 return resolve_expr_const_val_as_bignum_op(g, node, bignum_mul, op1, op2, resolved_type);
2119 } else if (bin_op_type == BinOpTypeDiv) {
2120 return resolve_expr_const_val_as_bignum_op(g, node, bignum_div, op1, op2, resolved_type);
2121 } else if (bin_op_type == BinOpTypeMod) {
2122 return resolve_expr_const_val_as_bignum_op(g, node, bignum_mod, op1, op2, resolved_type);
2123 } else if (bin_op_type == BinOpTypeBinOr) {
2124 return resolve_expr_const_val_as_bignum_op(g, node, bignum_or, op1, op2, resolved_type);
2125 } else if (bin_op_type == BinOpTypeBinAnd) {
2126 return resolve_expr_const_val_as_bignum_op(g, node, bignum_and, op1, op2, resolved_type);
2127 } else if (bin_op_type == BinOpTypeBinXor) {
2128 return resolve_expr_const_val_as_bignum_op(g, node, bignum_xor, op1, op2, resolved_type);
2129 } else if (bin_op_type == BinOpTypeBitShiftLeft) {
2130 return resolve_expr_const_val_as_bignum_op(g, node, bignum_shl, op1, op2, resolved_type);
2131 } else if (bin_op_type == BinOpTypeBitShiftRight) {
2132 return resolve_expr_const_val_as_bignum_op(g, node, bignum_shr, op1, op2, resolved_type);
2133 } else {
2134 zig_unreachable();
2135 }
21282136 }
21292137 case BinOpTypeUnwrapMaybe:
21302138 {
......@@ -2197,6 +2205,8 @@ static VariableTableEntry *analyze_variable_declaration_raw(CodeGen *g, ImportTa
21972205 AstNodeVariableDeclaration *variable_declaration,
21982206 bool expr_is_maybe)
21992207{
2208 bool is_const = variable_declaration->is_const;
2209
22002210 TypeTableEntry *explicit_type = nullptr;
22012211 if (variable_declaration->type != nullptr) {
22022212 explicit_type = analyze_type_expr(g, import, context, variable_declaration->type);
......@@ -2223,19 +2233,19 @@ static VariableTableEntry *analyze_variable_declaration_raw(CodeGen *g, ImportTa
22232233 add_node_error(g, source_node,
22242234 buf_sprintf("variable initialization is unreachable"));
22252235 implicit_type = g->builtin_types.entry_invalid;
2226 } else if (implicit_type->id == TypeTableEntryIdNumberLiteral) {
2227 add_node_error(g, source_node,
2228 buf_sprintf("unable to infer variable type"));
2229 implicit_type = g->builtin_types.entry_invalid;
2230 } else if (implicit_type->id == TypeTableEntryIdMetaType &&
2231 !variable_declaration->is_const)
2236 } else if (!is_const &&
2237 (implicit_type->id == TypeTableEntryIdNumLitFloat ||
2238 implicit_type->id == TypeTableEntryIdNumLitInt))
22322239 {
2240 add_node_error(g, source_node, buf_sprintf("unable to infer variable type"));
2241 implicit_type = g->builtin_types.entry_invalid;
2242 } else if (implicit_type->id == TypeTableEntryIdMetaType && !is_const) {
22332243 add_node_error(g, source_node, buf_sprintf("variable of type 'type' must be constant"));
22342244 implicit_type = g->builtin_types.entry_invalid;
22352245 }
22362246 }
22372247
2238 if (implicit_type == nullptr && variable_declaration->is_const) {
2248 if (implicit_type == nullptr && is_const) {
22392249 add_node_error(g, source_node, buf_sprintf("const variable missing initialization"));
22402250 implicit_type = g->builtin_types.entry_invalid;
22412251 }
......@@ -2244,7 +2254,7 @@ static VariableTableEntry *analyze_variable_declaration_raw(CodeGen *g, ImportTa
22442254 assert(type != nullptr); // should have been caught by the parser
22452255
22462256 VariableTableEntry *var = add_local_var(g, source_node, context,
2247 &variable_declaration->symbol, type, variable_declaration->is_const);
2257 &variable_declaration->symbol, type, is_const);
22482258
22492259
22502260 bool is_pub = (variable_declaration->visib_mod != VisibModPrivate);
......@@ -2300,28 +2310,15 @@ static TypeTableEntry *analyze_number_literal_expr(CodeGen *g, ImportTableEntry
23002310 return g->builtin_types.entry_invalid;
23012311 }
23022312
2303 ConstExprValue *const_val = &get_resolved_expr(node)->const_val;
2304 const_val->ok = true;
2305 if (is_num_lit_unsigned(node->data.number_literal.kind)) {
2306 const_val->data.x_uint = node->data.number_literal.data.x_uint;
2307 } else if (is_num_lit_float(node->data.number_literal.kind)) {
2308 const_val->data.x_float = node->data.number_literal.data.x_float;
2313 if (node->data.number_literal.kind == NumLitUInt) {
2314 return resolve_expr_const_val_as_unsigned_num_lit(g, node,
2315 expected_type, node->data.number_literal.data.x_uint);
2316 } else if (node->data.number_literal.kind == NumLitFloat) {
2317 return resolve_expr_const_val_as_float_num_lit(g, node,
2318 expected_type, node->data.number_literal.data.x_float);
23092319 } else {
23102320 zig_unreachable();
23112321 }
2312
2313 TypeTableEntry *num_lit_type = g->num_lit_types[node->data.number_literal.kind];
2314 if (expected_type) {
2315 NumLitCodeGen *codegen_num_lit = get_resolved_num_lit(node);
2316 assert(!codegen_num_lit->resolved_type);
2317 TypeTableEntry *after_implicit_cast_resolved_type =
2318 resolve_type_compatibility(g, block_context, node, expected_type, num_lit_type);
2319 assert(codegen_num_lit->resolved_type ||
2320 after_implicit_cast_resolved_type->id == TypeTableEntryIdInvalid);
2321 return after_implicit_cast_resolved_type;
2322 } else {
2323 return num_lit_type;
2324 }
23252322}
23262323
23272324static TypeTableEntry *analyze_error_literal_expr(CodeGen *g, ImportTableEntry *import,
......@@ -2353,8 +2350,15 @@ static TypeTableEntry *analyze_array_type(CodeGen *g, ImportTableEntry *import,
23532350
23542351 ConstExprValue *const_val = &get_resolved_expr(size_node)->const_val;
23552352 if (const_val->ok) {
2356 return resolve_expr_const_val_as_type(g, node,
2357 get_array_type(g, child_type, const_val->data.x_uint));
2353 if (const_val->data.x_bignum.is_negative) {
2354 add_node_error(g, size_node,
2355 buf_sprintf("array size %s is negative",
2356 buf_ptr(bignum_to_buf(&const_val->data.x_bignum))));
2357 return g->builtin_types.entry_invalid;
2358 } else {
2359 return resolve_expr_const_val_as_type(g, node,
2360 get_array_type(g, child_type, const_val->data.x_bignum.data.x_uint));
2361 }
23582362 } else {
23592363 return resolve_expr_const_val_as_type(g, node,
23602364 get_unknown_size_array_type(g, child_type, node->data.array_type.is_const));
......@@ -2493,9 +2497,9 @@ static TypeTableEntry *analyze_if_then_else(CodeGen *g, ImportTableEntry *import
24932497 if (expected_type) {
24942498 return (then_type->id == TypeTableEntryIdUnreachable) ? else_type : then_type;
24952499 } else {
2496 return resolve_peer_type_compatibility(g, context, parent_node,
2497 then_block, else_node,
2498 then_type, else_type);
2500 AstNode *op_nodes[] = {then_block, else_node};
2501 TypeTableEntry *op_types[] = {then_type, else_type};
2502 return resolve_peer_type_compatibility(g, context, parent_node, op_nodes, op_types, 2);
24992503 }
25002504}
25012505
......@@ -2535,10 +2539,60 @@ static TypeTableEntry *analyze_min_max_value(CodeGen *g, ImportTableEntry *impor
25352539 if (type_entry->id == TypeTableEntryIdInvalid) {
25362540 return g->builtin_types.entry_invalid;
25372541 } else if (type_entry->id == TypeTableEntryIdInt) {
2538 // TODO const expr eval for min/max int
2542 ConstExprValue *const_val = &get_resolved_expr(node)->const_val;
2543 const_val->ok = true;
2544 if (is_max) {
2545 if (type_entry->data.integral.is_signed) {
2546 int64_t val;
2547 if (type_entry->size_in_bits == 64) {
2548 val = INT64_MAX;
2549 } else if (type_entry->size_in_bits == 32) {
2550 val = INT32_MAX;
2551 } else if (type_entry->size_in_bits == 16) {
2552 val = INT16_MAX;
2553 } else if (type_entry->size_in_bits == 8) {
2554 val = INT8_MAX;
2555 } else {
2556 zig_unreachable();
2557 }
2558 bignum_init_signed(&const_val->data.x_bignum, val);
2559 } else {
2560 uint64_t val;
2561 if (type_entry->size_in_bits == 64) {
2562 val = UINT64_MAX;
2563 } else if (type_entry->size_in_bits == 32) {
2564 val = UINT32_MAX;
2565 } else if (type_entry->size_in_bits == 16) {
2566 val = UINT16_MAX;
2567 } else if (type_entry->size_in_bits == 8) {
2568 val = UINT8_MAX;
2569 } else {
2570 zig_unreachable();
2571 }
2572 bignum_init_unsigned(&const_val->data.x_bignum, val);
2573 }
2574 } else {
2575 if (type_entry->data.integral.is_signed) {
2576 int64_t val;
2577 if (type_entry->size_in_bits == 64) {
2578 val = INT64_MIN;
2579 } else if (type_entry->size_in_bits == 32) {
2580 val = INT32_MIN;
2581 } else if (type_entry->size_in_bits == 16) {
2582 val = INT16_MIN;
2583 } else if (type_entry->size_in_bits == 8) {
2584 val = INT8_MIN;
2585 } else {
2586 zig_unreachable();
2587 }
2588 bignum_init_signed(&const_val->data.x_bignum, val);
2589 } else {
2590 bignum_init_unsigned(&const_val->data.x_bignum, 0);
2591 }
2592 }
25392593 return type_entry;
25402594 } else if (type_entry->id == TypeTableEntryIdFloat) {
2541 // TODO const expr eval for min/max float
2595 zig_panic("TODO analyze_min_max_value float");
25422596 return type_entry;
25432597 } else if (type_entry->id == TypeTableEntryIdBool) {
25442598 return resolve_expr_const_val_as_bool(g, node, is_max);
......@@ -2559,10 +2613,9 @@ static void eval_const_expr_implicit_cast(CodeGen *g, ImportTableEntry *import,
25592613 case CastOpPointerReinterpret:
25602614 {
25612615 ConstExprValue *other_val = &get_resolved_expr(expr_node)->const_val;
2562 ConstExprValue *const_val = &get_resolved_expr(node)->const_val;
2563 if (other_val != const_val) {
2564 *const_val = *other_val;
2565 }
2616 ConstExprValue *const_val = &cast->const_val;
2617 assert(const_val != other_val);
2618 *const_val = *other_val;
25662619 break;
25672620 }
25682621 case CastOpToUnknownSizeArray:
......@@ -2571,14 +2624,11 @@ static void eval_const_expr_implicit_cast(CodeGen *g, ImportTableEntry *import,
25712624 case CastOpMaybeWrap:
25722625 {
25732626 ConstExprValue *other_val = &get_resolved_expr(expr_node)->const_val;
2574 ConstExprValue *const_val = &get_resolved_expr(node)->const_val;
2627 ConstExprValue *const_val = &cast->const_val;
25752628 if (!other_val->ok) {
25762629 break;
2577 } else if (const_val == other_val) {
2578 ConstExprValue *new_val = allocate<ConstExprValue>(1);
2579 memcpy(new_val, other_val, sizeof(ConstExprValue));
2580 other_val = new_val;
25812630 }
2631 assert(const_val != other_val);
25822632
25832633 const_val->data.x_maybe = other_val;
25842634 const_val->ok = true;
......@@ -2635,12 +2685,10 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B
26352685 context->cast_expr_alloca_list.append(cast);
26362686 eval_const_expr_implicit_cast(g, import, context, node, cast, expr_node);
26372687 return wanted_type;
2638 } else if (actual_type->id == TypeTableEntryIdNumberLiteral &&
2639 num_lit_fits_in_other_type(g, actual_type, wanted_type))
2688 } else if (actual_type->id == TypeTableEntryIdNumLitFloat ||
2689 actual_type->id == TypeTableEntryIdNumLitInt)
26402690 {
2641 NumLitCodeGen *codegen_num_lit = get_resolved_num_lit(expr_node);
2642 assert(!codegen_num_lit->resolved_type);
2643 codegen_num_lit->resolved_type = wanted_type;
2691 num_lit_fits_in_other_type(g, expr_node, wanted_type);
26442692 cast->op = CastOpNothing;
26452693 eval_const_expr_implicit_cast(g, import, context, node, cast, expr_node);
26462694 return wanted_type;
......@@ -2998,7 +3046,7 @@ static TypeTableEntry *analyze_prefix_op_expr(CodeGen *g, ImportTableEntry *impo
29983046 return g->builtin_types.entry_bool;
29993047 }
30003048
3001 bool answer = target_const_val->data.x_bool;
3049 bool answer = !target_const_val->data.x_bool;
30023050 return resolve_expr_const_val_as_bool(g, node, answer);
30033051 }
30043052 case PrefixOpBinNot:
......@@ -3008,8 +3056,7 @@ static TypeTableEntry *analyze_prefix_op_expr(CodeGen *g, ImportTableEntry *impo
30083056 if (expr_type->id == TypeTableEntryIdInvalid) {
30093057 return expr_type;
30103058 } else if (expr_type->id == TypeTableEntryIdInt ||
3011 (expr_type->id == TypeTableEntryIdNumberLiteral &&
3012 !is_num_lit_float(expr_type->data.num_lit.kind)))
3059 expr_type->id == TypeTableEntryIdNumLitInt)
30133060 {
30143061 return expr_type;
30153062 } else {
......@@ -3017,6 +3064,7 @@ static TypeTableEntry *analyze_prefix_op_expr(CodeGen *g, ImportTableEntry *impo
30173064 buf_ptr(&expr_type->name)));
30183065 return g->builtin_types.entry_invalid;
30193066 }
3067 // TODO const expr eval
30203068 }
30213069 case PrefixOpNegation:
30223070 {
......@@ -3030,13 +3078,16 @@ static TypeTableEntry *analyze_prefix_op_expr(CodeGen *g, ImportTableEntry *impo
30303078 return expr_type;
30313079 } else if (expr_type->id == TypeTableEntryIdFloat) {
30323080 return expr_type;
3033 } else if (expr_type->id == TypeTableEntryIdNumberLiteral) {
3081 } else if (expr_type->id == TypeTableEntryIdNumLitInt) {
3082 return expr_type;
3083 } else if (expr_type->id == TypeTableEntryIdNumLitFloat) {
30343084 return expr_type;
30353085 } else {
30363086 add_node_error(g, node, buf_sprintf("invalid negation type: '%s'",
30373087 buf_ptr(&expr_type->name)));
30383088 return g->builtin_types.entry_invalid;
30393089 }
3090 // TODO const expr eval
30403091 }
30413092 case PrefixOpAddressOf:
30423093 case PrefixOpConstAddressOf:
......@@ -4129,59 +4180,6 @@ Expr *get_resolved_expr(AstNode *node) {
41294180 zig_unreachable();
41304181}
41314182
4132NumLitCodeGen *get_resolved_num_lit(AstNode *node) {
4133 switch (node->type) {
4134 case NodeTypeNumberLiteral:
4135 return &node->data.number_literal.codegen;
4136 case NodeTypeErrorLiteral:
4137 return &node->data.error_literal.codegen;
4138 case NodeTypeFnCallExpr:
4139 return &node->data.fn_call_expr.resolved_num_lit;
4140 case NodeTypeReturnExpr:
4141 case NodeTypeBinOpExpr:
4142 case NodeTypePrefixOpExpr:
4143 case NodeTypeArrayAccessExpr:
4144 case NodeTypeSliceExpr:
4145 case NodeTypeFieldAccessExpr:
4146 case NodeTypeIfBoolExpr:
4147 case NodeTypeIfVarExpr:
4148 case NodeTypeWhileExpr:
4149 case NodeTypeForExpr:
4150 case NodeTypeSwitchExpr:
4151 case NodeTypeSwitchProng:
4152 case NodeTypeSwitchRange:
4153 case NodeTypeAsmExpr:
4154 case NodeTypeContainerInitExpr:
4155 case NodeTypeRoot:
4156 case NodeTypeRootExportDecl:
4157 case NodeTypeFnProto:
4158 case NodeTypeFnDef:
4159 case NodeTypeFnDecl:
4160 case NodeTypeParamDecl:
4161 case NodeTypeBlock:
4162 case NodeTypeExternBlock:
4163 case NodeTypeDirective:
4164 case NodeTypeVariableDeclaration:
4165 case NodeTypeStringLiteral:
4166 case NodeTypeCharLiteral:
4167 case NodeTypeSymbol:
4168 case NodeTypeUse:
4169 case NodeTypeBoolLiteral:
4170 case NodeTypeNullLiteral:
4171 case NodeTypeLabel:
4172 case NodeTypeGoto:
4173 case NodeTypeBreak:
4174 case NodeTypeContinue:
4175 case NodeTypeStructDecl:
4176 case NodeTypeStructField:
4177 case NodeTypeStructValueField:
4178 case NodeTypeArrayType:
4179 case NodeTypeErrorValueDecl:
4180 zig_unreachable();
4181 }
4182 zig_unreachable();
4183}
4184
41854183TopLevelDecl *get_resolved_top_level_decl(AstNode *node) {
41864184 switch (node->type) {
41874185 case NodeTypeVariableDeclaration:
src/analyze.hpp-1
......@@ -18,7 +18,6 @@ VariableTableEntry *find_variable(BlockContext *context, Buf *name);
1818TypeTableEntry *find_container(BlockContext *context, Buf *name);
1919BlockContext *new_block_context(AstNode *node, BlockContext *parent);
2020Expr *get_resolved_expr(AstNode *node);
21NumLitCodeGen *get_resolved_num_lit(AstNode *node);
2221TopLevelDecl *get_resolved_top_level_decl(AstNode *node);
2322bool is_node_void_expr(AstNode *node);
2423TypeTableEntry **get_int_type_ptr(CodeGen *g, bool is_signed, int size_in_bits);
src/bignum.cpp created+305
......@@ -0,0 +1,305 @@
1/*
2 * Copyright (c) 2016 Andrew Kelley
3 *
4 * This file is part of zig, which is MIT licensed.
5 * See http://opensource.org/licenses/MIT
6 */
7
8#include "bignum.hpp"
9
10#include <assert.h>
11#include <math.h>
12
13static void bignum_normalize(BigNum *bn) {
14 assert(bn->kind == BigNumKindInt);
15 if (bn->data.x_uint == 0) {
16 bn->is_negative = false;
17 }
18}
19
20void bignum_init_float(BigNum *dest, double x) {
21 dest->kind = BigNumKindFloat;
22 dest->is_negative = false;
23 dest->data.x_float = x;
24}
25
26void bignum_init_unsigned(BigNum *dest, uint64_t x) {
27 dest->kind = BigNumKindInt;
28 dest->is_negative = false;
29 dest->data.x_uint = x;
30}
31
32void bignum_init_signed(BigNum *dest, int64_t x) {
33 dest->kind = BigNumKindInt;
34 if (x < 0) {
35 dest->is_negative = true;
36 dest->data.x_uint = ((uint64_t)(-(x + 1))) + 1;
37 } else {
38 dest->is_negative = false;
39 dest->data.x_uint = x;
40 }
41}
42
43bool bignum_fits_in_bits(BigNum *bn, int bit_count, bool is_signed) {
44 assert(bn->kind == BigNumKindInt);
45
46 if (is_signed) {
47 if (bn->data.x_uint <= ((uint64_t)(INT8_MAX)) + 1) {
48 return bit_count >= 8;
49 } else if (bn->data.x_uint <= ((uint64_t)(INT16_MAX)) + 1) {
50 return bit_count >= 16;
51 } else if (bn->data.x_uint <= ((uint64_t)(INT32_MAX)) + 1) {
52 return bit_count >= 32;
53 } else {
54 return bit_count >= 64;
55 }
56 } else {
57 if (bn->is_negative) {
58 return bn->data.x_uint == 0;
59 } else {
60 if (bn->data.x_uint <= UINT8_MAX) {
61 return bit_count >= 8;
62 } else if (bn->data.x_uint <= UINT16_MAX) {
63 return bit_count >= 16;
64 } else if (bn->data.x_uint <= UINT32_MAX) {
65 return bit_count >= 32;
66 } else {
67 return bit_count >= 64;
68 }
69 }
70 }
71}
72
73uint64_t bignum_to_twos_complement(BigNum *bn) {
74 assert(bn->kind == BigNumKindInt);
75
76 if (bn->is_negative) {
77 int64_t x = bn->data.x_uint;
78 return -x;
79 } else {
80 return bn->data.x_uint;
81 }
82}
83
84// returns true if overflow happened
85bool bignum_add(BigNum *dest, BigNum *op1, BigNum *op2) {
86 assert(op1->kind == op2->kind);
87 dest->kind = op1->kind;
88
89 if (dest->kind == BigNumKindFloat) {
90 dest->data.x_float = op1->data.x_float + op2->data.x_float;
91 return false;
92 }
93
94 if (op1->is_negative == op2->is_negative) {
95 return __builtin_uaddll_overflow(op1->data.x_uint, op2->data.x_uint, &dest->data.x_uint);
96 } else if (!op1->is_negative && op2->is_negative) {
97 if (__builtin_usubll_overflow(op1->data.x_uint, op2->data.x_uint, &dest->data.x_uint)) {
98 dest->data.x_uint = (UINT64_MAX - dest->data.x_uint) + 1;
99 dest->is_negative = true;
100 bignum_normalize(dest);
101 return false;
102 } else {
103 bignum_normalize(dest);
104 return false;
105 }
106 } else {
107 return bignum_add(dest, op2, op1);
108 }
109}
110
111void bignum_negate(BigNum *dest, BigNum *op) {
112 dest->kind = op->kind;
113
114 if (dest->kind == BigNumKindFloat) {
115 dest->data.x_float = -dest->data.x_float;
116 } else {
117 dest->data.x_uint = op->data.x_uint;
118 dest->is_negative = !op->is_negative;
119 bignum_normalize(dest);
120 }
121}
122
123bool bignum_sub(BigNum *dest, BigNum *op1, BigNum *op2) {
124 BigNum op2_negated;
125 bignum_negate(&op2_negated, op2);
126 return bignum_add(dest, op1, &op2_negated);
127}
128
129bool bignum_mul(BigNum *dest, BigNum *op1, BigNum *op2) {
130 assert(op1->kind == op2->kind);
131 dest->kind = op1->kind;
132
133 if (dest->kind == BigNumKindFloat) {
134 dest->data.x_float = op1->data.x_float * op2->data.x_float;
135 bignum_normalize(dest);
136 return false;
137 }
138
139 if (__builtin_umulll_overflow(op1->data.x_uint, op2->data.x_uint, &dest->data.x_uint)) {
140 return true;
141 }
142
143 dest->is_negative = op1->is_negative != op2->is_negative;
144 bignum_normalize(dest);
145 return false;
146}
147
148bool bignum_div(BigNum *dest, BigNum *op1, BigNum *op2) {
149 assert(op1->kind == op2->kind);
150 dest->kind = op1->kind;
151
152 if (dest->kind == BigNumKindFloat) {
153 dest->data.x_float = op1->data.x_float / op2->data.x_float;
154 } else {
155 dest->data.x_uint = op1->data.x_uint / op2->data.x_uint;
156 dest->is_negative = op1->is_negative != op2->is_negative;
157 bignum_normalize(dest);
158 }
159 return false;
160}
161
162bool bignum_mod(BigNum *dest, BigNum *op1, BigNum *op2) {
163 assert(op1->kind == op2->kind);
164 dest->kind = op1->kind;
165
166 if (dest->kind == BigNumKindFloat) {
167 dest->data.x_float = fmod(op1->data.x_float, op2->data.x_float);
168 } else {
169 if (op1->is_negative || op2->is_negative) {
170 zig_panic("TODO handle mod with negative numbers");
171 }
172 dest->data.x_uint = op1->data.x_uint % op2->data.x_uint;
173 bignum_normalize(dest);
174 }
175 return false;
176}
177
178bool bignum_or(BigNum *dest, BigNum *op1, BigNum *op2) {
179 assert(op1->kind == BigNumKindInt);
180 assert(op2->kind == BigNumKindInt);
181
182 assert(!op1->is_negative);
183 assert(!op2->is_negative);
184
185 dest->kind = BigNumKindInt;
186 dest->data.x_uint = op1->data.x_uint | op2->data.x_uint;
187 return false;
188}
189
190bool bignum_and(BigNum *dest, BigNum *op1, BigNum *op2) {
191 assert(op1->kind == BigNumKindInt);
192 assert(op2->kind == BigNumKindInt);
193
194 assert(!op1->is_negative);
195 assert(!op2->is_negative);
196
197 dest->kind = BigNumKindInt;
198 dest->data.x_uint = op1->data.x_uint & op2->data.x_uint;
199 return false;
200}
201
202bool bignum_xor(BigNum *dest, BigNum *op1, BigNum *op2) {
203 assert(op1->kind == BigNumKindInt);
204 assert(op2->kind == BigNumKindInt);
205
206 assert(!op1->is_negative);
207 assert(!op2->is_negative);
208
209 dest->kind = BigNumKindInt;
210 dest->data.x_uint = op1->data.x_uint ^ op2->data.x_uint;
211 return false;
212}
213
214bool bignum_shl(BigNum *dest, BigNum *op1, BigNum *op2) {
215 assert(op1->kind == BigNumKindInt);
216 assert(op2->kind == BigNumKindInt);
217
218 assert(!op1->is_negative);
219 assert(!op2->is_negative);
220
221 dest->kind = BigNumKindInt;
222 dest->data.x_uint = op1->data.x_uint << op2->data.x_uint;
223 return false;
224}
225
226bool bignum_shr(BigNum *dest, BigNum *op1, BigNum *op2) {
227 assert(op1->kind == BigNumKindInt);
228 assert(op2->kind == BigNumKindInt);
229
230 assert(!op1->is_negative);
231 assert(!op2->is_negative);
232
233 dest->kind = BigNumKindInt;
234 dest->data.x_uint = op1->data.x_uint >> op2->data.x_uint;
235 return false;
236}
237
238
239Buf *bignum_to_buf(BigNum *bn) {
240 if (bn->kind == BigNumKindFloat) {
241 return buf_sprintf("%f", bn->data.x_float);
242 } else {
243 const char *neg = bn->is_negative ? "-" : "";
244 return buf_sprintf("%s%llu", neg, bn->data.x_uint);
245 }
246}
247
248bool bignum_cmp_eq(BigNum *op1, BigNum *op2) {
249 assert(op1->kind == op2->kind);
250 if (op1->kind == BigNumKindFloat) {
251 return op1->data.x_float == op2->data.x_float;
252 } else {
253 return op1->data.x_uint == op2->data.x_uint &&
254 (op1->is_negative == op2->is_negative || op1->data.x_uint == 0);
255 }
256}
257
258bool bignum_cmp_neq(BigNum *op1, BigNum *op2) {
259 return !bignum_cmp_eq(op1, op2);
260}
261
262bool bignum_cmp_lt(BigNum *op1, BigNum *op2) {
263 return !bignum_cmp_gte(op1, op2);
264}
265
266bool bignum_cmp_gt(BigNum *op1, BigNum *op2) {
267 return !bignum_cmp_lte(op1, op2);
268}
269
270bool bignum_cmp_lte(BigNum *op1, BigNum *op2) {
271 assert(op1->kind == op2->kind);
272 if (op1->kind == BigNumKindFloat) {
273 return (op1->data.x_float <= op2->data.x_float);
274 }
275
276 // assume normalized is_negative
277 if (!op1->is_negative && !op2->is_negative) {
278 return op1->data.x_uint <= op2->data.x_uint;
279 } else if (op1->is_negative && op2->is_negative) {
280 return op1->data.x_uint >= op2->data.x_uint;
281 } else if (op1->is_negative && !op2->is_negative) {
282 return true;
283 } else {
284 return false;
285 }
286}
287
288bool bignum_cmp_gte(BigNum *op1, BigNum *op2) {
289 assert(op1->kind == op2->kind);
290
291 if (op1->kind == BigNumKindFloat) {
292 return (op1->data.x_float >= op2->data.x_float);
293 }
294
295 // assume normalized is_negative
296 if (!op1->is_negative && !op2->is_negative) {
297 return op1->data.x_uint >= op2->data.x_uint;
298 } else if (op1->is_negative && op2->is_negative) {
299 return op1->data.x_uint <= op2->data.x_uint;
300 } else if (op1->is_negative && !op2->is_negative) {
301 return false;
302 } else {
303 return true;
304 }
305}
src/bignum.hpp created+56
......@@ -0,0 +1,56 @@
1/*
2 * Copyright (c) 2016 Andrew Kelley
3 *
4 * This file is part of zig, which is MIT licensed.
5 * See http://opensource.org/licenses/MIT
6 */
7
8#include "buffer.hpp"
9
10#include <stdint.h>
11
12enum BigNumKind {
13 BigNumKindInt,
14 BigNumKindFloat,
15};
16
17struct BigNum {
18 BigNumKind kind;
19 bool is_negative;
20 union {
21 unsigned long long x_uint;
22 double x_float;
23 } data;
24};
25
26void bignum_init_float(BigNum *dest, double x);
27void bignum_init_unsigned(BigNum *dest, uint64_t x);
28void bignum_init_signed(BigNum *dest, int64_t x);
29
30bool bignum_fits_in_bits(BigNum *bn, int bit_count, bool is_signed);
31uint64_t bignum_to_twos_complement(BigNum *bn);
32
33// returns true if overflow happened
34bool bignum_add(BigNum *dest, BigNum *op1, BigNum *op2);
35bool bignum_sub(BigNum *dest, BigNum *op1, BigNum *op2);
36bool bignum_mul(BigNum *dest, BigNum *op1, BigNum *op2);
37bool bignum_div(BigNum *dest, BigNum *op1, BigNum *op2);
38bool bignum_mod(BigNum *dest, BigNum *op1, BigNum *op2);
39
40bool bignum_or(BigNum *dest, BigNum *op1, BigNum *op2);
41bool bignum_and(BigNum *dest, BigNum *op1, BigNum *op2);
42bool bignum_xor(BigNum *dest, BigNum *op1, BigNum *op2);
43bool bignum_shl(BigNum *dest, BigNum *op1, BigNum *op2);
44bool bignum_shr(BigNum *dest, BigNum *op1, BigNum *op2);
45
46void bignum_negate(BigNum *dest, BigNum *op);
47
48// returns the result of the comparison
49bool bignum_cmp_eq(BigNum *op1, BigNum *op2);
50bool bignum_cmp_neq(BigNum *op1, BigNum *op2);
51bool bignum_cmp_lt(BigNum *op1, BigNum *op2);
52bool bignum_cmp_gt(BigNum *op1, BigNum *op2);
53bool bignum_cmp_lte(BigNum *op1, BigNum *op2);
54bool bignum_cmp_gte(BigNum *op1, BigNum *op2);
55
56Buf *bignum_to_buf(BigNum *bn);
src/codegen.cpp+50-119
......@@ -118,6 +118,9 @@ static TypeTableEntry *get_expr_type(AstNode *node) {
118118 if (expr->implicit_cast.after_type) {
119119 return expr->implicit_cast.after_type;
120120 }
121 if (expr->resolved_type) {
122 return expr->resolved_type;
123 }
121124 return expr->type_entry;
122125}
123126
......@@ -131,29 +134,35 @@ static TypeTableEntry *fn_proto_type_from_type_node(CodeGen *g, AstNode *type_no
131134 }
132135}
133136
134static LLVMValueRef gen_number_literal_raw(CodeGen *g, AstNode *source_node,
135 NumLitCodeGen *codegen_num_lit, AstNodeNumberLiteral *num_lit_node)
136{
137 TypeTableEntry *type_entry = codegen_num_lit->resolved_type;
137static LLVMValueRef gen_number_literal(CodeGen *g, AstNode *expr_node) {
138 Expr *expr = get_resolved_expr(expr_node);
139 TypeTableEntry *type_entry = expr->resolved_type;
140 if (!type_entry) {
141 type_entry = expr->type_entry;
142 }
138143 assert(type_entry);
139144
140 // override the expression type for number literals
141 get_resolved_expr(source_node)->type_entry = type_entry;
145 ConstExprValue *const_val = &expr->const_val;
142146
143 if (type_entry->id == TypeTableEntryIdInt) {
144 // here the union has int64_t and uint64_t and we purposefully read
145 // the uint64_t value in either case, because we want the twos
146 // complement representation
147 assert(const_val->ok);
147148
149 if (type_entry->id == TypeTableEntryIdInt) {
150 assert(const_val->data.x_bignum.kind == BigNumKindInt);
148151 return LLVMConstInt(type_entry->type_ref,
149 num_lit_node->data.x_uint,
150 type_entry->data.integral.is_signed);
152 bignum_to_twos_complement(&const_val->data.x_bignum),
153 type_entry->data.integral.is_signed);
151154 } else if (type_entry->id == TypeTableEntryIdFloat) {
152
153 return LLVMConstReal(type_entry->type_ref,
154 num_lit_node->data.x_float);
155 if (const_val->data.x_bignum.kind == BigNumKindFloat) {
156 return LLVMConstReal(type_entry->type_ref, const_val->data.x_bignum.data.x_float);
157 } else {
158 int64_t x = const_val->data.x_bignum.data.x_uint;
159 if (const_val->data.x_bignum.is_negative) {
160 x = -x;
161 }
162 return LLVMConstReal(type_entry->type_ref, x);
163 }
155164 } else {
156 zig_panic("bad number literal type");
165 zig_unreachable();
157166 }
158167}
159168
......@@ -265,73 +274,10 @@ static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) {
265274 return nullptr;
266275 }
267276 case BuiltinFnIdSizeof:
268 {
269 assert(node->data.fn_call_expr.params.length == 1);
270 AstNode *type_node = node->data.fn_call_expr.params.at(0);
271 TypeTableEntry *type_entry = get_type_for_type_node(type_node);
272
273 NumLitCodeGen *codegen_num_lit = get_resolved_num_lit(node);
274 AstNodeNumberLiteral num_lit_node;
275 num_lit_node.kind = NumLitU64; // this field isn't even read
276 num_lit_node.overflow = false;
277 num_lit_node.data.x_uint = type_entry->size_in_bits / 8;
278 return gen_number_literal_raw(g, node, codegen_num_lit, &num_lit_node);
279 }
280277 case BuiltinFnIdMinValue:
281 {
282 assert(node->data.fn_call_expr.params.length == 1);
283 AstNode *type_node = node->data.fn_call_expr.params.at(0);
284 TypeTableEntry *type_entry = get_type_for_type_node(type_node);
285
286
287 if (type_entry->id == TypeTableEntryIdInt) {
288 if (type_entry->data.integral.is_signed) {
289 return LLVMConstInt(type_entry->type_ref, 1ULL << (type_entry->size_in_bits - 1), false);
290 } else {
291 return LLVMConstNull(type_entry->type_ref);
292 }
293 } else if (type_entry->id == TypeTableEntryIdFloat) {
294 zig_panic("TODO codegen min_value float");
295 } else {
296 zig_unreachable();
297 }
298 }
299278 case BuiltinFnIdMaxValue:
300 {
301 assert(node->data.fn_call_expr.params.length == 1);
302 AstNode *type_node = node->data.fn_call_expr.params.at(0);
303 TypeTableEntry *type_entry = get_type_for_type_node(type_node);
304
305
306 if (type_entry->id == TypeTableEntryIdInt) {
307 if (type_entry->data.integral.is_signed) {
308 return LLVMConstInt(type_entry->type_ref, (1ULL << (type_entry->size_in_bits - 1)) - 1, false);
309 } else {
310 return LLVMConstAllOnes(type_entry->type_ref);
311 }
312 } else if (type_entry->id == TypeTableEntryIdFloat) {
313 zig_panic("TODO codegen max_value float");
314 } else {
315 zig_unreachable();
316 }
317 }
318279 case BuiltinFnIdMemberCount:
319 {
320 assert(node->data.fn_call_expr.params.length == 1);
321 AstNode *type_node = node->data.fn_call_expr.params.at(0);
322 TypeTableEntry *type_entry = get_type_for_type_node(type_node);
323
324 if (type_entry->id == TypeTableEntryIdEnum) {
325 NumLitCodeGen *codegen_num_lit = get_resolved_num_lit(node);
326 AstNodeNumberLiteral num_lit_node;
327 num_lit_node.kind = NumLitU64; // field ignored
328 num_lit_node.overflow = false;
329 num_lit_node.data.x_uint = type_entry->data.enumeration.field_count;
330 return gen_number_literal_raw(g, node, codegen_num_lit, &num_lit_node);
331 } else {
332 zig_unreachable();
333 }
334 }
280 return gen_number_literal(g, node);
335281 }
336282 zig_unreachable();
337283}
......@@ -1407,11 +1353,22 @@ static LLVMValueRef gen_if_bool_expr(CodeGen *g, AstNode *node) {
14071353 assert(node->data.if_bool_expr.condition);
14081354 assert(node->data.if_bool_expr.then_block);
14091355
1410 LLVMValueRef cond_value = gen_expr(g, node->data.if_bool_expr.condition);
1356 ConstExprValue *const_val = &get_resolved_expr(node->data.if_bool_expr.condition)->const_val;
1357 if (const_val->ok) {
1358 if (const_val->data.x_bool) {
1359 return gen_expr(g, node->data.if_bool_expr.then_block);
1360 } else if (node->data.if_bool_expr.else_node) {
1361 return gen_expr(g, node->data.if_bool_expr.else_node);
1362 } else {
1363 return nullptr;
1364 }
1365 } else {
1366 LLVMValueRef cond_value = gen_expr(g, node->data.if_bool_expr.condition);
14111367
1412 return gen_if_bool_expr_raw(g, node, cond_value,
1413 node->data.if_bool_expr.then_block,
1414 node->data.if_bool_expr.else_node);
1368 return gen_if_bool_expr_raw(g, node, cond_value,
1369 node->data.if_bool_expr.then_block,
1370 node->data.if_bool_expr.else_node);
1371 }
14151372}
14161373
14171374static LLVMValueRef gen_if_var_expr(CodeGen *g, AstNode *node) {
......@@ -1932,15 +1889,6 @@ static LLVMValueRef gen_var_decl_expr(CodeGen *g, AstNode *node) {
19321889 get_resolved_expr(node)->block_context, false, &init_val);
19331890}
19341891
1935static LLVMValueRef gen_number_literal(CodeGen *g, AstNode *node) {
1936 assert(node->type == NodeTypeNumberLiteral);
1937
1938 NumLitCodeGen *codegen_num_lit = get_resolved_num_lit(node);
1939 assert(codegen_num_lit);
1940
1941 return gen_number_literal_raw(g, node, codegen_num_lit, &node->data.number_literal);
1942}
1943
19441892static LLVMValueRef gen_error_literal(CodeGen *g, AstNode *node) {
19451893 assert(node->type == NodeTypeErrorLiteral);
19461894
......@@ -2383,20 +2331,6 @@ static void add_int_overflow_fns(CodeGen *g, TypeTableEntry *type_entry) {
23832331 type_entry->data.integral.mul_with_overflow_fn = get_arithmetic_overflow_fn(g, type_entry, "smul", "umul");
23842332}
23852333
2386static const NumLit num_lit_kinds[] = {
2387 NumLitF32,
2388 NumLitF64,
2389 NumLitF128,
2390 NumLitU8,
2391 NumLitU16,
2392 NumLitU32,
2393 NumLitU64,
2394 NumLitI8,
2395 NumLitI16,
2396 NumLitI32,
2397 NumLitI64,
2398};
2399
24002334static const int int_sizes_in_bits[] = {
24012335 8,
24022336 16,
......@@ -2411,18 +2345,15 @@ static void define_builtin_types(CodeGen *g) {
24112345 buf_init_from_str(&entry->name, "(invalid)");
24122346 g->builtin_types.entry_invalid = entry;
24132347 }
2414
2415 assert(NumLitCount == array_length(num_lit_kinds));
2416 for (int i = 0; i < NumLitCount; i += 1) {
2417 NumLit num_lit_kind = num_lit_kinds[i];
2418 // This type should just create a constant with whatever actual number
2419 // type is expected at the time.
2420 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdNumberLiteral);
2421 buf_resize(&entry->name, 0);
2422 buf_appendf(&entry->name, "(%s literal)", num_lit_str(num_lit_kind));
2423 entry->data.num_lit.kind = num_lit_kind;
2424 entry->size_in_bits = num_lit_bit_count(num_lit_kind);
2425 g->num_lit_types[i] = entry;
2348 {
2349 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdNumLitFloat);
2350 buf_init_from_str(&entry->name, "(float literal)");
2351 g->builtin_types.entry_num_lit_float = entry;
2352 }
2353 {
2354 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdNumLitInt);
2355 buf_init_from_str(&entry->name, "(integer literal)");
2356 g->builtin_types.entry_num_lit_int = entry;
24262357 }
24272358
24282359 for (int i = 0; i < array_length(int_sizes_in_bits); i += 1) {
src/parser.cpp+7-114
......@@ -301,13 +301,12 @@ void ast_print(AstNode *node, int indent) {
301301 break;
302302 case NodeTypeNumberLiteral:
303303 {
304 NumLit num_lit = node->data.number_literal.kind;
304 NumLit kind = node->data.number_literal.kind;
305305 const char *name = node_type_str(node->type);
306 const char *kind_str = num_lit_str(num_lit);
307 if (is_num_lit_unsigned(num_lit)) {
308 fprintf(stderr, "%s %s %" PRIu64 "\n", name, kind_str, node->data.number_literal.data.x_uint);
306 if (kind == NumLitUInt) {
307 fprintf(stderr, "%s uint %" PRIu64 "\n", name, node->data.number_literal.data.x_uint);
309308 } else {
310 fprintf(stderr, "%s %s %f\n", name, kind_str, node->data.number_literal.data.x_float);
309 fprintf(stderr, "%s float %f\n", name, node->data.number_literal.data.x_float);
311310 }
312311 break;
313312 }
......@@ -808,16 +807,7 @@ static void parse_number_literal(ParseContext *pc, Token *token, AstNodeNumberLi
808807 if (num_lit->overflow) return;
809808
810809 num_lit->data.x_uint = whole_number;
811
812 if (whole_number <= UINT8_MAX) {
813 num_lit->kind = NumLitU8;
814 } else if (whole_number <= UINT16_MAX) {
815 num_lit->kind = NumLitU16;
816 } else if (whole_number <= UINT32_MAX) {
817 num_lit->kind = NumLitU32;
818 } else {
819 num_lit->kind = NumLitU64;
820 }
810 num_lit->kind = NumLitUInt;
821811 } else {
822812 // float
823813
......@@ -834,7 +824,7 @@ static void parse_number_literal(ParseContext *pc, Token *token, AstNodeNumberLi
834824 }
835825 assert(str_end == buf_ptr(pc->buf) + token->end_pos);
836826 num_lit->data.x_float = x;
837 num_lit->kind = NumLitF64;
827 num_lit->kind = NumLitFloat;
838828 return;
839829 }
840830
......@@ -954,8 +944,7 @@ static void parse_number_literal(ParseContext *pc, Token *token, AstNodeNumberLi
954944 double x = *(double *)&double_bits;
955945
956946 num_lit->data.x_float = x;
957 // TODO: see if we can store it in f32
958 num_lit->kind = NumLitF64;
947 num_lit->kind = NumLitFloat;
959948 }
960949}
961950
......@@ -3053,99 +3042,3 @@ AstNode *ast_parse(Buf *buf, ZigList<Token> *tokens, ImportTableEntry *owner,
30533042 pc.root = ast_parse_root(&pc, &token_index);
30543043 return pc.root;
30553044}
3056
3057const char *num_lit_str(NumLit num_lit) {
3058 switch (num_lit) {
3059 case NumLitF32:
3060 return "f32";
3061 case NumLitF64:
3062 return "f64";
3063 case NumLitF128:
3064 return "f128";
3065 case NumLitU8:
3066 return "u8";
3067 case NumLitU16:
3068 return "u16";
3069 case NumLitU32:
3070 return "u32";
3071 case NumLitU64:
3072 return "u64";
3073 case NumLitI8:
3074 return "i8";
3075 case NumLitI16:
3076 return "i16";
3077 case NumLitI32:
3078 return "i32";
3079 case NumLitI64:
3080 return "i64";
3081 case NumLitCount:
3082 zig_unreachable();
3083 }
3084 zig_unreachable();
3085}
3086
3087bool is_num_lit_unsigned(NumLit num_lit) {
3088 switch (num_lit) {
3089 case NumLitF32:
3090 case NumLitF64:
3091 case NumLitF128:
3092 case NumLitI8:
3093 case NumLitI16:
3094 case NumLitI32:
3095 case NumLitI64:
3096 return false;
3097 case NumLitU8:
3098 case NumLitU16:
3099 case NumLitU32:
3100 case NumLitU64:
3101 return true;
3102 case NumLitCount:
3103 zig_unreachable();
3104 }
3105 zig_unreachable();
3106}
3107
3108bool is_num_lit_float(NumLit num_lit) {
3109 switch (num_lit) {
3110 case NumLitF32:
3111 case NumLitF64:
3112 case NumLitF128:
3113 return true;
3114 case NumLitU8:
3115 case NumLitU16:
3116 case NumLitU32:
3117 case NumLitU64:
3118 case NumLitI8:
3119 case NumLitI16:
3120 case NumLitI32:
3121 case NumLitI64:
3122 return false;
3123 case NumLitCount:
3124 zig_unreachable();
3125 }
3126 zig_unreachable();
3127}
3128
3129uint64_t num_lit_bit_count(NumLit num_lit) {
3130 switch (num_lit) {
3131 case NumLitU8:
3132 case NumLitI8:
3133 return 8;
3134 case NumLitU16:
3135 case NumLitI16:
3136 return 16;
3137 case NumLitU32:
3138 case NumLitI32:
3139 case NumLitF32:
3140 return 32;
3141 case NumLitU64:
3142 case NumLitI64:
3143 case NumLitF64:
3144 return 64;
3145 case NumLitF128:
3146 return 128;
3147 case NumLitCount:
3148 zig_unreachable();
3149 }
3150 zig_unreachable();
3151}
src/parser.hpp-6
......@@ -24,10 +24,4 @@ const char *node_type_str(NodeType node_type);
2424
2525void ast_print(AstNode *node, int indent);
2626
27const char *num_lit_str(NumLit num_lit);
28bool is_num_lit_unsigned(NumLit num_lit);
29bool is_num_lit_float(NumLit num_lit);
30uint64_t num_lit_bit_count(NumLit num_lit);
31
32
3327#endif
std/std.zig+1-1
......@@ -34,7 +34,7 @@ pub %.BadPerm;
3434pub %.PipeFail;
3535*/
3636
37const buffer_size: u16 = 4 * 1024;
37//const buffer_size: u16 = 4 * 1024;
3838const max_u64_base10_digits: isize = 20;
3939
4040/*
test/run_tests.cpp+1-1
......@@ -1323,7 +1323,7 @@ fn f() i32 => {
13231323fn f() => {
13241324 if (0) {}
13251325}
1326 )SOURCE", 1, ".tmp_source.zig:3:9: error: expected type 'bool', got '(u8 literal)'");
1326 )SOURCE", 1, ".tmp_source.zig:3:9: error: value 0 cannot be represented in type 'bool'");
13271327
13281328 add_compile_fail_case("assign unreachable", R"SOURCE(
13291329fn f() => {