Skip to content

Commit

Permalink
all integer sizes are available as primitives
Browse files Browse the repository at this point in the history
 * fix wrong implicit cast for `@IntType` bit_count parameter.
 * fix incorrect docs for `@IntType` bit_count parameter.

closes #1242
closes #745
closes #1240
  • Loading branch information
andrewrk committed Jul 16, 2018
1 parent 363f4fa commit e9a03cc
Show file tree
Hide file tree
Showing 17 changed files with 74 additions and 104 deletions.
12 changes: 6 additions & 6 deletions doc/langref.html.in
Expand Up @@ -2310,11 +2310,11 @@ test "while loop continue expression" {
}

test "while loop continue expression, more complicated" {
var i1: usize = 1;
var j1: usize = 1;
while (i1 * j1 < 2000) : ({ i1 *= 2; j1 *= 3; }) {
const my_ij1 = i1 * j1;
assert(my_ij1 < 2000);
var i: usize = 1;
var j: usize = 1;
while (i * j < 2000) : ({ i *= 2; j *= 3; }) {
const my_ij = i * j;
assert(my_ij < 2000);
}
}
{#code_end#}
Expand Down Expand Up @@ -5424,7 +5424,7 @@ fn add(a: i32, b: i32) i32 { return a + b; }
{#header_close#}

{#header_open|@IntType#}
<pre><code class="zig">@IntType(comptime is_signed: bool, comptime bit_count: u8) type</code></pre>
<pre><code class="zig">@IntType(comptime is_signed: bool, comptime bit_count: u32) type</code></pre>
<p>
This function returns an integer type with the given signness and bit count.
</p>
Expand Down
4 changes: 0 additions & 4 deletions src/all_types.hpp
Expand Up @@ -1587,7 +1587,6 @@ struct CodeGen {

struct {
TypeTableEntry *entry_bool;
TypeTableEntry *entry_int[2][12]; // [signed,unsigned][2,3,4,5,6,7,8,16,29,32,64,128]
TypeTableEntry *entry_c_int[CIntTypeCount];
TypeTableEntry *entry_c_longdouble;
TypeTableEntry *entry_c_void;
Expand All @@ -1596,12 +1595,9 @@ struct CodeGen {
TypeTableEntry *entry_u32;
TypeTableEntry *entry_u29;
TypeTableEntry *entry_u64;
TypeTableEntry *entry_u128;
TypeTableEntry *entry_i8;
TypeTableEntry *entry_i16;
TypeTableEntry *entry_i32;
TypeTableEntry *entry_i64;
TypeTableEntry *entry_i128;
TypeTableEntry *entry_isize;
TypeTableEntry *entry_usize;
TypeTableEntry *entry_f16;
Expand Down
73 changes: 31 additions & 42 deletions src/analyze.cpp
Expand Up @@ -3227,9 +3227,8 @@ static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) {
}

{
auto entry = g->primitive_type_table.maybe_get(tld->name);
if (entry) {
TypeTableEntry *type = entry->value;
TypeTableEntry *type = get_primitive_type(g, tld->name);
if (type != nullptr) {
add_node_error(g, tld->source_node,
buf_sprintf("declaration shadows type '%s'", buf_ptr(&type->name)));
}
Expand Down Expand Up @@ -3474,9 +3473,8 @@ VariableTableEntry *add_variable(CodeGen *g, AstNode *source_node, Scope *parent
add_error_note(g, msg, existing_var->decl_node, buf_sprintf("previous declaration is here"));
variable_entry->value->type = g->builtin_types.entry_invalid;
} else {
auto primitive_table_entry = g->primitive_type_table.maybe_get(name);
if (primitive_table_entry) {
TypeTableEntry *type = primitive_table_entry->value;
TypeTableEntry *type = get_primitive_type(g, name);
if (type != nullptr) {
add_node_error(g, source_node,
buf_sprintf("variable shadows type '%s'", buf_ptr(&type->name)));
variable_entry->value->type = g->builtin_types.entry_invalid;
Expand Down Expand Up @@ -4307,43 +4305,7 @@ void semantic_analyze(CodeGen *g) {
}
}

TypeTableEntry **get_int_type_ptr(CodeGen *g, bool is_signed, uint32_t size_in_bits) {
size_t index;
if (size_in_bits == 2) {
index = 0;
} else if (size_in_bits == 3) {
index = 1;
} else if (size_in_bits == 4) {
index = 2;
} else if (size_in_bits == 5) {
index = 3;
} else if (size_in_bits == 6) {
index = 4;
} else if (size_in_bits == 7) {
index = 5;
} else if (size_in_bits == 8) {
index = 6;
} else if (size_in_bits == 16) {
index = 7;
} else if (size_in_bits == 29) {
index = 8;
} else if (size_in_bits == 32) {
index = 9;
} else if (size_in_bits == 64) {
index = 10;
} else if (size_in_bits == 128) {
index = 11;
} else {
return nullptr;
}
return &g->builtin_types.entry_int[is_signed ? 0 : 1][index];
}

TypeTableEntry *get_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits) {
TypeTableEntry **common_entry = get_int_type_ptr(g, is_signed, size_in_bits);
if (common_entry)
return *common_entry;

TypeId type_id = {};
type_id.id = TypeTableEntryIdInt;
type_id.data.integer.is_signed = is_signed;
Expand Down Expand Up @@ -4953,6 +4915,8 @@ bool fn_eval_cacheable(Scope *scope, TypeTableEntry *return_type) {
while (scope) {
if (scope->id == ScopeIdVarDecl) {
ScopeVarDecl *var_scope = (ScopeVarDecl *)scope;
if (type_is_invalid(var_scope->var->value->type))
return false;
if (can_mutate_comptime_var_state(var_scope->var->value))
return false;
} else if (scope->id == ScopeIdFnDef) {
Expand Down Expand Up @@ -6310,3 +6274,28 @@ bool type_can_fail(TypeTableEntry *type_entry) {
bool fn_type_can_fail(FnTypeId *fn_type_id) {
return type_can_fail(fn_type_id->return_type) || fn_type_id->cc == CallingConventionAsync;
}

TypeTableEntry *get_primitive_type(CodeGen *g, Buf *name) {
if (buf_len(name) >= 2) {
uint8_t first_c = buf_ptr(name)[0];
if (first_c == 'i' || first_c == 'u') {
for (size_t i = 1; i < buf_len(name); i += 1) {
uint8_t c = buf_ptr(name)[i];
if (c < '0' || c > '9') {
goto not_integer;
}
}
bool is_signed = (first_c == 'i');
uint32_t bit_count = atoi(buf_ptr(name) + 1);

This comment has been minimized.

Copy link
@BarabasGitHub

BarabasGitHub Jul 17, 2018

Contributor

atoi parses to an int instead of u32 and it doesn't do any error handling (undefined if out of range).
If only you could write this in some language that didn't allow you to forget to handle errors! ;)

This comment has been minimized.

Copy link
@BarabasGitHub

BarabasGitHub Jul 17, 2018

Contributor

Curiously it works though. =D

This comment has been minimized.

Copy link
@andrewrk

andrewrk Jul 17, 2018

Author Member

Indeed, you can bet your bottom dollar the self hosted version will use std.fmt.parseUnsigned and handle the error code!

return get_int_type(g, is_signed, bit_count);
}
}

not_integer:

auto primitive_table_entry = g->primitive_type_table.maybe_get(name);
if (primitive_table_entry != nullptr) {
return primitive_table_entry->value;
}
return nullptr;
}
3 changes: 2 additions & 1 deletion src/analyze.hpp
Expand Up @@ -19,7 +19,6 @@ TypeTableEntry *get_pointer_to_type_extra(CodeGen *g, TypeTableEntry *child_type
bool is_volatile, PtrLen ptr_len, uint32_t byte_alignment, uint32_t bit_offset, uint32_t unaligned_bit_count);
uint64_t type_size(CodeGen *g, TypeTableEntry *type_entry);
uint64_t type_size_bits(CodeGen *g, TypeTableEntry *type_entry);
TypeTableEntry **get_int_type_ptr(CodeGen *g, bool is_signed, uint32_t size_in_bits);
TypeTableEntry *get_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits);
TypeTableEntry **get_c_int_type_ptr(CodeGen *g, CIntType c_int_type);
TypeTableEntry *get_c_int_type(CodeGen *g, CIntType c_int_type);
Expand Down Expand Up @@ -204,4 +203,6 @@ bool type_can_fail(TypeTableEntry *type_entry);
bool fn_eval_cacheable(Scope *scope, TypeTableEntry *return_type);
AstNode *type_decl_node(TypeTableEntry *type_entry);

TypeTableEntry *get_primitive_type(CodeGen *g, Buf *name);

#endif
13 changes: 0 additions & 13 deletions src/codegen.cpp
Expand Up @@ -6161,16 +6161,6 @@ static void define_builtin_types(CodeGen *g) {
g->builtin_types.entry_arg_tuple = entry;
}

for (size_t int_size_i = 0; int_size_i < array_length(int_sizes_in_bits); int_size_i += 1) {
uint8_t size_in_bits = int_sizes_in_bits[int_size_i];
for (size_t is_sign_i = 0; is_sign_i < array_length(is_signed_list); is_sign_i += 1) {
bool is_signed = is_signed_list[is_sign_i];
TypeTableEntry *entry = make_int_type(g, is_signed, size_in_bits);
g->primitive_type_table.put(&entry->name, entry);
get_int_type_ptr(g, is_signed, size_in_bits)[0] = entry;
}
}

for (size_t i = 0; i < array_length(c_int_type_infos); i += 1) {
const CIntTypeInfo *info = &c_int_type_infos[i];
uint32_t size_in_bits = target_c_type_size_in_bits(&g->zig_target, info->id);
Expand Down Expand Up @@ -6286,12 +6276,9 @@ static void define_builtin_types(CodeGen *g) {
g->builtin_types.entry_u29 = get_int_type(g, false, 29);
g->builtin_types.entry_u32 = get_int_type(g, false, 32);
g->builtin_types.entry_u64 = get_int_type(g, false, 64);
g->builtin_types.entry_u128 = get_int_type(g, false, 128);
g->builtin_types.entry_i8 = get_int_type(g, true, 8);
g->builtin_types.entry_i16 = get_int_type(g, true, 16);
g->builtin_types.entry_i32 = get_int_type(g, true, 32);
g->builtin_types.entry_i64 = get_int_type(g, true, 64);
g->builtin_types.entry_i128 = get_int_type(g, true, 128);

{
g->builtin_types.entry_c_void = get_opaque_type(g, nullptr, nullptr, "c_void");
Expand Down
21 changes: 12 additions & 9 deletions src/ir.cpp
Expand Up @@ -3217,9 +3217,8 @@ static VariableTableEntry *create_local_var(CodeGen *codegen, AstNode *node, Sco
add_error_note(codegen, msg, existing_var->decl_node, buf_sprintf("previous declaration is here"));
variable_entry->value->type = codegen->builtin_types.entry_invalid;
} else {
auto primitive_table_entry = codegen->primitive_type_table.maybe_get(name);
if (primitive_table_entry) {
TypeTableEntry *type = primitive_table_entry->value;
TypeTableEntry *type = get_primitive_type(codegen, name);
if (type != nullptr) {
add_node_error(codegen, node,
buf_sprintf("variable shadows type '%s'", buf_ptr(&type->name)));
variable_entry->value->type = codegen->builtin_types.entry_invalid;
Expand Down Expand Up @@ -3661,9 +3660,9 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node,
return &const_instruction->base;
}

auto primitive_table_entry = irb->codegen->primitive_type_table.maybe_get(variable_name);
if (primitive_table_entry) {
IrInstruction *value = ir_build_const_type(irb, scope, node, primitive_table_entry->value);
TypeTableEntry *primitive_type = get_primitive_type(irb->codegen, variable_name);
if (primitive_type != nullptr) {
IrInstruction *value = ir_build_const_type(irb, scope, node, primitive_type);
if (lval == LValPtr) {
return ir_build_ref(irb, scope, node, value, false, false);
} else {
Expand Down Expand Up @@ -10691,11 +10690,11 @@ static bool ir_resolve_align(IrAnalyze *ira, IrInstruction *value, uint32_t *out
return true;
}

static bool ir_resolve_usize(IrAnalyze *ira, IrInstruction *value, uint64_t *out) {
static bool ir_resolve_unsigned(IrAnalyze *ira, IrInstruction *value, TypeTableEntry *int_type, uint64_t *out) {
if (type_is_invalid(value->value.type))
return false;

IrInstruction *casted_value = ir_implicit_cast(ira, value, ira->codegen->builtin_types.entry_usize);
IrInstruction *casted_value = ir_implicit_cast(ira, value, int_type);
if (type_is_invalid(casted_value->value.type))
return false;

Expand All @@ -10707,6 +10706,10 @@ static bool ir_resolve_usize(IrAnalyze *ira, IrInstruction *value, uint64_t *out
return true;
}

static bool ir_resolve_usize(IrAnalyze *ira, IrInstruction *value, uint64_t *out) {
return ir_resolve_unsigned(ira, value, ira->codegen->builtin_types.entry_usize, out);
}

static bool ir_resolve_bool(IrAnalyze *ira, IrInstruction *value, bool *out) {
if (type_is_invalid(value->value.type))
return false;
Expand Down Expand Up @@ -18025,7 +18028,7 @@ static TypeTableEntry *ir_analyze_instruction_int_type(IrAnalyze *ira, IrInstruc

IrInstruction *bit_count_value = instruction->bit_count->other;
uint64_t bit_count;
if (!ir_resolve_usize(ira, bit_count_value, &bit_count))
if (!ir_resolve_unsigned(ira, bit_count_value, ira->codegen->builtin_types.entry_u32, &bit_count))
return ira->codegen->builtin_types.entry_invalid;

ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
Expand Down
2 changes: 1 addition & 1 deletion src/translate_c.cpp
Expand Up @@ -427,7 +427,7 @@ static AstNode *get_global(Context *c, Buf *name) {
if (entry)
return entry->value;
}
if (c->codegen->primitive_type_table.maybe_get(name) != nullptr) {
if (get_primitive_type(c->codegen, name) != nullptr) {
return trans_create_node_symbol(c, name);
}
return nullptr;
Expand Down
2 changes: 0 additions & 2 deletions std/buffer.zig
Expand Up @@ -5,8 +5,6 @@ const Allocator = mem.Allocator;
const assert = debug.assert;
const ArrayList = std.ArrayList;

const fmt = std.fmt;

/// A buffer that allocates memory and maintains a null byte at the end.
pub const Buffer = struct {
list: ArrayList(u8),
Expand Down
2 changes: 0 additions & 2 deletions std/crypto/sha1.zig
Expand Up @@ -4,8 +4,6 @@ const endian = @import("../endian.zig");
const debug = @import("../debug/index.zig");
const builtin = @import("builtin");

pub const u160 = @IntType(false, 160);

const RoundParam = struct {
a: usize,
b: usize,
Expand Down
3 changes: 0 additions & 3 deletions std/json.zig
Expand Up @@ -6,9 +6,6 @@ const std = @import("index.zig");
const debug = std.debug;
const mem = std.mem;

const u1 = @IntType(false, 1);
const u256 = @IntType(false, 256);

// A single token slice into the parent string.
//
// Use `token.slice()` on the input at the current position to get the current slice.
Expand Down
1 change: 0 additions & 1 deletion std/math/big/int.zig
Expand Up @@ -996,7 +996,6 @@ pub const Int = struct {
// They will still run on larger than this and should pass, but the multi-limb code-paths
// may be untested in some cases.

const u256 = @IntType(false, 256);
const al = debug.global_allocator;

test "big.int comptime_int set" {
Expand Down
24 changes: 12 additions & 12 deletions std/math/exp2.zig
Expand Up @@ -75,18 +75,18 @@ fn exp2_32(x: f32) f32 {
}

var uf = x + redux;
var i0 = @bitCast(u32, uf);
i0 += tblsiz / 2;
var i_0 = @bitCast(u32, uf);
i_0 += tblsiz / 2;

const k = i0 / tblsiz;
const k = i_0 / tblsiz;
// NOTE: musl relies on undefined overflow shift behaviour. Appears that this produces the
// intended result but should confirm how GCC/Clang handle this to ensure.
const uk = @bitCast(f64, u64(0x3FF + k) << 52);
i0 &= tblsiz - 1;
i_0 &= tblsiz - 1;
uf -= redux;

const z: f64 = x - uf;
var r: f64 = exp2ft[i0];
var r: f64 = exp2ft[i_0];
const t: f64 = r * z;
r = r + t * (P1 + z * P2) + t * (z * z) * (P3 + z * P4);
return @floatCast(f32, r * uk);
Expand Down Expand Up @@ -401,18 +401,18 @@ fn exp2_64(x: f64) f64 {
// reduce x
var uf = x + redux;
// NOTE: musl performs an implicit 64-bit to 32-bit u32 truncation here
var i0 = @truncate(u32, @bitCast(u64, uf));
i0 += tblsiz / 2;
var i_0 = @truncate(u32, @bitCast(u64, uf));
i_0 += tblsiz / 2;

const k: u32 = i0 / tblsiz * tblsiz;
const k: u32 = i_0 / tblsiz * tblsiz;
const ik = @bitCast(i32, k / tblsiz);
i0 %= tblsiz;
i_0 %= tblsiz;
uf -= redux;

// r = exp2(y) = exp2t[i0] * p(z - eps[i])
// r = exp2(y) = exp2t[i_0] * p(z - eps[i])
var z = x - uf;
const t = exp2dt[2 * i0];
z -= exp2dt[2 * i0 + 1];
const t = exp2dt[2 * i_0];
z -= exp2dt[2 * i_0 + 1];
const r = t + t * z * (P1 + z * (P2 + z * (P3 + z * (P4 + z * P5))));

return math.scalbn(r, ik);
Expand Down
2 changes: 1 addition & 1 deletion std/math/index.zig
Expand Up @@ -354,7 +354,7 @@ test "math.rotl" {

pub fn Log2Int(comptime T: type) type {
// comptime ceil log2
comptime var count: usize = 0;
comptime var count = 0;
comptime var s = T.bit_count - 1;
inline while (s != 0) : (s >>= 1) {
count += 1;
Expand Down
1 change: 0 additions & 1 deletion std/os/time.zig
Expand Up @@ -25,7 +25,6 @@ pub fn sleep(seconds: usize, nanoseconds: usize) void {
}
}

const u63 = @IntType(false, 63);
pub fn posixSleep(seconds: u63, nanoseconds: u63) void {
var req = posix.timespec{
.tv_sec = seconds,
Expand Down
5 changes: 0 additions & 5 deletions test/cases/misc.zig
Expand Up @@ -58,11 +58,6 @@ test "floating point primitive bit counts" {
assert(f64.bit_count == 64);
}

const u1 = @IntType(false, 1);
const u63 = @IntType(false, 63);
const i1 = @IntType(true, 1);
const i63 = @IntType(true, 63);

test "@minValue and @maxValue" {
assert(@maxValue(u1) == 1);
assert(@maxValue(u8) == 255);
Expand Down
1 change: 0 additions & 1 deletion test/cases/struct.zig
Expand Up @@ -240,7 +240,6 @@ fn getC(data: *const BitField1) u2 {
return data.c;
}

const u24 = @IntType(false, 24);
const Foo24Bits = packed struct {
field: u24,
};
Expand Down

0 comments on commit e9a03cc

Please sign in to comment.